/*
 *       File name:  libcn/types.cc
 *         Project:  cnrun
 *          Author:  Andrei Zavada <johnhommer@gmail.com>
 *                   building on original work by Thomas Nowotny <tnowotny@ucsd.edu>
 * Initial version:  2008-09-23
 *
 *         Purpose:  CN global unit descriptors
 *
 *         License:  GPL-2+
 */

#if HAVE_CONFIG_H && !defined(VERSION)
#  include "config.h"
#endif

#include <cstdio>
#include <cstring>

#include "libstilton/string.hh"
#include "types.hh"


using namespace std;

cnrun::SCNDescriptor cnrun::__CNUDT[] = {

// ---------------- Neuron types

        { UT_HOSTED,  // NT_HH_D
          8+18, 4,
          CN_Params_NeuronHH_d,
          CN_ParamNames_NeuronHH_d,
          CN_ParamSyms_NeuronHH_d,
          CN_Vars_NeuronHH_d,
          CN_VarNames_NeuronHH_d,
          CN_VarSyms_NeuronHH_d,
          "HH",
          "HH",
          "Hodgkin-Huxley by Traub and Miles (1991)"
        },

        { UT_RATEBASED,  // NT_HH_R
          4, 1,
          CN_Params_NeuronHH_r,
          CN_ParamNames_NeuronHH_r,
          CN_ParamSyms_NeuronHH_r,
          CN_Vars_NeuronHH_r,
          CN_VarNames_NeuronHH_r,
          CN_VarSyms_NeuronHH_r,
          "HHRate",
          "HHRate",
          "Rate-based model of the Hodgkin-Huxley neuron"
        },

        { UT_HOSTED,  // NT_HH2_D
          11+18-1, 4,
          CN_Params_NeuronHH2_d,
          CN_ParamNames_NeuronHH2_d,
          CN_ParamSyms_NeuronHH2_d,
          CN_Vars_NeuronHH2_d,
          CN_VarNames_NeuronHH_d,
          CN_VarSyms_NeuronHH_d,
          "HH2",
          "HH2",
          "Hodgkin-Huxley by Traub & Miles w/ K leakage"
        },

        { UT_RATEBASED | UT__STUB,  // NT_HH2_R
          0, 0,
          NULL,          NULL,          NULL,
          NULL,          NULL,          NULL,
          "HH2Rate",
          "HH2Rate",
          "Rate-based model of the Hodgkin-Huxley by Traub & Miles"
        },

//#ifdef CN_WANT_MORE_NEURONS
        { UT_HOSTED,  // NT_EC_D
          14, 6,
          CN_Params_NeuronEC_d,
          CN_ParamNames_NeuronEC_d,
          CN_ParamSyms_NeuronEC_d,
          CN_Vars_NeuronEC_d,
          CN_VarNames_NeuronEC_d,
          CN_VarSyms_NeuronEC_d,
          "EC",
          "EC",
          "Entorhinal Cortex neuron"
        },

        { UT_HOSTED,  // NT_ECA_D
          11, 7,
          CN_Params_NeuronECA_d,
          CN_ParamNames_NeuronECA_d,
          CN_ParamSyms_NeuronECA_d,
          CN_Vars_NeuronECA_d,
          CN_VarNames_NeuronECA_d,
          CN_VarSyms_NeuronECA_d,
          "ECA",
          "ECA",
          "Entorhinal Cortex (A) neuron"
        },
//#endif

        { UT_OSCILLATOR | UT_DOT,  // NT_POISSONDOT
          3, 2,
          CN_Params_OscillatorPoissonDot,
          CN_ParamNames_OscillatorPoissonDot,
          CN_ParamSyms_OscillatorPoissonDot,
          CN_Vars_OscillatorPoissonDot,
          CN_VarNames_OscillatorPoissonDot,
          CN_VarSyms_OscillatorPoissonDot,
          "DotPoisson",
          "DotPoisson",
          "Duration-less spike Poisson oscillator"
        },

        { UT_OSCILLATOR,  // NT_POISSON
          5, 1,
          CN_Params_OscillatorPoisson,
          CN_ParamNames_OscillatorPoisson,
          CN_ParamSyms_OscillatorPoisson,
          CN_Vars_OscillatorPoisson,
          CN_VarNames_OscillatorPoisson,
          CN_VarSyms_OscillatorPoisson,
          "Poisson",
          "Poisson",
          "Poisson oscillator"
        },

/*
        { UT_HOSTED | UT_OSCILLATOR,  // NT_LV
          1, 2,
          CN_Params_OscillatorLV,
          CN_ParamNames_OscillatorLV,
          CN_ParamSyms_OscillatorLV,
          CN_Vars_OscillatorLV,
          CN_VarNames_OscillatorLV,
          CN_VarSyms_OscillatorLV,
          "LV",
          "LV",
          "Lotka-Volterra oscillator"
        },
*/

        { UT_HOSTED | UT_OSCILLATOR,  // NT_COLPITTS,
          4, 3,
          CN_Params_OscillatorColpitts,
          CN_ParamNames_OscillatorColpitts,
          CN_ParamSyms_OscillatorColpitts,
          CN_Vars_OscillatorColpitts,
          CN_VarNames_OscillatorColpitts,
          CN_VarSyms_OscillatorColpitts,
          "Colpitts",
          "Colpitts",
          "Colpitts oscillator"
        },

        { UT_HOSTED | UT_OSCILLATOR,  // NT_VDPOL,
          2, 2,
          CN_Params_OscillatorVdPol,
          CN_ParamNames_OscillatorVdPol,
          CN_ParamSyms_OscillatorVdPol,
          CN_Vars_OscillatorVdPol,
          CN_VarNames_OscillatorVdPol,
          CN_VarSyms_OscillatorVdPol,
          "VdPol",
          "VdPol",
          "Van der Pol oscillator"
        },

        { UT_OSCILLATOR | UT_DOT,  // NT_DOTPULSE
          3, 2,
          CN_Params_NeuronDotPulse,
          CN_ParamNames_NeuronDotPulse,
          CN_ParamSyms_NeuronDotPulse,
          CN_Vars_NeuronDotPulse,
          CN_VarNames_NeuronDotPulse,
          CN_VarSyms_NeuronDotPulse,
          "DotPulse",
          "DotPulse",
          "Dot Pulse generator"
        },

        { UT_DDTSET,  // NT_MAP
          5, 1,
          CN_Params_NeuronMap,
          CN_ParamNames_NeuronMap,
          CN_ParamSyms_NeuronMap,
          CN_Vars_NeuronMap,
          CN_VarNames_NeuronMap,
          CN_VarSyms_NeuronMap,
          "NMap",
          "NMap",
          "Map neuron"
        },

// ---------------- Synapse types

// a proper synapse (of eg AB type) will be selected based on whether
// its source/target is rate-based or discrete

        { UT_HOSTED,  // YT_AB_DD
          5, 1,
          CN_Params_SynapseAB_dd,
          CN_ParamNames_SynapseAB_dd,
          CN_ParamSyms_SynapseAB_dd,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "AB",
          "AB_pp",
          "Alpha-Beta synapse (Destexhe, Mainen, Sejnowsky, 1994)"
        },

        { UT_HOSTED | UT_TGTISRATE | UT__STUB,  // YT_AB_DR
          5, 1,
          NULL,          NULL,          NULL,
          NULL,          NULL,          NULL,
          "AB",
          "AB_pt",
          "Alpha-Beta synapse (phasic->tonic)"
        },

        { UT_HOSTED | UT_SRCISRATE | UT__STUB,  // YT_AB_RD
          5, 1,
          NULL,          NULL,          NULL,
          NULL,          NULL,          NULL,
          "AB",
          "AB_tp",
          "Alpha-Beta synapse (tonic->phasic)"
        },

        { UT_HOSTED | UT_RATEBASED,  // YT_AB_RR
          4, 1,
          CN_Params_SynapseAB_rr,
          CN_ParamNames_SynapseAB_rr,
          CN_ParamSyms_SynapseAB_rr,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "AB",
          "AB_tt",
          "Alpha-Beta synapse (tonic->tonic)"
        },

        { UT_HOSTED | UT_MULTIPLEXING,  // YT_MXAB_DD, inheriting all parameters except alpha, and variables from YT_AB
          5, 1,
          CN_Params_SynapseMxAB_dd,
          CN_ParamNames_SynapseAB_dd,
          CN_ParamSyms_SynapseAB_dd,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "AB",
          "AB_Mx_pp",
          "Multiplexing Alpha-Beta synapse for use with durationless units as source (phasic->phasic)"
        },

        { UT_HOSTED | UT_TGTISRATE | UT_MULTIPLEXING,  // YT_MXAB_DR
          5, 1,
          CN_Params_SynapseMxAB_dr,
          CN_ParamNames_SynapseAB_dr,
          CN_ParamSyms_SynapseAB_dr,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "AB",
          "AB_Mx_pt",
          "Multiplexing Alpha-Beta synapse for use with durationless units as source (phasic->tonic)"
        },


        { UT_HOSTED,  // YT_ABMINS_DD
          5, 1,
          CN_Params_SynapseABMinus_dd,
          CN_ParamNames_SynapseAB_dd,
          CN_ParamSyms_SynapseAB_dd,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "ABMinus",
          "ABMinus_pp",
          "Alpha-Beta synapse w/out (1-S) term"
        },

        { UT_HOSTED | UT_TGTISRATE | UT__STUB,  // YT_ABMINS_DR
          5, 1,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "ABMinus",
          "ABMinus_pt",
          "Alpha-Beta synapse w/out (1-S) term (phasic->tonic)"
        },

        { UT_HOSTED | UT_SRCISRATE | UT__STUB,  // YT_ABMINS_RD
          5, 1,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "ABMinus",
          "ABMinus_tp",
          "Alpha-Beta synapse w/out (1-S) term (tonic->phasic)"
        },

        { UT_HOSTED | UT_SRCISRATE | UT_TGTISRATE | UT__STUB,  // YT_ABMINS_RR
          5, 1,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "ABMinus",
          "ABMinus_tt",
          "Alpha-Beta synapse w/out (1-S) term (tonic->tonic)"
        },

        { UT_HOSTED | UT_MULTIPLEXING | UT__STUB,  // YT_MXABMINUS_DD
          5, 1,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "ABMinus",
          "ABMinus_Mx_pp",
          "Multiplexing Alpha-Beta w/out (1-S) synapse for use with durationless units as source (phasic->phasic)"
        },

        { UT_HOSTED | UT_TGTISRATE | UT_MULTIPLEXING | UT__STUB,  // YT_MXABMINUS_DR
          5, 1,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "ABMinus",
          "ABMinus_Mx_pt",
          "Multiplexing Alpha-Beta w/out (1-S) synapse for use with durationless units as source (phasic->tonic)"
        },


        { UT_HOSTED,  // YT_RALL_DD
          3, 2,
          CN_Params_SynapseRall_dd,
          CN_ParamNames_SynapseRall_dd,
          CN_ParamSyms_SynapseRall_dd,
          CN_Vars_SynapseRall,
          CN_VarNames_SynapseRall,
          CN_VarSyms_SynapseRall,
          "Rall",
          "Rall_pp",
          "Rall synapse (Rall, 1967)"
        },

        { UT_HOSTED | UT_TGTISRATE | UT__STUB,  // YT_RALL_DR
          3, 2,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseRall,
          CN_VarNames_SynapseRall,
          CN_VarSyms_SynapseRall,
          "Rall",
          "Rall_pt",
          "Rall synapse (Rall, 1967) (phasic->tonic)"
        },

        { UT_HOSTED | UT_SRCISRATE | UT__STUB,  // YT_RALL_RD
          3, 2,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseRall,
          CN_VarNames_SynapseRall,
          CN_VarSyms_SynapseRall,
          "Rall",
          "Rall_tp",
          "Rall synapse (tonic->phasic)"
        },

        { UT_HOSTED | UT_SRCISRATE | UT_TGTISRATE | UT__STUB,  // YT_RALL_RR
          3, 2,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseRall,
          CN_VarNames_SynapseRall,
          CN_VarSyms_SynapseRall,
          "Rall",
          "Rall_tt",
          "Rall synapse (tonic->tonic)"
        },

        { UT_HOSTED | UT_MULTIPLEXING | UT__STUB,  // YT_MXRALL_DD
          3, 2,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseRall,
          CN_VarNames_SynapseRall,
          CN_VarSyms_SynapseRall,
          "Rall",
          "Rall_Mx_pp",
          "Rall synapse for use with durationless units as source (phasic->phasic)"
        },

        { UT_HOSTED | UT_TGTISRATE | UT_MULTIPLEXING | UT__STUB,  // YT_MXRALL_DR
          3, 2,
          NULL,          NULL,          NULL,
          CN_Vars_SynapseRall,
          CN_VarNames_SynapseRall,
          CN_VarSyms_SynapseRall,
          "Rall",
          "Rall_Mx_pt",
          "Rall synapse for use with durationless units as source (phasic->tonic)"
        },


        { UT_DDTSET,  // YT_MAP
          3, 1,
          CN_Params_SynapseMap,
          CN_ParamNames_SynapseMap,
          CN_ParamSyms_SynapseMap,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "Map",
          "Map",
          "Map synapse"
        },

        { UT_DDTSET | UT_MULTIPLEXING,  // YT_MXMAP
          3, 1,
          CN_Params_SynapseMap,
          CN_ParamNames_SynapseMap,
          CN_ParamSyms_SynapseMap,
          CN_Vars_SynapseAB,
          CN_VarNames_SynapseAB,
          CN_VarSyms_SynapseAB,
          "Map",
          "Map_Mx",
          "Multiplexing Map synapse"
        },
};



cnrun::TUnitType
cnrun::
unit_family_by_string( const string& id)
{
        for ( int i = NT_FIRST; i <= YT_LAST; ++i )
                if ( id == __CNUDT[i].family )
                        return (TUnitType)i;
        return NT_VOID;
}

cnrun::TUnitType
cnrun::
unit_species_by_string( const string& id)
{
        for ( int i = NT_FIRST; i <= YT_LAST; ++i )
                if ( id == __CNUDT[i].species )
                        return (TUnitType)i;
        return NT_VOID;
}




void
cnrun::
cnmodel_dump_available_units()
{
        using cnrun::stilton::str::double_dot_aligned_s;

        size_t u, p;
        printf( "\n===== Neurons:\n");
        for ( u = NT_FIRST; u <= NT_LAST; ++u ) {
                const auto &U = __CNUDT[u];
                if ( U.traits & UT__STUB )
                        continue;
                printf( "* [%s] %s:\n",
                        U.species, U.description);
                for ( p = 0; p < U.pno; ++p ) {
                        printf( "   %-12s %s  %s\n",
                                U.stock_param_syms[p],
                                double_dot_aligned_s(
                                        U.stock_param_values[p], 4, 8).c_str(),
                                U.stock_param_names[p]);
                }
                for ( p = 0; p < U.vno; ++p ) {
                        printf( "v: %-12s %s  %s\n",
                                U.stock_var_syms[p],
                                double_dot_aligned_s( U.stock_var_values[p], 4, 8).c_str(),
                                U.stock_var_names[p]);
                }
                printf( "\n");
        }
        printf( "\n===== Synapses:\n");
        for ( u = YT_FIRST; u <= YT_LAST; ++u ) {
                SCNDescriptor &U = __CNUDT[u];
                if ( U.traits & UT__STUB )
                        continue;
                printf( "* [%s] %s:\n",
                        U.species, U.description);
                for ( p = 0; p < U.pno; ++p ) {
                        printf( "   %-12s %s  %s\n",
                                U.stock_param_syms[p],
                                double_dot_aligned_s(
                                        U.stock_param_values[p], 4, 8).c_str(),
                                U.stock_param_names[p]);
                }
                for ( p = 0; p < U.vno; ++p ) {
                        printf( "v: %-12s %s  %s\n",
                                U.stock_var_syms[p],
                                double_dot_aligned_s( U.stock_var_values[p], 4, 8).c_str(),
                                U.stock_var_names[p]);
                }
                printf( "\n");
        }
        printf( "\n");
}

// Local Variables:
// Mode: c++
// indent-tabs-mode: nil
// tab-width: 8
// c-basic-offset: 8
// End:
