From c734b8dd09851ffbed9a0ebd7f34cf5f9b9e0f72 Mon Sep 17 00:00:00 2001 From: Melanie Stefan Date: Mon, 14 May 2018 13:12:58 +0100 Subject: [PATCH 01/28] Update README.md Included link to Moose installation instructions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 62a1608..53316da 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Quick start: A. Run one of the example experiments on the default model, generating a graph to compare model to experiment: -1. Install MOOSE +1. Install MOOSE (Instructions can be found here: http://moose.readthedocs.io/en/latest/install/install.html ) 2. Install FindSim: git clone https://github.com/BhallaLab/FindSim 3. Navigate to release or to development branch, e.g., From cb28da11c916aff2b6f9ed2458e4bcbfd760adc9 Mon Sep 17 00:00:00 2001 From: bhalla Date: Wed, 21 Nov 2018 16:55:58 +0530 Subject: [PATCH 02/28] Added framework for fEPSP to findSim. Added a demo in TestTSV --- TestTSV/fepsp.tsv | 80 +++++++++++++++++++++++++++++++++++++++++++++++ findSim.py | 76 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 TestTSV/fepsp.tsv diff --git a/TestTSV/fepsp.tsv b/TestTSV/fepsp.tsv new file mode 100644 index 0000000..9991353 --- /dev/null +++ b/TestTSV/fepsp.tsv @@ -0,0 +1,80 @@ +Experiment metadata +transcriber Upi +organization NCBS +emailId bhalla@ncbs.res.in +exptSource None +citationId None +authors None +journal None. This is a purely fictional _experiment_ for the purposes of testing findSim + + +Experiment context +exptType TimeSeries +species rat +cell-types hippocampal CA1 pyramidal neuron +temperature (Celsius) 30 +Include all +details +notes HFS, LTP + +Stimuli +compartment dend +timeUnits sec +quantityUnits Hz +entities synInput +field rate +Data +Time Value +0 0 +10 100 +11 0 + +Stimuli +compartment dend +timeUnits sec +quantityUnits ratio +entities synapse +field weight +Data +Time Value +0 1 +10 1 +11 0.4 + + +Readouts +timeUnits sec +quantityUnits mV +useXlog FALSE +useYlog FALSE +ratioReferenceTime 1 +ratioReferenceEntity soma +entities soma +field fEPSP_peak +useNormalization False +Data +Time Value stderr +6 0.2 0 +8 0.2 0 +15 0.6 0 +16 0.62 0 +17 0.7 0 +18 0.8 0 +20 0.9 0 + +Model mapping +modelSource internal +fileName models/plastic8.py +citationId +citation +authors +modelSubset all +modelLookup soma:elec/soma,synInput:elec/head0/glu/sh/synapse/synInput,synapse:elec/head0/glu/sh/synapse +scoringFormula abs((expt-sim)/(datarange+1e-9)) +solver none +notes +# Monitor response with a low stimulus amplitude/weight with initial +# test pulses 4 and 8 sec. Then give a 100Hz synaptic input at t = 10-11s. +# Then monitor response at 15, 20 s. + + diff --git a/findSim.py b/findSim.py index 19bd2ae..1e3f696 100644 --- a/findSim.py +++ b/findSim.py @@ -61,10 +61,14 @@ epspFields = [ 'EPSP_peak', 'EPSP_slope', 'IPSP_peak', 'IPSP_slope' ] epscFields = [ 'EPSC_peak', 'EPSC_slope', 'IPSC_peak', 'IPSC_slope' ] +fepspFields = [ 'fEPSP_peak', 'fEPSP_slope', 'fIPSP_peak', 'fIPSP_slope' ] elecFields = ['Vm', 'Im', 'current'] + epspFields + epscFields elecDt = 50e-6 elecPlotDt = 100e-6 +fepspScale = 4000.0 # Arb scaling. Need to figure out how to set, + # Obviously a function of stimulus strength but the experimentalist + # also typically adjusts stim to get response into a 'useful' range. def keywordMatches( k, m ): @@ -263,6 +267,9 @@ def __init__( self, """Dict of continuous, fine-timeseries plots for readouts, only activated in single-run mode""" self.epspFreq = 100.0 # Used to generate a single synaptic event self.epspWindow = 0.02 # Time of epspPlot to scan for peak/slope + self.ex = 0.0005 # Electrode position for field recordings. + self.ey = 0.0 + self.ez = 0.0 def configure( self, modelLookup ): """Sanity check on all fields. First, check that all the entities @@ -293,6 +300,10 @@ def displayPlots( self, fname, modelLookup, stim, hideSubplots, exptType ): tsUnits = 'mV' elif self.field in epscFields: tsUnits = 'pA' + elif self.field in fepspFields: + if not hideSubplots: + self.plotFepsps( fname ) + return elif self.useNormalization and abs(self._simDataReference)>1e-15: tsUnits = 'Fold change' tsScale = convertQuantityUnits[tsUnits] @@ -335,6 +346,26 @@ def displayPlots( self, fname, modelLookup, stim, hideSubplots, exptType ): ylabel = '{} Fold change'.format( self.field ) pp.plotme( fname, ylabel ) + def plotFepsps( self, fname ): + tconv = next( v for k, v in convertTimeUnits.items() if self.timeUnits in k ) + numPts = len( self.epspPlot.vector ) + xpts = np.array( range( numPts) ) * self.epspPlot.dt / tconv + sumvec = np.zeros( numPts ) + for i, wt in zip( self.epspPlot.vec, self.wts ): + #ypts = i.vector * wt * fepspScale + # I'm going to plot the original currents rather than the + # variously scaled contributions leading up to the fEPSP + ypts = i.vector * 1e12 + pylab.plot( xpts, ypts, 'r:' ) + sumvec += ypts + pylab.plot( xpts, sumvec, 'r--' ) + pylab.xlabel( "time ({})".format( self.timeUnits) ) + pylab.ylabel( "Compartment currents Im (pA)" ) + pylab.figure(2) + pp = PlotPanel( self, "timeseries" ) + pp.plotme( fname, "fEPSP (mV)" ) + + def applyRatio( self ): eps = 1e-16 rd = self.ratioData @@ -913,12 +944,30 @@ def makeReadoutPlots( readouts, modelLookup ): plotpath = '/model/plots/' + ntpath.basename(elm.name) if i.field in elecFields: plot = moose.Table(plotpath) + elif i.field in fepspFields: + numCompts = moose.element( '/model/elec' ).numCompartments + plot = moose.Table(plotpath, numCompts ) else: plot = moose.Table2(plotpath) i.plots[elm.name] = plot if i.field in epspFields: # Do EPSP stuff. fieldname = 'getVm' i.epspPlot = plot + elif i.field in fepspFields: # Do fEPSP stuff. + fieldname = 'getIm' + i.epspPlot = plot + i.wts = [] + pv = plot.vec + idx = 0 + compts = moose.wildcardFind( '/model/elec/##[ISA=CompartmentBase]' ) + for k,p in zip( compts, pv ): + moose.connect( p, 'requestOut', k, fieldname ) + dx = k.x-i.ex + dy = k.y-i.ey + dz = k.z-i.ez + r = np.sqrt( dx*dx + dy*dy + dz*dz ) + i.wts.append( fepspScale/r ) + return elif i.field in epscFields: # Do EPSC stuff. fieldname = 'getCurrent' ''' @@ -937,7 +986,7 @@ def putReadoutsInQ( q, readouts, pauseHsolve ): stdError = [] plotLookup = {} for i in readouts: - if i.field in (epspFields + epscFields): + if i.field in (fepspFields + epspFields + epscFields): for j in range( len( i.data ) ): t = float( i.data[j][0] ) * i.timeScale heapq.heappush( q, Qentry(t, pauseHsolve, 1) ) # Turn on hsolve @@ -999,11 +1048,34 @@ def doReadout( qe, model ): ratioReference = 0.0 if readout.field in (epspFields + epscFields): doEpspReadout( readout, model.modelLookup ) + elif readout.field in fepspFields: + doFepspReadout( readout, model.modelLookup ) elif val == -1: # This is a special event to get RatioReferenceValue doReferenceReadout( readout, model.modelLookup, readout.field ) else: doEntityAndRatioReadout(readout, model.modelLookup, readout.field) +def doFepspReadout( readout, modelLookup ): + n = int( round( readout.epspWindow / readout.epspPlot.dt ) ) + assert( n > 5 ) + pts = np.zeros( n ) + numPlots = len( readout.epspPlot.vec ) + assert( numPlots == len( readout.wts ) ) + for i, wt in zip( readout.epspPlot.vec, readout.wts ): + pts += np.array( i.vector[-n:] ) * wt + #pts = np.array( readout.epspPlot.vector[-n:] ) + pts /= len( readout.epspPlot.vec ) + #print( "DOING EPSP READOUT WITH " + readout.field ) + #print( ["{:.3g} ".format( x ) for x in pts] ) + if "slope" in readout.field: + dpts = pts[1:] - pts[:-1] + slope = max( abs( dpts ) )/readout.epspPlot.dt + readout.simData.append( slope ) + elif "peak" in readout.field: + pts -= pts[0] + pk = max( abs(pts) ) + readout.simData.append( pk ) + def doEpspReadout( readout, modelLookup ): n = int( round( readout.epspWindow / readout.epspPlot.dt ) ) assert( n > 5 ) @@ -1545,7 +1617,7 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna readoutStim = i if len(i.entities) > 0 and i.entities[0].lower() == 'syninput': readoutStim = i - if readouts[0].field in ( epspFields + epscFields ): + if readouts[0].field in ( fepspFields + epspFields + epscFields ): readouts[0].stim = readoutStim makeReadoutPlots( readouts, model.modelLookup ) if hasVclamp: From 94a3211b46e867f070a5c346add98e74b78fde08 Mon Sep 17 00:00:00 2001 From: bhalla Date: Sun, 25 Nov 2018 21:21:39 +0530 Subject: [PATCH 03/28] Better implementation for fieldEPSPs, using an integral function to approximate many stimulated cells in a thin layer in a slice --- TestTSV/fepsp.tsv | 14 +++++----- findSim.py | 66 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/TestTSV/fepsp.tsv b/TestTSV/fepsp.tsv index 9991353..ba9fcb1 100644 --- a/TestTSV/fepsp.tsv +++ b/TestTSV/fepsp.tsv @@ -54,13 +54,13 @@ field fEPSP_peak useNormalization False Data Time Value stderr -6 0.2 0 -8 0.2 0 -15 0.6 0 -16 0.62 0 -17 0.7 0 -18 0.8 0 -20 0.9 0 +6 0.15 0 +8 0.15 0 +15 0.4 0 +16 0.45 0 +17 0.5 0 +18 0.55 0 +20 0.6 0 Model mapping modelSource internal diff --git a/findSim.py b/findSim.py index 1e3f696..ad8dc2e 100644 --- a/findSim.py +++ b/findSim.py @@ -66,9 +66,11 @@ elecFields = ['Vm', 'Im', 'current'] + epspFields + epscFields elecDt = 50e-6 elecPlotDt = 100e-6 -fepspScale = 4000.0 # Arb scaling. Need to figure out how to set, +fepspScale = 1.0e7 # Arb scaling. Need to figure out how to set, # Obviously a function of stimulus strength but the experimentalist # also typically adjusts stim to get response into a 'useful' range. + # Should redo in terms of resistivity, but that too is a function of + # slice geometry. def keywordMatches( k, m ): @@ -270,6 +272,8 @@ def __init__( self, self.ex = 0.0005 # Electrode position for field recordings. self.ey = 0.0 self.ez = 0.0 + self.fepspMin = -0.002 # 2 mm to the left of trode + self.fepspMax = 0.001 # 1 mm to the right of trode def configure( self, modelLookup ): """Sanity check on all fields. First, check that all the entities @@ -933,6 +937,36 @@ def putStimsInQ( q, stims, pauseHsolve ): else: heapq.heappush( q, Qentry(t, pauseHsolve, 1) ) # Turn on hsolve +def fepspInteg( x, dy ): + # phi(r, t) = (1/(4pi.sigma) ) * Sum_n_in_1toN( I_n(t) / |r-r_n| + # Here we assume that the cells are all in a single plane and are + # nearly at the same Y level, and are vertical sticks. + # Integ = 1/Y * ( ln|x/Y + sqrt(1+(x/Y)^2)| ) + # where Y is y_compt - yelectrode, and x is x_cell, and we take + # x_electrode as zero. + # Problem here with singularities. + #return 1.0/dy * ln( abs(x/dy + np.sqrt( 1+(x/dy)*(x/dy)))) + # Some recalc, I got rid of the exteranal 1.0/dy + #print("CALC_INTEEG: ", x,dy, x + np.sqrt( x*x + dy*dy) ) + return np.log( abs(x) + np.sqrt( x*x + dy*dy) ) + +def cellLongAxis( compts ): + if len( compts ) < 2: + return np.array( [1.0,0.0,0.0] ) + L = np.zeros(3) + soma = moose.wildcardFind( '/model/elec/#soma#' ) + if len( soma ) < 1: + s = np.zeros(3) + else: + s = np.array( [soma[0].x, soma[0].y, soma[0].z] ) + for i in compts: + L[0] += i.x + L[1] += i.y + L[2] += i.z + L -= s * len(compts) + return L/np.sqrt( sum( [x*x for x in L] ) ) + + def makeReadoutPlots( readouts, modelLookup ): moose.Neutral('/model/plots') for i in readouts: @@ -960,13 +994,31 @@ def makeReadoutPlots( readouts, modelLookup ): pv = plot.vec idx = 0 compts = moose.wildcardFind( '/model/elec/##[ISA=CompartmentBase]' ) + L = cellLongAxis( compts ) for k,p in zip( compts, pv ): moose.connect( p, 'requestOut', k, fieldname ) - dx = k.x-i.ex - dy = k.y-i.ey - dz = k.z-i.ez - r = np.sqrt( dx*dx + dy*dy + dz*dz ) - i.wts.append( fepspScale/r ) + # We do not know ahead of time what the orientation of + # the cell is. + # Assume a cell long axis vector L. + # Assume integration is in the plane orthogonal to r. + # Assume soma roughly at 0,0,0 + dy = np.dot( L, [k.x-i.ex, k.y-i.ey, k.z-i.ez] ) + + #dx = k.x-i.ex + #dy = k.y-i.ey + #dz = k.z-i.ez + # This is the wrong, but easy version + #r = np.sqrt( dx*dx + dy*dy + dz*dz ) + #i.wts.append( fepspScale/r ) + # + # Here is the correct version, integrating over the + # pyramidal cell layer. + ret = fepspInteg(i.fepspMax, dy) - \ + fepspInteg(i.fepspMin, dy) + #print( k.name, ret, i.fepspMax, dy ) + i.wts.append( ret * fepspScale ) + + return elif i.field in epscFields: # Do EPSC stuff. fieldname = 'getCurrent' @@ -1449,7 +1501,7 @@ def getUniqueName( model, obj ): assert( len( wf ) > 0 ) if len( wf ) == 1: return pa + "/" + obj.name - print ("Concinit = {}".format( obj.concInit ) ) + #print ("Concinit = {}".format( obj.concInit ) ) raise SimError( "getUniqueName: {} and {} non-unique, please rename.".format( wf[0].path, wf[1].path ) ) return obj.name From ad59fb0e4d1b9037cf0f8384d0c4409963899e1b Mon Sep 17 00:00:00 2001 From: bhalla Date: Thu, 28 Feb 2019 13:48:37 +0530 Subject: [PATCH 04/28] Fixes to FindSim and some model files so that we can correctly handle findSim model subsetting even in multiscale models. --- findSim.py | 49 ++++++++++++++++++++++++++++++++++------------ models/loadhh.py | 4 +++- models/plastic8.py | 9 ++++++--- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/findSim.py b/findSim.py index ad8dc2e..cb21a45 100644 --- a/findSim.py +++ b/findSim.py @@ -624,9 +624,16 @@ def deleteItems( self, kinpath ): raise SimError("modelId/rootPath is not allowed to delete {}".format( obj) ) def subsetItems( self, kinpath ): - nonContainers, directContainers, indirectContainers = [],[],[] + nonContainers, directContainers = [],[] + indirectContainers = [moose.element(kinpath)] + # These objects are present in the base chem model container, + # below /kinetics. I'm not sure why we want to preserve this. + ''' for i in ['moregraphs', 'info', 'graphs']: - directContainers.append( moose.element( kinpath + '/' + i ) ) + if moose.exists( kinpath + '/' + i ) : + elm = moose.element( kinpath + '/' + i ) + directContainers.append( elm ) + ''' subsets = re.sub(r'\s', '', self.modelSubset).split(',') for i in subsets: @@ -663,7 +670,7 @@ def subsetItems( self, kinpath ): else: print( "Warning: deleting doomed obj {}: it does not exist".format( i ) ) - def modify( self, modelId, erSPlist, odelWarning): + def modify( self, modelId, erSPlist, modelWarning): ''' Semantics: There are two specifiers: what to save (modelSubset) and what to delete (itemstodelete). @@ -1436,7 +1443,9 @@ def buildSolver( modelId, solver, useVclamp = False ): # after loading the model. if useVclamp: if moose.exists( '/model/elec/hsolve' ): - raise SimError( "Hsolve already created. Please rebuild model without HSolve. In rdesigneur use the 'turnOffElec = True' flag." ) + raise SimError( "Hsolve already created. Please rebuild \ + model without HSolve." ) + if moose.exists( '/model/elec/soma' ) and not moose.exists( '/model/elec/hsolve' ): for i in range( 9 ): moose.setClock( i, elecDt ) @@ -1609,15 +1618,29 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna # the model. At this point the model must be in the current dir mscript = imp.load_source( "mscript", model.fileName ) #mscript = __import__( fileName ) - modelId = mscript.load() - + rdes = mscript.load() + if not moose.exists( '/library/chem' ): + modelId = moose.Neutral( '/library/chem' ) + else: + modelId = moose.element( '/library/chem' ) - for f in moose.wildcardFind('/model/##[ISA=ReacBase],/model/##[ISA=EnzBase]'): + mpath = modelId.path + for f in moose.wildcardFind('{0}/##[ISA=ReacBase],{0}/##[ISA=EnzBase]'.format( mpath ) ): erSPlist[f] = {'s':len(f.neighbors['sub']), 'p':len(f.neighbors['prd'])} # Then we apply whatever modifications are specified by user or protocol modelWarning = "" model.modify( modelId, erSPlist,modelWarning ) + #moose.le( '/library/chem/compartment_1' ) + if file_extension == ".py": + # Here we override the rdes to NOT make a solver. + temp = rdes.turnOffElec + rdes.turnOffElec = True + mscript.build( rdes ) + rdes.turnOffElec = temp + #turnOffElec = rdes.turnOffElec + moose.reinit() + model._scaleParams( scaleParam ) if len(dumpFname) > 2: if dumpFname[-2:] == '.g': @@ -1680,7 +1703,6 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna if file_extension != '.py': # rdesigneur sims will set own clocks for i in range( 10, 20 ): moose.setClock( i, 0.1 ) - ############################################################## # Here we handle presettling. First to generate, then to apply # the dict of settled values. @@ -1718,7 +1740,8 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna i.displayPlots( script, model.modelLookup, stims[0], hideSubplots, expt.exptType ) pylab.show() - moose.delete( modelId ) + if moose.exists( '/model' ): + moose.delete( '/model' ) if moose.exists( '/library' ): moose.delete( '/library' ) return score @@ -1726,10 +1749,10 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna except SimError as msg: if not silent: print( "Error: findSim failed for script {}: {}".format(script, msg )) - if modelId: - moose.delete( modelId ) - if moose.exists( '/library' ): - moose.delete( '/library' ) + if moose.exists( '/model' ): + moose.delete( '/model' ) + if moose.exists( '/library' ): + moose.delete( '/library' ) return -1.0 # Run the 'main' if this script is executed standalone. if __name__ == '__main__': diff --git a/models/loadhh.py b/models/loadhh.py index 6d786de..4dc1026 100644 --- a/models/loadhh.py +++ b/models/loadhh.py @@ -8,5 +8,7 @@ def load(): ['Na', 'soma', 'Gbar', '1200' ], ['K', 'soma', 'Gbar', '360' ]], ) + return rdes + +def build( rdes ): rdes.buildModel() - return rdes.model diff --git a/models/plastic8.py b/models/plastic8.py index 4e47824..82756ca 100644 --- a/models/plastic8.py +++ b/models/plastic8.py @@ -19,7 +19,7 @@ def load(): chemDt = 0.002, diffDt = 0.002, chemPlotDt = 0.02, - turnOffElec = True, #FindSim needs to create Vclamp and then solver. + turnOffElec = False,#FindSim needs to create Vclamp and then solver. useGssa = False, # cellProto syntax: ['ballAndStick', 'name', somaDia, somaLength, dendDia, dendLength, numDendSegments ] cellProto = [['ballAndStick', 'soma', 12e-6, 12e-6, 4e-6, 100e-6, 1 ]], @@ -52,6 +52,11 @@ def load(): stimList = [['head#', '0.2','glu', 'periodicsyn', '0']], ) moose.seed(1234567) + + return rdes + + +def build( rdes ): rdes.buildModel() #moose.element( '/model/chem/dend/ksolve' ).numThreads = 4 #moose.showfield( '/model/chem/dend/ksolve' ) @@ -63,5 +68,3 @@ def load(): #moose.showmsg( '/model/elec/head0/glu/sh/synapse/synInput_rs' ) #import presettle_CaMKII_MAPK7_init moose.reinit() - - return rdes.model From a09dd982b136e498da6d5f547f90ca285b3fead7 Mon Sep 17 00:00:00 2001 From: bhalla Date: Fri, 1 Mar 2019 11:31:52 +0530 Subject: [PATCH 05/28] Further fixes to findSim for multiscale models. Also a fix to the model loadhh.py --- findSim.py | 26 ++++++-------------------- models/loadhh.py | 2 +- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/findSim.py b/findSim.py index cb21a45..092c19e 100644 --- a/findSim.py +++ b/findSim.py @@ -1438,7 +1438,7 @@ def loadTsv( fname ): model = Model.load(fd ) return expt, stims, readouts, model -def buildSolver( modelId, solver, useVclamp = False ): +def buildSolver( modelId, solver, useVclamp = False, turnOffElec = False ): # Here we remove and rebuild the HSolver because we have to add vclamp # after loading the model. if useVclamp: @@ -1446,7 +1446,7 @@ def buildSolver( modelId, solver, useVclamp = False ): raise SimError( "Hsolve already created. Please rebuild \ model without HSolve." ) - if moose.exists( '/model/elec/soma' ) and not moose.exists( '/model/elec/hsolve' ): + if (not turnOffElec) and moose.exists( '/model/elec/soma' ) and not moose.exists( '/model/elec/hsolve' ): for i in range( 9 ): moose.setClock( i, elecDt ) moose.setClock( 8, elecPlotDt ) @@ -1632,12 +1632,13 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna modelWarning = "" model.modify( modelId, erSPlist,modelWarning ) #moose.le( '/library/chem/compartment_1' ) + turnOffElec = False if file_extension == ".py": # Here we override the rdes to NOT make a solver. - temp = rdes.turnOffElec + turnOffElec = rdes.turnOffElec rdes.turnOffElec = True mscript.build( rdes ) - rdes.turnOffElec = temp + rdes.turnOffElec = turnOffElec #turnOffElec = rdes.turnOffElec moose.reinit() @@ -1667,21 +1668,6 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna moose.delete( '/library' ) return score - ''' - for i in stims: - if i.field == 'Vclamp': - buildVclamp( i, model.modelLookup ) - ''' - - - ''' - if stims[0].field == 'Vclamp': - readouts[0].entities = ['vclamp'] - #readouts[0].field = 'current' - buildVclamp( stims[0], model.modelLookup ) - ''' - - hasVclamp = False readoutStim = stims[0] for i in stims: @@ -1699,7 +1685,7 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna #build the solver with a flag to say rebuild the hsolve. buildSolver( modelId, model.solver, useVclamp = True ) else: - buildSolver( modelId, model.solver ) + buildSolver( modelId, model.solver, turnOffElec = turnOffElec ) if file_extension != '.py': # rdesigneur sims will set own clocks for i in range( 10, 20 ): moose.setClock( i, 0.1 ) diff --git a/models/loadhh.py b/models/loadhh.py index 4dc1026..6eb80fa 100644 --- a/models/loadhh.py +++ b/models/loadhh.py @@ -2,7 +2,7 @@ import rdesigneur as rd def load(): rdes = rd.rdesigneur( - turnOffElec = True, + turnOffElec = False, chanProto = [['make_HH_Na()', 'Na'], ['make_HH_K()', 'K']], chanDistrib = [ ['Na', 'soma', 'Gbar', '1200' ], From f128df219d7105040169887acb0e1120e958eb02 Mon Sep 17 00:00:00 2001 From: bhalla Date: Thu, 25 Apr 2019 11:12:55 +0530 Subject: [PATCH 06/28] Fixes to findSim and multi_param_minimization to deal with long-standing issue of non-match of dumped optimized file. --- README.md | 2 +- findSim.py | 53 +++++++++++++++++-------------------- multi_param_minimization.py | 11 ++++---- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 86df84a..3560cdb 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Latest release is 1.1.0, which can be downloadable at # Quick start: A. Run one of the example experiments on the default model, generating a graph to compare model to experiment: To run the script, run the command in python and `synSynth7.g` is the latest model that is tested out the worksheets. - >python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv --model synSynth7.g + >python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv --model models/synSynth7.g or >python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv diff --git a/findSim.py b/findSim.py index 092c19e..7ed173b 100644 --- a/findSim.py +++ b/findSim.py @@ -205,6 +205,7 @@ def __init__( self, quantityUnits = 'mM', useRatio = False, useNormalization=False, + tabulateOutput = False, settleTime = 300.0, ratioReferenceEntities = '', ratioReferenceTime = 0.0, @@ -311,7 +312,6 @@ def displayPlots( self, fname, modelLookup, stim, hideSubplots, exptType ): elif self.useNormalization and abs(self._simDataReference)>1e-15: tsUnits = 'Fold change' tsScale = convertQuantityUnits[tsUnits] - #print( "tsScale = {}, {}".format( tsScale, tsUnits ) ) for i in self.entities: elms = modelLookup[i] @@ -329,8 +329,6 @@ def displayPlots( self, fname, modelLookup, stim, hideSubplots, exptType ): scale = tsScale * self.ratioData[0] else: scale = tsScale - #print( "LEN(ratioData) = {}, quantScale={}, simDataReference={}".format( len(self.ratioData), self.quantityScale,self._simDataReference ) ) - #print( "plotvec name = {}, val= {}".format( j.name, self.plots[j.name].vector ) ) ypts = self.plots[j.name].vector / scale sumvec += ypts if (not hideSubplots) and (len( elms ) > 1): @@ -396,11 +394,14 @@ def doScore( self, scoringFormula ): numScore = 0.0 dvals = [i[1] for i in self.data] datarange = max( dvals ) - min( dvals ) + if self.tabulateOutput: + print( "{:>12s} {:>12s} {:>12s} {:>12s}".format( "t", "expt", "sim", "sem" ) ) for i,sim in zip( self.data, self.simData ): t = i[0] expt = i[1] sem = i[2] - #print t, expt, sem, sim, datarange + if self.tabulateOutput: + print( "{:12.3f} {:12.3f} {:12.3f} {:12.3f}".format( t, expt, sim, sem ) ) #print "Formula = ", scoringFormula, eval( scoringFormula ) score += eval( scoringFormula ) numScore += 1.0 @@ -522,7 +523,6 @@ def buildModelLookup( self ): paths = self._tempModelLookup[i].split('+') # Summed sim entities are separated with a '+', but map to a # single experimentally defined entity. - #print( "In buildModelLookup, seeking {}:{}".format( i, paths[0] ) ) foundObj = [ self.findObj( '/model', p) for p in paths ] self.modelLookup[i] = foundObj @@ -593,24 +593,26 @@ def _scaleOneParam( self, params ): if obj.path == '/': # No object found return + field = params[1] scale = float( params[2] ) if not ( scale >= 0.0 and scale <= 100.0 ): print( "Error: Scale {} out of range".format( scale ) ) assert( False ) - #assert( scale >= 0.0 and scale <= 100.0 ) - if params[1] == 'Kd': + if field == 'Kd': if not obj.isA[ "ReacBase" ]: raise SimError( "scaleParam: can only assign Kd to a Reac, was: '{}'".format( obj.className ) ) sf = np.sqrt( scale ) obj.Kb *= sf obj.Kf /= sf - elif params[1] == 'tau': + #print("ScaledParam {}.{} Kf={:.4f} Kb={:.4f}".format( params[0], field, obj.Kf, obj.Kb) ) + elif field == 'tau': obj.Kb /= scale obj.Kf /= scale + #print("ScaledParam {}.{} Kf={:.4f} Kb={:.4f}".format( params[0], field, obj.Kf, obj.Kb) ) else: - val = obj.getField( params[1] ) - obj.setField( params[1], val * scale) - #print("ScaledParam {}.{} from {} to {}".format( params[0], params[1], val, obj.getField( params[1] ) ) ) + val = obj.getField( field ) + obj.setField( field, val * scale) + #print("ScaledParam {}.{} from {} to {}".format( params[0], field, val, obj.getField( field ) ) ) def deleteItems( self, kinpath ): if self.itemstodelete: @@ -709,7 +711,6 @@ def modify( self, modelId, erSPlist, modelWarning): obj = self.findObj(kinpath, entity) if field == "concInit (uM)": field = "concInit" - #print " obj ", obj, field, value obj.setField( field, value ) @@ -750,7 +751,6 @@ def getObjParam( elm, field ): raise SimError( "getObjParam: can only get tau on a Reac, was: '{}'".format( obj.className ) ) scaleKf = 0.001 ** (elm.numSubstrates-1) scaleKb = 0.001 ** (elm.numProducts-1) - #print( "scaleKf={}; scaleKb={}, numsu ={}, numPrd={},Kb={},Kf={}".format( scaleKf, scaleKb, elm.numSubstrates, elm.numProducts, elm.Kb, elm.Kf ) ) return 1.0 / ( elm.Kb * scaleKb + elm.Kf * scaleKf ) else: return elm.getField( field ) @@ -800,7 +800,6 @@ def innerLoad( fd, argNames, dataWidth = 2): if keywordMatches( c0, 'Data' ): readData( fd, data, dataWidth ) - #print "Ret READ DATA from INNERLOAD", len( data ) return arg, data, param, struct, modelLookup for i in argNames: @@ -937,7 +936,6 @@ def putStimsInQ( q, stims, pauseHsolve ): t = float(j[0])*i.timeScale heapq.heappush( q, Qentry( t, i, val ) ) # Below we tell the Hsolver to turn off or on for elec calcn. - #print( "in putStimsInQ, field = {}".format( i.field ) ) if i.field in ['Im', 'current', 'Vclamp'] or (i.field=='rate' and 'syn' in i.entities[0]) : if val == 0.0: heapq.heappush( q, Qentry(t+pauseHsolve.stimSettle, pauseHsolve, 0) ) @@ -954,7 +952,6 @@ def fepspInteg( x, dy ): # Problem here with singularities. #return 1.0/dy * ln( abs(x/dy + np.sqrt( 1+(x/dy)*(x/dy)))) # Some recalc, I got rid of the exteranal 1.0/dy - #print("CALC_INTEEG: ", x,dy, x + np.sqrt( x*x + dy*dy) ) return np.log( abs(x) + np.sqrt( x*x + dy*dy) ) def cellLongAxis( compts ): @@ -1022,7 +1019,6 @@ def makeReadoutPlots( readouts, modelLookup ): # pyramidal cell layer. ret = fepspInteg(i.fepspMax, dy) - \ fepspInteg(i.fepspMin, dy) - #print( k.name, ret, i.fepspMax, dy ) i.wts.append( ret * fepspScale ) @@ -1078,7 +1074,6 @@ def deliverStim( qe, model ): #print(" Setting Vclamp {} to {}".format( path, qe.val )) else: e.setField( field, qe.val ) - #print qe.t, e.path, field, qe.val #print( "########Stim = {} {} {} {} {}".format( qe.t, moose.element( '/model/elec/head0/glu' ).modulation, moose.element( '/model/chem/spine/Ca' ).conc, moose.element( '/model/elec/head0/Ca_conc' ).Ca, moose.element( '/model/elec/head0/glu/sh/synapse' ).weight ) ) if qe.t == 0: ## At time zero we initial the value concInit or nInit @@ -1246,6 +1241,8 @@ def runDoser( model, stim, readout, doseMol ): doseScale = stim.quantityScale referenceDose = readout.ratioReferenceDose * stim.quantityScale sim = 0.0 + dts = moose.element('/clock').dts + #print( "In runDoser: settle time {:.2f}, dt = {:.3f}, {:.3f}".format( readout.settleTime, dts[10], dts[16] ) ) for dose, response, sem in readout.data: doseMol.concInit = dose * doseScale moose.reinit() @@ -1470,7 +1467,6 @@ def buildSolver( modelId, solver, useVclamp = False, turnOffElec = False ): stoich = moose.Stoich( compt.path + '/stoich' ) stoich.compartment = moose.element( compt.path ) stoich.ksolve = ksolve - #print( "Path = " + compt.path + "/##" ) stoich.path = compt.path + '/##' def buildVclamp( stim, modelLookup ): @@ -1485,7 +1481,6 @@ def buildVclamp( stim, modelLookup ): vclamp.td = 5e-6 # Differential time. Should it be >= dt? #vclamp.gain = 0.00005 # Gain of vclamp ckt used for squid: 500x500um vclamp.gain = compt.Cm * 5e3 # assume SI units. Scaled by area so that gain is reasonable. Needed to avert NaNs. - #print( "Building Vclamp on {}. Compt Cm = {}".format( path, compt.Cm )) # Connect voltage clamp circuitry moose.connect( compt, 'VmOut', vclamp, 'sensedIn' ) @@ -1510,7 +1505,6 @@ def getUniqueName( model, obj ): assert( len( wf ) > 0 ) if len( wf ) == 1: return pa + "/" + obj.name - #print ("Concinit = {}".format( obj.concInit ) ) raise SimError( "getUniqueName: {} and {} non-unique, please rename.".format( wf[0].path, wf[1].path ) ) return obj.name @@ -1575,16 +1569,17 @@ def main(): parser.add_argument( '-m', '--model', type = str, help='Optional: model filename, .g or .xml', default = "" ) parser.add_argument( '-d', '--dump_subset', type = str, help='Optional: dump selected subset of model into named file', default = "" ) parser.add_argument( '-p', '--param_file', type = str, help='Optional: Generate file of tweakable params belonging to selected subset of model', default = "" ) + parser.add_argument( '-t', '--tabulate_output', action="store_true", help='Flag: Print table of plot values. Default is NOT to print table' ) parser.add_argument( '-hp', '--hide_plot', action="store_true", help='Hide plot output of simulation along with expected values. Default is to show plot.' ) parser.add_argument( '-hs', '--hide_subplots', action="store_true", help='Hide subplot output of simulation. By default the graphs include dotted lines to indicate individual quantities (e.g., states of a molecule) that are being summed to give a total response. This flag turns off just those dotted lines, while leaving the main plot intact.' ) parser.add_argument( '-o', '--optimize_elec', action="store_true", help='Optimize electrical computation. By default the electrical computation runs for the entire duration of the simulation. With this flag the system turns off the electrical engine except during the times when electrical stimuli are being given. This can be *much* faster.' ) parser.add_argument( '-s', '--scale_param', nargs=3, default=[], help='Scale specified object.field by ratio.' ) parser.add_argument( '-settle_time', '--settle_time', type=float, default=0, help='Run model for specified settle time and return dict of {path,conc}.' ) args = parser.parse_args() - innerMain( args.script, modelFile = args.model, dumpFname = args.dump_subset, paramFname = args.param_file, hidePlot = args.hide_plot, hideSubplots = args.hide_subplots, optimizeElec = args.optimize_elec, scaleParam = args.scale_param, settleTime = args.settle_time ) + innerMain( args.script, modelFile = args.model, dumpFname = args.dump_subset, paramFname = args.param_file, hidePlot = args.hide_plot, hideSubplots = args.hide_subplots, optimizeElec = args.optimize_elec, scaleParam = args.scale_param, settleTime = args.settle_time, tabulateOutput = args.tabulate_output ) -def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFname = "", hidePlot = True, hideSubplots = False, optimizeElec=True, silent = False, scaleParam=[], settleTime = 0, settleDict = {} ): +def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFname = "", hidePlot = True, hideSubplots = False, optimizeElec=True, silent = False, scaleParam=[], settleTime = 0, settleDict = {}, tabulateOutput = False ): ''' If *settleTime* > 0, then we need to return a dict of concs of all variable pools in the chem model obtained after loading in model, applying all modifications, and running for specified settle time.\n @@ -1597,6 +1592,9 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna modelWarning = "" modelId = "" expt, stims, readouts, model = loadTsv( script ) + for r in readouts: + r.tabulateOutput = tabulateOutput + if modelFile != "": model.fileName = modelFile model.pauseHsolve = PauseHsolve( optimizeElec ) @@ -1630,6 +1628,9 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna # Then we apply whatever modifications are specified by user or protocol modelWarning = "" + # We have to scale params _before_ modifying the model since the + # expt modifications override anything done to the model params. + model._scaleParams( scaleParam ) model.modify( modelId, erSPlist,modelWarning ) #moose.le( '/library/chem/compartment_1' ) turnOffElec = False @@ -1642,7 +1643,6 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna #turnOffElec = rdes.turnOffElec moose.reinit() - model._scaleParams( scaleParam ) if len(dumpFname) > 2: if dumpFname[-2:] == '.g': moose.mooseWriteKkit( modelId.path, dumpFname ) @@ -1695,19 +1695,16 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna if settleTime > 0: t0 = time.time() moose.reinit() - #print settleTime moose.start( settleTime ) w = moose.wildcardFind( modelId.path + "/##[ISA=PoolBase]" ) ret = {} for i in w: if not i.isBuffered: ret[i.path] = i.n - #print( "{}.nInit = {:.3f}".format( i.path, i.n )) - #print "-------------------- settle done -------------------" moose.delete( modelId ) if moose.exists( '/library' ): moose.delete( '/library' ) - #print( "Done settling in {:.2f} seconds".format( time.time()-t0)) + print( "Done global settle time {:.2f} in {:.2f} seconds".format( settleTime, time.time()-t0)) print( "s", end = '' ) sys.stdout.flush() return ret diff --git a/multi_param_minimization.py b/multi_param_minimization.py index 6434740..b9c8653 100644 --- a/multi_param_minimization.py +++ b/multi_param_minimization.py @@ -107,9 +107,10 @@ def doEval( self, x ): paramList.append( obj ) paramList.append( field ) paramList.append( j ) + #print( "{:6.3f}".format(j), end = "" ) for k in self.expts: - ret.append( self.pool.apply_async( findSim.innerMain, (k,), dict(modelFile = self.modelFile, hidePlot=True, silent=True, scaleParam=paramList), callback = reportReturn ) ) + ret.append( self.pool.apply_async( findSim.innerMain, (k,), dict(modelFile = self.modelFile, hidePlot=True, silent=True, scaleParam=paramList, tabulateOutput = False ), callback = reportReturn ) ) self.score = [ i.get() for i in ret ] sumScore = sum([ s*w for s,w in zip(self.score, self.weights) if s>=0.0]) sumWts = sum( [ w for s,w in zip(self.score, self.weights) if s>=0.0 ] ) @@ -166,6 +167,8 @@ def main(): results = optimize.minimize( ev.doEval, np.ones( len(params) ), method='L-BFGS-B', tol = args.tolerance, callback = optCallback, bounds = bounds ) print( "\n----------- Completed in {:.3f} sec ---------- ".format(time.time() - t0 ) ) print( "\n----- Score= {:.4f} ------ ".format(results.fun ) ) + + dumpData = False fp = "" if len( args.file ) > 0: @@ -208,12 +211,10 @@ def tweakParams( params, scaleFactors ): obj.Kb /= x else: obj.setField( field, obj.getField( field ) * x ) - #print( "Tweaked {}.{} by {}".format( obj.path, field, x ) ) def analyzeResults( fp, dumpData, results, params, evalObj, initScore ): - #assert( len(results.x) == len( results.fun ) ) assert( len(results.x) == len( params ) ) out = [] for p,x, in zip(params, results.x): @@ -224,12 +225,12 @@ def analyzeResults( fp, dumpData, results, params, evalObj, initScore ): numSum = 0.0 assert( len( evalObj.expts ) == len( initScore ) ) for e, i, f, w in zip( evalObj.expts, initScore, evalObj.score, evalObj.weights ): - out.append( "{:40s}{:12.3f}{:12.3f}{:12.3f}".format( e, i, f, w ) ) + out.append( "{:40s}{:12.5f}{:12.5f}{:12.3f}".format( e, i, f, w ) ) if i >= 0: initSum += i * w finalSum += f * w numSum += w - out.append( "\nInit score = {:.4f}, final = {:.4f}".format(initSum/numSum, finalSum / numSum) ) + out.append( "\nInit score = {:.4f}, final = {:.8f}".format(initSum/numSum, results.fun ) ) for i in out: print( i ) if dumpData: From 0f09020a7899ef713b46170a85bf529a1e122401 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 13:41:48 +0530 Subject: [PATCH 07/28] fixes to syntax. --- README.md | 109 ++++++++++++++++++++++++++++++---------------------- __init__.py | 0 setup.py | 23 +++++++++++ 3 files changed, 86 insertions(+), 46 deletions(-) create mode 100644 __init__.py create mode 100644 setup.py diff --git a/README.md b/README.md index 3560cdb..9fef3bb 100644 --- a/README.md +++ b/README.md @@ -16,60 +16,74 @@ This file and the files in this repository are licensed under GPL v3 or later. # Version -Latest release is 1.1.0, which can be downloadable at - https://github.com/BhallaLab/FindSim/archive/v1.1.0.zip - https://github.com/BhallaLab/FindSim/archive/v1.1.0.tar.gz +Latest release is 1.1.0, which can be downloadable at +https://github.com/BhallaLab/FindSim/archive/v1.1.0.zip # Install - To run FindSim script one needs to - - Install MOOSE which can be found here - https://moose.ncbs.res.in/readthedocs/install/install.html - - Install FindSim: - Clone the entire repository using - >git clone https://github.com/BhallaLab/FindSim - or, clone specific branch such as "stable" using: - >git clone -b https://github.com/BhallaLab/FindSim - -============================================================================= + +To run FindSim script one needs to + +1. Install MOOSE which can be found here https://moose.ncbs.res.in/readthedocs/install/install.html +2. Install FindSim: + - Clone this repository using + `git clone https://github.com/BhallaLab/FindSim` + + - or, clone specific branch such as "devel" using: + `git clone -b devel https://github.com/BhallaLab/FindSim` + # File organization: - FindSim/ : project directory - FindSim/stable : Stable branch. Stable version of `develop` branch - FindSim/Curated : Folder contains FindSim worksheets to which the model is well fit. - FindSim/models : Model files - FindSim/findSim.py : Main findSim script - FindSim/runAllParallel.py : Batch/parallel wrapper script. - FindSim/FindSim-Exptworksheet.xlsx : Template worksheet with inline help and units, for Microsoft Excel. - FindSim/FindSim-Exptworksheet.ods : Template worksheet with inline help and units, for Libre Office. - FindSim/FindSim-Schema.xml : Schema for tsv files for worksheet. - FindSim/README.md : This file + +FindSim/ : project directory +FindSim/stable : Stable branch. Stable version of `develop` branch +FindSim/Curated : Folder contains FindSim worksheets to which the model is well fit. +FindSim/models : Model files +FindSim/findSim.py : Main findSim script +FindSim/runAllParallel.py : Batch/parallel wrapper script. +FindSim/FindSim-Exptworksheet.xlsx : Template worksheet with inline help and units, for Microsoft Excel. +FindSim/FindSim-Exptworksheet.ods : Template worksheet with inline help and units, for Libre Office. +FindSim/FindSim-Schema.xml : Schema for tsv files for worksheet. +FindSim/README.md : This file -============================================================================= # Quick start: + A. Run one of the example experiments on the default model, generating a graph to compare model to experiment: - To run the script, run the command in python and `synSynth7.g` is the latest model that is tested out the worksheets. - >python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv --model models/synSynth7.g - or - >python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv +To run the script, run the command in python and `synSynth7.g` is the latest model that is tested out the worksheets. + +``` +python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv --model models/synSynth7.g +``` +or, + +``` +python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv +``` B. Batch run: - -runAllParallel.py script runs the findSim program on all tsv files in the specified directory, computes their scores, and prints out basic stats of the scores. It can do this in parallel using Python's multiprocessing library. + +- runAllParallel.py script runs the findSim program on all tsv files in the specified directory, computes their scores, and prints out basic stats of the scores. It can do this in parallel using Python's multiprocessing library. - >python runAllParallel.py Curated -n 8 (run of the entire set of `Curated` experiments on 8 cores) - or - >python runAllParallel.py Directory (of tsv files) -n (Number of processes to spawn) --model (synSynth7.g) +``` +python runAllParallel.py Curated -n 8 (run of the entire set of `Curated` experiments on 8 cores) +``` +or, + +``` +python runAllParallel.py Directory (of tsv files) -n (Number of processes to spawn) --model (synSynth7.g) +``` -C. Syntax help: - >python findSim.py -h - >python runAllParallel.py -h +C. Help: +``` +python findSim.py -h +python runAllParallel.py -h +``` -============================================================================= +# Extra Generating Figures for "FindSim: a Framework for Integrating Neuronal Data and Signaling Models." -by -Nisha A. Viswan, G.V. HarshaRani, Melanie I. Stefan, Upinder S. Bhalla +by Nisha A. Viswan, G.V. HarshaRani, Melanie I. Stefan, Upinder S. Bhalla Front Neuroinform. 2018 Jun 26;12:38. doi: 10.3389/fninf.2018.00038. eCollection 2018. All these are run using the development branch "stable" @@ -88,8 +102,8 @@ python findSim.py Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synS Figure 7D: python findSim.py Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g -============================================================================= # Other resources + Project is hosted at https://github.com/BhallaLab/FindSim The web template for experiment worksheet can be found here https://www.ncbs.res.in/faculty/bhalla-findsim/worksheet @@ -100,13 +114,16 @@ MOOSE documentation: http://moose.ncbs.res.in/readthedocs/install/index_install. Two papers were used as the initial basis for the models, and which in turn refer to a large number of experimental studies for their data: - - Bhalla US., Iyengar R. Emergent properties of networks of biological signaling pathways. Science. 1999 Jan 15;283(5400):381-7. - - Jain P, and Bhalla, U.S. Signaling logic of activity-triggered dendritic protein synthesis: an mTOR gate but not a feedback switch. PLoS Comput Biol. 2009 Feb;5(2):e1000287. Epub 2009 Feb 13 + +- Bhalla US., Iyengar R. Emergent properties of networks of biological signaling pathways. Science. 1999 Jan 15;283(5400):381-7. +- Jain P, and Bhalla, U.S. Signaling logic of activity-triggered dendritic protein synthesis: an mTOR gate but not a feedback switch. PLoS Comput Biol. 2009 Feb;5(2):e1000287. Epub 2009 Feb 13 Two further papers were used for some of the experiments: - - Gu J, et al. Beta1,4-N-Acetylglucosaminyltransferase III down-regulates neurite outgrowth induced by costimulation of epidermal growth factor and integrins through the Ras/ERK signaling pathway in PC12 cells. Glycobiology. 2004 Feb;14(2):177-86. Epub 2003 Oct 23 - - Ji Y, et al. Acute and gradual increases in BDNF concentration elicit distinct signaling and functions in neurons. Nat Neurosci. 2010 Mar;13(3):302-9. doi: 10.1038/nn.2505. Epub 2010 Feb 21. -DOQCS database, from which models were derived: http://doqcs.ncbs.res.in - Sivakumaran S. et al. The Database of Quantitative Cellular Signaling: management and analysis of chemical kinetic models of signaling networks. -Bioinformatics. 2003. 19(3):408–415 +- Gu J, et al. Beta1,4-N-Acetylglucosaminyltransferase III down-regulates neurite outgrowth induced by costimulation of epidermal growth factor and integrins through the Ras/ERK signaling pathway in PC12 cells. Glycobiology. 2004 Feb;14(2):177-86. Epub 2003 Oct 23 +- Ji Y, et al. Acute and gradual increases in BDNF concentration elicit distinct signaling and functions in neurons. Nat Neurosci. 2010 Mar;13(3):302-9. doi: 10.1038/nn.2505. Epub 2010 Feb 21. + +DOQCS database, from which models were derived: http://doqcs.ncbs.res.in +__Sivakumaran S. et al. The Database of Quantitative Cellular Signaling: +management and analysis of chemical kinetic models of signaling networks. +Bioinformatics. 2003. 19(3):408–415__ diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..2637b63 --- /dev/null +++ b/setup.py @@ -0,0 +1,23 @@ +import os +import sys +from setuptools import setup + +with open("README.md") as f: + readme = f.read() + +setup( + name = "findsim", + version = "1.0.0", + description = "A Framework for Integrating Neuronal Data and Singalling Model", + long_description = readme, + long_description_content_type = "text/markdown", + packages = [ "findsim" ], + package_dir = { "findsim" : "."}, + install_requires = [ 'pymoose', 'scipy' ], + author = "Dilawar Singh", # author of packaging. See contributors for + # autor of findsime + author_email = "dilawar@ncbs.res.in", + url = "http://github.com/BhallaLab/FindSime", + package_data = { "findsim" : [ '*.csv' ] }, + license='GPLv3' +) From 21e2b620e4bb672f7611709b790c132b339635a9 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 13:51:33 +0530 Subject: [PATCH 08/28] ready for testing. --- __main__.py | 23 +++++++++++++++++++++ findSim.py | 5 +++-- runAllParallel.py | 6 +++--- setup.py | 51 +++++++++++++++++++++++++++++++---------------- 4 files changed, 63 insertions(+), 22 deletions(-) create mode 100644 __main__.py diff --git a/__main__.py b/__main__.py new file mode 100644 index 0000000..d8458fb --- /dev/null +++ b/__main__.py @@ -0,0 +1,23 @@ +"""__main__.py: + +Entry point for this package. +""" + +__author__ = "Dilawar Singh" +__copyright__ = "Copyright 2017-, Dilawar Singh" +__version__ = "1.0.0" +__maintainer__ = "Dilawar Singh" +__email__ = "dilawars@ncbs.res.in" +__status__ = "Development" + +import findSim +import runAllParallel + +def run(): + findSim.main() + +def run_parallel(): + runAllParallel.main() + +if __name__ == '__main__': + run() diff --git a/findSim.py b/findSim.py index 7ed173b..7307186 100644 --- a/findSim.py +++ b/findSim.py @@ -31,9 +31,9 @@ ** also known as GENESIS 3 base code. ** copyright (C) 2003-2018 Upinder S. Bhalla. and NCBS **********************************************************************/ - ''' -from __future__ import print_function + +from __future__ import print_function, division import heapq import pylab import numpy as np @@ -1737,6 +1737,7 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna if moose.exists( '/library' ): moose.delete( '/library' ) return -1.0 + # Run the 'main' if this script is executed standalone. if __name__ == '__main__': main() diff --git a/runAllParallel.py b/runAllParallel.py index 4c8c4c9..bd5ed24 100644 --- a/runAllParallel.py +++ b/runAllParallel.py @@ -36,7 +36,7 @@ It can do this in parallel using Python's multiprocessing library. ''' -from __future__ import print_function +from __future__ import print_function, division import numpy import argparse import os @@ -115,8 +115,8 @@ def main(): numGood += 1 sumScore += j * w sumWts += w - print( "Weighted Score out of {:.0f} good runs = {:.3f}. Runtime = {:.3f} sec".format( numGood, sumScore / sumWts, time.time() - t0 ) ) - #print( "{0} : {1:.2f}".format( i, j ) ) + print( "Weighted Score out of {:.0f} good runs = {:.3f}. Runtime = {:.3f} sec".format( + numGood, sumScore / sumWts, time.time() - t0 ) ) # Run the 'main' if this script is executed standalone. diff --git a/setup.py b/setup.py index 2637b63..ba24c34 100644 --- a/setup.py +++ b/setup.py @@ -1,23 +1,40 @@ +"""setup.py: + Packaging script for FindSim. +""" + +__author__ = "Dilawar Singh" +__copyright__ = "Copyright 2017-, Dilawar Singh" +__version__ = "1.0.0" +__maintainer__ = "Dilawar Singh" +__email__ = "dilawars@ncbs.res.in" +__status__ = "Development" + import os import sys -from setuptools import setup +import setuptools with open("README.md") as f: readme = f.read() -setup( - name = "findsim", - version = "1.0.0", - description = "A Framework for Integrating Neuronal Data and Singalling Model", - long_description = readme, - long_description_content_type = "text/markdown", - packages = [ "findsim" ], - package_dir = { "findsim" : "."}, - install_requires = [ 'pymoose', 'scipy' ], - author = "Dilawar Singh", # author of packaging. See contributors for - # autor of findsime - author_email = "dilawar@ncbs.res.in", - url = "http://github.com/BhallaLab/FindSime", - package_data = { "findsim" : [ '*.csv' ] }, - license='GPLv3' -) +setuptools.setup( + name = "findsim", + version = "1.0.0", + description = "A Framework for Integrating Neuronal Data and Singalling Model", + long_description = readme, + long_description_content_type = "text/markdown", + packages = [ "findsim" ], + package_dir = { "findsim" : "."}, + install_requires = [ 'pymoose', 'scipy' ], + author = "Dilawar Singh", # author of packaging. See contributors for + # autor of findsime + author_email = "dilawar@ncbs.res.in", + url = "http://github.com/BhallaLab/FindSime", + package_data = { "findsim" : [ '*.csv' ] }, + license='GPLv3', + entry_points = { + 'console_scripts' : [ + 'findsim = findsim.__main__:run', + 'findsim_parallel = findsim.__main__:run_parallel' + ] + }, + ) From 987f13085879229c81cc8136429e7ebf9b9abacc Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 14:07:26 +0530 Subject: [PATCH 09/28] test installation [skip ci] --- MANIFEST.in | 1 + __init__.py | 3 +++ __main__.py | 4 ++-- runAllParallel.py | 2 +- setup.py | 11 ++++++----- 5 files changed, 13 insertions(+), 8 deletions(-) create mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..9eca5ae --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1 @@ +recursive-include . *.xml diff --git a/__init__.py b/__init__.py index e69de29..4b58dcb 100644 --- a/__init__.py +++ b/__init__.py @@ -0,0 +1,3 @@ +import findSim +import runAllParallel +__all__ = [ "findSim", "runAllParallel"] diff --git a/__main__.py b/__main__.py index d8458fb..bbdd89c 100644 --- a/__main__.py +++ b/__main__.py @@ -10,8 +10,8 @@ __email__ = "dilawars@ncbs.res.in" __status__ = "Development" -import findSim -import runAllParallel +from findsim import findSim +from findsim import runAllParallel def run(): findSim.main() diff --git a/runAllParallel.py b/runAllParallel.py index bd5ed24..b3edfde 100644 --- a/runAllParallel.py +++ b/runAllParallel.py @@ -36,7 +36,7 @@ It can do this in parallel using Python's multiprocessing library. ''' -from __future__ import print_function, division +from __future__ import print_function, division, absolute_import import numpy import argparse import os diff --git a/setup.py b/setup.py index ba24c34..3367877 100644 --- a/setup.py +++ b/setup.py @@ -17,19 +17,20 @@ readme = f.read() setuptools.setup( - name = "findsim", + name = "FindSim", version = "1.0.0", description = "A Framework for Integrating Neuronal Data and Singalling Model", long_description = readme, long_description_content_type = "text/markdown", - packages = [ "findsim" ], - package_dir = { "findsim" : "."}, + packages = [ "FindSim" ], + package_dir = { "FindSim" : "."}, install_requires = [ 'pymoose', 'scipy' ], author = "Dilawar Singh", # author of packaging. See contributors for - # autor of findsime + # the list of authors author_email = "dilawar@ncbs.res.in", url = "http://github.com/BhallaLab/FindSime", - package_data = { "findsim" : [ '*.csv' ] }, + package_data = { "FindSim" : [ '*.csv', '*.xml' ] }, + include_pacakge_data = True, license='GPLv3', entry_points = { 'console_scripts' : [ From ef1869b0b9734ece6103e4bf6cc7c7797753d4b0 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 14:16:25 +0530 Subject: [PATCH 10/28] Local tests have passed. --- __init__.py | 4 ++-- __main__.py | 4 ++-- runAllParallel.py | 4 ++-- setup.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/__init__.py b/__init__.py index 4b58dcb..b901bca 100644 --- a/__init__.py +++ b/__init__.py @@ -1,3 +1,3 @@ -import findSim -import runAllParallel +from FindSim import findSim +from FindSim import runAllParallel __all__ = [ "findSim", "runAllParallel"] diff --git a/__main__.py b/__main__.py index bbdd89c..85a7513 100644 --- a/__main__.py +++ b/__main__.py @@ -10,8 +10,8 @@ __email__ = "dilawars@ncbs.res.in" __status__ = "Development" -from findsim import findSim -from findsim import runAllParallel +from FindSim import findSim +from FindSim import runAllParallel def run(): findSim.main() diff --git a/runAllParallel.py b/runAllParallel.py index b3edfde..6264ae4 100644 --- a/runAllParallel.py +++ b/runAllParallel.py @@ -1,5 +1,5 @@ +# -*- coding: utf-8 -*- -# # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 3, or @@ -43,7 +43,7 @@ import sys import argparse import time -import findSim +from . import findSim from multiprocessing import Pool resultCount = 0 diff --git a/setup.py b/setup.py index 3367877..4a41b31 100644 --- a/setup.py +++ b/setup.py @@ -34,8 +34,8 @@ license='GPLv3', entry_points = { 'console_scripts' : [ - 'findsim = findsim.__main__:run', - 'findsim_parallel = findsim.__main__:run_parallel' + 'findsim = FindSim.__main__:run', + 'findsim_parallel = FindSim.__main__:run_parallel' ] }, ) From 5f44af8137b65f3b35e1df5c553b16ae17f1dd12 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 14:17:24 +0530 Subject: [PATCH 11/28] tweaks to readme file. --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9fef3bb..673b2b9 100644 --- a/README.md +++ b/README.md @@ -34,16 +34,16 @@ To run FindSim script one needs to # File organization: -FindSim/ : project directory -FindSim/stable : Stable branch. Stable version of `develop` branch -FindSim/Curated : Folder contains FindSim worksheets to which the model is well fit. -FindSim/models : Model files -FindSim/findSim.py : Main findSim script -FindSim/runAllParallel.py : Batch/parallel wrapper script. -FindSim/FindSim-Exptworksheet.xlsx : Template worksheet with inline help and units, for Microsoft Excel. -FindSim/FindSim-Exptworksheet.ods : Template worksheet with inline help and units, for Libre Office. -FindSim/FindSim-Schema.xml : Schema for tsv files for worksheet. -FindSim/README.md : This file + FindSim/ : project directory + FindSim/stable : Stable branch. Stable version of `develop` branch + FindSim/Curated : Folder contains FindSim worksheets to which the model is well fit. + FindSim/models : Model files + FindSim/findSim.py : Main findSim script + FindSim/runAllParallel.py : Batch/parallel wrapper script. + FindSim/FindSim-Exptworksheet.xlsx : Template worksheet with inline help and units, for Microsoft Excel. + FindSim/FindSim-Exptworksheet.ods : Template worksheet with inline help and units, for Libre Office. + FindSim/FindSim-Schema.xml : Schema for tsv files for worksheet. + FindSim/README.md : This file # Quick start: From e68e4c3ecdc5e8e9932432621a7c91c9e9988cc6 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 14:18:01 +0530 Subject: [PATCH 12/28] Alpha release. --- setup.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 4a41b31..43da748 100644 --- a/setup.py +++ b/setup.py @@ -4,10 +4,8 @@ __author__ = "Dilawar Singh" __copyright__ = "Copyright 2017-, Dilawar Singh" -__version__ = "1.0.0" __maintainer__ = "Dilawar Singh" __email__ = "dilawars@ncbs.res.in" -__status__ = "Development" import os import sys @@ -18,7 +16,7 @@ setuptools.setup( name = "FindSim", - version = "1.0.0", + version = "0.0.1", description = "A Framework for Integrating Neuronal Data and Singalling Model", long_description = readme, long_description_content_type = "text/markdown", From c4093e3b5591d37c7f6e983983b687973a075786 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 14:28:23 +0530 Subject: [PATCH 13/28] ready for alpha testing. --- setup.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 43da748..2694917 100644 --- a/setup.py +++ b/setup.py @@ -14,9 +14,18 @@ with open("README.md") as f: readme = f.read() +version_ = '1.0.0' +isPre_ = True +if isPre_: + import datetime + version_ += '.dev' + datetime.datetime.today().strftime('%Y%m%d') + print( "[INFO ] Building version %s" % version_ ) + + + setuptools.setup( name = "FindSim", - version = "0.0.1", + version = version_, description = "A Framework for Integrating Neuronal Data and Singalling Model", long_description = readme, long_description_content_type = "text/markdown", @@ -28,7 +37,6 @@ author_email = "dilawar@ncbs.res.in", url = "http://github.com/BhallaLab/FindSime", package_data = { "FindSim" : [ '*.csv', '*.xml' ] }, - include_pacakge_data = True, license='GPLv3', entry_points = { 'console_scripts' : [ From 102480ecbc218a0e6c782605235abd67621ec60e Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 14:50:01 +0530 Subject: [PATCH 14/28] Update to README files. --- README.md | 205 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 138 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 877ee66..14ab282 100644 --- a/README.md +++ b/README.md @@ -14,114 +14,185 @@ provides a score that reports how closely the two match. # LICENSE This file and the files in this repository are licensed under GPL v3 or later. -# Version +# Install -Latest release is 1.1.0, which can be downloadable at https://github.com/BhallaLab/FindSim/archive/v1.1.0.zip +One can get `FindSim` using `python-pip`. -# Install +To install last stable release (__NOTE__ This uses moose version 3.1.4 (outdated +with this release)) + + $ pip install FindSim -To run FindSim script one needs to +Or, to install the nightly built, + + $ pip install FinSim --pre # recommended + +Alternatively, you can download the source code and install it yourself. 1. Install MOOSE which can be found here https://moose.ncbs.res.in/readthedocs/install/install.html -2. Install FindSim: - - Clone this repository using - `git clone https://github.com/BhallaLab/FindSim` - - - or, clone specific branch such as "devel" using: - `git clone -b devel https://github.com/BhallaLab/FindSim` - -# File organization: - - FindSim/ : project directory - FindSim/stable : Stable branch. Stable version of `develop` branch - FindSim/Curated : Folder contains FindSim worksheets to which the model is well fit. - FindSim/models : Model files - FindSim/findSim.py : Main findSim script - FindSim/runAllParallel.py : Batch/parallel wrapper script. - FindSim/FindSim-Exptworksheet.xlsx : Template worksheet with inline help and units, for Microsoft Excel. - FindSim/FindSim-Exptworksheet.ods : Template worksheet with inline help and units, for Libre Office. - FindSim/FindSim-Schema.xml : Schema for tsv files for worksheet. - FindSim/README.md : This file - -# Quick start: +2. Install FindSim -A. Run one of the example experiments on the default model, generating a graph to compare model to experiment: -To run the script, run the command in python and `synSynth7.g` is the latest model that is tested out the worksheets. +``` +git clone https://github.com/BhallaLab/FindSim +cd FindSim +python setup.py install +``` + +After successful installation, two commands are available at your disposal +`findsim` and `findsim_parallel`. To see the help message, pass `-h` option to +either of these commands. For example, `findsim -h` will show you following +message. ``` -python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv --model models/synSynth7.g +usage: findsim [-h] [-m MODEL] [-d DUMP_SUBSET] [-p PARAM_FILE] [-t] [-hp] + [-hs] [-o] [-s SCALE_PARAM SCALE_PARAM SCALE_PARAM] + [-settle_time SETTLE_TIME] + script + +FindSim argument parser This program loads a kinetic model, and runs it with +the specified stimuli. The output is then compared with expected output +specified in the same file, to generate a model score. + +positional arguments: + script Required: filename of experiment spec, in tsv format. + +optional arguments: + -h, --help show this help message and exit + -m MODEL, --model MODEL + Optional: model filename, .g or .xml + -d DUMP_SUBSET, --dump_subset DUMP_SUBSET + Optional: dump selected subset of model into named + file + -p PARAM_FILE, --param_file PARAM_FILE + Optional: Generate file of tweakable params belonging + to selected subset of model + -t, --tabulate_output + Flag: Print table of plot values. Default is NOT to + print table + -hp, --hide_plot Hide plot output of simulation along with expected + values. Default is to show plot. + -hs, --hide_subplots Hide subplot output of simulation. By default the + graphs include dotted lines to indicate individual + quantities (e.g., states of a molecule) that are being + summed to give a total response. This flag turns off + just those dotted lines, while leaving the main plot + intact. + -o, --optimize_elec Optimize electrical computation. By default the + electrical computation runs for the entire duration of + the simulation. With this flag the system turns off + the electrical engine except during the times when + electrical stimuli are being given. This can be *much* + faster. + -s SCALE_PARAM SCALE_PARAM SCALE_PARAM, --scale_param SCALE_PARAM SCALE_PARAM SCALE_PARAM + Scale specified object.field by ratio. + -settle_time SETTLE_TIME, --settle_time SETTLE_TIME + Run model for specified settle time and return dict of + {path,conc}. + ``` -or, + +Command `findsim_parellel` is a helper utility: it runs multiple simulations +using `findsim` in parellel. + +# Quick start + +To run one of the example experiments on the default model (`synSynth7.g`) and generate a graph +to compare model to experiment. ``` -python findSim.py Curated/FindSim-Jain2009-Fig2B.tsv +findsim Curated/FindSim-Jain2009-Fig2B.tsv ``` -B. Batch run: +You can also pass the model explicitly, -- runAllParallel.py script runs the findSim program on all tsv files in the specified directory, computes their scores, and prints out basic stats of the scores. It can do this in parallel using Python's multiprocessing library. - ``` -python runAllParallel.py Curated -n 8 (run of the entire set of `Curated` experiments on 8 cores) +findsim Curated/FindSim-Jain2009-Fig2B.tsv --model models/synSynth7.g ``` -or, + +## Batch run + +To findSim program on all tsv files in the specified directory, computes their +scores, and prints out basic stats of the scores, you should use +`findsim_parallel` command. + ``` -python runAllParallel.py Directory (of tsv files) -n (Number of processes to spawn) --model (synSynth7.g) +findsim_parellel Curated -n 8 ``` -C. Help: +It will run the entire set of `Curated` experiments in parallel using 8 +independant processes (it will be effectively if your computer has at least 8 +cores). The value of `-n` should not be more than `N+1` where `N` is the number +of processors on your system (use system utility `nproc` to see this number). + +More detailed invocation of this command looks like the following: ``` -python findSim.py -h -python runAllParallel.py -h +findsim_parallel path/to/tsv/files -n 6 --model synSynth7.g ``` +# Repository organization + + FindSim/ : project directory + FindSim/stable : Stable branch. Stable version of `develop` branch + FindSim/Curated : Folder contains FindSim worksheets to which the model is well fit. + FindSim/models : Model files + FindSim/findSim.py : Main findSim script + FindSim/runAllParallel.py : Batch/parallel wrapper script. + FindSim/FindSim-Exptworksheet.xlsx : Template worksheet with inline help and units, for Microsoft Excel. + FindSim/FindSim-Exptworksheet.ods : Template worksheet with inline help and units, for Libre Office. + FindSim/FindSim-Schema.xml : Schema for tsv files for worksheet. + FindSim/README.md : This file + # Extra -Generating Figures for -"FindSim: a Framework for Integrating Neuronal Data and Signaling Models." -by Nisha A. Viswan, G.V. HarshaRani, Melanie I. Stefan, Upinder S. Bhalla -Front Neuroinform. 2018 Jun 26;12:38. doi: 10.3389/fninf.2018.00038. eCollection 2018. +Generating Figures for __FindSim: a Framework for Integrating Neuronal Data +and Signaling Models by Nisha A. Viswan, G.V. HarshaRani, Melanie I. Stefan, +Upinder S. Bhalla Front Neuroinform. 2018 Jun 26;12:38. doi: +10.3389/fninf.2018.00038. eCollection 2018.__ -All these are run using the development branch "stable" -Please change into the branch to run these. +All these are run using the branch `release.1.1.0`. Please change into the +branch to run these. Figure 6: bottom -python findSim.py Curated/FindSim-Jain2009_Fig4F.tsv --model models/synSynth7.g + python findSim.py Curated/FindSim-Jain2009_Fig4F.tsv --model models/synSynth7.g Figure 7B: -python findSim.py Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g -python findSim.py Curated/FindSim-Gu2004_Fig3.tsv --model models/synSynth7.g + python findSim.py Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g + python findSim.py Curated/FindSim-Gu2004_Fig3.tsv --model models/synSynth7.g Figure 7C: -python findSim.py Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g + python findSim.py Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g Figure 7D: -python findSim.py Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g + python findSim.py Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g -# Other resources -Project is hosted at https://github.com/BhallaLab/FindSim - -The web template for experiment worksheet can be found here https://www.ncbs.res.in/faculty/bhalla-findsim/worksheet +# Other resources -The MOOSE site: http://moose.ncbs.res.in +- The web template for experiment worksheet can be found here +https://www.ncbs.res.in/faculty/bhalla-findsim/worksheet -MOOSE documentation: http://moose.ncbs.res.in/readthedocs/install/index_install.html +- The MOOSE site: http://moose.ncbs.res.in. MOOSE documentation: + http://moose.ncbs.res.in/readthedocs/install/index_install.html -Two papers were used as the initial basis for the models, and which in turn -refer to a large number of experimental studies for their data: +- Two papers were used as the initial basis for the models, and which in turn + refer to a large number of experimental studies for their data: -- Bhalla US., Iyengar R. Emergent properties of networks of biological signaling pathways. Science. 1999 Jan 15;283(5400):381-7. -- Jain P, and Bhalla, U.S. Signaling logic of activity-triggered dendritic protein synthesis: an mTOR gate but not a feedback switch. PLoS Comput Biol. 2009 Feb;5(2):e1000287. Epub 2009 Feb 13 + 1. Bhalla US., Iyengar R. Emergent properties of networks of biological signaling pathways. Science. 1999 Jan 15;283(5400):381-7. + 2. Jain P, and Bhalla, U.S. Signaling logic of activity-triggered dendritic protein synthesis: an mTOR gate but not a feedback switch. PLoS Comput Biol. 2009 Feb;5(2):e1000287. Epub 2009 Feb 13 -Two further papers were used for some of the experiments: +- Two more papers were used for some of the experiments -- Gu J, et al. Beta1,4-N-Acetylglucosaminyltransferase III down-regulates neurite outgrowth induced by costimulation of epidermal growth factor and integrins through the Ras/ERK signaling pathway in PC12 cells. Glycobiology. 2004 Feb;14(2):177-86. Epub 2003 Oct 23 -- Ji Y, et al. Acute and gradual increases in BDNF concentration elicit distinct signaling and functions in neurons. Nat Neurosci. 2010 Mar;13(3):302-9. doi: 10.1038/nn.2505. Epub 2010 Feb 21. + 1. Gu J, et al. Beta1,4-N-Acetylglucosaminyltransferase III down-regulates + neurite outgrowth induced by costimulation of epidermal growth factor and + integrins through the Ras/ERK signaling pathway in PC12 cells. + Glycobiology. 2004 Feb;14(2):177-86. Epub 2003 Oct 23 + 2. Ji Y, et al. Acute and gradual increases in BDNF concentration elicit + distinct signaling and functions in neurons. Nat Neurosci. 2010 + Mar;13(3):302-9. doi: 10.1038/nn.2505. Epub 2010 Feb 21. -DOQCS database, from which models were derived: http://doqcs.ncbs.res.in -__Sivakumaran S. et al. The Database of Quantitative Cellular Signaling: -management and analysis of chemical kinetic models of signaling networks. -Bioinformatics. 2003. 19(3):408–415__ +- DOQCS database, from which models were derived: http://doqcs.ncbs.res.in + __Sivakumaran S. et al. The Database of Quantitative Cellular Signaling: + management and analysis of chemical kinetic models of signaling networks. + Bioinformatics. 2003. 19(3):408–415__ From f7a6c9301464f70e2f559d0f8379e62c38dc6aa6 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 15:02:35 +0530 Subject: [PATCH 15/28] Revered back to stable version. --- findSim.py | 245 +++++++++++++---------------------------------------- 1 file changed, 59 insertions(+), 186 deletions(-) diff --git a/findSim.py b/findSim.py index d93a820..14a3b5a 100644 --- a/findSim.py +++ b/findSim.py @@ -31,9 +31,9 @@ ** also known as GENESIS 3 base code. ** copyright (C) 2003-2018 Upinder S. Bhalla. and NCBS **********************************************************************/ -''' -from __future__ import print_function, division +''' +from __future__ import print_function import heapq #import pylab import numpy as np @@ -77,16 +77,10 @@ def default(self, obj): epspFields = [ 'EPSP_peak', 'EPSP_slope', 'IPSP_peak', 'IPSP_slope' ] epscFields = [ 'EPSC_peak', 'EPSC_slope', 'IPSC_peak', 'IPSC_slope' ] -fepspFields = [ 'fEPSP_peak', 'fEPSP_slope', 'fIPSP_peak', 'fIPSP_slope' ] elecFields = ['Vm', 'Im', 'current'] + epspFields + epscFields elecDt = 50e-6 elecPlotDt = 100e-6 -fepspScale = 1.0e7 # Arb scaling. Need to figure out how to set, - # Obviously a function of stimulus strength but the experimentalist - # also typically adjusts stim to get response into a 'useful' range. - # Should redo in terms of resistivity, but that too is a function of - # slice geometry. def keywordMatches( k, m ): @@ -221,7 +215,6 @@ def __init__( self, quantityUnits = 'mM', useRatio = False, useNormalization=False, - tabulateOutput = False, settleTime = 300.0, ratioReferenceEntities = '', ratioReferenceTime = 0.0, @@ -286,11 +279,6 @@ def __init__( self, """Dict of continuous, fine-timeseries plots for readouts, only activated in single-run mode""" self.epspFreq = 100.0 # Used to generate a single synaptic event self.epspWindow = 0.02 # Time of epspPlot to scan for peak/slope - self.ex = 0.0005 # Electrode position for field recordings. - self.ey = 0.0 - self.ez = 0.0 - self.fepspMin = -0.002 # 2 mm to the left of trode - self.fepspMax = 0.001 # 1 mm to the right of trode def configure( self, modelLookup ): """Sanity check on all fields. First, check that all the entities @@ -326,13 +314,10 @@ def displayPlots( self, fname, modelLookup, stim, hideSubplots, exptType ): tsUnits = 'mV' elif self.field in epscFields: tsUnits = 'pA' - elif self.field in fepspFields: - if not hideSubplots: - self.plotFepsps( fname ) - return elif self.useNormalization and abs(self._simDataReference)>1e-15: tsUnits = 'Fold change' tsScale = convertQuantityUnits[tsUnits] + #print( "tsScale = {}, {}".format( tsScale, tsUnits ) ) for i in self.entities: elms = modelLookup[i] @@ -350,6 +335,8 @@ def displayPlots( self, fname, modelLookup, stim, hideSubplots, exptType ): scale = tsScale * self.ratioData[0] else: scale = tsScale + #print( "LEN(ratioData) = {}, quantScale={}, simDataReference={}".format( len(self.ratioData), self.quantityScale,self._simDataReference ) ) + #print( "plotvec name = {}, val= {}".format( j.name, self.plots[j.name].vector ) ) ypts = self.plots[j.name].vector / scale sumvec += ypts if (not hideSubplots) and (len( elms ) > 1): @@ -369,26 +356,6 @@ def displayPlots( self, fname, modelLookup, stim, hideSubplots, exptType ): ylabel = '{} Fold change'.format( self.field ) pp.plotme( fname, ylabel ) - def plotFepsps( self, fname ): - tconv = next( v for k, v in convertTimeUnits.items() if self.timeUnits in k ) - numPts = len( self.epspPlot.vector ) - xpts = np.array( range( numPts) ) * self.epspPlot.dt / tconv - sumvec = np.zeros( numPts ) - for i, wt in zip( self.epspPlot.vec, self.wts ): - #ypts = i.vector * wt * fepspScale - # I'm going to plot the original currents rather than the - # variously scaled contributions leading up to the fEPSP - ypts = i.vector * 1e12 - pylab.plot( xpts, ypts, 'r:' ) - sumvec += ypts - pylab.plot( xpts, sumvec, 'r--' ) - pylab.xlabel( "time ({})".format( self.timeUnits) ) - pylab.ylabel( "Compartment currents Im (pA)" ) - pylab.figure(2) - pp = PlotPanel( self, "timeseries" ) - pp.plotme( fname, "fEPSP (mV)" ) - - def applyRatio( self ): eps = 1e-16 rd = self.ratioData @@ -415,14 +382,11 @@ def doScore( self, scoringFormula ): numScore = 0.0 dvals = [i[1] for i in self.data] datarange = max( dvals ) - min( dvals ) - if self.tabulateOutput: - print( "{:>12s} {:>12s} {:>12s} {:>12s}".format( "t", "expt", "sim", "sem" ) ) for i,sim in zip( self.data, self.simData ): t = i[0] expt = i[1] sem = i[2] - if self.tabulateOutput: - print( "{:12.3f} {:12.3f} {:12.3f} {:12.3f}".format( t, expt, sim, sem ) ) + #print t, expt, sem, sim, datarange #print "Formula = ", scoringFormula, eval( scoringFormula ) score += eval( scoringFormula ) numScore += 1.0 @@ -544,6 +508,7 @@ def buildModelLookup( self ): paths = self._tempModelLookup[i].split('+') # Summed sim entities are separated with a '+', but map to a # single experimentally defined entity. + #print( "In buildModelLookup, seeking {}:{}".format( i, paths[0] ) ) foundObj = [ self.findObj( '/model', p) for p in paths ] self.modelLookup[i] = foundObj @@ -614,26 +579,24 @@ def _scaleOneParam( self, params ): if obj.path == '/': # No object found return - field = params[1] scale = float( params[2] ) if not ( scale >= 0.0 and scale <= 100.0 ): print( "Error: Scale {} out of range".format( scale ) ) assert( False ) - if field == 'Kd': + #assert( scale >= 0.0 and scale <= 100.0 ) + if params[1] == 'Kd': if not obj.isA[ "ReacBase" ]: raise SimError( "scaleParam: can only assign Kd to a Reac, was: '{}'".format( obj.className ) ) sf = np.sqrt( scale ) obj.Kb *= sf obj.Kf /= sf - #print("ScaledParam {}.{} Kf={:.4f} Kb={:.4f}".format( params[0], field, obj.Kf, obj.Kb) ) - elif field == 'tau': + elif params[1] == 'tau': obj.Kb /= scale obj.Kf /= scale - #print("ScaledParam {}.{} Kf={:.4f} Kb={:.4f}".format( params[0], field, obj.Kf, obj.Kb) ) else: - val = obj.getField( field ) - obj.setField( field, val * scale) - #print("ScaledParam {}.{} from {} to {}".format( params[0], field, val, obj.getField( field ) ) ) + val = obj.getField( params[1] ) + obj.setField( params[1], val * scale) + #print("ScaledParam {}.{} from {} to {}".format( params[0], params[1], val, obj.getField( params[1] ) ) ) def deleteItems( self, kinpath ): if self.itemstodelete: @@ -647,11 +610,7 @@ def deleteItems( self, kinpath ): raise SimError("modelId/rootPath is not allowed to delete {}".format( obj) ) def subsetItems( self, kinpath ): - nonContainers, directContainers = [],[] - indirectContainers = [moose.element(kinpath)] - # These objects are present in the base chem model container, - # below /kinetics. I'm not sure why we want to preserve this. - ''' + nonContainers, directContainers, indirectContainers = [],[],[] for i in ['moregraphs', 'info', 'graphs']: if moose.exists( kinpath + '/' + i ): directContainers.append( moose.element( kinpath + '/' + i ) ) @@ -691,7 +650,7 @@ def subsetItems( self, kinpath ): else: print( "Warning: deleting doomed obj {}: it does not exist".format( i ) ) - def modify( self, modelId, erSPlist, modelWarning): + def modify( self, modelId, erSPlist, odelWarning): ''' Semantics: There are two specifiers: what to save (modelSubset) and what to delete (itemstodelete). @@ -730,6 +689,7 @@ def modify( self, modelId, erSPlist, modelWarning): obj = self.findObj(kinpath, entity) if field == "concInit (uM)": field = "concInit" + #print " obj ", obj, field, value obj.setField( field, value ) @@ -770,6 +730,7 @@ def getObjParam( elm, field ): raise SimError( "getObjParam: can only get tau on a Reac, was: '{}'".format( obj.className ) ) scaleKf = 0.001 ** (elm.numSubstrates-1) scaleKb = 0.001 ** (elm.numProducts-1) + #print( "scaleKf={}; scaleKb={}, numsu ={}, numPrd={},Kb={},Kf={}".format( scaleKf, scaleKb, elm.numSubstrates, elm.numProducts, elm.Kb, elm.Kf ) ) return 1.0 / ( elm.Kb * scaleKb + elm.Kf * scaleKf ) else: return elm.getField( field ) @@ -819,6 +780,7 @@ def innerLoad( fd, argNames, dataWidth = 2): if keywordMatches( c0, 'Data' ): readData( fd, data, dataWidth ) + #print "Ret READ DATA from INNERLOAD", len( data ) return arg, data, param, struct, modelLookup for i in argNames: @@ -955,41 +917,13 @@ def putStimsInQ( q, stims, pauseHsolve ): t = float(j[0])*i.timeScale heapq.heappush( q, Qentry( t, i, val ) ) # Below we tell the Hsolver to turn off or on for elec calcn. + #print( "in putStimsInQ, field = {}".format( i.field ) ) if i.field in ['Im', 'current', 'Vclamp'] or (i.field=='rate' and 'syn' in i.entities[0]) : if val == 0.0: heapq.heappush( q, Qentry(t+pauseHsolve.stimSettle, pauseHsolve, 0) ) else: heapq.heappush( q, Qentry(t, pauseHsolve, 1) ) # Turn on hsolve -def fepspInteg( x, dy ): - # phi(r, t) = (1/(4pi.sigma) ) * Sum_n_in_1toN( I_n(t) / |r-r_n| - # Here we assume that the cells are all in a single plane and are - # nearly at the same Y level, and are vertical sticks. - # Integ = 1/Y * ( ln|x/Y + sqrt(1+(x/Y)^2)| ) - # where Y is y_compt - yelectrode, and x is x_cell, and we take - # x_electrode as zero. - # Problem here with singularities. - #return 1.0/dy * ln( abs(x/dy + np.sqrt( 1+(x/dy)*(x/dy)))) - # Some recalc, I got rid of the exteranal 1.0/dy - return np.log( abs(x) + np.sqrt( x*x + dy*dy) ) - -def cellLongAxis( compts ): - if len( compts ) < 2: - return np.array( [1.0,0.0,0.0] ) - L = np.zeros(3) - soma = moose.wildcardFind( '/model/elec/#soma#' ) - if len( soma ) < 1: - s = np.zeros(3) - else: - s = np.array( [soma[0].x, soma[0].y, soma[0].z] ) - for i in compts: - L[0] += i.x - L[1] += i.y - L[2] += i.z - L -= s * len(compts) - return L/np.sqrt( sum( [x*x for x in L] ) ) - - def makeReadoutPlots( readouts, modelLookup ): moose.Neutral('/model/plots') for i in readouts: @@ -1001,47 +935,12 @@ def makeReadoutPlots( readouts, modelLookup ): plotpath = '/model/plots/' + ntpath.basename(elm.name) if i.field in elecFields: plot = moose.Table(plotpath) - elif i.field in fepspFields: - numCompts = moose.element( '/model/elec' ).numCompartments - plot = moose.Table(plotpath, numCompts ) else: plot = moose.Table2(plotpath) i.plots[elm.name] = plot if i.field in epspFields: # Do EPSP stuff. fieldname = 'getVm' i.epspPlot = plot - elif i.field in fepspFields: # Do fEPSP stuff. - fieldname = 'getIm' - i.epspPlot = plot - i.wts = [] - pv = plot.vec - idx = 0 - compts = moose.wildcardFind( '/model/elec/##[ISA=CompartmentBase]' ) - L = cellLongAxis( compts ) - for k,p in zip( compts, pv ): - moose.connect( p, 'requestOut', k, fieldname ) - # We do not know ahead of time what the orientation of - # the cell is. - # Assume a cell long axis vector L. - # Assume integration is in the plane orthogonal to r. - # Assume soma roughly at 0,0,0 - dy = np.dot( L, [k.x-i.ex, k.y-i.ey, k.z-i.ez] ) - - #dx = k.x-i.ex - #dy = k.y-i.ey - #dz = k.z-i.ez - # This is the wrong, but easy version - #r = np.sqrt( dx*dx + dy*dy + dz*dz ) - #i.wts.append( fepspScale/r ) - # - # Here is the correct version, integrating over the - # pyramidal cell layer. - ret = fepspInteg(i.fepspMax, dy) - \ - fepspInteg(i.fepspMin, dy) - i.wts.append( ret * fepspScale ) - - - return elif i.field in epscFields: # Do EPSC stuff. fieldname = 'getCurrent' ''' @@ -1060,7 +959,7 @@ def putReadoutsInQ( q, readouts, pauseHsolve ): stdError = [] plotLookup = {} for i in readouts: - if i.field in (fepspFields + epspFields + epscFields): + if i.field in (epspFields + epscFields): for j in range( len( i.data ) ): t = float( i.data[j][0] ) * i.timeScale heapq.heappush( q, Qentry(t, pauseHsolve, 1) ) # Turn on hsolve @@ -1093,6 +992,7 @@ def deliverStim( qe, model ): #print(" Setting Vclamp {} to {}".format( path, qe.val )) else: e.setField( field, qe.val ) + #print qe.t, e.path, field, qe.val #print( "########Stim = {} {} {} {} {}".format( qe.t, moose.element( '/model/elec/head0/glu' ).modulation, moose.element( '/model/chem/spine/Ca' ).conc, moose.element( '/model/elec/head0/Ca_conc' ).Ca, moose.element( '/model/elec/head0/glu/sh/synapse' ).weight ) ) if qe.t == 0: ## At time zero we initial the value concInit or nInit @@ -1121,34 +1021,11 @@ def doReadout( qe, model ): ratioReference = 0.0 if readout.field in (epspFields + epscFields): doEpspReadout( readout, model.modelLookup ) - elif readout.field in fepspFields: - doFepspReadout( readout, model.modelLookup ) elif val == -1: # This is a special event to get RatioReferenceValue doReferenceReadout( readout, model.modelLookup, readout.field ) else: doEntityAndRatioReadout(readout, model.modelLookup, readout.field) -def doFepspReadout( readout, modelLookup ): - n = int( round( readout.epspWindow / readout.epspPlot.dt ) ) - assert( n > 5 ) - pts = np.zeros( n ) - numPlots = len( readout.epspPlot.vec ) - assert( numPlots == len( readout.wts ) ) - for i, wt in zip( readout.epspPlot.vec, readout.wts ): - pts += np.array( i.vector[-n:] ) * wt - #pts = np.array( readout.epspPlot.vector[-n:] ) - pts /= len( readout.epspPlot.vec ) - #print( "DOING EPSP READOUT WITH " + readout.field ) - #print( ["{:.3g} ".format( x ) for x in pts] ) - if "slope" in readout.field: - dpts = pts[1:] - pts[:-1] - slope = max( abs( dpts ) )/readout.epspPlot.dt - readout.simData.append( slope ) - elif "peak" in readout.field: - pts -= pts[0] - pk = max( abs(pts) ) - readout.simData.append( pk ) - def doEpspReadout( readout, modelLookup ): n = int( round( readout.epspWindow / readout.epspPlot.dt ) ) assert( n > 5 ) @@ -1260,8 +1137,6 @@ def runDoser( model, stim, readout, doseMol ): doseScale = stim.quantityScale referenceDose = readout.ratioReferenceDose * stim.quantityScale sim = 0.0 - dts = moose.element('/clock').dts - #print( "In runDoser: settle time {:.2f}, dt = {:.3f}, {:.3f}".format( readout.settleTime, dts[10], dts[16] ) ) for dose, response, sem in readout.data: doseMol.concInit = dose * doseScale moose.reinit() @@ -1454,15 +1329,13 @@ def loadTsv( fname ): model = Model.load(fd ) return expt, stims, readouts, model -def buildSolver( modelId, solver, useVclamp = False, turnOffElec = False ): +def buildSolver( modelId, solver, useVclamp = False ): # Here we remove and rebuild the HSolver because we have to add vclamp # after loading the model. if useVclamp: if moose.exists( '/model/elec/hsolve' ): - raise SimError( "Hsolve already created. Please rebuild \ - model without HSolve." ) - - if (not turnOffElec) and moose.exists( '/model/elec/soma' ) and not moose.exists( '/model/elec/hsolve' ): + raise SimError( "Hsolve already created. Please rebuild model without HSolve. In rdesigneur use the 'turnOffElec = True' flag." ) + if moose.exists( '/model/elec/soma' ) and not moose.exists( '/model/elec/hsolve' ): for i in range( 9 ): moose.setClock( i, elecDt ) moose.setClock( 8, elecPlotDt ) @@ -1486,6 +1359,7 @@ def buildSolver( modelId, solver, useVclamp = False, turnOffElec = False ): stoich = moose.Stoich( compt.path + '/stoich' ) stoich.compartment = moose.element( compt.path ) stoich.ksolve = ksolve + #print( "Path = " + compt.path + "/##" ) stoich.path = compt.path + '/##' def buildVclamp( stim, modelLookup ): @@ -1500,6 +1374,7 @@ def buildVclamp( stim, modelLookup ): vclamp.td = 5e-6 # Differential time. Should it be >= dt? #vclamp.gain = 0.00005 # Gain of vclamp ckt used for squid: 500x500um vclamp.gain = compt.Cm * 5e3 # assume SI units. Scaled by area so that gain is reasonable. Needed to avert NaNs. + #print( "Building Vclamp on {}. Compt Cm = {}".format( path, compt.Cm )) # Connect voltage clamp circuitry moose.connect( compt, 'VmOut', vclamp, 'sensedIn' ) @@ -1524,6 +1399,7 @@ def getUniqueName( model, obj ): assert( len( wf ) > 0 ) if len( wf ) == 1: return pa + "/" + obj.name + print ("Concinit = {}".format( obj.concInit ) ) raise SimError( "getUniqueName: {} and {} non-unique, please rename.".format( wf[0].path, wf[1].path ) ) return obj.name @@ -1588,17 +1464,16 @@ def main(): parser.add_argument( '-m', '--model', type = str, help='Optional: model filename, .g or .xml', default = "" ) parser.add_argument( '-d', '--dump_subset', type = str, help='Optional: dump selected subset of model into named file', default = "" ) parser.add_argument( '-p', '--param_file', type = str, help='Optional: Generate file of tweakable params belonging to selected subset of model', default = "" ) - parser.add_argument( '-t', '--tabulate_output', action="store_true", help='Flag: Print table of plot values. Default is NOT to print table' ) parser.add_argument( '-hp', '--hide_plot', action="store_true", help='Hide plot output of simulation along with expected values. Default is to show plot.' ) parser.add_argument( '-hs', '--hide_subplots', action="store_true", help='Hide subplot output of simulation. By default the graphs include dotted lines to indicate individual quantities (e.g., states of a molecule) that are being summed to give a total response. This flag turns off just those dotted lines, while leaving the main plot intact.' ) parser.add_argument( '-o', '--optimize_elec', action="store_true", help='Optimize electrical computation. By default the electrical computation runs for the entire duration of the simulation. With this flag the system turns off the electrical engine except during the times when electrical stimuli are being given. This can be *much* faster.' ) parser.add_argument( '-s', '--scale_param', nargs=3, default=[], help='Scale specified object.field by ratio.' ) parser.add_argument( '-settle_time', '--settle_time', type=float, default=0, help='Run model for specified settle time and return dict of {path,conc}.' ) args = parser.parse_args() - innerMain( args.script, modelFile = args.model, dumpFname = args.dump_subset, paramFname = args.param_file, hidePlot = args.hide_plot, hideSubplots = args.hide_subplots, optimizeElec = args.optimize_elec, scaleParam = args.scale_param, settleTime = args.settle_time, tabulateOutput = args.tabulate_output ) + innerMain( args.script, modelFile = args.model, dumpFname = args.dump_subset, paramFname = args.param_file, hidePlot = args.hide_plot, hideSubplots = args.hide_subplots, optimizeElec = args.optimize_elec, scaleParam = args.scale_param, settleTime = args.settle_time ) -def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFname = "", hidePlot = True, hideSubplots = False, optimizeElec=True, silent = False, scaleParam=[], settleTime = 0, settleDict = {}, tabulateOutput = False ): +def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFname = "", hidePlot = True, hideSubplots = False, optimizeElec=True, silent = False, scaleParam=[], settleTime = 0, settleDict = {} ): ''' If *settleTime* > 0, then we need to return a dict of concs of all variable pools in the chem model obtained after loading in model, applying all modifications, and running for specified settle time.\n @@ -1611,9 +1486,6 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna modelWarning = "" modelId = "" expt, stims, readouts, model = loadTsv( script ) - for r in readouts: - r.tabulateOutput = tabulateOutput - if modelFile != "": model.fileName = modelFile model.pauseHsolve = PauseHsolve( optimizeElec ) @@ -1635,33 +1507,16 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna # the model. At this point the model must be in the current dir mscript = imp.load_source( "mscript", model.fileName ) #mscript = __import__( fileName ) - rdes = mscript.load() - if not moose.exists( '/library/chem' ): - modelId = moose.Neutral( '/library/chem' ) - else: - modelId = moose.element( '/library/chem' ) + modelId = mscript.load() + - mpath = modelId.path - for f in moose.wildcardFind('{0}/##[ISA=ReacBase],{0}/##[ISA=EnzBase]'.format( mpath ) ): + for f in moose.wildcardFind('/model/##[ISA=ReacBase],/model/##[ISA=EnzBase]'): erSPlist[f] = {'s':len(f.neighbors['sub']), 'p':len(f.neighbors['prd'])} # Then we apply whatever modifications are specified by user or protocol modelWarning = "" - # We have to scale params _before_ modifying the model since the - # expt modifications override anything done to the model params. - model._scaleParams( scaleParam ) model.modify( modelId, erSPlist,modelWarning ) - #moose.le( '/library/chem/compartment_1' ) - turnOffElec = False - if file_extension == ".py": - # Here we override the rdes to NOT make a solver. - turnOffElec = rdes.turnOffElec - rdes.turnOffElec = True - mscript.build( rdes ) - rdes.turnOffElec = turnOffElec - #turnOffElec = rdes.turnOffElec - moose.reinit() - + model._scaleParams( scaleParam ) if len(dumpFname) > 2: if dumpFname[-2:] == '.g': moose.mooseWriteKkit( modelId.path, dumpFname ) @@ -1687,6 +1542,21 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna moose.delete( '/library' ) return score + ''' + for i in stims: + if i.field == 'Vclamp': + buildVclamp( i, model.modelLookup ) + ''' + + + ''' + if stims[0].field == 'Vclamp': + readouts[0].entities = ['vclamp'] + #readouts[0].field = 'current' + buildVclamp( stims[0], model.modelLookup ) + ''' + + hasVclamp = False readoutStim = stims[0] for i in stims: @@ -1697,33 +1567,37 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna readoutStim = i if len(i.entities) > 0 and i.entities[0].lower() == 'syninput': readoutStim = i - if readouts[0].field in ( fepspFields + epspFields + epscFields ): + if readouts[0].field in ( epspFields + epscFields ): readouts[0].stim = readoutStim makeReadoutPlots( readouts, model.modelLookup ) if hasVclamp: #build the solver with a flag to say rebuild the hsolve. buildSolver( modelId, model.solver, useVclamp = True ) else: - buildSolver( modelId, model.solver, turnOffElec = turnOffElec ) + buildSolver( modelId, model.solver ) if file_extension != '.py': # rdesigneur sims will set own clocks for i in range( 10, 20 ): moose.setClock( i, 0.1 ) + ############################################################## # Here we handle presettling. First to generate, then to apply # the dict of settled values. if settleTime > 0: t0 = time.time() moose.reinit() + #print settleTime moose.start( settleTime ) w = moose.wildcardFind( modelId.path + "/##[ISA=PoolBase]" ) ret = {} for i in w: if not i.isBuffered: ret[i.path] = i.n + #print( "{}.nInit = {:.3f}".format( i.path, i.n )) + #print "-------------------- settle done -------------------" moose.delete( modelId ) if moose.exists( '/library' ): moose.delete( '/library' ) - print( "Done global settle time {:.2f} in {:.2f} seconds".format( settleTime, time.time()-t0)) + #print( "Done settling in {:.2f} seconds".format( time.time()-t0)) print( "s", end = '' ) sys.stdout.flush() return ret @@ -1753,12 +1627,11 @@ def innerMain( script, modelFile = "model/synSynth7.g", dumpFname = "", paramFna except SimError as msg: if not silent: print( "Error: findSim failed for script {}: {}".format(script, msg )) - if moose.exists( '/model' ): - moose.delete( '/model' ) - if moose.exists( '/library' ): - moose.delete( '/library' ) + if modelId: + moose.delete( modelId ) + if moose.exists( '/library' ): + moose.delete( '/library' ) return -1.0 - # Run the 'main' if this script is executed standalone. if __name__ == '__main__': main() From 929e1069c88be6548c7c23aef9f74191de4ad4c6 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 15:11:06 +0530 Subject: [PATCH 16/28] Added mpld3 and networkx to dependencies. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 2694917..4d13292 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,7 @@ long_description_content_type = "text/markdown", packages = [ "FindSim" ], package_dir = { "FindSim" : "."}, - install_requires = [ 'pymoose', 'scipy' ], + install_requires = [ 'pymoose', 'scipy', 'mpld3', 'networkx' ], author = "Dilawar Singh", # author of packaging. See contributors for # the list of authors author_email = "dilawar@ncbs.res.in", From 82b675f1af692b5825684f675180020aa14fb2fe Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 15:28:37 +0530 Subject: [PATCH 17/28] Fixes to make sure that findSim.py and runAllParallel.py can also be invoked as scripts. --- __init__.py | 3 --- findSim.py | 8 +++----- runAllParallel.py | 9 ++++++++- test.sh | 21 ++++++++++++--------- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/__init__.py b/__init__.py index b901bca..e69de29 100644 --- a/__init__.py +++ b/__init__.py @@ -1,3 +0,0 @@ -from FindSim import findSim -from FindSim import runAllParallel -__all__ = [ "findSim", "runAllParallel"] diff --git a/findSim.py b/findSim.py index 14a3b5a..3631847 100644 --- a/findSim.py +++ b/findSim.py @@ -33,9 +33,8 @@ **********************************************************************/ ''' -from __future__ import print_function +from __future__ import print_function, absolute_import import heapq -#import pylab import numpy as np import sys import argparse @@ -45,8 +44,8 @@ import ntpath import time import imp # This is apparently deprecated in Python 3.4 and up - -import matplotlib.pyplot as pyplot,mpld3 +import matplotlib.pyplot as pyplot +import mpld3 #mpld3 hack # suggested: https://github.com/mpld3/mpld3/issues/434 @@ -60,7 +59,6 @@ def default(self, obj): from mpld3 import _display _display.NumpyEncoder = NumpyEncoder - convertTimeUnits = {('sec','s') : 1.0, ('ms','millisec', 'msec') : 1e-3,('us','microsec') : 1e-6, ('ns','nanosec') : 1e-9, ('min','m') : 60.0, diff --git a/runAllParallel.py b/runAllParallel.py index 6264ae4..c0b3c0d 100644 --- a/runAllParallel.py +++ b/runAllParallel.py @@ -43,9 +43,16 @@ import sys import argparse import time -from . import findSim from multiprocessing import Pool +# Python's pain (import and scripts). See https://stackoverflow.com/a/49480246/1805129 +# This 'hack' is here to make sure that `python runAllParallel.py` also works +# and described in old documents. +if __package__ is None or __package__ == '': + import findSim +else: + from FindSim import findSim + resultCount = 0 def reportReturn( result ): global resultCount diff --git a/test.sh b/test.sh index d868a58..fcee08f 100755 --- a/test.sh +++ b/test.sh @@ -16,10 +16,12 @@ else $PYTHON -m pip install matplotlib --upgrade $PYTHON -m pip install --upgrade fi -$PYTHON -m pip install Jinja2 -$PYTHON -m pip install mpld3 -$PYTHON -m pip install pymoose --pre --upgrade -$PYTHON -m pip install pylint numpy --upgrade + +$PYTHON setup.py install --user +# $PYTHON -m pip install Jinja2 +# $PYTHON -m pip install mpld3 +# $PYTHON -m pip install pymoose --pre --upgrade +# $PYTHON -m pip install pylint numpy --upgrade find . -type f -name "*.py" | xargs -I file $PYTHON -m pylint \ --disable=no-member \ @@ -32,9 +34,10 @@ for _tsv in $(find ./TestTSV -name *.tsv -type f); do $PYTHON findSim.py ${_tsv} --model models/synSynth7.g done -$PYTHON findSim.py ./Curated/FindSim-Jain2009_Fig4F.tsv --model models/synSynth7.g -$PYTHON findSim.py ./Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g +findsim ./Curated/FindSim-Jain2009_Fig4F.tsv --model models/synSynth7.g +findsim ./Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g # Following takes a lot of time to run. -#$PYTHON findSim.py ./Curated/FindSim-Gu2004_fig3B.tsv --model models/synSynth7.g -$PYTHON findSim.py ./Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g -$PYTHON findSim.py ./Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g +#findsim ./Curated/FindSim-Gu2004_fig3B.tsv --model models/synSynth7.g +findsim ./Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g +findsim ./Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g +findsim_parallel Curated -N 8 From 5f14c18eeb6eccce6660b67753aea81cc3c493d8 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 15:36:56 +0530 Subject: [PATCH 18/28] virtualenv error on travis. --- .travis.yml | 1 + test.sh | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ad4053c..640e5ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,5 @@ before_script: script: - cp ./.travis/matplotlibrc . + - python -m pip install - ./test.sh diff --git a/test.sh b/test.sh index fcee08f..e583ddf 100755 --- a/test.sh +++ b/test.sh @@ -17,7 +17,7 @@ else $PYTHON -m pip install --upgrade fi -$PYTHON setup.py install --user +# travis.yml should install FindSim # $PYTHON -m pip install Jinja2 # $PYTHON -m pip install mpld3 # $PYTHON -m pip install pymoose --pre --upgrade @@ -40,4 +40,4 @@ findsim ./Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g #findsim ./Curated/FindSim-Gu2004_fig3B.tsv --model models/synSynth7.g findsim ./Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g findsim ./Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g -findsim_parallel Curated -N 8 +findsim_parallel Curated -n 4 From 678895fbc66357943637d360aa3ec95819d3918f Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 15:39:25 +0530 Subject: [PATCH 19/28] typo. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 640e5ad..2e96af0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,5 +13,5 @@ before_script: script: - cp ./.travis/matplotlibrc . - - python -m pip install + - python -m pip install . - ./test.sh From 086107420bb49059ae96d7a121d74cb06c4b0794 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 15:42:36 +0530 Subject: [PATCH 20/28] Install pylint as well. --- test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test.sh b/test.sh index e583ddf..c8259f4 100755 --- a/test.sh +++ b/test.sh @@ -18,10 +18,10 @@ else fi # travis.yml should install FindSim -# $PYTHON -m pip install Jinja2 +$PYTHON -m pip install Jinja2 --upgrade +$PYTHON -m pip install pylint --upgrade # $PYTHON -m pip install mpld3 # $PYTHON -m pip install pymoose --pre --upgrade -# $PYTHON -m pip install pylint numpy --upgrade find . -type f -name "*.py" | xargs -I file $PYTHON -m pylint \ --disable=no-member \ From a924bd56e349290572a09677fbe37a47c63703ad Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 16:00:10 +0530 Subject: [PATCH 21/28] Use latest moose, else tests will fail. 3.1.4 (last stable) is not over a year old!! --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 2e96af0..f119570 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,5 @@ before_script: script: - cp ./.travis/matplotlibrc . - python -m pip install . + - python -m pip install pymoose --pre --upgrade # till we relase 3.2.0 - ./test.sh From c273946e4116d436bd0211faa092fddb8f172bb9 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 16:21:02 +0530 Subject: [PATCH 22/28] use timeout when running in paralle. --- .travis.yml | 2 +- test.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index f119570..7db9b6f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ script: - cp ./.travis/matplotlibrc . - python -m pip install . - python -m pip install pymoose --pre --upgrade # till we relase 3.2.0 - - ./test.sh + - ./test.sh diff --git a/test.sh b/test.sh index c8259f4..9a73238 100755 --- a/test.sh +++ b/test.sh @@ -40,4 +40,4 @@ findsim ./Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g #findsim ./Curated/FindSim-Gu2004_fig3B.tsv --model models/synSynth7.g findsim ./Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g findsim ./Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g -findsim_parallel Curated -n 4 +timeout 60 findsim_parallel Curated -n 4 || echo "Timedout. We call it success!" From 6ef4bc2a471216570b72639391a4f17336d027b4 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 18:32:52 +0530 Subject: [PATCH 23/28] old command line executing and new module based executing are working fine with python2 and python3 locally. --- __main__.py | 4 ++-- requirements.txt | 3 +++ runAllParallel.py | 13 ++++++++----- test.sh | 3 ++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/__main__.py b/__main__.py index 85a7513..06bfcc5 100644 --- a/__main__.py +++ b/__main__.py @@ -10,13 +10,13 @@ __email__ = "dilawars@ncbs.res.in" __status__ = "Development" -from FindSim import findSim -from FindSim import runAllParallel def run(): + from FindSim import findSim findSim.main() def run_parallel(): + from FindSim import runAllParallel runAllParallel.main() if __name__ == '__main__': diff --git a/requirements.txt b/requirements.txt index b485fe7..4fe1a87 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,6 @@ numpy matplotlib networkx +pymoose +mpld3 +scipy diff --git a/runAllParallel.py b/runAllParallel.py index c0b3c0d..73daa8e 100644 --- a/runAllParallel.py +++ b/runAllParallel.py @@ -35,8 +35,8 @@ directory, computes their scores, and prints out basic stats of the scores. It can do this in parallel using Python's multiprocessing library. ''' +from __future__ import print_function, division -from __future__ import print_function, division, absolute_import import numpy import argparse import os @@ -45,13 +45,16 @@ import time from multiprocessing import Pool -# Python's pain (import and scripts). See https://stackoverflow.com/a/49480246/1805129 +# Python 2/3 pain (import and scripts). See https://stackoverflow.com/a/49480246/1805129 # This 'hack' is here to make sure that `python runAllParallel.py` also works # and described in old documents. -if __package__ is None or __package__ == '': - import findSim +if sys.version_info.major > 2: + if __package__ is None or __package__ == '': + import findSim + else: + from FindSim import findSim else: - from FindSim import findSim + import findSim resultCount = 0 def reportReturn( result ): diff --git a/test.sh b/test.sh index 9a73238..908ed4f 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -e +set -x # virtualenv does not require --user PYTHON=$(which python) @@ -14,7 +15,7 @@ if [ "$PYTHON_VERSION" -eq "27" ]; then else # $PYTHON -m pip uninstall matplotlib -y || echo "Failed to remove matplotlib" $PYTHON -m pip install matplotlib --upgrade - $PYTHON -m pip install --upgrade + $PYTHON -m pip install scipy --upgrade fi # travis.yml should install FindSim From 79c07aedd9ff8f96249724362e6a981efbbcd84a Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 18:37:23 +0530 Subject: [PATCH 24/28] bumped version for PyPI. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4d13292..4c0e6dd 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ with open("README.md") as f: readme = f.read() -version_ = '1.0.0' +version_ = '1.0.1' isPre_ = True if isPre_: import datetime From e429f0d9bdf3d9034a528b6078c6c4d7256db237 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 18:38:57 +0530 Subject: [PATCH 25/28] Version bumped after merging. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 4c0e6dd..db8224e 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ with open("README.md") as f: readme = f.read() -version_ = '1.0.1' +version_ = '1.0.2' isPre_ = True if isPre_: import datetime From 73a6bcc1e93e7d158b1d15158acebd7e9cd43db5 Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Tue, 11 Jun 2019 19:02:34 +0530 Subject: [PATCH 26/28] disable +x from the test script. Ready to be reviewed. --- test.sh | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/test.sh b/test.sh index 908ed4f..6a566fd 100755 --- a/test.sh +++ b/test.sh @@ -1,7 +1,5 @@ #!/usr/bin/env bash - set -e -set -x # virtualenv does not require --user PYTHON=$(which python) @@ -35,10 +33,10 @@ for _tsv in $(find ./TestTSV -name *.tsv -type f); do $PYTHON findSim.py ${_tsv} --model models/synSynth7.g done -findsim ./Curated/FindSim-Jain2009_Fig4F.tsv --model models/synSynth7.g -findsim ./Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g +time findsim ./Curated/FindSim-Jain2009_Fig4F.tsv --model models/synSynth7.g +time findsim ./Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g # Following takes a lot of time to run. #findsim ./Curated/FindSim-Gu2004_fig3B.tsv --model models/synSynth7.g -findsim ./Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g -findsim ./Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g +time findsim ./Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g +time findsim ./Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g timeout 60 findsim_parallel Curated -n 4 || echo "Timedout. We call it success!" From d73804938a94ae5f3044db430e3a57e0d812596f Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Fri, 14 Jun 2019 11:26:53 +0530 Subject: [PATCH 27/28] HOTFIX: Some fixes from static code anaylysis. Variables names were not changed everywhere. --- findSim.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/findSim.py b/findSim.py index 3631847..00c448c 100644 --- a/findSim.py +++ b/findSim.py @@ -717,7 +717,7 @@ def isNotDescendant( elm, ancestorSet ): def getObjParam( elm, field ): if field == 'Kd': if not elm.isA['ReacBase']: - raise SimError( "getObjParam: can only get Kd on a Reac, was: '{}'".format( obj.className ) ) + raise SimError( "getObjParam: can only get Kd on a Reac, was: '{}'".format( elm.className ) ) return elm.Kb/elm.Kf elif field == 'tau': # This is a little dubious, because order 1 reac has 1/conc.time @@ -725,7 +725,7 @@ def getObjParam( elm, field ): # This latter is the Kf we want to use, assuming typical concs are # around 1 uM. if not elm.isA['ReacBase']: - raise SimError( "getObjParam: can only get tau on a Reac, was: '{}'".format( obj.className ) ) + raise SimError( "getObjParam: can only get tau on a Reac, was: '{}'".format( elm.className ) ) scaleKf = 0.001 ** (elm.numSubstrates-1) scaleKb = 0.001 ** (elm.numProducts-1) #print( "scaleKf={}; scaleKb={}, numsu ={}, numPrd={},Kb={},Kf={}".format( scaleKf, scaleKb, elm.numSubstrates, elm.numProducts, elm.Kb, elm.Kf ) ) @@ -1109,7 +1109,7 @@ def parseAndRunDoser( model, stims, readouts, modelId ): exactly one stimulus block, {} defined".format( len(stims)) ) if len( readouts ) != 1: raise SimError( "parseAndRunDoser: Dose response run needs \ - exactly one readout block, {} defined".format( len(readout) ) ) + exactly one readout block, {} defined".format( len(readouts) ) ) numLevels = len( readouts[0].data ) if numLevels == 0: @@ -1206,7 +1206,7 @@ def parseAndRunBarChart( model, stims, readouts, modelId ): one stimulus block, {} defined".format( len( stims ) ) ) if len( readouts ) != 1: raise SimError( "parseAndRunBarChart: BarChart run needs exactly \ - one readout block, {} defined".format( len( readout ) ) ) + one readout block, {} defined".format( len( readouts ) ) ) numLevels = len( readouts[0].data ) if numLevels == 0: From ffedc847d0d7b995d023fd0a44ef71510c6aad3c Mon Sep 17 00:00:00 2001 From: Dilawar Singh Date: Fri, 14 Jun 2019 11:57:09 +0530 Subject: [PATCH 28/28] pylint is now strict; and it ignore mehtod overshadow created by mpl3d hack. --- findSim.py | 7 +++++-- test.sh | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/findSim.py b/findSim.py index 00c448c..da49ef5 100644 --- a/findSim.py +++ b/findSim.py @@ -45,17 +45,20 @@ import time import imp # This is apparently deprecated in Python 3.4 and up import matplotlib.pyplot as pyplot -import mpld3 -#mpld3 hack +# mpld3 hack # suggested: https://github.com/mpld3/mpld3/issues/434 import json + class NumpyEncoder(json.JSONEncoder): + # pylint: disable=method-hidden def default(self, obj): import numpy as np if isinstance(obj, np.ndarray): return obj.tolist() return json.JSONEncoder.default(self, obj) + +import mpld3 from mpld3 import _display _display.NumpyEncoder = NumpyEncoder diff --git a/test.sh b/test.sh index 6a566fd..8d954fc 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,21 @@ #!/usr/bin/env bash set -e +INVENV=$(python -c 'import sys; print ("1" if hasattr(sys, "real_prefix") else "")') + +echo "INVENV ${INVENV}" +if [ -z "$INVENV" ]; then + if [ -z "$TRAVIS" ]; then + echo "Not on travis. I'll set a virtualenv for you" + python -m pip install virtualenv --user --upgrade + virtualenv -p $(which python) /tmp/envPY + source /tmp/envPY/bin/activate + fi +else + echo "Already in virtualenv. How cool!" +fi + +# FROM NOW ON WE MUST BE IN A VIRTUALENV. # virtualenv does not require --user PYTHON=$(which python) @@ -19,13 +34,18 @@ fi # travis.yml should install FindSim $PYTHON -m pip install Jinja2 --upgrade $PYTHON -m pip install pylint --upgrade -# $PYTHON -m pip install mpld3 -# $PYTHON -m pip install pymoose --pre --upgrade +$PYTHON -m pip install mpld3 +$PYTHON -m pip install pymoose --pre --upgrade +$PYTHON -m pip install . +echo "PYLINT START=======================================================" find . -type f -name "*.py" | xargs -I file $PYTHON -m pylint \ --disable=no-member \ - --exit-zero \ + --generated-members=moose \ -E file +echo "========================================================PYLINT DONE" +echo " " +echo " " # Run it in ./TestTSV directory. for _tsv in $(find ./TestTSV -name *.tsv -type f); do @@ -40,3 +60,10 @@ time findsim ./Curated/FindSim-Bhalla1999_fig2B.tsv --model models/synSynth7.g time findsim ./Curated/FindSim-Ji2010_fig1C_ERK_acute.tsv --model models/synSynth7.g time findsim ./Curated/FindSim-Bhalla1999_fig4C.tsv --model models/synSynth7.g timeout 60 findsim_parallel Curated -n 4 || echo "Timedout. We call it success!" + +# deactivate venv if we are in it. +if [ ! -z "$INVENV" ]; then + if [ -z "$TRAVIS" ]; then + deactivate + fi +fi