#!/usr/bin/env python # -*- coding: utf-8 -*- import os import sys import math import datetime import pickle ## from node000: ## mpiexec -machinefile ~/hostfile -n ~/Python-2.6.4/bin/python2.6 odor_sins.py ## nohup mpiexec -machinefile ~/hostfile -n 201 ~/Python-2.6.4/bin/python2.6 odor_sins.py < /dev/null & ## typical value for num_sins = 5 ## typical value for num of trials = 40 ## (depends on number of available processing nodes and number of odorfiles generated) ## Set various option like NO_PGs or ONLY_TWO_MITS in simset_odor.py ## single simulation USAGE: ## python2.6 odor_sins.py sys.path.extend(["..","../networks","../generators","../simulations"]) from moose_utils import * # imports moose from data_utils import * # has mpi import and variables also from OBNetwork import * from sim_utils import * from stimuliConstants import * # has SETTLETIME, varied... from simset_odor import * from pylab import * # part of matplotlib that depends on numpy but not scipy from plot_odor_sins import * #----------------------------------------------------------- class odorResponse: def __init__(self): self.mpirank = mpirank self.context = moose.PyMooseBase.getContext() def setupStim(self,network,sinnum,trialnum): self.setupOdor(network, sinnum, trialnum) print "Setup sin frequency =",sine_frequencies[sinnum],"at",self.mpirank def setupOdor(self, network, sinnum, trailnum): ## first figure out which PG belongs to which glom ## PG_glom_map[pgname] returns the glom num of the PG: ## needed for ORN to PG connections. PG_glom_map = {} for projname in network.projectionDict.keys(): if 'PG_mitral' in projname: for i,proj in enumerate(network.projectionDict[projname][2]): ## get the glomnum from the post path proj[2] ## name of the mitral cell from '/mitrals_2/...' mitname = string.split(proj[2],'/')[1] ## glomerulus number from 'mitrals_2' by integer division i.e. 2/2 = 1 glomnum = int(string.split(mitname,'_')[1]) / 2 ## name of the PG cell from '/PGs_2/...' pgname = string.split(proj[1],'/')[1] PG_glom_map[pgname] = glomnum ## Now connect the ORNs for projname in network.projectionDict.keys(): #### Calling attach_spikes() for each projection, #### would reconnect files to the same segment multiple times. #### But attach_files_uniquely() checks whether timetable.tableSize is zero or not #### i.e. files already attached or not. ## connect ORNs to mitrals if 'ORN_mitral' in projname: print "connecting ORN files to mitrals" for i,proj in enumerate(network.projectionDict[projname][2]): ## get the glomnum from the post path proj[2] ## name of the mitral cell from '/mitrals_2/...' mitname = string.split(proj[2],'/')[1] ## glomerulus number from 'mitrals_2' by integer division i.e. 2/2 = 1 glomnum = int(string.split(mitname,'_')[1]) / 2 self.attach_appropriate_files_to_glom(proj[0],proj[2],sinnum,trialnum,glomnum) ## connect ORNs to PG if 'ORN_PG' in projname: print "connecting ORN files to PGs" for i,proj in enumerate(network.projectionDict[projname][2]): pgname = string.split(proj[2],'/')[1] # name of the PG cell from '/PGs_2/...' glomnum = PG_glom_map[pgname] self.attach_appropriate_files_to_glom(proj[0],proj[2],sinnum,trialnum,glomnum) def attach_appropriate_files_to_glom(self,proj1,proj2,sinnum,trialnum,glomnum): if LAT_SINS and glomnum == central_glom: filebase = '../firefiles/firefiles_constrate/firetimes_constrate'+str(SIN_MAIN_CONSTRATE) self.attach_files_uniquely(filebase,proj1,proj2,-1,trialnum) # sinnum=-1 to not use sinusoid else: filebase = '../firefiles/firefiles_sins/firetimes_sin_glom'+str(glomnum) self.attach_files_uniquely(filebase,proj1,proj2,sinnum,trialnum) def attach_files_uniquely(self,filebase,synname,postsegpath,sinnum=None,trialnum=None): ttpath = postsegpath+'/'+synname+'_tt' if self.context.exists(ttpath): # timetable already created by networkML reader - just wrap it below. tt = moose.TimeTable(ttpath) # post_segment_path+'/'+syn_name+'_tt' else: ## if timetable was not already created by networkML reader, ## it means that the synaptic weights must be zero! ## (no extra inhibition - only main inhibition) ## hence do not attach spikefiles return if tt.tableSize != 0: return # if files are already attached, do nothing! ## If sinnum == -1, it means do not use sinusoids. if sinnum is not None and sinnum != -1: filebase += '_fnum'+str(sinnum) if trialnum is not None: filebase += '_trial'+str(trialnum) ## attach_spikes() accesses filenumbers to this segment ## from 'fileNumbers' field (of the timetable object in MOOSE) ## which is created while reading in networkML. attach_spikes(filebase, tt, self.mpirank) def run(self,network, binned): print "Resetting MOOSE." # from moose_utils.py sets clocks and resets resetSim(network.context, SIMDT, PLOTDT) print "Running at",self.mpirank network.context.step(SIN_RUNTIME) mitral_responses = [] if ONLY_TWO_MITS: mits = [mitralidx, mitralsidekickidx] else: mits = range(NUM_GLOMS*MIT_SISTERS) ## network.mitralTable is a dictionary. for mitnum in mits: mitral = network.mitralTable[mitnum] ## need to convert to numpy's array(), ## else MOOSE table cannot be pickled for mpi4py send() mitral_responses.append(array(mitral._vmTableSoma)) return mitral_responses #---------------------------------------------------------------- if __name__ == "__main__": #### if only one process is called, plot one sim directly if mpisize == 1: #### run the slave processes sim = odorResponse() ## includeProjections gets used only if ONLY_TWO_MITS is True: ## Keep below projections to 'second order cells' ## i.e. to cells (granules) connected to mits0&1. ## The connections between second order cell ## and mits0&1 are automatically retained of course. # 'PG' includes 'ORN_PG', 'PG_mitral', 'mitral_PG' and 'SA_PG' includeProjections = ['PG','granule_baseline'] tweaks = build_tweaks(CLUB_MITRALS, NO_SPINE_INH, NO_SINGLES, NO_JOINTS,\ NO_MULTIS, NO_PGS, ONLY_TWO_MITS, includeProjections, mitralsidekickidx) network = OBNetwork(OBNet_file, synchan_activation_correction, tweaks,\ mpirank, granfilebase+'_noresp', spiketable=False) #printNetTree() # from moose_utils.py trialnum = 0 sinnum = 0 sim.setupStim(network, sinnum, trialnum) mitral_responses = sim.run(network, binned=False) timevec = arange(SETTLETIME,SETTLETIME+SIN_RUNTIME+3*PLOTDT/2.0,PLOTDT) plot(timevec, mitral_responses[0]) show() #### multiple processes else: if mpirank == boss: #### collate at boss process ## mitral_responses_list[avgnum][sinnum][mitnum][spikenum] mitral_responses_list = [] numavgs = (mpisize-1)/num_sins for avgnum in range(numavgs): response_set = [] for sinnum in range(num_sins): procnum = avgnum*num_sins + sinnum + 1 print 'waiting for process '+str(procnum)+'.' ## below: you get a numpy array of ## rows=NUM_GLOMS*MIT_SISTERS and cols=spike times ## mitral responses has spike times mitral_responses = mpicomm.recv(source=procnum, tag=0) response_set.append( mitral_responses ) mitral_responses_list.append(response_set) # write results to a file today = datetime.date.today() if NO_SINGLES: singles_str = '_NOSINGLES' else: singles_str = '_SINGLES' if NO_JOINTS: joints_str = '_NOJOINTS' else: joints_str = '_JOINTS' if NO_PGS: pgs_str = '_NOPGS' else: pgs_str = '_PGS' if NO_LATERAL: lat_str = '_NOLAT' else: lat_str = '' now = datetime.datetime.now().strftime("%Y_%m_%d_%H_%M") outfilename = '../results/odor_sins/'+now+'_sins'+singles_str+\ joints_str+pgs_str+lat_str+'_numgloms'+str(NUM_GLOMS)+'.pickle' f = open(outfilename,'w') pickle.dump(mitral_responses_list, f) f.close() print "Wrote", outfilename plot_sin_responses(outfilename) show() else: #### run the slave processes sim = odorResponse() ## includeProjections gets used only if ONLY_TWO_MITS is True: ## Keep below projections to 'second order cells' ## i.e. to cells (granules) connected to mits0&1. ## The connections between second order cell ## and mits0&1 are automatically retained of course. # 'PG' includes 'ORN_PG', 'PG_mitral', 'mitral_PG' and 'SA_PG' includeProjections = ['PG','granule_baseline'] tweaks = build_tweaks(CLUB_MITRALS, NO_SPINE_INH, NO_SINGLES, NO_JOINTS,\ NO_MULTIS, NO_PGS, ONLY_TWO_MITS, includeProjections, mitralsidekickidx) network = OBNetwork(OBNet_file, synchan_activation_correction, tweaks,\ mpirank, granfilebase+'_noresp', spiketable=True) #printNetTree() # from moose_utils.py trialnum = (mpirank-1)/num_sins sinnum = (mpirank-1)%num_sins sim.setupStim(network, sinnum, trialnum) mitral_responses = sim.run(network, binned=True) mpicomm.send( mitral_responses, dest=boss, tag=0 ) print 'sent from process',mpirank