|
13 | 13 |
|
14 | 14 | import os |
15 | 15 | import math |
| 16 | +import logging |
16 | 17 | import numpy as np |
17 | 18 | import moose |
18 | 19 |
|
19 | | -import logging |
| 20 | + |
20 | 21 | logger_ = logging.getLogger('moose.nml2') |
21 | 22 |
|
22 | | -import neuroml as nml |
23 | | -import pyneuroml.pynml as pynml |
| 23 | + |
| 24 | +nml_not_available_msg = '' |
| 25 | + |
| 26 | +try: |
| 27 | + import neuroml as nml |
| 28 | + import pyneuroml.pynml as pynml |
| 29 | +except ImportError as error: |
| 30 | + raise ImportError(f'Could not import neuroml/pyneuroml. Please make sure you have pyneuroml installed (`pip install pyneuroml`)') from error |
| 31 | + |
| 32 | + |
24 | 33 | from moose.neuroml2.units import SI |
25 | 34 |
|
| 35 | + |
26 | 36 | def _write_flattened_nml( doc, outfile ): |
27 | 37 | """_write_flattened_nml |
28 | 38 | Concat all NML2 read by moose and generate one flattened NML file. |
@@ -68,14 +78,15 @@ def _unique( ls ): |
68 | 78 |
|
69 | 79 | def _isConcDep(ct): |
70 | 80 | """_isConcDep |
71 | | - Check if componet is dependant on concentration. Most HHGates are |
72 | | - dependant on voltage. |
| 81 | + Check if componet is dependent on concentration. Most HHGates are |
| 82 | + dependent on voltage. |
73 | 83 |
|
74 | 84 | :param ct: ComponentType |
75 | 85 | :type ct: nml.ComponentType |
76 | 86 |
|
77 | 87 | :return: True if Component is depenant on conc, False otherwise. |
78 | 88 | """ |
| 89 | + # logger_.debug(f"{'#' * 10} EXTENDS {ct.extends}") |
79 | 90 | if 'ConcDep' in ct.extends: |
80 | 91 | return True |
81 | 92 | return False |
@@ -209,6 +220,7 @@ def read(self, filename, symmetric=True): |
209 | 220 | self.importInputs(self.doc) |
210 | 221 |
|
211 | 222 | for cell in self.doc.cells: |
| 223 | + # logger_.debug(f"{'%' * 10} Creating cell prototype {cell}") |
212 | 224 | self.createCellPrototype(cell, symmetric=symmetric) |
213 | 225 |
|
214 | 226 | if len(self.doc.networks)>=1: |
@@ -427,10 +439,15 @@ def copySpecies(self, species, compartment): |
427 | 439 | raise RuntimeError(msg) |
428 | 440 | pool_id = moose.copy(proto_pool, compartment, species.id) |
429 | 441 | pool = moose.element(pool_id) |
430 | | - pool.B = pool.B / (np.pi * compartment.length * ( |
| 442 | + # print('&' * 10, compartment.path, compartment.length, compartment.diameter, pool.thick) |
| 443 | + if compartment.length <= 0: |
| 444 | + vol = 4 * np.pi * (0.5 * compartment.diameter**3 - (0.5 * compartment.diameter - pool.thick)**3) / 3 |
| 445 | + else: |
| 446 | + vol = (np.pi * compartment.length * ( |
431 | 447 | 0.5 * compartment.diameter + pool.thick) * |
432 | 448 | (0.5 * compartment.diameter - pool.thick) |
433 | 449 | ) |
| 450 | + pool.B = pool.B / vol |
434 | 451 | return pool |
435 | 452 |
|
436 | 453 | def importAxialResistance(self, nmlcell, intracellularProperties): |
@@ -475,18 +492,20 @@ def calculateRateFn(self, ratefn, vmin, vmax, tablen=3000, vShift='0mV'): |
475 | 492 | if ratefn.type != ct.name: |
476 | 493 | continue |
477 | 494 |
|
478 | | - logger_.info("Using %s to evaluate rate"%ct.name) |
| 495 | + logger_.info(f"Using %s to evaluate rate"%ct.name) |
479 | 496 | rate = [] |
480 | 497 | for v in tab: |
481 | | - # Note: MOOSE HHGate are either voltage of concentration |
482 | | - # dependant. Here we figure out if nml description of gate is |
483 | | - # concentration dependant or note. |
| 498 | + # Note: MOOSE HHGate are voltage and/or concentration |
| 499 | + # dependent. Here we figure out if nml description of gate is |
| 500 | + # concentration dependent or not. |
| 501 | + # logger_.debug(f"{'#' * 5} {_isConcDep(ct)}") |
484 | 502 | if _isConcDep(ct): |
485 | | - # Concentration dependant. Concentration can't be negative. |
| 503 | + # Concentration dependent. Concentration can't be negative. |
486 | 504 | # Find a suitable CaConc from the /library. Currently on Ca |
487 | | - # dependant channels are allowed. |
| 505 | + # dependent channels are allowed. |
488 | 506 | caConcName = _findCaConcVariableName() |
489 | | - req_vars = {caConcName:'%g'%max(0,v),'vShift':vShift,'temperature':self._getTemperature()} |
| 507 | + req_vars = {'v': '0.0V', 'caConc':f'{max(1e-11,v):g}', caConcName:f'{max(1e-11,v):g}','vShift':vShift,'temperature':self._getTemperature()} |
| 508 | + # logger_.debug(f"{'A' * 30} {req_vars}") |
490 | 509 | else: |
491 | 510 | req_vars = {'v':'%sV'%v,'vShift':vShift,'temperature':self._getTemperature()} |
492 | 511 | req_vars.update( self._variables ) |
@@ -669,6 +688,7 @@ def importInputs(self, doc): |
669 | 688 | pg.firstWidth = SI(pg_nml.duration) |
670 | 689 | pg.firstLevel = SI(pg_nml.amplitude) |
671 | 690 | pg.secondDelay = 1e9 |
| 691 | + logger_.debug(f'{"$" * 10} Created input {epath}') |
672 | 692 |
|
673 | 693 |
|
674 | 694 | def importIonChannels(self, doc, vmin=-150e-3, vmax=100e-3, vdivs=5000): |
@@ -707,6 +727,6 @@ def createDecayingPoolConcentrationModel(self, concModel): |
707 | 727 | # shell and d is thickness - must divide by |
708 | 728 | # shell volume when copying |
709 | 729 | self.proto_pools[concModel.id] = ca |
710 | | - self.nml_concs_to_moose[concModel.id] = ca |
| 730 | + self.nml_conc_to_moose[concModel.id] = ca |
711 | 731 | self.moose_to_nml[ca] = concModel |
712 | 732 | logger_.debug('Created moose element: %s for nml conc %s' % (ca.path, concModel.id)) |
0 commit comments