| 77 | | 'v_rest' : ('U0' , "parameters['v_rest']"), |
|---|
| 78 | | 'v_reset' : ('Vreset', "parameters['v_reset']"), |
|---|
| 79 | | 'cm' : ('C' , "parameters['cm']*1000.0"), # C is in pF, cm in nF |
|---|
| 80 | | 'tau_m' : ('Tau' , "parameters['tau_m']"), |
|---|
| 81 | | 'tau_refrac': ('TauR' , "max(dt,parameters['tau_refrac'])"), |
|---|
| 82 | | 'tau_syn_E' : ('TauSynE', "parameters['tau_syn_E']"), |
|---|
| 83 | | 'tau_syn_I' : ('TauSynI', "parameters['tau_syn_I']"), |
|---|
| 84 | | 'v_thresh' : ('Theta' , "parameters['v_thresh']"), |
|---|
| 85 | | 'i_offset' : ('I0' , "parameters['i_offset']*1000.0"), # I0 is in pA, i_offset in nA |
|---|
| 86 | | 'v_init' : ('u' , "parameters['v_init']"), |
|---|
| | 104 | 'v_rest' : ('E_L' , "parameters['v_rest']"), |
|---|
| | 105 | 'v_reset' : ('V_reset', "parameters['v_reset']"), |
|---|
| | 106 | 'cm' : ('C_m' , "parameters['cm']*1000.0"), # C_m is in pF, cm in nF |
|---|
| | 107 | 'tau_m' : ('tau_m' , "parameters['tau_m']"), |
|---|
| | 108 | 'tau_refrac': ('tau_ref', "max(dt,parameters['tau_refrac'])"), |
|---|
| | 109 | 'tau_syn_E' : ('tau_ex' , "parameters['tau_syn_E']"), |
|---|
| | 110 | 'tau_syn_I' : ('tau_in' , "parameters['tau_syn_I']"), |
|---|
| | 111 | 'v_thresh' : ('V_th' , "parameters['v_thresh']"), |
|---|
| | 112 | 'i_offset' : ('I_e' , "parameters['i_offset']*1000.0"), # I_e is in pA, i_offset in nA |
|---|
| | 113 | 'v_init' : ('V_m' , "parameters['v_init']"), |
|---|
| 123 | | 'v_rest' : ('U0' , "parameters['v_rest']"), |
|---|
| 124 | | 'v_reset' : ('Vreset' , "parameters['v_reset']"), |
|---|
| 125 | | 'cm' : ('C' , "parameters['cm']*1000.0"), # C is in pF, cm in nF |
|---|
| 126 | | 'tau_m' : ('Tau' , "parameters['tau_m']"), |
|---|
| 127 | | 'tau_refrac': ('TauR' , "max(dt,parameters['tau_refrac'])"), |
|---|
| 128 | | 'tau_syn_E' : ('TauSyn_E' , "parameters['tau_syn_E']"), |
|---|
| 129 | | 'tau_syn_I' : ('TauSyn_I' , "parameters['tau_syn_I']"), |
|---|
| 130 | | 'v_thresh' : ('Theta' , "parameters['v_thresh']"), |
|---|
| 131 | | 'i_offset' : ('Istim' , "parameters['i_offset']*1000.0"), # I0 is in pA, i_offset in nA |
|---|
| 132 | | 'e_rev_E' : ('V_reversal_E', "parameters['e_rev_E']"), |
|---|
| 133 | | 'e_rev_I' : ('V_reversal_I', "parameters['e_rev_I']"), |
|---|
| 134 | | 'v_init' : ('u' , "parameters['v_init']"), |
|---|
| | 150 | 'v_rest' : ('E_L' , "parameters['v_rest']"), |
|---|
| | 151 | 'v_reset' : ('V_reset' , "parameters['v_reset']"), |
|---|
| | 152 | 'cm' : ('C_m' , "parameters['cm']*1000.0"), # C is in pF, cm in nF |
|---|
| | 153 | 'tau_m' : ('g_L' , "parameters['cm']/parameters['tau_m']*1000.0"), |
|---|
| | 154 | 'tau_refrac': ('t_ref' , "max(dt,parameters['tau_refrac'])"), |
|---|
| | 155 | 'tau_syn_E' : ('tau_syn_ex', "parameters['tau_syn_E']"), |
|---|
| | 156 | 'tau_syn_I' : ('tau_syn_in', "parameters['tau_syn_I']"), |
|---|
| | 157 | 'v_thresh' : ('V_th' , "parameters['v_thresh']"), |
|---|
| | 158 | #'i_offset' : ('Istim' , "parameters['i_offset']*1000.0"), # I0 is in pA, i_offset in nA |
|---|
| | 159 | 'e_rev_E' : ('E_ex' , "parameters['e_rev_E']"), |
|---|
| | 160 | 'e_rev_I' : ('E_in' , "parameters['e_rev_I']"), |
|---|
| | 161 | 'v_init' : ('V_m' , "parameters['v_init']"), |
|---|
| 150 | | 'v_rest' : ('U0' , "parameters['v_rest']"), |
|---|
| 151 | | 'v_reset' : ('Vreset' , "parameters['v_reset']"), |
|---|
| 152 | | 'cm' : ('C' , "parameters['cm']*1000.0"), # C is in pF, cm in nF |
|---|
| 153 | | 'tau_m' : ('Tau' , "parameters['tau_m']"), |
|---|
| 154 | | 'tau_refrac': ('TauR' , "max(dt,parameters['tau_refrac'])"), |
|---|
| 155 | | 'tau_syn_E' : ('TauSyn_E' , "parameters['tau_syn_E']"), |
|---|
| 156 | | 'tau_syn_I' : ('TauSyn_I' , "parameters['tau_syn_I']"), |
|---|
| 157 | | 'v_thresh' : ('Theta' , "parameters['v_thresh']"), |
|---|
| 158 | | 'i_offset' : ('Istim' , "parameters['i_offset']*1000.0"), # I0 is in pA, i_offset in nA |
|---|
| 159 | | 'e_rev_E' : ('V_reversal_E', "parameters['e_rev_E']"), |
|---|
| 160 | | 'e_rev_I' : ('V_reversal_I', "parameters['e_rev_I']"), |
|---|
| 161 | | 'v_init' : ('u' , "parameters['v_init']"), |
|---|
| | 176 | 'v_rest' : ('E_L' , "parameters['v_rest']"), |
|---|
| | 177 | 'v_reset' : ('V_reset' , "parameters['v_reset']"), |
|---|
| | 178 | 'cm' : ('C_m' , "parameters['cm']*1000.0"), # C is in pF, cm in nF |
|---|
| | 179 | 'tau_m' : ('g_L' , "parameters['cm']/parameters['tau_m']*1000.0"), |
|---|
| | 180 | 'tau_refrac': ('t_ref' , "max(dt,parameters['tau_refrac'])"), |
|---|
| | 181 | 'tau_syn_E' : ('tau_syn_ex' , "parameters['tau_syn_E']"), |
|---|
| | 182 | 'tau_syn_I' : ('tau_syn_in' , "parameters['tau_syn_I']"), |
|---|
| | 183 | 'v_thresh' : ('V_th' , "parameters['v_thresh']"), |
|---|
| | 184 | #'i_offset' : ('Istim' , "parameters['i_offset']*1000.0"), # I0 is in pA, i_offset in nA |
|---|
| | 185 | 'e_rev_E' : ('E_ex', "parameters['e_rev_E']"), |
|---|
| | 186 | 'e_rev_I' : ('E_in', "parameters['e_rev_I']"), |
|---|
| | 187 | 'v_init' : ('V_m' , "parameters['v_init']"), |
|---|
| | 223 | class AdaptiveExponentialIF_alpha(common.AdaptiveExponentialIF_alpha): |
|---|
| | 224 | """adaptive exponential integrate and fire neuron according to Brette and Gerstner (2005)""" |
|---|
| | 225 | |
|---|
| | 226 | translations = { |
|---|
| | 227 | 'v_init' : ('V_m', "parameters['v_init']"), |
|---|
| | 228 | 'w_init' : ('w', "parameters['w_init']*1000.0"), # nA -> pA |
|---|
| | 229 | 'cm' : ('C_m', "parameters['cm']*1000.0"), # nF -> pF |
|---|
| | 230 | 'tau_refrac': ('t_ref', "parameters['tau_refrac']"), |
|---|
| | 231 | 'v_spike' : ('V_peak', "parameters['v_spike']"), |
|---|
| | 232 | 'v_reset' : ('V_reset', "parameters['v_reset']"), |
|---|
| | 233 | 'v_rest' : ('E_L', "parameters['v_rest']"), |
|---|
| | 234 | 'tau_m' : ('g_L', "parameters['cm']/parameters['tau_m']*1000.0"), |
|---|
| | 235 | 'i_offset' : ('I_e', "parameters['i_offset']*1000.0"), # nA -> pA |
|---|
| | 236 | 'a' : ('a', "parameters['a']"), |
|---|
| | 237 | 'b' : ('b', "parameters['b']*1000.0"), # nA -> pA. |
|---|
| | 238 | 'delta_T' : ('Delta_T', "parameters['delta_T']"), |
|---|
| | 239 | 'tau_w' : ('tau_w', "parameters['tau_w']"), |
|---|
| | 240 | 'v_thresh' : ('V_th', "parameters['v_thresh']"), |
|---|
| | 241 | 'e_rev_E' : ('E_ex', "parameters['e_rev_E']"), |
|---|
| | 242 | 'tau_syn_E' : ('tau_syn_ex', "parameters['tau_syn_E']"), |
|---|
| | 243 | 'e_rev_I' : ('E_in', "parameters['e_rev_I']"), |
|---|
| | 244 | 'tau_syn_I' : ('tau_syn_in', "parameters['tau_syn_I']"), |
|---|
| | 245 | } |
|---|
| | 246 | nest_name = "aeif_cond_alpha" |
|---|
| | 247 | |
|---|
| | 248 | def __init__(self,parameters): |
|---|
| | 249 | common.AdaptiveExponentialIF_alpha.__init__(self,parameters) |
|---|
| | 250 | self.parameters = self.translate(self.parameters) |
|---|
| 417 | | spike_detector = nest.Create('spike_detector') |
|---|
| 418 | | nest.setDict(spike_detector,{'withtime':True, # record time of spikes |
|---|
| 419 | | 'withpath':True}) # record which neuron spiked |
|---|
| 420 | | if type(source) == types.ListType: |
|---|
| 421 | | source = [nest.getAddress(src) for src in source] |
|---|
| 422 | | else: |
|---|
| 423 | | source = [nest.getAddress(source)] |
|---|
| 424 | | for src in source: |
|---|
| 425 | | nest.connect(src,spike_detector[0]) |
|---|
| 426 | | nest.sr('/%s (%s/%s) (w) file def' % (filename, tempdir, filename)) |
|---|
| 427 | | nest.sr('%s << /output_stream %s >> SetStatus' % (nest.getGID(spike_detector[0]),filename)) |
|---|
| 428 | | ll_spike_files.append(filename) |
|---|
| 429 | | |
|---|
| 430 | | |
|---|
| 431 | | def record_v(source,filename_user): |
|---|
| | 488 | device_name = recording_device_names[variable] |
|---|
| | 489 | print "Trying to record %s from cell %s using a %s" % (variable, source, device_name) |
|---|
| | 490 | recording_device = nest.Create(device_name) # does it need to be an ID? |
|---|
| | 491 | nest.SetStatus(recording_device, |
|---|
| | 492 | {"to_file" : True, "withgid" : True, "withtime" : True, |
|---|
| | 493 | "interval": nest.GetStatus([0], "resolution")[0]}) |
|---|
| | 494 | |
|---|
| | 495 | if type(source) != types.ListType: |
|---|
| | 496 | source = [source] |
|---|
| | 497 | _connect_recording_device(recording_device, record_from=source) |
|---|
| | 498 | recorder_dict[filename] = recording_device |
|---|
| | 499 | |
|---|
| | 500 | def record(source, filename): |
|---|
| | 501 | """Record spikes to a file. source can be an individual cell or a list of |
|---|
| | 502 | cells.""" |
|---|
| | 503 | # would actually like to be able to record to an array and choose later |
|---|
| | 504 | # whether to write to a file. |
|---|
| | 505 | _record('spikes', source, filename) |
|---|
| | 506 | |
|---|
| | 507 | def record_v(source, filename): |
|---|
| 437 | | if type(source) != types.ListType: |
|---|
| 438 | | source = [source] |
|---|
| 439 | | record_file = filename_user |
|---|
| 440 | | #ll_v_files.append(filename) |
|---|
| 441 | | filename = nest.record_v(source,record_file) |
|---|
| 442 | | ll_v_files.append(filename) |
|---|
| 443 | | |
|---|
| 444 | | def _printSpikes(filename, compatible_output=True): |
|---|
| 445 | | """ Print spikes into a file, and postprocessed them if |
|---|
| 446 | | needed and asked to produce a compatible output for all the simulator |
|---|
| 447 | | Should actually work with record() and allow to dissociate the recording of the |
|---|
| 448 | | writing process, which is not the case for the moment""" |
|---|
| 449 | | tempfilename = "%s/%s" %(tempdir, filename) |
|---|
| 450 | | nest.sr('%s close' %filename) |
|---|
| 451 | | if (compatible_output): |
|---|
| 452 | | # Here we postprocess the file to have effectively the |
|---|
| 453 | | # desired format : |
|---|
| 454 | | # First line: # dimensions of the population |
|---|
| 455 | | # Then spiketime (in ms) cell_id-min(cell_id) |
|---|
| 456 | | result = open(filename,'w',1000) |
|---|
| 457 | | # Writing # such that Population.printSpikes and this have same output format |
|---|
| 458 | | result.write("# "+"\n") |
|---|
| 459 | | # Writing spiketimes, cell_id-min(cell_id) |
|---|
| 460 | | # Pylab has a great load() function, but it is not necessary to import |
|---|
| 461 | | # it into pyNN. The fromfile() function of numpy has trouble on several |
|---|
| 462 | | # machine with Python 2.5, so that's why a dedicated _readArray function |
|---|
| 463 | | # has been created to load from file the raster or the membrane potentials |
|---|
| 464 | | # saved by NEST |
|---|
| 465 | | try: |
|---|
| 466 | | raster = _readArray(tempfilename, sepchar=None) |
|---|
| 467 | | raster = raster[:,1:3] |
|---|
| 468 | | raster[:,1] = raster[:,1]*dt |
|---|
| 469 | | for idx in xrange(len(raster)): |
|---|
| 470 | | result.write("%g\t%d\n" %(raster[idx][1], raster[idx][0])) |
|---|
| 471 | | except Exception: |
|---|
| 472 | | print "Error while writing data into a compatible mode" |
|---|
| 473 | | result.close() |
|---|
| 474 | | os.system("rm %s" %tempfilename) |
|---|
| | 513 | _record('v', source, filename) |
|---|
| | 514 | |
|---|
| | 515 | def _print(user_filename, gather=True, compatible_output=True, population=None, variable=None): |
|---|
| | 516 | global recorder_dict |
|---|
| | 517 | |
|---|
| | 518 | if population is None: |
|---|
| | 519 | recorder = recorder_dict[user_filename] |
|---|
| 476 | | shutil.move(tempfilename, filename) |
|---|
| 477 | | |
|---|
| 478 | | |
|---|
| 479 | | def _print_v(filename, compatible_output=True): |
|---|
| 480 | | """ Print membrane potentials in a file, and postprocessed them if |
|---|
| 481 | | needed and asked to produce a compatible output for all the simulator |
|---|
| 482 | | Should actually work with record_v() and allow to dissociate the recording of the |
|---|
| 483 | | writing process, which is not the case for the moment""" |
|---|
| 484 | | tempfilename = tempdir+'/'+filename |
|---|
| 485 | | nest.sr('%s close' %tempfilename.replace('/','_')) |
|---|
| 486 | | result = open(filename,'w',1000) |
|---|
| 487 | | dt = nest.getNESTStatus()['resolution'] |
|---|
| 488 | | n = int(nest.getNESTStatus()['time']/dt) |
|---|
| 489 | | result.write("# dt = %f\n# n = %d\n" % (dt,n)) |
|---|
| 490 | | if (compatible_output): |
|---|
| 491 | | # Here we postprocess the file to have effectively the |
|---|
| 492 | | # desired format : |
|---|
| 493 | | # First line: dimensions of the population |
|---|
| 494 | | # Then spiketime cell_id-min(cell_id) |
|---|
| 495 | | |
|---|
| 496 | | # Pylab has a great load() function, but it is not necessary to import |
|---|
| 497 | | # it into pyNN. The fromfile() function of numpy has trouble on several |
|---|
| 498 | | # machine with Python 2.5, so that's why a dedicated _readArray function |
|---|
| 499 | | # has been created to load from file the raster or the membrane potentials |
|---|
| 500 | | # saved by NEST |
|---|
| 501 | | try: |
|---|
| 502 | | raster = _readArray(tempfilename.replace('/','_'), sepchar=None) |
|---|
| 503 | | for idx in xrange(len(raster)): |
|---|
| 504 | | result.write("%g\t%d\n" %(raster[idx][1], raster[idx][0])) |
|---|
| 505 | | except Exception: |
|---|
| 506 | | print "Error while writing data into a compatible mode" |
|---|
| 507 | | else: |
|---|
| 508 | | f = open(tempfilename.replace('/','_'),'r',1000) |
|---|
| 509 | | lines = f.readlines() |
|---|
| 510 | | f.close() |
|---|
| 511 | | for line in lines: |
|---|
| 512 | | result.write(line) |
|---|
| 513 | | result.close() |
|---|
| 514 | | os.system("rm %s" %tempfilename.replace('/','_')) |
|---|
| 515 | | |
|---|
| 516 | | def _readArray(filename, sepchar = None, skipchar = '#'): |
|---|
| | 521 | assert variable in ['spikes', 'v', 'conductance'] |
|---|
| | 522 | recorder = population.recorders[variable] |
|---|
| | 523 | |
|---|
| | 524 | nest.FlushDevice(recorder) |
|---|
| | 525 | status = nest.GetStatus([0])[0] |
|---|
| | 526 | local_num_threads = status['local_num_threads'] |
|---|
| | 527 | node_list = range(nest.GetStatus([0], "num_processes")[0]) |
|---|
| | 528 | |
|---|
| | 529 | # First combine data from different threads |
|---|
| | 530 | os.system("rm -f %s" % user_filename) |
|---|
| | 531 | for nest_thread in range(local_num_threads): |
|---|
| | 532 | nest.sps(recorder[0]) |
|---|
| | 533 | nest.sr("%i GetAddress %i append" % (recorder[0], nest_thread)) |
|---|
| | 534 | nest.sr("GetStatus /filename get") |
|---|
| | 535 | nest_filename = nest.spp() #nest.GetStatus(recorder, "filename") |
|---|
| | 536 | ##system_line = 'cat %s >> %s' % (nest_filename, "%s_%d" % (user_filename, nest.Rank())) |
|---|
| | 537 | merged_filename = "%s/%s" % (os.path.dirname(nest_filename), user_filename) |
|---|
| | 538 | system_line = 'cat %s >> %s' % (nest_filename, merged_filename) # will fail if writing to a common directory, e.g. using NFS |
|---|
| | 539 | print system_line |
|---|
| | 540 | os.system(system_line) |
|---|
| | 541 | if gather: |
|---|
| | 542 | raise Exception("'gather' not currently supported.") |
|---|
| | 543 | if nest.Rank() == 0: # only on the master node (?) |
|---|
| | 544 | for node in node_list: |
|---|
| | 545 | pass # not a good way to do it at the moment |
|---|
| | 546 | |
|---|
| | 547 | if compatible_output: |
|---|
| | 548 | if gather == False or nest.Rank() == 0: # if we gather, only do this on the master node |
|---|
| | 549 | logging.info("Writing %s in compatible format." % user_filename) |
|---|
| | 550 | |
|---|
| | 551 | # Here we postprocess the file to have effectively the |
|---|
| | 552 | # desired format: spiketime (in ms) cell_id-min(cell_id) |
|---|
| | 553 | #if not os.path.exists(user_filename): |
|---|
| | 554 | result = open(user_filename,'w',1000) |
|---|
| | 555 | #else: |
|---|
| | 556 | # result = open(user_filename,'a',1000) |
|---|
| | 557 | |
|---|
| | 558 | ## Writing header info (e.g., dimensions of the population) |
|---|
| | 559 | if population is not None: |
|---|
| | 560 | result.write("# " + "\t".join([str(d) for d in self.dim]) + "\n") |
|---|
| | 561 | padding = population.cell.flatten()[0] |
|---|
| | 562 | else: |
|---|
| | 563 | padding = 0 |
|---|
| | 564 | result.write("# dt = %g\n" % nest.GetStatus([0], "resolution")[0]) |
|---|
| | 565 | |
|---|
| | 566 | # Writing spiketimes, cell_id-min(cell_id) |
|---|
| | 567 | |
|---|
| | 568 | # (Pylab has a great load() function, but it is not necessary to import |
|---|
| | 569 | # it into pyNN. The fromfile() function of numpy has trouble on several |
|---|
| | 570 | # machine with Python 2.5, so that's why a dedicated _readArray function |
|---|
| | 571 | # has been created to load from file the raster or the membrane potentials |
|---|
| | 572 | # saved by NEST). |
|---|
| | 573 | |
|---|
| | 574 | # open file |
|---|
| | 575 | if int(os.path.getsize(merged_filename)) > 0: |
|---|
| | 576 | raster = _readArray(merged_filename, sepchar=None) |
|---|
| | 577 | result.write("# n = %d\n" % len(raster)) # shouldn't be called raster |
|---|
| | 578 | raster[:,0] = raster[:,0] - padding |
|---|
| | 579 | for idx in xrange(len(raster)): |
|---|
| | 580 | result.write("%g\t%d\n" % (raster[idx][2], raster[idx][0])) # v id |
|---|
| | 581 | else: |
|---|
| | 582 | logging.info("%s_tmp is empty" % user_filename) |
|---|
| | 583 | result.close() |
|---|
| | 584 | |
|---|
| | 585 | recorder_dict.pop(user_filename) |
|---|
| | 586 | |
|---|
| | 587 | def _readArray(filename, sepchar=None, skipchar='#'): |
|---|
| 859 | | global hl_c_files |
|---|
| 860 | | |
|---|
| 861 | | # create device |
|---|
| 862 | | |
|---|
| 863 | | self.conductancemeter = nest.Create("conductancemeter") |
|---|
| 864 | | params = {"to_file" : True, "withgid" : True, "withtime" : True} |
|---|
| 865 | | nest.SetStatus(self.conductancemeter, [params]) |
|---|
| 866 | | |
|---|
| 867 | | filename = nest.GetStatus(self.conductancemeter, "filename") |
|---|
| 868 | | hl_c_files[self.label] = filename |
|---|
| 869 | | |
|---|
| 870 | | |
|---|
| 871 | | # create list of neurons |
|---|
| 872 | | fixed_list = False |
|---|
| 873 | | if record_from: |
|---|
| 874 | | if type(record_from) == types.ListType: |
|---|
| 875 | | fixed_list = True |
|---|
| 876 | | n_rec = len(record_from) |
|---|
| 877 | | elif type(record_from) == types.IntType: |
|---|
| 878 | | n_rec = record_from |
|---|
| 879 | | else: |
|---|
| 880 | | raise "record_from must be a list or an integer" |
|---|
| 881 | | else: |
|---|
| 882 | | n_rec = self.size |
|---|
| 883 | | |
|---|
| 884 | | tmp_list = [] |
|---|
| 885 | | if (fixed_list == True): |
|---|
| 886 | | tmp_list = [neuron for neuron in record_from] |
|---|
| 887 | | else: |
|---|
| 888 | | for neuron in numpy.random.permutation(numpy.reshape(self.cell,(self.cell.size,)))[0:n_rec]: |
|---|
| 889 | | tmp_list.append(neuron) |
|---|
| 890 | | |
|---|
| 891 | | # connect device to neurons |
|---|
| 892 | | nest.DivergentConnect(self.conductancemeter, tmp_list) |
|---|
| 893 | | |
|---|
| 894 | | def printSpikes(self,filename,gather=True, compatible_output=False): |
|---|
| | 890 | self._record('conductance', record_from, rng) |
|---|
| | 891 | |
|---|
| | 892 | def printSpikes(self, filename, gather=True, compatible_output=False): |
|---|
| 909 | | """ |
|---|
| 910 | | global hl_spike_files |
|---|
| 911 | | global tempdir |
|---|
| 912 | | # closing of the file |
|---|
| 913 | | # just a workaround, nest will do that automatically soon |
|---|
| 914 | | if hl_spike_files.has_key(self.label):# __contains__(tempfilename): |
|---|
| 915 | | nest.sps(self.spike_detector) |
|---|
| 916 | | nest.sr("FlushDevice") |
|---|
| 917 | | |
|---|
| 918 | | status = nest.GetStatus([0])[0] |
|---|
| 919 | | np = status['num_processes'] |
|---|
| 920 | | vp = status['vp'] |
|---|
| 921 | | local_num_threads = status['local_num_threads'] |
|---|
| 922 | | rank = numpy.mod(vp,np) |
|---|
| 923 | | |
|---|
| 924 | | |
|---|
| 925 | | filename = filename + '-%d' % rank |
|---|
| 926 | | if (compatible_output): |
|---|
| 927 | | if rank == 0: |
|---|
| 928 | | logging.info("Writing %s in compatible format." % filename) |
|---|
| 929 | | for nest_thread in range(local_num_threads): |
|---|
| 930 | | label = '-%d-%d-%d.gdf' %(rank,nest_thread,self.spike_detector) |
|---|
| 931 | | # Here we postprocess the file to have effectively the |
|---|
| 932 | | # desired format: spiketime (in ms) cell_id-min(cell_id) |
|---|
| 933 | | if not os.path.exists(filename): |
|---|
| 934 | | result = open(filename,'w',1000) |
|---|
| 935 | | # Writing dimensions of the population: |
|---|
| 936 | | result.write("# " + "\t".join([str(d) for d in self.dim]) + "\n") |
|---|
| 937 | | # Writing spiketimes, cell_id-min(cell_id) |
|---|
| 938 | | ###padding = numpy.reshape(self.cell,self.cell.size)[0] # moved below |
|---|
| 939 | | else: |
|---|
| 940 | | result = open(filename,'a',1000) |
|---|
| 941 | | padding = numpy.reshape(self.cell,self.cell.size)[0] |
|---|
| 942 | | |
|---|
| 943 | | # Pylab has a great load() function, but it is not necessary to import |
|---|
| 944 | | # it into pyNN. The fromfile() function of numpy has trouble on several |
|---|
| 945 | | # machine with Python 2.5, so that's why a dedicated _readArray function |
|---|
| 946 | | # has been created to load from file the raster or the membrane potentials |
|---|
| 947 | | # saved by NEST |
|---|
| 948 | | # open file |
|---|
| 949 | | simfile = tempdir + '/spike_detector'+ label |
|---|
| 950 | | # if int(os.path.getsize(hl_spike_files[self.label][0])) > 0: |
|---|
| 951 | | if int(os.path.getsize(simfile)) > 0: |
|---|
| 952 | | # try: |
|---|
| 953 | | raster = _readArray(simfile ,sepchar=None) |
|---|
| 954 | | # Sometimes, nest doesn't write the last line entirely, so we need |
|---|
| 955 | | # to trunk it to avoid errors |
|---|
| 956 | | ###raster = raster[:,1:3] |
|---|
| 957 | | raster[:,0] = raster[:,0] - padding |
|---|
| 958 | | raster[:,1] = raster[:,1]*dt |
|---|
| 959 | | for idx in xrange(len(raster)): |
|---|
| 960 | | result.write("%g\t%d\n" %(raster[idx][1], raster[idx][0])) |
|---|
| 961 | | |
|---|
| 962 | | # except Exception, inst: |
|---|
| 963 | | # print "Error while writing data into a compatible mode" |
|---|
| 964 | | # logging.error("Error while writing data into a compatible mode: %s" % str(inst)) |
|---|
| 965 | | else: |
|---|
| 966 | | logging.info("%s is empty" % simfile) |
|---|
| 967 | | result.close() |
|---|
| 968 | | # os.system("rm %s" % hl_spike_files[self.label][0]) |
|---|
| 969 | | else: |
|---|
| 970 | | if gather: |
|---|
| 971 | | if os.path.exists(filename): |
|---|
| 972 | | # 'target file exists, will be removed before copying the new data.' |
|---|
| 973 | | os.remove(filename) |
|---|
| 974 | | for nest_thread in range(local_num_threads): |
|---|
| 975 | | label = '-%d-%d-%d.gdf' %(rank,nest_thread,self.spike_detector) |
|---|
| 976 | | simfile = tempdir + '/spike_detector'+ label |
|---|
| 977 | | system_line = 'cat %s >> %s' %(simfile,filename) |
|---|
| 978 | | if os.system(system_line) == 0: # cat was successful |
|---|
| 979 | | os.remove(simfile) |
|---|
| 980 | | else: |
|---|
| 981 | | print 'spike data is not gathered and located in: ',tempdir |
|---|
| 982 | | |
|---|
| 983 | | hl_spike_files.pop(self.label) |
|---|
| 984 | | |
|---|
| 985 | | def collectdata(self,filename): |
|---|
| 986 | | """ |
|---|
| 987 | | merges all mpi data into one final file, should only be called once, after all spikes have been printed |
|---|
| 988 | | """ |
|---|
| 989 | | status = nest.GetStatus([0])[0] |
|---|
| 990 | | np = status['num_processes'] |
|---|
| 991 | | vp = status['vp'] |
|---|
| 992 | | local_num_threads = status['local_num_threads'] |
|---|
| 993 | | rank = numpy.mod(vp,np) |
|---|
| 994 | | if os.path.exists(filename): |
|---|
| 995 | | os.remove(filename) |
|---|
| 996 | | |
|---|
| 997 | | for processor in range(np): |
|---|
| 998 | | filename_p = filename+'-'+str(processor) |
|---|
| 999 | | system_line = 'cat %s >> %s' %(filename_p,filename) |
|---|
| 1000 | | if os.system(system_line) == 0: # cat was successful |
|---|
| 1001 | | os.remove(filename_p) |
|---|
| 1002 | | |
|---|
| 1003 | | def meanSpikeCount(self,gather=True): |
|---|
| | 907 | """ |
|---|
| | 908 | _print(filename, gather=gather, compatible_output=compatible_output, |
|---|
| | 909 | population=self, variable="spikes") |
|---|
| | 910 | |
|---|
| | 911 | def meanSpikeCount(self, gather=True): |
|---|