/**********************************************************************
 *
 *   The include file for the JEMX shared library JEMXLIB
 *
 *   2004-10-26   Version 1.0
 *
 *   Holds contributions from
 *           Sami Maisala, University of Helsinki
 *           Peter Kretschmar, ISDC, Switzerland,
 *           and Niels J. Westergaard, Danish Space Research Institute
 *
 **********************************************************************/
#include <stdio.h>
#include <isdc.h>
#include <dal3aux.h>

#define JEMXLIB_MAXNUMLISTIDX  11
#define JEMXLIB_SHDSIZE  65536
#define J_CHATTY_NORMAL  3
#define JEMX_MAX_USEFUL_RADIUS   118.0
#define JEMX_RAW_CENTER_X        127
#define JEMX_RAW_CENTER_Y        127
#define JEMXLIB_DETDIM_X           256
#define JEMXLIB_DETDIM_Y           256



/* Error codes 1-99 within the J_BKG_SCAL   range are for this executable */
  
#define JEMXLIB_ERROR_START                   (J_ERROR_CODE_START+JEMXLIB_ERR)
#define JEMXLIB_OUT_OF_MEMORY                 (JEMXLIB_ERROR_START - 1)
#define JEMXLIB_ILLEGAL_DETECTOR_NUMBER       (JEMXLIB_ERROR_START - 2)
#define JEMXLIB_ILLEGAL_INPUT_DATA            (JEMXLIB_ERROR_START - 3)
#define JEMXLIB_ILLEGAL_SIM_PARAMETER         (JEMXLIB_ERROR_START - 4)
#define JEMXLIB_INPUT_DATA_NOT_FOUND          (JEMXLIB_ERROR_START - 5)
#define JEMXLIB_HK_DATA_EMPTY                 (JEMXLIB_ERROR_START - 6)
#define JEMXLIB_MODEL_NOT_FOUND               (JEMXLIB_ERROR_START - 7)
#define JEMXLIB_MEM_ALLOC_ERROR               (JEMXLIB_ERROR_START - 8)
#define JEMXLIB_DIFFUSE_DATA_EMPTY            (JEMXLIB_ERROR_START - 9)
#define JEMXLIB_INSTRUMENT_DATA_EMPTY         (JEMXLIB_ERROR_START - 10)
#define JEMXLIB_CLOBBER_OFF                   (JEMXLIB_ERROR_START - 11)
#define JEMXLIB_HK_EXPOSURE_EMPTY             (JEMXLIB_ERROR_START - 12)
#define JEMXLIB_ILLEGAL_IMAGE_SIZE            (JEMXLIB_ERROR_START - 13)

#define JEMXLIB_OUT_OF_MEMORY                 (JEMXLIB_ERROR_START - 14)
#define JEMXLIB_BAD_DIMENSIONS                (JEMXLIB_ERROR_START - 15)
#define JEMXLIB_BAD_IMOD_DATA                 (JEMXLIB_ERROR_START - 16)

/*
 * Several bits and pieces of detector information are grouped in
 * one struct to keep function APIs shorter, while maintaining
 * flexibility in the future.
 * NOTE: the pixelArea values are in cm^2.
 */

typedef struct {
    double         area;
    unsigned short detMap[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y];
    double         CorX[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y];
    double         CorY[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y];
    double         pixelArea[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y];
    double         pixelLowerLeftX[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y];
    double         pixelLowerLeftY[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y];
} JEMXdetectorData;

/*
 *  The following definition is used in JEMXLIBdetGetRegPixels
 */

typedef struct {
       long   number[JEMXLIB_SHDSIZE];
       long   list_idx[JEMXLIB_SHDSIZE][JEMXLIB_MAXNUMLISTIDX];
       float  fraction[JEMXLIB_SHDSIZE][JEMXLIB_MAXNUMLISTIDX];
}  JEMXdetData;
       


/*
 *
 *      Function prototypes
 *
 */


int JEMXLIBdetGetRegPixels(
       dal_element  *ptr,
       long        rawPixelIndex,
       int         *number,
       long      *list_idx,
       float     *fraction,
       int       chatter,
       int       status );

int JEMXLIBdetMkRegShdA(
       char            *instMod,
       dal_element     *ptr_instMod,
       Instrument      jemx,
       long            numEvents,
       short           *rawx,
       short           *rawy,
       float           *regShd,
       int             chatter,
       int             status);

int JEMXLIBdetMkRegShdB(
       JEMXdetData   *detData,
       long          numEvents,
       short         *rawx,
       short         *rawy,
       float         *regShd,
       int           chatter,
       int           status);

int JEMXLIBinitDetData(
       char         *instMod,
       dal_element  *ptr_instMod,
       Instrument   jemxInst,
       JEMXdetData  *detData,
       int          chatter,
       int          status);



int JEMXLIBgetBkgmodels(
     dal_element *theSWG,                    /* Input SWG                          */
     float       **bkgSpatModel,             /* instrument bkg spatial model       */
     float       **dbgSpatModel,             /* diffuse  bkg spatial model         */
     short       **bkgSidxMap,               /* instrument bkg spectral index map  */
     short       **dbgSidxMap,               /* diffuse bkg spectral index map     */
     float       **bkgScalFact,              /* instrument bkg scaling factor      */
     float       **dbgScalFact,              /* diffuse bkg scaling factor         */
     float       **bkgSpecCat,               /* instrument bkg  spectrum catalogue */
     float       **dbgSpecCat,               /* diffuse bkg  spectrum catalogue    */
     char         bkgSpecCatIdx[DAL_FILE_NAME_STRING],
                                             /* instrument bkg cat. location string*/
     char         dbgSpecCatIdx[DAL_FILE_NAME_STRING],
                                             /* diffuse bkg cat. location string   */
     int         *numOBTvalues,              /* Num of OBT values in scaling factor*/
     OBTime      **OBTvaluesScal,            /* OBT values in scaling factor       */
     int         *numSpecCatBkg,             /* number of bkg spectras in catalogue*/
     int         *numSpecCatDbg,             /* number of dbg spectras in catalogue*/
     int          jemxNum,                   /* instrument numeber                 */
     int          chatty,                            
     int          status);


   


int JEMXLIBgetBkg(
    float      *bkgSpatModel,                 /* instrument bkg spatial model       */
    float      *dbgSpatModel,                 /* diffuse  bkg spatial model         */
    short      *bkgSidxMap,                   /* instrument bkg spectral index map  */
    short      *dbgSidxMap,                   /* diffuse bkg spectral index map     */
    float      *bkgScalFact,                  /* instrument bkg scaling factor      */
    float      *dbgScalFact,                  /* diffuse bkg  spectrum catalogue    */
    float      *bkgSpecCat,                   /* instrument bkg  spectrum catalogue */
    float      *dbgSpecCat,                   /* diffuse bkg  spectrum catalogue    */
    int         Xpos,                         /* input Xpos                         */
    int         Ypos,                         /* input Ypos                         */
    float      *BkgValue,                     /* output intrument bkg value         */
    float      *DbgValue,                     /* output diffuse bkg value           */
    int         chanMin,                      /* Lower limit - channel number       */
    int         chanMax,                      /* upper limit - channel number       */
    int         numOBTvalues,                 /* number of scaling factor rows      */
    int         numSpecCatBkg,                /* number of spectra in bkg catalogue */
    int         numSpecCatDbg,                /* number of spectra in dbg catalogue */
    int         numGTI,                       /* number of GTIs                     */
    OBTime      OBTstartSWG,                  /* OBT start value in the SWG         */
    OBTime     *OBTValuesScal,                /* Scaling factors OBT values         */
    OBTime     *GTIstart,                     /*  GTI start times                   */
    OBTime     *GTIstop,                      /*  GTI end times                     */
    int         onTime,                       /*  The effective exposure time       */
    int         chatty, 
    int         status); 




/* --- Functions for general purpose ------------------------ */

int JEMXarrayGet(dal_element     *group,
                 char            *arrayName,
                 dal_dataType     arrayType,
                 int              numAxes,
                 long            *dimAxes,
                 dal_element    **arrayPtr,
                 void           **array,
                 int              chatter,
                 int              callingStatus);

/* --- Functions to access IMOD data ------------------------ */

int JEMXdetectorGetMap(dal_element     *instModGrp,
                  Instrument       jemxInstr,
                  unsigned short   detMap[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  double          *onAxisArea,
                  int              chatter,
                  int              callingStatus);

int JEMXdetectorGetCorXY(dal_element *instModGrp,
                  Instrument   jemxInstr,
                  double       detCorX[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  double       detCorY[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  int          chatter,
                  int          callingStatus);

int JEMXdetectorPixelAreas(double detCorX[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  double detCorY[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  double pixelArea[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  double pixelLowLeftX[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  double pixelLowLeftY[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  int    chatter,
                  int    callingStatus);

int JEMXdetectorGetData(dal_element      *instModGrp,
                  Instrument        jemxInstr,
                  JEMXdetectorData *detector,
                  int               chatter,
                  int               callingStatus);

    
    
int JEMXdetectorCalcOnAxisArea(JEMXdetectorData  detector,
                  double            radiusLimit,
                  unsigned short    excludeFlags,
                  double           *area,
                  unsigned short    
                  usedMap[JEMXLIB_DETDIM_X][JEMXLIB_DETDIM_Y],
                  int               chatter,
                  int               callingStatus);
   
    

