//=//////////////////////////////////////////////////////////////////////
//=
//= creadparam            
//=
//= @file        creadparam.cxx
//= @desc        Reading of parameters file
//= @author      J C Gonzalez
//= @email       gonzalez@mppmu.mpg.de
//= @date        Thu May  7 16:24:22 1998
//=
//=----------------------------------------------------------------------
//=
//= Created: Thu May  7 16:24:22 1998
//= Author:  Jose Carlos Gonzalez
//= Purpose: Program for reflector simulation
//= Notes:   See files README for details
//=    
//=----------------------------------------------------------------------
//=
//= $RCSfile: creadparam.cxx,v $
//= $Revision: 1.35 $
//= $Author: MAGIC $ 
//= $Date: 2004-12-15 01:56:39 $
//=
//=//////////////////////////////////////////////////////////////////////


#include "creadparam.h"
#include "camera.h"      // Needed for MAX_NUMBER_OF_CTS

//  Here we define the global variables where the values from the
//  parameters file are stored.

static char **Input_filename;  //@< input filename
static char Starfield_filename[PATH_MAX_LENGTH]; //@< starfield input filename
static int Starfield_center[6]={0,0,0,0,0,0}; //@< center of the starfield FOV
                                              //@< RA(H,M,S) & DEC (D,M,S)
static char Data_filename[PATH_MAX_LENGTH];   //@< data filename
static char ROOT_filename[PATH_MAX_LENGTH];   //@< data filename
static char Loop_filename[PATH_MAX_LENGTH];   //@< special data filename
static char CT_geom_string[256];              //@< Contains geometry ids of CTs  
static int  CT_number = 1;                    //@< Number of CT
static char **QE_filename; //@< name of the qe file
static char NSB_directory[PATH_MAX_LENGTH];   //@< database for NSB
static char NSB_outer_directory[PATH_MAX_LENGTH];   //@< database for NSB
static int  Starfield_rotate = FALSE;         //@< switch on starfield rotation
static int ElecNoise = TRUE;                  //@< Will we add ElecNoise?
static float FADC_pedestal = 10.0;            //@< Value for FADC Pedestal
static float FADC_Noise_inner = 2.0;         //@< Value for FADC ElecNoise
static float FADC_Noise_outer = 2.0;         //@< Value for FADC ElecNoise
static float Digital_Noise = 0.0;            //@< Value for FADC  digital Noise
static float Trig_Noise = 0.3;                //@< Factor for Trigger ElecNoise
static int simulateNSB = TRUE;                //@< Will we simulate NSB?
static float meanNSB;           //@< NSB mean value (per pixel)
static int nphe2NSB=0;          //@< Number of phe from shower to do NSB simulation 
static float **qThreshold; //@< Threshold values
static int Individual_Thres = FALSE;
static float RiseDisc = -1.0;
static float SecureDisc = 7.0;
static long int Seeds[2]={69184,10406}; 
static int *Skip;
static int nSkip=0;
static int Data_From_STDIN = FALSE;
static int Write_All_Images = FALSE;
static int Write_McEvt  = TRUE;
static int Write_McTrig = FALSE;
static int Write_McFadc = FALSE;
static int Write_RawEvt = TRUE;
static int Select_Energy = TRUE;
static float Select_Energy_le = 0.0;           //@< GeV
static float Select_Energy_ue = 100000.0;      //@< GeV
static int Trigger_Scan = FALSE;
static int FADC_Scan = FALSE;
static int Trigger_Loop = FALSE;
static float Trigger_gate_length = 3.0;
static float Trigger_over_time = 0.25;
static float Trigger_response_ampl = 1.0;
static float Trigger_response_fwhm = 2.0;
static float Trigger_threshold[MAX_NUMBER_OF_CTS];
static int Trigger_multiplicity[MAX_NUMBER_OF_CTS];
static int Trigger_topology[MAX_NUMBER_OF_CTS];
static float Trigger_loop_lthres = 3.0;
static float Trigger_loop_uthres = 10.0;
static float Trigger_loop_sthres = 1.0;
static int Trigger_loop_lmult = 2;
static int Trigger_loop_umult = 10;
static int Trigger_loop_ltop = 0;
static int Trigger_loop_utop = 2;
static int FADC_shape = 0;
static float FADC_response_ampl = MFADC_RESPONSE_INTEGRAL;
static float FADC_response_fwhm = MFADC_RESPONSE_FWHM;
static int   FADC_shape_out = 0;
static float FADC_resp_ampl_out = MFADC_RESPONSE_INTEGRAL;
static float FADC_resp_fwhm_out = MFADC_RESPONSE_FWHM;
static float FADC_slices_per_ns = FADC_SLICES_PER_NSEC;
static int   FADC_slices_written = FADC_SLICES;
static float High_to_Low = 10.0;      //@< Low gain channel respct to High

static float sigma_x_spot = 0.; // Sigma in x and y (cm) for additional 
static float sigma_y_spot = 0.; // gaussian spread of the mirror spot.
                               
static float misp_x = 0.; // Mispointing in x 
static float misp_y = 0.; // Mispointing in y

static float trig_delay = 25.;  // Delay in ns between beginning of FADC
                                // time window and the trigger instant.

static float pmt_jitter = 0.25; // Time jitter in ns (sigma of gaussian)
                                // of the PMT (per phe)

static float CTcoor[MAX_NUMBER_OF_CTS][3]; 

static float m_fraction[MAX_NUMBER_OF_CTS];

static int   CalibrationRun = 0;  // > 0 if a calibration run has been chosen
static float lambda = 0.;         // Mean wavelength for photons of calibration pulses.
static float sigma_lambda = 0.;   // Sigma of wavelength distribution for calibration.
static float phot_per_pix = 0.;   // Average number of photons per inner pixel for calibration.
static float fwhm_time = 0.;      // Time spread (FWHM of gaussian) of calibration photons.
static int   nevents = 0;         // Number of events in calibration run.
static int   selected_pixel = -1; // Selected pixel: if >= 0 ==> only this pixel is filled! 

static int   gain_fluctuations = 1; // Is 0 if PMT gain fluctuations are disabled for signal
static int   noise_gain_fluctuations = 1; // Is 0 if PMT gain fluctuations are disabled for NSB noise

// Coordinates of CT locations, in centimeters, in the Corsika system.

void 
readparam(char * filename)
{
  char sign[] = GLUE_postp( PROGRAM, VERSION ); //@< initialize sign
  char line[LINE_MAX_LENGTH];    //@< line to get from the stdin
  char token[ITEM_MAX_LENGTH];   //@< a single token
  int i, j, k;                      //@< dummy counters
  float aux, aux1, aux2;                    //@< auxiliar variable
  int aux3, aux4;                    //@< auxiliar variable
  ifstream ifile;
  char filename_tmp[PATH_MAX_LENGTH];


  memset((char*)CT_geom_string, 0, sizeof(CT_geom_string));

  Input_filename = new char *[MAX_NUMBER_OF_CTS];
  QE_filename = new char *[MAX_NUMBER_OF_CTS];
  qThreshold = new float *[MAX_NUMBER_OF_CTS];

  for (int i = 0; i < MAX_NUMBER_OF_CTS; i++)
    {
      Input_filename[i] = new char[PATH_MAX_LENGTH];
      QE_filename[i] = new char[PATH_MAX_LENGTH];
      qThreshold[i] = new float[CAMERA_PIXELS];
      CTcoor[i][0] = 0.; CTcoor[i][1] = 0.; CTcoor[i][2] = 0.;
      m_fraction[i] = 1.;
    }

  // use cin or ifile (reading from STDIN or from parameters file?
  if ( filename != NULL )
    ifile.open( filename );

  // get signature
  if ( filename != NULL )
    ifile.getline(line, LINE_MAX_LENGTH);
  else
    cin.getline(line, LINE_MAX_LENGTH);
  line[strlen(SIGNATURE)] = '\0';
  strcpy(sign, line);
  cout<< '"' << sign << '"' << '\n';
  if (strcmp(sign, SIGNATURE) != 0) {
    cerr << "ERROR: Signature of parameters file is not correct\n";
    cerr << '"' << sign << '"' << '\n';
    cerr << "should be: " << SIGNATURE << '\n';
    exit(1);
  }

  // loop till the "end" directive is reached
  int is_end = FALSE;
  while (! is_end) {          

    // get line from file or stdin
    if ( filename != NULL )
      ifile.getline(line, LINE_MAX_LENGTH);
    else
      cin.getline(line, LINE_MAX_LENGTH);

    // skip comments (start with '#')
    if (line[0] == '#')
      continue;

    // show user comments (start with '>')
    if (line[0] == '>') {
      cout << line << endl << flush;
      continue;
    }

    // look for each item at the beginning of the line
    for (i=0; i<=end_file; i++) 
      if (strstr(line, ITEM_NAMES[i]) == line)
        break;
        
    // if it is not a valid line, just ignore it
    if (i == end_file+1) {
      cerr << "ERROR: Unknown token in [" << line << "]\n";
      exit(-1);
    }

    // case block for each directive
    switch ( i ) {

    case input_file:          //@< name of the input file
          
      // get the name of the input_file from the line
      sscanf(line, "%s %i %s", token,&k, filename_tmp);
      if(k>99 || k<0){
	printf("ERROR :  The input_file command in input card is faulty. \n\t Most likely the control index for CT is missing.\n");
	exit(1);
      }
      strcpy(&Input_filename[k][0],&filename_tmp[0]);
      break;

    case starfield_file:         //@< name of the output file
          
      // get the name of the output_file from the line
      sscanf(line, "%s %s", token, Starfield_filename);

      break;

    case starfield_center:         //@< name of the output file
          
      // get the name of the output_file from the line
	sscanf(line, "%s %i %i %i %i %i %i", token, &Starfield_center[0], &Starfield_center[1], &Starfield_center[2], &Starfield_center[3], &Starfield_center[4], &Starfield_center[5]);

      break;
      
    case data_file:           //@< name of the data file
          
      // get the name of the data_file from the line
      sscanf(line, "%s %s", token, Data_filename);

      break;

    case root_file:          //@< name of the ROOT file
          
      // get the name of the data_file from the line
      sscanf(line, "%s %s", token, ROOT_filename);
      cout << '[' << ROOT_filename << ']' << endl << flush;

      break;

    case ct_num:             //@< number of telescopes
          
      // get the name of the ct_file from the line
      sscanf(line, "%s %i", token, &CT_number);

      break;

    case ct_geom:             //@< name of the telescope file
          
      // get the name of the ct_file from the line
      sscanf(line, "%s %s", token, CT_geom_string);
      if ( strlen(CT_geom_string) > MAX_NUMBER_OF_CTS )
	{
	  printf("\nError: ct_geom option read from input card wrong:\n");
	  printf("Number of digits (%d) is larger than maximum number\n",strlen(CT_geom_string) );
	  printf("of allowed telescopes (%d). Exiting.\n\n", MAX_NUMBER_OF_CTS);
	  exit(1);
	}

      break;

    case qe_file:             //@< name of the telescope file
          
      // get the name of the ct_file from the line
      sscanf(line, "%s %i %s", token, &k, filename_tmp);
      strcpy(&QE_filename[k][0],&filename_tmp[0]);

      break;

    case elec_noise_off:              //@< add ElecNoise?
          
      // we will not add electronic noise for FADC and Trigger channels.
      ElecNoise = FALSE;
      FADC_Noise_inner = 0.0;
      FADC_Noise_outer = 0.0;
      Trig_Noise =0.0;

      break;

    case fadc_pedestal:              //@< FADC pedestal
          
      // value for FADC Pedestal
      sscanf(line, "%s %f", token, &FADC_pedestal);
          
      //
      // A. Moralejo:
      // Require integer mean pedestal. Although it seems a silly
      // restriction, this saves lots of trouble (due to rounding 
      // happening in the FADC), particularly when running the
      // simulation with no noise (NSB or electronic):
      //

      if (fmod((double)FADC_pedestal, (double)1.) > 1.e-4)
      {
	  printf("ERROR :  requested average FADC pedestal (%f) is not integer. Please use an integer value.\n", FADC_pedestal);
	  exit(1);
      }

      break;

    case high_to_low:              //@< High to Low gain ratio
          
      // Value for the Low Gain channel respect to the High gain
      sscanf(line, "%s %f", token, &High_to_Low);
          
      break;

    case fadc_noise:              //@< FADC ElecNoise
          
      // value for FADC Elec Noise
      sscanf(line, "%s %f %f %f", token, 
	     &FADC_Noise_inner, &FADC_Noise_outer,
	     &Digital_Noise);

      ElecNoise = TRUE;
          
      break;

    case trig_noise:              //@< add ElecNoise?
          
      // factor for Trigger Elec Noise
      sscanf(line, "%s %f", token, &Trig_Noise);
      ElecNoise = TRUE;
          
      break;

    case sfr_on:              //@< simulate starfield rotation?
          
      // we will simulate Starfield rotation
      Starfield_rotate = TRUE;
          
      break;


    case nsb_on:              //@< simulate NSB?
          
      // we will simulate NSB
      simulateNSB = TRUE;
          
      break;

    case nsb_off:             //@< simulate NSB?
          
      // we will NOT simulate NSB
      simulateNSB = FALSE;
          
      break;

    case nsb_mean:            //@< value of <NSB> per pixel
          
      // get value of <NSB> (in photons)
      sscanf(line, "%s %f %d", token, &meanNSB, &nphe2NSB);

      break;

    case nsb_directory:         //@< name of the output file
          
      // get the name of the NSB diretory for inner pixels
      sscanf(line, "%s %s", token, NSB_directory);

      break;

    case nsb_dir_outer:         //@< name of the output file
          
      // get the name of the NSB diretory for outer pixels
      sscanf(line, "%s %s", token, NSB_outer_directory);

      break;

    case pixel_thres:           //@< value of threshold for trigger (q0)
          
      // get value of threshold (in ph.e.)
      sscanf(line, "%s %i %f", token,&k, &aux);
      if(k>99 || k<0){
	printf("ERROR :  The input_file command in input card is faulty. \n\t Most likely the control index for CT is missing.\n");
	exit(1);
      }
      qThreshold[0][k]=aux;
      Individual_Thres = TRUE;

      break;

    case secure_disc:           //@< value of secure threshold 
          
      // get value of secure threshold (in ph.e.)
      sscanf(line, "%s %f %f", token,&aux, &aux2);
      RiseDisc=aux;
      SecureDisc=aux2;

      break;

    case seeds:               //@< values of seeds for random numbers
          
      // get seeds
      sscanf(line, "%s %ld %ld", token, &Seeds[0], &Seeds[1]);

      break;

    case skip:                //@< skip pathological showers
          
      // get showers to skip
      cin >> nSkip;
      Skip = new int[nSkip];
      for (j=0; j<nSkip; ++j) {
        cin >> Skip[j];
        cout << Skip[j] << endl << flush;
      }

      break;

    case data_from_stdin:     //@< to read data from stdin
          
      // change boolean value
      Data_From_STDIN = TRUE;

      break;

    case write_all_events:    //@< to write ALL the images
          
      // change boolean value
      Write_All_Images = TRUE;

      break;

    case nowrite_McEvt:    //@< do not write the McEvt info
          
      // change boolean value
      Write_McEvt = FALSE;

      break;

    case write_McTrig:    //@< to write the McTrig info
          
      // change boolean value
      Write_McTrig = TRUE;

      break;

    case write_McFadc:    //@< to write the McFadc info
          
      // change boolean value
      Write_McFadc = TRUE;

      break;

    case nowrite_RawEvt:    //@< to write the McFadc info
          
      // change boolean value
      Write_RawEvt = FALSE;

      break;

    case select_energy:       //@< value of islands_cut (i0)
          
      // get energy range
      sscanf(line, "%s %f %f", token, &Select_Energy_le, &Select_Energy_ue);
      Select_Energy = TRUE;

      break;

    case fadc_scan:

      // change boolean value
      FADC_Scan = TRUE;

      break;

    case fadc_prop:

      //  Get parameters for the fadc  response for one phe
      sscanf(line, "%s %i %f %f", token, &FADC_shape, &FADC_response_ampl,&FADC_response_fwhm);

      break;

    case fadc_outer:

      //  Get parameters for the fadc  response for one phe
      sscanf(line, "%s %i %f %f", token, &FADC_shape_out, &FADC_resp_ampl_out,&FADC_resp_fwhm_out);

      break;

    case fadc_GHz:

      //  Get FADC sampling frequency in GHz (default 0.3)
      sscanf(line, "%s %f %i", token, &FADC_slices_per_ns, &FADC_slices_written);

      break;

    case trigger_scan:

      // change boolean value
      Trigger_Scan = TRUE;

      break;
    case trigger_prop:

      //  Get parameters for the diskriminator and the electronic
      //  response for one phe
      sscanf(line, "%s %f %f %f %f", token, &Trigger_gate_length,&Trigger_over_time, &Trigger_response_ampl,&Trigger_response_fwhm);

      break;

    case trigger_loop:

      //  Get loop's limits
      sscanf(line, "%s %f %f %f %d %d %d %d", token, &Trigger_loop_lthres, &Trigger_loop_uthres, &Trigger_loop_sthres, &Trigger_loop_lmult, &Trigger_loop_umult, &Trigger_loop_ltop, &Trigger_loop_utop );

      // Set qThreshold to a global value
      for(k=0;k<CAMERA_PIXELS;k++){
	qThreshold[0][k]=Trigger_loop_lthres;
      }

      // change boolean value
      Trigger_Loop = TRUE;
      Write_RawEvt = FALSE;
      Individual_Thres = FALSE;

      break;

    case trigger_single:

      //  Get trigger conditions
      sscanf(line, "%s %d %f %d %d", token, &j, &aux, &aux3, &aux4);
      if(j>99 || j<0){
	printf("ERROR :  The input_file command in input card is faulty. \n\t Most likely the control index for CT is missing.\n");
	exit(1);
      }
      Trigger_threshold[j]=aux;
      Trigger_multiplicity[j]=aux3;
      Trigger_topology[j]=aux4;

      // Set qThreshold to a global value
      for(k=0;k<CAMERA_PIXELS;k++){
	qThreshold[j][k]=Trigger_threshold[j];
      }

      // change boolean value
      Trigger_Loop = FALSE;
      Write_RawEvt = TRUE;
      Individual_Thres = FALSE;

      break;

    case Trigger_Loop_Output_Only_Specialists:

      // get the name of the data_file from the line
      sscanf(line, "%s %s", token, Loop_filename);
      cout << '[' << Loop_filename << ']' << endl << flush;
          
      // change boolean value
      Write_RawEvt = TRUE;
      
      break;

    case trigger_delay:

      sscanf(line, "%s %f", token, &trig_delay);
      break;

    case pmt_jitter_ns:

      sscanf(line, "%s %f", token, &pmt_jitter);
      break;


    case sigma_xy_cm_spot:

      sscanf(line, "%s %f", token, &sigma_x_spot);
      sigma_y_spot=sigma_x_spot;
      break;

    case sigma_x_cm_spot:

      sscanf(line, "%s %f", token, &sigma_x_spot);
      break;

    case sigma_y_cm_spot:

      sscanf(line, "%s %f", token, &sigma_y_spot);
      break;

    case misspoint_deg:

      sscanf(line, "%s %f %f", token, &misp_x, &misp_y);
      break;

    case telescope_location_cm:

      if ( 5 != sscanf(line, "%s %d %f %f %f", token, &j, &aux, &aux1, &aux2) )
	{
	  printf("\nError: wrong number of arguments for command telescope_location_cm.\n");
	  printf("Usage: telescope_location_cm ct_id x y z\n");
	  printf("Coordinates must be written in centimeters.");
	  printf("Exiting.\n\n");
	  exit(1);
	}

      if (j >= MAX_NUMBER_OF_CTS)
	{
	  printf("\nError: coordinates were supplied for a telescope index (%d)\n", j);
	  printf("larger than allowed. Valid telescope ids range from 0 to %d. Exiting.\n\n", MAX_NUMBER_OF_CTS-1);
	  exit(1);
	}
      CTcoor[j][0] = aux;
      CTcoor[j][1] = aux1;
      CTcoor[j][2] = aux2;

      break;

    case mirror_fraction:

      sscanf(line, "%s %d %f", token, &j, &aux);
      m_fraction[j] = aux;
	
      break;

    case calibration_run:

      sscanf(line, "%s %f %f %f %f %i %i", token, &lambda, &sigma_lambda, &phot_per_pix,
	     &fwhm_time, &nevents, &selected_pixel);
      
      CalibrationRun = 1;
      
      break;

    case gain_fluctuations_off:

      gain_fluctuations = 0;

      break;

    case noise_gain_fluctuations_off:

      noise_gain_fluctuations = 0;

      break;

    case end_file:            //@< end of the parameters file

      // show a short message
      is_end = TRUE;

      break;


    } // switch ( i ) 

  } // while (! is_end)

  // after the loop is finished, return to the main function
  return;
}
//!@}


//!-----------------------------------------------------------
// @name get_input_filename
//                                                
// @desc get name of the input file
//
// @return   Name of the Input file
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
char *
get_input_filename(int i)
{
  return (Input_filename[i]);
}
//!@}


//!-----------------------------------------------------------
// @name get_starfield_filename
//                                                
// @desc get name of the starfield input file
//
// @return   Name of the starfield file
//
// @date Tue Feb 15 16:02:18 CET 2000
//------------------------------------------------------------
// @function 

//!@{
char *
get_starfield_filename(void)
{
  return (Starfield_filename);
}
//!@}


//!-----------------------------------------------------------
// @name get_starfield_center
//                                                
// @desc get center of the starfield FOV
//
// @return   Central co-ordinates in RA and DEC for the centre of FOV
//
// @date Tue Feb 15 16:02:18 CET 2000
//------------------------------------------------------------
// @function 

//!@{
void get_starfield_center(int *rh,int *rm,int *rs,int *dd,int *dm,int *ds)
{
    *rh=Starfield_center[0];
    *rm=Starfield_center[1];
    *rs=Starfield_center[2];
    *dd=Starfield_center[3];
    *dm=Starfield_center[4];
    *ds=Starfield_center[5];
}
//!-----------------------------------------------------------
// @name get_starfield_rotate
//
// @Starfield_rotate
//
// @return   
//
//------------------------------------------------------------
// @function

//!@{
int  
get_starfield_rotate(void)
{
    return(Starfield_rotate);
}


//!@}
//!-----------------------------------------------------------
// @name get_data_filename
//                                                
// @desc get name of the data file
//
// @return   Name of the Data file
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
char *
get_data_filename(void)
{
  return (Data_filename);
}
//!@}


//!-----------------------------------------------------------
// @name get_root_filename
//                                                
// @desc get name of the ROOT file
//
// @return   Name of the ROOT file
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
char *
get_root_filename(void)
{
  return (ROOT_filename);
}
//!@}
//!-----------------------------------------------------------
// @name get_loop_filename
//                                                
// @desc get name of the special ROOT file
//
// @return   Name of the special ROOT file
//
// @date Fri Jun 23 17:34:19 CEST 2000
//------------------------------------------------------------
// @function 

//!@{

char *
get_loop_filename(void)
{
  return (Loop_filename);
}
//!@}

//!-----------------------------------------------------------
// @name get_ct_number
//                                                
// @desc get number of CT 
//
// @return   number of CT
//
// @date Tue Jul 29 01:48:26 CEST 2003
//------------------------------------------------------------
// @function 

//!@{
int 
get_ct_number(void)
{
  return (CT_number);
}
//!@}

//!-----------------------------------------------------------
// @name get_ct_geometry
//                                                
// @desc get geometry of CT
//
// @return   geometry of CT
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
int 
get_ct_geometry(int ict)
{
  char dummy[2];
  strncpy(dummy, &(CT_geom_string[ict]), 1);
  dummy[1] = '\0';

  return ((int)atoi(dummy));
}
//!@}

//!-----------------------------------------------------------
// @name get_qe_filename
//                                                
// @desc get name of QE definition file
//
// @return   Name of the QE definition file
//
// @date Thu Jul 10 14:10:13 CEST 2003 
//------------------------------------------------------------
// @function 

//!@{
char *
get_qe_filename(int ict)
{
  return (QE_filename[ict]);
}
//!@}

//!-----------------------------------------------------------
// @name get_nsb_directory
//                                                
// @desc get name of the directory where the database for NSB is
//
// @return   Name of the NSB directory
//
// @date Tue Jan 30 12:07:56 MET 2001
//------------------------------------------------------------
// @function 

//!@{
char *
get_nsb_directory(void)
{
  return (NSB_directory);
}
//!@}



//!-----------------------------------------------------------
// @name get_nsb_directory_outer
//                                                
// @desc get name of the directory where the database for NSB is
//
// @return   Name of the NSB directory for outer pixels
//
// @date Thu Jul 10 14:10:13 CEST 2003
//------------------------------------------------------------
// @function 

//!@{
char *
get_nsb_directory_outer(void)
{
  return (NSB_outer_directory);
}
//!@}



//!-----------------------------------------------------------
// @name add_elec_noise
//                                                
// @desc are we going to add the ElecNoise?
//
// @date Mon Jan 14 19:27:56 MET DST 2002
//------------------------------------------------------------
// @function 

//!@{
int
add_elec_noise(float *fadcinner, float*fadcouter, float *digi, float *trig)
{
  *fadcinner = FADC_Noise_inner;
  *fadcouter = FADC_Noise_outer;

  *digi = Digital_Noise;
  *trig = Trig_Noise;
  
  return ( ElecNoise);
}
//!@}

//!-----------------------------------------------------------
// @name get_nsb
//                                                
// @desc are we going to simulate NSB ?
//
// @var  *n  Mean value for the NSB (ph.e./pixel)
// @return   TRUE: we'll simulate NSB; FALSE: we won't
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
int
get_nsb(float *n, int *m)
{
  *n = meanNSB;
  *m = nphe2NSB;
  return ( simulateNSB );
}
//!@}


//!-----------------------------------------------------------
// @name get_threshold   
//                                                
// @desc get threshold value
//
// @return   Value of the threshold q$_0$
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
void 
get_threshold(float *t)
{
  for(int i=0;i<CAMERA_PIXELS;i++)
    t[i]=qThreshold[0][i];
}
//!@}

//!-----------------------------------------------------------
// @name get_secure_threhold
//                                                
// @desc get values for secure threshold.
//
// @return  AC (ac)value above which discriminator threshold rised to disc
//
// @date Wed Jul 18 16:29:43 CEST 2001
//------------------------------------------------------------
// @function 

//!@{
void 
get_secure_threhold(float *ac, float *disc)
{
  *ac=RiseDisc;
  *disc=SecureDisc;
}
//!@}

//!-----------------------------------------------------------
// @name get_indi_thres_pixel
//                                                
// @desc get boolean information about global (FALSE) or 
// @desc individual (TRUE) pixel trigger threshold
//
// @return   Value for the Individual_Thres
//
// @date Wed Jul 18 16:29:43 CEST 2001
//------------------------------------------------------------
// @function 

//!@{
int get_indi_thres_pixel(void){
  return  Individual_Thres;
}
//!@}


//!-----------------------------------------------------------
// @name get_seeds
//                                                
// @desc are we going to count the islands ?
//
// @var  *n  Number of the seed
// @return   N-th random-number Seed
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
long int
get_seeds(int n)
{
  return ( Seeds[n] );
}
//!@}


//!-----------------------------------------------------------
// @name get_skip_showers
//                                                
// @desc get list of showers to skip
//
// @var *s1  Pointer to a vector of number of showers
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
void 
get_skip_showers( int *s )
{
  int i;
  for (i=0; i<nSkip; ++i)
    s[i] = Skip[i];
}
//!@}


//!-----------------------------------------------------------
// @name get_nskip_showers
//                                                
// @desc get number of showers to skip
//
// @return  Number of showers to be skipped
//
// @date Mon Sep 14 13:27:56 MET DST 1998
//------------------------------------------------------------
// @function 

//!@{
int 
get_nskip_showers( void )
{
  return( nSkip );
}
//!@}


//!-----------------------------------------------------------
// @name get_data_from_stdin
//                                                
// @desc get whether we will read the data from the STDIN
//
// @return  TRUE: we'll read data from STDIN; FALSE: we won't
//
// @date Wed Nov 25 13:21:00 MET 1998
//------------------------------------------------------------
// @function 

//!@{
int
get_data_from_stdin(void)
{
  return ( Data_From_STDIN );
}
//!@}


//!-----------------------------------------------------------
// @name write_all_events
//                                                
// @desc write all images to .phe, even those without trigger
//
// @return  TRUE: we'll write everything; FALSE: we won't
//
// @date Wed Nov 25 13:21:00 MET 1998
//------------------------------------------------------------
// @function 

//!@{
int
get_write_all_events(void)
{
  return ( Write_All_Images );
}
//!@}

//!-----------------------------------------------------------
// @name write_McEvt
//                                                
// @desc write the McEvt class for each event to the .root file 
//
// @return  TRUE: we'll write it;  FALSE: we won't
//
//------------------------------------------------------------
// @function 

//!@{
int
get_write_McEvt(void)
{
  return ( Write_McEvt );
}
//!@}

//!-----------------------------------------------------------
// @name write_McTrig
//                                                
// @desc write the McTrig class for each event to the .root file 
//
// @return  TRUE: we'll write it;  FALSE: we won't
//
//------------------------------------------------------------
// @function 
 
//!@{
int
get_write_McTrig(void)
{
  return ( Write_McTrig );
}
//!@}

//!-----------------------------------------------------------
// @name write_McFadc
//                                                
// @desc write the McFadc class for each event to the .root file 
//
// @return  TRUE: we'll write it;  FALSE: we won't
//
//------------------------------------------------------------
// @function 
 
//!@{
int
get_write_McFadc(void)
{
  return ( Write_McFadc );
}
//!@}

//!-----------------------------------------------------------
// @name write_RawEvt
//                                                
// @desc write the RawEvt class for each event to the .root file 
//
// @return  TRUE: we'll write it;  FALSE: we won't
//
//------------------------------------------------------------
// @function 

//!@{
int
get_write_RawEvt(void)
{
  return ( Write_RawEvt );
}
//!@}

//!-----------------------------------------------------------
// @name get_select_energy                                      
//
// @desc return energy range allowed for showers from .phe file
//
// @var *le  Lower limit in the allowed energy range
// @var *ue  Lower limit in the allowed energy range
// @return  TRUE: we make selection on the energy; FALSE: we don't
//
// @date Wed Nov 25 13:21:00 MET 1998
//------------------------------------------------------------
// @function 

//!@{
int
get_select_energy(float *le, float *ue)
{
  *le = Select_Energy_le;
  *ue = Select_Energy_ue;
  return ( Select_Energy );
}
//!@}

//!-----------------------------------------------------------
// @name FADC_Scan
//                                                
// @desc show the FADC signal for each event in the screen 
//
// @return  TRUE: we'll show it;  FALSE: we won't
//
//------------------------------------------------------------
// @function 

//!@{
int
get_FADC_Scan(void)
{
  return ( FADC_Scan );
}
//!@}

//!-----------------------------------------------------------
// @name Trigger_Scan
//                                                
// @desc show the Trigger signal for each event in the screen 
//
// @return  TRUE: we'll show it;  FALSE: we won't
//
//------------------------------------------------------------
// @function 

//!@{
int
get_Trigger_Scan(void)
{
  return ( Trigger_Scan );
}
//!@}

//!-----------------------------------------------------------
// @name Fadc_Propeties
//                                                
// @desc fix properties of the FADC response 
//
//------------------------------------------------------------
// @function 

//!@{
void
get_FADC_properties(int *shape,float *ra, float *rf,
		    int *shapeo, float *rao, float *rfo, 
		    float *fadc_spns, int *fadc_slices)
{
  *shape = FADC_shape;
  *ra = FADC_response_ampl;
  *rf = FADC_response_fwhm;
  *shapeo = FADC_shape_out;
  *rao = FADC_resp_ampl_out;
  *rfo = FADC_resp_fwhm_out;
  *fadc_spns = FADC_slices_per_ns;
  *fadc_slices = FADC_slices_written;
}
//!@}

//!-----------------------------------------------------------
// @name Trigger_Propeties
//                                                
// @desc fix properties of the diskriminator and amplifier for Trigger 
//
//------------------------------------------------------------
// @function 

//!@{
void
get_Trigger_properties(float *gl, float *ot, float *ra, float *rf)
{
  *gl=Trigger_gate_length;
  *ot=Trigger_over_time;
  *ra=Trigger_response_ampl;
  *rf=Trigger_response_fwhm;

}
//!@}

//!-----------------------------------------------------------
// @name Trigger_Loop
//                                                
// @desc make a loop over Trigger conditions 
//
// @return  TRUE: we'll make it;  FALSE: we won't
//
//------------------------------------------------------------
// @function 

//!@{
int
get_Trigger_Loop(float *lt, float *ut, float *st, int *lm, int *um, int *lg, int *ug)
{
  *lt=Trigger_loop_lthres;
  *ut=Trigger_loop_uthres;
  *st=Trigger_loop_sthres;
  *lm=Trigger_loop_lmult;
  *um=Trigger_loop_umult;
  *lg=Trigger_loop_ltop;
  *ug=Trigger_loop_utop;
  return ( Trigger_Loop );
}
//!@}

//!-----------------------------------------------------------
// @name Trigger_Single
//                                                
// @desc fix Trigger conditions 
//
//------------------------------------------------------------
// @function 

//!@{
void
get_Trigger_Single(float **t, int *m, int *g)
{
  for(int j=0;j<MAX_NUMBER_OF_CTS;j++){
    for(int i=0;i<CAMERA_PIXELS;i++)
      t[j][i]=qThreshold[j][i];
    m[j]=Trigger_multiplicity[j];
    g[j]=Trigger_topology[j];
  }
}
//!@}

//!-----------------------------------------------------------
// @name get_FADC_pedestal
//                                                
// @desc get the value for the FADC pedestals
//
//------------------------------------------------------------
// @function 

//!@{


float get_FADC_pedestal(void){

  return FADC_pedestal;

}

//!@}
//!-----------------------------------------------------------
// @name get_High_to_Low
//                                                
// @desc get the conversion factor between high and low gain
//
//------------------------------------------------------------
// @function 

//!@{


float get_High_to_Low(void){

  return High_to_Low;

}

int get_misspointing(float *x, float *y){

  *x=misp_x;
  *y=misp_y;

  if (misp_x == 0.0 && misp_y==0.0)
    return 0;
  else 
    return 1;

}

float get_sigma_xy_cm_spot(float *x, float *y){

  *x=sigma_x_spot;
  *y=sigma_y_spot;

  if (sigma_x_spot > 0.0 || sigma_y_spot >0.0)
    return 1.0;
  else 
    return -1.0;

}

float get_trig_delay(void){

  return trig_delay;

}

float get_pmt_jitter_ns(){

  return pmt_jitter;

}

float get_telescope_location_cm(int j, int icoor){

  return CTcoor[j][icoor];

}

float get_mirror_fraction(int j){
    return m_fraction[j];
}

int is_calibration_run(){
  return CalibrationRun;
}

void  get_calibration_properties(float *a, float *b, float *c, float *d, int *e, int *f)
{
  *a = lambda;
  *b = sigma_lambda;
  *c = phot_per_pix;
  *d = fwhm_time / 2.35;  // Convert from FWHM to sigma of gaussian
  *e = nevents;
  *f = selected_pixel;
}

int apply_gain_fluctuations()
{
  return gain_fluctuations;
}
  
int apply_noise_gain_fluctuations()
{
  return noise_gain_fluctuations;
}
  

//=------------------------------------------------------------
//!@subsection Log of this file.

//!@{
//
// $Log: not supported by cvs2svn $
// Revision 1.34  2004/11/17 11:36:07  moralejo
// *** empty log message ***
//
// Revision 1.33  2004/10/26 13:58:59  moralejo
//
// Added option gain_fluctuations_off
//
// Revision 1.32  2004/10/14 16:53:49  moralejo
//
// Added option calibration_run
//
// Revision 1.31  2004/10/13 17:05:05  moralejo
// *** empty log message ***
//
// Revision 1.30  2004/10/12 13:32:02  moralejo
// *** empty log message ***
//
// Revision 1.29  2004/09/17 14:48:21  moralejo
//
// Changes to adapt headers to c++ style.
//
// Revision 1.28  2004/09/16 15:27:08  moralejo
// Updated in CVS after some time (see changes below)
//
//
// Revision 1.27  2004/05/12 A. Moralejo
//
// Changed fadc_noise command: now the two first numbers are respectively
// the analogic electronic noise for inner (small) and outer (big) pixels
// respectively. Last number is still the FADC digital noise which affects
// equallly inner and outer pixels (as well as high and low gain).
//
// Revision 1.26  2004/01/30 09:58:39  blanch
// [Changes done mainly by A. Moralejo]
//
// Two new commands of the input card have been added:
//
// sigma_xy_cm_spot: to enlarge the point spread function.
// trigger_delay: to center the FADC signal
//
// There is also a check that the Pedestal is an integer, otherwise it
// becames complex to get a reasonable rms for events without electronic noise.
//
// Revision 1.25  2003/10/26 19:45:38  blanch
// The write_all_data input card command has been removed.
//
// Revision 1.24  2003/10/17 19:40:24  blanch
// The gain ratio between the high and low FADC gain is controlled from the
// input card.
//
// Revision 1.23  2003/09/23 17:38:48  blanch
// ana_pixels command has been removed.
//
// Revision 1.22  2003/09/23 16:52:07  blanch
// We do not read ct_file anymore.
//
// Revision 1.21  2003/09/15 10:17:09  blanch
// Some modifications in the input card has been done for the multitelescope
// configuration.
//
// Revision 1.20  2003/07/17 18:04:53  blanch
// Some new parameters to be read have been introduced
//
// 	- FADC pedestals
// 	- Response outer FADC
// 	- Qe file
//
// The obsolete ones have been removed.
//
// Revision 1.19  2003/02/12 13:47:32  blanch
// *** empty log message ***
//
// Revision 1.18  2003/01/14 13:37:47  blanch
// Option to set a dc value to rise the discriminator threshold has been added.
//
// Revision 1.17  2002/07/16 16:20:41  blanch
// Modifications done for the camera.cxx version, where a first implementation
// of the Star Field Rotation has been introduced.
//
// Revision 1.16  2002/03/15 15:17:18  blanch
// Several modification needed to simulate the actual trigger zone.
//
// Revision 1.15  2002/03/04 17:15:51  blanch
// An item, which allows to switch off the storage of the RawEvt, has been
// introduced. It is called nowrite_RawEvt. To avoid confusion the item
// write_all_images has been moved to write_all_events.
//
// Revision 1.14  2002/02/28 15:07:23  blanch
// Small changes have been done to introduce thes step variable for the
// discriminator threshold in the trigger loop mode.
//
// Revision 1.13  2002/01/18 17:43:08  blanch
// Three new commands have been added: fadc_noise, trig_noise and
// elec_noise_off.
// A small bug in the SIGNATURE check has been solved.
//
// Revision 1.12  2001/11/13 17:05:14  blanch
// New input items int the input card parameter list have been included to fill
// the MMcRunHeader.
// There has been also some change to remove warnings in the compilation.
//
// Revision 1.11  2001/07/25 11:38:00  magicsol
// Minnor changes
//
// Revision 1.10  2001/07/19 09:28:30  blanch
// A new command, which allows to set individual trigger threshod for each pixel,
// has been added.
//
// Revision 1.9  2001/03/05 10:43:18  blanch
// New input commands have been added:
//
// 	- write_McFadc: to write the FADC simulation information.
// 	- fadc_prop: gives the shape of the single phe response of the FADC
//
// And new value has been added in the mean_NSB command that tells how many phes
// have to come from the shower to do the NSB simulation in that shower (it speeds
// up the simulation).
//
// Revision 1.8  2001/02/23 10:55:43  magicsol
// An input commmand that talls the path for the NSB database has been added.
//
// Revision 1.7  2001/01/15 12:37:48  magicsol
// It has been introduced the option to read from the input card the overlaping
// time.
//
// Revision 1.6  2000/09/21 11:47:33  harald
// Oscar found some smaller errors in the calculation of the pixel shape and
// corrected it.
//
// Revision 1.5  2000/07/04 14:13:02  MagicSol
// It reads from the general input card the parameters for the
// trigger analysi.
//
// Revision 1.4  2000/05/11 14:22:33  blanch
// New input card option has been introduced:
// 	trigger_loop lt ut lm um lg ug
// It forces the camera program to study several condition trigger implementations. Integers after key word fix limits of loop over thershold, multiplicity and topology.
//
// Revision 1.3  2000/03/24 18:14:05  blanch
// Parameters that tell as if we are going to see the diskriminator and/or FADC signal have been included.
//
// Revision 1.2  2000/02/18 17:45:43  petry
// This version belongs to camera.cxx 1.5.
// It has been put in the repository in order to be
// able to share the further development with others.
//
// If you need something working, wait or take an earlier one.
// See file README
//
// Revision 1.1.1.1  1999/11/05 11:59:34  harald
// This the starting point for CVS controlled further developments of the
// camera program. The program was originally written by Jose Carlos. 
// But here you can find a "rootified" version to the program. This means 
// that there is no hbook stuff in it now. Also the output of the
// program changed to the MagicRawDataFormat. 
//
// The "rootification" was done by Dirk Petry and Harald Kornmayer. 
//
// In the following you can see the README file of that version:
//
// ==================================================
//
// Fri Oct 22  1999   D.P.
//
// The MAGIC Monte Carlo System
//
// Camera Simulation Programme
// ---------------------------
//
// 1) Description
//
// This version is the result of the fusion of H.K.'s
// root_camera which is described below (section 2)
// and another version by D.P. which had a few additional
// useful features.
//
// The version compiles under Linux with ROOT 2.22 installed
// (variable ROOTSYS has to be set).
//
// Compile as before simply using "make" in the root_camera
// directory.
//
// All features of H.K.'s root_camera were retained.
//
// Additional features of this version are:
//
//   a) HBOOK is no longer used and all references are removed.
//
//   b) Instead of HBOOK, the user is given now the possibility of 
//      having Diagnostic data in ROOT format as a complement
//      to the ROOT Raw data.
//
//      This data is written to the file which is determined by
//      the new input parameter "diag_file" in the camera parameter
//      file.
//
//      All source code file belonging to this part have filenames
//      starting with "MDiag".
//
//      The user can read the output file using the following commands
//      in an interactive ROOT session:
//
//        	root [0] .L MDiag.so
// 	root [1] new TFile("diag.root");
// 	root [2] new TTreeViewer("T");
// 	
//      This brings up a viewer from which all variables of the
//      TTree can be accessed and histogrammed. This example
//      assumes that you have named the file "diag.root", that
//      you are using ROOT version 2.22 or later and that you have
//      the shared object library "MDiag.so" which is produced
//      by the Makefile along with the executable "camera".
//        
//  !   The contents of the so-called diag file is not yet fixed.
//  !   At the moment it is what J.C.G. used to put into the HBOOK
//  !   ntuple. In future versions the moments calculation can be
//  !   removed and the parameter list be modified correspondingly.
//
//   c) Now concatenated reflector files can be read. This is useful
//      if you have run the reflector with different parameters but
//      you want to continue the analysis with all reflector data
//      going into ONE ROOT outputfile.
//
//      The previous camera version contained a bug which made reading 
//      of two or more concatenated reflector files impossible.
//
//   d) The reflector output format was changed. It is now version
//      0.4 .
//      The change solely consists in a shortening of the flag
//      definition in the file 
//
//            include-MC/MCCphoton.hxx  
//
//  !   IF YOU WANT TO READ REFLECTOR FORMAT 0.3, you can easily
//  !   do so by recompiling camera with the previous version of
//  !   include-MC/MCCphoton.hxx.
//
//      The change was necessary for saving space and better
//      debugging. From now on, this format can be frozen.
//
//  !   For producing reflector output in the new format, you
//  !   of course have to recompile your reflector with the
//  !   new include-MC/MCCphoton.hxx .
//
//   e) A first version of the pixelization with the larger
//      outer pixels is implemented. THIS IS NOT YET FULLY
//      TESTED, but first rough tests show that it works
//      at least to a good approximation.
//
//      The present version implements the camera outline
//      with 18 "gap-pixels" and 595 pixels in total as
//      shown in 
//
//         http://sarastro.ifae.es/internal/home/hardware/camera/numbering.ps
//
//      This change involved 
//
// 	(i) The file pixels.dat is no longer needed. Instead
//           the coordinates are generated by the program itself
//           (takes maybe 1 second). In the file 
//
// 		pixel-coords.txt
//
// 	  in the same directory as this README, you find a list
//           of the coordinates generated by this new routine. It
//           has the format
//
//               number   i   j   x  y  size-factor
//
//           where i and j are J.C.G.'s so called biaxis hexagonal
//           coordinates (for internal use) and x and y are the
//           coordinates of the pixel centers in the standard camera
//           coordinate system in units of centimeters. The value
//           of "size-factor" determines the linear size of the pixel
//           relative to the central pixels. 
//
//         (ii) The magic.def file has two additional parameters
//           which give the number of central pixels and the
//           number of gap pixels
//
//         (iii) In camera.h and camera.cxx several changes were 
//           necessary, among them the introduction of several
//           new functions 
//
//      The newly suggested outline with asymmetric Winston cones
//      will be implemented in a later version.
//
//   f) phe files can no longer be read since this contradicts
//      our philosophy that the analysis should be done with other
//      programs like e.g. EVITA and not with "camera" itself.
//      This possibility was removed. 
//
//   g) ROOT is no longer invoked with an interactive interface.
//      In this way, camera can better be run as a batch program and
//      it uses less memory.
//
//   h) small changes concerning the variable "t_chan" were necessary in
//      order to avoid segmentation faults: The variable is used as an
//      index and it went sometimes outside the limits when camera
//      was reading proton data. This is because the reflector files
//      don't contain the photons in a chronological order and also
//      the timespread can be considerably longer that the foreseen
//      digitisation timespan. Please see the source code of camera.cxx
//      round about line 1090.
//
//   j) several unused variables were removed, a few warning messages
//      occur when you compile camera.cxx but these can be ignored at
//      the moment.
//
// In general the program is of course not finished. It still needs
// debugging, proper trigger simulation, simulation of the asymmetric
// version of the outer pixels, proper NSB simulation, adaption of
// the diag "ntuple" contents to our need and others small improvements.
//
// In the directory rfl-files there is now a file in reflector format 0.4
// containing a single event produced by the starfiled adder. It has
// a duration of 30 ns and represents the region around the Crab Nebula.
// Using the enclosed input parameter file, camera should process this
// file without problems.
//
// 2) The README for the previous version of root_camera
//
// README for a preliminary version of the 
// root_camera program. 
//
// root_camera is based on the program "camera"of Jose Carlos
// Gonzalez. It was changed in the way that only the pixelisation 
// and the distibution of the phe to the FADCs works in a 
// first version. 
//
// Using the #undef command most possibilities of the orignal 
// program are switched of. 
//
// The new parts are signed by 
//
// - ROOT or __ROOT__ 
//   nearly all  important codelines for ROOT output are enclosed 
//   in structures like 
//   #ifdef __ROOT__ 
//   
//     code 
//
//   #endif __ROOT__ 
//
//   In same case the new lines are signed by a comment with the word 
//   ROOT in it. 
//
//   For timing of the pulse some variable names are changed. 
//   (t0, t1, t  -->  t_ini, t_fin, t_1st, t_chan,...) 
//   Look also for this changes. 
//
//   For the new root-file is also a change in readparm-files
//
//
// - __DETAIL_TRIGGER__
//
//   This is for the implementation of the current work on trigger 
//   studies. Because the class MTrigger is not well documented it 
//   isnīt a part of this tar file. Only a dummy File exists. 
//
//
//
// With all files in the archive, the root_camera program should run. 
//
// A reflector file is in the directory rfl-files
//
// ==================================================
//
// From now on, use CVS for development!!!!
//
//
//
// Revision 1.2  1999/10/22 15:01:28  petry
// version sent to H.K. and N.M. on Fri Oct 22 1999
//
// Revision 1.1.1.1  1999/10/21 16:35:11  petry
// first synthesised version
//
// Revision 1.6  1999/03/15  14:59:08  gonzalez
// camera-1_1
//
// Revision 1.5  1999/03/02  09:56:12  gonzalez
// *** empty log message ***
//
// Revision 1.4  1999/01/14  17:32:41  gonzalez
// Added to camera the STDIN input option (data_from_input)
//
//!@}

//=EOF
