gundam-organization / gundam

GUNDAM, for Generalized and Unified Neutrino Data Analysis Methods, is a suite of applications which aims at performing various statistical analysis with different purposes and setups.
GNU Lesser General Public License v2.1
13 stars 11 forks source link

Feature/Tabulated Dials #554

Closed ClarkMcGrew closed 3 months ago

ClarkMcGrew commented 3 months ago

This provides the infrastructure necessary to use an external library to calculate a event-by-event weights. It can be used for near detector exotics fits (e.g. short baseline oscillation fits).

Initialize the Tabulated type. That yaml for this is

tableConfig:
    - name: <table-name>                A table name passed to the library.
      bins:  <number>                   The (optional) expected number of
                                           bins in the table. Will be
                                           overridden by the initFunction.
      libraryPath: <path-to-library>    Location of the library
      initFunction: <init-func-name>    Function called for initialization
      initArguments: [<arg1>, ...]      List of argument strings (e.g.
                                           input file names)
      updateFunction: <update-func-name> Function called to update table
      binningFunction: <bin-func-name>  Function to find bin index
      variables: [<var1>, <var2>, ... ] Variables used for binning the
                                           table "X" coordinate by the
                                           binning function.

INITIALIZATION FUNCTION:

If initFunction is provided it will be called with the signature:

    extern "C"
    int initFunc(const char* name, int argc, const char* argv[], int bins)

The function should return less than or equal to zero for failure, and otherwise, the number of elements needed to store the table (usually, the same as the input value of "bins").

UPDATE TABLE FUNCTION:

The updateFunction signature is:

    extern "C"
    int updateFunc(const char* name,
                   double table[], int bins,
                   const double par[], int npar)

The function should return 0 for success, and any other value for failure

The table will be filled with "bins" values calculated with uniform spacing between "low" and "high". If bins is one, there must be one value calculated for "low", if bins is two or more, then the first point is located at "low", and the last point is located at "high". The step between the bins is (high-low)/(bins-1). Examples:

    bins = 2, low = 1.0, high = 6.0
       values calculated at 1.0 and 6.0
    bins = 3, low = 1.0, high = 6.0
       values calculated at 1.0, 3.5, and 6.0

While the update can (in principle) be done directly on the GPU, and have the table directly accessed by the Cache::Manager, the results must be copied back to the CPU so that the Propagator event weight calculation can be done. The current implementation does not expose the methods to hand the table directly from the external library to the Cache::Manager kernels. The calculation can also be done solely on the CPU, and the results will be copied to the GPU.

BIN INDEX DETERMINATION:

The binningFunction signature is:

    extern "C"
    double binFunc(const char* name, int nvar, const double varv[], int bins);

The function should return a double giving the fractional bin number greater or equal to zero and LESS THAN the maximum number of bins. The integer part determines the index of the value below the value to be interpolated, and the fractional part determines the interpolation between the indexed bin, and the next. This determines where to find the entry for the input (truth) variables.

The code should loadable by dlopen, so it needs be compiled with (at least)

gcc -fPIC -rdynamic --shared -o <LibraryName>.so <source>

Testing

There are basic tests added to the fast-test. The main check is to verify that the cached Propagator event weight calculation correctly reproduces the Cache::Manager calculation so that fits can be done on CPU only machines.

nadrino commented 3 months ago

Excellent! Let's talk about this tomorrow if we got the time 😄