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
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_;
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
00075 #define ebykt (11.604589/(273.15 + celsius))
00076
00077
00078
00079
00080
00081
00082
00083
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;
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;
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
00128 void setf(int direction, int type, Vect* vec, double vmin, double vmax);
00129
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
00139
00140
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
00152 virtual double alpha(Datum*);
00153 virtual double beta();
00154 void lig2pd(int pdoff);
00155 public:
00156 Object* obj_;
00157 int index_;
00158 int src_;
00159 int target_;
00160 KSChan* ks_;
00161 KSChanFunction* f0;
00162 KSChanFunction* f1;
00163 int type_;
00164
00165 int ligand_index_;
00166 int pd_index_;
00167 int stoichiom_;
00168 private:
00169
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_;
00184 int sindex_;
00185 int nstate_;
00186 int power_;
00187 };
00188
00189 class KSIv {
00190 public:
00191
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
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
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
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
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
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_;
00234 CopyString name_;
00235 int index_;
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
00254 void add_channel(char**);
00255
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
00264 int state(const char* name);
00265 const char* state(int index);
00266 int trans_index(const char* src, const char* target);
00267 int trans_index(int src, int target);
00268 int gate_index(int state_index);
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
00285 KSState* add_hhstate(const char*);
00286 KSState* add_ksstate(int igate, const char*);
00287 void remove_state(int);
00288
00289
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);
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();
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
00333 int pointtype_;
00334 int mechtype_;
00335 public:
00336 CopyString name_;
00337 CopyString ion_;
00338 double gmax_deflt_;
00339 double erev_deflt_;
00340 int cond_model_;
00341 KSIv* iv_relation_;
00342 int ngate_;
00343 int ntrans_;
00344 int ivkstrans_;
00345 int iligtrans_;
00346
00347 int nhhstate_;
00348 int nksstate_;
00349 int nstate_;
00350
00351
00352 KSState* state_;
00353 KSGateComplex* gc_;
00354 KSTransition* trans_;
00355 Symbol* ion_sym_;
00356 int nligand_;
00357 Symbol** ligands_;
00358 Object* obj_;
00359 KSSingle* single_;
00360 private:
00361 int cvode_ieq_;
00362 Symbol* mechsym_;
00363 Symbol* rlsym_;
00364 char* mat_;
00365 double** elms_;
00366 double** diag_;
00367 int dsize_;
00368 int psize_;
00369 int soffset_;
00370 int gmaxoffset_;
00371
00372 int ppoff_;
00373
00374
00375 double vmin_, vmax_, dvinv_, dtsav_;
00376 int hh_tab_size_;
00377 boolean usetable_;
00378 };
00379
00380 #endif