00001 #ifndef __SPECIFIC_ION_CHANNELS_H_ 00002 #define __SPECIFIC_ION_CHANNELS_H_ 00003 00004 #include "viongate.h" 00005 #include "conciongate.h" 00006 #include "activechannel.h" 00007 #include "activecachannel.h" 00008 #include "csimerror.h" 00009 00010 // parameters for voltage range transformations 00011 #define V_REST_BIOL_MV (-70) // [mV] (general in publications used unit) 00012 #define V_THRESH_BIOL_MV (-40) // [mV] 00013 #define V_REST_SIM (0.0) // [V] (all simulation parameters are in SI units) 00014 #define V_THRESH_SIM (15e-3) // [V] 00015 00016 #define A_MEMBRANE (0.01e-2) // [cm2] 00017 00018 /* Transform biological Erev value to model voltage range */ 00019 /* Note that in the ActiveChannel constructor actual Neuron voltages are unknown */ 00020 #define TRANSFORM_EREV Erev = ((Erev - V_REST_BIOL_MV)*(V_THRESH_SIM - V_REST_SIM)/(V_THRESH_BIOL_MV-V_REST_BIOL_MV) + V_REST_SIM); 00021 00022 00023 #define TRANSFORM_V /* Transform model voltage value to biological voltage range */ \ 00024 V = (V - *Vresting)*(V_THRESH_BIOL_MV - V_REST_BIOL_MV)/(*VmScale) + V_REST_BIOL_MV 00025 00026 #define TSCALE 1000 00027 #define VSCALE 1000 00028 00029 //============================================================ 00030 00031 #define CASCALE 1.1180e+07 00032 00034 #define IONGATE_CA_MIN 0.0 00035 00037 #define IONGATE_CA_MAX 1000e-9 00038 00040 #define IONGATE_CA_INC 5.0e-10 00041 00042 #define IONGATE_CA_TABLE_SIZE ((int)((IONGATE_CA_MAX - IONGATE_CA_MIN) / IONGATE_CA_INC + 1)) 00043 00045 // Could only be connected to CaChannel_Yamada98 class, where the ca mechanism is included 00046 class CaGate_Yamada98 : public VIonGate { 00047 00048 DO_REGISTERING 00049 00050 public: 00051 CaGate_Yamada98(void) { k=2; Ca=0; Ts=1; C1=0; C2=0; } 00052 00053 virtual ~CaGate_Yamada98(void) { if (getC1()) { free(getC1()); setC1(0); } 00054 if (getC2()) { free(getC2()); setC2(0); }} 00055 00056 virtual double tau(double C) { return Ts/( pow(CASCALE*C,2) + 2.5); } 00057 00058 virtual double infty(double C) { return pow(CASCALE*C,2)/( pow(CASCALE*C,2) + 2.5); } 00059 00060 virtual double pInfty(MembranePatchSimple *) { return 0;} 00061 00062 virtual void reset(void); 00063 00064 virtual void setCa(double *C) { Ca = C; } 00065 00066 virtual int updateInternal(void); 00067 00068 virtual int advance(void); 00069 00070 virtual int addIncoming(Advancable *Incoming); 00071 00073 double Ts; 00074 00075 protected: 00076 00078 double *Ca; 00079 00080 virtual double *getC1(void) { return C1; } 00081 virtual double *getC2(void) { return C2; } 00082 virtual void setC1(double *p) { C1=p; } 00083 virtual void setC2(double *p) { C2=p; } 00084 00086 double *C1; 00087 00089 double *C2; 00090 }; 00091 00092 //== Channels used by James Maciokas / Reno ========================================================== 00093 00095 // Ca mechanism is included in the channel class not the neuron class. 00096 class CaChannel_Yamada98 : public ActiveChannel { 00097 00098 DO_REGISTERING 00099 00100 public: 00101 00102 CaChannel_Yamada98(void) { 00103 Erev = -5e-6 * VSCALE; // assumed resting potential Vresting = 0 00104 u = 200e-9; // Mol 00105 Ts = 70e-3; // Sec 00106 Ca = 0; // Mol 00107 Gbar = 54e-9; // S 00108 } 00109 00110 virtual void membraneSpikeNotify(double ) { Ca = Ca + u; }; 00111 00112 virtual void reset(void); 00113 00114 virtual int updateInternal(void); 00115 00116 virtual int advance(void); 00117 00119 float u; 00120 00122 float Ts; 00123 00125 double Ca; 00126 00127 protected: 00128 00130 float C1; 00131 }; 00132 00133 00135 class MmGate_Wang98 : public VIonGate { 00136 public: 00137 MmGate_Wang98(void) { k=1; } 00138 double tau(double V) { return TSCALE * exp(+( VSCALE * (V - *Vresting) - 12.3)/9.15) / 3800; } 00139 double infty(double V) { return 1/(1 + exp(-( VSCALE * (V - *Vresting) - 13)/4.4)); } 00140 00141 IONGATE_TABLES(MmGate_Wang98); 00142 }; 00143 00144 00145 00147 class MChannel_Wang98 : public ActiveChannel { 00148 00149 DO_REGISTERING 00150 00151 public: 00152 00153 MChannel_Wang98(void) { 00154 addGate(new MmGate_Wang98); 00155 00156 Erev = -80; // [mV] biological value 00157 // Transform to model voltage range 00158 TRANSFORM_EREV; 00159 } 00160 00161 virtual ~MChannel_Wang98(void) { 00162 for(int i=0;i<nGates;i++) 00163 delete gates[i]; 00164 } 00165 }; 00166 00168 class AmGate_Hoffman97 : public VIonGate { 00169 public: 00170 AmGate_Hoffman97(void) { k=1; } 00171 00172 double tau(double ) { return TSCALE*0.2e-6; } 00173 double infty(double V) { return 1/(1 + exp(-( VSCALE * (V - *Vresting) - 40.5)/9)); } 00174 00175 IONGATE_TABLES(AmGate_Hoffman97); 00176 }; 00177 00178 00180 class AhGate_Hoffman97 : public VIonGate { 00181 public: 00182 AhGate_Hoffman97(void) { k=1; } 00183 00184 double tau(double ) { return TSCALE*5e-6; } 00185 double infty(double V) { return 1/(1 + exp(( VSCALE * (V - *Vresting) - 7)/4)); } 00186 00187 IONGATE_TABLES(AhGate_Hoffman97); 00188 }; 00189 00190 00191 00193 class AChannel_Hoffman97 : public ActiveChannel { 00194 00195 DO_REGISTERING 00196 00197 public: 00198 00199 AChannel_Hoffman97(void) { 00200 addGate(new AmGate_Hoffman97); 00201 addGate(new AhGate_Hoffman97); 00202 00203 Erev = -80; // [mV] biological value 00204 // Transform to model voltage range 00205 TRANSFORM_EREV; 00206 } 00207 00208 virtual ~AChannel_Hoffman97(void) { 00209 for(int i=0;i<nGates;i++) 00210 delete gates[i]; 00211 } 00212 }; 00213 00215 class SICmGate_Maciokas02 : public VIonGate { 00216 public: 00217 SICmGate_Maciokas02(void) { k=1; } 00218 00219 double tau(double ) { return TSCALE*0.2e-6; } 00220 double infty(double V) { return 1/(1 + exp(-( VSCALE * (V - *Vresting) - 20)/2.5)); } 00221 00222 IONGATE_TABLES(SICmGate_Maciokas02); 00223 }; 00224 00226 class SIChGate_Maciokas02 : public VIonGate { 00227 public: 00228 SIChGate_Maciokas02(void) { k=1; } 00229 00230 double tau(double ) { return TSCALE*5e-6; } 00231 double infty(double V) { return 1/(1 + exp(( VSCALE * (V - *Vresting) - 15)/2.5)); } 00232 00233 IONGATE_TABLES(SIChGate_Maciokas02); 00234 }; 00235 00237 class SICChannel_Maciokas02 : public ActiveChannel { 00238 00239 DO_REGISTERING 00240 00241 public: 00242 00243 SICChannel_Maciokas02(void) { 00244 addGate(new SICmGate_Maciokas02); 00245 addGate(new SIChGate_Maciokas02); 00246 00247 Erev = -80; // [mV] biological value 00248 // Transform to model voltage range 00249 TRANSFORM_EREV; 00250 } 00251 00252 virtual ~SICChannel_Maciokas02(void) { 00253 for(int i=0;i<nGates;i++) 00254 delete gates[i]; 00255 } 00256 }; 00257 00258 00259 00260 //== Channels of neocortical pyramidal neurons from the SenseLab ModelDB archiv ======== 00261 00262 00263 00265 class AnGate_Korngreen02 : public VIonGate { 00266 public: 00267 AnGate_Korngreen02(void) { k=2;} 00268 00269 double tau(double V) { TRANSFORM_V; 00270 return (V < -50) ? 1e-3 * (1.25+175.03*exp(V*0.026)) : 1e-3 * (1.25+13*exp(-V*0.026)); } 00271 double infty(double V) { TRANSFORM_V; 00272 return 1/(1+exp(-(V+14)/14.6)); } 00273 00274 IONGATE_TABLES(AnGate_Korngreen02); 00275 }; 00276 00278 class AlGate_Korngreen02 : public VIonGate { 00279 public: 00280 AlGate_Korngreen02(void) { k=1; } 00281 00282 double tau(double V) { TRANSFORM_V; 00283 return 1e-3 * (360+(1010+24*(V+55))*exp(-pow((V+75)/48,2))); } 00284 double infty(double V) { TRANSFORM_V; 00285 return 1/(1+exp((V+54)/11)); } 00286 00287 IONGATE_TABLES(AlGate_Korngreen02); 00288 }; 00289 00290 00292 class AChannel_Korngreen02 : public ActiveChannel { 00293 00294 DO_REGISTERING 00295 00296 public: 00297 00298 AChannel_Korngreen02(void) { 00299 addGate(new AnGate_Korngreen02); 00300 addGate(new AlGate_Korngreen02); 00301 Ts = 1; 00302 Gbar = 8e-3*A_MEMBRANE; // [S/cm2]*[cm2] 00303 Erev = -80; // (original -90) [mV] biological value 00304 // Transform biological Erev value to model voltage range 00305 TRANSFORM_EREV; 00306 } 00307 00308 virtual ~AChannel_Korngreen02(void) { 00309 for(int i=0;i<nGates;i++) 00310 delete gates[i]; 00311 } 00312 00313 virtual int updateInternal(void); 00314 00316 double Ts; 00317 }; 00318 00319 00321 class KnGate_Korngreen02 : public VIonGate { 00322 public: 00323 KnGate_Korngreen02(void) { k=4;} 00324 00325 double tau(double V) { TRANSFORM_V; 00326 return 1e-3 * (0.34 + 0.92*exp(-pow((V+71)/59,2))); } 00327 double infty(double V) { TRANSFORM_V; 00328 return 1/(1+exp(-(V+47)/29)); } 00329 00330 IONGATE_TABLES(KnGate_Korngreen02); 00331 }; 00332 00334 class KlGate_Korngreen02 : public VIonGate { 00335 public: 00336 KlGate_Korngreen02(void) { k=1; } 00337 00338 double tau(double V) { TRANSFORM_V; 00339 return 1e-3 * (8 + 49*exp(-pow((V+73)/23,2))); } 00340 double infty(double V) { TRANSFORM_V; 00341 return 1/(1+exp((V+66)/10)); } 00342 00343 IONGATE_TABLES(KlGate_Korngreen02); 00344 }; 00345 00346 00348 class KChannel_Korngreen02 : public ActiveChannel { 00349 00350 DO_REGISTERING 00351 00352 public: 00353 00354 KChannel_Korngreen02(void) { 00355 addGate(new KnGate_Korngreen02); 00356 addGate(new KlGate_Korngreen02); 00357 Ts = 1; 00358 Gbar = 8e-3*A_MEMBRANE; // [S/cm2]*[cm2] 00359 00360 Erev = -80; // (original -90) [mV] biological value 00361 // Transform biological Erev value to model voltage range 00362 TRANSFORM_EREV; 00363 } 00364 00365 virtual ~KChannel_Korngreen02(void) { 00366 for(int i=0;i<nGates;i++) 00367 delete gates[i]; 00368 } 00369 00370 virtual int updateInternal(void); 00371 00373 double Ts; 00374 }; 00375 00376 00380 class NPmGate_McCormick92 : public VIonGate { 00381 public: 00382 NPmGate_McCormick92(void) { k=1; } 00383 00384 double alpha(double V) { TRANSFORM_V; 00385 return 1e3 * (0.091*(V+48)/(1.0-exp(-(V+48.0)/5.0))); } 00386 double beta(double V) { TRANSFORM_V; 00387 return 1e3 * (-0.062*(V+48.0)/(1.0-exp((V+48.0)/5.0))); } 00388 double infty(double V) { TRANSFORM_V; 00389 return 1.0/(1.0+exp(-(49.0+V)/5)); } 00390 00391 IONGATE_TABLES(NPmGate_McCormick92); 00392 }; 00393 00394 00398 class NPChannel_McCormick02 : public ActiveChannel { 00399 00400 DO_REGISTERING 00401 00402 public: 00403 00404 NPChannel_McCormick02(void) { 00405 addGate(new NPmGate_McCormick92); 00406 Ts = 1; 00407 Gbar = 2.2e-3*A_MEMBRANE; // [S/cm2]*[cm2] 00408 00409 Erev = 55.0; // [mV] biological value 00410 // Transform biological Erev value to model voltage range 00411 TRANSFORM_EREV; 00412 } 00413 00414 virtual ~NPChannel_McCormick02(void) { 00415 for(int i=0;i<nGates;i++) 00416 delete gates[i]; 00417 } 00418 00419 virtual int updateInternal(void); 00420 00422 double Ts; 00423 }; 00424 00425 00427 class MnGate_Mainen96 : public VIonGate { 00428 public: 00429 MnGate_Mainen96(void) { k=1; } 00430 00431 double alpha(double V) { TRANSFORM_V; 00432 return 1e3 * (0.001*(V+30)/(1-exp(-(V+30)/9))); } 00433 double beta(double V) { TRANSFORM_V; 00434 return 1e3 * (-0.001*(V+30)/(1-exp((V+30)/9))); } 00435 00436 IONGATE_TABLES(MnGate_Mainen96); 00437 }; 00438 00439 00441 class MChannel_Mainen96 : public ActiveChannel { 00442 00443 DO_REGISTERING 00444 00445 public: 00446 00447 MChannel_Mainen96(void) { 00448 addGate(new MnGate_Mainen96); 00449 Ts = 1; 00450 Gbar = 1e-3*A_MEMBRANE; // [S/cm2]*[cm2] 00451 00452 Erev = -80.0; // (original -90) [mV] biological value 00453 // Transform biological Erev value to model voltage range 00454 TRANSFORM_EREV; 00455 } 00456 00457 virtual ~MChannel_Mainen96(void) { 00458 for(int i=0;i<nGates;i++) 00459 delete gates[i]; 00460 } 00461 00462 virtual int updateInternal(void); 00463 00465 double Ts; 00466 }; 00467 00468 #define CELSIUS 30 00469 00471 class HnGate_Stuart98 : public VIonGate { 00472 public: 00473 HnGate_Stuart98(void) { k=1; } 00474 00475 double alpha(double V) { return exp(1e-3*3*(V+88)*9.648e4/(8.315*(273.16+CELSIUS))); } 00476 double beta(double V) { return exp(1e-3*3*0.4*(V+88)*9.648e4/(8.315*(273.16+CELSIUS))); } 00477 double tau(double V) { TRANSFORM_V; 00478 return 1e-3 * (beta(V)/(0.00057+0.00057*alpha(V))); } 00479 double infty(double V) { TRANSFORM_V; 00480 return 1/(1+alpha(V)); } 00481 00482 IONGATE_TABLES(HnGate_Stuart98); 00483 }; 00484 00485 00487 class HChannel_Stuart98 : public ActiveChannel { 00488 00489 DO_REGISTERING 00490 00491 public: 00492 00493 HChannel_Stuart98(void) { 00494 addGate(new HnGate_Stuart98); 00495 Ts = 1; 00496 Gbar = 3e-3*A_MEMBRANE; // [S/cm2]*[cm2] 00497 00498 Erev = -35.0; // [mV] biological value 00499 // Transform biological Erev value to model voltage range 00500 TRANSFORM_EREV; 00501 } 00502 00503 virtual ~HChannel_Stuart98(void) { 00504 for(int i=0;i<nGates;i++) 00505 delete gates[i]; 00506 } 00507 00508 virtual int updateInternal(void); 00509 00511 double Ts; 00512 }; 00513 00514 #define SECH(_V_) 2/(exp(2*_V_)+exp(-2*_V_)) 00515 00518 class HVACAuGate_Brown93 : public VIonGate { 00519 public: 00520 HVACAuGate_Brown93(void) { k=2;} 00521 00522 double tau(double V) { TRANSFORM_V; 00523 return 1e-3 * (1.25*SECH(-0.031*(V+37.1))); } 00524 double infty(double V) { TRANSFORM_V; 00525 return 1/(1+exp(-(V+24.6)/11.3)); } 00526 00527 IONGATE_TABLES(HVACAuGate_Brown93); 00528 }; 00529 00532 class HVACAvGate_Brown93 : public VIonGate { 00533 public: 00534 HVACAvGate_Brown93(void) { k=1; } 00535 00536 double tau(double V) { TRANSFORM_V; 00537 return 1e-3 * 420; } 00538 double infty(double V) { TRANSFORM_V; 00539 return 1/(1+exp((V+12.6)/18.9)); } 00540 00541 IONGATE_TABLES(HVACAvGate_Brown93); 00542 }; 00543 00544 00547 class HVACAChannel_Brown93 : public ActiveCaChannel { 00548 00549 DO_REGISTERING 00550 00551 public: 00552 00553 HVACAChannel_Brown93(void) { 00554 addGate(new HVACAuGate_Brown93); 00555 addGate(new HVACAvGate_Brown93); 00556 Ts = 1; 00557 Gbar = 0.3e-3*A_MEMBRANE; // [S/cm2]*[cm2] 00558 00559 Erev = 140; // [mV] biological value 00560 // Transform biological Erev value to model voltage range 00561 TRANSFORM_EREV; 00562 } 00563 00564 virtual ~HVACAChannel_Brown93(void) { 00565 for(int i=0;i<nGates;i++) 00566 delete gates[i]; 00567 } 00568 00569 virtual int updateInternal(void); 00570 00572 double Ts; 00573 }; 00574 00575 00577 class CALmGate_Destexhe98 : public VIonGate { 00578 public: 00579 CALmGate_Destexhe98(void) { k=2;} 00580 00581 double tau(double V) { TRANSFORM_V; 00582 return 1e-3 * 0.1; } /* Originally 0 */ 00583 double infty(double V) { TRANSFORM_V; 00584 return 1.0/(1+exp(-(V+57)/6.2)); } 00585 00586 IONGATE_TABLES(CALmGate_Destexhe98); 00587 }; 00588 00590 class CALhGate_Destexhe98 : public VIonGate { 00591 public: 00592 CALhGate_Destexhe98(void) { k=1; } 00593 00594 double tau(double V) { TRANSFORM_V; 00595 return 1e-3 * (30.8 + (211.4 + exp((V+113.2)/5))/(1+exp((V+84)/3.2))); } 00596 double infty(double V) { TRANSFORM_V; 00597 return 1.0/(1+exp((V+81)/4.0)); } 00598 00599 IONGATE_TABLES(CALhGate_Destexhe98); 00600 }; 00601 00602 00604 class CALChannel_Destexhe98 : public ActiveChannel { 00605 00606 DO_REGISTERING 00607 00608 public: 00609 00610 CALChannel_Destexhe98(void) { 00611 addGate(new CALmGate_Destexhe98); 00612 addGate(new CALhGate_Destexhe98); 00613 Ts = 1; 00614 Gbar = 2e-3*A_MEMBRANE; // [S/cm2]*[cm2] 00615 00616 Erev = 140; // [mV] biological value 00617 // Transform biological Erev value to model voltage range 00618 TRANSFORM_EREV; 00619 } 00620 00621 virtual ~CALChannel_Destexhe98(void) { 00622 for(int i=0;i<nGates;i++) 00623 delete gates[i]; 00624 } 00625 00626 virtual int updateInternal(void); 00627 00629 double Ts; 00630 }; 00631 00632 00634 class KCAnGate_Mainen96 : public ConcIonGate { 00635 public: 00636 KCAnGate_Mainen96(void) { k=1; ConcType=CA;} 00637 00638 00640 double alpha(double C) { return 0.01*C*1e3; } 00642 double beta(double ) { return 0.02; } 00643 00644 double tau(double C) { return 1e-3/(alpha(C) + beta(C)); } 00645 double infty(double C) { return alpha(C)/(alpha(C) + beta(C)); } 00646 00647 IONGATE_TABLES(KCAnGate_Mainen96); 00648 }; 00649 00650 00652 class KCAChannel_Mainen96 : public ActiveChannel { 00653 00654 DO_REGISTERING 00655 00656 public: 00657 00658 KCAChannel_Mainen96(void) { 00659 addGate(new KCAnGate_Mainen96); 00660 Ts = 1; 00661 Gbar = 1e-3*A_MEMBRANE; // [S/cm2]*[cm2] 00662 00663 Erev = -80; // (original -90) [mV] biological value 00664 // Transform biological Erev value to model voltage range 00665 TRANSFORM_EREV; 00666 } 00667 00668 virtual ~KCAChannel_Mainen96(void) { 00669 for(int i=0;i<nGates;i++) 00670 delete gates[i]; 00671 } 00672 00673 virtual int updateInternal(void); 00674 00676 double Ts; 00677 }; 00678 00679 00680 00681 00682 #endif 00683 00684 00685