From 4a898adc06f41f05c13b64f911d0515685a84477 Mon Sep 17 00:00:00 2001 From: vvbragin Date: Tue, 10 Oct 2023 20:54:40 +0200 Subject: [PATCH] extracted conditions checking code to separate method --- netpyne/cell/cell.py | 31 ++----- netpyne/cell/compartCell.py | 158 ++++++------------------------------ netpyne/sim/utils.py | 37 +++++++++ 3 files changed, 72 insertions(+), 154 deletions(-) diff --git a/netpyne/cell/cell.py b/netpyne/cell/cell.py index 171438510..de12a5923 100644 --- a/netpyne/cell/cell.py +++ b/netpyne/cell/cell.py @@ -186,29 +186,8 @@ def recordTraces(self): conditionsMet = 1 if 'conds' in params: - for (condKey, condVal) in params['conds'].items(): # check if all conditions are met - # choose what to comapare to - if condKey in ['gid']: # CHANGE TO GID - compareTo = self.gid - else: - compareTo = self.tags[condKey] - - # check if conditions met - if isinstance(condVal, list) and isinstance(condVal[0], Number): - if compareTo == self.gid: - if compareTo not in condVal: - conditionsMet = 0 - break - elif compareTo < condVal[0] or compareTo > condVal[1]: - conditionsMet = 0 - break - elif isinstance(condVal, list) and isinstance(condVal[0], basestring): - if compareTo not in condVal: - conditionsMet = 0 - break - elif compareTo != condVal: - conditionsMet = 0 - break + conditionsMet = self.checkConditions(params['conds']) + if conditionsMet: try: ptr = None @@ -373,6 +352,12 @@ def recordTraces(self): # else: # if sim.cfg.verbose: print ' NOT recording ', key, 'from cell ', self.gid, ' with parameters: ',str(params) + + def checkConditions(self, conditions): + from ..sim.utils import checkConditions + return checkConditions(conditions=conditions, against=self.tags, cellGid=self.gid) + + def _randomizer(self): try: return self.__cellParamsRand diff --git a/netpyne/cell/compartCell.py b/netpyne/cell/compartCell.py index 39c3aa036..d0f1c4646 100644 --- a/netpyne/cell/compartCell.py +++ b/netpyne/cell/compartCell.py @@ -90,19 +90,7 @@ def create(self, createNEURONObj=None): for propLabel, prop in sim.net.params.cellParams.items(): # for each set of cell properties conditionsMet = 1 if 'conds' in prop and len(prop['conds']) > 0: - for (condKey, condVal) in prop['conds'].items(): # check if all conditions are met - if isinstance(condVal, list): - if isinstance(condVal[0], Number): - if self.tags.get(condKey) < condVal[0] or self.tags.get(condKey) > condVal[1]: - conditionsMet = 0 - break - elif isinstance(condVal[0], basestring): - if self.tags.get(condKey) not in condVal: - conditionsMet = 0 - break - elif self.tags.get(condKey) != condVal: - conditionsMet = 0 - break + conditionsMet = self.checkConditions(prop['conds']) elif self.tags['cellType'] != propLabel: # simplified method for defining cell params (when no 'conds') conditionsMet = False @@ -132,32 +120,14 @@ def create(self, createNEURONObj=None): def modify(self, prop): from .. import sim - conditionsMet = 1 - for (condKey, condVal) in prop['conds'].items(): # check if all conditions are met - if condKey == 'label': - if condVal not in self.tags['label']: - conditionsMet = 0 - break - elif isinstance(condVal, list): - if isinstance(condVal[0], Number): - if self.tags.get(condKey) < condVal[0] or self.tags.get(condKey) > condVal[1]: - conditionsMet = 0 - break - elif isinstance(condVal[0], basestring): - if self.tags.get(condKey) not in condVal: - conditionsMet = 0 - break - elif self.tags.get(condKey) != condVal: - conditionsMet = 0 - break + conditionsMet = self.checkConditions(prop['conds']) if conditionsMet: # if all conditions are met, set values for this cell if sim.cfg.createPyStruct: self.createPyStruct(prop) if sim.cfg.createNEURONObj: - self.createNEURONObj( - prop - ) # add sections, mechanisms, synaptic mechanisms, geometry and topolgy specified by this property set + # add sections, mechanisms, synaptic mechanisms, geometry and topolgy specified by this property set + self.createNEURONObj(prop) def createPyStruct(self, prop): from .. import sim @@ -847,45 +817,28 @@ def modifySynMechs(self, params): conditionsMet = 1 if 'cellConds' in params: - if conditionsMet: - for (condKey, condVal) in params['cellConds'].items(): # check if all conditions are met - # check if conditions met - if isinstance(condVal, list): - if self.tags.get(condKey) < condVal[0] or self.tags.get(condKey) > condVal[1]: - conditionsMet = 0 - break - elif self.tags.get(condKey) != condVal: - conditionsMet = 0 - break + conditionsMet = self.checkConditions(params['cellConds']) if conditionsMet: for secLabel, sec in self.secs.items(): for synMech in sec['synMechs']: conditionsMet = 1 if 'conds' in params: - for (condKey, condVal) in params['conds'].items(): # check if all conditions are met - # check if conditions met - if condKey == 'sec': - if condVal != secLabel: - conditionsMet = 0 - break - elif isinstance(condVal, list) and isinstance(condVal[0], Number): - if synMech.get(condKey) < condVal[0] or synMech.get(condKey) > condVal[1]: - conditionsMet = 0 - break - elif isinstance(condVal, list) and isinstance(condVal[0], basestring): - if synMech.get(condKey) not in condVal: - conditionsMet = 0 - break - elif synMech.get(condKey) != condVal: - conditionsMet = 0 - break + # first check if section matches + secLabelInConds = params['conds'].get('sec') + if secLabelInConds and (secLabelInConds != secLabel): + # skip to next section + break + + # then check the rest of conds + synMechConds = deepcopy(params['conds']) + synMechConds.pop('sec') + conditionsMet = sim.utils.checkConditions(synMechConds, against=synMech) if conditionsMet: # if all conditions are met, set values for this cell exclude = ['conds', 'cellConds'] + SynMechParams.reservedKeys() - for synParamName, synParamValue in { - k: v for k, v in params.items() if k not in exclude - }.items(): + paramsToModify = {k: v for k, v in params.items() if k not in exclude} + for synParamName, synParamValue in paramsToModify.items(): if sim.cfg.createPyStruct: synMech[synParamName] = synParamValue if sim.cfg.createNEURONObj: @@ -1198,59 +1151,22 @@ def modifyConns(self, params): conditionsMet = 1 if 'conds' in params: - for (condKey, condVal) in params['conds'].items(): # check if all conditions are met - # choose what to comapare to - if condKey in ['postGid']: - compareTo = self.gid - else: - compareTo = conn.get(condKey) + conds = params['conds'] - # check if conditions met - if isinstance(condVal, list) and isinstance(condVal[0], Number): - if compareTo < condVal[0] or compareTo > condVal[1]: - conditionsMet = 0 - break - elif isinstance(condVal, list) and isinstance(condVal[0], basestring): - if compareTo not in condVal: - conditionsMet = 0 - break - elif compareTo != condVal: - conditionsMet = 0 - break + # `conds` may contain `postGid` key, which is deprecated in favour of having `gid` key in `postConds`, + # but for backward compatibility, try to detect it here and replace with `gid`, so checkConditions() can process it: + if 'postGid' in conds: + conds['gid'] = conds.pop('postGid') + conditionsMet = sim.utils.checkConditions(conds, against=conn, cellGid=self.gid) if conditionsMet and 'postConds' in params: - for (condKey, condVal) in params['postConds'].items(): # check if all conditions are met - # check if conditions met - if isinstance(condVal, list) and isinstance(condVal[0], Number): - if self.tags.get(condKey) < condVal[0] or self.tags.get(condKey) > condVal[1]: - conditionsMet = 0 - break - elif isinstance(condVal, list) and isinstance(condVal[0], basestring): - if self.tags.get(condKey) not in condVal: - conditionsMet = 0 - break - elif self.tags.get(condKey) != condVal: - conditionsMet = 0 - break + conditionsMet = self.checkConditions(params['postConds']) if conditionsMet and 'preConds' in params: try: cell = sim.net.cells[conn['preGid']] - if cell: - for (condKey, condVal) in params['preConds'].items(): # check if all conditions are met - # check if conditions met - if isinstance(condVal, list) and isinstance(condVal[0], Number): - if cell.tags.get(condKey) < condVal[0] or cell.tags.get(condKey) > condVal[1]: - conditionsMet = 0 - break - elif isinstance(condVal, list) and isinstance(condVal[0], basestring): - if cell.tags.get(condKey) not in condVal: - conditionsMet = 0 - break - elif cell.tags.get(condKey) != condVal: - conditionsMet = 0 - break + conditionsMet = cell.checkConditions(params['preConds']) except: pass # print('Warning: modifyConns() does not yet support conditions of presynaptic cells when running parallel sims') @@ -1279,34 +1195,14 @@ def modifyStims(self, params): conditionsMet = 1 if 'cellConds' in params: if conditionsMet: - for (condKey, condVal) in params['cellConds'].items(): # check if all conditions are met - # check if conditions met - if isinstance(condVal, list): - if self.tags.get(condKey) < condVal[0] or self.tags.get(condKey) > condVal[1]: - conditionsMet = 0 - break - elif self.tags.get(condKey) != condVal: - conditionsMet = 0 - break + conditionsMet = self.checkConditions(params['cellConds']) if conditionsMet == 1: for stim in self.stims: conditionsMet = 1 if 'conds' in params: - for (condKey, condVal) in params['conds'].items(): # check if all conditions are met - # check if conditions met - if isinstance(condVal, list) and isinstance(condVal[0], Number): - if stim.get(condKey) < condVal[0] or stim.get(condKey) > condVal[1]: - conditionsMet = 0 - break - elif isinstance(condVal, list) and isinstance(condVal[0], basestring): - if stim.get(condKey) not in condVal: - conditionsMet = 0 - break - elif stim.get(condKey) != condVal: - conditionsMet = 0 - break + conditionsMet = sim.utils.checkConditions(params['conds'], against=stim) if conditionsMet: # if all conditions are met, set values for this cell if stim['type'] == 'NetStim': # for netstims, find associated netcon diff --git a/netpyne/sim/utils.py b/netpyne/sim/utils.py index 6bc0a37a9..e408bfec8 100644 --- a/netpyne/sim/utils.py +++ b/netpyne/sim/utils.py @@ -1017,6 +1017,43 @@ def clearAll(): gc.collect() +def checkConditions(conditions, against, cellGid=None): + + conditionsMet = 1 + for (condKey, condVal) in conditions.items(): + + # gid matching will be processed in specific way + gidCompare = False + if (cellGid is not None) and (condKey == 'gid'): + compareTo = cellGid + gidCompare = True + + else: + compareTo = against.get(condKey) + + if isinstance(condVal, list): + if isinstance(condVal[0], Number): + if gidCompare: + if compareTo not in condVal: + conditionsMet = 0 + break + elif compareTo < condVal[0] or compareTo > condVal[1]: + conditionsMet = 0 + break + elif isinstance(condVal[0], basestring): + if compareTo not in condVal: + conditionsMet = 0 + break + elif isinstance(compareTo, list): # e.g. to match 'label', which may be list + if condVal not in compareTo: + conditionsMet = 0 + break + elif compareTo != condVal: + conditionsMet = 0 + break + return conditionsMet + + # ------------------------------------------------------------------------------ # Create a subclass of json.JSONEncoder to convert numpy types in Python types # ------------------------------------------------------------------------------