4747os .chdir (constants .NETPYNE_WORKDIR_PATH )
4848
4949
50+ class NetpyneValidationError (Exception ):
51+ ...
52+
53+
54+ def deepcopy_wout_empty (d , memo = None ):
55+ def is_empty (x ):
56+ return x == '' or x == [] or x == () or x == set () or x == {} or x is None
57+
58+ # if is_empty(d):
59+ # return None
60+ memo = {} if memo is None else memo
61+ if id (d ) in memo :
62+ return memo [id (d )]
63+ if isinstance (d , dict ):
64+ cpy = {}
65+ for k , v in d .items ():
66+ v_cpy = deepcopy_wout_empty (v , memo = memo )
67+ if is_empty (v_cpy ):
68+ continue
69+ cpy [k ] = memo .setdefault (id (v ), v_cpy )
70+ return cpy
71+ elif isinstance (d , (list , set , tuple )):
72+ return d .__class__ (memo .setdefault (id (v ), deepcopy_wout_empty (v , memo = memo )) for v in d if not is_empty (v ))
73+ elif hasattr (d , '__dict__' ):
74+ cpy = d .__new__ (d .__class__ ) # We skip the initializer, in case it needs some arguments
75+ for k , v in d .__dict__ .items ():
76+ v_cpy = deepcopy_wout_empty (v , memo = memo )
77+ # if is_empty(v_cpy): #
78+ # continue
79+ cpy .__dict__ [k ] = memo .setdefault (id (v ), v_cpy )
80+ return cpy
81+ return d
82+
83+
5084class NetPyNEGeppetto :
5185
5286 def __init__ (self ):
@@ -185,6 +219,11 @@ def instantiateNetPyNEModelInGeppetto(self, args):
185219 self .geppetto_model = self .model_interpreter .getGeppettoModel (netpyne_model )
186220
187221 return json .loads (GeppettoModelSerializer .serialize (self .geppetto_model ))
222+ except NetpyneValidationError as e :
223+ message = ("Error while validating the NetPyNE model before instantiation.\n "
224+ "One or more components in your model have issues, see details below:" )
225+ logging .exception (message )
226+ return utils .getJSONError (message , '\n ' .join (e .args ))
188227 except Exception as e :
189228 message = "Error while instantiating the NetPyNE model"
190229 logging .exception (message )
@@ -256,6 +295,26 @@ def simulate_single_model(self, experiment: model.Experiment = None, use_prev_in
256295 response = json .loads (GeppettoModelSerializer .serialize (self .geppetto_model ))
257296 return response
258297
298+
299+ def validate_netParams (self ):
300+ cpy = deepcopy_wout_empty (self .netParams )
301+ _ , failed = sim .validator .validateNetParams (cpy )
302+ if failed :
303+ message = ""
304+ components_error = {}
305+ for entry in failed :
306+ components_error .setdefault (entry .component , []).append ((entry .keyPath , entry .summary ))
307+ for component , details in components_error .items ():
308+ message = message + f"* Error validating { component } \n "
309+ for (keyPath , summary ) in details :
310+ path = ' -> ' .join (f"{ key } " for key in keyPath )
311+ message = message + f" Error in { path } \n "
312+ for line in summary :
313+ message = message + f" { line } \n "
314+ message = message + "\n "
315+ raise NetpyneValidationError (message )
316+
317+
259318 def simulateNetPyNEModelInGeppetto (self , args ):
260319 """ Starts simulation of the currently loaded NetPyNe model.
261320
@@ -270,8 +329,9 @@ def simulateNetPyNEModelInGeppetto(self, args):
270329 allTrials = args .get ('allTrials' , True )
271330 use_prev_inst = args .get ('usePrevInst' , False )
272331 sim_id = args .get ('simId' , 0 )
273-
274332 try :
333+ self .validate_netParams ()
334+
275335 experiment = experiments .get_current ()
276336 if experiment :
277337 if self .experiments .any_in_state ([model .ExperimentState .PENDING , model .ExperimentState .SIMULATING ]):
@@ -300,6 +360,11 @@ def simulateNetPyNEModelInGeppetto(self, args):
300360
301361 else :
302362 return self .simulate_single_model (use_prev_inst = use_prev_inst )
363+ except NetpyneValidationError as e :
364+ message = (f"Error while validating the NetPyNE model before simulation { sim_id } .\n "
365+ "One or more components in your model have issues, see details below:" )
366+ logging .exception (message )
367+ return utils .getJSONError (message , '\n ' .join (e .args ))
303368
304369 except Exception as e :
305370 message = f"Error while simulating the NetPyNE model: { e } . SimulationId { sim_id } "
@@ -740,6 +805,7 @@ def deleteModel(self, modelParams):
740805 return utils .getJSONReply ()
741806
742807 def instantiateNetPyNEModel (self ):
808+ self .validate_netParams ()
743809 with redirect_stdout (sys .__stdout__ ):
744810 saveData = sim .allSimData if hasattr (sim , 'allSimData' ) and 'spkt' in sim .allSimData .keys () and len (
745811 sim .allSimData ['spkt' ]) > 0 else False
@@ -774,7 +840,8 @@ def doIhaveInstOrSimData(self):
774840 return {'haveInstance' : out [0 ], 'haveSimData' : out [1 ]}
775841
776842 def rename (self , path , oldValue , newValue ):
777- command = 'sim.rename(self.' + path + ',"' + oldValue + '","' + newValue + '")'
843+ # command = 'sim.rename(self.' + path + ',"' + oldValue + '","' + newValue + '")'
844+ command = f'sim.rename(self.{ path } , { oldValue !r} , { newValue !r} )'
778845 logging .debug ('renaming ' + command )
779846
780847 eval (command )
@@ -912,11 +979,15 @@ def getAvailableCellModels(self):
912979 cell_models .add (cm )
913980 return list (cell_models )
914981
915- def getAvailableCellTypes (self ):
916- cell_types = set ([])
917- for p in self .netParams .cellParams :
918- cell_types .add (p )
919- return list (cell_types )
982+ def getAvailableCellModels (self ):
983+ return ["" , "VecStim" , "NetStim" , "IntFire1" ]
984+
985+ def getAvailableStimulationDistribution (self ):
986+ return ["normal" , "uniform" ]
987+
988+ def getAvailableStimulationPattern (self ):
989+ # self.netParams.popParams[name]['spikePattern'] = {}
990+ return ["" , "rhythmic" , "evoked" , "poisson" , "gauss" ]
920991
921992 def getAvailableSections (self ):
922993 sections = {}
0 commit comments