kschan.h

Go to the documentation of this file.
00001 #ifndef kschan_h
00002 #define kschan_h
00003 
00004 #include <math.h>
00005 #include <OS/string.h>
00006 #include "nrnoc2iv.h"
00007 #include "ivocvect.h"
00008 
00009 extern "C" {
00010 #include "spmatrix.h"
00011 }
00012 
00013 extern "C" {
00014    //extern double dt;
00015    extern double celsius;
00016 }
00017 
00018 class KSState;
00019 class KSChan;
00020 class KSSingle;
00021 struct NrnThread;
00022 
00023 class KSChanFunction {
00024 public:
00025    KSChanFunction();
00026    virtual ~KSChanFunction();
00027    virtual int type() { return 0; }
00028    virtual double f(double v) { return 1.; }
00029    void f(int cnt, double* v, double* val) {
00030       int i; for (i=0; i < cnt; ++i) { val[i] = f(v[i]); }
00031    }
00032    static KSChanFunction* new_function(int type, Vect*, double , double);
00033    Vect* gp_; // gate parameters
00034    double c(int i) { return gp_->elem(i); }
00035    static double Exp(double x) { if (x > 700.) {return exp(700.);
00036             } else if (x < -700.) { return exp(-700.);
00037             } else { return exp(x); } }
00038 };
00039 
00040 class KSChanConst : public KSChanFunction {
00041 public:
00042    virtual int type() { return 1; }
00043    virtual double f(double v) { return c(0); }
00044 };
00045 
00046 class KSChanExp : public KSChanFunction {
00047 public:
00048    virtual int type() { return 2; }
00049    virtual double f(double v) { return c(0)*Exp(c(1) * (v - c(2))); }
00050 };
00051 
00052 class KSChanLinoid : public KSChanFunction {
00053 public:
00054    virtual int type() { return 3; }
00055    virtual double f(double v) {
00056       double x = c(1)*(v - c(2));
00057       if (fabs(x) > 1e-6) {
00058          return c(0)*x/(1 -  Exp(-x));
00059       }else{
00060          return c(0)*(1 + x/2.);
00061       }
00062    }
00063 };
00064 
00065 class KSChanSigmoid : public KSChanFunction {
00066 public:
00067    virtual int type() { return 4; }
00068    virtual double f(double v) {
00069       return c(0) / (1. + Exp(c(1) * (v - c(2))));
00070    }
00071 };
00072 
00073 
00074 // e/(kT) e/k=11.604589 from hoc's FARADAY and R values
00075 #define ebykt (11.604589/(273.15 + celsius))
00076 
00077 // from MODELING NEURONAL BIOPHYSICS Lyle J Graham
00078 //A Chapter in the Handbook of Brain Theory and Neural Networks, Volume 2
00079 //a' = K*exp(z*gam*(v-vhalf)*F/RT)
00080 //b' = K*exp(-z*(1-gam)*(v-vhalf)*F/RT)
00081 //but tau = 1/(a' + b') + tau0
00082 //and inf = a'/(a' + b')   
00083 // so there is no fast way to get either a,b or inf,tau individually
00084 
00085 class KSChanBGinf : public KSChanFunction {
00086 public:
00087    virtual int type() { return 5; }
00088    virtual double f(double v) {
00089       double x = ebykt*c(2)*(v - c(1));
00090       double ap = c(0) * Exp(c(3)*x);
00091       double bp = c(0) * Exp((c(3) - 1.)*x);
00092       tau = 1/(ap + bp);
00093       double inf = ap*tau; tau += c(4);
00094       return inf;
00095    }
00096    double tau; // may avoid duplicate call to KSChanBGtau
00097 };
00098 
00099 class KSChanBGtau : public KSChanFunction {
00100 public:
00101    virtual int type() { return 6; }
00102    virtual double f(double v) {
00103       double x = ebykt*c(2)*(v - c(1));
00104       double ap = c(0) * Exp(c(3)*x);
00105       double bp = c(0) * Exp((c(3) - 1.)*x);
00106       double tau = 1/(ap + bp);
00107       inf = ap*tau; tau += c(4);
00108       return tau;
00109    }
00110    double inf; // may avoid duplicate call to KSChanBGinf
00111 };
00112 
00113 class KSChanTable : public KSChanFunction {
00114 public:
00115    KSChanTable(Vect*, double vmin, double vmax);
00116    virtual int type() { return 7; }
00117    virtual double f(double v);
00118    double vmin_, vmax_;
00119 private:
00120    double dvinv_;
00121 };
00122 
00123 class KSTransition {
00124 public:
00125    KSTransition();
00126    virtual ~KSTransition();
00127    // vmin, vmax only for type KSChanTable
00128    void setf(int direction, int type, Vect* vec, double vmin, double vmax);
00129    // only voltage gated for now
00130    double alpha(double v) { return type_ == 0 ? f0->f(v) : f0->f(v)/f1->f(v); }
00131    double beta(double v) { return type_ == 0 ? f1->f(v) : (1. - f0->f(v))/f1->f(v); }
00132    double inf(double v) { return type_ == 1 ? f0->f(v) : f0->f(v)/(f0->f(v) + f1->f(v)); }
00133    double tau(double v) { return type_ == 1 ? f1->f(v) : 1./(f0->f(v) + f1->f(v)); }
00134    void ab(double v, double& a, double& b);
00135    void ab(Vect* v, Vect* a, Vect* b);
00136    void inftau(double v, double& inf, double& tau);
00137    void inftau(Vect* v, Vect* inf, Vect* tau);
00138    // hh tables
00139    // easily out of date!!
00140    // in anything about f0 or f1 changes then must call hh_table_make;
00141    void hh_table_make(double dt, int size=200, double vmin=-100., double vmax=50.);
00142    boolean usehhtable() { return (size1_ > 0); }
00143    void inftau_hh_table(int i, double& inf, double& tau) {
00144       inf = inftab_[i];
00145       tau = tautab_[i];
00146    }
00147    void inftau_hh_table(int i, double x, double& inf, double& tau) {
00148       inf = inftab_[i] + (inftab_[i+1] - inftab_[i])*x;
00149       tau = tautab_[i] + (tautab_[i+1] - tautab_[i])*x;
00150    }
00151    // the agent style
00152    virtual double alpha(Datum*);
00153    virtual double beta();
00154    void lig2pd(int pdoff);
00155 public:
00156    Object* obj_;
00157    int index_; // into trans_ array
00158    int src_;
00159    int target_;
00160    KSChan* ks_;
00161    KSChanFunction* f0;
00162    KSChanFunction* f1;
00163    int type_; // 0-ab,voltage gated; 1-inftau voltage gated
00164          // 2-ligand outside;  3-ligand inside
00165    int ligand_index_;
00166    int pd_index_;
00167    int stoichiom_;
00168 private:
00169    // for hh tables.
00170    double* inftab_;
00171    double* tautab_;
00172    int size1_;
00173 };
00174 
00175 class KSGateComplex {
00176 public:
00177    KSGateComplex();
00178    virtual ~KSGateComplex();
00179    double conductance(double* state, KSState* st);
00180 public:
00181    Object* obj_;
00182    KSChan* ks_;
00183    int index_; // into gc_ array
00184    int sindex_; // starting state index for this complex
00185    int nstate_; // number of states
00186    int power_; // eg. n^4, or m^3   
00187 };
00188 
00189 class KSIv {
00190 public:
00191    // this one for ionic ohmic and nernst.
00192    virtual double cur(double g, double* p, Datum* pd, double v);
00193    virtual double jacob(double* p, Datum* pd, double v);
00194 };
00195 class KSIvghk : public KSIv {
00196 public:
00197    // this one for ionic Goldman-Hodgkin-Katz
00198    virtual double cur(double g, double* p, Datum* pd, double v);
00199    virtual double jacob(double* p, Datum* pd, double v);
00200    double z;
00201 };
00202 class KSIvNonSpec : public KSIv{
00203    // this one for non-specific ohmic. There will be a PARAMETER e_suffix at p[1]
00204    virtual double cur(double g, double* p, Datum* pd, double v);
00205    virtual double jacob(double* p, Datum* pd, double v);
00206 };
00207 
00208 class KSPPIv : public KSIv {
00209 public:
00210    // this one for POINT_PROCESS ionic ohmic and nernst.
00211    virtual double cur(double g, double* p, Datum* pd, double v);
00212    virtual double jacob(double* p, Datum* pd, double v);
00213    int ppoff_;
00214 };
00215 class KSPPIvghk : public KSPPIv {
00216 public:
00217    // this one for POINT_PROCESS ionic Goldman-Hodgkin-Katz
00218    virtual double cur(double g, double* p, Datum* pd, double v);
00219    virtual double jacob(double* p, Datum* pd, double v);
00220    double z;
00221 };
00222 class KSPPIvNonSpec : public KSPPIv{
00223    // this one for POINT_PROCESS non-specific ohmic. There will be a PARAMETER e_suffix at p[1]
00224    virtual double cur(double g, double* p, Datum* pd, double v);
00225    virtual double jacob(double* p, Datum* pd, double v);
00226 };
00227 
00228 class KSState {
00229 public:
00230    KSState();
00231    virtual ~KSState();
00232    const char* string() { return name_.string(); }
00233    double f_; // normalized conductance
00234    CopyString name_; 
00235    int index_; // into state_ array
00236    KSChan* ks_;
00237    Object* obj_;
00238 };
00239 
00240 class KSChan {
00241 public:
00242    KSChan(Object*, boolean is_point = false);
00243    virtual ~KSChan();
00244    virtual void alloc(Prop*);
00245    virtual void init(int, Node**, double**, Datum**, NrnThread*);
00246    virtual void cur(int, Node**, double**, Datum**);
00247    virtual void jacob(int, Node**, double**, Datum**);
00248    virtual void state(int, Node**, double**, Datum**, NrnThread*);
00249 #if CACHEVEC != 0
00250    virtual void cur(int, int *, double**, Datum**, NrnThread*);
00251    virtual void jacob(int, int *, double**, Datum**, NrnThread*);
00252    virtual void state(int, int *, Node**, double**, Datum**, NrnThread*);
00253 #endif /* CACHEVEC */
00254    void add_channel(char**);
00255    //for cvode
00256    virtual int count();
00257    virtual void map(int, double**, double**, double*, Datum*, double*);
00258    virtual void spec(int, Node**, double**, Datum**);
00259    virtual void matsol(int, Node**, double**, Datum**, NrnThread*);
00260    virtual void cv_sc_update(int, Node**, double**, Datum**, NrnThread*);
00261    double conductance(double gmax, double* state);
00262 public:
00263    // hoc accessibilty
00264    int state(const char* name);
00265    const char* state(int index);
00266    int trans_index(const char* src, const char* target); // index of the transition
00267    int trans_index(int src, int target); // index of the transition
00268    int gate_index(int state_index); // index of the gate
00269    boolean is_point() { return is_point_; }
00270    boolean is_single() { return is_single_; }
00271    void set_single(boolean, boolean update = true);
00272    void destroy_pnt(Point_process*);
00273    int nsingle(Point_process*);
00274    void nsingle(Point_process*, int);
00275    double alpha(double v, int, int) {return 0.;}
00276    double beta(double v, int, int) {return 0.;}
00277    void setstructure(Vect*);
00278    void setname(const char*);
00279    void setsname(int, const char*);
00280    void setion(const char*);
00281    void setligand(int i, const char*);
00282    void settype(KSTransition*, int type, const char*);
00283    void setivrelation(int);
00284    // hoc incremental management
00285    KSState* add_hhstate(const char*);
00286    KSState* add_ksstate(int igate, const char*);
00287    void remove_state(int);
00288    // these are only for kinetic scheme transitions since an hh
00289    // always has one and only one transition.
00290    KSTransition* add_transition(int src, int target, const char* ligand);
00291    void remove_transition(int);
00292    void setcond();
00293    void power(KSGateComplex*, int);
00294    void usetable(boolean, int size, double vmin, double vmax);
00295    void usetable(boolean);
00296    int usetable(double* vmin, double* vmax);// get info
00297    boolean usetable() { return usetable_; }
00298    void check_table_thread(NrnThread*);
00299 private:
00300    void free1();
00301    void build();
00302    void setupmat();
00303    void fillmat(double v, Datum* pd);
00304    void mat_dt(double dt, double* p);
00305    void solvemat(double*);
00306    void mulmat(double*, double*);
00307    void ion_consist();
00308    void ligand_consist(int, int, Prop*, Node*);
00309    Prop* needion(Symbol*, Node*, Prop*);
00310    void state_consist(int shift = 0);
00311    void sname_install();
00312    Symbol* looksym(const char*, Symbol* tmplt = nil);
00313    Symbol* installsym(const char*, int, Symbol* tmplt = nil);
00314    void freesym(Symbol*, Symbol* tmplt = nil);
00315    Symbol** newppsym(int);
00316    void delete_schan_node_data();
00317    void alloc_schan_node_data();
00318    void update_prop(); // can add and remove Nsingle and SingleNodeData
00319 
00320    KSState* state_insert(int i, const char* name, double frac);
00321    void state_remove(int i);
00322    KSGateComplex* gate_insert(int ig, int is, int power);
00323    void gate_remove(int i);
00324    KSTransition* trans_insert(int i, int src, int target);
00325    void trans_remove(int i);
00326    void check_struct();
00327    int state_size_;
00328    int gate_size_;
00329    int trans_size_;
00330    boolean is_point_;
00331    boolean is_single_;
00332    // for point process
00333    int pointtype_;
00334    int mechtype_;
00335 public:
00336    CopyString name_; // name of channel
00337    CopyString ion_; // name of ion , "" means non-specific
00338    double gmax_deflt_;
00339    double erev_deflt_;
00340    int cond_model_;
00341    KSIv* iv_relation_;
00342    int ngate_; // number of gating complexes
00343    int ntrans_; // total number of transitions
00344    int ivkstrans_; // index of beginning of voltage sensitive ks transitions
00345    int iligtrans_; // index of beginning of ligand sensitive ks transitions
00346          // 0 to ivkstrans_ - 1 are the hh transitions
00347    int nhhstate_; // total number of hh states, does not include ks states
00348    int nksstate_; // total number of kinetic scheme states.
00349    int nstate_;   // total number of all states, nhhstate_ to nstate_ - 1
00350          // are kinetic scheme states. The nhhstate_ are first
00351          // and the nhhstate_ = ivkstrans_
00352    KSState* state_; // the state names
00353    KSGateComplex* gc_;
00354    KSTransition* trans_; // array of transitions
00355    Symbol* ion_sym_; // if nil then non-specific and e_suffix is a parameter
00356    int  nligand_;
00357    Symbol** ligands_;
00358    Object* obj_;
00359    KSSingle* single_;
00360 private:
00361    int cvode_ieq_;
00362    Symbol* mechsym_; // the top level symbol (insert sym or new sym)
00363    Symbol* rlsym_; // symbol with the range list (= mechsym_ when  density)
00364    char* mat_;
00365    double** elms_;
00366    double** diag_;
00367    int dsize_; // size of prop->dparam
00368    int psize_; // size of prop->param
00369    int soffset_; //STATE begins here in the p array.
00370    int gmaxoffset_; // gmax is here in the p array, normally 0 but if
00371       // there is an Nsingle then it is 1.
00372    int ppoff_; //2 or 3 for point process since area and Point_process* are
00373          // first two elements and there may be a KSSingleNodeData*
00374    // for hh rate tables
00375    double vmin_, vmax_, dvinv_, dtsav_;
00376    int hh_tab_size_;
00377    boolean usetable_;
00378 };
00379 
00380 #endif
Generated on Mon Jun 13 08:10:25 2011 for NEURON by  doxygen 1.6.3