Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Bias.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file Bias.cpp
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <cmath>
5 #include <iomanip>
6 #include <assert.h>
7 #include <time.h>
8 
9 #ifndef __CINT__
10 //#include "fftw3.h"
12 //# include <QSqlDatabase>
13 //# include <QSqlError>
14 //# include <QStringList>
15 //# include <QSqlQuery>
16 //# include <QSqlRecord>
17 //# include <QVariant>
18 #endif
19 
20 #include <TROOT.h>
21 #include <TSystem.h>
22 #include <TCanvas.h>
23 #include <TImage.h>
24 #include <TGraph.h>
25 #include <TGraphErrors.h>
26 #include <TH1.h>
27 #include <TH2.h>
28 #include <TF1.h>
29 #include <TF2.h>
30 #include <TMath.h>
31 #include <TStyle.h>
32 #include <TRandom.h>
33 #include "TMinuit.h"
34 #include "TMultiGraph.h"
35 
36 
37 #include "fitsio.h"
38 #include "longnam.h"
39 
40 #include "fftw3.h"
41 
42 #include <iostream>
43 #include <string>
44 #include <vector>
45 #include <map>
46 #include <set>
47 #include <algorithm>
48 using namespace std;
49 
50 // GLOBALS ------------------------------------------------------------
51 const double TwoPi = 2. * 3.14159265358979323846 ;
52 const unsigned int T1995 = 788936400; //UTC time of 19950101 00:00
53 const char * KeyList[] = {
54  "CTIME", "USEC", "EXPOSURE", "EXPTIME","MONOWL",
55  "AMP2.VOLTAGE", "AMP2.CURRENT",
56  "CRYO.A.TEMP", "CRYO.B.TEMP", "CRYO.C.TEMP", "CRYO.D.TEMP", "CRYO.1.SETPT",
57  "MONOCH-WAVELENG", "MONOCH.WAVELENG",
58  "AMP0.MEAS_NPLC",
59  0
60  };
61  enum { Nkey = sizeof(KeyList)/sizeof(char*)-1 };
62  vector <double>::iterator V_Iter;
63  vector<double> Vval[Nkey];
64 
65 //---------------------------------------------------------------------
66 // FFileDB class ---------------------------------------------------------
67 //class FFileDB {
68 //public:
69 // FFileDB( const string & d_name );
70 // ~FFileDB(){};
71 // int SelectFiles( void );
72 // set<string> GetFnames( void );
73 // void GetFparams();
74 // int get_dbOK() { return dbOK;};
75 // int get_dataOK() { return dataOK;};
76 // int get_bitpix() { return bitpix;};
77 // int get_naxis() { return naxis;};
78 // int get_naxis1() { return naxis1;};
79 // int get_naxis2() { return naxis2;};
80 //private:
81 // const char * DB_host;
82 // const char * DB_name;
83 // const char * DB_user;
84 // const char * DB_pswd;
85 // const char * TABLE_name;
86 // const char * SERVER_name;
87 //#ifndef __CINT__
88 // QSqlDatabase db;
89 //#endif
90 // static int dbOK;
91 // static int dataOK;
92 // static int bitpix;
93 // static int naxis;
94 // static int naxis1;
95 // static int naxis2;
96 // string dir_name;
97 // int Nfiles;
98 // set <string> FName;
99 //};
100 //
101 //int FFileDB::dbOK = 0;
102 //int FFileDB::dataOK = 0;
103 //int FFileDB::bitpix = 0;
104 //int FFileDB::naxis = 0;
105 //int FFileDB::naxis1 = 0;
106 //int FFileDB::naxis2 = 0;
107 //
108 //FFileDB::FFileDB( const string & d_name ) :
109 // DB_host ("localhost"),
110 // DB_name ("LSSTsensor"),
111 // DB_user ("ccdtest"),
112 // DB_pswd ("sensor"),
113 // TABLE_name ("TestInfo"),
114 // SERVER_name ("mysql"),
115 // dir_name(d_name),
116 // Nfiles(0)
117 //{
118 // char * driver = "QMYSQL";
119 // QSqlError err;
120 // int cCount = 0;
121 // db = QSqlDatabase::addDatabase(driver, QString("Browser%1").arg(++cCount));
122 // db.setDatabaseName( DB_name );
123 // db.setHostName( DB_host);
124 //
125 // cout << "MySQL CONNECTION: ------------------------------------" << endl;
126 // if ( !db.open(DB_user, DB_pswd) ) {
127 // err = db.lastError();
128 // db = QSqlDatabase();
129 // QSqlDatabase::removeDatabase(QString("Browser%1").arg(cCount));
130 // cout << err.text().toLocal8Bit().constData() << endl;
131 // return;
132 // }
133 // dbOK = 1;
134 // cout << "CONNECTED ------------------------------------" << endl;
137 // QStringList t = db.tables();
138 // cout << "SQL TABLES: --------------------------------------" << endl;
139 // for (int i = 0; i < t.size(); ++i)
140 // cout << t.at(i).toLocal8Bit().constData() << endl;
142 //}
143 //
144 //int FFileDB::SelectFiles( void )
145 //{
146 // char stmnt[200];
147 // Nfiles = 0;
148 // cout << "SQL: Select from FileLocation TABLE-------------------" << endl;
149 // sprintf(stmnt,"SELECT FileName FROM FileLocation WHERE DirName ='%s'", dir_name.c_str());
150 // cout << stmnt << endl;
151 // QSqlQuery query = db.exec(stmnt);
152 // QSqlRecord rec = query.record();
153 // QString qValue;
154 // while (query.next()) {
155 // qValue = query.value(0).toString();
156 // FName.insert(qValue.toLocal8Bit().constData()); // qValue.toString());
157 // Nfiles++;
158 // cout << Nfiles << ". " << qValue.toLocal8Bit().constData() << endl;
159 // }
160 // cout << "DB.Nfiles=" << Nfiles << endl;
161 // return Nfiles;
162 //}
163 //
164 //set<string> FFileDB::GetFnames( void )
165 //{
166 // string filename;
167 // set<string> CFiles;
168 // set<string>::iterator ii = FName.begin();
169 // for(; ii != FName.end(); ii++)
170 // {
171 // filename = dir_name + "/" + *ii + ".fits";
172 // CFiles.insert(filename);
173 // }
174 // return CFiles;
175 //}
176 //
177 //void FFileDB::GetFparams()
178 //{
179 // dataOK = 1;
180 // char stmnt[200];
181 // cout << "SQL: Select from TestInfo TABLE-------------------" << endl;
182 // set<string>::iterator it = FName.begin();
183 // for( ; it != FName.end(); it++)
184 // {
185 // sprintf(stmnt,"SELECT BITPIX, NAXIS, NAXIS1, NAXIS2 FROM TestInfo WHERE FileName ='%s'", it->c_str());
186 // cout << stmnt << endl;
187 // QSqlQuery query = db.exec(stmnt);
188 // QSqlRecord rec = query.record();
189 // //QString qValue;
190 // while (query.next()) {
191 // for (int j = 0; j <rec.count(); j++)
192 // {
193 // //qValue = query.value(j).toString();
194 // //qValue = query.value(j).toInt();
195 // int iValue = query.value(j).toInt();
196 // switch(j){
197 // case 0:
198 // if (!bitpix) bitpix = iValue;
199 // else
200 // if (bitpix != iValue){
201 // printf("Error:: bitpix has new value %d\n", iValue);
202 // dataOK = 0;
203 // }
204 // break;
205 // case 1:
206 // if(!naxis) naxis = iValue;
207 // else
208 // if (naxis != iValue){
209 // printf("Error:: naxis has new value %d\n", iValue);
210 // dataOK = 0;
211 // }
212 // break;
213 // case 2:
214 // if(!naxis1) naxis1 = iValue;
215 // else
216 // if (naxis1 != iValue){
217 // printf("Error:: naxis1 has new value %d\n", iValue);
218 // dataOK = 0;
219 // }
220 // break;
221 // case 3:
222 // if(!naxis2) naxis2 = iValue;
223 // else
224 // if (naxis2 != iValue){
225 // printf("Error:: naxis2 has new value %d\n", iValue);
226 // dataOK = 0;
227 // }
228 // break;
229 // default:
230 // printf("Error:: default for j=%i \n", j);
231 // dataOK = 0;
232 // break;
233 // } //end switch
234 // } //end records
235 // } //end query
236 // } //end files
237 //} //end GetFparams()
238 //
239 
240 //---------------------------------------------------------------------
241 // DataStr class ---------------------------------------------------------
242 class DataStr{
243 private:
244  static DataStr * pInstance;
245 protected:
246  double pixsz;
247  int device;
248  int xmin, xmax; //"active" range
249  int ymin, ymax;
250  int NXpres, NYpres; //pre-scan
251  int NXover, NYover;
252  int oxmin, oxmax; //overscan range
253  int oymin, oymax;
254 
255  DataStr (int nx, int ny);
256  ~DataStr(){};
257 public:
258  static DataStr * Instance( int nx, int ny);
259  double PixSz(){ return pixsz;}
260  int minX(){ return xmin; }
261  int maxX(){ return xmax; }
262  int NoverX(){ return NXover; }
263  int OmiXs(){ return (oxmin+8); }
264  int OmiX(){ return oxmin; }
265  int OmaX(){ return oxmax; }
266  int minY(){ return ymin; }
267  int maxY(){ return ymax; }
268  int IsOver( int x, int y);
269  int IsOverX( int x);
270 };
271 
274 {
275  //static DataStr inst (nx, ny);
276  //return &inst;
277  if ( pInstance == 0 ) {
278  pInstance = new DataStr (nx,ny);
279  }
280  return pInstance;
281 }
282 
283 DataStr::DataStr (int nx, int ny)
284 {
285  device = -1;
286  NYpres=0;
287 
288  // SIX device 2018
289  if ( (nx == 3302) && (ny == 1612) ){
290  pixsz = 16.;
291  device = 3;
292  NXpres = 1665; //0;
293  NXover = 1665; //1665;
294  NYpres = 1;
295  NYover = 1;
296  printf(" DataStr::DataStr device = XCAM \n");
297  printf(" PixSz= %f device_id=%i \n", pixsz, device);
298  xmin = NXpres;
299  xmax = nx - 1; // for SIX LS: nx-1;
300  oxmin = 1; // for SIX LS: 1
301  oxmax = xmin; // for SIX LS: xmin
302  ymin = NYpres;
303  ymax = ny - NYover;
304  oymin = ymax;
305  oymax = ny;
306  return;
307  }
308  if ( (nx == 1652) && (ny == 1612) ){
309  pixsz = 16.;
310  device = 3;
311  NXpres = 16; //0;
312  NXover = 1; //1665;
313  NYpres = 1;
314  NYover = 1;
315  printf(" DataStr::DataStr device = XCAM active area \n");
316  printf(" PixSz= %f device_id=%i \n", pixsz, device);
317  xmin = NXpres;
318  xmax = nx - NXover; // for SIX LS: nx-1;
319  oxmin = 1; // for SIX LS: 1
320  oxmax = xmin-1; // for SIX LS: xmin
321  ymin = NYpres;
322  ymax = ny - NYover;
323  oymin = ymax;
324  oymax = ny;
325  return;
326  }
327  //Swiss Light Source Camera
328  if ( (nx == 817) && (ny == 1606) ){
329  pixsz = 10.;
330  device = 4;
331  NXpres = 1;
332  NXover = 1;
333  NYpres = 1;
334  NYover = 1;
335  printf(" DataStr::DataStr device = Swiss \n");
336  printf(" PixSz= %f device_id=%i \n", pixsz, device);
337  xmin = NXpres;
338  xmax = nx - 1; // for SIX LS: nx-1;
339  oxmin = 1; // for SIX LS: 1
340  oxmax = xmin; // for SIX LS: xmin
341  ymin = NYpres;
342  ymax = ny - NYover;
343  oymin = ymax;
344  oymax = ny;
345  return;
346  }
347 
348  // STA3800B
349 // if ( (nx == 544) && (ny == 2048) ){
350 // pixsz = 10.;
351 // device = 2;
352 // NXpres = 3;
353 // NXover = 32;
354 // NYover = 48;
355 // printf(" DataStr::DataStr device = STA3800B \n");
356 // printf(" PixSz= %f device_id=%i \n", pixsz, device);
357 // }
358 
359  // e2v CCD250 March 2017
360 // if ( (nx == 572) && (ny == 2048) ){
361 // pixsz = 10.;
362 // device = 1;
363 // NXpres = 10;
364 // NXover = nx-NXpres-512;
365 // if (NXover < 0) NXover=0;
366 // NYover = ny-2002;
367 // if (NYover < 0) NYover=0;
368 // printf(" DataStr::DataStr device = e2v CCD250 \n");
369 // printf(" PixSz= %f device_id=%i \n", pixsz, device);
370 // }
371 
372  if ( device < 0) {
373  printf(" DataStr::DataStr - not recognized device, use default \n");
374  pixsz = 10.;
375  NXpres = 10;
376  NXover = nx-NXpres-512;
377  if (NXover < 0) NXover=0;
378  NYover = ny-2002;
379  if (NYover < 0) NYover=0;
380  printf(" DataStr::DataStr default as e2v CCD250 %i (%i,%i) %i (%i,%i) \n",
381  nx,NXpres,NXover, ny,NYpres,NYover);
382  printf(" PixSz= %f device_id=%i \n", pixsz, device);
383  }
384 // calculate dev parameters
385 
386  xmin = NXpres;
387  xmax = nx - NXover; // - NXover; for SIX LS: nx-1;
388  oxmin = xmax; //xmax; for SIX LS: 1
389  oxmax = nx; //nx; for SIX LS: xmin
390  ymin = NYpres;
391  ymax = ny - NYover;
392  oymin = ymax;
393  oymax = ny;
394 
395 } //end constructor DataStr
396 
397 int DataStr::IsOver( int x, int y)
398 {
399  if ( x >= oxmin &&
400  x <= oxmax ) {return 1;}
401  if ( y >= oymin &&
402  y <= oymax ) {return 1;}
403  return 0;
404 }
405 
407 {
408  if ( x >= oxmin &&
409  x <= oxmax ) {return 1;}
410 // if ( x < xmin ) return 1;
411  else {return 0;}
412 }
413 
414 //---------------------------------------------------------------------
415 // FileF class ---------------------------------------------------------
416 class FileF{
417 public:
418  const char * fname;
419  fitsfile *fptr;
420  fitsfile *fout;
421  int iEOF;
422  int Nhdu;
423  int hdu;
424  int hdutype;
425  enum { MaxP = 22 }; // Max number of hdu (channels/amplifiers)
426 
427  long * buffer;
428 // unsigned short * buffer;
429 // vector<unsigned short> buffer;
430 
431  static unsigned short nullval;
432  int anynull;
433  char strnull[10];
434  int status;
435  char comment[FLEN_CARD];
436  int bitpix;
437  double bzero;
438  double bscale;
439  int naxis;
440  enum { MAXIS = 10 };
441  long naxes[MAXIS];
442  long nx, ny;
443  unsigned long npixels; /* number of pixels in the image */
444  const long fpixel;
445  unsigned short datamin;
446  unsigned short datamax;
447 
448  static const int klength;
449  static const char valuebegin;
450  static const char valuend;
451  int Ncards;
452  enum { Lcard = FLEN_CARD };
453  char card[Lcard];
454  char value_str[Lcard];
455  char keyword[Lcard];
456  double value;
457 
458  double ltv1;
459  double ltv2;
460  double ltm1_1;
461  double ltm1_2;
462  double ltm2_1;
463  double ltm2_2;
464 
465  typedef pair <string, double> H_Pair;
466  map <string, double>::iterator H_Iter;
467  std::pair<map <string, double>::iterator, bool> pptr;
468  map <string, double> mHeader;
469 
470 // table variables
471  int lTable; // 1= good table
472  char TableName[FLEN_VALUE];
473  int ncols;
474  static long nrows;
475  enum { NbCol = 2 }; // number of columns
476  char * ColName[NbCol];
477  static vector<double> TabData[NbCol];
478  static const char * FieldName[NbCol];
479 
480 public:
481  FileF ();
482  ~FileF();
483  int Open( const char * file_name );
484  void Close();
485  int Read(int copy =0);
486  void PrimeOut (long Nx, long Ny );
487  void CloseOut ();
488  int OpenOutF ( const char * fOutName = "Out_bufzs" );
489  int OutFitsF( unsigned short * buf);
490  int getValue( const char * name, double * value );
491 // vector<unsigned short> &Pbuf() {return buffer;};
492 // unsigned short * Pbuf() {return buffer;};
493  void PrintKeys( void );
494 };
495 
496 // initialization of static members
497 unsigned short FileF::nullval = 0; // don't check for null values in the image
498 const int FileF::klength = 8;
499 const char FileF::valuebegin = '=';
500 const char FileF::valuend = '/';
501 const char * FileF::FieldName[NbCol]={"TIMES","CURRENT"};
502 long FileF::nrows;
503 vector<double> FileF::TabData[NbCol];
504 
506 // delete [] buffer; buffer = 0;
507  for (int i = 0; i < NbCol; i++) { /* deallocate space for the column labels */
508  delete [] ColName[i]; ColName[i]=0;
509  //delete [] TabData[i]; TabData[i]=0;
510  }
511 }
512 
514  fptr(0),
515  buffer(0),
516  anynull(0),
517  status(0),
518  fpixel(1),
519  datamin(65535),
520  datamax(0),
521  Ncards(0)
522 {
523  strcpy(strnull, " ");
524  for (int i = 0; i < NbCol; i++) { /* allocate space for the column labels */
525  ColName[i] = new char[FLEN_VALUE]; /* max label length = 69 */
526  memset(ColName[i], 0, FLEN_VALUE);
527  //TabData[i]= new double[2500];
528  //memset(TabData[i], 0, 2500*sizeof(double));
529  }
530 
531 } //end constructor FileF
532 
533 
534 int FileF::OpenOutF( const char * fOutName )
535 {
536  status = 0;
537  char foutname[200];
538  strcpy (foutname, fOutName);
539  strcat (foutname, ".fits");
540  printf( " OpenOutF name = %s \n", foutname);
541 
542  remove(foutname);
543  fits_create_file( &fout, foutname, &status); // create output FITS file
544  if ( status ) {printf(" create_file status error: %i \n", status); return -6;}
545  printf(" OpenOutF:: hdu=%i \n", fout->HDUposition);
546 
547  return 0;
548 }
549 
551 {
552  fits_close_file( fout, &status);
553  if ( status ) printf(" CloseOut status error: %i \n", status);
554 }
555 
556 void FileF::PrimeOut (long Nx, long Ny )
557 {
558  nx = Nx;
559  ny = Ny;
560 
561  bitpix = 16; // 64-bit floating point values
562  naxis = 2; // 2-dimensional image
563  status = 0;
564  bzero = 32768.0;
565  bscale = 1.0;
566  naxis = 2; // 2-dimensional image
567  naxes[0] = nx;
568  naxes[1] = ny;
569  int channels =2;
570 
571  if (fits_create_img( fout, bitpix, 0, NULL, &status))
572  fits_report_error(stderr, status );
573  if ( fits_update_key(fout, TINT, "BZERO", &bzero,"", &status) )
574  fits_report_error(stderr, status );
575  if ( fits_update_key(fout, TINT, "BSCALE", &bscale,"", &status) )
576  fits_report_error(stderr, status );
577  if ( fits_update_key(fout, TINT, "NEXTEND", &channels,"", &status) )
578  fits_report_error(stderr, status );
579 // if ( fits_update_key(fout, TSTRING, "DATE", &sdate,"", &status) )
580 // fits_report_error(stderr, status );
581  if ( fits_update_key(fout, TSTRING, "COMMENT", &comment,"", &status) )
582  fits_report_error(stderr, status );
583  printf(" primary header done \n");
584 }
585 
586 int FileF::OutFitsF( unsigned short * buf)
587 {
588  status = 0;
589  npixels = nx*ny;
590  char detector[] = "XCAM ";
591  char cname[10] = "Ch";
592 
593 // HEADER ----------------
594  if (fits_create_img( fout, bitpix, naxis, naxes, &status)) {fits_report_error(stderr,status);}
595  if ( fits_update_key(fout, TSTRING, "EXTNAME", cname,"Channel number", &status) )
596  fits_report_error(stderr, status );
597  if ( fits_update_key(fout, TDOUBLE, "BZERO", &bzero,"", &status) )
598  fits_report_error(stderr, status );
599  if ( fits_update_key(fout, TINT, "BITPIX", &bitpix,"BITS PER PIXEL", &status) )
600  fits_report_error(stderr, status );
601  if ( fits_update_key(fout, TDOUBLE, "BSCALE", &bscale,"", &status) )
602  fits_report_error(stderr, status );
603  if ( fits_update_key(fout, TSTRING, "DETECTOR", detector,"DETECTOR ID", &status) )
604  fits_report_error(stderr, status );
605 
606 // DATA ---------------------------------------------------
607 // unsigned short * outb = new unsigned short[npixels];
608 // for (unsigned long i=0; i<npixels;i++) {
609 // double amp = buf[i] + 100.;
610 // if ( amp < 0.) amp = 0.;
611 // if ( amp > 65535.) amp = 65535.;
612 // outb[i] = (unsigned short)amp;
613 // }
614  fits_write_img( fout, TUSHORT, fpixel, npixels, buf, &status);
615  if ( status ) {printf(" write_img status error: %i \n", status); return -6;}
616 
617  //delete [] outb;
618  return 0;
619 }
620 
622 {
623  fits_close_file (fptr, &status);
624  delete [] buffer; buffer = 0;
625 // buffer.clear();
626 }
627 
628 int FileF::Open( const char * file_name )
629 {
630  iEOF = 0;
631  //fname = file_name;
632  fits_open_file (&fptr, file_name, READONLY, &status);
633  if (status) { printf(" FileF::Open::status error: %i %s \n", status, file_name);
634  status=0;
635  return -1;
636  }
637  hdu = fptr->HDUposition + 1; // get the current HDU number
638  //fits_get_num_hdus(fptr, &Nhdu, &status); //get number of HDUs
639  //if (status) { printf(" FileF::Open::status:num_hdus error: %i \n", status);
640  // status=0;
641  // return -1;
642  //} else { printf(" Number of HDUs: %i \n", Nhdu); }
643  strcpy(TableName, " ");
644 
645  return 0;
646 }
647 
648 int FileF::Read( int copy)
649 {
650  lTable=0;
651  hdu = fptr->HDUposition + 1; // get the current HDU number
652  fits_get_hdu_type(fptr, &hdutype, &status); // get the HDU type
653 
654 // main header -------------------------------------------------------------
655  if (hdu == 1) { // read keys of the main header
656  mHeader.clear();
657  int morekeys=0;
658  fits_get_hdrspace( fptr, &Ncards, &morekeys, &status);
659  if (status) {printf( "FileF::ReadHeader status %i \n", status ); return -3;}
660  if ( Ncards < 1) return -3;
661 
662  char * cr = 0;
663  char * pdest =0;
664  int lngth;
665  int L;
666  for (int ik=0; ik<Ncards; ik++){
667  value=0.0;
668  memset(card, '\0',Lcard);
669  memset(value_str, '\0',Lcard);
670  memset(keyword, '\0',Lcard);
671 
672  fits_read_record (fptr, ik+1, card, &status);
673  if (status) {printf( "Read card %i status %i \n", ik, status ); return -3;}
674 
675  // keyword field
676  lngth = klength;
677  strncpy( keyword, card, lngth);
678  cr = card + lngth + 1; //move pointer to "behind the name" position
679  L = lngth-1;
680  while (L >= 0 && keyword[L]==' ') {keyword[L]='\0'; L--;}
681  int cond = strcmp( keyword, "COMMENT") &&
682  strcmp( keyword, "HISTORY") &&
683  strcmp( keyword, "SCRIPT") &&
684  strcmp( keyword, "CONTINUE");
685  if ( !cond ) continue;
686  if ( !strcmp( keyword, "HIERARCH") ){
687  pdest = strchr( cr, valuebegin );
688  lngth = (int)( pdest - cr );
689  strncpy( keyword, cr, lngth);
690  keyword[lngth] = '\0';
691  cr += lngth + 1; // move to "behind the name" position
692  }
693  L = lngth-1;
694  while (L >= 0 && keyword[L]==' ') {keyword[L]='\0'; L--;}
695 
696  // value field
697  pdest = strchr( cr, valuend );
698  if (pdest != 0) {
699  lngth = (int)( pdest - cr );
700  strncpy( value_str, cr, lngth);
701  value_str[lngth]='\0';
702  cr += lngth + 1; // move to "behind the name" position
703  }
704  else lngth = 0;
705 
706  L = lngth-1;
707  while (L >= 0 && value_str[L]==' ') {value_str[L]='\0'; L--;}
708  lngth = L+1;
709 
710  cr = value_str;
711  L = 0;
712  while (L <lngth && value_str[L]==' ') {cr++; L++;}
713  lngth -= --L;
714  strncpy( value_str, cr, lngth );
715  value_str[lngth]='\0';
716 
717  if ( value_str[0] =='T' ) value = 1.0;
718  else value = atof( value_str );
719  pptr = mHeader.insert( H_Pair(keyword, value) );
720  if (!pptr.second){
721  printf (" This key: %s already exists; attemted value %f \n", keyword, value);
722  }
723  }
724  //PrintKeys();
725  }
726 
727 // copy header
728  if ( copy && (hdutype == IMAGE_HDU) ) {
729  printf(" OutFitsF:: fptr.hdu=%i fout.hdu=%i \n",
730  fptr->HDUposition, fout->HDUposition);
731  fits_copy_header( fptr, fout, &status); //ffcphd
732  if ( status ) {printf(" create_img status error: %i \n", status); return -6;}
733  printf(" OutFitsF:: fout.hdu=%i \n", fout->HDUposition);
734  }
735 
736 // data ---------------------------------------------------------------
737 
738  naxis=0;
739  if (hdutype == IMAGE_HDU)
740  {
741  fits_get_img_param( fptr, MAXIS, &bitpix, &naxis, naxes, &status);
742  if (status) {printf( "Get_img_param status %i \n", status ); return -5;}
743  //printf(" NAXIS=%i naxes[0]=%ld naxes[1]=%ld \n", naxis, naxes[0], naxes[1]);
744 
745  // coordinate transformation parameters
746  ltv1=ltv2 =0.;
747  ltm1_1=ltm2_2= 1.;
748  ltm1_2=ltm2_1= 0.;
749 
750  fits_read_key(fptr, TDOUBLE, "LTV1", &ltv1, 0, &status);
751  if (status) {/*printf( "Get_LTV1_param status %i \n", status );*/ status=0;}
752 
753  fits_read_key(fptr, TDOUBLE, "LTV2", &ltv2, 0, &status);
754  if (status) {/*printf( "Get_LTV2_param status %i \n", status );*/ status=0;}
755 
756  fits_read_key(fptr, TDOUBLE, "LTM1_1", &ltm1_1, 0, &status);
757  if (status) {/*printf( "Get_LTM1_1_param status %i \n", status );*/ status=0;}
758 
759  fits_read_key(fptr, TDOUBLE, "LTM2_2", &ltm2_2, 0, &status);
760  if (status) {/*printf( "Get_LTM2_2_param status %i \n", status );*/ status=0;}
761 
762 
763  if ( naxis > 0 ) {
764  nx = naxes[0];
765  ny = naxes[1];
766  npixels = naxes[0] * naxes[1]; // number of pixels in the image
767  //if (buffer == 0) buffer = new unsigned short[npixels]; // buffer.resize(npixels,0);
768  //fits_read_img ( fptr, TUSHORT, fpixel, npixels, &nullval,
769  // &buffer[0], &anynull, &status);
770 
771  if (buffer == 0) {buffer = new long[npixels];} // buffer.resize(npixels,0);
772  fits_read_img ( fptr, TLONG, fpixel, npixels, &nullval,
773  &buffer[0], &anynull, &status);
774  if (status) { printf( "Read_Img status %i \n", status ); return -5; }
775  }
776  }
777 
778  if (hdutype == BINARY_TBL)
779  {
780  // get TableName from EXTNAME, example "AMP0.MEAS_TIMES"
781  fits_read_key_str(fptr, "EXTNAME", TableName, NULL, &status);
782 
783  //printf("\nReading binary table %s from HDU %d:\n", TableName, hdu);
784 
785  /* gets number of rows and columns */
786  fits_get_num_rows(fptr, &nrows, &status) ;
787  fits_get_num_cols(fptr, &ncols, &status);
788  //printf(" NRows = %i NCols = %i\n", nrows, ncols);
789 
790  /* read the column names from the TTYPEn keywords */
791  int colnum[NbCol] = {0};
792  long frow =1;
793  long felem=1;
794  int nfound;
795  fits_read_keys_str(fptr, "TTYPE", 1, NbCol, ColName, &nfound, &status);
796  //printf(" names found =%i Row %10s %10s\n", nfound, ColName[0], ColName[1]);
797  if ( nfound != NbCol ) goto BadTable;
798 
799  for (int i=0; i<NbCol; i++){
800  if ( strstr(ColName[i], FieldName[0])) { colnum[0]=i+1;}
801  if ( strstr(ColName[i], FieldName[1])) { colnum[1]=i+1;}
802  TabData[i].assign(nrows,0.0);
803  }
804 
805  /* read columns */
806  for (int i=0; i<NbCol; i++){
807  int typecode;
808  long repeat, width;
809  fits_get_coltype(fptr, colnum[i], &typecode, &repeat, &width, &status);
810  fits_read_col(fptr, typecode, colnum[i], frow, felem, nrows, strnull, &TabData[i][0], &anynull,
811  &status);
812  }
813  if ( status ) {
814  printf(" FileF::Read BINARY_TBL problem: status=%i \n", status);
815  lTable=0; status = 0;
816  } else { lTable=1;}
817 
818  BadTable: ; //printf( "Jump over BadTable:%s nfound=%i\n", TableName, nfound);
819  }// end tbl if
820 
821  Nhdu = hdu;
822  fits_movrel_hdu( fptr, 1, NULL, &status); // move to the next HDU
823  //printf( " Movrel: %s Nhdu=%i hdu=%i status=%i \n", fname, Nhdu, hdu, status);
824  if ( status ) {status = 0; iEOF=1;} // Reset normal error, == END_OF_FILE
825  return 0;
826 }
827 
828 int FileF::getValue ( const char * name, double * Value )
829 {
830  H_Iter =mHeader.find(name);
831  if ( H_Iter == mHeader.end( ) ) {*Value=0.; return 1;}
832  else {*Value= H_Iter->second; return 0; }
833 
834  return 1;
835 }
836 
838 {
839  int msize = mHeader.size();
840  printf(" FileF::PrintKeys Ncards= %i MapSize= %i \n", Ncards, msize);
841  int i=0;
842  for (H_Iter=mHeader.begin(); H_Iter != mHeader.end(); H_Iter++, i++){
843  string name = H_Iter->first;
844  double val = H_Iter->second;
845  printf(" %2i. %s:: %f \n", i, name.c_str(), val );
846  }
847  return;
848 }
849 
850 //---------------------------------------------------------------------
851 // FileList class ---------------------------------------------------------
852 class FileList {
853 public:
854 
855  string dir_name;
856  string fname;
857  int Nfile;
858  set <string> FName;
859  set <string>::iterator FName_Iter;
860 
861 public:
862  FileList ( string dir_name );
864 };
865 
866 FileList::FileList ( string dir_nm ):
867  Nfile(0)
868 {
869  printf(" FileList::dir_nm: %s \n", dir_nm.c_str());
870  const char *afile;
871  const char fstr[] = ".fits";
872  const char * pdest = strstr( dir_nm.c_str(), fstr );
873 
874  if ( pdest != 0 ){
875  FName.insert( dir_nm );
876  Nfile++;
877  printf(" FileList:: Single file %i: %s \n", Nfile, dir_nm.c_str());
878  }
879  else { // list files from the directory -----------------------------
880  void *dirp = gSystem->OpenDirectory(dir_nm.c_str());
881  while( (afile = gSystem->GetDirEntry(dirp)) ) {
882  pdest = strstr( afile, fstr );
883  if ( pdest == 0 ) continue;
884  fname = afile;
885  fname = dir_nm + "/" + fname;
886  FName.insert( fname );
887  printf(" %i: %s \n", Nfile, fname.c_str());
888  Nfile++;
889  }
890  printf(" FileList::Nfiles = %i \n", Nfile);
891  }
892 
893  return;
894 } //end FileList constructor
895 
896 
897 
898 //---------------------------------------------------------------------
899 // FFT class ---------------------------------------------------------
900 class FFT
901 {
902 public:
903 
904  const char * FFTName;
905  const int minData;
906  const int maxData;
907  const int minLine;
908  const int maxLine;
909  const int stepD;
910  const int stepL;
911 
912  const int Nline;
913  const int Ndata;
914  const int Nfreq;
915 
916  double * inA;
917  fftw_complex * outF;
918  fftw_plan p1d;
919 
920  vector<double> Freq;
921  vector<double> PSDs;
922  enum { MaxP = 20 };
923  vector<double> PSDav[MaxP];
924 
925  double * DaAv;
926 
927  TH1D * hbuf[4];
928 
929  int jb;
930  int sbtr;
931  const int kf; //58 for rows 20130123
932  const double Fk;
933  const double Farg;
934  const double Ak;
935 
936 public:
937  FFT( const char * Name,
938  const int minD, const int maxD,
939  const int minL, const int maxL,
940  const int stepD, const int stepL,
941  const int FrInd=0, const double Afk=2. );
942  void DTrans(double * buf, const int idu, int sub);
943  void Plot_FFT(const int Nch);
944  ~FFT();
945 }; //end FFT class
946 
948 {
949  fftw_free(inA); inA = 0;
950  fftw_free(outF); outF = 0;
951  fftw_destroy_plan(p1d); p1d=0;
952 
953  delete [] DaAv; DaAv = 0;
954 }
955 
956 void FFT::Plot_FFT( int Nch )
957 {
958  const float left_margin = (float)0.04;
959  const float right_margin = (float)0.001;
960  const float top_margin = (float)0.01;
961  const float bot_margin = (float)0.04;
962 
963  if (Nch > MaxP) Nch=MaxP;
964  const int Ncha=Nch;
965  TCanvas * Tr[MaxP];
966 for (int u=0; u<Ncha; u++){ //Nhdu
967  int ich=u+1;
968  char tiname[50];
969  char PDFname[50];
970  sprintf(tiname, "%s %i", FFTName, ich);
971  sprintf(PDFname, "%s_%i.pdf", FFTName, ich);
972  Tr[u] = new TCanvas( tiname, tiname, 200+4*u, 10+2*u, 800, 600);
973  Tr[u]->SetBorderMode (1); //to remove border
974  Tr[u]->SetLeftMargin (left_margin); //to move plot to the right 0.14
975  Tr[u]->SetRightMargin (right_margin); //to move plot to the right 0.05
976  Tr[u]->SetTopMargin (top_margin); //to use more space 0.07
977  Tr[u]->SetBottomMargin(bot_margin); //default
978  Tr[u]->SetFrameFillColor(0);
979  Tr[u]->Divide(1,1);
980 
981 /***************** Plot Power Spectrum *************/
982  printf(" Start draw Power Spectrum for %s %i\n\n", FFTName, u);
983  Tr[u]->cd(1);
984  gPad->SetLogy();
985  gPad->SetLogx();
986 
987  do {
988  int Npsd = PSDav[ich].size();
989  int Nfrq = Freq.size();
990  printf(" RowPSD points =%i RowFreq size=%i *** \n", Npsd, Nfrq);
991  if ( Npsd <= 3 ) continue;
992  int nn = Npsd -3;
993  if ( Nfrq < nn ) continue;
994  TGraph * std6 = new TGraph( nn, &Freq[0], &PSDav[ich][0]);
995  std6->SetTitle(FFTName);
996  std6->GetYaxis()->SetTitle("PSD ");
997  std6->GetXaxis()->SetTitle("k/N, 1/pixel");
998  std6->SetMarkerColor(4);
999  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 };
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
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 
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 
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 
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