Skip to content

Commit f82804a

Browse files
committed
HillTau fixes: less memory leak, go faster over settle phase of runs.
1 parent 9bc71b5 commit f82804a

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

findSim.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ def load( findsim ):
190190
load = staticmethod( load )
191191

192192
def minInterval( self ):
193+
"""
194+
This function checks if stim steps up from zero at t>0.
195+
I think for plotting? Maybe for numerical stability. Either way,
196+
it inserts a very small nonzero value just before the step.
197+
"""
193198
ret = 1000.0
194199
lastt = 0.0
195200
lastval = 0.0
@@ -208,9 +213,9 @@ def minInterval( self ):
208213
if (not isElec) and (t - lastt) >= 100.0 and lastval < 1e-7 and val > 0.5e-4:
209214
# Have to insert intermediate step in data.
210215
newdata.append( [float(d[0]), 1e-6 / self.quantityScale] )
211-
newt = t + (t - lastt)/( 100.0 * self.timeScale )
216+
newt = t + (t - lastt)/100.0
212217
#print( "inserting: ", [d[0], 1e-6], [newt, d[1]] )
213-
newdata.append( [newt, d[1]] )
218+
newdata.append( [newt/self.timeScale, d[1]] )
214219
ret = min( ret, (t - lastt)/100.0 )
215220
else:
216221
newdata.append( [d[0], d[1]] )
@@ -1002,7 +1007,7 @@ def __lt__( self, other ):
10021007

10031008
def putStimsInQ( q, stims, pauseHsolve ):
10041009
for i in stims:
1005-
isElec = i.field in ['Im', 'current', 'Vclamp'] or (i.field=='rate' and 'syn' in i.entities[0])
1010+
isElec = i.field in ['Im', 'current', 'Vclamp'] or (i.field=='rate' and 'syn' in i.entity['name'])
10061011
for j in i.data:
10071012
if len(j) == 0:
10081013
continue
@@ -1147,7 +1152,8 @@ def parseAndRun( model, stims, readouts, getPlots = False ):
11471152
currt = sw.getCurrentTime()
11481153
if ( qe.t > currt ):
11491154
#print( "currt={:.4f}, qt={:.4f}".format( currt, qe.t) )
1150-
sw.advanceSimulation( qe.t - currt, doPlot = getPlots )
1155+
sw.advanceSimulation( qe.t - currt, doPlot = getPlots,
1156+
doSettle = (i==0) )
11511157
if isinstance( qe.entry, Stimulus ):
11521158
sw.deliverStim( qe )
11531159
#print( "DELIVER STIM {} {} {} {}".format( qe.entry.entities, qe.entry.field, qe.entry.data, qe.val ) )
@@ -1502,9 +1508,9 @@ def runit( expt, model, stims, readouts, getPlots = False ):
15021508
def getInitParams( modelFile, mapFile, paramList ):
15031509
# ParamList as strings of objpath.field
15041510
if modelFile.split('.')[-1] == "json":
1505-
sw = SimWrapHillTau( mapFile = mapFile, ignoreMissingObj = False, silent = False, exptFile = "" )
1511+
sw = SimWrapHillTau( mapFile = mapFile, ignoreMissingObj = False, silent = False, exptFile = "getInitParams" )
15061512
else:
1507-
sw = SimWrapMoose( mapFile = mapFile, ignoreMissingObj = False, silent = False, exptFile = "" )
1513+
sw = SimWrapMoose( mapFile = mapFile, ignoreMissingObj = False, silent = False, exptFile = "getInitParams" )
15081514

15091515
sw.deleteSimulation()
15101516
sw.loadModelFile( modelFile, silentDummyModify, [], "", "" )
@@ -1565,6 +1571,9 @@ def innerMain( exptFile, scoreFunc = defaultScoreFunc, modelFile = "", mapFile =
15651571
readouts.tabulateOutput = tabulateOutput
15661572
readouts.generate = generate
15671573

1574+
if not silent:
1575+
print( "FindSim: doing expt ", exptFile )
1576+
15681577
if mapFile != "":
15691578
mapFile = mapFile
15701579
else:

simWrapHillTau.py

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -527,11 +527,59 @@ def makeReadoutPlots( self, readouts ):
527527
self.numMainPlots = numPlots
528528
self.plots = [[]]*numPlots
529529

530-
def fillPlots( self ): # takes plots from sim and puts the numpy arrays of the plot values from sim into the return. Also returns main plot dt as a float, and the number of main plots.
530+
def old_fillPlots( self ):
531+
# takes plots from sim and puts the numpy arrays of the plot values from sim into the return. Also returns main plot dt as a float, and the number of main plots.
531532
tempArray = np.array(self.model.plotvec).transpose()
532533
for index, plotNum in self.plotPath.values():
533534
self.plots[plotNum] = tempArray[index]
534535
return [ np.array( i ) for i in self.plots], [self.plotDt] * len( self.plots ), self.numMainPlots
536+
537+
def fillPlots(self):
538+
"""
539+
takes plots from sim and puts the numpy arrays of the plot values from
540+
sim into the return. Also returns main plot dt as a float, and the
541+
number of main plots.
542+
Optimized using AI.
543+
"""
544+
tempArray = np.array(self.model.plotvec).transpose()
545+
546+
# If there are no plots specified, return early.
547+
if not self.plotPath:
548+
return [], [], self.numMainPlots
549+
550+
# Get the desired row indices and their corresponding plot numbers.
551+
# We assume self.plotPath.values() yields (index, plotNum) tuples.
552+
path_values = list(self.plotPath.values())
553+
indices_to_select = [item[0] for item in path_values]
554+
plot_num_keys = [item[1] for item in path_values]
555+
556+
# Use advanced indexing to select all required plots in a single operation.
557+
# This creates one new, compact array with only the data you need.
558+
selected_plots = tempArray[indices_to_select]
559+
560+
# Populate self.plots with views into the selected_plots array.
561+
# This avoids creating a new copy for each plot.
562+
for i, key in enumerate(plot_num_keys):
563+
self.plots[key] = selected_plots[i]
564+
565+
# The original function returned a list of 1D arrays.
566+
# `list(selected_plots)`
567+
# does this efficiently without making a final, unnecessary copy.
568+
output_plots = list(selected_plots)
569+
570+
return output_plots, [self.plotDt] * len(output_plots), self.numMainPlots
571+
572+
573+
574+
575+
576+
577+
578+
579+
580+
581+
582+
535583

536584
def deliverStim( self, qe ):
537585
field = qe.entry.field
@@ -668,7 +716,7 @@ def getObjParam( self, entity, field, isSilent = False ):
668716
if not entity in self.modelLookup:
669717
if self.ignoreMissingObj or isSilent:
670718
return -2.0
671-
raise SimError( "SimWrapHillTau::getObjParam: Entity {} not found".format( entity ) )
719+
raise SimError( "SimWrapHillTau::getObjParam: {}: Entity {} not found".format( self.exptFile, entity ) )
672720
elms = self.modelLookup[entity]
673721
if len( elms ) != 1:
674722
if isSilent:
@@ -727,7 +775,7 @@ def steadyStateStims(self, stimList, responseList, isSeries = False, settleTime
727775
self.setField( elm, "conc", value * scale )
728776
self.setField( elm, "concInit", value * scale )
729777
self.reinitSimulation()
730-
self.advanceSimulation( settleTime, doPlot = False )
778+
self.advanceSimulation( settleTime, doPlot = False, doSettle = True )
731779
for elm, field, oldval in orig:
732780
self.setField( elm, field, oldval )
733781
if field == 'conc':

0 commit comments

Comments
 (0)