Electron Distributions

eDist(double[::1] gamma, double ne, list params, unicode edist)

Common function for built-in electron distributions

Parameters
  • gamma (np.ndarray) – 1-D gamma array (C contiguous)

  • ne (float) – Number of electrons

  • params (list of floats) –

    Electron distributions parameters varies based on edist
    • ”thermal” : theta_E

    • ”kappa” : kappa, kappa_width

    • ”powerlaw” : p, g_min, g_max

    • ”bknpowerlaw” : p1, p2, g_break, g_min, g_max

    • ”powerlawexpcutoff” : p, g_min, g_max

    • ”bknpowerlawexpcutoff” : p1, p2, g_break, g_min, g_max

  • edist (str) – see params

Returns

dN/dgamma

Return type

np.ndarray

How to add new electron distributions

Unfortunately, we are not able to provide a convenient way to add new electron distributions in python as electron distributions are tightly integrated in C utilities at lower level. But, C interface is modular and it is possible to add new distributions on the source code.

Our powerlaw implementation at C level is given below:

// cfuncs/edist.c
//...

// params : p, gamma_min, gamma_max
double powerlaw(double gamma, void *params){
    double *p = (double*) params;
    return pow(gamma, -p[0]);
}

//...

double powerlaw_norm(void* params){
    double *p = (double*) params;
    return (P_THRESH > fabs(p[0] - 1)) ? (log(p[2])-log(p[1])) : (pow(p[1], -p[0]+1)-pow(p[2], -p[0]+1))/(p[0]-1);
}
//...

// cfuncs/edist.h
//...
// params : p, gamma_min, gamma_max
double powerlaw(double gamma, void *params);
//...
double powerlaw_norm(void *params);
//...

Then, the distribution needs to be registered with a name tag in Cython interface. This makes the distribution available to the rest of the code with the given name tag.

# flaremodel/utils/cfuncs.pyx

# ...

cdef extern from "edist.h":
    double powerlaw (double, void*) # <--
    double powerlawexpcutoff (double, void*)
    double thermal (double, void*)
    double kappa (double, void*)
    double bknpowerlaw (double, void*)
    double bknpowerlawexpcutoff (double, void*)
    double powerlaw_norm (void*) # <--
    double thermal_norm (void*)
    double kappa_norm (void*)
    double bknpowerlaw_norm (void*)
    int c_eDist         "eDist"         (...)

# ...

cdef _set_source_params(Source *source_t, str edist):

    cdef double *params = source_t.params

    if edist == "powerlaw": # <--
        source_t.gamma_min = params[1]
        source_t.gamma_max = params[2]
        source_t.d_func = &powerlaw
        source_t.n_func = &powerlaw_norm
    elif edist == "thermal":
        source_t.d_func = &thermal
        source_t.n_func = &thermal_norm
    elif edist == "kappa":
        source_t.d_func = &kappa
        source_t.n_func = &kappa_norm
    elif edist == "bknpowerlaw":
        source_t.gamma_min = params[3]
        source_t.gamma_max = params[4]
        source_t.d_func = &bknpowerlaw
        source_t.n_func = &bknpowerlaw_norm
    elif edist == "powerlawexpcutoff":
        source_t.gamma_min = params[1]
        source_t.gamma_max = params[2]*10
        source_t.d_func = &powerlawexpcutoff
        source_t.n_func = &powerlaw_norm
    elif edist == "bknpowerlawexpcutoff":
        source_t.gamma_min = params[3]
        source_t.gamma_max = params[4]*10
        source_t.d_func = &bknpowerlawexpcutoff
        source_t.n_func = &bknpowerlaw_norm
    else:
        raise ValueError("%s not implemented" % edist)

# ...