#include "constants.hpp"
#include "bcbg2.hpp"
#include "helper_fct.hpp"
#include "run_sim.hpp"
int is_in(std::vector <int>& c, int i)
{
for (int j=0; j<c.size(); j++) {
if (i==c[j]) {
return 1;
}
}
return 0;
}
float param2hz(float value) {
return 200.0 + value * 300.0f;
}
float param2boutons(float value) {
#ifdef NODELETEDCON
return value * 5995.0f + 5.0f;
#elif defined(NOTMUCHDELETEDCON)
return value * 5995.0f + 5.0f;
#else
return value * 6000.0f;
#endif
}
float param2boutons2(float value) {
#ifdef NOTMUCHDELETEDCON
return value * 6000.0f;
#elif defined(NODELETEDCON)
return value * 5995.0f + 5.0f;
#else
return value * 6000.0f;
#endif
}
float _do_trial(
std::vector<float>& means,
std::vector<float>& ref,
std::vector<float>& params,
std::vector<int>& delays,
std::vector<float>& activations,
int nucleus,
float proportional_change,
float proportional_radius,
float sim_time,
MemoryBCBG2& mem,
bool checkedtrial)
{
// this functions performs one trial of a deactivation
// there are many options with #define implemented here to allow various speed-up of the optimization
#ifdef MSN_SEPARATION
int msn_separation = 1;
#else
int msn_separation = 0;
#endif
#ifdef MULTICHANNELSMODEL
int ch_n = 3;
#elif defined(CELLSMODEL)
int ch_n = 0;
#else
int ch_n = 1;
#endif
#ifdef ISSMALLDT
float dt = 1e-3;
#elif defined(ISBIGDT)
float dt = 1e-5;
#elif defined(ISHUGEDT)
float dt = 1e-6;
#else
float dt = 1e-4;
#endif
std::vector<float> cs;
cs.assign(ARGS_NUMBER, 0.);
#ifdef LIGHTESTCONV
float sim_step = 0.01;
#else
float sim_step = 0.1;
#endif
#if defined(MIXEDMEDIUMDT)
int converged;
if (checkedtrial) {
converged = _run_sim(sim_time,sim_step,dt,activations,cs,params,delays,means,0,ch_n,msn_separation,0,mem,1);
} else {
converged = _run_sim(sim_time,sim_step,dt,activations,cs,params,delays,means,0,ch_n,msn_separation,0,mem,0);
if (converged == 1) {
std::vector <float> smalldt_means(means);
converged = _run_sim(sim_time,sim_step,dt,activations,cs,params,delays,means,0,ch_n,msn_separation,0,mem,1);
if (converged != -1) {
for (int i=0;i<NUCLEUS_NUMBER;i++) {
if (abs(means[i*ch_n] - smalldt_means[i*ch_n]) > 1) {
converged = -1;
}
}
}
}
}
#elif defined(MIXEDFULLDT)
delays.assign(ARGS_NUMBER,1); // 1ms everywhere
int converged = _run_sim(sim_time,0.1,1e-3,activations,cs,params,delays,means,0,ch_n,msn_separation,0,mem,0);
if (converged != -1) {
std::vector <float> smalldt_means(means);
delays.assign(ARGS_NUMBER,10); // 1ms everywhere
converged = _run_sim(sim_time,0.1,1e-4,activations,cs,params,delays,means,0,ch_n,msn_separation,0,mem,0);
if (converged != -1) {
float diff = 0.;
for (int i=0;i<NUCLEUS_NUMBER;i++) {
diff += abs(means[i*ch_n] - smalldt_means[i*ch_n]);
}
if (diff > 1) {
converged = 0;
}
}
}
#else
int converged = _run_sim(sim_time,sim_step,dt,activations,cs,params,delays,means,0,ch_n,msn_separation,0,mem,0);
#endif
#ifdef TRONQGALL
float score = _has_changed_near_tronqgaussian(ref[nucleus*ch_n],means[nucleus*ch_n],proportional_change,proportional_radius);
#else
float score = _has_changed_near_gaussian(ref[nucleus*ch_n],means[nucleus*ch_n],proportional_change,proportional_radius);
#endif
if ( converged == -1) {
return -10000;
} else {
return score;
}
}
float calc_score_desactivation(
std::vector <float>& means,
std::vector <float>& params,
std::vector <int>& delays,
float desactivation_level,
float sim_time,
MemoryBCBG2& mem,
bool verbose)
{
// computes part of the electrophysiological plausibility objective
// these are the deactivation studies taken into account in the paper Lienard and Girard 2013.
#ifdef MULTICHANNELSMODEL
int ch_n = 3;
#elif defined(CELLSMODEL)
int ch_n = 0;
#else
int ch_n = 1;
#endif
float scoreg = 0.;
float score = 0.;
std::vector <float> activations;
activations.assign(DESACT_NUMBER,1.0f);
std::vector <float> ref(means);
std::vector <float> ref_tmp(ref);
// when NBQX is applied in GPe, we expect a 56.7% decrease in GPe
// (cf Kita et al. 2004 : "Role of Ionotropic Glutamatergic and GABAergic Inputs
// on the Firing Activity of Neurons in the External Pallidum in Awake Monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPe_AMPA] = desactivation_level; // to block the AMPA channel of GPe
activations[CMPf_GPe_AMPA] = desactivation_level; // to block the AMPA channel of GPe
score = _do_trial(means,ref,params,delays,activations,GPe_N,-0.567,0.356,sim_time,mem,false);
scoreg += score;
if (verbose) {
std::cout << means[GPe_N*ch_n] << " ";
}
// WARNING : this desactivation has to follow the NBQX application in GPe.
ref_tmp.assign(NUCLEUS_NUMBER,0.);
ref_tmp[GPe_N*ch_n] = means[GPe_N*ch_n];
// when NBQX then gabazine are applied in GPe, we expect a 116.5% further increase in the GPe
// (cf Kita et al. 2004 : "Role of Ionotropic Glutamatergic and GABAergic Inputs
// on the Firing Activity of Neurons in the External Pallidum in Awake Monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPe_AMPA] = desactivation_level; // to block the AMPA channel of GPe
activations[CMPf_GPe_AMPA] = desactivation_level; // to block the AMPA channel of GPe
activations[MSN_GPe_GABAA] = desactivation_level; // to block the GABA channel of GPe (from D2)
activations[GPe_GPe_GABAA] = desactivation_level; // to block the GABA channel of GPe (from GPe)
if (scoreg >= 0) {
score = _do_trial(means,ref_tmp,params,delays,activations,GPe_N,+1.165,0.167,sim_time,mem,false);
scoreg += score;
} else if (verbose) {
score = _do_trial(means,ref_tmp,params,delays,activations,GPe_N,+1.165,0.167,sim_time,mem,false);
}
if (verbose) {
std::cout << means[GPe_N*ch_n] << " ";
}
// when CPP is applied in GPe, we expect a 32.4% decrease in GPe
// (cf Kita et al. 2004 : "Role of Ionotropic Glutamatergic and GABAergic Inputs
// on the Firing Activity of Neurons in the External Pallidum in Awake Monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPe_NMDA] = desactivation_level; // to block the NMDA channel of GPe
activations[CMPf_GPe_NMDA] = desactivation_level; // to block the NMDA channel of GPe
if (scoreg >= 0) {
score = _do_trial(means,ref,params,delays,activations,GPe_N,-0.324,0.145,sim_time,mem,false);
scoreg += score;
} else if (verbose) {
score = _do_trial(means,ref,params,delays,activations,GPe_N,-0.324,0.145,sim_time,mem,false);
}
if (verbose) {
std::cout << means[GPe_N*ch_n] << " ";
}
// when gabazine is applied in GPe, we expect a 115.8% increase in GPe
// (cf Kita et al. 2004 : "Role of Ionotropic Glutamatergic and GABAergic Inputs
// on the Firing Activity of Neurons in the External Pallidum in Awake Monkeys")
activations.assign(DESACT_NUMBER,1);
activations[MSN_GPe_GABAA] = desactivation_level; // to block the GABA channel of GPe (from D2)
activations[GPe_GPe_GABAA] = desactivation_level; // to block the GABA channel of GPe (from GPe)
if (scoreg >= 0) {
score = _do_trial(means,ref,params,delays,activations,GPe_N,+1.158,0.815,sim_time,mem,false);
scoreg += score;
} else if (verbose) {
score = _do_trial(means,ref,params,delays,activations,GPe_N,+1.158,0.815,sim_time,mem,false);
}
if (verbose) {
std::cout << means[GPe_N*ch_n] << " ";
}
// when CPP is applied in GPi, we expect a 27.5% decrease in GPi
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPi_NMDA] = desactivation_level; // to block the NMDA channel of GPi
activations[CMPf_GPi_NMDA] = desactivation_level; // to block the NMDA channel of GPi
if (scoreg >= 0) {
score = _do_trial(means,ref,params,delays,activations,GPi_N,-0.275,0.264,sim_time,mem,false);
scoreg += score;
} else if (verbose) {
score = _do_trial(means,ref,params,delays,activations,GPi_N,-0.275,0.264,sim_time,mem,false);
}
if (verbose) {
std::cout << means[GPi_N*ch_n] << " ";
}
// WARNING : this desactivation has to follow the CPP application in GPi.
ref_tmp.assign(NUCLEUS_NUMBER,0.);
ref_tmp[GPi_N*ch_n] = means[GPi_N*ch_n];
// when CPP and then NBQX are applied in GPi, we expect a 54.2% further decrease in GPi
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPi_AMPA] = desactivation_level; // to block the AMPA channel of GPi
activations[CMPf_GPi_AMPA] = desactivation_level; // to block the AMPA channel of GPi
activations[STN_GPi_NMDA] = desactivation_level; // to block the NMDA channel of GPi
activations[CMPf_GPi_NMDA] = desactivation_level; // to block the NMDA channel of GPi
if (scoreg >= 0) {
score = _do_trial(means,ref_tmp,params,delays,activations,GPi_N,-0.542,0.208,sim_time,mem,false);
scoreg += score;
} else if (verbose) {
score = _do_trial(means,ref_tmp,params,delays,activations,GPi_N,-0.542,0.208,sim_time,mem,false);
}
if (verbose) {
std::cout << means[GPi_N*ch_n] << " ";
}
// when NBQX is applied in GPi, we expect a 53.6% decrease in GPi
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPi_AMPA] = desactivation_level; // to block the AMPA channel of GPi
activations[CMPf_GPi_AMPA] = desactivation_level; // to block the AMPA channel of GPi
if (scoreg >= 0) {
score = _do_trial(means,ref,params,delays,activations,GPi_N,-0.536,0.367,sim_time,mem,false);
scoreg += score;
} else if (verbose) {
score = _do_trial(means,ref,params,delays,activations,GPi_N,-0.536,0.367,sim_time,mem,false);
}
if (verbose) {
std::cout << means[GPi_N*ch_n] << " ";
}
// when gabazine is applied in GPi, we expect a 92% increase in GPi
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[MSN_GPi_GABAA] = desactivation_level; // to block the GABA channel of GPi (from D1)
activations[GPe_GPi_GABAA] = desactivation_level; // to block the GABA channel of GPi (from GPe)
if (scoreg >= 0) {
score = _do_trial(means,ref,params,delays,activations,GPi_N,+0.92,1.173,sim_time,mem,false);
scoreg += score;
} else if (verbose) {
score = _do_trial(means,ref,params,delays,activations,GPi_N,+0.92,1.173,sim_time,mem,false);
}
if (verbose) {
std::cout << means[GPi_N*ch_n] << " ";
}
// this desactivation was unset before. Reason ? Because the data is not supplied with changes, but as an absolute value. The choice is to integrate it with the absolute value
// when CPP, NBQX and gabazine are applied in GPi, we expect a normal firing rate
// (ie : near 75.1Hz)
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPi_AMPA] = desactivation_level; // to block the AMPA channel of GPi (from STN)
activations[CMPf_GPi_AMPA] = desactivation_level; // to block the AMPA channel of GPi (from CM/Pf)
activations[STN_GPi_NMDA] = desactivation_level; // to block the NMDA channel of GPi (from STN)
activations[CMPf_GPi_NMDA] = desactivation_level; // to block the NMDA channel of GPi (from CM/Pf)
activations[MSN_GPi_GABAA] = desactivation_level; // to block the GABA channel of GPi (from D1)
activations[GPe_GPi_GABAA] = desactivation_level; // to block the GABA channel of GPi (from GPe)
ref_tmp[GPi_N*ch_n] = 75.1;
if (scoreg >= 0) {
score = _do_trial(means,ref_tmp,params,delays,activations,GPi_N,0.0f,0.217,sim_time,mem,false);
scoreg += score;
} else if (verbose) {
score = _do_trial(means,ref_tmp,params,delays,activations,GPi_N,0.0f,0.217,sim_time,mem,false);
}
if (verbose) {
std::cout << means[GPi_N*ch_n] << " ";
}
if (scoreg < 0) {
scoreg = 0;
}
return scoreg;
}
float calc_score_desactivation_other(
std::vector <float>& means,
std::vector <float>& params,
std::vector <int>& delays,
float desactivation_level,
float sim_time,
MemoryBCBG2& mem,
bool verbose)
{
// these deactivation studies were included later in the process of model making, and are not part of the initial constraints for the optimization
#ifdef MULTICHANNELSMODEL
int ch_n = 3;
#elif defined(CELLSMODEL)
int ch_n = 0;
#else
int ch_n = 1;
#endif
float scoreg = 0.;
float score = 0.;
std::vector <float> activations;
activations.assign(DESACT_NUMBER,1.0f);
std::vector <float> ref(means);
std::vector <float> ref_tmp(ref);
// NB for GPe: "The STN blockade greatly decreased the firing rate, to complete silence in some neurons. However, 5–10 min after the muscimol injection, the activity began to increase with repeated occurrences of short grouped spike discharges. As time progressed, the activity further increased and developed into repeated occurrences of 2–12 s of a very high-frequency active phase and then 2–12 s of a completely silent period"
// when NBQX is applied in GPe, we expect a 51.2% decrease in GPe
// (cf Kita et al. 2004 : "Role of Ionotropic Glutamatergic and GABAergic Inputs
// on the Firing Activity of Neurons in the External Pallidum in Awake Monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPe_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_GPi_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_MSN_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_FSI_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_GPe_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_GPi_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_MSN_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_FSI_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[CMPf_GPe_AMPA] = desactivation_level; // to block the AMPA channel of GPe
score = _do_trial(means,ref,params,delays,activations,GPe_N,-0.512,0.42,sim_time,mem,false);
scoreg += score;
if (verbose) {
std::cerr << score << " ";
for (int i=0; i<NUCLEUS_NUMBER; i++) {
std::cout << means[i*ch_n] << " ";
}
}
// when gabazine is applied in GPe, we expect a 198% increase in GPe
// (cf Kita et al. 2004 : "Role of Ionotropic Glutamatergic and GABAergic Inputs
// on the Firing Activity of Neurons in the External Pallidum in Awake Monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPe_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_GPi_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_MSN_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_FSI_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_GPe_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_GPi_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_MSN_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_FSI_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[MSN_GPe_GABAA] = desactivation_level; // to block the GABA channel of GPe (from D2)
activations[GPe_GPe_GABAA] = desactivation_level; // to block the GABA channel of GPe (from GPe)
score = _do_trial(means,ref,params,delays,activations,GPe_N,+1.98,1.38,sim_time,mem,false);
scoreg += score;
if (verbose) {
std::cerr << score << " ";
for (int i=0; i<NUCLEUS_NUMBER; i++) {
std::cout << means[i*ch_n] << " ";
}
}
// the data is not supplied with changes, but as an absolute value. The choice is to integrate it with the absolute value
// when no drug is employed, the firing rate is close to normal (ie near 67.8 +/- 30.2 Hz)
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPe_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_GPi_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_MSN_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_FSI_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_GPe_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_GPi_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_MSN_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_FSI_NMDA] = 0.0f; // to block the NMDA channel from STN
ref_tmp[GPi_N*ch_n] = 67.8;
score = _do_trial(means,ref_tmp,params,delays,activations,GPi_N,0.0f,0.302,sim_time,mem,false);
scoreg += score;
if (verbose) {
std::cerr << score << " ";
for (int i=0; i<NUCLEUS_NUMBER; i++) {
std::cout << means[i*ch_n] << " ";
}
}
// when gabazine is applied in GPi, we expect a 28.6% increase in GPi
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[STN_GPe_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_GPi_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_MSN_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_FSI_AMPA] = 0.0f; // to block the AMPA channel from STN
activations[STN_GPe_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_GPi_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_MSN_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[STN_FSI_NMDA] = 0.0f; // to block the NMDA channel from STN
activations[MSN_GPi_GABAA] = desactivation_level; // to block the GABA channel of GPi (from D1)
activations[GPe_GPi_GABAA] = desactivation_level; // to block the GABA channel of GPi (from GPe)
score = _do_trial(means,ref,params,delays,activations,GPi_N,+0.286,0.128,sim_time,mem,false);
scoreg += score;
if (verbose) {
std::cerr << score << " ";
for (int i=0; i<NUCLEUS_NUMBER; i++) {
std::cout << means[i*ch_n] << " ";
}
}
// NB "very regular and oscillatory firing"
// when muscimol is applied in GPe, shutting it, we expect a 38.3% increase in GPi
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[GPe_MSN_GABAA] = 0.0f; // to block the GABAA channel from GPe
activations[GPe_FSI_GABAA] = 0.0f; // to block the GABAA channel from GPe
activations[GPe_STN_GABAA] = 0.0f; // to block the GABAA channel from GPe
activations[GPe_GPi_GABAA] = 0.0f; // to block the GABAA channel from GPe
score = _do_trial(means,ref,params,delays,activations,GPi_N,+0.383,0.331,sim_time,mem,false);
scoreg += score;
if (verbose) {
std::cerr << score << " ";
for (int i=0; i<NUCLEUS_NUMBER; i++) {
std::cout << means[i*ch_n] << " ";
}
}
// when gabazine is applied in GPe, we expect a 30.3% decrease in GPi
// (cf Tachibana et al. 2008 : "Motor cortical control of internal pallidal
// activity through glutamatergic and GABAergic inputs in awake monkeys")
activations.assign(DESACT_NUMBER,1);
activations[MSN_GPe_GABAA] = desactivation_level; // to block the GABAA channel of GPe (from MSN)
activations[GPe_GPe_GABAA] = desactivation_level; // to block the GABAA channel of GPe (from GPe)
score = _do_trial(means,ref,params,delays,activations,GPi_N,-0.303,0.229,sim_time,mem,false);
scoreg += score;
if (verbose) {
std::cerr << score << " ";
for (int i=0; i<NUCLEUS_NUMBER; i++) {
std::cout << means[i*ch_n] << " ";
}
}
return scoreg;
}
float calc_score_selective_boutons(std::vector <float>& params, bool verbose, int studied_nucleus)
{
// computes part of the anatomical plausibility objective
float weak[] = {15, 149};
float high[] = {150, 1499};
float massive[] = {1500, 4999};
float ctxpt_stn[] = {0, 1499};
float not_nonexistent[] = {15, 4999};
float ctx_msn_range[] = {250, 4999};
float ctxpt_msn_fsi_range[] = {100, 2499};
std::vector <int> c_weak; c_weak.resize(0);
std::vector <int> c_high; c_high.resize(0);
std::vector <int> c_massive; c_massive.resize(0);
std::vector <int> c_ctxpt_stn; c_ctxpt_stn.resize(0);
std::vector <int> c_not_nonexistent; c_not_nonexistent.resize(0);
std::vector <int> c_ctx_msn_range; c_ctx_msn_range.resize(0);
std::vector <int> c_ctxpt_msn_fsi_range; c_ctxpt_msn_fsi_range.resize(0);
if (studied_nucleus == MSN_N || studied_nucleus == -1) {
//axons
///CTX -> MSN+FSI treated separately after this function (for now)
c_weak.push_back(STN_MSN);
//c_not_nonexistent.push_back(CTX_MSN);
//c_not_nonexistent.push_back(GPe_MSN); // data exists only for the rat (Bevan98)
c_massive.push_back(FSI_MSN); // estimation from Humphries10b is ~3000
c_high.push_back(MSN_MSN); // estimation from Humphries10b is ~700; Estimation from Wilson07 & Wickens07 is ~450; Wickens07 wth Lee 1997, estimates at ~550
c_massive.push_back(CMPf_MSN); // estimation from Parent05
c_ctx_msn_range.push_back(CTX_MSN); //TODO
}
if (studied_nucleus == FSI_N || studied_nucleus == -1) {
//axons
//c_not_nonexistent.push_back(CTX_FSI);
c_weak.push_back(STN_FSI);
//c_not_nonexistent.push_back(GPe_FSI); // data exists only for the rat (Bevan98)
c_weak.push_back(FSI_FSI); // estimation from Humphries10b is < 100
c_high.push_back(CMPf_FSI); // estimation from Sidibe99: 1/3 of the contacts happen on FSI
c_ctxpt_msn_fsi_range.push_back(CTX_FSI); //TODO
}
if (studied_nucleus == STN_N || studied_nucleus == -1) {
//axons
///CTX -> STN treated separately after this function (for now)
//c_not_nonexistent.push_back(CTX_STN);
c_high.push_back(GPe_STN);
c_weak.push_back(CMPf_STN); // estimation from Sadikot92b and Tande06: weak
c_ctxpt_msn_fsi_range.push_back(CTX_STN); //TODO
}
if (studied_nucleus == GPe_N || studied_nucleus == -1) {
//axons
c_high.push_back(MSN_GPe); // Wickens07: ~749
c_high.push_back(STN_GPe);
c_high.push_back(GPe_GPe); // (hazardous ?) estimate: the Shink96 count of synapses (2.5 times more synapses from STN than from GPe) and we can compare the number of neurons (~3 more neurons in the GPe than in the STN), leading to the estimate that their should be slighty more boutons in the GPe -> GPe connection than in the STN -> GPe connection. Hence the value is expected to be around 500-1000, in the "high" range as the STN -> GPe connection.
c_weak.push_back(CMPf_GPe); // estimation from Sadikot92b, Parent05 and Tande06: weak
}
if (studied_nucleus == GPi_N || studied_nucleus == -1) {
//axons
c_high.push_back(MSN_GPi); // Wickens07: ~749
c_high.push_back(STN_GPi);
c_high.push_back(GPe_GPi);
c_weak.push_back(CMPf_GPi); // estimation from Parent05 and Tande06: weak
}
float borneinf = 0.;
float bornesup = 5000.;
float score = 0.;
float score_c = 1.; float score_d = 1.;
float *mini = NULL; float *maxi = NULL;
int nb_elem_treated = 0;
bool elem_already_treated = false;
for (int i=0; i<PARAMS_NUMBER; i++) {
if (is_in(c_weak,i)) {
mini = weak; maxi = weak+1;
} else if (is_in(c_high,i)) {
mini = high; maxi = high+1;
} else if (is_in(c_massive,i)) {
mini = massive; maxi = massive+1;
} else if (is_in(c_ctxpt_stn,i)) {
mini = ctxpt_stn; maxi = ctxpt_stn+1;
} else if (is_in(c_not_nonexistent,i)) {
mini = not_nonexistent; maxi = not_nonexistent+1;
} else if (is_in(c_ctx_msn_range,i)) {
mini = ctx_msn_range; maxi = ctx_msn_range+1;
} else if (is_in(c_ctxpt_msn_fsi_range,i)) {
mini = ctxpt_msn_fsi_range; maxi = ctxpt_msn_fsi_range+1;
} else {
mini = NULL;
}
if (mini) {
nb_elem_treated++;
elem_already_treated = true;
score_c = _is_near_tronqgaussian((*mini+*maxi)/2,params[i],((*mini+*maxi)/2)- *mini);
} else {
score_c = 0.;
}
if (verbose) {
if (score_c < 1 && mini) {
std::cout << "!!!! boutons count n° " << i << " out of range (" << params[i] << " not in [" << *mini << "," << *maxi << "])" << std::endl;
} else if (mini) {
std::cout << " boutons count n° " << i << " inside range (" << params[i] << " in [" << *mini << "," << *maxi << "])" << std::endl;
}
}
if (studied_nucleus == -1 || elem_already_treated) {
score += score_c;
}
elem_already_treated = false;
}
// c_prox.push_back(DIST_GPe_MSN); //no data for monkey (for the rat, it would have been "middle" according to Bevan98)
// c_prox.push_back(DIST_GPe_FSI); //no data for monkey (for the rat, it would have been "middle" according to Bevan98)
if (studied_nucleus == -1) {
nb_elem_treated++;
#ifdef LINEARDIST
score_c = _linear_dist(params[GPe_MSN]+params[GPe_FSI],high[0],high[1],borneinf,bornesup);
#else
score_c = _is_near_tronqgaussian((high[0]+high[1])/2,params[GPe_MSN]+params[GPe_FSI],((high[0]+high[1])/2)- high[0]);
#endif
if (score_c < 1 && verbose) {
std::cout << "pallido-striatal inputs out of range (score = " << score_c << ")" << std::endl;
}
score += score_c;
}
if (verbose) {
std::cout << "Summary: " << score << "/" << nb_elem_treated << std::endl;
}
return score;
}
float calc_score_selective_axons(std::vector <float>& params, bool verbose, int studied_nucleus)
{
// computes part of the anatomical plausibility objective
float weak[] = {15, 149}; // this constant and following ranges are for the bouton counts
float high[] = {150, 749};
float pretty_massive[] = {500, 1999};
float massive[] = {1500, 4999};
float not_nonexistent[] = {15, 749};
float ctx_msn_range[] = {250, 4999};
float ctxpt_msn_fsi_range[] = {1, 999};
float ctxpt_stn[] = {25, 4999};
std::vector <int> c_weak; c_weak.resize(0);
std::vector <int> c_high; c_high.resize(0);
std::vector <int> c_massive; c_massive.resize(0);
std::vector <int> c_pretty_massive; c_pretty_massive.resize(0);
std::vector <int> c_not_nonexistent; c_not_nonexistent.resize(0);
std::vector <int> c_ctx_msn_range; c_ctx_msn_range.resize(0);
std::vector <int> c_ctxpt_msn_fsi_range; c_ctxpt_msn_fsi_range.resize(0);
std::vector <int> c_ctxpt_stn; c_ctxpt_stn.resize(0);
// range for the synaptic localization
float prox[] = {0., 0.2};
float middle[] = {0.2, 0.6};
float far[] = {0.6, 1.};
std::vector <int> c_prox; c_prox.resize(0);
std::vector <int> c_middle; c_middle.resize(0);
std::vector <int> c_far; c_far.resize(0);
if (studied_nucleus == MSN_N || studied_nucleus == -1) {
//axons
///CTX -> MSN+FSI treated separately after this function (for now)
// c_weak.push_back(STN_MSN); // see below
//c_not_nonexistent.push_back(CTX_MSN);
//c_not_nonexistent.push_back(GPe_MSN); // data exists only for the rat (Bevan98) and is difficult to interpret (Mallet12)
c_massive.push_back(FSI_MSN); // estimation from Humphries10b is ~3000
c_high.push_back(MSN_MSN); // estimation from Humphries10b is ~700; Estimation from Wilson07 & Wickens07 is ~450; Wickens07 wth Lee 1997, estimates at ~550
c_massive.push_back(CMPf_MSN); // estimation from Parent05 (~1500 to ~3500 varicosities) and Sidibe99 (2/3 of these should target MSN neurons)
c_ctx_msn_range.push_back(CTX_MSN); //TODO
c_ctxpt_msn_fsi_range.push_back(CTXPT_MSN); //TODO
// synapses
c_far.push_back(DIST_CTX_MSN); // [rat] Wilson07 : "The synapses formed by cortical axons end almost exclusively (about 95%) on dendritic spines (Kemp and Powell, 1971b; Somogyi et al., 1981; Xu et al., 1989)"
c_far.push_back(DIST_CTXPT_MSN); // [rat] Wilson07 : "The synapses formed by cortical axons end almost exclusively (about 95%) on dendritic spines (Kemp and Powell, 1971b; Somogyi et al., 1981; Xu et al., 1989)"
// c_prox.push_back(DIST_STN_MSN); // not known
c_prox.push_back(DIST_FSI_MSN); // [rat] Tepper08 (p. 274); Wilson07 (p. 95)
c_far.push_back(DIST_MSN_MSN); // [rat] Tepper08 (p. 276); Wilson07 (p. 95)
c_middle.push_back(DIST_CMPf_MSN); // Sidibe96 + Sidibe99
}
if (studied_nucleus == FSI_N || studied_nucleus == -1) {
//axons
//c_not_nonexistent.push_back(CTX_FSI);
// c_weak.push_back(STN_FSI); // see below
//c_not_nonexistent.push_back(GPe_FSI); // data exists only for the rat (Bevan98)
c_weak.push_back(FSI_FSI); // estimation from Humphries10b is < 100
c_pretty_massive.push_back(CMPf_FSI); // estimation from Sidibe99: 1/3 of the contacts happen on FSI, and Parent05 : (~1500 to ~3500 varicosities for these axons)
c_ctx_msn_range.push_back(CTX_FSI); //TODO
c_ctxpt_msn_fsi_range.push_back(CTXPT_FSI); //TODO
// synapses
c_far.push_back(DIST_CTX_FSI); // Lapper92 (table 1, p. 219)
c_far.push_back(DIST_CTXPT_FSI); // Lapper92 (table 1, p. 219)
// c_prox.push_back(DIST_STN_FSI); // not known
// c_prox.push_back(DIST_FSI_FSI);
c_prox.push_back(DIST_CMPf_FSI); // Sidibe99
}
if (studied_nucleus == STN_N || studied_nucleus == -1) {
//axons
///CTX -> STN treated separately after this function (for now)
//c_not_nonexistent.push_back(CTX_STN);
//c_high.push_back(GPe_STN); // Following Martin Parent advice
c_weak.push_back(GPe_STN); // cf Karachi 05
//c_not_nonexistent.push_back(GPe_STN); // we can't really know better
c_weak.push_back(CMPf_STN); // estimation from Sadikot92b and Tande06: weak
c_ctxpt_stn.push_back(CTX_STN); //TODO
// synapses
c_far.push_back(DIST_CTX_STN); // Marani 08 (ch 2)
// c_prox.push_back(DIST_GPe_STN); // cf Shink 96 : 31% axosomatic and 69% axodendritic; and cf Parent 95b : 30% soma, 40% proximal dendrites and 30% distant dendrite. Hassler82 + Marani08 => labelled it as "prox"
c_middle.push_back(DIST_GPe_STN); // there was an ambiguity, as this is the term always got wrong after evolution, we labelled it as "middle". Coherent with the rat (Bevan97) which show a repartion : 31% on perikarya, 39% on large dendrites, 30% on small dendrites
}
if (studied_nucleus == GPe_N || studied_nucleus == -1) {
//axons
c_high.push_back(MSN_GPe); // Wickens07: ~749
c_high.push_back(STN_GPe);
//c_high.push_back(GPe_GPe); // (hazardous ?) estimate: the Shink96 count of synapses (2.5 times more synapses from STN than from GPe) and we can compare the number of neurons (~3 more neurons in the GPe than in the STN), leading to the estimate that their should be slighty more boutons in the GPe -> GPe connection than in the STN -> GPe connection. Hence the value is expected to be around 500-1000, in the "high" range as the STN -> GPe connection.
#ifdef TRYGPEGPE
c_high.push_back(GPe_GPe);
#else
c_weak.push_back(GPe_GPe); // Following Martin Parent advice
#endif
c_weak.push_back(CMPf_GPe); // estimation from Sadikot92b, Parent05 and Tande06: weak
// synapses
c_middle.push_back(DIST_MSN_GPe); // cf Shink 95: but we believe it should be more 0.2 than 0.6 here !
c_middle.push_back(DIST_STN_GPe); // cf Shink 95 and Shink 96
c_prox.push_back(DIST_GPe_GPe); // cf Shink 95
}
if (studied_nucleus == GPi_N || studied_nucleus == -1) {
//axons
c_high.push_back(MSN_GPi); // Wickens07: ~749
c_high.push_back(STN_GPi);
#ifdef TRYGPEGPI
c_high.push_back(GPe_GPi); // following Martin Parent advice
#else
c_not_nonexistent.push_back(GPe_GPi); // we can't really know better
#endif
c_weak.push_back(CMPf_GPi); // estimation from Parent05 and Tande06: weak
// synapses
c_middle.push_back(DIST_MSN_GPi); // cf Shink 95: as well axosynaptic as axodendritic
c_middle.push_back(DIST_STN_GPi); // cf Shink 95
c_prox.push_back(DIST_GPe_GPi); // cf Shink 95. More or less coherent with the rat (Bevan97)
}
float borneinf = 0.;
float bornesup = 5000.;
float score = 0.;
float score_c; float score_d;
float *mini = NULL; float *maxi = NULL;
int nb_elem_treated = 0;
bool elem_already_treated = false;
for (int i=0; i<CONNECT_NUMBER; i++) {
if (is_in(c_weak,i)) {
mini = weak; maxi = weak+1;
} else if (is_in(c_high,i)) {
mini = high; maxi = high+1;
} else if (is_in(c_massive,i)) {
mini = massive; maxi = massive+1;
} else if (is_in(c_pretty_massive,i)) {
mini = pretty_massive; maxi = pretty_massive+1;
} else if (is_in(c_ctxpt_stn,i)) {
mini = ctxpt_stn; maxi = ctxpt_stn+1;
} else if (is_in(c_not_nonexistent,i)) {
mini = not_nonexistent; maxi = not_nonexistent+1;
} else if (is_in(c_ctx_msn_range,i)) {
mini = ctx_msn_range; maxi = ctx_msn_range+1;
} else if (is_in(c_ctxpt_msn_fsi_range,i)) {
mini = ctxpt_msn_fsi_range; maxi = ctxpt_msn_fsi_range+1;
} else {
mini = NULL;
}
if (mini) {
nb_elem_treated++;
elem_already_treated = true;
score_c = _is_near_tronqgaussian((*mini+*maxi)/2,params[i],((*mini+*maxi)/2)- *mini);
} else {
score_c = 1.;
}
if (verbose) {
if (score_c < 1) {
std::cout << "!!!! boutons count n° " << i << " out of range (" << params[i] << " not in [" << *mini << "," << *maxi << "])" << std::endl;
} else if (mini) {
std::cout << " boutons count n° " << i << " inside range (" << params[i] << " in [" << *mini << "," << *maxi << "])" << std::endl;
}
}
if (is_in(c_prox,i+CONNECT_NUMBER)) {
mini = prox; maxi = prox+1;
} else if (is_in(c_middle,i+CONNECT_NUMBER)) {
mini = middle; maxi = middle+1;
} else if (is_in(c_far,i+CONNECT_NUMBER)) {
mini = far; maxi = far+1;
} else {
mini = NULL;
}
if (mini) {
elem_already_treated = true;
if (!elem_already_treated) {
nb_elem_treated++;
}
score_d = _is_near_tronqgaussian((*mini+*maxi)/2,params[i+CONNECT_NUMBER],((*mini+*maxi)/2)- *mini);
} else {
score_d = 1.;
}
if (verbose) {
if (score_d < 1) {
std::cout << "!!!! distance n° " << i+CONNECT_NUMBER << " out of range (" << params[i+CONNECT_NUMBER] << " not in [" << *mini << "," << *maxi << "])" << std::endl;
} else if (mini) {
std::cout << " distance n° " << i+CONNECT_NUMBER << " inside range (" << params[i+CONNECT_NUMBER] << " in [" << *mini << "," << *maxi << "])" << std::endl;
}
}
if (studied_nucleus == -1 || elem_already_treated) {
score += score_c * score_d;
}
elem_already_treated = false;
}
// c_prox.push_back(DIST_GPe_MSN); //no data for monkey (for the rat, it would have been "middle" according to Bevan98)
// c_prox.push_back(DIST_GPe_FSI); //no data for monkey (for the rat, it would have been "middle" according to Bevan98)
if (studied_nucleus == -1) {
nb_elem_treated++;
score_c = _is_near_tronqgaussian((high[0]+high[1])/2,params[GPe_MSN]+params[GPe_FSI],((high[0]+high[1])/2)- high[0]);
if (score_c < 1 && verbose) {
std::cout << "pallido-striatal inputs out of range (score = " << score_c << ")" << std::endl;
}
score += score_c;
}
if (studied_nucleus == -1) {
nb_elem_treated++;
score_c = _is_near_tronqgaussian((weak[0]+weak[1])/2,params[STN_MSN]+params[STN_FSI],((weak[0]+weak[1])/2)- weak[0]);
if (score_c < 1 && verbose) {
std::cout << "subthalamico-striatal inputs out of range (score = " << score_c << ")" << std::endl;
}
score += score_c;
}
if (verbose) {
std::cout << "Summary: " << score << "/" << nb_elem_treated << std::endl;
}
return score;
}
float _is_near_gaussian(
float reference,
float mean,
float absolute_radius)
{
return exp((-0.5)*(mean-reference)*(mean-reference)/(absolute_radius*absolute_radius));
}
float _is_near_tronqgaussian(
float reference,
float mean,
float absolute_radius)
{
if ((mean >= reference - absolute_radius) and (mean <= reference + absolute_radius)) {
return 1.;
}
return (exp((-0.5)*(mean-reference)*(mean-reference)/(absolute_radius*absolute_radius)))/(exp(-0.5));
}
float _has_changed_near_gaussian(
float reference,
float mean,
float proportional_change,
float proportional_radius)
{
float new_ref = reference + reference * proportional_change;
float absolute_radius = abs(new_ref - (reference + reference * (proportional_change+proportional_radius)));
if (absolute_radius < 1) {
return 0.;
} else {
return exp((-0.5)*(mean-new_ref)*(mean-new_ref)/(absolute_radius*absolute_radius));
}
}
float _has_changed_near_tronqgaussian(
float reference,
float mean,
float proportional_change,
float proportional_radius)
{
float new_ref = reference + reference * proportional_change;
float absolute_radius = abs(new_ref - (reference + reference * (proportional_change+proportional_radius)));
if ((mean >= new_ref - absolute_radius) and (mean <= new_ref + absolute_radius)) {
return 1.;
}
return (exp((-0.5)*(mean-new_ref)*(mean-new_ref)/(absolute_radius*absolute_radius)))/(exp(-0.5));
}
float _is_near_step(
float reference,
float mean,
float absolute_radius)
{
if ((mean >= reference - absolute_radius) and (mean <= reference + absolute_radius)) {
return 1;
}
return 0;
}