/* See {nmsim_neuron_parms.h} */ /* Last edited on 2018-04-11 16:19:23 by jstolfi */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include nmsim_neuron_parms_t* nmsim_neuron_parms_new ( double V_B, double V_R, double c_B, double L_R, double L_mu, double G_R, double G_mu, double H_R, double H_mu, struct nmsim_firing_func_t *Phi ) { nmsim_neuron_parms_t* pm = notnull(malloc(sizeof(nmsim_neuron_parms_t)), "no mem"); (*pm) = (nmsim_neuron_parms_t) { .V_B = V_B, .V_R = V_R, .c_B = c_B, .L_R = L_R, .L_mu = L_mu, .G_R = G_R, .G_mu = G_mu, .H_R = H_R, .H_mu = H_mu, .Phi = Phi }; return pm; } void nmsim_neuron_parms_write(FILE *wr, nmsim_neuron_parms_t *parms) { auto void write_param(char *name, double v); /* Writes a line "{name} = {v}". */ filefmt_write_header(wr, nmsim_neuron_parms_FILE_TYPE, nmsim_neuron_parms_VERSION); write_param("V_R", parms->V_R); write_param("V_B", parms->V_B); write_param("c_B", parms->c_B); write_param("L_R", parms->L_R); write_param("G_R", parms->G_R); write_param("H_R", parms->H_R); write_tau_param_from_mu("L_tau", parms->L_mu); write_tau_param_from_mu("G_tau", parms->G_mu); write_tau_param_from_mu("H_tau", parms->H_mu); filefmt_write_footer(wr, nmsim_neuron_parms_FILE_TYPE); void write_param(char *name, double v) { fprintf(wr, "%s = %9.7f\n", name, v); } void write_tau_param_from_mu(char *name, double mu) { double tau; if (mu == 0) { tau = 0; } else if (mu == INF) { tau = INF; } else { tau = -timeStep*log(mu); } write_param("G_tau", tau); } } nmsim_neuron_parms_t *nmsim_neuron_parms_read(FILE *rd, double timeStep) { auto double read_param(char *name, double vmin, double vmax); /* Reads a line \"{name} = {value}\", including the end-of-line, and checks that {value} is in the range {[vmin_vmax]}. */ auto double read_mu_from_tau_param(char *name); /* Reads a line \"{name} = {value}\", including the end-of-line, and then converts {value} from a characteristic time to a decay factor based on the given {timeStep}. */ double read_param(char *name, double vmin, double vmax) { double v = nget_double(rd, name); if ((v < vmin) || (v > vmax)) { fprintf ( stderr, "** parameter {%s} = %24.16e is out of range [ %24.16e _ %24.16e ]\n", name, v, vmin, vmax ); demand(FALSE, "aborted"); } fget_eol(rd); return v; } double read_mu_from_tau_param(char *name) { double tau = read_param(name, 0.0, INF); if (tau < 0.02*timeStep) { return 0.0; } else if (tau == INF) { return 1.0; } else { return exp(-timeStep/tau); } } /* Read header line: */ filefmt_read_header(rd, nmsim_neuron_parms_FILE_TYPE, nmsim_neuron_parms_VERSION); /* Read the parameters: */ double V_B = read_param("V_B", -200.0, +200.0); double V_R = read_param("V_R", -200.0, +200.0); double c_B = read_mu_from_tau_param("tau_V"); double L_R = read_param("L_R", 0.0, 1.0); double L_mu = read_mu_from_tau_param("tau_L"); double G_R = read_param("G_R", 0.0, 1.0); double G_mu = read_mu_from_tau_param("tau_G"); double H_R = read_param("H_R", 0.0, 1.0); double H_mu = read_mu_from_tau_param("tau_H"); /* Read name and parameters of the firing function: */ char *Phi_name = nget_string(rd, "Phi"); double V_M = fget_double(rd); double D_M = fget_double(rd); int32_t deg = fget_int32(rd); fget_eol(rd); struct nmsim_firing_func_t *Phi = nmsim_firing_func_new(Phi_name, V_M, D_M, deg); nmsim_neuron_parms_t *parms = nmsim_neuron_parms_new ( V_B, V_R, c_B, L_R, L_mu, G_R, G_mu, H_R, H_mu, Phi ); /* Read footer line: */ filefmt_read_footer(rd, nmsim_neuron_parms_FILE_TYPE); return parms; }