Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[neuron-writer] how can one set the tolerance value? #103

Open
7 of 10 tasks
sanjayankur31 opened this issue Aug 4, 2023 · 14 comments
Open
7 of 10 tasks

[neuron-writer] how can one set the tolerance value? #103

sanjayankur31 opened this issue Aug 4, 2023 · 14 comments

Comments

@sanjayankur31
Copy link
Member

sanjayankur31 commented Aug 4, 2023

I'm running some sims here and getting lots of nan values. Apparently, to workaround this, one has to reduce the tolerance value used in NEURON:

https://nrn.readthedocs.io/en/8.2.2/hoc/simctrl/cvode.html#CVode.atol

How would one do this while using NeuroML to generate NEURON code? (I don't think we have a way to do it yet?)

A workaround would be to generate the python script and then add a line to it, but this isn't ideal.

Edit: tasks:

  • add Meta tag to LEMS schema (optional, since we don't always validate LEMS files against the schema)
  • annotate Meta in jLEMS (https://docs.neuroml.org/Userdocs/LEMS_elements/Definingcomponenttypes.html#meta -> needs improvement)
  • check that meta tag contents are exposed in writers
  • add special case for handling cvode in neuron writer
  • add example for testing, also in NEURON Showcase
  • update LEMS_TEMPLATE in pyNeuroML to include Meta
  • update LEMSSimulation to add method to include Meta
  • regenerate docs.neuroml.org with update Meta annotation
  • add special case for handling cvode in netpyne writer
  • update lems simulation documentation to include netpyne options
@borismarin
Copy link
Contributor

IIRC generated neuron code does not use the variable stepsize solver (cvode) - but it could: we would first need a way to specify that cvode is to be used. Not sure if that would go in the Lems definition, but jLems implements two integration methods, 4th order Runge Kutta (default) or Euler, which can be selected using the method attribute). So, we could have an additional (neuron specific) integration method (jlems would have to ignore it).

Once cvode is selected, we won't have evenly spaced points in time (i.e. time won't necessarily be an integer multiple of the dt attribute), and error tolerances should be specified instead, using eg atol as mentioned (yet another new attribute, also disregarded by jLems).

If those Simulation attrs are defined, it shouldn't be hard to update NeuronWriter.java to enable cvode and set the appropriate tolerance.

@sanjayankur31
Copy link
Member Author

Thanks @borismarin , that makes sense. I think the ability to specify arbitrary simulator specific integration methods (or just a way to provide simulator specific code snippets that LEMS can ignore and "pass through" to the simulation engines) is perhaps a good general addition that we should look into. @pgleeson : what do you think?

@pgleeson
Copy link
Member

pgleeson commented Aug 9, 2023

The closest thing to this is the recommended_dt_ms and recommended_duration_ms properties: https://github.com/NeuroML/NeuroMLlite/blob/master/examples/Example4_PyNN.net.nml#L14

Though these go in the network file and are generally used if the nml file is found on its own, to help generate a useful lems file (e.g. simulating on osb v1, but copuld be used when importing the nml (not lems) into netpyne...).

I can't think of any example of a lems file that has metadata/properties with some simulator specific values. It certainly could be implemented in jnml, with jlems ignoring those options or refusing to run it, but it may be better to add general options for simulator specific info to neuromllite simulation files and more easily handle options for running them there, e.g. https://github.com/NeuroML/NeuroMLlite/blob/master/examples/Example4.py#L117, but that might require an update to the hoc/py files generated by NeuronWriter too...

@sanjayankur31
Copy link
Member Author

Just making a note: we do have a "Meta" tag that seems like it was included for this purpose. The LEMS interpreter ignores it, but it should be accessible in the neuron writer;

https://github.com/LEMS/jLEMS/blob/a7a7b8662498ae55719ad22d79049077ca2ca666/src/test/resources/ex-flat.xml#L54

I'll take a look to see if we can use this to specify cvode etc.

@sanjayankur31
Copy link
Member Author

LEMS/LEMS#29

@sanjayankur31
Copy link
Member Author

LEMS/jLEMS#113

@sanjayankur31
Copy link
Member Author

@sanjayankur31
Copy link
Member Author

sanjayankur31 commented Aug 23, 2023

Final PRs:

LEMS/jLEMS#114

and

#105

So, a file like this:

<Lems>
    
    <!-- 

        This LEMS file has been automatically generated using PyNeuroML v1.0.8 (libNeuroML v0.5.3)

     -->
    
    <!-- Specify which component to run -->
    <Target component="HHSim" reportFile="report.txt"/>

    <!-- Include core NeuroML2 ComponentType definitions -->
    <Include file="Cells.xml"/>
    <Include file="Networks.xml"/>
    <Include file="Simulation.xml"/>
    
    <Include file="NML2_SingleCompHHCell.nml"/>
    <Include file="NaConductance.channel.nml"/>
    <Include file="KConductance.channel.nml"/>
    <Include file="LeakConductance.channel.nml"/>
   
    <Simulation id="HHSim" length="500ms" step="0.05ms" target="net1" seed="12345">  <!-- Note seed: ensures same random numbers used every run -->
        <Meta for="neuron" method="cvode" abs_tolerance="0.0001" rel_tolerance="0.001" />
        
        <Display id="display0" title="Voltages" timeScale="1ms" xmin="-50.0" xmax="550.0" ymin="-90" ymax="50">
            <Line id="v" quantity="hhpop[0]/v" scale="1mV" color="#ffffff" timeScale="1ms"/>
        </Display>
        
        <OutputFile id="Volts_file" fileName="HHSim.v.dat">
            <OutputColumn id="v" quantity="hhpop[0]/v"/> 
        </OutputFile>
        
        <EventOutputFile id="Events_file" fileName="HHSim.v.spikes" format="ID_TIME">
            <EventSelection id="0" select="hhpop[0]" eventPort="spike"/> 
        </EventOutputFile>
        
    </Simulation>

</Lems>

generates:

'''
Neuron simulator export for:

Components:
    null (Type: notes)
    NaConductance (Type: ionChannelHH:  conductance=1.0E-11 (SI conductance))
    null (Type: notes)
    KConductance (Type: ionChannelHH:  conductance=1.0E-11 (SI conductance))
    null (Type: notes)
    LeakConductance (Type: ionChannelHH:  conductance=1.0E-11 (SI conductance))
    hhcell (Type: cell)
    pulseGen1 (Type: pulseGenerator:  delay=0.1 (SI time) duration=0.1 (SI time) amplitude=8.000000000000001E-11 (SI current))
    net1 (Type: network)
    HHSim (Type: Simulation:  length=0.5 (SI time) step=5.0E-5 (SI time))


    This NEURON file has been generated by org.neuroml.export (see https://github.com/NeuroML/org.neuroml.export)
         org.neuroml.export  v1.9.0
         org.neuroml.model   v1.9.0
         jLEMS               v0.10.7

'''

import neuron

import time
import datetime
import sys

import hashlib
h = neuron.h
h.load_file("stdlib.hoc")

h.load_file("stdgui.hoc")

h("objref p")
h("p = new PythonObject()")

class NeuronSimulation():

    def __init__(self, tstop, dt, seed=12345, abs_tol=0.0001, rel_tol=0.001):

        print("\n    Starting simulation in NEURON of %sms generated from NeuroML2 model...\n"%tstop)

        self.setup_start = time.time()
        self.seed = seed
        import socket
        self.report_file = open('report.txt','w')
        print('Simulator version:  %s'%h.nrnversion())
        self.report_file.write('# Report of running simulation with %s\n'%h.nrnversion())
        self.report_file.write('Simulator=NEURON\n')
        self.report_file.write('SimulatorVersion=%s\n'%h.nrnversion())

        self.report_file.write('SimulationFile=%s\n'%__file__)
        self.report_file.write('PythonVersion=%s\n'%sys.version.replace('\n',' '))
        print('Python version:     %s'%sys.version.replace('\n',' '))
        self.report_file.write('NeuroMLExportVersion=1.9.0\n')
        self.report_file.write('SimulationSeed=%s\n'%self.seed)
        self.report_file.write('Hostname=%s\n'%socket.gethostname())
        self.randoms = []
        self.next_global_id = 0  # Used in Random123 classes for elements using random(), etc. 

        self.next_spiking_input_id = 0  # Used in Random123 classes for elements using random(), etc. 

        '''
        Adding simulation Component(id=HHSim type=Simulation) of network/component: net1 (Type: network)
        
        '''
        # ######################   Population: hhpop
        print("Population hhpop contains 1 instance(s) of component: hhcell of type: cell")

        h.load_file("hhcell.hoc")
        a_hhpop = []
        h("{ n_hhpop = 1 }")
        h("objectvar a_hhpop[n_hhpop]")
        for i in range(int(h.n_hhpop)):
            h("a_hhpop[%i] = new hhcell()"%i)
            h("access a_hhpop[%i].soma"%i)

            self.next_global_id+=1


        h("proc initialiseV_hhpop() { for i = 0, n_hhpop-1 { a_hhpop[i].set_initial_v() } }")
        h("objref fih_hhpop")
        h('{fih_hhpop = new FInitializeHandler(0, "initialiseV_hhpop()")}')

        h("proc initialiseIons_hhpop() { for i = 0, n_hhpop-1 { a_hhpop[i].set_initial_ion_properties() } }")
        h("objref fih_ion_hhpop")
        h('{fih_ion_hhpop = new FInitializeHandler(1, "initialiseIons_hhpop()")}')

        # Adding single input: Component(id=null type=explicitInput)
        h("objref explicitInput_pulseGen1a_hhpop_0__soma")
        h("a_hhpop[0].soma { explicitInput_pulseGen1a_hhpop_0__soma = new pulseGen1(0.5) } ")

        trec = h.Vector()
        trec.record(h._ref_t)

        h.tstop = tstop

        cvode = h.CVode()
        cvode.active(1)
        cvode.atol(abs_tol)
        cvode.rtol(rel_tol)


        # ######################   File to save: HHSim.v.dat (Volts_file)
        # Column: hhpop[0]/v
        h(' objectvar v_v_Volts_file ')
        h(' { v_v_Volts_file = new Vector() } ')
        h(' { v_v_Volts_file.record(&a_hhpop[0].soma.v(0.5)) } ')
        h.v_v_Volts_file.resize((h.tstop * h.steps_per_ms) + 1)

        # ######################   File to save: HHSim.v.spikes (Events_file)
        h(' objectvar spiketimes_Events_file, t_spiketimes_Events_file ')
        h(' { spiketimes_Events_file = new Vector() } ')
        h(' { t_spiketimes_Events_file = new Vector() } ')
        h(' objref netConnSpike_Events_file, nil ')
        # Column: hhpop[0] (0) a_hhpop[0].soma
        h(' a_hhpop[0].soma { netConnSpike_Events_file = new NetCon(&v(0.5), nil, -20.0, 0, 1) } ')
        h(' { netConnSpike_Events_file.record(t_spiketimes_Events_file, spiketimes_Events_file, 0) } ')

        # ######################   File to save: time.dat (time)
        # Column: time
        h(' objectvar v_time ')
        h(' { v_time = new Vector() } ')
        h(' { v_time.record(&t) } ')
        h.v_time.resize((h.tstop * h.steps_per_ms) + 1)

        self.initialized = False

        self.sim_end = -1 # will be overwritten

        setup_end = time.time()
        self.setup_time = setup_end - self.setup_start
        print("Setting up the network to simulate took %f seconds"%(self.setup_time))

    def run(self):

        self.initialized = True
        sim_start = time.time()
        print("Running a simulation of %sms (dt = %sms; seed=%s)" % (h.tstop, h.dt, self.seed))

        try:
            h.run()
        except Exception as e:
            print("Exception running NEURON: %s" % (e))
            quit()


        self.sim_end = time.time()
        self.sim_time = self.sim_end - sim_start
        print("Finished NEURON simulation in %f seconds (%f mins)..."%(self.sim_time, self.sim_time/60.0))

        try:
            self.save_results()
        except Exception as e:
            print("Exception saving results of NEURON simulation: %s" % (e))
            quit()


    def advance(self):

        if not self.initialized:
            h.finitialize()
            self.initialized = True

        h.fadvance()


    ###############################################################################
    # Hash function to use in generation of random value
    # This is copied from NetPyNE: https://github.com/Neurosim-lab/netpyne/blob/master/netpyne/simFuncs.py
    ###############################################################################
    def _id32 (self,obj): 
        return int(hashlib.md5(obj.encode('utf-8')).hexdigest()[0:8],16)  # convert 8 first chars of md5 hash in base 16 to int


    ###############################################################################
    # Initialize the stim randomizer
    # This is copied from NetPyNE: https://github.com/Neurosim-lab/netpyne/blob/master/netpyne/simFuncs.py
    ###############################################################################
    def _init_stim_randomizer(self,rand, stimType, gid, seed): 
        #print("INIT STIM  %s; %s; %s; %s"%(rand, stimType, gid, seed))
        rand.Random123(self._id32(stimType), gid, seed)


    def save_results(self):

        print("Saving results at t=%s..."%h.t)

        if self.sim_end < 0: self.sim_end = time.time()


        # ######################   File to save: time.dat (time)
        py_v_time = [ t/1000 for t in h.v_time.to_python() ]  # Convert to Python list for speed...

        f_time_f2 = open('time.dat', 'w')
        num_points = len(py_v_time)  # Simulation may have been stopped before tstop...

        for i in range(num_points):
            f_time_f2.write('%f'% py_v_time[i])  # Save in SI units...
        f_time_f2.close()
        print("Saved data to: time.dat")

        # ######################   File to save: HHSim.v.dat (Volts_file)
        py_v_v_Volts_file = [ float(x  / 1000.0) for x in h.v_v_Volts_file.to_python() ]  # Convert to Python list for speed, variable has dim: voltage

        f_Volts_file_f2 = open('HHSim.v.dat', 'w')
        num_points = len(py_v_time)  # Simulation may have been stopped before tstop...

        for i in range(num_points):
            f_Volts_file_f2.write('%e\t%e\t\n' % (py_v_time[i], py_v_v_Volts_file[i], ))
        f_Volts_file_f2.close()
        print("Saved data to: HHSim.v.dat")

        # ######################   File to save: HHSim.v.spikes (Events_file)

        f_Events_file_f2 = open('HHSim.v.spikes', 'w')
        h(' objref netConnSpike_Events_file ')
        spike_ids = h.spiketimes_Events_file.to_python()  
        spike_times = h.t_spiketimes_Events_file.to_python()
        for i, id in enumerate(spike_ids):
            # Saving in format: ID_TIME
            f_Events_file_f2.write("%i\t%s\n"%(id,spike_times[i]/1000.0))
        f_Events_file_f2.close()
        print("Saved data to: HHSim.v.spikes")

        save_end = time.time()
        save_time = save_end - self.sim_end
        print("Finished saving results in %f seconds"%(save_time))

        self.report_file.write('StartTime=%s\n'%datetime.datetime.fromtimestamp(self.setup_start).strftime('%Y-%m-%d %H:%M:%S'))
        self.report_file.write('SetupTime=%s\n'%self.setup_time)
        self.report_file.write('RealSimulationTime=%s\n'%self.sim_time)
        self.report_file.write('SimulationSaveTime=%s\n'%save_time)
        self.report_file.close()

        print("Saving report of simulation to %s"%('report.txt'))

        print("Done")

        quit()


if __name__ == '__main__':

    ns = NeuronSimulation(tstop=500, dt=0.01, seed=12345)

    ns.run()

@sanjayankur31
Copy link
Member Author

I think this is also needed:

NeuroML/NeuroML2#214

@pgleeson
Copy link
Member

Great! It might be best though if you just make the __init__ independent of the settings, e.g. just add the values for abstol etc. in the __main__ and then set them to None in the __init__, as was done with dt. Then do a check for dt or abstol later in the init.

Idea there is that if it is run as main, it will use the set values, otherwise it is a class that can be imported elsewhere which requires these values to be set for it to be used correctly (think this is what happens in openworm's c302...)

@sanjayankur31
Copy link
Member Author

Cool, I'll go update it now.

@sanjayankur31
Copy link
Member Author

How does this look? It includes both, and setting the params for the cvode "enables it":

'''
Neuron simulator export for:

Components:
    null (Type: notes)
    NaConductance (Type: ionChannelHH:  conductance=1.0E-11 (SI conductance))
    null (Type: notes)
    KConductance (Type: ionChannelHH:  conductance=1.0E-11 (SI conductance))
    null (Type: notes)
    LeakConductance (Type: ionChannelHH:  conductance=1.0E-11 (SI conductance))
    hhcell (Type: cell)
    pulseGen1 (Type: pulseGenerator:  delay=0.1 (SI time) duration=0.1 (SI time) amplitude=8.000000000000001E-11 (SI current))
    net1 (Type: network)
    HHSim (Type: Simulation:  length=0.5 (SI time) step=5.0E-5 (SI time))


    This NEURON file has been generated by org.neuroml.export (see https://github.com/NeuroML/org.neuroml.export)
         org.neuroml.export  v1.9.0
         org.neuroml.model   v1.9.0
         jLEMS               v0.10.7

'''

import neuron

import time
import datetime
import sys

import hashlib
h = neuron.h
h.load_file("stdlib.hoc")

h.load_file("stdgui.hoc")

h("objref p")
h("p = new PythonObject()")

class NeuronSimulation():

    def __init__(self, tstop, dt=None, seed=12345, abs_tol=None, rel_tol=None):

        print("\n    Starting simulation in NEURON of %sms generated from NeuroML2 model...\n"%tstop)

        self.setup_start = time.time()
        self.seed = seed
        self.abs_tol = abs_tol
        self.rel_tol = rel_tol
        import socket
        self.report_file = open('report.txt','w')
        print('Simulator version:  %s'%h.nrnversion())
        self.report_file.write('# Report of running simulation with %s\n'%h.nrnversion())
        self.report_file.write('Simulator=NEURON\n')
        self.report_file.write('SimulatorVersion=%s\n'%h.nrnversion())

        self.report_file.write('SimulationFile=%s\n'%__file__)
        self.report_file.write('PythonVersion=%s\n'%sys.version.replace('\n',' '))
        print('Python version:     %s'%sys.version.replace('\n',' '))
        self.report_file.write('NeuroMLExportVersion=1.9.0\n')
        self.report_file.write('SimulationSeed=%s\n'%self.seed)
        self.report_file.write('Hostname=%s\n'%socket.gethostname())
        self.randoms = []
        self.next_global_id = 0  # Used in Random123 classes for elements using random(), etc. 

        self.next_spiking_input_id = 0  # Used in Random123 classes for elements using random(), etc. 

        '''
        Adding simulation Component(id=HHSim type=Simulation) of network/component: net1 (Type: network)
        
        '''
        # ######################   Population: hhpop
        print("Population hhpop contains 1 instance(s) of component: hhcell of type: cell")

        h.load_file("hhcell.hoc")
        a_hhpop = []
        h("{ n_hhpop = 1 }")
        h("objectvar a_hhpop[n_hhpop]")
        for i in range(int(h.n_hhpop)):
            h("a_hhpop[%i] = new hhcell()"%i)
            h("access a_hhpop[%i].soma"%i)

            self.next_global_id+=1


        h("proc initialiseV_hhpop() { for i = 0, n_hhpop-1 { a_hhpop[i].set_initial_v() } }")
        h("objref fih_hhpop")
        h('{fih_hhpop = new FInitializeHandler(0, "initialiseV_hhpop()")}')

        h("proc initialiseIons_hhpop() { for i = 0, n_hhpop-1 { a_hhpop[i].set_initial_ion_properties() } }")
        h("objref fih_ion_hhpop")
        h('{fih_ion_hhpop = new FInitializeHandler(1, "initialiseIons_hhpop()")}')

        # Adding single input: Component(id=null type=explicitInput)
        h("objref explicitInput_pulseGen1a_hhpop_0__soma")
        h("a_hhpop[0].soma { explicitInput_pulseGen1a_hhpop_0__soma = new pulseGen1(0.5) } ")

        trec = h.Vector()
        trec.record(h._ref_t)

        h.tstop = tstop

        if self.abs_tol is not None and self.rel_tol is not None:
            cvode = h.CVode()
            cvode.active(1)
            cvode.atol(self.abs_tol)
            cvode.rtol(self.rel_tol)
        else:
            h.dt = dt
            h.steps_per_ms = 1/h.dt



        # ######################   File to save: HHSim.v.dat (Volts_file)
        # Column: hhpop[0]/v
        h(' objectvar v_v_Volts_file ')
        h(' { v_v_Volts_file = new Vector() } ')
        h(' { v_v_Volts_file.record(&a_hhpop[0].soma.v(0.5)) } ')
        h.v_v_Volts_file.resize((h.tstop * h.steps_per_ms) + 1)

        # ######################   File to save: HHSim.v.spikes (Events_file)
        h(' objectvar spiketimes_Events_file, t_spiketimes_Events_file ')
        h(' { spiketimes_Events_file = new Vector() } ')
        h(' { t_spiketimes_Events_file = new Vector() } ')
        h(' objref netConnSpike_Events_file, nil ')
        # Column: hhpop[0] (0) a_hhpop[0].soma
        h(' a_hhpop[0].soma { netConnSpike_Events_file = new NetCon(&v(0.5), nil, -20.0, 0, 1) } ')
        h(' { netConnSpike_Events_file.record(t_spiketimes_Events_file, spiketimes_Events_file, 0) } ')

        # ######################   File to save: time.dat (time)
        # Column: time
        h(' objectvar v_time ')
        h(' { v_time = new Vector() } ')
        h(' { v_time.record(&t) } ')
        h.v_time.resize((h.tstop * h.steps_per_ms) + 1)

        self.initialized = False

        self.sim_end = -1 # will be overwritten

        setup_end = time.time()
        self.setup_time = setup_end - self.setup_start
        print("Setting up the network to simulate took %f seconds"%(self.setup_time))

    def run(self):

        self.initialized = True
        sim_start = time.time()
        if self.abs_tol is not None and self.rel_tol is not None:
            print("Running a simulation of %sms (cvode abs_tol = %sms, rel_tol = %sms; seed=%s)" % (h.tstop, self.abs_tol, self.rel_tol, self.seed))
        else:
            print("Running a simulation of %sms (dt = %sms; seed=%s)" % (h.tstop, h.dt, self.seed))

        try:
            h.run()
        except Exception as e:
            print("Exception running NEURON: %s" % (e))
            quit()


        self.sim_end = time.time()
        self.sim_time = self.sim_end - sim_start
        print("Finished NEURON simulation in %f seconds (%f mins)..."%(self.sim_time, self.sim_time/60.0))

        try:
            self.save_results()
        except Exception as e:
            print("Exception saving results of NEURON simulation: %s" % (e))
            quit()


    def advance(self):

        if not self.initialized:
            h.finitialize()
            self.initialized = True

        h.fadvance()


    ###############################################################################
    # Hash function to use in generation of random value
    # This is copied from NetPyNE: https://github.com/Neurosim-lab/netpyne/blob/master/netpyne/simFuncs.py
    ###############################################################################
    def _id32 (self,obj): 
        return int(hashlib.md5(obj.encode('utf-8')).hexdigest()[0:8],16)  # convert 8 first chars of md5 hash in base 16 to int


    ###############################################################################
    # Initialize the stim randomizer
    # This is copied from NetPyNE: https://github.com/Neurosim-lab/netpyne/blob/master/netpyne/simFuncs.py
    ###############################################################################
    def _init_stim_randomizer(self,rand, stimType, gid, seed): 
        #print("INIT STIM  %s; %s; %s; %s"%(rand, stimType, gid, seed))
        rand.Random123(self._id32(stimType), gid, seed)


    def save_results(self):

        print("Saving results at t=%s..."%h.t)

        if self.sim_end < 0: self.sim_end = time.time()


        # ######################   File to save: time.dat (time)
        py_v_time = [ t/1000 for t in h.v_time.to_python() ]  # Convert to Python list for speed...

        f_time_f2 = open('time.dat', 'w')
        num_points = len(py_v_time)  # Simulation may have been stopped before tstop...

        for i in range(num_points):
            f_time_f2.write('%f'% py_v_time[i])  # Save in SI units...
        f_time_f2.close()
        print("Saved data to: time.dat")

        # ######################   File to save: HHSim.v.dat (Volts_file)
        py_v_v_Volts_file = [ float(x  / 1000.0) for x in h.v_v_Volts_file.to_python() ]  # Convert to Python list for speed, variable has dim: voltage

        f_Volts_file_f2 = open('HHSim.v.dat', 'w')
        num_points = len(py_v_time)  # Simulation may have been stopped before tstop...

        for i in range(num_points):
            f_Volts_file_f2.write('%e\t%e\t\n' % (py_v_time[i], py_v_v_Volts_file[i], ))
        f_Volts_file_f2.close()
        print("Saved data to: HHSim.v.dat")

        # ######################   File to save: HHSim.v.spikes (Events_file)

        f_Events_file_f2 = open('HHSim.v.spikes', 'w')
        h(' objref netConnSpike_Events_file ')
        spike_ids = h.spiketimes_Events_file.to_python()  
        spike_times = h.t_spiketimes_Events_file.to_python()
        for i, id in enumerate(spike_ids):
            # Saving in format: ID_TIME
            f_Events_file_f2.write("%i\t%s\n"%(id,spike_times[i]/1000.0))
        f_Events_file_f2.close()
        print("Saved data to: HHSim.v.spikes")

        save_end = time.time()
        save_time = save_end - self.sim_end
        print("Finished saving results in %f seconds"%(save_time))

        self.report_file.write('StartTime=%s\n'%datetime.datetime.fromtimestamp(self.setup_start).strftime('%Y-%m-%d %H:%M:%S'))
        self.report_file.write('SetupTime=%s\n'%self.setup_time)
        self.report_file.write('RealSimulationTime=%s\n'%self.sim_time)
        self.report_file.write('SimulationSaveTime=%s\n'%save_time)
        self.report_file.close()

        print("Saving report of simulation to %s"%('report.txt'))

        print("Done")

        quit()


if __name__ == '__main__':

    ns = NeuronSimulation(tstop=500, dt=0.01, seed=12345, abs_tol=0.001, rel_tol=0)

    ns.run()

@sanjayankur31
Copy link
Member Author

NeuroML/pyNeuroML#262

@sanjayankur31
Copy link
Member Author

We also need to do this for netpyne, should be doable using the simconfig bit by setting cvode_active, and cvode_atol attributes:

http://www.netpyne.org/user_documentation.html

https://github.com/search?q=repo%3Asuny-downstate-medical-center%2Fnetpyne%20cvode&type=code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: 🏗 In progress
Development

No branches or pull requests

3 participants