22
22
23
23
import logging
24
24
logger_ = logging .getLogger ('moose.nml2' )
25
+ logger_ .setLevel (logging .INFO )
25
26
26
27
try :
27
28
import neuroml .loaders as loaders
@@ -49,6 +50,9 @@ def _unique(ls):
49
50
res .append (l )
50
51
return res
51
52
53
+ def _whichGate (chan ):
54
+ return chan .name [- 1 ]
55
+
52
56
def _isConcDep (ct ):
53
57
"""_isConcDep
54
58
Check if componet is dependant on concentration. Most HHGates are
@@ -59,19 +63,22 @@ def _isConcDep(ct):
59
63
60
64
:return: True if Component is depenant on conc, False otherwise.
61
65
"""
66
+ if not hasattr (ct , 'extends' ):
67
+ return False
62
68
if 'ConcDep' in ct .extends :
63
69
return True
64
70
return False
65
71
66
- def _findCaConcVariableName ():
67
- """_findCaConcVariableName
72
+
73
+ def _findCaConc ():
74
+ """_findCaConc
68
75
Find a suitable CaConc for computing HHGate tables.
69
76
This is a hack, though it is likely to work in most cases.
70
77
"""
71
78
caConcs = moose .wildcardFind ( '/library/##[TYPE=CaConc]' )
72
- assert len (caConcs ) > = 1 , "No moose.CaConc found. Currently moose \
79
+ assert len (caConcs ) = = 1 , "No moose.CaConc found. Currently moose \
73
80
supports HHChannel which depends only on moose.CaConc ."
74
- return caConcs [0 ]. name
81
+ return caConcs [0 ]
75
82
76
83
77
84
def sarea (comp ):
@@ -471,17 +478,36 @@ def calculateRateFn(self, ratefn, vmin, vmax, tablen=3000, vShift='0mV'):
471
478
logger_ .info ("Using %s to evaluate rate" % ct .name )
472
479
rate = []
473
480
for v in tab :
474
- # Note: MOOSE HHGate are either voltage of concentration
475
- # dependant. Here we figure out if nml description of gate is
476
- # concentration dependant or not.
477
- if _isConcDep (ct ):
478
- # Concentration dependant. Concentration can't be negative.
479
- # Find a suitable CaConc from the /library. Currently only
480
- # Ca dependant channels are allowed.
481
- caConcName = _findCaConcVariableName ()
482
- req_vars = {caConcName :'%g' % max (0 ,v ),'vShift' :vShift ,'temperature' :self ._getTemperature ()}
483
- else :
484
- req_vars .update ( self ._variables )
481
+ req_vars = {'v' :'%sV' % v ,'vShift' :vShift ,'temperature' :self ._getTemperature ()}
482
+ req_vars .update (self ._variables )
483
+ vals = pynml .evaluate_component (ct , req_variables = req_vars )
484
+ '''print(vals)'''
485
+ if 'x' in vals :
486
+ rate .append (vals ['x' ])
487
+ if 't' in vals :
488
+ rate .append (vals ['t' ])
489
+ if 'r' in vals :
490
+ rate .append (vals ['r' ])
491
+ return np .array (rate )
492
+
493
+ def calculateRateFnCaDep (self , ratefn , ca , camin , camax , tablen = 3000 , vShift = '0mV' ):
494
+ """Returns A / B table from ngate.
495
+
496
+ FIXME: Merge with calculateRateFn
497
+ """
498
+ tab = np .linspace (camin , camax , tablen )
499
+ if self ._is_standard_nml_rate (ratefn ):
500
+ midpoint , rate , scale = map (
501
+ SI , (ratefn .midpoint , ratefn .rate , ratefn .scale ))
502
+ return self .rate_fn_map [ratefn .type ](tab , rate , scale , midpoint )
503
+
504
+ for ct in self .doc .ComponentType :
505
+ if ratefn .type != ct .name :
506
+ continue
507
+ logger_ .info ("Using %s to evaluate rate (caConc dependant)" % ct .name )
508
+ rate = []
509
+ for v in tab :
510
+ req_vars = {ca .name :'%sV' % v ,'vShift' :vShift ,'temperature' :self ._getTemperature ()}
485
511
vals = pynml .evaluate_component (ct , req_variables = req_vars )
486
512
'''print(vals)'''
487
513
if 'x' in vals :
@@ -591,19 +617,23 @@ def _is_standard_nml_rate(self, rate):
591
617
def createHHChannel (self , chan , vmin = - 150e-3 , vmax = 100e-3 , vdivs = 5000 ):
592
618
mchan = moose .HHChannel ('%s/%s' % (self .lib .path , chan .id ))
593
619
mgates = map (moose .element , (mchan .gateX , mchan .gateY , mchan .gateZ ))
594
- assert (len (chan .gate_hh_rates ) <= 3
595
- ) # We handle only up to 3 gates in HHCHannel
620
+
621
+ # We handle only up to 3 gates in HHCHannel
622
+ assert (len (chan .gate_hh_rates ) <= 3 )
596
623
597
624
if self .verbose :
598
625
print ('== Creating channel: %s (%s) -> %s (%s)' %
599
626
(chan .id , chan .gate_hh_rates , mchan , mgates ))
600
627
all_gates = chan .gates + chan .gate_hh_rates
601
628
for ngate , mgate in zip (all_gates , mgates ):
602
- if mgate .name .endswith ('X' ):
629
+ if ngate is None :
630
+ continue
631
+ logger_ .info ('whichGate(mgate) %s %s' % (mgate , _whichGate (mgate )))
632
+ if _whichGate (mgate ) == 'X' :
603
633
mchan .Xpower = ngate .instances
604
- elif mgate . name . endswith ( 'Y' ) :
634
+ elif _whichGate ( mgate ) == 'Y' :
605
635
mchan .Ypower = ngate .instances
606
- elif mgate . name . endswith ( 'Z' ) :
636
+ elif _whichGate ( mgate ) == 'Z' :
607
637
mchan .Zpower = ngate .instance
608
638
mgate .min = vmin
609
639
mgate .max = vmax
@@ -638,14 +668,28 @@ def createHHChannel(self, chan, vmin=-150e-3, vmax=100e-3, vdivs=5000):
638
668
'Unknown Q10 scaling type %s: %s' %
639
669
(ngate .q10_settings .type , ngate .q10_settings ))
640
670
641
- if self .verbose :
642
- print (
643
- ' === Gate: %s; %s; %s; %s; %s; scale=%s' %
671
+ logger_ .info (' === Gate: %s; %s; %s; %s; %s; scale=%s' %
644
672
(ngate .id , mgate .path , mchan .Xpower , fwd , rev , q10_scale ))
645
673
674
+ print (fwd , rev )
675
+ quit ()
676
+
646
677
if (fwd is not None ) and (rev is not None ):
647
- alpha = self .calculateRateFn (fwd , vmin , vmax , vdivs )
648
- beta = self .calculateRateFn (rev , vmin , vmax , vdivs )
678
+ # Note: MOOSE HHGate are either voltage of concentration
679
+ # dependant. Here we figure out if nml description of gate is
680
+ # concentration dependant or not.
681
+ if not _isConcDep (fwd ):
682
+ alpha = self .calculateRateFn (fwd , vmin , vmax , vdivs )
683
+ else :
684
+ ca = _findCaConc ()
685
+ alpha = self .calculateRateFnCaDep (fwd , ca , vmin , vmax , vdivs )
686
+
687
+ if not _isConcDep (rev ):
688
+ beta = self .calculateRateFnCaDep (rev , vmin , vmax , vdivs )
689
+ else :
690
+ ca = _findCaConc ()
691
+ beta = self .calculateRateFn (rev , ca , vmin , vmax , vdivs )
692
+
649
693
mgate .tableA = q10_scale * (alpha )
650
694
mgate .tableB = q10_scale * (alpha + beta )
651
695
@@ -659,9 +703,8 @@ def createHHChannel(self, chan, vmin=-150e-3, vmax=100e-3, vdivs=5000):
659
703
mgate .tableA = q10_scale * (inf / tau )
660
704
mgate .tableB = q10_scale * (1 / tau )
661
705
662
- if hasattr (ngate ,
663
- 'steady_state' ) and (ngate .time_course is None ) and (
664
- ngate .steady_state is not None ):
706
+ if hasattr (ngate , 'steady_state' ) and (ngate .time_course is None ) \
707
+ and (ngate .steady_state is not None ):
665
708
inf = ngate .steady_state
666
709
tau = 1 / (alpha + beta )
667
710
if (inf is not None ):
0 commit comments