//=//////////////////////////////////////////////////////////////////////
//=
//= camera                
//=
//= @file        camera.h
//= @desc        Header 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: camera.h,v $
//= $Revision: 1.18 $
//= $Author: blanch $ 
//= $Date: 2003-09-15 10:06:47 $
//=
//=//////////////////////////////////////////////////////////////////////

// @T \newpage

//!@section Source code of |camera.h|.

/*!@"

  This section shows the include file |camera.h|

  @"*/

//=-----------------------------------------------------------
//!@subsection Include files.

//!@{

#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <libgen.h>
#include <time.h>

#include "camera-v.h"

#include "jcmacros.h"
#include "jcdebug.h"

#include "creadparam.h"
#include "moments.h"

#include "MCRunHeader.hxx"
#include "MCEventHeader.hxx"
#include "MCEventHeader_2.hxx"
#include "MCCphoton.hxx"
#include "MTrigger.hxx"

#include "MParContainer.h"
#include "MArray.h"

// command line options available

#define COMMAND_LINE_OPTIONS    "f:h"

/*@'

  This is C++, but RANLIB routines are written in pure ANSI C.
  In order to read easily these routines, we must include
  the following directive
  
*/

extern "C" { 
#include "ranlib.h"       
}

// version of the reflector program that can read

#define REFL_PROGRAM reflector
#define REFL_VERSION_A 0.4
#define REFL_VERSION_B 0.5
#define REFL_VERSION_C 0.6

const char REFL_SIGNATURE_A[] = GLUE_postp( REFL_PROGRAM, REFL_VERSION_A );
const char REFL_SIGNATURE_B[] = GLUE_postp( REFL_PROGRAM, REFL_VERSION_B );
const char REFL_SIGNATURE_C[] = GLUE_postp( REFL_PROGRAM, REFL_VERSION_C );

//!@}

//=------------------------------------------------------------
//!@subsection Macro-definitions, and constants.

//!@{

#define SLICES            19
#define WIDTH_TIMESLICE   3.3
 
#define NOTIME 9e+10

#define SIN60   0.866025403784439
#define COS60   0.500000000000000

#define RandomNumber  drand48()

#define iMAXNUMPIX  3500 // total maximum possible number of pixels in the camera

#define iMAXNUMPHE 50000 // maximum total number of photoelectrons in one event

#define iNUMNSBPRODCALLS 1  // in order to average over the QE simulation, call the
                            // phe production function for the NSB iNUMNSBPRODCALLS times

#define iNUMWAVEBANDS 5  // number of wavebands for the NSB simulation

#define WAVEBANDBOUND1 290. // iNUMWAVEBANDS+1 boundaries for waveband definitions (nm)
#define WAVEBANDBOUND2 310. // for the NSB generation
#define WAVEBANDBOUND3 400.
#define WAVEBANDBOUND4 500.
#define WAVEBANDBOUND5 600.
#define WAVEBANDBOUND6 800.

#define EXTWAVEBAND1 3.715  // iNUMWAVEBANDS extinction values in magnitudes per airmass
#define EXTWAVEBAND2 0.642  // - these values were taken from D.L. King, Isaac Newton Group
#define EXTWAVEBAND3 0.209  // Tech Note No. 31, they are for a clear night at the ORM,
#define EXTWAVEBAND4 0.107  // La Palma. The values were averaged in the given wavebands
#define EXTWAVEBAND5 0.053

#define SIMTIMEOFFSET_NS 5  // determines how many ns before the first and after the last
                            // shower photoelectron, there should be NSB photoelectrons 

//@ now we define the list CT_ITEM_LIST of possible items in the CT def. file
#define CT_ITEM_LIST  /* LIST OF ITEMS IN THE CT DEFINITION FILE */  \
T(type),              /* type of definition file */                  \
T(focal_distance),    /* std(focal distance) */                      \
T(focal_std),         /* focal distance */                           \
T(point_spread),      /* std(point spread)   */                      \
T(point_std),         /* point spread   */                           \
T(adjustment_dev),    /* std of adjustment deviation   */            \
T(black_spot),        /* radius of the black spot in center of mirror */ \
T(n_mirrors),         /* number of mirrors */                        \
T(r_mirror),          /* radius of one mirror */                     \
T(camera_width),      /* camera width */                             \
T(n_pixels),          /* total number of pixels in the camera */     \
T(n_centralpixels),   /* number of central pixels in the camera */   \
T(n_gappixels),       /* number of gap pixels in the camera */       \
T(pixel_width),       /* pixel width */                              \
T(define_mirrors)     /* this entry is followed by the def. of pixels */
  
#define T(x)  x               //@< define T() as the name as it is

enum CT_ITEM_TYPE {
  CT_ITEM_LIST
};

#undef T

#define T(x)  #x              //@< define T() as the string of x

const char *const CT_ITEM_NAMES[] = {
  CT_ITEM_LIST
};

#undef T


// TYPE=0  (CT1)
//     i   s   rho   theta   x   y   z   thetan  phin  xn   yn   zn
//
//      i : number of the mirror
//      s : arc length [cm]
//    rho : polar rho of the position of the center of the mirror [cm]
//  theta : polar angle of the position of the center of the mirror [cm]
//      x : x coordinate of the center of the mirror [cm]
//      y : y coordinate of the center of the mirror [cm]
//      z : z coordinate of the center of the mirror [cm]
// thetan : polar theta angle of the direction where the mirror points to
//   phin : polar phi angle of the direction where the mirror points to
//     xn : xn coordinate of the normal vector in the center (normalized)
//     yn : yn coordinate of the normal vector in the center (normalized)
//     zn : zn coordinate of the normal vector in the center (normalized)
//
// TYPE=1  (MAGIC)
//     i  f   sx   sy   x   y   z   thetan  phin 
//
//      i : number of the mirror
//      f : focal distance of that mirror
//     sx : curvilinear coordinate of mirror's center in X[cm]
//     sy : curvilinear coordinate of mirror's center in X[cm]
//      x : x coordinate of the center of the mirror [cm]
//      y : y coordinate of the center of the mirror [cm]
//      z : z coordinate of the center of the mirror [cm]
// thetan : polar theta angle of the direction where the mirror points to
//   phin : polar phi angle of the direction where the mirror points to
//     xn : xn coordinate of the normal vector in the center (normalized)
//     yn : yn coordinate of the normal vector in the center (normalized)
//     zn : zn coordinate of the normal vector in the center (normalized)

#define CT_I       0

#define CT_S       1
#define CT_RHO     2
#define CT_THETA   3

#define CT_FOCAL   1
#define CT_SX      2
#define CT_SY      3

#define CT_X       4
#define CT_Y       5
#define CT_Z       6
#define CT_THETAN  7
#define CT_PHIN    8
#define CT_XN      9
#define CT_YN     10
#define CT_ZN     11

#define CT_NDATA  12
 
//!@}

//=------------------------------------------------------------
//!@subsection data types

struct camera { /* camera parameters for imaging */
  int inumpixels;
  int inumcentralpixels;
  int inumgappixels;
  int inumbigpixels;
  double dpixdiameter_cm; /* diameter of the central and gap pixels in centimeters */
  double dpixsizefactor[iMAXNUMPIX]; /* size of the pixel relative to  dpixdiameter_deg */
  double dxc[iMAXNUMPIX]; /* Pixel coordinates in camera coordinate system (x points from pixel 1 to 2). */
  double dyc[iMAXNUMPIX]; /* The numbering of the pixels in these arrays starts at 0! */
  double dxpointcorr_deg; /* correction of the pixel coordinates; to be added to dxc[] to get correct value */
  double dypointcorr_deg; /* correction of the pixel coordinates; to be added to dxc[] to get correct value */
 
};

//=------------------------------------------------------------
//!@subsection Pre-defined file names.

//!@{

#define QE_FILE     "../Data/qe.dat"
#define WC_FILE     "../Data/lightguides.dat"

//!@}

//=------------------------------------------------------------
//!@subsection Prototypes of functions.

//!@{

//++
// prototypes
//--

#define ONoff(x)  ((x==TRUE) ? "[ ON ]" : "[ off]")

// Under Linux, the nint function does not exist, so we have to define it.
#define nint(x)  ((int)floor((x)+0.5))

void present(void);
void usage(void);
void clean(void);
void log(const char *funct, char *fmt, ...);
void error(const char *funct, char *fmt, ...);
int isA( char * s1, const char * flag );
void read_ct_file(void);
int igen_pixel_coordinates(struct camera *cam);
void read_pixels(struct camera *cam); 
void read_QE(char fname[256], int ict);
void read_WC(void);
void read_ascii( FILE *sp, // the input file
		 MMcConfigRunHeader *config
		 );
int pixels_are_neig(int pix1, int pix2);
int bpoint_is_in_pix(double dx, double dy, int ipixnum, 
		      MGeomCam *pcamgeom); 
float  dist_r_P(float a, float b, float c, 
                float l, float m, float n,
                float x, float y, float z);
int check_reflector_file(FILE *infile);
float lin_interpol(float x1, float y1, float x2, float y2, float x);
int produce_phes( FILE *sp, // the input file
		  class MGeomCam *camgeom, // the camera layout
		  float minwl_nm, // the minimum accepted wavelength
		  float maxwl_nm, // the maximum accepted wavelength
		  class MTrigger *trigger,
		  class MFadc *fadc,
		  int *itotnphe, // total number of produced photoelectrons
		  float *nphe, // number of photoelectrons in each pixel
		  int *incph,    // total number of cph read
		  float *tmin_ns,   // minimum arrival time of all phes
		  float *tmax_ns,    // maximum arrival time of all phes
		  int telescope      // Telescope that is being analised to get the right QE.
		  ); 

int produce_nsbrates( char *inname,
		      MGeomCam *camgeom,
		      float nsbrate[][iNUMWAVEBANDS],
		      int ict
		      );

int produce_nsb_phes( float *atmin_ns,
		      float *atmax_ns,
		      float theta_rad,
		      struct camera *cam,
		      float nsbr_phepns[iMAXNUMPIX][iNUMWAVEBANDS],
		      float dnsb_phepns[iMAXNUMPIX],
		      float extinction[iNUMWAVEBANDS],
		      float fnpx[iMAXNUMPIX],
		      class MTrigger *trigger,
		      class MFadc *fadc,
		      int *inphe,
		      float base_mv[iMAXNUMPIX]); 

int size_rotated ( float *rotated,
		   float nsb[iMAXNUMPIX],
		   float ro);

//!@}

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

//!@{

/*
 *$Log: not supported by cvs2svn $
 *Revision 1.17  2003/07/17 18:03:03  blanch
 *Header file for camera 1.57
 *
 *Revision 1.15  2003/01/07 16:34:09  blanch
 *Header file for camera.cxx version 1.50.
 *
 *Revision 1.14  2002/12/12 17:41:13  blanch
 **** empty log message ***
 *
 *Revision 1.13  2002/12/10 17:20:32  blanch
 **** empty log message ***
 *
 *Revision 1.12  2002/10/29 17:16:28  blanch
 *Header file for camera.cxx version 1.45
 *
 *Revision 1.11  2002/10/18 16:53:30  blanch
 *Modification to read several reflector version files.
 *
 *Revision 1.10  2002/09/09 16:01:12  blanch
 *Header file of camera.cxx 1.42.
 *
 *Revision 1.9  2002/09/04 09:59:07  blanch
 *Modifications to use MGeomCam from MARS.
 *
 *Revision 1.8  2002/07/16 16:20:23  blanch
 *Modifications done for the camera.cxx version, where a first implementation
 *of the Star Field Rotation has been introduced.
 *
 *Revision 1.7  2002/03/15 16:06:53  blanch
 *Library time.h has been added.
 *
 *Revision 1.6  2001/04/09 14:39:47  magicsol
 *Flag that indicates version of reflector format to read: REFL_VERSION has
 *changed from 0.3 to 0.4.
 *
 *Revision 1.5  2000/05/11 13:58:42  blanch
 *This version of camera.h owns to the version 1.8 of camera.cxx.
 *
 *Revision 1.4  2000/02/18 17:42:39  petry
 *This version includes drastic changes and belongs to camera.cxx 1.5.
 *It is not yet finished and not immediately useful because the
 *trigger simulation is not yet re-implemented. I had to take it
 *out together with some other stuff in order to tidy the whole
 *program up. This is not meant as an insult to anyone. I needed
 *to do this in order to be able to work on it.
 *
 *This version 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.3  1999/11/11 20:29:29  harald
 *Small changes to run the new version on a linux machine.
 *
 *Revision 1.2  1999/11/10 07:42:41  harald
 *Small change to read the right data files in.
 *
 *Revision 1.1.1.1  1999/11/05 11:59:31  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. 
 *
 *Revision 1.3  1999/10/22 15:32:56  petry
 *tidied-up version, really sent to H.K. and N.M., 22-10-99
 *
 *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:10  petry
 *first synthesised version
 *
 * Revision 1.8  1999/03/15  14:59:06  gonzalez
 * camera-1_1
 *
 * Revision 1.7  1999/03/02  09:56:11  gonzalez
 * *** empty log message ***
 *
 * Revision 1.6  1999/01/14  17:32:40  gonzalez
 * Added to camera the STDIN input option (data_from_input)
 *
 */

//!@}
//=EOF

