Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:15:05

0001 #include <stdio.h>
0002 #include <stdlib.h>
0003 #include <string.h>
0004 #include <cmath>
0005 #include <iomanip>
0006 #include <assert.h>
0007 #include <time.h>
0008 
0009 #ifndef __CINT__
0010 //#include "fftw3.h"

0011 ////#include <QtGui>

0012 //#  include <QSqlDatabase>

0013 //#  include <QSqlError>

0014 //#  include <QStringList>

0015 //#  include <QSqlQuery>

0016 //#  include <QSqlRecord>

0017 //#  include <QVariant>

0018 #endif
0019 
0020 #include <TROOT.h>
0021 #include <TSystem.h>
0022 #include <TCanvas.h>
0023 #include <TImage.h>
0024 #include <TGraph.h>
0025 #include <TGraphErrors.h>
0026 #include <TH1.h>
0027 #include <TH2.h>
0028 #include <TF1.h>
0029 #include <TF2.h>
0030 #include <TMath.h>
0031 #include <TStyle.h>
0032 #include <TRandom.h>
0033 #include "TMinuit.h"
0034 #include "TMultiGraph.h"
0035 
0036 
0037 #include "fitsio.h"
0038 #include "longnam.h"
0039 
0040 #include "fftw3.h"
0041 
0042 #include <iostream>
0043 #include <string>
0044 #include <vector>
0045 #include <map>
0046 #include <set>
0047 #include <algorithm>
0048 using namespace std;
0049 
0050 // GLOBALS ------------------------------------------------------------

0051 const double TwoPi = 2. * 3.14159265358979323846 ;
0052 const unsigned int T1995 = 788936400; //UTC time of 19950101 00:00

0053 const char * KeyList[] = {
0054         "CTIME", "USEC", "EXPOSURE", "EXPTIME","MONOWL",
0055         "AMP2.VOLTAGE", "AMP2.CURRENT", 
0056         "CRYO.A.TEMP", "CRYO.B.TEMP", "CRYO.C.TEMP", "CRYO.D.TEMP", "CRYO.1.SETPT",
0057         "MONOCH-WAVELENG", "MONOCH.WAVELENG",
0058         "AMP0.MEAS_NPLC",
0059         0
0060     };
0061     enum { Nkey = sizeof(KeyList)/sizeof(char*)-1 };
0062     vector <double>::iterator V_Iter;
0063     vector<double> Vval[Nkey];
0064 
0065 //---------------------------------------------------------------------

0066 // FFileDB class ---------------------------------------------------------

0067 //class FFileDB {

0068 //public:

0069 //  FFileDB( const string & d_name );

0070 //  ~FFileDB(){};

0071 //  int SelectFiles( void );

0072 //  set<string> GetFnames( void );

0073 //  void GetFparams();

0074 //  int get_dbOK()   { return dbOK;};

0075 //  int get_dataOK() { return dataOK;};

0076 //  int get_bitpix() { return bitpix;};

0077 //  int get_naxis()  { return naxis;};

0078 //    int get_naxis1() { return naxis1;};

0079 //  int get_naxis2() { return naxis2;};

0080 //private:

0081 //  const char *  DB_host;

0082 //  const char *  DB_name;

0083 //  const char *  DB_user;

0084 //  const char *  DB_pswd;

0085 //  const char *  TABLE_name; 

0086 //  const char *  SERVER_name;

0087 //#ifndef __CINT__

0088 //    QSqlDatabase db;

0089 //#endif

0090 //  static int dbOK;

0091 //  static int dataOK;

0092 //    static int bitpix;

0093 //  static int naxis;

0094 //  static int naxis1;

0095 //  static int naxis2;

0096 //  string dir_name;

0097 //  int Nfiles;

0098 //  set <string> FName;

0099 //};

0100 //

0101 //int FFileDB::dbOK = 0;

0102 //int FFileDB::dataOK = 0;

0103 //int FFileDB::bitpix = 0;

0104 //int FFileDB::naxis  = 0;

0105 //int FFileDB::naxis1 = 0;

0106 //int FFileDB::naxis2 = 0;

0107 //

0108 //FFileDB::FFileDB( const string & d_name ) : 

0109 //  DB_host ("localhost"),

0110 //  DB_name ("LSSTsensor"),

0111 //  DB_user ("ccdtest"),

0112 //  DB_pswd ("sensor"),

0113 //  TABLE_name ("TestInfo"), 

0114 //  SERVER_name ("mysql"),

0115 //  dir_name(d_name),

0116 //  Nfiles(0)

0117 //{

0118 //  char * driver = "QMYSQL";

0119 //  QSqlError err;

0120 //  int  cCount = 0;

0121 //  db = QSqlDatabase::addDatabase(driver, QString("Browser%1").arg(++cCount));

0122 //  db.setDatabaseName( DB_name );

0123 //  db.setHostName( DB_host);

0124 //

0125 //  cout << "MySQL CONNECTION: ------------------------------------" << endl;

0126 //  if ( !db.open(DB_user, DB_pswd) ) {

0127 //      err = db.lastError();

0128 //      db = QSqlDatabase();

0129 //      QSqlDatabase::removeDatabase(QString("Browser%1").arg(cCount));

0130 //      cout << err.text().toLocal8Bit().constData() << endl;

0131 //      return;

0132 //  }

0133 //  dbOK = 1;

0134 //  cout << "CONNECTED ------------------------------------" << endl;

0135 ////*******************************************************************

0136 //// DB is open

0137 //  QStringList t = db.tables();

0138 //  cout << "SQL TABLES: --------------------------------------" << endl;

0139 //  for (int i = 0; i < t.size(); ++i)

0140 //      cout << t.at(i).toLocal8Bit().constData() << endl;

0141 ////*******************************************************************

0142 //}

0143 //

0144 //int FFileDB::SelectFiles( void )

0145 //{

0146 //  char stmnt[200];

0147 //  Nfiles = 0;

0148 //  cout << "SQL: Select from FileLocation TABLE-------------------" << endl;

0149 //  sprintf(stmnt,"SELECT FileName FROM FileLocation WHERE DirName ='%s'", dir_name.c_str());

0150 //  cout << stmnt << endl;

0151 //  QSqlQuery query = db.exec(stmnt);

0152 //  QSqlRecord rec = query.record();

0153 //  QString qValue;

0154 //  while (query.next()) {

0155 //        qValue = query.value(0).toString();

0156 //        FName.insert(qValue.toLocal8Bit().constData()); // qValue.toString());

0157 //        Nfiles++;

0158 //        cout << Nfiles << ". " << qValue.toLocal8Bit().constData() << endl;

0159 //  }

0160 //  cout << "DB.Nfiles=" << Nfiles << endl;

0161 //  return Nfiles;

0162 //}

0163 //

0164 //set<string> FFileDB::GetFnames( void )

0165 //{

0166 //  string filename;

0167 //  set<string> CFiles;

0168 //  set<string>::iterator ii = FName.begin();

0169 //  for(; ii != FName.end(); ii++)

0170 //  {

0171 //       filename = dir_name + "/" + *ii + ".fits";

0172 //     CFiles.insert(filename);

0173 //  }

0174 //     return CFiles;

0175 //}

0176 //

0177 //void FFileDB::GetFparams()

0178 //{

0179 //  dataOK = 1;

0180 //  char stmnt[200];

0181 //  cout << "SQL: Select from TestInfo TABLE-------------------" << endl;

0182 //  set<string>::iterator it = FName.begin();

0183 //  for( ; it != FName.end(); it++)

0184 //  {

0185 //        sprintf(stmnt,"SELECT BITPIX, NAXIS, NAXIS1, NAXIS2 FROM TestInfo WHERE FileName ='%s'", it->c_str());

0186 //      cout << stmnt << endl;

0187 //      QSqlQuery query = db.exec(stmnt);

0188 //      QSqlRecord rec = query.record();

0189 //      //QString qValue;

0190 //      while (query.next()) {

0191 //          for (int j = 0; j <rec.count(); j++)

0192 //          {

0193 //              //qValue = query.value(j).toString();

0194 //              //qValue = query.value(j).toInt();

0195 //              int iValue = query.value(j).toInt();

0196 //              switch(j){

0197 //                  case 0:

0198 //                      if (!bitpix) bitpix = iValue;

0199 //                      else

0200 //                          if (bitpix != iValue){

0201 //                              printf("Error:: bitpix has new value %d\n", iValue);

0202 //                              dataOK = 0;

0203 //                          }

0204 //                        break;

0205 //                  case 1:

0206 //                      if(!naxis) naxis = iValue;

0207 //                      else

0208 //                          if (naxis != iValue){

0209 //                              printf("Error:: naxis has new value %d\n", iValue);

0210 //                              dataOK = 0;

0211 //                          }

0212 //                      break;

0213 //                  case 2:

0214 //                      if(!naxis1) naxis1 = iValue;

0215 //                      else

0216 //                          if (naxis1 != iValue){

0217 //                              printf("Error:: naxis1 has new value %d\n", iValue);

0218 //                              dataOK = 0;

0219 //                          }

0220 //                      break;

0221 //                  case 3:

0222 //                      if(!naxis2) naxis2 = iValue;

0223 //                      else

0224 //                          if (naxis2 != iValue){

0225 //                              printf("Error:: naxis2 has new value %d\n", iValue);

0226 //                              dataOK = 0;

0227 //                          }

0228 //                      break;

0229 //                  default:

0230 //                              printf("Error:: default for j=%i \n", j);

0231 //                              dataOK = 0;

0232 //                       break;

0233 //              } //end switch

0234 //          }  //end records  

0235 //      }  //end query

0236 //  }  //end files

0237 //} //end GetFparams()

0238 //

0239 
0240 //---------------------------------------------------------------------

0241 // DataStr class ---------------------------------------------------------

0242 class DataStr{
0243 private:
0244     static DataStr * pInstance;
0245 protected:
0246     double pixsz;
0247     int device;
0248     int xmin, xmax;   //"active" range

0249     int ymin, ymax;
0250     int NXpres, NYpres;       //pre-scan

0251     int NXover, NYover;
0252     int oxmin, oxmax;  //overscan range

0253     int oymin, oymax;
0254 
0255     DataStr (int nx, int ny);
0256     ~DataStr(){};
0257 public:
0258     static DataStr * Instance( int nx, int ny);
0259     double PixSz(){ return pixsz;}
0260     int minX(){ return xmin; }
0261     int maxX(){ return xmax; }
0262     int NoverX(){ return NXover; }
0263     int OmiXs(){ return (oxmin+8); }
0264     int OmiX(){ return oxmin; }
0265     int OmaX(){ return oxmax; }
0266     int minY(){ return ymin; }
0267     int maxY(){ return ymax; }
0268     int IsOver( int x, int y);
0269     int IsOverX( int x);
0270 };
0271 
0272 DataStr * DataStr::pInstance = 0;
0273 DataStr * DataStr::Instance(int nx, int ny)
0274 {
0275     //static DataStr inst (nx, ny);

0276     //return &inst;

0277     if ( pInstance == 0 ) {
0278         pInstance = new DataStr (nx,ny);
0279     }
0280     return pInstance;
0281 }
0282 
0283 DataStr::DataStr (int nx, int ny) 
0284 {
0285     device = -1;
0286     NYpres=0;
0287 
0288     // SIX device 2018

0289     if ( (nx == 3302) && (ny == 1612) ){
0290         pixsz = 16.;
0291         device = 3;
0292         NXpres = 1665;  //0;

0293         NXover = 1665;  //1665;

0294         NYpres = 1;
0295         NYover = 1;
0296         printf(" DataStr::DataStr device = XCAM \n");
0297         printf(" PixSz= %f device_id=%i \n", pixsz, device);
0298         xmin  = NXpres;
0299         xmax  = nx - 1;  // for SIX LS: nx-1;

0300         oxmin = 1;       // for SIX LS: 1

0301         oxmax = xmin;    // for SIX LS: xmin

0302         ymin  = NYpres;
0303         ymax  = ny - NYover;
0304         oymin = ymax;
0305         oymax = ny;
0306         return;
0307     }
0308     if ( (nx == 1652) && (ny == 1612) ){
0309         pixsz = 16.;
0310         device = 3;
0311         NXpres = 16;  //0;

0312         NXover = 1;  //1665;

0313         NYpres = 1;
0314         NYover = 1;
0315         printf(" DataStr::DataStr device = XCAM active area \n");
0316         printf(" PixSz= %f device_id=%i \n", pixsz, device);
0317         xmin  = NXpres;
0318         xmax  = nx - NXover;  // for SIX LS: nx-1;

0319         oxmin = 1;       // for SIX LS: 1

0320         oxmax = xmin-1;    // for SIX LS: xmin

0321         ymin  = NYpres;
0322         ymax  = ny - NYover;
0323         oymin = ymax;
0324         oymax = ny;
0325         return;
0326     }
0327     //Swiss Light Source Camera

0328     if ( (nx == 817) && (ny == 1606) ){
0329         pixsz = 10.;
0330         device = 4;
0331         NXpres = 1;
0332         NXover = 1;
0333         NYpres = 1;
0334         NYover = 1;
0335         printf(" DataStr::DataStr device = Swiss \n");
0336         printf(" PixSz= %f device_id=%i \n", pixsz, device);
0337         xmin  = NXpres;
0338         xmax  = nx - 1;  // for SIX LS: nx-1;

0339         oxmin = 1;       // for SIX LS: 1

0340         oxmax = xmin;    // for SIX LS: xmin

0341         ymin  = NYpres;
0342         ymax  = ny - NYover;
0343         oymin = ymax;
0344         oymax = ny;
0345         return;
0346     }
0347     
0348     // STA3800B

0349 //  if ( (nx == 544) && (ny == 2048) ){

0350 //      pixsz = 10.;

0351 //      device = 2;

0352 //      NXpres = 3;

0353 //      NXover = 32;

0354 //      NYover = 48;

0355 //      printf(" DataStr::DataStr device = STA3800B \n");

0356 //      printf(" PixSz= %f device_id=%i \n", pixsz, device);

0357 //  }

0358     
0359     // e2v CCD250 March 2017

0360 //    if ( (nx == 572) && (ny == 2048) ){

0361 //        pixsz = 10.;

0362 //        device = 1;

0363 //        NXpres = 10;

0364 //        NXover = nx-NXpres-512;

0365 //        if (NXover < 0) NXover=0;

0366 //        NYover = ny-2002;

0367 //        if (NYover < 0) NYover=0;

0368 //        printf(" DataStr::DataStr device = e2v CCD250 \n");

0369 //        printf(" PixSz= %f device_id=%i \n", pixsz, device);

0370 //    }

0371     
0372     if ( device < 0) {
0373         printf(" DataStr::DataStr - not recognized device, use default \n");
0374         pixsz = 10.;
0375         NXpres = 10;
0376         NXover = nx-NXpres-512;
0377         if (NXover < 0) NXover=0;
0378         NYover = ny-2002;
0379         if (NYover < 0) NYover=0;
0380         printf(" DataStr::DataStr default as e2v CCD250 %i (%i,%i) %i (%i,%i) \n", 
0381                         nx,NXpres,NXover, ny,NYpres,NYover);
0382         printf(" PixSz= %f device_id=%i \n", pixsz, device);
0383     }
0384 // calculate dev parameters

0385 
0386         xmin  = NXpres;
0387         xmax  = nx - NXover;  // - NXover;   for SIX LS: nx-1;

0388         oxmin = xmax;         //xmax;  for SIX LS: 1

0389         oxmax = nx;           //nx; for SIX LS: xmin

0390         ymin  = NYpres;
0391         ymax  = ny - NYover;  
0392         oymin = ymax;
0393         oymax = ny;
0394 
0395 } //end constructor DataStr

0396 
0397 int DataStr::IsOver( int x, int y)
0398 {
0399     if ( x >= oxmin &&
0400          x <= oxmax    ) {return 1;}
0401     if ( y >= oymin  &&
0402         y <= oymax     ) {return 1;}
0403     return 0;
0404 }
0405 
0406 int DataStr::IsOverX( int x)
0407 {
0408     if ( x >= oxmin &&
0409         x <= oxmax ) {return 1;}
0410 //  if ( x <  xmin ) return 1;

0411     else {return 0;}
0412 }
0413 
0414 //---------------------------------------------------------------------

0415 // FileF class ---------------------------------------------------------

0416 class FileF{
0417 public:
0418     const char * fname;
0419     fitsfile *fptr;
0420     fitsfile *fout;
0421     int iEOF;
0422     int Nhdu;
0423     int hdu;
0424     int hdutype;
0425     enum { MaxP = 22 };         // Max number of hdu (channels/amplifiers)

0426 
0427     long * buffer;
0428 //  unsigned short * buffer;

0429 //  vector<unsigned short> buffer; 

0430 
0431     static unsigned short nullval; 
0432     int anynull;
0433     char strnull[10];
0434     int status;
0435     char comment[FLEN_CARD];
0436     int bitpix; 
0437     double bzero;
0438     double bscale;
0439     int naxis;
0440     enum { MAXIS = 10 };
0441     long naxes[MAXIS];
0442     long nx, ny;
0443     unsigned long npixels;    /* number of pixels in the image */
0444     const long fpixel;
0445     unsigned short datamin;
0446     unsigned short datamax;
0447 
0448     static const int klength;
0449     static const char valuebegin;
0450     static const char valuend;
0451     int Ncards;
0452     enum { Lcard = FLEN_CARD };
0453     char card[Lcard];
0454     char value_str[Lcard];
0455     char keyword[Lcard];
0456     double value;
0457     
0458     double ltv1;
0459     double ltv2;
0460     double ltm1_1;
0461     double ltm1_2;
0462     double ltm2_1;
0463     double ltm2_2;
0464     
0465     typedef pair <string, double> H_Pair;
0466     map <string, double>::iterator H_Iter;
0467     std::pair<map <string, double>::iterator, bool> pptr;
0468     map <string, double> mHeader;
0469 
0470 // table variables

0471     int lTable;                 // 1= good table

0472     char TableName[FLEN_VALUE];
0473     int  ncols;
0474     static long nrows;
0475     enum { NbCol = 2 };         // number of columns

0476     char * ColName[NbCol];
0477     static vector<double> TabData[NbCol];
0478     static const char * FieldName[NbCol];
0479 
0480 public:
0481     FileF ();
0482     ~FileF();
0483     int Open( const char * file_name );
0484     void Close();
0485     int Read(int copy =0);
0486     void PrimeOut (long Nx, long Ny );
0487     void CloseOut ();
0488     int OpenOutF ( const char * fOutName = "Out_bufzs" );
0489     int OutFitsF( unsigned short * buf);
0490     int getValue( const char * name, double * value );
0491 //  vector<unsigned short> &Pbuf()  {return buffer;};

0492 //  unsigned short * Pbuf()  {return buffer;};

0493     void PrintKeys( void );
0494 };
0495 
0496 // initialization of static members

0497 unsigned short FileF::nullval  = 0;  // don't check for null values in the image 

0498 const int  FileF::klength = 8;
0499 const char FileF::valuebegin = '=';
0500 const char FileF::valuend = '/';
0501 const char * FileF::FieldName[NbCol]={"TIMES","CURRENT"}; 
0502 long FileF::nrows;
0503 vector<double> FileF::TabData[NbCol];
0504 
0505 FileF::~FileF(){
0506 //    delete [] buffer; buffer = 0; 

0507         for (int i = 0; i < NbCol; i++) {      /* deallocate space for the column labels */
0508             delete [] ColName[i]; ColName[i]=0; 
0509             //delete [] TabData[i]; TabData[i]=0;

0510         }
0511 }
0512 
0513 FileF::FileF ():
0514     fptr(0),
0515     buffer(0),
0516     anynull(0),
0517     status(0),
0518     fpixel(1),
0519     datamin(65535),
0520     datamax(0),
0521     Ncards(0)
0522 {
0523     strcpy(strnull, " ");
0524     for (int i = 0; i < NbCol; i++) {      /* allocate space for the column labels */
0525         ColName[i] = new char[FLEN_VALUE];  /* max label length = 69 */
0526         memset(ColName[i], 0, FLEN_VALUE);
0527         //TabData[i]= new double[2500];

0528         //memset(TabData[i], 0, 2500*sizeof(double));

0529     }
0530 
0531 } //end constructor FileF

0532 
0533 
0534 int FileF::OpenOutF( const char * fOutName  )
0535 {
0536     status = 0;
0537     char foutname[200];
0538     strcpy (foutname, fOutName);
0539     strcat (foutname, ".fits");
0540     printf( " OpenOutF name = %s \n", foutname);
0541     
0542     remove(foutname);
0543     fits_create_file( &fout, foutname, &status); // create output FITS file

0544     if ( status ) {printf(" create_file status error: %i \n", status); return -6;}
0545     printf(" OpenOutF:: hdu=%i \n", fout->HDUposition);
0546     
0547     return 0;
0548 }
0549 
0550 void FileF::CloseOut ()
0551 {
0552     fits_close_file( fout, &status);
0553     if ( status ) printf(" CloseOut status error: %i \n", status);
0554 }
0555 
0556 void FileF::PrimeOut (long Nx, long Ny )
0557 {
0558     nx = Nx;
0559     ny = Ny;
0560 
0561     bitpix  =  16;  // 64-bit floating point values

0562     naxis   =  2;   // 2-dimensional image

0563     status = 0;
0564     bzero = 32768.0;
0565     bscale = 1.0;
0566     naxis   =  2;   // 2-dimensional image

0567     naxes[0] = nx;
0568     naxes[1] = ny;
0569     int channels =2;
0570     
0571     if (fits_create_img( fout, bitpix, 0,  NULL, &status))
0572         fits_report_error(stderr, status );
0573     if ( fits_update_key(fout, TINT, "BZERO", &bzero,"", &status) )
0574         fits_report_error(stderr, status );
0575     if ( fits_update_key(fout, TINT, "BSCALE", &bscale,"", &status) )
0576         fits_report_error(stderr, status );
0577     if ( fits_update_key(fout, TINT, "NEXTEND", &channels,"", &status) )
0578         fits_report_error(stderr, status );
0579 //    if ( fits_update_key(fout, TSTRING, "DATE", &sdate,"", &status) )

0580 //        fits_report_error(stderr, status );

0581     if ( fits_update_key(fout, TSTRING, "COMMENT", &comment,"", &status) )
0582         fits_report_error(stderr, status );
0583     printf(" primary header done \n");
0584 }
0585 
0586 int FileF::OutFitsF( unsigned short  * buf)
0587 {
0588     status = 0;
0589     npixels = nx*ny;
0590     char detector[] = "XCAM             ";
0591     char cname[10] = "Ch";
0592     
0593 // HEADER ----------------

0594     if (fits_create_img( fout, bitpix, naxis, naxes, &status)) {fits_report_error(stderr,status);}
0595     if ( fits_update_key(fout, TSTRING, "EXTNAME", cname,"Channel number", &status) )
0596         fits_report_error(stderr, status );
0597     if ( fits_update_key(fout, TDOUBLE, "BZERO", &bzero,"", &status) )
0598         fits_report_error(stderr, status );
0599     if ( fits_update_key(fout, TINT, "BITPIX", &bitpix,"BITS PER PIXEL", &status) )
0600         fits_report_error(stderr, status );
0601     if ( fits_update_key(fout, TDOUBLE, "BSCALE", &bscale,"", &status) )
0602         fits_report_error(stderr, status );
0603     if ( fits_update_key(fout, TSTRING, "DETECTOR", detector,"DETECTOR ID", &status) )
0604         fits_report_error(stderr, status );
0605     
0606 // DATA ---------------------------------------------------

0607 //    unsigned short * outb = new unsigned short[npixels];

0608 //  for (unsigned long i=0; i<npixels;i++)  {

0609 //      double amp = buf[i] + 100.;

0610 //      if (  amp < 0.) amp = 0.;

0611 //      if (  amp > 65535.) amp = 65535.;

0612 //      outb[i] = (unsigned short)amp;

0613 //  }

0614     fits_write_img( fout, TUSHORT, fpixel, npixels, buf, &status);
0615     if ( status ) {printf(" write_img status error: %i \n", status); return -6;}
0616     
0617     //delete [] outb;

0618     return 0;
0619 }
0620 
0621 void FileF::Close ()
0622 {
0623     fits_close_file (fptr, &status);
0624     delete [] buffer; buffer = 0;
0625 //       buffer.clear();

0626 }
0627 
0628 int FileF::Open( const char * file_name )
0629 {
0630     iEOF = 0;
0631     //fname = file_name;

0632     fits_open_file (&fptr, file_name, READONLY, &status);
0633     if (status) { printf(" FileF::Open::status error: %i  %s \n", status, file_name);
0634         status=0;
0635         return -1;
0636     }
0637     hdu = fptr->HDUposition + 1;   // get the current HDU number

0638     //fits_get_num_hdus(fptr, &Nhdu, &status);  //get number of HDUs

0639     //if (status) { printf(" FileF::Open::status:num_hdus error: %i \n", status);

0640     //  status=0;

0641     //  return -1;

0642     //} else { printf(" Number of HDUs: %i \n", Nhdu); }

0643     strcpy(TableName, " ");
0644 
0645     return 0;
0646 }
0647 
0648 int FileF::Read( int copy)
0649 {
0650     lTable=0;
0651     hdu = fptr->HDUposition + 1;   // get the current HDU number

0652     fits_get_hdu_type(fptr, &hdutype, &status);  // get the HDU type

0653 
0654 // main header -------------------------------------------------------------

0655     if (hdu == 1) {  // read keys of the main header

0656         mHeader.clear(); 
0657         int morekeys=0;
0658         fits_get_hdrspace( fptr, &Ncards, &morekeys, &status);
0659         if (status)  {printf( "FileF::ReadHeader status %i \n", status ); return -3;}
0660         if ( Ncards < 1) return -3;
0661         
0662         char * cr = 0;
0663         char * pdest =0;
0664         int lngth;
0665         int L;
0666         for (int ik=0; ik<Ncards; ik++){
0667             value=0.0;
0668             memset(card, '\0',Lcard);
0669             memset(value_str, '\0',Lcard);
0670             memset(keyword, '\0',Lcard);
0671 
0672             fits_read_record (fptr, ik+1, card, &status);
0673             if (status) {printf( "Read card %i status %i \n", ik, status ); return -3;}
0674 
0675             // keyword field

0676             lngth = klength;
0677             strncpy( keyword, card, lngth);
0678             cr = card + lngth + 1;  //move pointer to "behind the name" position

0679             L = lngth-1;
0680             while (L >= 0 && keyword[L]==' ') {keyword[L]='\0'; L--;}
0681             int cond =  strcmp( keyword, "COMMENT") && 
0682                         strcmp( keyword, "HISTORY") &&
0683                         strcmp( keyword, "SCRIPT")  && 
0684                         strcmp( keyword, "CONTINUE");
0685             if ( !cond ) continue;
0686             if ( !strcmp( keyword, "HIERARCH") ){
0687                    pdest = strchr( cr, valuebegin );
0688                    lngth = (int)( pdest - cr ); 
0689                    strncpy( keyword, cr, lngth);
0690                    keyword[lngth] = '\0';
0691                    cr += lngth + 1; // move to "behind the name" position

0692             }
0693             L = lngth-1;
0694             while (L >= 0 && keyword[L]==' ') {keyword[L]='\0'; L--;}
0695             
0696             // value field

0697            pdest = strchr( cr, valuend );
0698            if (pdest != 0) {
0699                lngth = (int)( pdest - cr );
0700                strncpy( value_str, cr, lngth);
0701                value_str[lngth]='\0';
0702                cr += lngth + 1; // move to "behind the name" position

0703            }
0704            else lngth = 0;
0705             
0706             L = lngth-1; 
0707             while (L >= 0 && value_str[L]==' ') {value_str[L]='\0'; L--;}
0708             lngth = L+1;
0709 
0710             cr = value_str;
0711             L = 0;
0712             while (L <lngth && value_str[L]==' ') {cr++; L++;} 
0713             lngth -= --L;
0714             strncpy( value_str, cr, lngth );
0715             value_str[lngth]='\0';
0716             
0717             if ( value_str[0] =='T' ) value = 1.0;
0718             else value = atof( value_str );
0719             pptr = mHeader.insert( H_Pair(keyword, value) );
0720             if (!pptr.second){
0721                 printf (" This key: %s already exists; attemted value %f \n", keyword, value);
0722             }
0723         }
0724         //PrintKeys();

0725     }
0726 
0727 // copy header

0728     if ( copy && (hdutype == IMAGE_HDU) ) {
0729         printf(" OutFitsF:: fptr.hdu=%i fout.hdu=%i \n", 
0730                             fptr->HDUposition, fout->HDUposition);  
0731         fits_copy_header( fptr, fout, &status);  //ffcphd

0732         if ( status ) {printf(" create_img status error: %i \n", status); return -6;}
0733         printf(" OutFitsF:: fout.hdu=%i \n", fout->HDUposition);  
0734     }
0735 
0736 // data ---------------------------------------------------------------

0737     
0738     naxis=0;
0739     if (hdutype == IMAGE_HDU)   
0740     {
0741         fits_get_img_param( fptr, MAXIS, &bitpix, &naxis, naxes, &status);
0742         if (status) {printf( "Get_img_param status %i \n", status ); return -5;}
0743         //printf(" NAXIS=%i naxes[0]=%ld naxes[1]=%ld \n", naxis, naxes[0], naxes[1]);

0744         
0745         // coordinate transformation parameters

0746         ltv1=ltv2 =0.;
0747         ltm1_1=ltm2_2= 1.;
0748         ltm1_2=ltm2_1= 0.;
0749         
0750         fits_read_key(fptr, TDOUBLE, "LTV1", &ltv1, 0, &status);
0751         if (status) {/*printf( "Get_LTV1_param status %i \n", status );*/ status=0;}
0752         
0753         fits_read_key(fptr, TDOUBLE, "LTV2", &ltv2, 0, &status);
0754         if (status) {/*printf( "Get_LTV2_param status %i \n", status );*/ status=0;}
0755         
0756         fits_read_key(fptr, TDOUBLE, "LTM1_1", &ltm1_1, 0, &status);
0757         if (status) {/*printf( "Get_LTM1_1_param status %i \n", status );*/ status=0;}
0758         
0759         fits_read_key(fptr, TDOUBLE, "LTM2_2", &ltm2_2, 0, &status);
0760         if (status) {/*printf( "Get_LTM2_2_param status %i \n", status );*/ status=0;}
0761         
0762         
0763         if ( naxis > 0 ) {
0764             nx = naxes[0];
0765             ny = naxes[1];
0766             npixels  = naxes[0] * naxes[1];       // number of pixels in the image 

0767             //if (buffer == 0) buffer = new unsigned short[npixels]; // buffer.resize(npixels,0);

0768             //fits_read_img ( fptr, TUSHORT, fpixel, npixels, &nullval,

0769             //                         &buffer[0], &anynull, &status);

0770 
0771             if (buffer == 0) {buffer = new long[npixels];} // buffer.resize(npixels,0);

0772             fits_read_img ( fptr, TLONG, fpixel, npixels, &nullval,
0773                                        &buffer[0], &anynull, &status);
0774             if (status) { printf( "Read_Img status %i \n", status ); return -5; }
0775         }
0776     }
0777 
0778     if (hdutype == BINARY_TBL)   
0779     {
0780         // get TableName from EXTNAME, example "AMP0.MEAS_TIMES"

0781         fits_read_key_str(fptr, "EXTNAME", TableName, NULL, &status);
0782 
0783         //printf("\nReading binary table %s from HDU %d:\n", TableName, hdu); 

0784 
0785         /* gets number of rows and columns */
0786         fits_get_num_rows(fptr, &nrows, &status) ;
0787         fits_get_num_cols(fptr, &ncols, &status); 
0788         //printf(" NRows = %i NCols = %i\n", nrows, ncols);

0789 
0790     /* read the column names from the TTYPEn keywords */
0791         int colnum[NbCol] = {0};
0792         long frow =1; 
0793         long felem=1; 
0794         int nfound;
0795         fits_read_keys_str(fptr, "TTYPE", 1, NbCol, ColName, &nfound, &status);
0796         //printf(" names found =%i Row  %10s %10s\n", nfound, ColName[0], ColName[1]);

0797         if ( nfound != NbCol ) goto BadTable;
0798 
0799         for (int i=0; i<NbCol; i++){
0800             if ( strstr(ColName[i], FieldName[0])) { colnum[0]=i+1;}
0801             if ( strstr(ColName[i], FieldName[1])) { colnum[1]=i+1;}
0802             TabData[i].assign(nrows,0.0);
0803         }
0804 
0805         /*  read columns */ 
0806         for (int i=0; i<NbCol; i++){
0807             int  typecode;
0808             long repeat, width;
0809             fits_get_coltype(fptr, colnum[i], &typecode, &repeat, &width, &status);
0810             fits_read_col(fptr, typecode, colnum[i], frow, felem, nrows, strnull, &TabData[i][0], &anynull,
0811                     &status);
0812         }
0813         if ( status ) {
0814             printf(" FileF::Read BINARY_TBL problem: status=%i \n", status);
0815             lTable=0; status = 0;
0816         } else {  lTable=1;}
0817 
0818         BadTable: ; //printf( "Jump over BadTable:%s nfound=%i\n", TableName, nfound); 

0819     }// end tbl if

0820     
0821     Nhdu = hdu; 
0822     fits_movrel_hdu( fptr, 1, NULL, &status);  // move to the next HDU

0823     //printf( " Movrel: %s Nhdu=%i hdu=%i status=%i \n", fname, Nhdu, hdu, status); 

0824     if ( status ) {status = 0; iEOF=1;}   // Reset normal error, == END_OF_FILE

0825     return 0;
0826 }
0827 
0828 int FileF::getValue ( const char * name, double * Value )
0829 {
0830     H_Iter =mHeader.find(name);
0831     if ( H_Iter == mHeader.end( ) ) {*Value=0.; return 1;}
0832     else {*Value= H_Iter->second; return 0; }
0833 
0834     return 1;
0835 }
0836     
0837 void FileF::PrintKeys (  )
0838 {
0839     int msize = mHeader.size();
0840     printf(" FileF::PrintKeys Ncards= %i MapSize= %i \n", Ncards, msize);
0841     int i=0;
0842     for (H_Iter=mHeader.begin(); H_Iter != mHeader.end(); H_Iter++, i++){
0843         string name = H_Iter->first;
0844         double val = H_Iter->second;
0845         printf(" %2i. %s:: %f \n", i, name.c_str(), val );
0846     }
0847     return;
0848 }
0849 
0850 //---------------------------------------------------------------------

0851 // FileList class ---------------------------------------------------------

0852 class FileList {
0853 public:
0854 
0855     string dir_name;
0856     string fname; 
0857     int Nfile;
0858     set <string> FName;
0859     set <string>::iterator FName_Iter;
0860 
0861 public:
0862     FileList ( string dir_name );
0863     ~FileList(){};
0864 };
0865 
0866 FileList::FileList ( string dir_nm ):
0867     Nfile(0)
0868 {
0869     printf(" FileList::dir_nm: %s \n", dir_nm.c_str());
0870     const char *afile;
0871     const char fstr[] = ".fits";
0872     const char * pdest = strstr( dir_nm.c_str(), fstr );
0873 
0874     if ( pdest != 0 ){
0875         FName.insert( dir_nm );
0876         Nfile++;
0877         printf(" FileList:: Single file %i: %s \n", Nfile, dir_nm.c_str());
0878     }
0879     else {    // list files from the directory -----------------------------

0880         void *dirp = gSystem->OpenDirectory(dir_nm.c_str());
0881         while( (afile = gSystem->GetDirEntry(dirp)) ) {
0882             pdest = strstr( afile, fstr );
0883             if ( pdest == 0 ) continue;
0884             fname = afile;
0885             fname = dir_nm + "/" + fname;
0886             FName.insert( fname );
0887             printf("  %i: %s \n", Nfile, fname.c_str());
0888             Nfile++;
0889         }
0890         printf(" FileList::Nfiles = %i \n", Nfile);
0891     }
0892 
0893     return;
0894 } //end FileList constructor

0895 
0896 
0897 
0898 //---------------------------------------------------------------------

0899 // FFT class ---------------------------------------------------------

0900 class FFT
0901 {  
0902 public:
0903 
0904     const char * FFTName;
0905     const int minData;  
0906     const int maxData;  
0907     const int minLine;  
0908     const int maxLine; 
0909     const int stepD;  
0910     const int stepL;  
0911 
0912     const int Nline;
0913     const int Ndata;
0914     const int Nfreq;
0915 
0916     double * inA;
0917     fftw_complex * outF;
0918     fftw_plan p1d;
0919 
0920     vector<double> Freq;
0921     vector<double> PSDs;
0922     enum {  MaxP = 20 };            
0923     vector<double> PSDav[MaxP];
0924 
0925     double * DaAv;
0926 
0927     TH1D * hbuf[4];
0928 
0929     int jb;
0930     int sbtr;
0931     const int kf;  //58 for rows 20130123

0932     const double Fk;
0933     const double Farg;
0934     const double Ak;
0935 
0936 public:
0937     FFT( const char * Name,
0938          const int minD,  const int maxD, 
0939          const int minL,  const int maxL, 
0940          const int stepD, const int stepL,
0941          const int FrInd=0, const double Afk=2. );
0942     void DTrans(double * buf, const int idu, int sub); 
0943     void Plot_FFT(const int Nch);
0944     ~FFT();
0945 }; //end FFT class

0946 
0947 FFT::~FFT()
0948 {
0949     fftw_free(inA);  inA = 0;
0950     fftw_free(outF); outF = 0;
0951     fftw_destroy_plan(p1d); p1d=0;
0952 
0953     delete [] DaAv; DaAv = 0;
0954 }
0955 
0956 void FFT::Plot_FFT( int Nch )
0957 {
0958      const float left_margin = (float)0.04;
0959      const float right_margin = (float)0.001;
0960      const float top_margin = (float)0.01;
0961      const float bot_margin = (float)0.04;
0962 
0963     if (Nch > MaxP) Nch=MaxP;
0964     const int Ncha=Nch;
0965     TCanvas * Tr[MaxP];
0966 for (int u=0; u<Ncha; u++){  //Nhdu

0967     int ich=u+1;
0968     char tiname[50];
0969     char PDFname[50];
0970     sprintf(tiname, "%s %i", FFTName, ich);
0971     sprintf(PDFname, "%s_%i.pdf", FFTName, ich);
0972      Tr[u] = new TCanvas( tiname, tiname, 200+4*u, 10+2*u, 800, 600);
0973      Tr[u]->SetBorderMode  (1);         //to remove border

0974      Tr[u]->SetLeftMargin  (left_margin);  //to move plot to the right 0.14

0975      Tr[u]->SetRightMargin (right_margin); //to move plot to the right 0.05

0976      Tr[u]->SetTopMargin   (top_margin);   //to use more space 0.07

0977      Tr[u]->SetBottomMargin(bot_margin);   //default

0978      Tr[u]->SetFrameFillColor(0);
0979      Tr[u]->Divide(1,1); 
0980 
0981 /***************** Plot Power Spectrum  *************/
0982      printf(" Start draw Power Spectrum for %s %i\n\n", FFTName, u);
0983      Tr[u]->cd(1);
0984      gPad->SetLogy();
0985      gPad->SetLogx();
0986 
0987      do {
0988          int Npsd = PSDav[ich].size();
0989          int Nfrq = Freq.size();
0990          printf(" RowPSD points =%i RowFreq size=%i *** \n", Npsd, Nfrq);
0991          if ( Npsd <= 3 ) continue;
0992          int nn = Npsd -3;
0993          if ( Nfrq < nn ) continue;
0994          TGraph * std6 = new TGraph( nn, &Freq[0], &PSDav[ich][0]);
0995          std6->SetTitle(FFTName);
0996          std6->GetYaxis()->SetTitle("PSD ");
0997          std6->GetXaxis()->SetTitle("k/N, 1/pixel");
0998          std6->SetMarkerColor(4);
0999          std6->SetMarkerStyle(21);
1000          std6->Draw("AP");
1001             // cout << "i" << " - " << "Freq" << " - " << FFTName << " PSD" << endl;

1002          //for (int i=0; i<Npsd; i++){

1003             // cout << i << ". - " << Freq[i] << " - " << PSDav[u][i] << endl;

1004          //}

1005      } while(0);
1006 
1007     Tr[u]->Update();
1008     Tr[u]->Print(PDFname);
1009 }
1010 
1011 /***************** Plot subtraction histos *************/
1012 
1013     TCanvas *   Tb = new TCanvas( "subtract", "subtract", 250, 20, 800, 600);
1014      Tb->SetBorderMode  (1);            //to remove border

1015      Tb->SetLeftMargin  (left_margin);  //to move plot to the right 0.14

1016      Tb->SetRightMargin (right_margin); //to move plot to the right 0.05

1017      Tb->SetTopMargin   (top_margin);   //to use more space 0.07

1018      Tb->SetBottomMargin(bot_margin);   //default

1019      Tb->SetFrameFillColor(0);
1020      Tb->Divide(2,2); 
1021 
1022     int Entry = (int)hbuf[0]->GetEntries();
1023     if ( Entry >1 ) {
1024         Tb->cd(1);
1025         gPad->SetLogy();
1026         gStyle->SetOptFit(1);
1027         hbuf[0]->Draw();
1028         hbuf[0]->Fit("gaus");
1029     }
1030     
1031     Entry = (int)hbuf[1]->GetEntries();
1032     if ( Entry >1 ) {
1033         Tb->cd(2);
1034         gPad->SetLogy();
1035         gStyle->SetOptFit(1);
1036         hbuf[1]->Draw();
1037         hbuf[1]->Fit("gaus");
1038     }
1039 
1040     Entry = (int)hbuf[2]->GetEntries();
1041     if ( Entry >1 ) {
1042         Tb->cd(3);
1043         gPad->SetLogy();
1044         hbuf[2]->Draw();
1045     }
1046 
1047     Entry = (int)hbuf[3]->GetEntries();
1048     if ( Entry >1 ) {
1049         Tb->cd(4);
1050         gPad->SetLogy();
1051         hbuf[3]->Draw();
1052     }
1053 
1054      return;
1055 } // end FFT::Plot_FFT

1056 
1057 FFT::FFT(const char * Name,
1058          const int minD, 
1059          const int maxD, 
1060          const int minL, 
1061          const int maxL, 
1062          const int stepDa,
1063          const int stepLi,
1064          const int FrInd,
1065          const double Afk ):
1066     FFTName(Name),
1067     minData(minD),  
1068     maxData(maxD),  
1069     minLine(minL),  
1070     maxLine(maxL), 
1071     stepD(stepDa),
1072     stepL(stepLi),
1073     Nline(maxLine-minLine),
1074     Ndata(maxData-minData),
1075     Nfreq(Ndata/2 + 1),
1076     jb(0),
1077     sbtr(0),
1078     kf(FrInd),
1079     Fk( (double)kf/(double)Ndata ),
1080     Farg(TwoPi * Fk),
1081     Ak(Afk)
1082 {
1083     int size = sizeof(double) * Ndata;
1084     int size2 = sizeof(fftw_complex) * Nfreq;
1085     inA = (double*) fftw_malloc(size);
1086     outF = (fftw_complex *)fftw_malloc(size2);
1087     p1d = fftw_plan_dft_r2c_1d(Ndata, inA, outF, FFTW_MEASURE);
1088 
1089     Freq.resize(Nfreq, 0.);
1090     for(int i =1; i < Nfreq; i++) { 
1091         Freq[i] = (double)i/Ndata;
1092     }
1093     PSDs.resize(Nfreq,0.);
1094     for(int i =0; i < MaxP; i++) {PSDav[i].resize(Nfreq,0.);}
1095 
1096     DaAv = new double [Ndata];
1097 
1098     char title[40];
1099     char titl2[40];
1100     sprintf(title, "buf in %i", Ndata);
1101     hbuf[0] = new TH1D(title,title, 400,-100.,300.);
1102     hbuf[0]->SetStats(1);
1103     sprintf(title, "buf out %i", Ndata);
1104     hbuf[1] = new TH1D(title,title, 400,-100.,300.);
1105     hbuf[1]->SetStats(1);
1106     sprintf(title, "Asub %i", Ndata);
1107     sprintf(titl2, "kf %i", kf);
1108     hbuf[2] = new TH1D(title,titl2, 80,-16.,16.);
1109     hbuf[2]->SetStats(1);
1110     sprintf(title, "WA %i", Ndata);
1111     hbuf[3] = new TH1D(title,titl2, 80,0.,20.);
1112     hbuf[3]->SetStats(1);
1113 }
1114 
1115 
1116 void FFT::DTrans(double * buf, const int idu, int sub)
1117 {
1118     sbtr = sub;
1119 //  FFT direct transform 

1120 
1121     //for (int k=0, iL=minLine; iL<maxLine; iL++, k++) {

1122     //  DaAv[k]=0.;

1123     //  jb = iL*stepL + minData*stepD;

1124     //  for (int iD=minData; iD<maxData; iD++) {

1125     //      DaAv[k] += buf[jb];

1126     //      jb += stepD;

1127     //  }

1128     //  DaAv[k] /= Ndata; 

1129     //}

1130 
1131     PSDs.clear();
1132     PSDs.resize(Nfreq, 0.);  
1133     for (int k=0, iL=minLine; iL<maxLine; iL++, k++) {
1134         jb = iL*stepL + minData*stepD;
1135         for (int j=0, iD=minData; iD<maxData; iD++, j++) {
1136             inA[j] = buf[jb];  // - DaAv[k];          

1137             jb += stepD;
1138         }
1139         fftw_execute(p1d);
1140 
1141         for(int i=1; i<Nfreq; i++) {  
1142             PSDs[i] += outF[i][0]*outF[i][0]+outF[i][1]*outF[i][1];  
1143         }
1144 
1145         if (sbtr) {
1146             double ReA = outF[kf][0]/Nfreq;  
1147             double ImA = outF[kf][1]/Nfreq;
1148             double WA = sqrt(ReA*ReA + ImA*ImA);
1149                    hbuf[3]->Fill( WA );
1150             //if ( WA > 0.000001) { ReA/=WA; ImA/=WA;}      

1151             jb = iL*stepL + minData*stepD;
1152             for (int j=0, iD=minData; iD<maxData; iD++, j++) {
1153                 double arg = Farg * j;
1154                 double A_subtr = (ReA*cos(arg) - ImA*sin(arg));  //Ak*

1155                 hbuf[0]->Fill( buf[jb] );
1156                 buf[jb] -= A_subtr; 
1157                 hbuf[1]->Fill( buf[jb] );
1158                 hbuf[2]->Fill( A_subtr );
1159                 jb += stepD;
1160             }
1161         }
1162     }
1163 
1164     double Norm = (double)Nfreq * (double)Nfreq * (double)Nline;
1165     int ind=idu;
1166     if (ind >= MaxP ) {ind=0;}
1167     for(int i =1; i < Nfreq; i++) {  
1168         PSDav[ind][i] += PSDs[i]/Norm; }
1169 
1170     return;
1171 } // end FFT::DTrans

1172 
1173 
1174 // other constants ++++++++++++++++++++++++++++++++++++++++++++++++++++

1175 const double eQ = 1.60217657;  //charge of electron in C*10**19

1176 const double gain[16] = {  // e2v-216 20170307

1177     2.898321,
1178     2.917557,
1179     2.912855,
1180     2.932351,
1181     2.919847,
1182     2.909128,
1183     2.941916,
1184     2.937061,
1185     3.003625,
1186     2.975065,
1187     2.975082,
1188     2.963982,
1189     2.922063,
1190     2.949454,
1191     2.927139,
1192     2.916869
1193 };
1194 
1195 struct SpectrResp {
1196     double wave;
1197     double Sresp;
1198     double qe;
1199 };
1200 const SpectrResp PDresp[] = {
1201     //wl(nm)    Sensitivity(A/W)    QE =1240*S/lambda

1202     { 200., 0.125,  0.775},
1203     { 210., 0.132,  0.779428571},
1204     { 220., 0.133,  0.749636364},
1205     { 230., 0.139,  0.749391304},
1206     { 240., 0.141,  0.7285},
1207     { 250., 0.133,  0.65968},
1208     { 260., 0.12,   0.572307692},
1209     { 270., 0.103,  0.473037037},
1210     { 280., 0.103,  0.456142857},
1211     { 290., 0.117,  0.500275862},
1212     { 300., 0.131,  0.541466667},
1213     { 310., 0.139,  0.556},
1214     { 320., 0.142,  0.55025},
1215     { 330., 0.149,  0.559878788},
1216     { 340., 0.154,  0.561647059},
1217     { 350., 0.153,  0.542057143},
1218     { 360., 0.154,  0.530444444},
1219     { 370., 0.154,  0.516108108},
1220     { 380., 0.164,  0.535157895},
1221     { 390., 0.179,  0.569128205},
1222     { 400., 0.189,  0.5859},
1223     { 420., 0.206,  0.608190476},
1224     { 440., 0.222,  0.625636364},
1225     { 460., 0.235,  0.633478261},
1226     { 480., 0.247,  0.638083333},
1227     { 500., 0.262,  0.64976},
1228     { 520., 0.275,  0.655769231},
1229     { 540., 0.286,  0.656740741},
1230     { 560., 0.297,  0.657642857},
1231     { 580., 0.311,  0.664896552},
1232     { 600., 0.321,  0.6634},
1233     { 620., 0.334,  0.668},
1234     { 640., 0.347,  0.6723125},
1235     { 660., 0.359,  0.674484848},
1236     { 680., 0.368,  0.671058824},
1237     { 700., 0.379,  0.671371429},
1238     { 720., 0.391,  0.673388889},
1239     { 740., 0.403,  0.675297297},
1240     { 760., 0.413,  0.673842105},
1241     { 780., 0.425,  0.675641026},
1242     { 800., 0.434,  0.6727},
1243     { 820., 0.445,  0.672926829},
1244     { 840., 0.459,  0.677571429},
1245     { 860., 0.469,  0.676232558},
1246     { 880., 0.48,   0.676363636},
1247     { 900., 0.491,  0.676488889},
1248     { 920., 0.5,    0.673913043},
1249     { 940., 0.512,  0.675404255},
1250     { 960., 0.522,  0.67425},
1251     { 980., 0.513,  0.649102041},
1252     {1000., 0.492,  0.61008},
1253     {1020., 0.439,  0.533686275},
1254     {1040., 0.354,  0.422076923},
1255     {1060., 0.244,  0.285433962},
1256     {1080., 0.168,  0.192888889}
1257 };
1258 enum { Ncal = sizeof(PDresp)/sizeof(SpectrResp) };
1259 
1260 struct SpectrRatio {
1261     double wave;
1262     double ratio;
1263 };
1264 const SpectrRatio PDratio[] = {
1265     //wl  ratio

1266     {310.,  270.9},
1267     {320.,  271.6},
1268     {330.,  272.2},
1269     {340.,  272.9},
1270     {350.,  273.5},
1271     {360.,  274.8},
1272     {370.,  277.4},
1273     {380.,  279.5},
1274     {390.,  280.5},
1275     {400.,  281.6},
1276     {410.,  282.0},
1277     {420.,  282.2},
1278     {430.,  282.2},
1279     {440.,  282.3},
1280     {450.,  282.4},
1281     {460.,  282.4},
1282     {470.,  282.6},
1283     {480.,  282.6},
1284     {490.,  282.6},
1285     {500.,  282.7},
1286     {510.,  282.7},
1287     {520.,  282.8},
1288     {530.,  282.9},
1289     {540.,  282.9},
1290     {550.,  283.0},
1291     {560.,  283.0},
1292     {570.,  283.2},
1293     {580.,  283.4},
1294     {590.,  283.6},
1295     {600.,  283.8},
1296     {610.,  284.0},
1297     {620.,  284.0},
1298     {630.,  284.1},
1299     {640.,  284.3},
1300     {650.,  284.5},
1301     {660.,  284.7},
1302     {670.,  284.8},
1303     {680.,  284.9},
1304     {690.,  285.0},
1305     {700.,  285.1},
1306     {710.,  285.2},
1307     {720.,  285.4},
1308     {730.,  285.6},
1309     {740.,  285.9},
1310     {750.,  286.4},
1311     {760.,  286.3},
1312     {770.,  286.6},
1313     {780.,  286.8},
1314     {790.,  287.1},
1315     {800.,  287.3},
1316     {810.,  287.6},
1317     {820.,  287.6},
1318     {830.,  287.7},
1319     {840.,  288.0},
1320     {850.,  288.3},
1321     {860.,  288.4},
1322     {870.,  288.6},
1323     {880.,  288.9},
1324     {890.,  289.0},
1325     {900.,  289.3},
1326     {910.,  289.5},
1327     {920.,  289.8},
1328     {930.,  290.3},
1329     {940.,  291.5},
1330     {950.,  291.8},
1331     {960.,  291.1},
1332     {970.,  290.9},
1333     {980.,  289.9},
1334     {970.,  289.9},
1335     {1010., 287.9},
1336     {1020., 285.8},
1337     {1020., 282.7},
1338     {1030., 278.7},
1339     {1040., 273.7},
1340     {1060., 268.8},
1341     {1070., 265.0},
1342     {1080., 262.1},
1343     {1090., 260.6},
1344     {1090., 266.1},
1345     {1100., 262.0}
1346 };
1347 
1348 enum { Nratio = sizeof(PDratio)/sizeof(SpectrRatio) };
1349 
1350 double QEPD (double waw )
1351 {
1352     double QE;
1353     if (waw <= PDresp[0].wave)      {QE=PDresp[0].qe; return QE;}
1354     if (waw > PDresp[Ncal -1].wave) {QE=PDresp[Ncal-1].qe; return QE;}
1355     int i=0;
1356     for (; i<Ncal; i++){
1357         if (waw > PDresp[i].wave) continue;
1358         break;
1359     }
1360     double w1=PDresp[i-1].wave;
1361     double w2=PDresp[i].wave;
1362     double q1=PDresp[i-1].qe;
1363     double q2=PDresp[i].qe;
1364     QE = q1 + (q2-q1)*(waw-w1)/(w2-w1);
1365     //printf(" QEPD: waw=%f i=%i w1=%f w2=%f q1=%f q2=%f qe=%f \n",waw,i, w1,w2,q1,q2,QE );

1366     
1367     return QE;
1368 }
1369 
1370 double RaPD (double waw )
1371 {
1372     double Ra;
1373     if (waw <= PDratio[0].wave)        {Ra=PDratio[0]. ratio; return Ra;}
1374     if (waw > PDratio[Nratio -1].wave) {Ra=PDratio[Nratio-1]. ratio; return Ra;}
1375     int i=0;
1376     for (; i<Nratio; i++){
1377         if (waw > PDratio[i].wave) continue;
1378         break;
1379     }
1380     double w1=PDratio[i-1].wave;
1381     double w2=PDratio[i].wave;
1382     double q1=PDratio[i-1]. ratio;
1383     double q2=PDratio[i]. ratio;
1384     Ra = q1 + (q2-q1)*(waw-w1)/(w2-w1);
1385     //printf(" RaPD: waw=%f i=%i w1=%f w2=%f q1=%f q2=%f  ratio=%f \n",waw,i, w1,w2,q1,q2,Ra );

1386     
1387     return Ra;
1388 }
1389 
1390 //*********************************************************************

1391 int PeakRange(TH1D * hist, double * maxpos, double * Rmin, double * Rmax, double * maxV)
1392 {
1393     const double Fract = 0.04;
1394     int maxbin =    hist->GetMaximumBin();
1395     *maxpos =       hist->GetBinCenter(maxbin);
1396     double maxval = hist->GetBinContent(maxbin);
1397     *maxV = maxval;
1398     
1399     cout << " maxbin=" << maxbin << " maxval=" <<maxval <<endl;
1400     cout << " max/maxpos=" << *maxpos << endl;
1401     
1402     int bin = maxbin;
1403     while (bin>0 && hist->GetBinContent(bin) > Fract*maxval) bin--;
1404     *Rmin = hist->GetBinCenter(bin);
1405     cout << " Rmin=" << *Rmin << " A(Rmin)=" << hist->GetBinContent(bin) << endl;
1406     
1407     int xlast   = hist->GetXaxis()->GetLast();
1408     bin = maxbin;
1409     while (bin<xlast && hist->GetBinContent(bin) > Fract*maxval) bin++;
1410     bin++;
1411     *Rmax = hist->GetBinCenter(bin);
1412     cout << " Rmax=" << *Rmax << " A(Rmax)=" << hist->GetBinContent(bin) << endl;
1413     
1414     return 0;
1415 }
1416 
1417 //---------------------------------------------------------------------

1418 // PhotoDiode class ---------------------------------------------------------

1419 class PhDi {
1420 public:
1421     // canvas constants

1422     static const float left_margin;
1423     static const float right_margin;
1424     static const float top_margin;
1425     static const float bot_margin;
1426     
1427     static const int Npar;  //fit parameters

1428     
1429     // Photo Diode

1430     
1431     const int Nsets;
1432     const char * PDname;
1433     int Nf;
1434     int PDbad;
1435     double SiLe;
1436     double SiIn;
1437     int PDreads;
1438     double eTime;
1439     
1440     TCanvas *   PDh;
1441     int NXpad;
1442     int NYpad;
1443     
1444     vector<TGraph *> PDplot;
1445     vector<TH1D   *> PDhisB;
1446     vector<TH1D   *> PDhisS;
1447     vector<TF1    *> fitB;
1448     vector<TF1    *> fitS;
1449     TH1D   * PDdtm;
1450     TH1D   * PD_Int;
1451     
1452     
1453     vector<double> FileNb;
1454     vector<double> WaveL;
1455     vector<double> PDbase;
1456     vector<double> PDbw;
1457     vector<int>    PDstat;
1458     vector<double> SiL;
1459     vector<double> SiI;
1460     vector<double> SinT;
1461     vector<double> SiE;
1462     TGraph * SiLplot;
1463     TGraph * SiIplot;
1464     TGraph * SiEplot;
1465     
1466 public:
1467     PhDi ( int Nfiles, const char * PDn );
1468     ~PhDi(){};
1469     static double  Gauss ( double *v, double *par );  //fiting function

1470     double Integral( vector<double>::iterator first,
1471                     vector<double>::iterator last,
1472                     vector<double>::iterator point,
1473                     const double base,
1474                     const double b_rms,
1475                     int & readings,
1476                     vector<double> & Time,
1477                     double & iTime,
1478                     int & istat );
1479     void GetValue( int fNb, double wave, double time );
1480     void PlotData( void );
1481 };
1482 
1483 // initialization of static members

1484 const float PhDi::left_margin =  (float)0.06;
1485 const float PhDi::right_margin = (float)0.006;
1486 const float PhDi::top_margin =   (float)0.01;
1487 const float PhDi::bot_margin =   (float)0.04;
1488 const int   PhDi::Npar = 4;
1489 
1490 PhDi::PhDi( int Nfiles, const char * PDn ):
1491 Nsets(Nfiles),
1492 PDname(PDn)
1493 {
1494     NXpad = 7;
1495     NYpad = 7;
1496     // PD histos +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1497     PDh = new TCanvas( PDname, PDname, 80, 60, 900, 800);
1498     PDh->SetBorderMode  (0);      //to remove border

1499     PDh->SetLeftMargin  (left_margin);   //to move plot to the right 0.14

1500     PDh->SetRightMargin (right_margin);  //to move plot to the right 0.05

1501     PDh->SetTopMargin   (top_margin);    //to use more space 0.07

1502     PDh->SetBottomMargin(bot_margin);    //default

1503     PDh->SetFrameFillColor(0);
1504     PDh->Divide(NXpad,NYpad);
1505     PDh->SetFillStyle(4100);
1506     PDh->SetFillColor(0);
1507     PDh->Update();
1508     
1509     PDplot.resize(Nsets);  //assign(Nsets,0);

1510     PDhisB.resize(Nsets);  //assign(Nsets,0);

1511     PDhisS.resize(Nsets);  //assign(Nsets,0);

1512     fitB.resize(Nsets);  //assign(Nsets,0);

1513     fitS.resize(Nsets);  //assign(Nsets,0);

1514     PDbad=0;
1515     
1516     char hname[50];
1517     sprintf(hname, "%s time", PDname);
1518     PDdtm = new TH1D (hname, hname, 100, 0., 25.);
1519     PDdtm->SetStats(1);
1520     sprintf(hname, "%s integral", PDname);
1521     PD_Int = new TH1D (hname, hname, 1000, 0., 100.);
1522     PD_Int->SetStats(1);
1523     
1524     //FileNb.resize(Nsets,0.0);

1525     //PDbase.resize(Nsets,0.0);

1526     //PDstat.resize(Nsets,0);

1527     //SiL.resize(Nsets,0.0);

1528     //SiI.resize(Nsets,0.0);

1529     //SinT.resize(Nsets,0.0);

1530     //SiE.resize(Nsets,0.0);

1531     //WaveL.resize(Nsets,0.0);

1532     
1533     //for (int i=0; i<Nsets; i++) {FileNb.push_back(i);}

1534     
1535     printf("PhDi object %s is constructed for %i files \n", PDname, Nsets);
1536     printf("Number of PD calibration points %i  *** \n", Ncal);
1537     //Nsets=-1;

1538     
1539 }
1540 //----------------------------------------------------------------

1541 double  PhDi::Gauss ( double *v, double *par )
1542 {
1543     
1544     double x = v[0];
1545     double s1 = par[2];
1546     if (s1 < 0.000001) s1=0.000001;
1547     //double GNorm = 1./(TMath::Sqrt(2.*TMath::Pi())*s1);

1548     double argG1 = (x - par[1])/s1;
1549     double fitval = par[0]*TMath::Exp(-0.5*argG1*argG1);  //GNorm*

1550     return fitval;
1551 }
1552 //-----------------------------------------------------------------

1553 double PhDi::Integral(vector<double>::iterator first,
1554                       vector<double>::iterator last,
1555                       vector<double>::iterator point,
1556                       const double base,
1557                       const double b_rms,
1558                       int & readings,
1559                       vector<double> & Time,
1560                       double & iTime,
1561                       int & istate )
1562 {
1563     int indx;
1564     double ti;
1565     double Val = base - *point;
1566     double InT = 0.;
1567     double limit =  4.*abs(b_rms);
1568     if (abs(b_rms) < 0.0001 )  limit = 0.1*(base - *point);
1569     
1570     readings=0.;
1571     iTime=0.;
1572     istate=0;
1573     if (first == last) {PDbad++; return InT;}
1574     
1575     indx = std::distance(first,point);
1576     if (point==first)     {ti = Time[indx+1] - Time[indx]   ; }
1577     else if (point==last) {ti = Time[indx]   - Time[indx-1] ; }
1578     else                  {ti =(Time[indx+1] - Time[indx-1])/2.;}
1579     if (Val < limit) {PDbad++; return InT;}
1580     InT = Val*ti;
1581     
1582     vector<double>::iterator stop, start;
1583     start = stop = point;
1584     stop++;
1585     for (; stop <= last; stop++) {
1586         Val = base - *stop;
1587         if ( Val < limit) {stop--; break;}
1588         indx = std::distance(first,stop);
1589         if (stop==last) {ti = Time[indx]   - Time[indx-1] ;}
1590         else            {ti =(Time[indx+1] - Time[indx-1])/2.;}
1591         InT += Val*ti;
1592     }
1593     start--;
1594     for (; start >= first; start--) {
1595         Val = base - *start;
1596         if (Val < limit) {start++; break;}
1597         indx = std::distance(first,start);
1598         if (start==first) {ti = Time[indx+1] - Time[indx]   ;}
1599         else              {ti =(Time[indx+1] - Time[indx-1])/2.;}
1600         InT += Val*ti;
1601     }
1602     istate=1;
1603     int before = std::distance(first, start);
1604       readings = std::distance(start, stop) + 1;
1605     int after  = std::distance(stop,  last);
1606     if (before < 1) {istate=-1; PDbad++;}
1607     if (after  < 1) {istate=-2; PDbad++;}
1608     
1609     int ind_strt = std::distance(first,start);
1610     int ind_stop = std::distance(first,stop);
1611     iTime = Time[ind_stop] - Time[ind_strt];
1612     printf(" Integral: strt=%i pnt=%li stop=%i \n ",ind_strt, std::distance(first,point),  ind_stop);
1613     printf(" Integral: base=%f rms=%f limit=%f \n",base,b_rms,limit);
1614     
1615     return InT;
1616 }  //Integral

1617 
1618 void PhDi::GetValue( int fNb, double wave, double time )
1619 {
1620     Nf=fNb;
1621     SiLe=0.;
1622     SiIn=0.;
1623     PDreads =0;
1624     eTime = time;
1625     double inTime;
1626     int istat;
1627     
1628     char title[50];
1629     
1630     double maxpos;
1631     double Rmin;
1632     double Rmax;
1633     double maxVa;
1634     
1635     const char fitname[] = "fitGauss";
1636     int base_flag = 10;
1637     double position = 0.;
1638     double width    = 0.;
1639     double peak_tot = 0.;
1640     //*****************************************************************************

1641     if ( Nf >= Nsets ) return;
1642     WaveL.push_back(wave);  // [Nf] = wave;

1643     FileNb.push_back(Nf);
1644     
1645     printf("PhDi::%s file=%i wave=%f \n", PDname, Nf, WaveL[Nf]);
1646     
1647     // units conversion to pA

1648     for (int i=0; i<FileF::nrows; i++) {FileF::TabData[1][i] *= 1.0e+12;}
1649     
1650     vector<double>::iterator iTab = std::min_element(FileF::TabData[1].begin(), FileF::TabData[1].end());
1651     double min = *iTab;
1652     double max = *std::max_element(FileF::TabData[1].begin(), FileF::TabData[1].end());
1653     printf("GetValue: nfile=%i nrows=%li min=%f max=%f \n", Nf, FileF::nrows, min, max);
1654     
1655     //Calculate baseline(B) and signal(S) levels

1656     double middle = (max + min) / 2.;
1657     double numB = 0., AvB =0.;
1658     double numS = 0., AvS =0.;
1659     for(int i = 0; i < FileF::nrows; i++){
1660         if(FileF::TabData[1][i] >= middle){
1661             AvB += FileF::TabData[1][i]; numB++; }
1662         else{   AvS += FileF::TabData[1][i]; numS++; }
1663     }
1664     if (numB > 0) {AvB /= numB;}
1665     else {AvB =0.;}
1666     if (numS > 0) {AvS /= numS;}
1667     else {AvS=0.;}
1668     printf("GetValue: numB=%f AvB=%f numS=%f AvS=%f \n", numB, AvB, numS, AvS);
1669     //find range of histograms (max-rms1 and rms2-min)

1670     double dB = max - AvB;
1671     double dS = AvS - min;
1672     double rangeB = AvB - 2.*dB;
1673     double rangeS = AvS + 2.*dS;
1674     cout << "RANGEB= " << rangeB << "RANGES= " << rangeS << endl;
1675     
1676     sprintf(title, "PD_S %i", Nf);
1677     PDhisS[Nf] = new TH1D (title, title, 16, min-dS, rangeS);
1678     PDhisS[Nf]->SetStats(1);
1679     sprintf(title, "PD_B %i", Nf);
1680     PDhisB[Nf] = new TH1D (title, title, 20, rangeB, max);
1681     PDhisB[Nf]->SetStats(1);
1682     double dt;
1683     double time_read= 0.;
1684     printf("time::");
1685     for (int i=0; i<FileF::nrows; i++) {
1686         PDhisB[Nf]->Fill(FileF::TabData[1][i]);
1687         PDhisS[Nf]->Fill(FileF::TabData[1][i]);
1688         dt =  FileF::TabData[0][i] - time_read;
1689         time_read = FileF::TabData[0][i];
1690         if (i<10) printf(" %7.4f",  dt);  //   %7.4f  FileF::TabData[0][i],

1691         if (i==0) continue;
1692         PDdtm->Fill(dt*1000.);
1693     }
1694     printf(" \n");
1695     PDplot[Nf]  = new TGraph(FileF::nrows, &FileF::TabData[0][0], &FileF::TabData[1][0]);
1696     
1697     // get base line and signal levels

1698     ////b_shift = hs[ch_idx][1]->GetMean();

1699     ////b_rms   = hs[ch_idx][1]->GetRMS();

1700     ////printf (" OS: shift=%f rms=%f \n", b_shift, b_rms);

1701     
1702     //int Entry;

1703     //Entry = (int)PDhisB[Nf]->GetEntries();

1704     //cout<<"PD base entries =" << Entry << endl;

1705     PeakRange( PDhisB[Nf], &maxpos, &Rmin, &Rmax, &maxVa);
1706     cout << " maxpos=" << maxpos << " Rmin=" << Rmin << " Rmax" << Rmax <<endl;
1707     cout << endl;
1708     if ( maxVa>0. ) {
1709         
1710         if ( Nf < (NXpad*NYpad/2) ) {
1711             PDh->cd(1+2*Nf);
1712             gPad->SetFillStyle(4100);
1713             gPad->SetFillColor(0);
1714             //gPad->SetLogy();

1715             gPad->SetGrid(1,0);
1716             PDhisB[Nf]->SetLineColor(4);
1717             PDhisB[Nf]->Draw();
1718         } else { PDh->cd(NXpad*NYpad); }
1719         
1720         fitB[Nf] = new TF1(fitname, PhDi::Gauss, Rmin, Rmax, 3);
1721         fitB[Nf]->SetParameter(0, maxVa);
1722         fitB[Nf]->SetParameter(1, maxpos);
1723         fitB[Nf]->SetParameter(2, (Rmax - Rmin)/4.);
1724         cout << " par0=" << maxVa <<  endl;
1725         cout << " par1=" << maxpos << " par2=" << (Rmax - Rmin)/4. << endl;
1726         cout << "fitname=" << fitname << endl;
1727         
1728         base_flag = PDhisB[Nf]->Fit(fitname,"LR");  //NS

1729         peak_tot = fitB[Nf]->GetParameter(0);
1730         position = fitB[Nf]->GetParameter(1);
1731         width    = fitB[Nf]->GetParameter(2);
1732         printf (" PD base: peak_events=%f position=%f rms=%f fit_flag=%i \n",
1733                 peak_tot, position, width, base_flag);
1734         PDh->Update();
1735         
1736         SiLe = position;
1737         PDbase.push_back(position);
1738         PDbw.push_back(width);
1739     }
1740     
1741     SiIn = Integral( FileF::TabData[1].begin(), FileF::TabData[1].end(), iTab, PDbase[Nf], width, PDreads,
1742                     FileF::TabData[0], inTime, istat );
1743     SiIn /=eQ;  // in 10^-12 [C]/(eQ*10^-19)[C] = 10^7/eQ in e- => in 10^7 e- = in 10 Me-

1744     SiIn /=100.; // convert in Ge-

1745     SiI.push_back(SiIn);
1746     SiE.push_back(PDreads);
1747     SinT.push_back(inTime);
1748     PDstat.push_back(istat);
1749     PD_Int->Fill(SiIn);
1750     printf(" SiIn=%f readings=%i inTime=%f istat=%i \n", SiI[Nf], PDreads, inTime, istat);
1751     
1752     //    Entry = (int)PDhisS[Nf]->GetEntries();

1753     //    cout<<"PD base entries =" << Entry << endl;

1754     PeakRange( PDhisS[Nf], &maxpos, &Rmin, &Rmax, &maxVa);
1755     cout << " maxpos=" << maxpos << " Rmin=" << Rmin << " Rmax" << Rmax <<endl;
1756     cout << endl;
1757     if ( maxVa>0. ) {
1758         
1759         if ( Nf < (NXpad*NYpad/2) ) {
1760             PDh->cd(2+2*Nf);
1761             gPad->SetFillStyle(4100);
1762             gPad->SetFillColor(0);
1763             //gPad->SetLogy();

1764             gPad->SetGrid(1,0);
1765             PDhisS[Nf]->SetLineColor(4);
1766             PDhisS[Nf]->Draw();
1767         } else { PDh->cd(NXpad*NYpad); }
1768         
1769         fitS[Nf] = new TF1(fitname, PhDi::Gauss, Rmin, Rmax, 3);
1770         fitS[Nf]->SetParameter(0, maxVa);
1771         fitS[Nf]->SetParameter(1, maxpos);
1772         fitS[Nf]->SetParameter(2, (Rmax - Rmin)/4.);
1773         cout << " par0=" << maxVa <<  endl;
1774         cout << " par1=" << maxpos << " par2=" << (Rmax - Rmin)/4. << endl;
1775         cout << "fitname=" << fitname << endl;
1776         
1777         base_flag = PDhisS[Nf]->Fit(fitname,"LR");  //NS

1778         peak_tot = fitS[Nf]->GetParameter(0);
1779         position = fitS[Nf]->GetParameter(1);
1780         width    = fitS[Nf]->GetParameter(2);
1781         printf (" PD sgnl: peak_events=%f position=%f rms=%f fit_flag=%i \n",
1782                 peak_tot, position, width, base_flag);
1783         SiLe -= position;
1784         
1785     }
1786     
1787     
1788     PDh->Update();
1789     
1790     SiL.push_back(SiLe * eTime);
1791     
1792     return;
1793 }  //end PhDi::GetValue

1794 
1795 void PhDi::PlotData( void )
1796 {
1797     char title[40];
1798     //int Entry;

1799     NXpad=10;
1800     NYpad=10;
1801     int Npads = NXpad*NYpad;
1802     int NH = (Npads<Nsets)?Npads:Nsets;
1803     
1804     // PD plots +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1805     sprintf(title, "%s_0", PDname);
1806     TCanvas *   PD = new TCanvas( title,title, 60, 40, 900, 800);
1807     PD->SetBorderMode  (0);      //to remove border

1808     PD->SetLeftMargin  (left_margin);   //to move plot to the right 0.14

1809     PD->SetRightMargin (right_margin);  //to move plot to the right 0.05

1810     PD->SetTopMargin   (top_margin);    //to use more space 0.07

1811     PD->SetBottomMargin(bot_margin);    //default

1812     PD->SetFrameFillColor(0);
1813     PD->Divide(NXpad,NYpad);
1814     
1815     gPad->SetFillStyle(4100);
1816     gPad->SetFillColor(0);
1817     
1818     for (int i=0; i<NH; i++){
1819         if ( !PDplot[i] ) continue;
1820         PD->cd(1+i);
1821         //gPad->SetLogy();

1822         gPad->SetGrid(1,0);
1823         PDplot[i]->SetTitle("exposure");
1824         PDplot[i]->GetXaxis()->SetTimeDisplay(1);
1825         PDplot[i]->GetXaxis()->SetLabelOffset((float)0.02);
1826         PDplot[i]->SetMarkerColor (4);
1827         PDplot[i]->SetMarkerStyle (8);
1828         PDplot[i]->SetMarkerSize  (1);
1829         PDplot[i]->SetLineColor   (4);
1830         PDplot[i]->SetLineWidth   (2);
1831         PDplot[i]->Draw("ALP");
1832     }
1833     
1834     PD->Update();
1835     //PD->Print("PD0.pdf");

1836     
1837     // PD signal plot +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1838     sprintf(title, "%s_s", PDname);
1839     TCanvas *   PDs = new TCanvas( title, title, 65, 45, 900, 800);
1840     PDs->SetBorderMode  (0);      //to remove border

1841     PDs->SetLeftMargin  (left_margin);   //to move plot to the right 0.14

1842     PDs->SetRightMargin (right_margin);  //to move plot to the right 0.05

1843     PDs->SetTopMargin   (top_margin);    //to use more space 0.07

1844     PDs->SetBottomMargin(bot_margin);    //default

1845     PDs->SetFrameFillColor(0);
1846     PDs->Divide(3,3);
1847     
1848     gPad->SetFillStyle(4100);
1849     gPad->SetFillColor(0);
1850     
1851     TGraph * PDsp  = new TGraph(Nsets, &WaveL[0], &SiL[0]);
1852     PDs->cd(1);
1853     //gPad->SetLogy();

1854     gPad->SetGrid(1,0);
1855     sprintf(title, "%s current", PDname);
1856     PDsp->SetTitle(title);
1857     PDsp->GetXaxis()->SetTitle("Wavelength, nm");
1858     PDsp->GetXaxis()->SetLabelOffset((float)0.02);
1859     PDsp->GetYaxis()->SetTitle("Charge, pC");
1860     PDsp->SetMarkerColor (4);
1861     PDsp->SetMarkerStyle (8);
1862     PDsp->SetMarkerSize  (1);
1863     PDsp->SetLineColor   (4);
1864     PDsp->SetLineWidth   (2);
1865     PDsp->Draw("ALP");
1866     
1867     PDs->Update();
1868     
1869     TGraph * PDip  = new TGraph(Nsets, &WaveL[0], &SiI[0]);
1870     PDs->cd(2);
1871     //gPad->SetLogy();

1872     gPad->SetGrid(1,0);
1873     sprintf(title, "%s integral", PDname);
1874     PDip->SetTitle(title);
1875     PDip->GetXaxis()->SetTitle("Wavelength, nm");
1876     PDip->GetXaxis()->SetLabelOffset((float)0.02);
1877     PDip->GetYaxis()->SetTitle("Charge, Ge-");
1878     PDip->SetMarkerColor (4);
1879     PDip->SetMarkerStyle (8);
1880     PDip->SetMarkerSize  (1);
1881     PDip->SetLineColor   (4);
1882     PDip->SetLineWidth   (2);
1883     PDip->Draw("ALP");
1884     
1885     PDs->Update();
1886     
1887     TGraph * PDep  = new TGraph(Nsets, &WaveL[0], &SiE[0]);
1888     PDs->cd(3);
1889     //gPad->SetLogy();

1890     gPad->SetGrid(1,0);
1891     sprintf(title, "%s signal readings", PDname);
1892     PDep->SetTitle(title);
1893     PDep->GetXaxis()->SetTitle("Wavelength, nm");
1894     PDep->GetXaxis()->SetLabelOffset((float)0.02);
1895     PDep->SetMarkerColor (4);
1896     PDep->SetMarkerStyle (8);
1897     PDep->SetMarkerSize  (1);
1898     PDep->SetLineColor   (4);
1899     PDep->SetLineWidth   (2);
1900     PDep->Draw("ALP");
1901     
1902     PDs->Update();
1903     
1904     
1905     TGraph * PDit  = new TGraph(Nsets, &WaveL[0], &SinT[0]);
1906     PDs->cd(4);
1907     //gPad->SetLogy();

1908     gPad->SetGrid(1,0);
1909     sprintf(title, "%s exposure", PDname);
1910     PDit->SetTitle(title);
1911     PDit->GetXaxis()->SetTitle("Wavelength, nm");
1912     PDit->GetXaxis()->SetLabelOffset((float)0.02);
1913     PDit->SetMarkerColor (4);
1914     PDit->SetMarkerStyle (8);
1915     PDit->SetMarkerSize  (1);
1916     PDit->SetLineColor   (4);
1917     PDit->SetLineWidth   (2);
1918     PDit->Draw("ALP");
1919     
1920     PDs->Update();
1921     
1922     TGraph * PDsip  = new TGraph(Nsets, &SiL[0], &SiI[0]);
1923     PDs->cd(5);
1924     //gPad->SetLogy();

1925     gPad->SetGrid(1,0);
1926     sprintf(title, "%s Current vs Int", PDname);
1927     PDsip->SetTitle(title);
1928     PDsip->GetXaxis()->SetTitle("Charge L, pC");
1929     PDsip->GetXaxis()->SetLabelOffset((float)0.02);
1930     PDsip->GetYaxis()->SetTitle("Charge, Ge-");
1931     PDsip->SetMarkerColor (4);
1932     PDsip->SetMarkerStyle (8);
1933     PDsip->SetMarkerSize  (1);
1934     PDsip->SetLineColor   (4);
1935     PDsip->SetLineWidth   (2);
1936     PDsip->Draw("ALP");
1937     
1938     PDs->Update();
1939     
1940     TGraph * PDba  = new TGraph(Nsets, &FileNb[0], &PDbase[0]);
1941     PDs->cd(6);
1942     //gPad->SetLogy();

1943     gPad->SetGrid(1,0);
1944     sprintf(title, "%s base line", PDname);
1945     PDba->SetTitle(title);
1946     PDba->GetXaxis()->SetTitle("File Nb");
1947     PDba->GetXaxis()->SetLabelOffset((float)0.02);
1948     PDba->GetYaxis()->SetTitle("Current, pA");
1949     PDba->SetMarkerColor (4);
1950     PDba->SetMarkerStyle (8);
1951     PDba->SetMarkerSize  (1);
1952     PDba->SetLineColor   (4);
1953     PDba->SetLineWidth   (2);
1954     PDba->Draw("ALP");
1955     
1956     PDs->Update();
1957     
1958     TGraph * PDbawi = new TGraph(Nsets, &FileNb[0], &PDbw[0]);
1959     PDs->cd(7);
1960     //gPad->SetLogy();

1961     gPad->SetGrid(1,0);
1962     sprintf(title, "%s base line width", PDname);
1963     PDbawi->SetTitle(title);
1964     PDbawi->GetXaxis()->SetTitle("File Nb");
1965     PDbawi->GetXaxis()->SetLabelOffset((float)0.02);
1966     PDbawi->GetYaxis()->SetTitle("Current, pA");
1967     PDbawi->SetMarkerColor (4);
1968     PDbawi->SetMarkerStyle (8);
1969     PDbawi->SetMarkerSize  (1);
1970     PDbawi->SetLineColor   (4);
1971     PDbawi->SetLineWidth   (2);
1972     PDbawi->Draw("ALP");
1973     
1974     PDs->Update();
1975     
1976     TGraph * PDw  = new TGraph(Nsets, &FileNb[0], &WaveL[0]);
1977     PDs->cd(8);
1978     //gPad->SetLogy();

1979     gPad->SetGrid(1,0);
1980     sprintf(title, "%s wavelength", PDname);
1981     PDw->SetTitle(title);
1982     PDw->GetXaxis()->SetTitle("File Nb");
1983     PDw->GetXaxis()->SetLabelOffset((float)0.02);
1984     PDw->GetYaxis()->SetTitle("Wavelength, nm");
1985     PDw->SetMarkerColor (4);
1986     PDw->SetMarkerStyle (8);
1987     PDw->SetMarkerSize  (1);
1988     PDw->SetLineColor   (4);
1989     PDw->SetLineWidth   (2);
1990     PDw->Draw("ALP");
1991     
1992     PDs->Update();
1993 
1994     PDs->cd(9);
1995     //gPad->SetLogy();

1996     gPad->SetGrid(1,0);
1997     sprintf(title, "%s time interval, ms", PDname);
1998     PDdtm->GetXaxis()->SetTitle(title);
1999     PDdtm->GetXaxis()->SetLabelOffset((float)0.02);
2000     PDdtm->GetYaxis()->SetTitle("Counts");
2001     PDdtm->SetMarkerColor (4);
2002     PDdtm->SetMarkerStyle (8);
2003     PDdtm->SetMarkerSize  (1);
2004     PDdtm->SetLineColor   (4);
2005     PDdtm->SetLineWidth   (2);
2006     PDdtm->Draw("");
2007     
2008     PDs->Update();
2009     
2010     PDs->Print("PD0s.pdf");
2011     
2012     // PD signal QA plot +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2013     sprintf(title, "%s_QA", PDname);
2014     TCanvas *   PDQA = new TCanvas( title, title, 65, 45, 900, 800);
2015     PDQA->SetBorderMode  (0);      //to remove border

2016     PDQA->SetLeftMargin  (left_margin);   //to move plot to the right 0.14

2017     PDQA->SetRightMargin (right_margin);  //to move plot to the right 0.05

2018     PDQA->SetTopMargin   (top_margin);    //to use more space 0.07

2019     PDQA->SetBottomMargin(bot_margin);    //default

2020     PDQA->SetFrameFillColor(0);
2021     PDQA->Divide(2,3);
2022     
2023     gPad->SetFillStyle(4100);
2024     gPad->SetFillColor(0);
2025     
2026     TGraph * PDqa1  = new TGraph(Nsets, &FileNb[0], &SiI[0]);
2027     PDQA->cd(1);
2028     //gPad->SetLogy();

2029     gPad->SetGrid(1,0);
2030     sprintf(title, "%s charge", PDname);
2031     PDqa1->SetTitle(title);
2032     PDqa1->GetXaxis()->SetTitle("File Nb");
2033     PDqa1->GetXaxis()->SetLabelOffset((float)0.02);
2034     PDqa1->GetYaxis()->SetTitle("Charge, Me-");
2035     PDqa1->SetMarkerColor (4);
2036     PDqa1->SetMarkerStyle (8);
2037     PDqa1->SetMarkerSize  (1);
2038     PDqa1->SetLineColor   (4);
2039     PDqa1->SetLineWidth   (2);
2040     PDqa1->Draw("ALP");
2041     
2042     PDQA->Update();
2043     
2044     TGraph * PDqa2  = new TGraph(Nsets, &FileNb[0], &SiE[0]);
2045     PDQA->cd(2);
2046     //gPad->SetLogy();

2047     gPad->SetGrid(1,0);
2048     sprintf(title, "%s signal readings", PDname);
2049     PDqa2->SetTitle(title);
2050     PDqa2->GetXaxis()->SetTitle("File Nb");
2051     PDqa2->GetXaxis()->SetLabelOffset((float)0.02);
2052     PDqa2->SetMarkerColor (4);
2053     PDqa2->SetMarkerStyle (8);
2054     PDqa2->SetMarkerSize  (1);
2055     PDqa2->SetLineColor   (4);
2056     PDqa2->SetLineWidth   (2);
2057     PDqa2->Draw("ALP");
2058     
2059     PDQA->Update();
2060     
2061     
2062     TGraph * PDqa3  = new TGraph(Nsets, &FileNb[0], &SinT[0]);
2063     PDQA->cd(3);
2064     //gPad->SetLogy();

2065     gPad->SetGrid(1,0);
2066     sprintf(title, "%s exposure", PDname);
2067     PDqa3->SetTitle(title);
2068     PDqa3->GetXaxis()->SetTitle("File Nb");
2069     PDqa3->GetXaxis()->SetLabelOffset((float)0.02);
2070     PDqa3->SetMarkerColor (4);
2071     PDqa3->SetMarkerStyle (8);
2072     PDqa3->SetMarkerSize  (1);
2073     PDqa3->SetLineColor   (4);
2074     PDqa3->SetLineWidth   (2);
2075     PDqa3->Draw("ALP");
2076     
2077     PDQA->Update();
2078     
2079     TGraph * PDqa4  = new TGraph(Nsets, &FileNb[0], &PDbase[0]);
2080     PDQA->cd(4);
2081     //gPad->SetLogy();

2082     gPad->SetGrid(1,0);
2083     sprintf(title, "%s base line", PDname);
2084     PDqa4->SetTitle(title);
2085     PDqa4->GetXaxis()->SetTitle("File Nb");
2086     PDqa4->GetXaxis()->SetLabelOffset((float)0.02);
2087     PDqa4->GetYaxis()->SetTitle("Current, pA");
2088     PDqa4->SetMarkerColor (4);
2089     PDqa4->SetMarkerStyle (8);
2090     PDqa4->SetMarkerSize  (1);
2091     PDqa4->SetLineColor   (4);
2092     PDqa4->SetLineWidth   (2);
2093     PDqa4->Draw("ALP");
2094     
2095     PDQA->Update();
2096     
2097     TGraph * PDqa5  = new TGraph(Nsets, &FileNb[0], &WaveL[0]);
2098     PDQA->cd(5);
2099     //gPad->SetLogy();

2100     gPad->SetGrid(1,0);
2101     //sprintf(title, "%s wavelength", PDname);

2102     PDqa5->SetTitle("Wavelength");
2103     PDqa5->GetXaxis()->SetTitle("File Nb");
2104     PDqa5->GetXaxis()->SetLabelOffset((float)0.02);
2105     PDqa5->GetYaxis()->SetTitle("Wavelength, nm");
2106     PDqa5->SetMarkerColor (4);
2107     PDqa5->SetMarkerStyle (8);
2108     PDqa5->SetMarkerSize  (1);
2109     PDqa5->SetLineColor   (4);
2110     PDqa5->SetLineWidth   (2);
2111     PDqa5->Draw("ALP");
2112     
2113     PDQA->Update();
2114     
2115     PDQA->cd(6);
2116     if ( PD_Int->GetEntries() > 0 ){
2117         //gPad->SetLogy();

2118         PD_Int->Draw();
2119     }
2120     
2121     PDQA->Print("PD0qa.pdf");
2122     
2123     return;
2124 }  //end PhDi::PlotPDdata

2125 
2126 
2127 //---------------------------------------------------------------------

2128 // Bias class ---------------------------------------------------------

2129 class Bias: public FileF 
2130 {
2131 public:
2132     int Flag;
2133 
2134     const string dname;
2135     const string outNm;
2136     string filename;
2137 
2138     int XminUse;  
2139     int XmaxUse;  
2140     int YminUse;  
2141     int YmaxUse;  
2142 
2143     int Nchan;
2144     int ch_idx;
2145     //vector<int> ChanIdu;

2146 
2147 // FFT 

2148     const int doFFT;
2149 
2150     FFT * Col;
2151     FFT * Row;
2152 
2153 //  double * bufd;

2154     double * tmpbuf;
2155 
2156 // averages (vectors)

2157 
2158     static const double maxdata;
2159     vector<double> avbuf[MaxP];
2160     vector<double> mibuf[MaxP];
2161     vector<double> mabuf[MaxP];
2162 //  vector<double> m2buf[MaxP];

2163     vector<double> trbuf[MaxP];
2164     vector<double> pix_rms[MaxP];
2165 
2166     double bias_rms[MaxP];
2167 
2168     enum { Nhist = 5 };
2169     TH1D * hb[MaxP][Nhist];
2170     TH1D * htrA[MaxP];
2171     TH1D * htrS[MaxP];
2172     TH1D * htrD[MaxP];
2173     enum { Nfhst = 16 }; //49

2174     TH1F * hfz[Nfhst];
2175     TGraph * gPDc[Nfhst];
2176     double PDbl[Nfhst];
2177 
2178 public:
2179 //  Bias ( const string & dir_name, const int dofft );

2180     Bias ( const string & dir_name,
2181            const string & outFnm,
2182            const int dofft        );
2183     void Plot_FFT();
2184     void Plot();
2185     int OutFitsF ( double * outbuf, const char * fOutName = "bias_outf" );
2186     int PrintVal( void  ); 
2187     ~Bias();
2188 };
2189 const double Bias::maxdata=pow(2., 18);
2190 
2191 Bias::~Bias(){
2192     //if (doFFT) {

2193     //  delete [] tmpbuf; tmpbuf = 0;

2194     //  delete    Col; Col = 0;

2195     //  delete    Row; Row = 0;

2196     //}

2197     //Col = 0;

2198     //Row = 0;

2199 }
2200 
2201 Bias::Bias ( const string & dir_name,
2202              const string & outFnm,
2203              const int dofft           ):
2204     Flag(-1),
2205     dname(dir_name),
2206     outNm(outFnm),
2207     Nchan(0),
2208     doFFT(dofft),
2209 //  bufd(0),

2210     Col(0),
2211     Row(0)
2212 {
2213     for (int i= 0; i< MaxP; i++) 
2214         {bias_rms[i]=0.; trbuf[i].resize(1,0);}
2215 //FFileDB: *************************************************************

2216     //FFileDB mDB(dname);

2217     //int dbFiles=mDB.SelectFiles();

2218     //mDB.GetFparams();

2219     //cout << "dataOK=" << mDB.get_dataOK() << endl;

2220     //cout << "bitpix=" << mDB.get_bitpix() << endl;

2221     //cout << "naxis="  << mDB.get_naxis()  << endl;

2222  //   cout << "naxis1=" << mDB.get_naxis1() << endl;

2223     //cout << "naxis2=" << mDB.get_naxis2() << endl;

2224 // files:  ************************************************************

2225     FileList FL(dname);
2226     if (FL.Nfile <= 0) {Flag= -10; return;}
2227     
2228 // averages ***********************************************************

2229 
2230     int Nf = 0;
2231     int FFTinit=0;
2232     FL.FName_Iter=FL.FName.begin();
2233     cout << "Set starts:" << *FL.FName_Iter << endl;
2234     for (FL.FName_Iter=FL.FName.begin(); FL.FName_Iter != FL.FName.end(); FL.FName_Iter++ ) 
2235     {
2236         ch_idx=0;
2237         //filename = dname + "/" + *FL.FName_Iter;

2238         filename = *FL.FName_Iter;
2239         cout << "File: " << *FL.FName_Iter << endl;
2240         if ( Open(filename.c_str()) ) continue;
2241 
2242         while( !iEOF ){              
2243             if ( hdu > MaxP )   break;
2244             if ( Read() )    continue;
2245             if ( hdu == 1){
2246                 for (int i=0; i<Nkey; i++){
2247                     double v; 
2248                     int ir = getValue( KeyList[i], &v );
2249                     if (!i) v -= T1995; //convert CTIME to root time

2250                     if (!ir) Vval[i].push_back( v ); 
2251                 }
2252             }
2253 
2254             if ( naxis != 2) continue;
2255 
2256             if ( Nf == 0) {
2257                 Nchan++;
2258                 avbuf[ch_idx].resize(npixels,0);
2259                 mibuf[ch_idx].resize(npixels,maxdata);
2260                 mabuf[ch_idx].resize(npixels,0);
2261 //              m2buf[ch_idx].resize(npixels,0);

2262             }
2263 
2264             for (unsigned long i=0; i<npixels; i++){
2265                 double amp = (double)buffer[i];
2266                 avbuf[ch_idx][i] += amp;
2267                 if ( amp < mibuf[ch_idx][i] ) mibuf[ch_idx][i] = amp;
2268                 if ( amp > mabuf[ch_idx][i] ) mabuf[ch_idx][i] = amp;
2269                 //if ((amp > m2buf[ch_idx][i]) &&

2270                 //  (amp < mabuf[ch_idx][i])) m2buf[ch_idx][i] = amp;

2271             }
2272 
2273             ch_idx++;
2274         }
2275 
2276         Nf++;
2277         Close();
2278     } //end "bias files for loop"

2279 
2280     printf(" Average over %i zero exposures Nhdu=%i \n", Nf, Nhdu);
2281     if ( Nf < 1 ) {printf(" No bias files \n"); Flag = -2; return;}
2282     if ( Nchan < 1 ) {printf(" No channels detected \n"); Flag = -2; return;}
2283 
2284     for (int u=0; u<Nchan; u++){
2285         printf(" Bias::Bias ch_idx=%i Nchan=%i avbuf_size=%lu npixels=%lu \n", u, Nchan, (long unsigned)avbuf[u].size(), npixels); 
2286         if ( avbuf[u].size() < npixels) continue;
2287                 trbuf[u].resize(npixels,0);
2288         if ( Nf > 2 ) {
2289             for (unsigned long i=0; i<npixels; i++){ 
2290                 trbuf[u][i]  = avbuf[u][i]-mabuf[u][i];
2291                 trbuf[u][i] -= mibuf[u][i];
2292                 trbuf[u][i] /= (Nf-2);
2293                 avbuf[u][i] /= Nf;
2294                 //htrA[u]->Fill( trbuf[u][i] );

2295             }
2296         }
2297         else {
2298             for (unsigned long i=0; i<npixels; i++) {
2299                 avbuf[u][i] /= Nf;
2300                 trbuf[u][i] = avbuf[u][i];
2301             }
2302         }
2303      } //end Nhdu loop 

2304 
2305     if ( Nf < 2 ) {printf(" ** Only one bias file :( \n"); Flag = 0; return;}
2306 
2307 // Histograms for Average Amplitudes & Spread

2308     for (int u=0; u<Nchan; u++){
2309          char title[20];
2310          char hname[50];
2311          if ( u > MaxP )   break;
2312          sprintf(title, "hb0%i", u);
2313          sprintf(hname, "pixel average amplitude");
2314          hb[u][0] = new TH1D( title, hname, 2000, 1900., 41900.);
2315          hb[u][0]->GetXaxis()->SetNdivisions(505);
2316          hb[u][0]->SetStats(0);
2317 
2318          sprintf(title, "hb1%i", u);
2319          sprintf(hname, "pixel simple average subtracted");
2320          hb[u][1] = new TH1D( title, hname, 1000, -100., 100.);
2321          hb[u][1]->GetXaxis()->SetNdivisions(505);
2322          hb[u][1]->SetStats(0);
2323 
2324          sprintf(title, "hb2%i", u);
2325          sprintf(hname, "pixel rms");
2326          hb[u][2] = new TH1D( title, hname, 400, 0., 40.);
2327          hb[u][2]->GetXaxis()->SetNdivisions(505);
2328          hb[u][2]->SetStats(0);
2329 
2330          sprintf(title, "hb3%i", u);
2331          sprintf(hname, "over_scan subtracted amplitude");
2332          hb[u][3] = new TH1D( title, hname, 600, -100., 500.);
2333          hb[u][3]->SetDirectory(0);
2334          hb[u][3]->GetXaxis()->SetNdivisions(505);
2335          hb[u][3]->SetStats(0);
2336 
2337          sprintf(title, "hb4%i", u);
2338          sprintf(hname, "X_overscan average amplitude");
2339          hb[u][4] = new TH1D( title, hname, 2000, 1900., 41900.);
2340          hb[u][4]->GetXaxis()->SetNdivisions(505);
2341          hb[u][4]->SetStats(0);
2342 
2343          // truncated amplitude histos  

2344          sprintf(title, "htrA%i", u);
2345          sprintf(hname, "Traverage amplitudes");
2346          htrA[u] = new TH1D( title, hname, 2000, 1900., 41900.);
2347          htrA[u]->GetXaxis()->SetNdivisions(505);
2348          htrA[u]->SetStats(0);
2349          sprintf(title, "hmi%i", u);    
2350          sprintf(hname, "pixel truncated average subtracted");
2351          htrS[u] = new TH1D( title, hname, 1000, -100., 100.);
2352          htrS[u]->GetXaxis()->SetNdivisions(505);
2353          htrS[u]->SetStats(0);
2354          sprintf(title, "hma%i", u);
2355          sprintf(hname, "Tr rms");
2356          htrD[u] = new TH1D( title, hname, 400, 0., 40.);
2357          htrD[u]->GetXaxis()->SetNdivisions(505);
2358          htrD[u]->SetStats(0);
2359     }
2360 
2361 // get device description ************************

2362 
2363         DataStr * Dev = DataStr::Instance(nx,ny);
2364 
2365 // fill average: Overscan Amp; Active Amp; Trunkated Amp;  

2366     for (int u=0; u<Nchan; u++){
2367         if ( u > MaxP )   break;
2368         if ( avbuf[u].size() < npixels) continue;
2369         for (int iy=Dev->minY(); iy<Dev->maxY(); iy++) {
2370              for (int ix=0; ix<nx; ix++) {
2371                  int j = iy*nx + ix;
2372                  if ( Dev->IsOverX(ix) ) hb[u][4]->Fill( avbuf[u][j] );
2373                  else {
2374                      hb[u][0]->Fill( avbuf[u][j] );
2375                      htrA[u]->Fill(  trbuf[u][j] );
2376                  }
2377              }
2378          }
2379     }
2380 
2381 // distribution arround average ---------------------------------------

2382      FL.FName_Iter=FL.FName.begin();
2383      for (int i=0; i<Nfhst; i++){
2384         gPDc[i]=0;
2385         PDbl[i]=0.;
2386         char htitle[40];
2387         sprintf(htitle, "File %i", i);
2388         if ( i >= FL.Nfile ) {hfz[i]=0; }
2389         else {
2390             filename = *FL.FName_Iter++; 
2391             hfz[i] = new TH1F( htitle, filename.c_str(), 1000, -250., 750.);
2392             hfz[i]->SetStats(1);
2393         }
2394      }
2395 
2396 // prepare FFT stuf -----------------

2397 
2398     if (doFFT && (!FFTinit)) {
2399         Col = new FFT(  "Bias Col",
2400                         Dev->minY(), Dev->maxY(),
2401                         Dev->minX(), Dev->maxX(),
2402                         nx, 1);
2403         Row = new FFT(  "Bias Row",
2404                         Dev->minX(), Dev->maxX(),
2405                         Dev->minY(), Dev->maxY(),
2406                         1, nx ); 
2407         FFTinit=1;
2408     }
2409         tmpbuf   = new double [npixels];
2410         memset(tmpbuf,0,npixels * sizeof(double));
2411 
2412     Nf=0;
2413 
2414     for (FL.FName_Iter=FL.FName.begin(); FL.FName_Iter != FL.FName.end(); FL.FName_Iter++ ) 
2415     {
2416         ch_idx=0;
2417         //filename = dname + "/" + *FL.FName_Iter;

2418         filename = *FL.FName_Iter;
2419         cout << "Distribution, File: " << *FL.FName_Iter << endl;
2420         if ( Open(filename.c_str()) ) continue;
2421 
2422         while( !iEOF ){              
2423             if ( hdu > MaxP )   break;
2424             if ( Read() )    continue;
2425             if ( lTable && strstr(TableName,"AMP0") && (Nf<Nfhst) ) {
2426                 gPDc[Nf] = new TGraph(nrows, &TabData[0][0], &TabData[1][0]);
2427                 for (int i=0; i<nrows; i++) {PDbl[Nf]+=TabData[1][i]/nrows;}
2428             }
2429             if ( naxis != 2) continue; 
2430             if ( Nf == 0) pix_rms[ch_idx].resize(npixels,0);
2431         
2432             double act = 0;
2433             double b_shift = 0;
2434             for (int iy=Dev->minY(); iy<Dev->maxY(); iy++) {
2435                 for (int ix=Dev->minX(); ix<Dev->maxX(); ix++) {
2436                   int j = iy*nx + ix;
2437                   double amp = (double)buffer[j] - trbuf[ch_idx][j];
2438                   tmpbuf[j] = amp;
2439                   if (TMath::Abs(amp) < 100. ) {b_shift += amp; act+=1.;}
2440                 }
2441             }
2442             if (act > 100000.) b_shift /= act;
2443             else b_shift=0.;
2444             //printf( " Bias: act=%f b_shift=%f \n", act, b_shift);

2445             if (doFFT) { 
2446                 Row->DTrans(tmpbuf, ch_idx, 1); 
2447                 Col->DTrans(tmpbuf, ch_idx, 0); 
2448             }
2449 
2450             for (int iy=Dev->minY(); iy<Dev->maxY(); iy++) {
2451                 double a_over = 0.;
2452                 for (int ix=nx-1; ix>=Dev->minX(); ix--) {
2453                     int j = iy*nx + ix;
2454                     if ( Dev->IsOverX(ix) ) a_over += (double)buffer[j]/Dev->NoverX(); 
2455                     if ( Dev->IsOverX(ix) ) continue;
2456                     double Amp = (double)buffer[j] - avbuf[ch_idx][j] - b_shift;
2457                     double Atr = tmpbuf[j] - b_shift;  //(double)buffer[j] - trbuf[ch_idx][j] - b_shift;

2458                     //if (doFFT) { tmpbuf[j] = Atr; }

2459                     hb[ch_idx][1]->Fill(  Amp );
2460                     hb[ch_idx][3]->Fill( (double)buffer[j] - a_over );
2461                     htrS[ch_idx]->Fill(  Atr );
2462                     if (Nf < Nfhst) hfz[Nf]->Fill( Atr );
2463                     pix_rms[ch_idx][j] += Atr*Atr;
2464                 }
2465             }
2466 
2467             ch_idx++;
2468 
2469         } //end while

2470 
2471         Nf++;
2472         Close();
2473     } //end "distributions" for loop

2474 
2475 // Norm FFT vectors +++++++++++++++++++++++++++++++++++++++++++++++++++++

2476 
2477     if (doFFT) {
2478         for (int u=0; u<Nchan; u++){   
2479             for(int i =1; i < Col->Nfreq; i++) {Col->PSDav[u][i] /= Nf;}
2480             for(int i =1; i < Row->Nfreq; i++) {Row->PSDav[u][i] /= Nf;}
2481         }
2482     }       
2483 //  ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2484 
2485     if ( Nf < 2 ) {printf(" Not enough bias files for RMS: %i \n", Nf); Flag = 0; return;}
2486 
2487     // output file: *******************************************************

2488     string foName = "BiasNoise_";
2489     foName += outNm;
2490     foName += ".txt";
2491     printf(" Output File: %s  \n", foName.c_str());
2492     FILE * pFile = fopen (foName.c_str(),"wt");
2493     if (pFile == 0) {printf(" File %s cann't be open \n", foName.c_str()); Flag=-1; return;}
2494     fprintf (pFile,"// %s  input files from: %s \n", foName.c_str(), dname.c_str());
2495     fprintf (pFile,"// Channel   Noise rms \n");
2496 
2497     for (int u=0; u<Nchan; u++){
2498         bias_rms[u] = 0.;
2499         if ( pix_rms[u].size() < npixels) continue;
2500         for (unsigned long i=0; i<npixels; i++) pix_rms[u][i] /= (Nf-1.);
2501         for (int iy=Dev->minY(); iy<Dev->maxY(); iy++) {
2502             for (int ix=Dev->minX(); ix<Dev->maxX(); ix++) {
2503                 int j = iy*nx + ix;
2504                 double rms = TMath::Sqrt(pix_rms[u][j]);
2505                 hb[u][2]->Fill( rms );
2506                 if ( Nf < 4 ) continue;
2507                 double S2 = pix_rms[u][j]*(Nf-1.);
2508                 S2 -= (mibuf[u][j]-trbuf[u][j])*(mibuf[u][j]-trbuf[u][j]);
2509                 S2 -= (mabuf[u][j]-trbuf[u][j])*(mabuf[u][j]-trbuf[u][j]);
2510                 double Trms = TMath::Sqrt( S2/(Nf-3.) );
2511                 htrD[u]->Fill( Trms );
2512              }
2513         }
2514         bias_rms[u] = hb[u][2]->GetMean();
2515         fprintf (pFile," %d    %f \n", u, bias_rms[u]);
2516     }
2517     fclose( pFile );
2518 
2519     Flag = 0;
2520     return;
2521 } //end Bias constructor

2522 
2523 void Bias::Plot_FFT()
2524 {
2525      const float left_margin = (float)0.04;
2526      const float right_margin = (float)0.001;
2527      const float top_margin = (float)0.01;
2528      const float bot_margin = (float)0.04;
2529 
2530     TCanvas *   Tr[MaxP];
2531 for (int u=0; u<Nchan; u++){
2532     if ( avbuf[u].size() < npixels) continue;
2533     char tiname[50];
2534     char PDFname[50];
2535     sprintf(tiname, "Bias FFT %i", u);
2536     sprintf(PDFname, "BiasFFT_%i.pdf", u);
2537     if ( u > MaxP )   break;
2538      Tr[u] = new TCanvas( tiname,tiname, 200+4*u, 10+2*u, 800, 600);
2539      Tr[u]->SetBorderMode  (1);         //to remove border

2540      Tr[u]->SetLeftMargin  (left_margin);  //to move plot to the right 0.14

2541      Tr[u]->SetRightMargin (right_margin); //to move plot to the right 0.05

2542      Tr[u]->SetTopMargin   (top_margin);   //to use more space 0.07

2543      Tr[u]->SetBottomMargin(bot_margin);   //default

2544      Tr[u]->SetFrameFillColor(0);
2545      Tr[u]->Divide(1,2); 
2546 
2547 /***************** Plot Power Spectrum for Rows *************/
2548      printf(" Start draw Power Spectrum for Rows\n\n");
2549      Tr[u]->cd(1);
2550      gPad->SetLogy();
2551      gPad->SetLogx();
2552 
2553      do {
2554      int Npsd = Row->PSDav[u].size();
2555      int Nfrq = Row->Freq.size();
2556      printf(" RowPSD points =%i RowFreq size=%i *** \n", Npsd, Nfrq);
2557      if ( Npsd <= 3 ) continue;
2558      int nn = Npsd -3;
2559      if ( Nfrq < nn ) continue;
2560      TGraph * std6 = new TGraph( nn, &Row->Freq[0], &Row->PSDav[u][0]);
2561      std6->SetTitle("Rows");
2562      std6->GetYaxis()->SetTitle("PSD ");
2563      std6->GetXaxis()->SetTitle("k/N, 1/pixel");
2564      std6->SetMarkerColor(4);
2565      std6->SetMarkerStyle(21);
2566      std6->Draw("AP");
2567      } while(0);
2568 
2569 /*********************Plot Power Spectrum for Columns*********/
2570      Tr[u]->cd(2);
2571      gPad->SetLogy();
2572      gPad->SetLogx();
2573      do {
2574      int Npsd = Col->PSDav[u].size();
2575      int Nfrq = Col->Freq.size();
2576      printf(" ColPSD points =%i ColFreq size=%i *** \n", Npsd, Nfrq);
2577      if ( Npsd <= 3 ) continue;
2578      int nn = Npsd -3;
2579      if ( Nfrq < nn ) continue;
2580      TGraph * std7 = new TGraph( nn, &Col->Freq[0], &Col->PSDav[u][0]);
2581      std7->SetTitle("Columns");
2582      std7->GetYaxis()->SetTitle("PSD ");
2583      std7->GetXaxis()->SetTitle("k/N, 1/pixel");
2584      std7->SetMarkerColor(6);
2585      std7->SetMarkerStyle(21);
2586      std7->Draw("AP");
2587      } while(0);
2588 
2589     Tr[u]->Update();
2590     Tr[u]->Print(PDFname);
2591 }
2592      return;
2593 }
2594 
2595 void Bias::Plot( void )
2596 {
2597     const float left_margin = (float)0.04;
2598     const float right_margin = (float)0.001;
2599     const float top_margin = (float)0.01;
2600     const float bot_margin = (float)0.04;
2601     TCanvas *   Bi[MaxP];
2602 
2603     int NH = 0;   // used in canvas 2 as well

2604     double mean[Nfhst];
2605     while ( hfz[NH] && (NH < Nfhst) ){
2606         mean[NH] = hfz[NH]->GetMean();
2607         NH++;
2608     }
2609     //printf(" Bias::Plot NH=%i pVval=%p \n", NH, &Vval[0][0]);

2610 
2611 for (int u=0; u<Nchan; u++){
2612     if ( avbuf[u].size() < npixels) continue;
2613     char tiname[50];
2614     char PDFname[50];
2615     sprintf(tiname, "Bias BL %i", u);
2616     sprintf(PDFname, "BiasBL_%i.pdf", u);
2617     if ( u > MaxP )   break;
2618 
2619 // set bias canvas 1 ****************************************************

2620     Bi[u] = new TCanvas( tiname, tiname, 10+5*u, 10+5*u, 900, 800);
2621     Bi[u]->SetBorderMode  (0);          //to remove border

2622     Bi[u]->SetLeftMargin  (left_margin);  //to move plot to the right 0.14

2623     Bi[u]->SetRightMargin (right_margin); //to move plot to the right 0.05

2624     Bi[u]->SetTopMargin   (top_margin);   //to use more space 0.07

2625     Bi[u]->SetBottomMargin(bot_margin);   //default

2626     Bi[u]->SetFrameFillColor(0);
2627     Bi[u]->Divide(5,2);
2628 
2629     gPad->SetFillStyle(4100);
2630     gPad->SetFillColor(0);
2631 
2632     for (int i = 0; i<Nhist; i++){
2633         int Entry = (int)hb[u][i]->GetEntries();
2634         //printf(" Bias::Plot: hb%d GetEntries %i \n", i, Entry);

2635         if ( Entry < 1 ) continue;
2636         Bi[u]->cd(i+1);
2637         gPad->SetLogy(); 
2638         hb[u][i]->Draw();
2639     }
2640 
2641     Bi[u]->cd(6);
2642     gPad->SetLogy(); 
2643     htrA[u]->Draw();
2644 
2645     Bi[u]->cd(7);
2646     gPad->SetLogy(); 
2647     htrS[u]->Draw();
2648     
2649     Bi[u]->cd(8);
2650     gPad->SetLogy(); 
2651     htrD[u]->Draw();
2652 
2653     if ( (NH > 0) & (Vval[0].size() > 0) ){
2654         Bi[u]->cd(9);
2655         TGraph * pGmean = new TGraph( NH, &Vval[0][0], mean);
2656         pGmean->GetXaxis()->SetTimeDisplay(1);
2657         pGmean->GetXaxis()->SetLabelOffset((float)0.02);
2658         pGmean->GetXaxis()->SetTimeFormat("#splitline{%Y-%m-%d}{%H:%M:%S}"); 
2659         pGmean->SetTitle("Mean level"); 
2660         pGmean->SetMarkerColor (4);
2661         pGmean->SetMarkerStyle (8);
2662         pGmean->SetMarkerSize  (1);
2663         pGmean->SetLineColor   (4);
2664         pGmean->SetLineWidth   (2);
2665         pGmean->GetYaxis()->SetNdivisions (505);
2666         pGmean->GetYaxis()->SetTitle ("File mean bias level, adu");
2667         pGmean->GetYaxis()->CenterTitle();
2668         pGmean->GetYaxis()->SetTitleOffset ((float)1.06);
2669         pGmean->GetYaxis()->SetLabelSize ((float)0.037);
2670         pGmean->Draw("ALP");
2671     }
2672 
2673     Bi[u]->Update();
2674 //  Bi[u]->Print(PDFname);

2675 
2676 } // end "section" canvas loop

2677 
2678     if ( NH < 1 ) return;
2679 // Bias canvas 2 ******************************************************

2680     TCanvas *   Zi = new TCanvas( "BiasVar", "BiasVar", 50, 30, 900, 800);
2681     Zi->SetBorderMode  (0);      //to remove border

2682     Zi->SetLeftMargin  (left_margin);   //to move plot to the right 0.14

2683     Zi->SetRightMargin (right_margin);  //to move plot to the right 0.05

2684     Zi->SetTopMargin   (top_margin);    //to use more space 0.07

2685     Zi->SetBottomMargin(bot_margin);    //default

2686     Zi->SetFrameFillColor(0);
2687     Zi->Divide(7,7);
2688 
2689     gPad->SetFillStyle(4100);
2690     gPad->SetFillColor(0);
2691 
2692     for (int i=0; i<NH; i++){
2693         if ( hfz[i]->GetEntries() < 1 ) continue;
2694         Zi->cd(1+i);
2695         gPad->SetLogy(); 
2696         gPad->SetGrid(1,0);
2697         hfz[i]->Draw();
2698     }
2699 
2700     Zi->Update();
2701     //Zi->Print("BiasVar.pdf");

2702     
2703      if ( !NH ) return;
2704 // Bias canvas 3 ******************************************************

2705     TCanvas *   PD = new TCanvas( "PDmonBias", "PDmonBias", 60, 40, 900, 800);
2706     PD->SetBorderMode  (0);      //to remove border

2707     PD->SetLeftMargin  (left_margin);   //to move plot to the right 0.14

2708     PD->SetRightMargin (right_margin);  //to move plot to the right 0.05

2709     PD->SetTopMargin   (top_margin);    //to use more space 0.07

2710     PD->SetBottomMargin(bot_margin);    //default

2711     PD->SetFrameFillColor(0);
2712     PD->Divide(4,4); //7,7

2713 
2714     gPad->SetFillStyle(4100);
2715     gPad->SetFillColor(0);
2716 
2717     for (int i=0; i<NH; i++){
2718         if ( !gPDc[i] ) continue;
2719         PD->cd(1+i);
2720         //gPad->SetLogy(); 

2721         gPad->SetGrid(1,0);
2722         gPDc[i]->SetTitle("exposure"); 
2723         gPDc[i]->GetXaxis()->SetTimeDisplay(1);
2724         gPDc[i]->GetXaxis()->SetLabelOffset((float)0.02);
2725         gPDc[i]->SetMarkerColor (4);
2726         gPDc[i]->SetMarkerStyle (8);
2727         gPDc[i]->SetMarkerSize  (1);
2728         gPDc[i]->SetLineColor   (4);
2729         gPDc[i]->SetLineWidth   (2);
2730         gPDc[i]->Draw("ALP");
2731     }
2732     
2733     PD->cd(16);  //49

2734     double xnf[Nfhst];
2735     for (int i=0; i<NH; i++){ xnf[i]=i;}
2736      TGraph * pPDa = new TGraph( NH, xnf, PDbl);
2737      pPDa->SetTitle("PD average"); 
2738      pPDa->GetXaxis()->SetLabelOffset((float)0.02);
2739      pPDa->SetMarkerColor (14);
2740      pPDa->SetMarkerStyle (8);
2741      pPDa->SetMarkerSize  (1);
2742      pPDa->SetLineColor   (14);
2743      pPDa->SetLineWidth   (2);
2744      pPDa->Draw("ALP");
2745 
2746     PD->Update();
2747     //PD->Print("PD0.pdf");

2748     return;
2749 } //end Plot    

2750 
2751 
2752 int Bias::PrintVal( void  ) 
2753 {
2754     for (int i=0; i<Nkey; i++) {
2755         printf(" Key= %s \n", KeyList[i]); 
2756         for ( V_Iter = Vval[i].begin( ); V_Iter != Vval[i].end( ); V_Iter++){
2757             printf(" val= %f \n", *V_Iter);} 
2758     }
2759     return 0;
2760 }
2761 
2762 // end Bias class --------------------------------------------------------------------

2763