diff --git a/LGneurons.py b/LGneurons.py index 19f05f1..c6c2601 100644 --- a/LGneurons.py +++ b/LGneurons.py @@ -9,7 +9,7 @@ import pandas as pd import pylab - +from modelParams import * import nest import numpy as np import numpy.random as rnd @@ -33,19 +33,82 @@ def loadLG14params(ID): for k,v in alpha.iteritems(): try: - alpha[k] = round(float(LG14Solutions[ID]['ALPHA_'+k.replace('->','_')]),0) + if k == 'Arky->MSN': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_GPe_MSN']),0) + elif k == 'Arky->FSI': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_GPe_FSI']),0) + elif k == 'CMPf->Arky': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_CMPf_GPe']),0) + elif k == 'CMPf->Prot': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_CMPf_GPe']),0) + elif k == 'MSN->Arky': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_MSN_GPe']),0) + elif k == 'MSN->Prot': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_MSN_GPe']),0) + elif k == 'Prot->STN': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_GPe_STN']),0) + elif k == 'STN->Arky': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_STN_GPe']),0) + elif k == 'STN->Prot': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_STN_GPe']),0) + elif k == 'Arky->Arky': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_GPe_GPe']),0) + elif k == 'Arky->Prot': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_GPe_GPe']),0) + elif k == 'Prot->Arky': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_GPe_GPe']),0) + elif k == 'Prot->Prot': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_GPe_GPe']),0) + elif k == 'Prot->GPi': + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_GPe_GPi']),0) + else: + alpha[k] = round(float(LG14Solutions[ID]['ALPHA_'+k.replace('->','_')]),0) except: print('Could not find LG14 parameters for connection `'+k+'`, trying to run anyway.') for k,v in p.iteritems(): - try: - p[k] = round(float(LG14Solutions[ID]['DIST_'+k.replace('->','_')]),2) - except: - print('Could not find LG14 parameters for connection `'+k+'`, trying to run anyway.') + try: + if k == 'Arky->MSN': + p[k] = round(float(LG14Solutions[ID]['DIST_GPe_MSN']),2) + elif k == 'Arky->FSI': + p[k] = round(float(LG14Solutions[ID]['DIST_GPe_FSI']),2) + elif k == 'CMPf->Arky': + p[k] = round(float(LG14Solutions[ID]['DIST_CMPf_GPe']),2) + elif k == 'CMPf->Prot': + p[k] = round(float(LG14Solutions[ID]['DIST_CMPf_GPe']),2) + elif k == 'MSN->Arky': + p[k] = round(float(LG14Solutions[ID]['DIST_MSN_GPe']),2) + elif k == 'MSN->Prot': + p[k] = round(float(LG14Solutions[ID]['DIST_MSN_GPe']),2) + elif k == 'Prot->STN': + p[k] = round(float(LG14Solutions[ID]['DIST_GPe_STN']),2) + elif k == 'STN->Arky': + p[k] = round(float(LG14Solutions[ID]['DIST_STN_GPe']),2) + elif k == 'STN->Prot': + p[k] = round(float(LG14Solutions[ID]['DIST_STN_GPe']),2) + elif k == 'Arky->Arky': + p[k] = round(float(LG14Solutions[ID]['DIST_GPe_GPe']),2) + elif k == 'Arky->Prot': + p[k] = round(float(LG14Solutions[ID]['DIST_GPe_GPe']),2) + elif k == 'Prot->Arky': + p[k] = round(float(LG14Solutions[ID]['DIST_GPe_GPe']),2) + elif k == 'Prot->Prot': + p[k] = round(float(LG14Solutions[ID]['DIST_GPe_GPe']),2) + elif k == 'Prot->GPi': + p[k] = round(float(LG14Solutions[ID]['DIST_GPe_GPi']),2) + else: + p[k] = round(float(LG14Solutions[ID]['DIST_'+k.replace('->','_')]),2) + except: + print('Could not find LG14 parameters for connection `'+k+'`, trying to run anyway.') for k,v in BGparams.iteritems(): try: - BGparams[k]['V_th'] = round(float(LG14Solutions[ID]['THETA_'+k]),1) + if k == 'Arky': + BGparams[k]['V_th'] = round(float(LG14Solutions[ID]['THETA_GPe']),1) + elif k == 'Prot': + BGparams[k]['V_th'] = round(float(LG14Solutions[ID]['THETA_GPe']),1) + else: + BGparams[k]['V_th'] = round(float(LG14Solutions[ID]['THETA_'+k]),1) except: print('Could not find LG14 parameters for connection `'+k+'`, trying to run anyway.') @@ -460,20 +523,25 @@ def computeW(listRecType, nameSrc, nameTgt, inDegree, gain=1.,verbose=False): 'FSI': [7.8,14.0], # the refined constraint of 10.9 +/- 3.1 Hz was extracted from the following papers: Adler et al., 2016; Yamada et al., 2016 (summarizing date from three different experiments); and Marche and Apicella, 2017 'STN': [15.2,22.8], 'GPe': [55.7,74.5], + 'Arky': [55.7,74.5], + 'Prot': [55.7,74.5], 'GPi': [59.1,79.5], } + FRRGPi = {'AMPA+NMDA+GABAA':[53.4,96.8], 'NMDA':[27.2451,78.6255], 'NMDA+AMPA':[6.811275,52.364583], 'AMPA':[5.7327,66.0645], 'GABAA':[44.1477,245.8935], } + FRRGPe = {'AMPA':[4.2889,58.7805], 'AMPA+GABAA':[10.0017148,137.076126], 'NMDA':[29.5767,61.1645], 'GABAA':[74.8051,221.4885], } -FRRAnt = {'GPe':FRRGPe,'GPi':FRRGPi} + +FRRAnt = {'Arky':FRRGPe,'Prot':FRRGPe,'GPe':FRRGPe,'GPi':FRRGPi} # imported from Chadoeuf "connexweights" # All the parameters needed to replicate Lienard model @@ -491,7 +559,10 @@ def computeW(listRecType, nameSrc, nameTgt, inDegree, gain=1.,verbose=False): Ri=200.E-2 # Ohms.m Rm=20000.E-4 # Ohms.m^2 -NUCLEI=['MSN','FSI','STN','GPe','GPi'] +if params['splitGPe']: + NUCLEI=['MSN','FSI','STN','Arky','Prot','GPi'] +else: + NUCLEI=['MSN','FSI','STN','GPe','GPi'] # Number of neurons in the real macaque brain # one hemisphere only, based on Hardman et al. 2002 paper, except for striatum & CM/Pf @@ -499,6 +570,8 @@ def computeW(listRecType, nameSrc, nameTgt, inDegree, gain=1.,verbose=False): 'FSI': 532.0E3, 'STN': 77.0E3, 'GPe': 251.0E3, + 'Arky': 251.0E3, + 'Prot': 251.0E3, 'GPi': 143.0E3, 'CMPf': 86.0E3, 'CSN': None, 'PTN': None # prevents key error @@ -509,126 +582,212 @@ def computeW(listRecType, nameSrc, nameTgt, inDegree, gain=1.,verbose=False): 'FSI': 0., 'STN': 0., 'GPe': 0., + 'Arky': 0., + 'Prot': 0., 'GPi': 0., 'CMPf':0., 'CSN': 0., - 'PTN': 0., - } + 'PTN': 0.,} # P(X->Y): probability that a given neuron from X projects to at least neuron of Y P = {'MSN->GPe': 1., + 'MSN->Arky': 1., + 'MSN->Prot': 1., 'MSN->GPi': 0.82, 'MSN->MSN': 1., + 'FSI->MSN': 1., 'FSI->FSI': 1., - 'STN->GPe': 0.83, - 'STN->GPi': 0.72, - 'STN->MSN': 0.17, - 'STN->FSI': 0.17, + + 'STN->GPe': 0.83, + 'STN->Arky': 0.83, + 'STN->Prot': 0.83, + 'STN->GPi': 0.72, + 'STN->MSN': 0.17, + 'STN->FSI': 0.17, + 'GPe->STN': 1., 'GPe->GPe': 0.84, 'GPe->GPi': 0.84, 'GPe->MSN': 0.16, 'GPe->FSI': 0.16, + + 'Arky->Arky': 0.84, + 'Arky->Prot': 0.84, + 'Arky->MSN': 0.16, + 'Arky->FSI': 0.16, + + 'Prot->STN': 1., + 'Prot->Arky': 0.84, + 'Prot->Prot': 0.84, + 'Prot->GPi': 0.84, + 'CSN->MSN': 1., 'CSN->FSI': 1., + 'PTN->MSN': 1., 'PTN->FSI': 1., 'PTN->STN': 1., + 'CMPf->STN': 1., 'CMPf->MSN': 1., 'CMPf->FSI': 1., 'CMPf->GPe': 1., - 'CMPf->GPi': 1. - } + 'CMPf->Arky': 1., + 'CMPf->Prot': 1., + 'CMPf->GPi': 1.,} # alpha X->Y: average number of synaptic contacts made by one neuron of X to one neuron of Y, when there is a connexion # for the moment set from one specific parameterization, should be read from Jean's solution file alpha = {'MSN->GPe': 171, + 'MSN->Arky': 171, + 'MSN->Prot': 171, 'MSN->GPi': 210, 'MSN->MSN': 210, + 'FSI->MSN': 4362, 'FSI->FSI': 116, + 'STN->GPe': 428, + 'STN->Arky': 428, + 'STN->Prot': 428, 'STN->GPi': 233, 'STN->MSN': 0, 'STN->FSI': 91, + 'GPe->STN': 19, 'GPe->GPe': 38, 'GPe->GPi': 16, 'GPe->MSN': 0, 'GPe->FSI': 353, + + 'Arky->Arky': 38, + 'Arky->Prot': 38, + 'Arky->MSN': 0, + 'Arky->FSI': 353, + + 'Prot->STN': 19, + 'Prot->Arky': 38, + 'Prot->Prot': 38, + 'Prot->GPi': 16, + 'CSN->MSN': 342, # here, represents directly \nu 'CSN->FSI': 250, # here, represents directly \nu + 'PTN->MSN': 5, # here, represents directly \nu 'PTN->FSI': 5, # here, represents directly \nu 'PTN->STN': 259, # here, represents directly \nu + 'CMPf->MSN': 4965, 'CMPf->FSI': 1053, 'CMPf->STN': 76, 'CMPf->GPe': 79, - 'CMPf->GPi': 131 - } + 'CMPf->Arky': 79, + 'CMPf->Prot': 79, + 'CMPf->GPi': 131,} # p(X->Y): relative distance on the dendrite from the soma, where neurons rom X projects to neurons of Y # Warning: p is not P! p = {'MSN->GPe': 0.48, + 'MSN->Arky': 0.48, + 'MSN->Prot': 0.48, 'MSN->GPi': 0.59, 'MSN->MSN': 0.77, + 'FSI->MSN': 0.19, 'FSI->FSI': 0.16, + 'STN->GPe': 0.30, + 'STN->Prot': 0.30, + 'STN->Arky': 0.30, 'STN->GPi': 0.59, 'STN->MSN': 0.16, 'STN->FSI': 0.41, + 'GPe->STN': 0.58, 'GPe->GPe': 0.01, 'GPe->GPi': 0.13, 'GPe->MSN': 0.06, 'GPe->FSI': 0.58, + + 'Arky->Arky': 0.01, + 'Arky->Prot': 0.01, + 'Arky->MSN': 0.06, + 'Arky->FSI': 0.58, + + 'Prot->STN': 0.58, + 'Prot->Arky': 0.01, + 'Prot->Prot': 0.01, + 'Prot->GPi': 0.13, + 'CSN->MSN': 0.95, 'CSN->FSI': 0.82, + 'PTN->MSN': 0.98, 'PTN->FSI': 0.70, 'PTN->STN': 0.97, + 'CMPf->STN': 0.46, 'CMPf->MSN': 0.27, 'CMPf->FSI': 0.06, - 'CMPf->GPe': 0.0, - 'CMPf->GPi': 0.48 - } + 'CMPf->GPe': 0.00, + 'CMPf->Arky': 0.00, + 'CMPf->Prot': 0.00, + 'CMPf->GPi': 0.48,} # electrotonic constant L computation: -dx={'MSN':1.E-6,'FSI':1.5E-6,'STN':1.5E-6,'GPe':1.7E-6,'GPi':1.2E-6} -lx={'MSN':619E-6,'FSI':961E-6,'STN':750E-6,'GPe':865E-6,'GPi':1132E-6} +dx={'MSN':1.E-6,'FSI':1.5E-6,'STN':1.5E-6,'GPe':1.7E-6,'Arky':1.7E-6,'Prot':1.7E-6,'GPi':1.2E-6} +lx={'MSN':619E-6,'FSI':961E-6,'STN':750E-6,'GPe':865E-6,'Arky':865E-6,'Prot':865E-6,'GPi':1132E-6} LX={} for n in NUCLEI: LX[n]=lx[n]*sqrt((4*Ri)/(dx[n]*Rm)) # tau: communication delays tau = {'MSN->GPe': 7., + 'MSN->Arky': 7., + 'MSN->Prot': 7., 'MSN->GPi': 11., 'MSN->MSN': 1., + 'FSI->MSN': 1., 'FSI->FSI': 1., + 'STN->GPe': 3., + 'STN->Arky': 3., + 'STN->Prot': 3., 'STN->GPi': 3., 'STN->MSN': 3., 'STN->FSI': 3., + 'GPe->STN': 10., 'GPe->GPe': 1., 'GPe->GPi': 3., 'GPe->MSN': 3., 'GPe->FSI': 3., + + 'Arky->Arky': 1., + 'Arky->Prot': 1., + 'Arky->MSN': 3., + 'Arky->FSI': 3., + + 'Prot->STN': 10., + 'Prot->Arky': 1., + 'Prot->Prot': 1., + 'Prot->GPi': 3., + 'CSN->MSN': 7., 'CSN->FSI': 7., + 'PTN->MSN': 3., 'PTN->FSI': 3., 'PTN->STN': 3., + 'CMPf->MSN': 7., 'CMPf->FSI': 7., 'CMPf->STN': 7.,#4 'CMPf->GPe': 7.,#5 + 'CMPf->Arky': 7.,#5 + 'CMPf->Prot': 7.,#5 'CMPf->GPi': 7.,#6 } @@ -651,8 +810,8 @@ def computeW(listRecType, nameSrc, nameTgt, inDegree, gain=1.,verbose=False): 'V_reset': 0.0, 'I_e': 0.0, 'V_min': -20.0, # as in HSG06 - 'tau_syn': tau_syn - } + 'tau_syn': tau_syn,} + initNeurons() # sets the default params of iaf_alpha_psc_mutisynapse neurons to CommonParams MSNparams = {'tau_m': 13.0, # according to SBE12 @@ -675,6 +834,15 @@ def computeW(listRecType, nameSrc, nameTgt, inDegree, gain=1.,verbose=False): 'C_m': 14.0 # so that R_m=1, C_m=tau_m } +Arkyparams = {'tau_m': 14.0, # 20 -> 14 based on Johnson & McIntyre 2008, JNphy) + 'V_th': 11.0, # value of the LG14 example model, table 9 + 'C_m': 14.0 # so that R_m=1, C_m=tau_m + } + +Protparams = {'tau_m': 14.0, # 20 -> 14 based on Johnson & McIntyre 2008, JNphy) + 'V_th': 11.0, # value of the LG14 example model, table 9 + 'C_m': 14.0 # so that R_m=1, C_m=tau_m + } GPiparams = {'tau_m': 14.0, # 20 -> 14 based on Johnson & McIntyre 2008, JNphy) 'V_th': 6.0, # value of the LG14 example model, table 9 'C_m': 14.0 # so that R_m=1, C_m=tau_m @@ -688,6 +856,8 @@ def computeW(listRecType, nameSrc, nameTgt, inDegree, gain=1.,verbose=False): 'FSI':FSIparams, 'STN':STNparams, 'GPe':GPeparams, + 'Arky':Arkyparams, + 'Prot':Protparams, 'GPi':GPiparams} Pop = {} @@ -702,7 +872,9 @@ def computeW(listRecType, nameSrc, nameTgt, inDegree, gain=1.,verbose=False): 'FSI': 16.6 , 'STN': 14.3 , 'GPe': 62.6 , - 'GPi': 64.2 + 'Arky': 62.6 , + 'Prot': 62.6 , + 'GPi': 64.2 , } #--------------------------- diff --git a/baseParams.py b/baseParams.py index 17e6f59..cc69ddf 100644 --- a/baseParams.py +++ b/baseParams.py @@ -6,30 +6,79 @@ #################################################################################### params = { +'splitGPe': False, 'nbCh': 1, # number of concurrent channels to simulate 'LG14modelID': 9, # LG 2014 parameterization used (default: model #9) + 'nbMSN': 2644., # population size (default: 1/1000 of the BG) 'nbFSI': 53., # ^ 'nbSTN': 8., # ^ 'nbGPe': 25., # ^ +'nbArky': 5., # part of the GPe which projects to the striatum +'nbProt': 20., # part of the GPe which projects to the STN and GPi/SNr 'nbGPi': 14., # ^ 'nbCSN': 3000., # ^ 'nbPTN': 100., # ^ 'nbCMPf': 9., # ^ -'GMSN': 1., # gain on all synapses (default: no gain) -'GFSI': 1., # ^ -'GSTN': 1., # ^ -'GGPe': 1., # ^ -'GGPi': 1., # ^ + +'GCSNMSN': 1., # defining connection types for channel-based models (focused or diffuse) based on LG14 - refer to this paper for justification +'GPTNMSN': 1., # ^ +'GCMPfMSN': 1., # ^ +'GMSNMSN': 1., # ^ +'GFSIMSN': 1., # ^ +'GSTNMSN': 1., # ^ +'GGPeMSN': 1., # ^ +'GArkyMSN': 1., # ^ + +'GCSNFSI': 1., # ^ +'GPTNFSI': 1., # ^ +'GCMPfFSI': 1., # ^ +'GFSIFSI': 1., # ^ +'GSTNFSI': 1., # ^ +'GGPeFSI': 1., # ^ +'GArkyFSI': 1., # ^ + +'GPTNSTN': 1., # ^ +'GCMPfSTN': 1., # ^ +'GGPeSTN': 1., # ^ +'GProtSTN': 1., # ^ + +'GCMPfGPe': 1., # ^ +'GMSNGPe': 1., # ^ +'GSTNGPe': 1., # ^ +'GGPeGPe': 1., # ^ + +'GCMPfArky': 1., # ^ +'GMSNArky': 1., # ^ +'GSTNArky': 1., # ^ +'GArkyArky': 1/5., # ^ +'GProtArky': 4/5., # ^ + +'GCMPfProt': 1., # ^ +'GMSNProt': 1., # ^ +'GSTNProt': 1., # ^ +'GArkyProt': 1/5., # ^ +'GProtProt': 4/5., # ^ + +'GCMPfGPi': 1., # ^ +'GMSNGPi': 1., # ^ +'GSTNGPi': 1., # ^ +'GGPeGPi': 1., # LG14: no data available to decide; setting to diffuse improve selection properties +'GProtGPi': 1., # + 'IeMSN': 0., # tonic input currents (default: no input current) 'IeFSI': 0., # ^ 'IeSTN': 0., # ^ 'IeGPe': 0., # ^ +'IeArky': 0., # ^ +'IeProt': 0., # ^ 'IeGPi': 0., # ^ + # There are 3 different format for setting the inDegreeXY (=number of different incoming neurons from X that target one neuron in Y) # - 'inDegreeAbs': specify the absolute number of different input neurons from X that target one neuron of Y --- be careful when using this setting, as the population size varies widly between the striatum and the downstream nuclei # - 'outDegreeAbs': specify the absolute number of contacts between an axon from X to each dendritic tree in Y # - 'outDegreeCons': specify the constrained number of contacts between an axon from X to each dendritic tree in Y as a fraction between 0 (minimal number of contacts to achieve required axonal bouton counts) and 1 (maximal number of contacts with respect to population numbers) + 'RedundancyType': 'outDegreeAbs', # by default all axons are hypothesized to target each dendritic tree at 3 different locations 'redundancyCSNMSN': 3, # ^ 'redundancyPTNMSN': 3, # ^ @@ -38,23 +87,44 @@ 'redundancyFSIMSN': 3, # ^ 'redundancySTNMSN': 3, # ^ 'redundancyGPeMSN': 3, # ^ +'redundancyArkyMSN': 3, # ^ + 'redundancyCSNFSI': 3, # ^ 'redundancyPTNFSI': 3, # ^ -'redundancySTNFSI': 3, # ^ -'redundancyGPeFSI': 3, # ^ 'redundancyCMPfFSI': 3, # ^ 'redundancyFSIFSI': 3, # ^ +'redundancySTNFSI': 3, # ^ +'redundancyGPeFSI': 3, # ^ +'redundancyArkyFSI': 3, # ^ + 'redundancyPTNSTN': 3, # ^ 'redundancyCMPfSTN': 3, # ^ 'redundancyGPeSTN': 3, # ^ +'redundancyProtSTN': 3, # ^ + 'redundancyCMPfGPe': 3, # ^ 'redundancySTNGPe': 3, # ^ 'redundancyMSNGPe': 3, # ^ 'redundancyGPeGPe': 3, # ^ + +'redundancyCMPfArky': 3, # ^ +'redundancySTNArky': 3, # ^ +'redundancyMSNArky': 3, # ^ +'redundancyArkyArky': 3, # ^ +'redundancyProtArky': 3, # ^ + +'redundancyCMPfProt': 3, # ^ +'redundancySTNProt': 3, # ^ +'redundancyMSNProt': 3, # ^ +'redundancyArkyProt': 3, # ^ +'redundancyProtProt': 3, # ^ + +'redundancyCMPfGPi': 3, # ^ 'redundancyMSNGPi': 3, # ^ 'redundancySTNGPi': 3, # ^ 'redundancyGPeGPi': 3, # ^ -'redundancyCMPfGPi': 3, # ^ +'redundancyProtGPi': 3, # ^ + 'cTypeCSNMSN': 'focused', # defining connection types for channel-based models (focused or diffuse) based on LG14 - refer to this paper for justification 'cTypePTNMSN': 'focused', # ^ 'cTypeCMPfMSN': 'diffuse', # ^ @@ -62,23 +132,44 @@ 'cTypeFSIMSN': 'diffuse', # ^ 'cTypeSTNMSN': 'diffuse', # ^ 'cTypeGPeMSN': 'diffuse', # ^ +'cTypeArkyMSN': 'diffuse', # ^ + 'cTypeCSNFSI': 'focused', # ^ 'cTypePTNFSI': 'focused', # ^ 'cTypeCMPfFSI': 'diffuse', # ^ 'cTypeFSIFSI': 'diffuse', # ^ 'cTypeSTNFSI': 'diffuse', # ^ 'cTypeGPeFSI': 'diffuse', # ^ +'cTypeArkyFSI': 'diffuse', # ^ + 'cTypePTNSTN': 'focused', # ^ 'cTypeCMPfSTN': 'diffuse', # ^ 'cTypeGPeSTN': 'focused', # ^ +'cTypeProtSTN': 'focused', # ^ + 'cTypeCMPfGPe': 'diffuse', # ^ 'cTypeMSNGPe': 'focused', # ^ 'cTypeSTNGPe': 'diffuse', # ^ 'cTypeGPeGPe': 'diffuse', # ^ + +'cTypeCMPfArky': 'diffuse', # ^ +'cTypeMSNArky': 'focused', # ^ +'cTypeSTNArky': 'diffuse', # ^ +'cTypeArkyArky': 'diffuse', # ^ +'cTypeProtArky': 'diffuse', # ^ + +'cTypeCMPfProt': 'diffuse', # ^ +'cTypeMSNProt': 'focused', # ^ +'cTypeSTNProt': 'diffuse', # ^ +'cTypeArkyProt': 'diffuse', # ^ +'cTypeProtProt': 'diffuse', # ^ + 'cTypeCMPfGPi': 'diffuse', # ^ 'cTypeMSNGPi': 'focused', # ^ 'cTypeSTNGPi': 'diffuse', # ^ 'cTypeGPeGPi': 'diffuse', # LG14: no data available to decide; setting to diffuse improve selection properties +'cTypeProtGPi': 'diffuse', # + 'parrotCMPf' : True, # Should the CMPf be simulated using parrot neurons? 'stochastic_delays': None, # If specified, gives the relative sd of a clipped Gaussian distribution for the delays # For convenience, a few simulator variables are also set here @@ -88,5 +179,6 @@ 'nbcpu': 1, # number of CPUs to be used by nest 'durationH': '08', # max duration of a simulation, used by Sango cluster 'nbnodes': '1', # number of nodes, used by K computer +'tSimu': 5000., # time duration of one simulation } diff --git a/baseParams.pyc b/baseParams.pyc new file mode 100644 index 0000000..ccb6be4 Binary files /dev/null and b/baseParams.pyc differ diff --git a/iniBG.py b/iniBG.py index 802501b..7b835a6 100644 --- a/iniBG.py +++ b/iniBG.py @@ -50,10 +50,20 @@ def create_pop(*args, **kwargs): create_pop('STN') update_Ie('STN') - nbSim['GPe'] = params['nbGPe'] - create_pop('GPe') - update_Ie('GPe') - + if params['splitGPe']: + nbSim['Arky'] = params['nbArky'] + create_pop('Arky') + update_Ie('Arky') + + nbSim['Prot'] = params['nbProt'] + create_pop('Prot') + update_Ie('Prot') + else: + nbSim['GPe'] = params['nbGPe'] + create_pop('GPe') + update_Ie('GPe') + + nbSim['GPi'] = params['nbGPi'] create_pop('GPi') update_Ie('GPi') @@ -79,14 +89,6 @@ def create_pop(*args, **kwargs): # Connects the populations of a previously created multi-channel BG circuit #------------------------------------------ def connectBG(antagInjectionSite,antag): - G = {'MSN': params['GMSN'], - 'FSI': params['GFSI'], - 'STN': params['GSTN'], - 'GPe': params['GGPe'], - 'GPi': params['GGPi'], - } - - print "Gains on LG14 syn. strength:", G # single or multi-channel? if params['nbCh'] == 1: @@ -106,111 +108,223 @@ def connect_pop(*args, **kwargs): print '* MSN Inputs' if 'nbCues' not in params.keys(): # usual case: CSN have as the same number of channels than the BG nuclei - CSN_MSN = connect_pop('ex','CSN','MSN', projType=params['cTypeCSNMSN'], redundancy=params['redundancyCSNMSN'], gain=G['MSN']) + CSN_MSN = connect_pop('ex','CSN','MSN', projType=params['cTypeCSNMSN'], redundancy=params['redundancyCSNMSN'], gain=params['GCSNMSN']) else: # special case: extra 'cue' channels that target MSN - CSN_MSN = connect_pop('ex','CSN','MSN', projType=params['cTypeCSNMSN'], redundancy=params['redundancyCSNMSN'], gain=G['MSN']/2., source_channels=range(params['nbCh'])) - connect_pop('ex','CSN','MSN', projType='diffuse', redundancy=params['redundancyCSNMSN'], gain=G['MSN']/2., source_channels=range(params['nbCh'], params['nbCh']+params['nbCues'])) - PTN_MSN = connect_pop('ex','PTN','MSN', projType=params['cTypePTNMSN'], redundancy= params['redundancyPTNMSN'], gain=G['MSN']) - CMPf_MSN = connect_pop('ex','CMPf','MSN',projType=params['cTypeCMPfMSN'],redundancy= params['redundancyCMPfMSN'],gain=G['MSN']) - connect_pop('in','MSN','MSN', projType=params['cTypeMSNMSN'], redundancy= params['redundancyMSNMSN'], gain=G['MSN']) - connect_pop('in','FSI','MSN', projType=params['cTypeFSIMSN'], redundancy= params['redundancyFSIMSN'], gain=G['MSN']) + CSN_MSN = connect_pop('ex','CSN','MSN', projType=params['cTypeCSNMSN'], redundancy=params['redundancyCSNMSN'], gain=Params['GCSNMSN']/2., source_channels=range(params['nbCh'])) + connect_pop('ex','CSN','MSN', projType='diffuse', redundancy=params['redundancyCSNMSN'], gain=params['GCSNMSN']/2., source_channels=range(params['nbCh'], params['nbCh']+params['nbCues'])) + PTN_MSN = connect_pop('ex','PTN','MSN', projType=params['cTypePTNMSN'], redundancy= params['redundancyPTNMSN'], gain=params['GPTNMSN']) + CMPf_MSN = connect_pop('ex','CMPf','MSN',projType=params['cTypeCMPfMSN'],redundancy= params['redundancyCMPfMSN'],gain=params['GCMPfMSN']) + connect_pop('in','MSN','MSN', projType=params['cTypeMSNMSN'], redundancy= params['redundancyMSNMSN'], gain=params['GMSNMSN']) + connect_pop('in','FSI','MSN', projType=params['cTypeFSIMSN'], redundancy= params['redundancyFSIMSN'], gain=params['GFSIMSN']) # some parameterizations from LG14 have no STN->MSN or GPe->MSN synaptic contacts if alpha['STN->MSN'] != 0: print "alpha['STN->MSN']",alpha['STN->MSN'] - connect_pop('ex','STN','MSN', projType=params['cTypeSTNMSN'], redundancy= params['redundancySTNMSN'], gain=G['MSN']) + connect_pop('ex','STN','MSN', projType=params['cTypeSTNMSN'], redundancy= params['redundancySTNMSN'], gain=params['GSTNMSN']) if alpha['GPe->MSN'] != 0: - print "alpha['GPe->MSN']",alpha['GPe->MSN'] - connect_pop('in','GPe','MSN', projType=params['cTypeGPeMSN'], redundancy= params['redundancyGPeMSN'], gain=G['MSN']) + if params['splitGPe']: + print "alpha['Arky->MSN']",alpha['Arky->MSN'] + connect_pop('in','Arky','MSN', projType=params['cTypeArkyMSN'], redundancy= params['redundancyArkyMSN'], gain=params['GArkyMSN']) + else: + print "alpha['GPe->MSN']",alpha['GPe->MSN'] + connect_pop('in','GPe','MSN', projType=params['cTypeGPeMSN'], redundancy= params['redundancyGPeMSN'], gain=params['GGPeMSN']) print '* FSI Inputs' - connect_pop('ex','CSN','FSI', projType=params['cTypeCSNFSI'], redundancy= params['redundancyCSNFSI'], gain=G['FSI']) - connect_pop('ex','PTN','FSI', projType=params['cTypePTNFSI'], redundancy= params['redundancyPTNFSI'], gain=G['FSI']) + connect_pop('ex','CSN','FSI', projType=params['cTypeCSNFSI'], redundancy= params['redundancyCSNFSI'], gain=params['GCSNFSI']) + connect_pop('ex','PTN','FSI', projType=params['cTypePTNFSI'], redundancy= params['redundancyPTNFSI'], gain=params['GPTNFSI']) if alpha['STN->FSI'] != 0: - connect_pop('ex','STN','FSI', projType=params['cTypeSTNFSI'],redundancy= params['redundancySTNFSI'],gain=G['FSI']) - connect_pop('in','GPe','FSI', projType=params['cTypeGPeFSI'], redundancy= params['redundancyGPeFSI'], gain=G['FSI']) - connect_pop('ex','CMPf','FSI',projType=params['cTypeCMPfFSI'],redundancy= params['redundancyCMPfFSI'],gain=G['FSI']) - connect_pop('in','FSI','FSI', projType=params['cTypeFSIFSI'], redundancy= params['redundancyFSIFSI'], gain=G['FSI']) + connect_pop('ex','STN','FSI', projType=params['cTypeSTNFSI'],redundancy= params['redundancySTNFSI'],gain=params['GSTNFSI']) + if params['splitGPe']: + connect_pop('in','Arky','FSI', projType=params['cTypeArkyFSI'], redundancy= params['redundancyArkyFSI'], gain=params['GArkyFSI']) + else: + connect_pop('in','GPe','FSI', projType=params['cTypeGPeFSI'], redundancy= params['redundancyGPeFSI'], gain=params['GGPeFSI']) + + connect_pop('ex','CMPf','FSI',projType=params['cTypeCMPfFSI'],redundancy= params['redundancyCMPfFSI'],gain=params['GCMPfFSI']) + connect_pop('in','FSI','FSI', projType=params['cTypeFSIFSI'], redundancy= params['redundancyFSIFSI'], gain=params['GFSIFSI']) print '* STN Inputs' - connect_pop('ex','PTN','STN', projType=params['cTypePTNSTN'], redundancy= params['redundancyPTNSTN'], gain=G['STN']) - connect_pop('ex','CMPf','STN',projType=params['cTypeCMPfSTN'],redundancy= params['redundancyCMPfSTN'], gain=G['STN']) - connect_pop('in','GPe','STN', projType=params['cTypeGPeSTN'], redundancy= params['redundancyGPeSTN'], gain=G['STN']) - - print '* GPe Inputs' - if 'fakeGPeRecurrent' not in params.keys(): - # usual case: GPe's recurrent collaterals are handled normally - GPe_recurrent_source = 'GPe' + connect_pop('ex','PTN','STN', projType=params['cTypePTNSTN'], redundancy= params['redundancyPTNSTN'], gain=params['GPTNSTN']) + connect_pop('ex','CMPf','STN',projType=params['cTypeCMPfSTN'],redundancy= params['redundancyCMPfSTN'], gain=params['GCMPfSTN']) + if params['splitGPe']: + connect_pop('in','Prot','STN', projType=params['cTypeProtSTN'], redundancy= params['redundancyProtSTN'], gain=params['GProtSTN']) else: - # here collaterals are simulated with Poisson train spikes firing at the frequency given by params['fakeGPeRecurrent'] - rate['Fake_GPe'] = float(params['fakeGPeRecurrent']) - for nucleus_dict in [nbSim, neuronCounts]: - nucleus_dict['Fake_GPe'] = nucleus_dict['GPe'] - for connection_dict in [P, alpha, p, tau]: - connection_dict['Fake_GPe->GPe'] = connection_dict['GPe->GPe'] - if params['nbCh'] == 1: - create('Fake_GPe', fake=True, parrot=True) - else: - createMC('Fake_GPe', params['nbCh'], fake=True, parrot=True) - GPe_recurrent_source = 'Fake_GPe' - if antagInjectionSite == 'GPe': - if antag == 'AMPA': - connect_pop('NMDA','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=G['GPe']) - connect_pop('NMDA','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=G['GPe']) - connect_pop('in','MSN','GPe', projType=params['cTypeMSNGPe'], redundancy= params['redundancyMSNGPe'], gain=G['GPe']) - connect_pop('in', GPe_recurrent_source, 'GPe', projType=params['cTypeGPeGPe'], redundancy= params['redundancyGPeGPe'], gain=G['GPe']) - elif antag == 'NMDA': - connect_pop('AMPA','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=G['GPe']) - connect_pop('AMPA','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=G['GPe']) - connect_pop('in','MSN','GPe', projType=params['cTypeMSNGPe'], redundancy= params['redundancyMSNGPe'], gain=G['GPe']) - connect_pop('in', GPe_recurrent_source, 'GPe', projType=params['cTypeGPeGPe'], redundancy= params['redundancyGPeGPe'], gain=G['GPe']) - elif antag == 'AMPA+GABAA': - connect_pop('NMDA','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=G['GPe']) - connect_pop('NMDA','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=G['GPe']) - elif antag == 'GABAA': - connect_pop('ex','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=G['GPe']) - connect_pop('ex','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=G['GPe']) - else: - print antagInjectionSite,": unknown antagonist experiment:",antag + connect_pop('in','GPe','STN', projType=params['cTypeGPeSTN'], redundancy= params['redundancyGPeSTN'], gain=params['GGPeSTN']) + + if params['splitGPe']: + print '* Arky Inputs' + if 'fakeArkyRecurrent' not in params.keys(): + # usual case: Arky's recurrent collaterals are handled normally + Arky_recurrent_source = 'Arky' + else: + # here collaterals are simulated with Poisson train spikes firing at the frequency given by params['fakeArkyRecurrent'] + rate['Fake_Arky'] = float(params['fakeArkyRecurrent']) + for nucleus_dict in [nbSim, neuronCounts]: + nucleus_dict['Fake_Arky'] = nucleus_dict['Arky'] + for connection_dict in [P, alpha, p, tau]: + connection_dict['Fake_Arky->Arky'] = connection_dict['Arky->Arky'] + if params['nbCh'] == 1: + create('Fake_Arky', fake=True, parrot=True) + else: + createMC('Fake_Arky', params['nbCh'], fake=True, parrot=True) + Arky_recurrent_source = 'Fake_Arky' + if antagInjectionSite == 'GPe': + if antag == 'AMPA': + connect_pop('NMDA','CMPf','Arky',projType=params['cTypeCMPfArky'],redundancy= params['redundancyCMPfArky'],gain=params['GCMPfArky']) + connect_pop('NMDA','STN','Arky', projType=params['cTypeSTNArky'], redundancy= params['redundancySTNArky'], gain=params['GSTNArky']) + connect_pop('in','MSN','Arky', projType=params['cTypeMSNArky'], redundancy= params['redundancyMSNArky'], gain=params['GMSNArky']) + connect_pop('in','Prot','Arky', projType=params['cTypeProtArky'], redundancy= params['redundancyProtArky'], gain=params['GProtArky']) + connect_pop('in', Arky_recurrent_source, 'Arky', projType=params['cTypeArkyArky'], redundancy= params['redundancyArkyArky'], gain=params['GArkyArky']) + elif antag == 'NMDA': + connect_pop('AMPA','CMPf','Arky',projType=params['cTypeCMPfArky'],redundancy= params['redundancyCMPfArky'],gain=params['GCMPfArky']) + connect_pop('AMPA','STN','Arky', projType=params['cTypeSTNArky'], redundancy= params['redundancySTNArky'], gain=params['GSTNArky']) + connect_pop('in','MSN','Arky', projType=params['cTypeMSNArky'], redundancy= params['redundancyMSNArky'], gain=params['GMSNArky']) + connect_pop('in','Prot','Arky', projType=params['cTypeProtArky'], redundancy= params['redundancyProtArky'], gain=params['GProtArky']) + connect_pop('in', Arky_recurrent_source, 'Arky', projType=params['cTypeArkyArky'], redundancy= params['redundancyArkyArky'], gain=params['GArkyArky']) + elif antag == 'AMPA+GABAA': + connect_pop('NMDA','CMPf','Arky',projType=params['cTypeCMPfArky'],redundancy= params['redundancyCMPfArky'],gain=params['GCMPfArky']) + connect_pop('NMDA','STN','Arky', projType=params['cTypeSTNArky'], redundancy= params['redundancySTNArky'], gain=params['GSTNArky']) + elif antag == 'GABAA': + connect_pop('ex','CMPf','Arky',projType=params['cTypeCMPfArky'],redundancy= params['redundancyCMPfArky'],gain=params['GCMPfArky']) + connect_pop('ex','STN','Arky', projType=params['cTypeSTNArky'], redundancy= params['redundancySTNArky'], gain=params['GSTNArky']) + else: + print antagInjectionSite,": unknown antagonist experiment:",antag + else: + connect_pop('ex','CMPf','Arky',projType=params['cTypeCMPfArky'],redundancy= params['redundancyCMPfArky'],gain=params['GCMPfArky']) + connect_pop('ex','STN','Arky', projType=params['cTypeSTNArky'], redundancy= params['redundancySTNArky'], gain=params['GSTNArky']) + connect_pop('in','MSN','Arky', projType=params['cTypeMSNArky'], redundancy= params['redundancyMSNArky'], gain=params['GMSNArky']) + connect_pop('in','Prot','Arky', projType=params['cTypeProtArky'], redundancy= params['redundancyProtArky'], gain=params['GProtArky']) + connect_pop('in', Arky_recurrent_source, 'Arky', projType=params['cTypeArkyArky'], redundancy= params['redundancyArkyArky'], gain=params['GArkyArky']) + + print '* Prot Inputs' + if 'fakeProtRecurrent' not in params.keys(): + # usual case: Prot's recurrent collaterals are handled normally + Prot_recurrent_source = 'Prot' + else: + # here collaterals are simulated with Poisson train spikes firing at the frequency given by params['fakeProtRecurrent'] + rate['Fake_Prot'] = float(params['fakeProtRecurrent']) + for nucleus_dict in [nbSim, neuronCounts]: + nucleus_dict['Fake_Prot'] = nucleus_dict['Prot'] + for connection_dict in [P, alpha, p, tau]: + connection_dict['Fake_Prot->Prot'] = connection_dict['Prot->Prot'] + if params['nbCh'] == 1: + create('Fake_Prot', fake=True, parrot=True) + else: + createMC('Fake_Prot', params['nbCh'], fake=True, parrot=True) + Prot_recurrent_source = 'Fake_Prot' + if antagInjectionSite == 'GPe': + if antag == 'AMPA': + connect_pop('NMDA','CMPf','Prot',projType=params['cTypeCMPfProt'],redundancy= params['redundancyCMPfProt'],gain=params['GCMPfProt']) + connect_pop('NMDA','STN','Prot', projType=params['cTypeSTNProt'], redundancy= params['redundancySTNProt'], gain=params['GSTNProt']) + connect_pop('in','MSN','Prot', projType=params['cTypeMSNProt'], redundancy= params['redundancyMSNProt'], gain=params['GMSNProt']) + connect_pop('in','Arky','Prot', projType=params['cTypeArkyProt'], redundancy= params['redundancyArkyProt'], gain=params['GArkyProt']) + connect_pop('in', Prot_recurrent_source, 'Prot', projType=params['cTypeProtProt'], redundancy= params['redundancyProtProt'], gain=params['GProtProt']) + elif antag == 'NMDA': + connect_pop('AMPA','CMPf','Prot',projType=params['cTypeCMPfProt'],redundancy= params['redundancyCMPfProt'],gain=params['GCMPfProt']) + connect_pop('AMPA','STN','Prot', projType=params['cTypeSTNProt'], redundancy= params['redundancySTNProt'], gain=params['GSTNProt']) + connect_pop('in','MSN','Prot', projType=params['cTypeMSNProt'], redundancy= params['redundancyMSNProt'], gain=params['GMSNProt']) + connect_pop('in','Arky','Prot', projType=params['cTypeArkyProt'], redundancy= params['redundancyArkyProt'], gain=params['GArkyProt']) + connect_pop('in', Prot_recurrent_source, 'Prot', projType=params['cTypeProtProt'], redundancy= params['redundancyProtProt'], gain=params['GProtProt']) + elif antag == 'AMPA+GABAA': + connect_pop('NMDA','CMPf','Prot',projType=params['cTypeCMPfProt'],redundancy= params['redundancyCMPfProt'],gain=params['GCMPfProt']) + connect_pop('NMDA','STN','Prot', projType=params['cTypeSTNProt'], redundancy= params['redundancySTNProt'], gain=params['GSTNProt']) + elif antag == 'GABAA': + connect_pop('ex','CMPf','Prot',projType=params['cTypeCMPfProt'],redundancy= params['redundancyCMPfProt'],gain=params['GCMPfProt']) + connect_pop('ex','STN','Prot', projType=params['cTypeSTNProt'], redundancy= params['redundancySTNProt'], gain=params['GSTNProt']) + else: + print antagInjectionSite,": unknown antagonist experiment:",antag + else: + connect_pop('ex','CMPf','Prot',projType=params['cTypeCMPfProt'],redundancy= params['redundancyCMPfProt'],gain=params['GCMPfProt']) + connect_pop('ex','STN','Prot', projType=params['cTypeSTNProt'], redundancy= params['redundancySTNProt'], gain=params['GSTNProt']) + connect_pop('in','MSN','Prot', projType=params['cTypeMSNProt'], redundancy= params['redundancyMSNProt'], gain=params['GMSNProt']) + connect_pop('in','Arky','Prot', projType=params['cTypeArkyProt'], redundancy= params['redundancyArkyProt'], gain=params['GArkyProt']) + connect_pop('in', Prot_recurrent_source, 'Prot', projType=params['cTypeProtProt'], redundancy= params['redundancyProtProt'], gain=params['GProtProt']) + else: - connect_pop('ex','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=G['GPe']) - connect_pop('ex','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=G['GPe']) - connect_pop('in','MSN','GPe', projType=params['cTypeMSNGPe'], redundancy= params['redundancyMSNGPe'], gain=G['GPe']) - connect_pop('in', GPe_recurrent_source, 'GPe', projType=params['cTypeGPeGPe'], redundancy= params['redundancyGPeGPe'], gain=G['GPe']) + print '* GPe Inputs' + if 'fakeGPeRecurrent' not in params.keys(): + # usual case: GPe's recurrent collaterals are handled normally + GPe_recurrent_source = 'GPe' + else: + # here collaterals are simulated with Poisson train spikes firing at the frequency given by params['fakeGPeRecurrent'] + rate['Fake_GPe'] = float(params['fakeGPeRecurrent']) + for nucleus_dict in [nbSim, neuronCounts]: + nucleus_dict['Fake_GPe'] = nucleus_dict['GPe'] + for connection_dict in [P, alpha, p, tau]: + connection_dict['Fake_GPe->GPe'] = connection_dict['GPe->GPe'] + if params['nbCh'] == 1: + create('Fake_GPe', fake=True, parrot=True) + else: + createMC('Fake_GPe', params['nbCh'], fake=True, parrot=True) + GPe_recurrent_source = 'Fake_GPe' + if antagInjectionSite == 'GPe': + if antag == 'AMPA': + connect_pop('NMDA','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=params['GCMPfGPe']) + connect_pop('NMDA','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=params['GSTNGPe']) + connect_pop('in','MSN','GPe', projType=params['cTypeMSNGPe'], redundancy= params['redundancyMSNGPe'], gain=params['GMSNGPe']) + connect_pop('in', GPe_recurrent_source, 'GPe', projType=params['cTypeGPeGPe'], redundancy= params['redundancyGPeGPe'], gain=params['GGPeGPe']) + elif antag == 'NMDA': + connect_pop('AMPA','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=params['GCMPfGPe']) + connect_pop('AMPA','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=params['GSTNGPe']) + connect_pop('in','MSN','GPe', projType=params['cTypeMSNGPe'], redundancy= params['redundancyMSNGPe'], gain=params['GMSNGPe']) + connect_pop('in', GPe_recurrent_source, 'GPe', projType=params['cTypeGPeGPe'], redundancy= params['redundancyGPeGPe'], gain=params['GGPeGPe']) + elif antag == 'AMPA+GABAA': + connect_pop('NMDA','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=params['GCMPfGPe']) + connect_pop('NMDA','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=params['GSTNGPe']) + elif antag == 'GABAA': + connect_pop('ex','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=params['GCMPfGPe']) + connect_pop('ex','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=params['GSTNGPe']) + else: + print antagInjectionSite,": unknown antagonist experiment:",antag + else: + connect_pop('ex','CMPf','GPe',projType=params['cTypeCMPfGPe'],redundancy= params['redundancyCMPfGPe'],gain=params['GCMPfGPe']) + connect_pop('ex','STN','GPe', projType=params['cTypeSTNGPe'], redundancy= params['redundancySTNGPe'], gain=params['GSTNGPe']) + connect_pop('in','MSN','GPe', projType=params['cTypeMSNGPe'], redundancy= params['redundancyMSNGPe'], gain=params['GMSNGPe']) + connect_pop('in', GPe_recurrent_source, 'GPe', projType=params['cTypeGPeGPe'], redundancy= params['redundancyGPeGPe'], gain=params['GGPeGPe']) print '* GPi Inputs' if antagInjectionSite =='GPi': if antag == 'AMPA+NMDA+GABAA': pass elif antag == 'NMDA': - connect_pop('in','MSN','GPi', projType=params['cTypeMSNGPi'], redundancy= params['redundancyMSNGPi'], gain=G['GPi']) - connect_pop('AMPA','STN','GPi', projType=params['cTypeSTNGPi'], redundancy= params['redundancySTNGPi'], gain=G['GPi']) - connect_pop('in','GPe','GPi', projType=params['cTypeGPeGPi'], redundancy= params['redundancyGPeGPi'], gain=G['GPi']) - connect_pop('AMPA','CMPf','GPi',projType=params['cTypeCMPfGPi'],redundancy= params['redundancyCMPfGPi'],gain=G['GPi']) + connect_pop('in','MSN','GPi', projType=params['cTypeMSNGPi'], redundancy= params['redundancyMSNGPi'], gain=params['GMSNGPi']) + connect_pop('AMPA','STN','GPi', projType=params['cTypeSTNGPi'], redundancy= params['redundancySTNGPi'], gain=params['GSTNGPi']) + if params['splitGPe']: + connect_pop('in','Prot','GPi', projType=params['cTypeProtGPi'], redundancy= params['redundancyProtGPi'], gain=params['GProtGPi']) + else: + connect_pop('in','GPe','GPi', projType=params['cTypeGPeGPi'], redundancy= params['redundancyGPeGPi'], gain=params['GGPeGPi']) + connect_pop('AMPA','CMPf','GPi',projType=params['cTypeCMPfGPi'],redundancy= params['redundancyCMPfGPi'],gain=params['GCMPfGPi']) elif antag == 'NMDA+AMPA': - connect_pop('in','MSN','GPi', projType=params['cTypeMSNGPi'],redundancy= params['redundancyMSNGPi'], gain=G['GPi']) - connect_pop('in','GPe','GPi', projType=params['cTypeGPeGPi'],redundancy= params['redundancyGPeGPi'], gain=G['GPi']) + connect_pop('in','MSN','GPi', projType=params['cTypeMSNGPi'],redundancy= params['redundancyMSNGPi'], gain=params['GMSNGPi']) + if params['splitGPe']: + connect_pop('in','Prot','GPi', projType=params['cTypeProtGPi'], redundancy= params['redundancyProtGPi'], gain=params['GProtGPi']) + else: + connect_pop('in','GPe','GPi', projType=params['cTypeGPeGPi'], redundancy= params['redundancyGPeGPi'], gain=params['GGPeGPi']) elif antag == 'AMPA': - connect_pop('in','MSN','GPi', projType=params['cTypeMSNGPi'], redundancy= params['redundancyMSNGPi'], gain=G['GPi']) - connect_pop('NMDA','STN','GPi', projType=params['cTypeSTNGPi'], redundancy= params['redundancySTNGPi'], gain=G['GPi']) - connect_pop('in','GPe','GPi', projType=params['cTypeGPeGPi'], redundancy= params['redundancyGPeGPi'], gain=G['GPi']) - connect_pop('NMDA','CMPf','GPi',projType=params['cTypeCMPfGPi'],redundancy= params['redundancyCMPfGPi'],gain=G['GPi']) + connect_pop('in','MSN','GPi', projType=params['cTypeMSNGPi'], redundancy= params['redundancyMSNGPi'], gain=params['GMSNGPi']) + connect_pop('NMDA','STN','GPi', projType=params['cTypeSTNGPi'], redundancy= params['redundancySTNGPi'], gain=params['GSTNGPi']) + if params['splitGPe']: + connect_pop('in','Prot','GPi', projType=params['cTypeProtGPi'], redundancy= params['redundancyProtGPi'], gain=params['GProtGPi']) + else: + connect_pop('in','GPe','GPi', projType=params['cTypeGPeGPi'], redundancy= params['redundancyGPeGPi'], gain=params['GGPeGPi']) + connect_pop('NMDA','CMPf','GPi',projType=params['cTypeCMPfGPi'],redundancy= params['redundancyCMPfGPi'],gain=params['GCMPfGPi']) elif antag == 'GABAA': - connect_pop('ex','STN','GPi', projType=params['cTypeSTNGPi'], redundancy= params['redundancySTNGPi'], gain=G['GPi']) - connect_pop('ex','CMPf','GPi',projType=params['cTypeCMPfGPi'],redundancy= params['redundancyCMPfGPi'],gain=G['GPi']) + connect_pop('ex','STN','GPi', projType=params['cTypeSTNGPi'], redundancy= params['redundancySTNGPi'], gain=params['GSTNGPi']) + connect_pop('ex','CMPf','GPi',projType=params['cTypeCMPfGPi'],redundancy= params['redundancyCMPfGPi'],gain=params['GCMPfGPi']) else: print antagInjectionSite,": unknown antagonist experiment:",antag else: - connect_pop('in','MSN','GPi', projType=params['cTypeMSNGPi'], redundancy= params['redundancyMSNGPi'], gain=G['GPi']) - connect_pop('ex','STN','GPi', projType=params['cTypeSTNGPi'], redundancy= params['redundancySTNGPi'], gain=G['GPi']) - connect_pop('in','GPe','GPi', projType=params['cTypeGPeGPi'], redundancy= params['redundancyGPeGPi'], gain=G['GPi']) - connect_pop('ex','CMPf','GPi',projType=params['cTypeCMPfGPi'],redundancy= params['redundancyCMPfGPi'],gain=G['GPi']) + connect_pop('in','MSN','GPi', projType=params['cTypeMSNGPi'], redundancy= params['redundancyMSNGPi'], gain=params['GMSNGPi']) + connect_pop('ex','STN','GPi', projType=params['cTypeSTNGPi'], redundancy= params['redundancySTNGPi'], gain=params['GSTNGPi']) + if params['splitGPe']: + connect_pop('in','Prot','GPi', projType=params['cTypeProtGPi'], redundancy= params['redundancyProtGPi'], gain=params['GProtGPi']) + else: + connect_pop('in','GPe','GPi', projType=params['cTypeGPeGPi'], redundancy= params['redundancyGPeGPi'], gain=params['GGPeGPi']) + connect_pop('ex','CMPf','GPi',projType=params['cTypeCMPfGPi'],redundancy= params['redundancyCMPfGPi'],gain=params['GCMPfGPi']) base_weights = {'CSN_MSN': CSN_MSN, 'PTN_MSN': PTN_MSN, 'CMPf_MSN': CMPf_MSN} return base_weights - #------------------------------------------ # Re-weight a specific connection, characterized by a source, a target, and a receptor # Returns the previous value of that connection (useful for 'reactivating' after a deactivation experiment) @@ -240,7 +354,11 @@ def alter_connection(src, tgt, tgt_receptor, altered_weight): # gets the nuclei involved in deactivation experiments in GPe/GPi #------------------------------------------ def get_afferents(a): - GABA_afferents = ['MSN', 'GPe'] # afferents with gabaergic connections + if params['splitGPe']: + GABA_afferents = ['MSN', 'Arky', 'Prot'] # afferents with gabaergic connections + else: + GABA_afferents = ['MSN', 'GPe'] # afferents with gabaergic connections + GLUT_afferents = ['STN', 'CMPf'] # afferents with glutamatergic connections if a == 'GABAA': afferents = GABA_afferents @@ -296,7 +414,36 @@ def instantiate_BG(params={}, antagInjectionSite='none', antag=''): # We check that all the necessary parameters have been defined. They should be in the modelParams.py file. # If one of them misses, we exit the program. - necessaryParams=['nbCh','nbMSN','nbFSI','nbSTN','nbGPe','nbGPi','nbCSN','nbPTN','nbCMPf','IeMSN','IeFSI','IeSTN','IeGPe','IeGPi','GMSN','GFSI','GSTN','GGPe','GGPi','redundancyCSNMSN','redundancyPTNMSN','redundancyCMPfMSN','redundancyMSNMSN','redundancyFSIMSN','redundancySTNMSN','redundancyGPeMSN','redundancyCSNFSI','redundancyPTNFSI','redundancySTNFSI','redundancyGPeFSI','redundancyCMPfFSI','redundancyFSIFSI','redundancyPTNSTN','redundancyCMPfSTN','redundancyGPeSTN','redundancyCMPfGPe','redundancySTNGPe','redundancyMSNGPe','redundancyGPeGPe','redundancyMSNGPi','redundancySTNGPi','redundancyGPeGPi','redundancyCMPfGPi',] + if params['splitGPe']: + necessaryParams=['nbCh','nbMSN','nbFSI','nbSTN','nbGPe','nbArky','nbProt','nbGPi','nbCSN','nbPTN','nbCMPf', + 'IeMSN','IeFSI','IeSTN','IeGPe','IeArky','IeProt','IeGPi', + 'GCSNMSN','GPTNMSN','GCMPfMSN','GMSNMSN','GFSIMSN','GSTNMSN','GGPeMSN','GArkyMSN', + 'GCSNFSI','GPTNFSI','GSTNFSI','GGPeFSI','GArkyFSI','GCMPfFSI','GFSIFSI', + 'GPTNSTN','GCMPfSTN','GGPeSTN','GProtSTN', + 'GCMPfGPe','GSTNGPe','GMSNGPe','GGPeGPe', + 'GCMPfArky','GSTNArky','GMSNArky','GArkyArky','GProtArky', + 'GCMPfProt','GSTNProt','GMSNProt','GProtProt','GArkyProt', + 'GMSNGPi','GSTNGPi','GGPeGPi','GProtGPi','GCMPfGPi', + 'redundancyCSNMSN','redundancyPTNMSN','redundancyCMPfMSN','redundancyMSNMSN','redundancyFSIMSN','redundancySTNMSN','redundancyGPeMSN','redundancyArkyMSN', + 'redundancyCSNFSI','redundancyPTNFSI','redundancySTNFSI','redundancyGPeFSI','redundancyArkyFSI','redundancyCMPfFSI','redundancyFSIFSI', + 'redundancyPTNSTN','redundancyCMPfSTN','redundancyGPeSTN','redundancyProtSTN', + 'redundancyCMPfGPe','redundancySTNGPe','redundancyMSNGPe','redundancyGPeGPe', + 'redundancyCMPfArky','redundancySTNArky','redundancyMSNArky','redundancyArkyArky','redundancyProtArky', + 'redundancyCMPfProt','redundancySTNProt','redundancyMSNProt','redundancyProtProt','redundancyArkyProt', + 'redundancyMSNGPi','redundancySTNGPi','redundancyGPeGPi','redundancyProtGPi','redundancyCMPfGPi',] + else: + necessaryParams=['nbCh','nbMSN','nbFSI','nbSTN','nbGPe','nbGPi','nbCSN','nbPTN','nbCMPf', + 'IeMSN','IeFSI','IeSTN','IeGPe','IeGPi', + 'GCSNMSN','GPTNMSN','GCMPfMSN','GMSNMSN','GFSIMSN','GSTNMSN','GGPeMSN', + 'GCSNFSI','GPTNFSI','GSTNFSI','GGPeFSI','GCMPfFSI','GFSIFSI', + 'GPTNSTN','GCMPfSTN','GGPeSTN', + 'GCMPfGPe','GSTNGPe','GMSNGPe','GGPeGPe', + 'GMSNGPi','GSTNGPi','GGPeGPi','GCMPfGPi', + 'redundancyCSNMSN','redundancyPTNMSN','redundancyCMPfMSN','redundancyMSNMSN','redundancyFSIMSN','redundancySTNMSN','redundancyGPeMSN', + 'redundancyCSNFSI','redundancyPTNFSI','redundancySTNFSI','redundancyGPeFSI','redundancyCMPfFSI','redundancyFSIFSI', + 'redundancyPTNSTN','redundancyCMPfSTN','redundancyGPeSTN', + 'redundancyCMPfGPe','redundancySTNGPe','redundancyMSNGPe','redundancyGPeGPe', + 'redundancyMSNGPi','redundancySTNGPi','redundancyGPeGPi','redundancyCMPfGPi',] for np in necessaryParams: if np not in params: raise KeyError('Missing parameter: '+np) diff --git a/params/params9_inDegreeAbs.py b/params/params9_inDegreeAbs.py index 6916e8a..80a4559 100644 --- a/params/params9_inDegreeAbs.py +++ b/params/params9_inDegreeAbs.py @@ -3,21 +3,29 @@ the_scale = 4. -params = {'LG14modelID':9 , +params = {'tSimu': 5000., + 'LG14modelID':9 , 'IeMSN': 24.5, 'IeFSI': 8. , 'IeSTN': 9.5 , 'IeGPe': 12. , + 'IeArky': 12. , + 'IeProt': 12. , 'IeGPi': 11. , + 'nbMSN': 2644.*the_scale, # original number of neurons, possibly scaled 'nbFSI': 53.*the_scale , # ^ 'nbSTN': 8.*the_scale , # ^ 'nbGPe': 25.*the_scale , # ^ + 'nbArky': 5.*the_scale , # ^ + 'nbProt': 20.*the_scale , # ^ 'nbGPi': 14.*the_scale , # ^ 'nbCSN': 3000.*the_scale, # large pool of CSN neurons (split per channel) - 'nbPTN': 3000.*the_scale , # large pool of PTN neurons (possibly split per channel) + 'nbPTN': 3000.*the_scale, # large pool of PTN neurons (possibly split per channel) 'nbCMPf': 3000.*the_scale, # large pool of thalamic neurons (not split per channel) + 'RedundancyType': 'inDegreeAbs', # + 'redundancyCSNMSN': 114, 'redundancyPTNMSN': 1.66666666667, 'redundancyCMPfMSN': 5.38150332728, @@ -25,21 +33,41 @@ 'redundancyFSIMSN': 29.2471264368, 'redundancySTNMSN': 0, # connection not defined 'redundancyGPeMSN': 0, # connection not defined +'redundancyArkyMSN': 0, # connection not defined + 'redundancyCSNFSI': 83.3333333333, 'redundancyPTNFSI': 1.66666666667, 'redundancySTNFSI': 0.746359649123, 'redundancyGPeFSI': 8.88250626566, +'redundancyArkyFSI': 8.88250626566, 'redundancyCMPfFSI': 56.7406015038, 'redundancyFSIFSI': 38.6666666667, + 'redundancyPTNSTN': 86.3333333333, 'redundancyCMPfSTN': 28.2943722944, 'redundancyGPeSTN': 20.645021645, +'redundancyProtSTN': 20.645021645, + 'redundancyCMPfGPe': 9.02257636122, 'redundancySTNGPe': 36.326002656, # should be reduced to 32 when using scale=4 'redundancyMSNGPe': 6006.11952191, 'redundancyGPeGPe': 10.36, + +'redundancyCMPfArky': 9.02257636122, +'redundancySTNArky': 36.326002656, # should be reduced to 32 when using scale=4 +'redundancyMSNArky': 6006.11952191, +'redundancyArkyArky': 10.36, +'redundancyProtArky': 10.36, + +'redundancyCMPfProt': 9.02257636122, +'redundancySTNProt': 36.326002656, # should be reduced to 32 when using scale=4 +'redundancyMSNProt': 6006.11952191, +'redundancyProtProt': 10.36, +'redundancyArkyProt': 10.36, + 'redundancyMSNGPi': 10616.1902098, # should be reduced to 10576.0 when using scale=4 'redundancySTNGPi': 30.1107692308, 'redundancyGPeGPi': 7.8634965035, +'redundancyProtGPi': 7.8634965035, 'redundancyCMPfGPi': 26.2610722611, } diff --git a/params/params9_outDegreeAbs.py b/params/params9_outDegreeAbs.py index 43203d4..ca77016 100644 --- a/params/params9_outDegreeAbs.py +++ b/params/params9_outDegreeAbs.py @@ -3,21 +3,29 @@ the_scale = 4. -params = {'LG14modelID':9 , +params = {'tSimu': 5000., + 'LG14modelID':9 , 'IeMSN': 24.5, 'IeFSI': 8. , 'IeSTN': 9.5 , 'IeGPe': 12. , + 'IeArky': 12. , + 'IeProt': 12. , 'IeGPi': 11. , + 'nbMSN': 2644.*the_scale, # original number of neurons, possibly scaled 'nbFSI': 53.*the_scale , # ^ 'nbSTN': 8.*the_scale , # ^ 'nbGPe': 25.*the_scale , # ^ + 'nbArky': 5.*the_scale , # ^ + 'nbProt': 20.*the_scale , # ^ 'nbGPi': 14.*the_scale , # ^ 'nbCSN': 3000.*the_scale, # large pool of CSN neurons (split per channel) - 'nbPTN': 3000.*the_scale , # large pool of PTN neurons (possibly split per channel) + 'nbPTN': 3000.*the_scale, # large pool of PTN neurons (possibly split per channel) 'nbCMPf': 3000.*the_scale, # large pool of thalamic neurons (not split per channel) + 'RedundancyType': 'outDegreeAbs', # by default all axons are hypothesized to target each dendritic tree at 3 different locations + 'redundancyCSNMSN': 3, # ^ 'redundancyPTNMSN': 3, # ^ 'redundancyCMPfMSN': 3, # ^ @@ -25,21 +33,40 @@ 'redundancyFSIMSN': 3, # ^ 'redundancySTNMSN': 3, # ^ 'redundancyGPeMSN': 3, # ^ +'redundancyArkyMSN': 3, # ^ + 'redundancyCSNFSI': 3, # ^ 'redundancyPTNFSI': 3, # ^ 'redundancySTNFSI': 3, # ^ 'redundancyGPeFSI': 3, # ^ +'redundancyArkyFSI': 3, # ^ 'redundancyCMPfFSI': 3, # ^ 'redundancyFSIFSI': 3, # ^ + 'redundancyPTNSTN': 3, # ^ 'redundancyCMPfSTN': 3, # ^ 'redundancyGPeSTN': 3, # ^ +'redundancyProtSTN': 3, # ^ + 'redundancyCMPfGPe': 3, # ^ 'redundancySTNGPe': 3, # ^ 'redundancyMSNGPe': 3, # ^ 'redundancyGPeGPe': 3, # ^ + +'redundancyCMPfArky': 3, # ^ +'redundancySTNArky': 3, # ^ +'redundancyMSNArky': 3, # ^ +'redundancyArkyArky': 3, # ^ +'redundancyProtArky': 3, # ^ + +'redundancyCMPfProt': 3, # ^ +'redundancySTNProt': 3, # ^ +'redundancyMSNProt': 3, # ^ +'redundancyProtProt': 3, # ^ +'redundancyArkyProt': 3, # ^ + 'redundancyMSNGPi': 3, # ^ 'redundancySTNGPi': 3, # ^ 'redundancyGPeGPi': 3, # ^ -'redundancyCMPfGPi': 3, # ^ - } +'redundancyProtGPi': 3, # ^ +'redundancyCMPfGPi': 3,} diff --git a/run.py b/run.py index 767c2e2..fde111b 100644 --- a/run.py +++ b/run.py @@ -45,6 +45,7 @@ def __init__(self, cmd_args): self.platform = cmd_args.platform self.interactive = cmd_args.interactive self.storeGDF = cmd_args.gdf + self.splitGPe = cmd_args.splitGPe self.mock = cmd_args.mock self.tag = cmd_args.tag self.sim_counter = self.last_sim = 0 @@ -86,7 +87,7 @@ def load_custom_config(self, custom): def load_cmdline_config(self, cmd_args): # Loads the options from the commandline, overriding all previous parameterizations - self.params.update({k: v for k, v in vars(cmd_args).items() if k in ['LG14modelID', 'whichTest', 'nbcpu', 'nbCh', 'email', 'nestSeed', 'pythonSeed'] if v != None}) + self.params.update({k: v for k, v in vars(cmd_args).items() if k in ['LG14modelID', 'whichTest', 'nbcpu', 'nbCh', 'email', 'nestSeed', 'pythonSeed', 'splitGPe'] if v != None}) def create_workspace(self, IDstring): # Initialize the experiment-specific directory named with IDstring and populate it with the required files @@ -380,11 +381,12 @@ def main(): Optional = parser.add_argument_group('optional arguments') Optional.add_argument('--custom', type=str, help='Provide a custom file to initialize parameters - without the .py extension', default=None) Optional.add_argument('--LG14modelID', type=int, help='Which LG14 parameterization to use?', default=None) - Optional.add_argument('--whichTest', type=str, help='Which test to run?', choices=['testPlausibility', 'testGPR01', 'testChannel', 'testChannelBG'], default=None) + Optional.add_argument('--whichTest', type=str, help='Which test to run?', choices=['testPlausibility', 'testGPR01', 'testPauses', 'testChannelBG'], default=None) Optional.add_argument('--nbcpu', type=int, help='Number of CPU to use (-1 to guess)', default=None) Optional.add_argument('--nbCh', type=int, help='Number of Basal Ganglia channels to simulate', default=None) Optional.add_argument('--interactive', action="store_true", help='Set to enable the display of debug plots', default=False) Optional.add_argument('--gdf', action="store_true", help='Set to store spike rasters (gdf files) of the simulation', default=False) + Optional.add_argument('--splitGPe', action="store_true", help='Set to split the GPe into 2 populations', default=False) Optional.add_argument('--email', type=str, help='To receive emails when Sango cluster simulations are done', default='') Optional.add_argument('--tag', type=str, help='optional tag for this experiment, to be added to the directory name (avoid special characters like "/" or "\\")', default='') Optional.add_argument('--nestSeed', type=int, help='Nest seed (affects the Poisson spike train generator)', default=None) diff --git a/testPauses.py b/testPauses.py new file mode 100644 index 0000000..6d24695 --- /dev/null +++ b/testPauses.py @@ -0,0 +1,535 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +## +## testPlausibility.py +## +## This script tests the 14 electrophysiological constraints from LG14 +## Works both in single-channel and multi-channels cases + +from iniBG import * +from modelParams import * +import nest.raster_plot +import os +import numpy as np +import sys +import matplotlib.pyplot as plt +import math + +restFR = {} # this will be populated with firing rates of all nuclei, at rest +oscilPow = {} # Oscillations power and frequency at rest +oscilFreq = {} + +#------------------------------------------ +# Checks whether the BG model respects the electrophysiological constaints (firing rate at rest). +# If testing for a given antagonist injection experiment, specifiy the injection site in antagInjectionSite, and the type of antagonists used in antag. +# Returns [score obtained, maximal score] +# params possible keys: +# - nb{MSN,FSI,STN,GPi,GPe,CSN,PTN,CMPf} : number of simulated neurons for each population +# - Ie{GPe,GPi} : constant input current to GPe and GPi +# - G{MSN,FSI,STN,GPi,GPe} : gain to be applied on LG14 input synaptic weights for each population +#------------------------------------------ +def checkAvgFR(showRasters=False,params={},antagInjectionSite='none',antag='',logFileName=''): + nest.ResetNetwork() + initNeurons() + + showPotential = False # Switch to True to graph neurons' membrane potentials - does not handle well restarted simulations + + dataPath='log/' + nest.SetKernelStatus({"overwrite_files":True}) # when we redo the simulation, we erase the previous traces + + nstrand.set_seed(params['nestSeed'], params['pythonSeed']) # sets the seed for the simulation + + simulationOffset = nest.GetKernelStatus('time') + print('Simulation Offset: '+str(simulationOffset)) + offsetDuration = 1000. + simDuration = params['tSimu'] # ms + + # single or multi-channel? + if params['nbCh'] == 1: + connect_detector = lambda N: nest.Connect(Pop[N], spkDetect[N]) + disconnect_detector = lambda N: nest.Disconnect(Pop[N], spkDetect[N]) + connect_multimeter = lambda N: nest.Connect(multimeters[N], [Pop[N][0]]) + else: + connect_detector= lambda N: [nest.Connect(Pop[N][i], spkDetect[N]) for i in range(len(Pop[N]))] + disconnect_detector= lambda N: [nest.Disconnect(Pop[N][i], spkDetect[N]) for i in range(len(Pop[N]))] + connect_multimeter = lambda N: nest.Connect(multimeters[N], [Pop[N][0][0]]) + + #------------------------- + # measures + #------------------------- + spkDetect={} # spike detectors used to record the experiment + multimeters={} # multimeters used to record one neuron in each population + expeRate={} + + antagStr = '' + if antagInjectionSite != 'none': + antagStr = antagInjectionSite+'_'+antag+'_' + + for N in NUCLEI: + # 1000ms offset period for network stabilization + spkDetect[N] = nest.Create("spike_detector", params={"withgid": True, "withtime": True, "label": antagStr+N, "to_file": storeGDF, 'start':offsetDuration+simulationOffset,'stop':offsetDuration+simDuration+simulationOffset}) + connect_detector(N) + if showPotential: + # multimeter records only the last 200ms in one neuron in each population + multimeters[N] = nest.Create('multimeter', params = {"withgid": True, 'withtime': True, 'interval': 0.1, 'record_from': ['V_m'], "label": antagStr+N, "to_file": False, 'start':offsetDuration+simulationOffset+simDuration-200.,'stop':offsetDuration+simDuration+simulationOffset}) + connect_multimeter(N) + + #------------------------- + # Simulation + #------------------------- + nest.Simulate(simDuration+offsetDuration) + + score = 0 + + text=[] + frstr = "#" + str(params['LG14modelID'])+ " , " + antagInjectionSite + ', ' + s = '----- RESULTS -----' + print s + text.append(s+'\n') + if antagInjectionSite == 'none': + validationStr = "\n#" + str(params['LG14modelID']) + " , " + frstr += "none , " + for N in NUCLEI: + strTestPassed = 'NO!' + expeRate[N] = nest.GetStatus(spkDetect[N], 'n_events')[0] / float(nbSim[N]*simDuration*params['nbCh']) * 1000 + if expeRate[N] <= FRRNormal[N][1] and expeRate[N] >= FRRNormal[N][0]: + # if the measured rate is within acceptable values + strTestPassed = 'OK' + score += 1 + validationStr += N + "=OK , " + else: + # out of the ranges + if expeRate[N] > FRRNormal[N][1] : + difference = expeRate[N] - FRRNormal[N][1] + validationStr += N + "=+%.2f , " % difference + else: + difference = expeRate[N] - FRRNormal[N][0] + validationStr += N + "=%.2f , " % difference + + frstr += '%f , ' %(expeRate[N]) + s = '* '+N+' - Rate: '+str(expeRate[N])+' Hz -> '+strTestPassed+' ('+str(FRRNormal[N][0])+' , '+str(FRRNormal[N][1])+')' + print s + text.append(s+'\n') + restFR[N] = str(expeRate[N]) + + oscilPow[N] = -1. + oscilFreq[N] = -1. + try: + spikes_N = nest.GetStatus(spkDetect[N], keys="events")[0]['times'] # get the timing of all spikes + data = np.bincount([int(i-offsetDuration-simulationOffset) for i in spikes_N], minlength=int(simDuration)) # discretize them in bins of 1ms + ps = np.abs(np.fft.fft(data))**2 + time_step = 1 / 1000. # 1000 ms + freqs = np.fft.fftfreq(data.size, time_step) + idx = np.argsort(freqs) + posi_spectrum = np.where((freqs[idx]>0) & (freqs[idx]<200)) # restrict the analysis to freqs < 200 Hz + oscilPow[N] = np.max(ps[idx][posi_spectrum]) + oscilFreq[N] = freqs[idx][posi_spectrum][np.where(oscilPow[N] == ps[idx][posi_spectrum])[0][0]] + #pl.plot(freqs[idx][posi_spectrum], ps[idx][posi_spectrum]) # simple plot + #pl.show() + except: + print("Power spectrum computation failed - skipping") + else: + validationStr = "" + frstr += str(antag) + " , " + for N in NUCLEI: + expeRate[N] = nest.GetStatus(spkDetect[N], 'n_events')[0] / float(nbSim[N]*simDuration*params['nbCh']) * 1000 + if N == antagInjectionSite: + strTestPassed = 'NO!' + if expeRate[N] <= FRRAnt[N][antag][1] and expeRate[N] >= FRRAnt[N][antag][0]: + # if the measured rate is within acceptable values + strTestPassed = 'OK' + score += 1 + validationStr += N + "_" + antag + "=OK , " + else: + # out of the ranges + if expeRate[N] > FRRNormal[N][1] : + difference = expeRate[N] - FRRNormal[N][1] + validationStr += N + "_" + antag + "=+%.2f , " % difference + else: + difference = expeRate[N] - FRRNormal[N][0] + validationStr += N + "_" + antag + "=%.2f , " % difference + + s = '* '+N+' with '+antag+' antagonist(s): '+str(expeRate[N])+' Hz -> '+strTestPassed+' ('+str(FRRAnt[N][antag][0])+' , '+str(FRRAnt[N][antag][1])+')' + print s + text.append(s+'\n') + else: + s = '* '+N+' - Rate: '+str(expeRate[N])+' Hz' + print s + text.append(s+'\n') + frstr += '%f , ' %(expeRate[N]) + + s = '-------------------' + print s + text.append(s+'\n') + + frstr+='\n' + firingRatesFile=open(dataPath+'firingRates.csv','a') + firingRatesFile.writelines(frstr) + firingRatesFile.close() + + #print "************************************** file writing",text + #res = open(dataPath+'OutSummary_'+logFileName+'.txt','a') + res = open(dataPath+'OutSummary.txt','a') + res.writelines(text) + res.close() + + validationFile = open("validationArray.csv",'a') + validationFile.write(validationStr) + validationFile.close() + #------------------------- + # Displays + #------------------------- + if showRasters and interactive: + displayStr = ' ('+antagStr[:-1]+')' if (antagInjectionSite != 'none') else '' + for N in NUCLEI: + # histograms crash in the multi-channels case + nest.raster_plot.from_device(spkDetect[N], hist=(params['nbCh'] == 1), title=N+displayStr) + + if showPotential: + pl.figure() + nsub = 231 + for N in NUCLEI: + pl.subplot(nsub) + nest.voltage_trace.from_device(multimeters[N],title=N+displayStr+' #0') + disconnect_detector(N) + pl.axhline(y=BGparams[N]['V_th'], color='r', linestyle='-') + nsub += 1 + pl.show() + + return score, 5 if antagInjectionSite == 'none' else 1 + +# ----------------------------------------------------------------------------- +# This function verify if their is pauses in the GPe and if the caracteristiques +# of theses pauses are relevant with the data of the elias paper 2007 +# It is run after CheckAVGFR because it uses the gdf files of the simulation. +# ----------------------------------------------------------------------------- + +#---------------------------- begining getSpikes ------------------------------ +# return an ordered dictionnary of the spikes occurences by neuron and in the time +def getSpikes(Directory, Nuclei): + spikesDict = {} + spikesList = [] + gdfList = os.listdir(Directory + '/NoeArchGdf') + + for f in gdfList: + if f.find(Nuclei) != -1 and f[-4:] == ".gdf" : + spikeData = open(Directory +'/NoeArchGdf/' + f) + for line in spikeData: # take the spike and put it in neuronRecording + spk = line.split('\t') + spk.pop() + spikesList.append(float(spk[1])) + if spk[0] in spikesDict: + spikesDict[spk[0]].append(float(spk[1])) + else: + spikesDict[spk[0]] = [float(spk[1])] + + for neuron in spikesDict: + spikesDict[neuron] = sorted(spikesDict[neuron]) + + return spikesDict, spikesList +#---------------------------- end getSpikes ----------------------------------- + +#--------------------------- begining getISIs --------------------------------- +# return ISIs ordered by neuron in a dictionnary +def getISIs(spikesDict): + ISIsDict = {} + for neuron in spikesDict: + ISIsDict[neuron] = [] + for i in range(len(spikesDict[neuron]) - 1): + ISIsDict[neuron].append(round(spikesDict[neuron][i+1] - spikesDict[neuron][i], 1)) + ISIsList = [] + for neuron in ISIsDict: + for isi in ISIsDict[neuron]: + ISIsList.append(isi) + return ISIsDict, ISIsList +#----------------------------- end getISIs ------------------------------------ + +#--------------------------- begining rasterPlot ------------------------------ +# plot rasters figures in the directory /raster +def rasterPlot(spikesDict, Nuclei, Directory): + rasterList = [] + + if not os.path.exists(Directory + '/rasterPlot'): + os.makedirs(Directory + '/rasterPlot') + + for neuron in spikesDict: + rasterList.append(spikesDict[neuron]) + plt.figure(figsize=(40,15)) + plt.eventplot(rasterList, linelengths = 0.8, linewidths = 0.6) + plt.title('Spike raster plot ' + Nuclei) + plt.grid() + plt.savefig(Directory + '/rasterPlot/' + 'RasterPlot_' + Nuclei + '.png') +#----------------------------- end rasterPlot --------------------------------- + +#--------------------------- begining BarPlot --------------------------------- +# plot the nuclei histogram of ISIs +def activityHistPlot(spikesList, Nuclei, Directory): + + if not os.path.exists(Directory + '/activityHistPlot'): + os.makedirs(Directory + '/activityHistPlot') + + plt.figure(figsize=(40,5)) + plt.hist(spikesList, bins=200, normed=0.5) + plt.title('Histogram of the activity' + Nuclei) + plt.grid() + plt.savefig(Directory + '/activityHistPlot/'+ 'activityHistPlot_' + Nuclei + '.png') +#----------------------------- end BarPlot ------------------------------------ + +#--------------------------- begining BarPlot --------------------------------- +# plot the nuclei histogram of ISIs +def HistPlot(ISIsList, Nuclei, Directory): + + if not os.path.exists(Directory + '/histPlot'): + os.makedirs(Directory + '/histPlot') + + plt.figure() + plt.hist(ISIsList, bins=20, normed=0.5) + plt.title('Histogram ' + Nuclei) + plt.grid() + plt.savefig(Directory + '/histPlot/'+ 'HistPlot_' + Nuclei + '.png') +#----------------------------- end BarPlot ------------------------------------ + +#--------------------------- begining poisson --------------------------------- +# compute the poissonian probability that n or less spike occure during T ms +def poisson(n, r, T): # Tsum of 2 isi or 3 ? n = 2 + P = 0 + for i in range(n): + P += math.pow(r*T, i)/ math.factorial(i) + + return P*math.exp(-r*T) +#----------------------------- end poisson ------------------------------------ + +#----------------------- begining Pause Analysis ------------------------------ +def PauseAnalysis(ISIsDict,ISIsList): # Tsum of 2 isi or 3 ? n = 2 + simuSpecs = {'meanISI': np.mean(ISIsList),} + + r = 1/float(simuSpecs['meanISI']) + pausesDict = {} + pausesList = [] + coreIList = [] + + isiThreshold = 0 + + if max(ISIsList) >= 250: + isiThreshold = 250 + elif max(ISIsList) >= 200: + isiThreshold = 200 + elif max(ISIsList) >= 150: + isiThreshold = 150 + elif max(ISIsList) >= 100: + isiThreshold = 100 + elif max(ISIsList) >= 80: + isiThreshold = 80 + elif max(ISIsList) >= 60: + isiThreshold = 60 + elif max(ISIsList) >= 40: + isiThreshold = 40 + else: + isiThreshold = 20 + + for neuron in ISIsDict: + skip = False + for i in range(1,len(ISIsDict[neuron])-1): + if ISIsDict[neuron][i] >= isiThreshold and not skip : + coreI = ISIsDict[neuron][i] + pause = coreI + s = -math.log10(poisson(1, r, coreI)) + s2 = -math.log10(poisson(2, r, coreI+ISIsDict[neuron][i-1])) + s3 = -math.log10(poisson(2, r, coreI+ISIsDict[neuron][i+1])) + if s2 > s and s2 >= s3: + s = s2 + pause += ISIsDict[neuron][i-1] + elif s3 > s: + s = s3 + pause += ISIsDict[neuron][i+1] + skip = True + + if neuron in pausesDict: + pausesDict[neuron].append(pause) + pausesList.append(pause) + coreIList.append(coreI) + else: + pausesDict[neuron] = [pause] + pausesList.append(pause) + coreIList.append(coreI) + else: + skip = False + + pausersFRRList = [] + correctedFRRList = [] + for neuron in pausesDict: + pausersFRRList.append((len(ISIsDict[neuron])+1)*1000/float(params['tSimu'])) + pausesLength = sum(pausesDict[neuron]) + correctedFRRList.append((len(ISIsDict[neuron])-len(pausesDict[neuron])+1)*1000/(float(params['tSimu'])-pausesLength)) + + + + simuSpecs['isiThreshold'] = isiThreshold + simuSpecs['percentagePausers'] = len(pausesDict)/float(len(ISIsDict))*100 + simuSpecs['nbPausersNeurons'] = len(pausesDict) + simuSpecs['meanPausesDuration'] = round(np.mean(pausesList),2) + simuSpecs['meanCoreI'] = round(np.mean(coreIList),2) + simuSpecs['nbPausesPerMin'] = round(len(pausesList)/float(len(pausesDict)*params['tSimu'])*60000,2) + simuSpecs['nbPauses'] = len(pausesList) + simuSpecs['meanISI'] = round(np.mean(ISIsList),2) + simuSpecs['pausersFRR'] = round(np.mean(pausersFRRList),2) + simuSpecs['minPausersFRR'] = round(min(pausersFRRList),2) + simuSpecs['correctedPausersFRR'] = round(np.mean(correctedFRRList),2) + + return simuSpecs +#-------------------------- end Pause Analysis -------------------------------- + +#------------------------- begining gdf exploitation -------------------------- +# call the function and plot results +def gdfExploitation(Directory): + for N in NUCLEI: + a = getSpikes(Directory, N) + spikesDict = a[0] + activityHistPlot(a[1], N, Directory) + rasterPlot(spikesDict, N, Directory) + + if N == 'Arky' or N == 'Prot' or N == 'GPe': + + simuSpecs = PauseAnalysis(getISIs(spikesDict)[0], getISIs(spikesDict)[1]) + + text = "\n################# Pause Results " + N + " #################" + text += "\n ISI threshold = " + str(simuSpecs['isiThreshold']) + " ms | 250 ms" + text += "\n Mean coreI duration = " + str(simuSpecs['meanCoreI']) + " ms | [200 - 600]" + text += "\n Mean pause duration = " + str(simuSpecs['meanPausesDuration']) + " ms | 620 ms" + text += "\n Mean ISI = " + str(simuSpecs['meanISI']) + " ms | 15 ms" + text += "\n total Pauses Nb = " + str(simuSpecs['nbPauses']) + text += "\n pause/min/neuron = " + str(simuSpecs['nbPausesPerMin']) + " | [13 - 24]" + text += "\n Pauser neurons Nb = " + str(simuSpecs['nbPausersNeurons']) + text += "\n % Pauser neurons = " + str(simuSpecs['percentagePausers']) + " | [60 - 100]\n" + text += "\n pausersFRR = " + str(simuSpecs['pausersFRR']) + " | [37 - 54]" + text += "\n corr pausers FRR = " + str(simuSpecs['correctedPausersFRR']) + " | [44 - 62]" + text += "\n Min pausers FRR = " + str(simuSpecs['minPausersFRR']) + " | [30 - 54] \n" + text += "\n#####################################################\n" + + res = open(Directory+'/log/OutSummary.txt','a') + res.writelines(text) + res.close() + print text + +#---------------------------- end gdf exploitation ---------------------------- + +pausesDATA = {'percentagePausers': [40. , 100., 75.], # percentage of pauser neurons in GPe [low value, High value, perfect value] + 'shortPercentageISI': [0 , 0.70, 0.2], # percentage of Interspike intervals inferior to 2 ms + 'meanPausesDuration': [450. , 730., 620.], # change to [0.45, 0.73, 0.62] are the extreme recorded values if it is too selective + 'nbPausesPerMin': [8. , 23., 13.], # change to [8, 23, 13] are the extreme recorded values if it is too selective + 'meanIPI': [2.63 , 8.74, 6.19], # InterPauses Inteval | [2.63, 8.74, 6.19]are the extreme recorded values if it is too selective + 'pausersFRR': [37.48 , 71.25, 54.37], # change to [21.47, 76.04, 54.13] which are the extreme recorded values if it is too selective + 'correctedPausersFRR':[44.04 , 81.00, 62.52], # change to [22.60, 86.63, 62.52] which are the extreme recorded values if it is too selective + 'nonPausersFRR': [37.10 , 75.75, 56.43],} # change to [31.37, 91.70, 56.43] which are the extreme recorded values if it is too selective + +#------------------------------------------------------------------------------ + +def main(): + if len(sys.argv) >= 2: + print "Command Line Parameters" + paramKeys = ['LG14modelID', + 'nbMSN', + 'nbFSI', + 'nbSTN', + 'nbGPe', + 'nbGPi', + 'nbCSN', + 'nbPTN', + 'nbCMPf', + 'GMSN', + 'GFSI', + 'GSTN', + 'GGPe', + 'GGPi', + 'IeGPe', + 'IeGPi', + 'inDegCSNMSN', + 'inDegPTNMSN', + 'inDegCMPfMSN', + 'inDegFSIMSN', + 'inDegMSNMSN', + 'inDegCSNFSI', + 'inDegPTNFSI', + 'inDegSTNFSI', + 'inDegGPeFSI', + 'inDegCMPfFSI', + 'inDegFSIFSI', + 'inDegPTNSTN', + 'inDegCMPfSTN', + 'inDegGPeSTN', + 'inDegCMPfGPe', + 'inDegSTNGPe', + 'inDegMSNGPe', + 'inDegGPeGPe', + 'inDegMSNGPi', + 'inDegSTNGPi', + 'inDegGPeGPi', + 'inDegCMPfGPi', + ] + if len(sys.argv) == len(paramKeys)+1: + print "Using command line parameters" + print sys.argv + i = 0 + for k in paramKeys: + i+=1 + params[k] = float(sys.argv[i]) + else : + print "Incorrect number of parameters:",len(sys.argv),"-",len(paramKeys),"expected" + + nest.set_verbosity("M_WARNING") + + instantiate_BG(params, antagInjectionSite='none', antag='') + score = np.zeros((2)) + #mapTopology2D(show=True) + score += checkAvgFR(params=params,antagInjectionSite='none',antag='',showRasters=True) + + Directory = os.getcwd() + os.system('mkdir NoeArchGdf') # save the .gdf files before antagonist desaster + if params['splitGPe']: + os.system('cp log/MSN* log/STN* log/Arky* log/Prot* log/GPi* log/FSI* NoeArchGdf/ ') + os.system('rm log/MSN* log/STN* log/Arky* log/Prot* log/FSI* log/GPi*') + else: + os.system('cp log/MSN* log/STN* log/GPe* log/GPi* log/FSI* NoeArchGdf/ ') + os.system('rm log/MSN* log/STN* log/GPe* log/FSI* log/GPi*') + gdfExploitation(Directory) + + # don't bother with deactivation tests if activities at rest are not within plausible bounds + if score[0] < score[1]: + print("Activities at rest do not match") + + #------------------------- + print "******************" + print "* Score:",score[0],'/',score[1] + print "******************" + + #------------------------- + # log the results in a file + #------------------------- + res = open('log/OutSummary.txt','a') + for k,v in params.iteritems(): + res.writelines(k+' , '+str(v)+'\n') + res.writelines("Score: "+str(score[0])+' , '+str(score[1])) + res.close() + + res = open('score.txt','w') + res.writelines(str(score[0])+'\n') + res.close() + + # combined params+score output, makes it quicker to read the outcome of many experiments + params['sim_score'] = score[0] + params['max_score'] = score[1] + with open('params_score.csv', 'wb') as csv_file: + writer = csv.writer(csv_file) + for key, value in params.items(): + writer.writerow([key, value]) + for key, value in restFR.items(): + writer.writerow([key+'_Rate', value]) + for key, value in oscilPow.items(): + writer.writerow([key+'_Pow', value]) + for key, value in oscilFreq.items(): + writer.writerow([key+'_Freq', value]) + +#--------------------------- +if __name__ == '__main__': + main() diff --git a/testPlausibility.py b/testPlausibility.py index 1bc2b9f..1479f26 100644 --- a/testPlausibility.py +++ b/testPlausibility.py @@ -8,6 +8,7 @@ ## Works both in single-channel and multi-channels cases from iniBG import * +from modelParams import * restFR = {} # this will be populated with firing rates of all nuclei, at rest oscilPow = {} # Oscillations power and frequency at rest @@ -36,7 +37,7 @@ def checkAvgFR(showRasters=False,params={},antagInjectionSite='none',antag='',lo simulationOffset = nest.GetKernelStatus('time') print('Simulation Offset: '+str(simulationOffset)) offsetDuration = 1000. - simDuration = 5000. # ms + simDuration = params['tSimu'] # ms # single or multi-channel? if params['nbCh'] == 1: @@ -257,26 +258,51 @@ def main(): if score[0] < score[1]: print("Activities at rest do not match: skipping deactivation tests") else: - if params['nbCh'] == 1: - # The following implements the deactivation tests without re-wiring the BG (faster but implemented only in single-channel case) - for a in ['AMPA','AMPA+GABAA','NMDA','GABAA']: - ww = deactivate('GPe', a) - score += checkAvgFR(params=params,antagInjectionSite='GPe',antag=a) - reactivate('GPe', a, ww) - - for a in ['AMPA+NMDA+GABAA','AMPA','NMDA+AMPA','NMDA','GABAA']: - ww = deactivate('GPi', a) - score += checkAvgFR(params=params,antagInjectionSite='GPi',antag=a) - reactivate('GPi', a, ww) + if params['splitGPe']: + if params['nbCh'] == 1: + # The following implements the deactivation tests without re-wiring the BG (faster but implemented only in single-channel case) + for a in ['AMPA','AMPA+GABAA','NMDA','GABAA']: + wwA = deactivate('Arky', a) + wwP = deactivate('Prot', a) + score += checkAvgFR(params=params,antagInjectionSite='GPe',antag=a) + reactivate('Arky', a, wwA) + reactivate('Prot', a, wwP) + + for a in ['AMPA+NMDA+GABAA','AMPA','NMDA+AMPA','NMDA','GABAA']: + ww = deactivate('GPi', a) + score += checkAvgFR(params=params,antagInjectionSite='GPi',antag=a) + reactivate('GPi', a, ww) + else: + # The following implements the deactivation tests with re-creation of the entire BG every time (slower but also implemented for multi-channels) + for a in ['AMPA','AMPA+GABAA','NMDA','GABAA']: + instantiate_BG(params, antagInjectionSite='GPe', antag=a) + score += checkAvgFR(params=params,antagInjectionSite='GPe',antag=a) + + for a in ['AMPA+NMDA+GABAA','AMPA','NMDA+AMPA','NMDA','GABAA']: + instantiate_BG(params, antagInjectionSite='GPi', antag=a) + score += checkAvgFR(params=params,antagInjectionSite='GPi',antag=a) + else: - # The following implements the deactivation tests with re-creation of the entire BG every time (slower but also implemented for multi-channels) - for a in ['AMPA','AMPA+GABAA','NMDA','GABAA']: - instantiate_BG(params, antagInjectionSite='GPe', antag=a) - score += checkAvgFR(params=params,antagInjectionSite='GPe',antag=a) - - for a in ['AMPA+NMDA+GABAA','AMPA','NMDA+AMPA','NMDA','GABAA']: - instantiate_BG(params, antagInjectionSite='GPi', antag=a) - score += checkAvgFR(params=params,antagInjectionSite='GPi',antag=a) + if params['nbCh'] == 1: + # The following implements the deactivation tests without re-wiring the BG (faster but implemented only in single-channel case) + for a in ['AMPA','AMPA+GABAA','NMDA','GABAA']: + ww = deactivate('GPe', a) + score += checkAvgFR(params=params,antagInjectionSite='GPe',antag=a) + reactivate('GPe', a, ww) + + for a in ['AMPA+NMDA+GABAA','AMPA','NMDA+AMPA','NMDA','GABAA']: + ww = deactivate('GPi', a) + score += checkAvgFR(params=params,antagInjectionSite='GPi',antag=a) + reactivate('GPi', a, ww) + else: + # The following implements the deactivation tests with re-creation of the entire BG every time (slower but also implemented for multi-channels) + for a in ['AMPA','AMPA+GABAA','NMDA','GABAA']: + instantiate_BG(params, antagInjectionSite='GPe', antag=a) + score += checkAvgFR(params=params,antagInjectionSite='GPe',antag=a) + + for a in ['AMPA+NMDA+GABAA','AMPA','NMDA+AMPA','NMDA','GABAA']: + instantiate_BG(params, antagInjectionSite='GPi', antag=a) + score += checkAvgFR(params=params,antagInjectionSite='GPi',antag=a) #------------------------- print "******************"