emcRawDataCalibratorV2.C

Go to the documentation of this file.
00001 //-------------------------------------------------------------------------
00002 // $Id: emcRawDataCalibratorV2.C,v 1.31 2005/04/17 00:19:52 phnxemc Exp $
00003 // <EK> 111302 Implementation for Run3
00004 // 
00005 // Package: Calib
00006 // 
00007 // Copyright (C) PHENIX collaboration, 1999-2001
00008 //
00009 // Implementation of class : emcRawDataCalibratorV2
00010 //
00011 // Authors: Real calculation content = E. Kistenev (kistenev@bnl.gov)
00012 //          C++ consulting = L. Aphecetche (aphecetc@in2p3.fr)
00013 //
00014 //-------------------------------------------------------------------------
00015 
00016 #include "emcRawDataCalibratorV2.h"
00017 
00018 #include "emcRawDataAccessor.h"
00019 #include "emcMixedDataObject.h"
00020 #include "emcCalibratedDataObject.h"
00021 #include "EmcDynamicData.h"
00022 #include "emcDataFormatter.h"
00023 #include "emcHLRatios.h"
00024 #include "emcPedestals5.h"
00025 #include "emcGains.h"
00026 #include "emcGainFEM.h" 
00027 #include "emcLCTofs.h"
00028 #include "emcQAs.h"
00029 #include "emcWalkTofs.h" 
00030 //#include "emcTofT0s.h"
00031 #include "emcTacPeds.h"
00032 #include "EmcStaticData.h"
00033 #include "emcDataManager.h"
00034 #include "EmcSector.h"
00035 #include "emcCalibrationData.h"
00036 #include "EmcIndexer.h"
00037 #include "emcFEMtupleFactory.h"
00038 #include "emcHLRatioFEM.h"
00039 #include "emcPedestalFEM.h"
00040 #include "pbscTimingFixes.h"
00041 
00042 #include <cassert>
00043 #include <iostream>
00044 #include <fstream>
00045 #include <cmath>
00046 #include <cstdlib>
00047 #include <vector>
00048 
00049 #include "emcException.h"
00050 #include "emcDefines.h"
00051 
00052 using std::vector ;
00053 using std::cout ;
00054 using std::cerr ;
00055 using std::endl ;
00056 using std::ifstream ;
00057 using std::string;
00058 
00059 static const string kTACPED = "TAC";
00060 static const string kHG_Pre = "HG_Pre";
00061 static const string kHG_Post = "HG_Post";
00062 static const string kLG_Pre = "LG_Pre";
00063 static const string kLG_Post = "LG_Post";
00064 
00065 namespace {
00066 
00067   float walkCorrection(float amp)
00068   {
00069     static const float walkCorrections[] = {
00070       //  the first 6 or 7 numbers in this table are badly defined (no data). Unless the data are available - there was no point in trying to improve the parametrisation
00071       0.0277778, 0.107143, 0.173529, 0.0543478, 0.116667, 0.10, 0.0744804, 0.0957627, 0.164296, 0.077351, 0.153276, 0.205479, 0.164593, 0.165495, 0.21152, 0.24188, 0.26691, 0.264707, 0.260216, 0.235105, 0.170128, 0.101093, 0.0506275, 0.0129709, -0.0310411, -0.0710098, -0.107253, -0.155408, -0.190727, -0.217815, -0.236577, -0.241337, -0.241553, -0.242847, -0.232342, -0.215285, -0.206976, -0.191099, -0.172913, -0.152418, -0.126642, -0.102625, -0.083642, -0.0752175, -0.0562135, -0.0406164, -0.0194486, -0.00347076, 0.0184414, 0.0312518, 0.0502009, 0.0678629, 0.0832042, 0.0936487, 0.103101, 0.114466, 0.137864, 0.156677, 0.169112, 0.174417, 0.173401, 0.17573, 0.185781, 0.201714, 0.215833, 0.22749, 0.240455, 0.246843, 0.252532, 0.256536, 0.262321, 0.26874, 0.278161, 0.285608, 0.289092, 0.290117, 0.301697, 0.308295, 0.316562, 0.331756, 0.334545, 0.34805, 0.362435, 0.36986, 0.373365, 0.382179, 0.405925, 0.396395, 0.406755, 0.421493, 0.430347, 0.440847, 0.457075, 0.463535, 0.458969, 0.466124, 0.479996, 0.487251, 0.489726, 0.494271
00072     };
00073     
00074     int bin=int(amp/10);
00075     if(bin>=100) bin=99;
00076     return walkCorrections[bin];
00077   }
00078 }
00079 
00080 //-------------------------------------------------------------------------
00081 emcRawDataCalibratorV2::emcRawDataCalibratorV2() : emcCalibrator()                
00082 {
00083   fName = "emcRawDataCalibratorV2" ; // must be the classname (because it's used by the Factory)
00084   Reset() ;
00085 }
00086 
00087 //-------------------------------------------------------------------------
00088 emcRawDataCalibratorV2::~emcRawDataCalibratorV2()
00089 {
00090 }
00091 
00092 //_____________________________________________________________________________
00093 bool emcRawDataCalibratorV2::Calibrate(const emcRawDataObject& const_rdo,
00094                          emcMixedDataObject& mdo,
00095                          const PHTimeStamp& when)
00096 {
00097   /* Make ADC and TDC values out of the RawDataObject.
00098 
00099      To perform this, we need to get access to some calibration objects :
00100      a) pedestals
00101      b) high/low gain ratios
00102 
00103      Those objects are collected from the database (being file or Objy)
00104      using the DataManager.
00105 
00106      NOTE: mdo can't be zero suppressed, if done - it will create a problem 
00107      in calibrating data. Associating suppressed data with Gains will 
00108      require search what is simply too time consuming.
00109    */
00110 
00111   float INVALID_FLOAT = -9999 ;
00112 
00113   // This method lies about it's use of rdo.  It claims it'll be
00114   // treated as const, but then it modifies it.  This line is a HACK
00115   // and should be properly fixed by an expert.
00116   emcRawDataObject& rdo = const_cast<emcRawDataObject&>(const_rdo);
00117     
00118   bool rv = true ; 
00119 
00120   if (fMustCollectForMDO) {
00121     CollectForMDO(when) ;
00122     fMustCollectForMDO = false ;
00123   }
00124 
00125   // Sets the corresponding flags of the MDO
00126   mdo.SetPedestalFlag(fCollectPedestalStatus) ; 
00127   mdo.SetHLRatioFlag(fCollectHLRatioStatus) ; 
00128 
00129   // Initialize the MDO from the RDO
00130   int* datamap ;
00131   long* softkeys ;
00132   int* dataerrors ;
00133   rdo.GetDataDescriptionPointers(datamap,softkeys,dataerrors) ;
00134   mdo.SetMaxSize(rdo.GetMaxSize()) ;
00135   Int_t* deadmap = 0;
00136   Int_t* warnmap = 0 ;
00137 
00138   if(fQA){
00139     deadmap = fQA->GetDeadMap();
00140     assert(deadmap!=0) ;
00141     warnmap = fQA->GetWarnMap() ;
00142     assert(warnmap!=0) ;
00143   }
00144   mdo.SetDataDescriptionPointers(datamap,softkeys,dataerrors,deadmap,warnmap) ;
00145 
00147   Int_t index ;
00148   Float_t adc,tdc ;
00149   Float_t hgpost,hgpre,lgpost,lgpre ;
00150   Float_t phg, plg;
00151   Float_t lg, hg ;
00152   int amupre,amupost,amutac ;
00153   int data_error ;
00154   float newTDCValue, tacped;
00155   float scale=0.0;
00156 
00157   // Loop over towers
00158 
00159   for (index = 0; index < rdo.GetSize(); index++ ) {
00160 
00161     int TowerId = rdo.GetItemId(index); 
00162 
00163     // Is the channel to be declared dead ?
00164     if ( mdo.GetDead(index) & emcQAs::IamDeadMask() ) {
00165       mdo.AddDataError(index,0x2000);
00166       mdo.SetToZero(index) ;
00167       continue;
00168     }
00169 
00170     //  rdo.IsZero should identify the channels which are pedestal 
00171     //  suppressed in DCM. We are using it at all stages of data processing 
00172     //  so - there is no real need to reset to zero locations in mdo which 
00173     //  contain non-zero values from previous event (time saving). 
00174     //  We'll keep this for the time being but - it can be removed later.
00175     
00176     if (rdo.IsZero(index)) {
00177       mdo.SetToZero(index) ;
00178       continue;
00179     }
00180 
00181     rdo.Get(index,tdc,hgpost,lgpost,hgpre,lgpre,
00182              amupre,amupost,amutac,data_error) ;
00183     //    rdo.Get(index,tdc,hgpost,lgpost,hgpre,lgpre,data_error) ;
00184 
00185     // ADC 
00186 
00187 
00188     //=====> different treatment for PbSc and PbGl MV 2001/08/24
00189     bool chooseLowGain =true;
00190     if(fUseOnlyLowGain) {
00191       scale              = 1.;
00192     } else {
00193       if(EmcIndexer::isPbSc(TowerId)){
00194 
00195         //      chooseLowGain = data_error&0x003c || (lgpre-lgpost)>192.;
00196         chooseLowGain = data_error&(emcDataFormatter::HG_PRE_OUT+emcDataFormatter::HG_POST_OUT) || (lgpre-lgpost)>192.;
00197 
00198         scale = (fCollectHLRatioStatus? fHLRatios->getValue(index) : 15.22) ;
00199         if(scale<12.||scale>18.) scale = 15.4; 
00200       
00201       } else if(EmcIndexer::isPbGl(TowerId)){
00202       
00203         bool badHighGain=(hgpre-hgpost)<0. && (lgpre-lgpost)>50.;
00204         bool goodLowGain=(lgpre-lgpost)>170.;
00205         chooseLowGain= data_error&0x003f || badHighGain || hgpost<1024. || goodLowGain;
00206 
00207         scale = (fCollectHLRatioStatus? fHLRatios->getValue(index,3) : 15.33);
00208         if(scale<10.||scale>21.) scale = 15.33;
00209       
00210       }
00211     }
00212 
00213     // Current decision - if both High and Low are flagged as bad :
00214     // use Low but set a flag of corrupted data
00215     adc = lgpre-lgpost ;
00216     if(chooseLowGain) {
00217       //  Low Gain leg selected
00218       if (fCollectPedestalStatus&&fUseAmpPedestals) {
00219         plg = (-fPedestals->getValue(index, amupre, "LG_Pre")+
00220                fPedestals->getValue(index, amupost, "LG_Post")) ;
00221         if(fabs(plg)<20.)   adc += plg;
00222       }
00223       adc *= scale;
00224     } else {
00225       //  High Gain leg selected
00226       adc =  hgpre-hgpost ;
00227       if (fCollectPedestalStatus&&fUseAmpPedestals) { 
00228         phg = (-fPedestals->getValue(index, amupre, "HG_Pre")+
00229                fPedestals->getValue(index, amupost, "HG_Post")) ;
00230         if(fabs(phg)<20.)   adc += phg;
00231       }
00232     }
00233 //     if (data_error&0x23c0) {
00234 //       rdo.AddDataError(index,0x2000);
00235 //     }
00236 
00237     // TDC
00238     if(tdc>=4095) tdc = 0;
00239     newTDCValue = INVALID_FLOAT ;
00240 
00241     if (fCollectPedestalStatus) {
00242       newTDCValue = tdc;
00243       tacped   = fPedestals->getValue(index,rdo.GetTACCell(index), kTACPED) ; 
00244       //  FIXME: this is to protect against zero pedestals in TAC
00245       tdc -= ((tacped>0)? tacped : fPedestals->getValue(index, 0, kTACPED)) ; 
00246     }
00247 
00248     if (mdo.IsUsingHGLG()) {
00249       hg = hgpre-hgpost ;
00250       lg = lgpre-lgpost ;
00251       rdo.GetCells(index,amupre,amupost,amutac);
00252       if (fCollectPedestalStatus) {     
00253         //      cout<<index<<" "<<amupre<<" "<<amupost<<endl;
00254         phg = fUseAmpPedestals? (-fPedestals->getValue(index, amupre, kHG_Pre)+
00255                                  fPedestals->getValue(index, amupost, kHG_Post)) : 0.;
00256         plg = fUseAmpPedestals? (-fPedestals->getValue(index, amupre, kLG_Pre)+
00257                                  fPedestals->getValue(index, amupost, kLG_Post)) : 0. ;
00258 
00259         hg += phg;
00260         lg += plg;
00261       }
00262       int iadc = static_cast<int>(floor(adc+0.5));
00263       int itdc = static_cast<int>(floor(tdc+0.5));
00264       mdo.Set(index, iadc, itdc, hg, lg) ;
00265     }
00266     else {
00267       mdo.Set(index, adc, tdc) ;
00268     } 
00269 
00270   }
00271 
00272   return rv ; 
00273 } 
00274 
00275 //_____________________________________________________________________________
00276 bool emcRawDataCalibratorV2::Calibrate(const emcMixedDataObject& mdo,
00277                          emcCalibratedDataObject& cdo,
00278                          const PHTimeStamp& when)
00279 {
00280   /* Make Energie (GeV) and Time (ns) values out of the MixedDataObject 
00281 
00282      To perform this, we need to get access to some calibration objects :
00283      a) time-dependant gains
00284      b) least-count tofs
00285      c) walk tofs
00286 
00287      Those objects are collected from the database (being file or Objy)
00288      using the DataManager.
00289 
00290      We also need time-zero calibrations to get the final GeV values.
00291 
00292    */
00293 
00294   if ( fECalAtT0.empty() ) {
00295     if(!GetECalAtT0(when,true)) return false;
00296   }
00297   bool rv = true ; 
00298   Int_t index ; 
00299 
00300 
00301   if (fMustCollectForCDO) {
00302     CollectForCDO(when) ;
00303     tf = pbscTimingFixes::getInstance();
00304     if(!(tf->areFixesLoaded())) tf = 0;
00305     fMustCollectForCDO = false ;
00306   }
00307 
00308   bool energycalibrated = true; 
00309   bool timecalibrated   = true;
00310   
00311   cdo.Reset();
00312 
00313   Float_t adc, tdc ; 
00314   Int_t   outindex =0; 
00315   Float_t etotal   =0.;
00316 
00317   // Loop over towers
00318   for (index = 0; index < mdo.GetSize(); index++ ) {
00319 
00320     int TowerId = mdo.GetItemId(index) ; 
00321 
00322     // Skip reference towers, if any.
00323     if (EmcIndexer::isReference(TowerId)) continue;
00324 
00325     adc = mdo.GetADC(index) ; 
00326     float asv = adc;
00327     float tsv = mdo.GetTDC(index) ;
00328     int errorFlag = mdo.GetErrorFlag(index);
00329 
00330     if( adc > GetThresholdADC() && !(errorFlag&0x2000)) { 
00331       tdc = mdo.GetTDC(index) ; 
00332       if (!(errorFlag&0x2400)) {
00333         //      timecalibrated &= CalibrateTime(tdc, adc, index, TowerId, eventTime );
00334         timecalibrated &= CalibrateTime(tdc, adc, index, TowerId, 0);
00335       }
00336       //      energycalibrated &= CalibrateEnergy( adc, index, TowerId, eventTime) ;
00337       energycalibrated &= CalibrateEnergy( adc, index, TowerId, 0) ;
00338       cdo.Set(outindex, TowerId, mdo.GetSoftwareKey(index), errorFlag, 
00339               adc, tdc,mdo.GetDead(index),mdo.GetWarn(index)) ;
00340       etotal += adc ;
00341       outindex++;
00342     } 
00343     else {
00344       if(!fZeroSuppression) {
00345         cdo.Set(outindex, TowerId, mdo.GetSoftwareKey(index), 
00346                 errorFlag, 0., 0.,mdo.GetDead(index),mdo.GetWarn(index)) ;
00347         outindex++;
00348        }
00349     }
00350     if ( fVerbose>=1 && asv>10.) cout<<"Calib "<<index<<" ADC "<<asv<<" E "<<adc<<" TDC "<<tsv<<" T"<<tdc<<endl;
00351   }  
00352   cdo.SetTotalEnergy(etotal);
00353   cdo.SetZeroSuppressedFlag(fZeroSuppression);
00354   cdo.SetEnergyCalibratedFlag(energycalibrated);
00355   cdo.SetTimeCalibratedFlag(timecalibrated) ; 
00356 
00357   return rv ; 
00358  } 
00359 
00360 //_____________________________________________________________________________
00361 bool emcRawDataCalibratorV2::Calibrate(const emcRawDataObject& rdo,
00362                          emcCalibratedDataObject& cdo,
00363                          const PHTimeStamp& when)
00364 {
00369   emcMixedDataObject mdo ;
00370   bool rv = Calibrate(rdo,mdo,when) ;
00371   rv &= Calibrate(mdo,cdo,when) ;
00372   return rv ;
00373 }
00374 
00375 //-------------------------------------------------------------------------
00376 bool 
00377 emcRawDataCalibratorV2::CalibrateEnergy(Float_t & adc, const Int_t index, 
00378                                         const Int_t TowerId,
00379                                         int incrementalTime) 
00380 {
00381   if (fCollectGainStatus==false) { return false; }
00382 
00383   float normt, dummy;
00384   dummy = adc;
00385   if(EmcIndexer::isPbSc(TowerId)) {
00386     // PBSC
00387     normt = fGains->getValue(index,incrementalTime) ;
00388     //  we changed the range for Gains in pp-run5 - no more scaling for test-pulse
00389     adc  *= ((normt>0.01)?  fECalAtT0[index]/normt : 0.) ; 
00390     if ( fVerbose>=1 && dummy>10.) cout<<"<CE> Index "<<index<<" TowerId "<<TowerId<<" ADC "<<dummy<<" Time "<<incrementalTime<<" NORM "<<normt<<"/"<<fGains->getValue(index,0)<<" ECal "<<fECalAtT0[index]<<" Energy "<<adc<<endl;
00391   } else {
00392     assert(EmcIndexer::isPbGl(TowerId)) ;
00393     // PBGL  - EXPLICITLY NO TIMING DEPENDENCE FOR NOW 
00394     normt = fGains->getValue(index,0) ;
00395     adc  *= ((normt>0.)?  fECalAtT0[index]/normt : 0.) ; 
00396   }
00397   //  cout<<"<CE> Index "<<index<<" TowerId "<<TowerId<<" ADC "<<dummy<<" NORM "<<normt<<" ECal "<<fECalAtT0[index]<<" Energy "<<adc<<endl;
00398   return true ;
00399 } 
00400 
00401 //_________________________________________________________________________
00402 bool  
00403 emcRawDataCalibratorV2::CalibrateTime(Float_t & tdc, float adc, 
00404                                     const Int_t index, const Int_t TowerId,
00405                                       int /*incrementalTime*/)
00406 { 
00407   if (fCollectTofStatus==false) { return false; }
00408   float lc = fLCTofs->GetValue1(index);
00409   float t0 = 0.;
00410   //  t0       = fWalkTofs->GetValue1(index);
00411   float wk = fWalkTofs->GetValue2(index);
00412   float dt;
00413 
00414   //=====> different functions for PbGl and PbSc MV 2001/08/24  
00415   if ( TowerId < 15552 )
00416     {
00417 //       //  new set of 2003 calibration data has all LC defined. 
00418 //       // We'll keep this test for just in case
00419 //       lc = ((lc>32.&&lc<48.)? lc : 40)/1000.;    
00420 //       //  EK 04/10/03
00421 //       //  first attempt to introduce global corrections for 
00422 //       // nonlinearities in the walk values
00423    
00424 //       float walk        = (adc>0.)? wk*log(adc)*1000. : 0.;
00425 //       //  next line is hopefully valid for all runs but functional 
00426 //       //  form needs to be redefined
00427 //       //  correction function depends on LG adc - it is enough to 
00428 //       // use a common scale everywhere
00429 //       float walkCorr    = (lc>0)? walkCorrection(adc/15.7) : 0.; 
00430 //       //  due to nonlinear amplitude dependence
00431 //       //  we will probably find some better way of explaining/presenting 
00432 //       // this correction 
00433 //       float walkStretch = (lc>0)? (wk-0.0469)*6.26     : 0.;   
00434 //       //  due to residual walk stretching
00435 //       tdc =  - ((tdc-t0-walk)*lc -walkCorr-walkStretch);
00436       
00437 
00438       lc = ((lc>25.&&lc<65.)? lc : 40.0)/1000.;  
00439 
00440 
00441       float walk = (adc>0.&&wk<0.)? wk*4000./adc : 0.;
00442 
00443       tdc =  - lc*(tdc-walk) - t0;
00444     } 
00445   else if ( TowerId < 24768 )
00446     {
00447       // Changed at Maxim's request, Sep 28, 2001 GD
00448       //    //=====> recalculate adc to low gain MV 2001/08/24
00449       //    float scale;
00450       
00451       
00452       //    if(scale<12.|| scale>18.) scale = 15.33;
00453       
00454       //    lc = ((lc>20. && lc<55.)? lc : 38.9)/1000.;
00455       //    float lgadc=adc/scale;
00456       //    dt=((lgadc>0.)? wk*pow(lgadc, -0.2): 0.);
00457       
00458       // MV 2001/09/27 walk correction is calculated using physics data,
00459       // so T0 should be taken care of automatically
00460       t0 = fWalkTofs->GetValue1(index);
00461       lc = ((lc>20. && lc<55.)? lc : 38.9)/1000.;
00462       dt=((adc>0.)? wk*log(adc): 0.);
00463       tdc =  - (tdc-t0-dt)*lc + GetGlobalT0() ;
00464     }
00465   
00466   return true;
00467 }
00468 
00469 //_____________________________________________________________________________
00470 void emcRawDataCalibratorV2::CollectForCDO(const PHTimeStamp& when)
00471 {
00472   // Collection of gain and time calibration data.
00473   cout << "emcRawDataCalibratorV2::CollectForCDO" << endl ;
00474 
00475   static emcGains    gainDriver ;
00476   static emcLCTofs   lctofDriver ;
00477   static emcWalkTofs walktofDriver ;
00478 
00479   //  EK 01/11/02
00480   //  static emcTofT0s   drifttofDriver;
00481   static emcTacPeds   drifttofDriver;
00482   
00483   emcDataManager* dm = emcDataManager::GetInstance() ;
00484   
00485   // FIXME : THIS WILL WORK ONLY IF ALL DATA HAVE THE SAME START 
00486   // OF VALIDITY TIME 
00487   // Try to collect Tof-related data
00488   if ( fTofSource != emcManageable::kNone && maxFailTof ) {
00489     // Try to collect ToF drifts
00490     //    drifttofDriver.SetSource( fTofSource ) ;
00491     
00492     //  EK 01/11/02
00493     //    fTofT0s   = dynamic_cast<emcTofT0s*>( dm->Collect(drifttofDriver, when)) ; 
00494     //    fTacPeds   = dynamic_cast<emcTacPeds*>( dm->Collect(drifttofDriver, when)) ; 
00495     //    if(!fTacPeds) cout<<"failed to collect drifts"<<endl;
00496     // Try to collect least counts for ToF 
00497     lctofDriver.SetSource( fTofSource ) ;
00498     //    cout<<"Collecting LCTOFs"<<endl;
00499     fLCTofs = dynamic_cast<emcLCTofs*>( dm->Collect(lctofDriver, when) ) ;
00500     //    cout<<"Collecting LCTOFs - done"<<endl;
00501 
00502     // Try to collect walks for ToF 
00503     walktofDriver.SetSource( fTofSource ) ;
00504     fWalkTofs = dynamic_cast<emcWalkTofs*>( dm->Collect(walktofDriver, when)) ;
00505 
00506 
00507 
00508     // (*1) ... here it might be that collection was not ok ...
00509     fCollectTofStatus = (fLCTofs!=0 && fWalkTofs!=0) ;
00510     maxFailTof -= !fCollectTofStatus ;
00511   }
00512 
00513 
00514   // by default we consider that collection never happened... (*1)
00515   if (maxFailGain) fCollectGainStatus = false ;
00516   
00517   // Try to collect Gains
00518   if ( fGainsSource != emcManageable::kNone && maxFailGain ) {
00519     gainDriver.SetSource( fGainsSource ) ;
00520     fGains = dynamic_cast<emcGains*>( dm->Collect(gainDriver, when) ) ;
00521     // (*1) ... here it might be that collection was not ok ...
00522     fCollectGainStatus = (fGains!=0) ;
00523     maxFailGain -= !fCollectGainStatus ;
00524   } 
00525   
00526   if ( fVerbose>=1 ) {
00527     if (!fCollectTofStatus) {
00528       cerr << "<E> emcRawDataCalibratorV2::CollectForCDO " << endl 
00529            << "    ToFs collection failed. Source: " <<fTofSource<< endl ;
00530     }
00531     if (!fCollectGainStatus) {
00532       cerr << "<E> emcRawDataCalibratorV2::CollectForCDO() " << endl
00533            << "    Gains collection failed. Source: " <<fGainsSource<< endl ;
00534     }
00535   }
00536 }
00537 
00538 //_____________________________________________________________________________
00539 void emcRawDataCalibratorV2::CollectForMDO(const PHTimeStamp& when)
00540 {
00541   // Collection of pedestals, hlratios and Q&As
00542   cout << "emcRawDataCalibratorV2::CollectForMDO" << endl ;
00543 
00544   static emcPedestals5 pedDriver ;
00545   static emcHLRatios hlrDriver ;
00546   static emcQAs qaDriver ;
00547 
00548   emcDataManager* dm = emcDataManager::GetInstance() ;
00549 
00550   // by default we consider that collection never happened... (*1)
00551   fCollectPedestalStatus = fCollectHLRatioStatus = false ;
00552 
00553   // Try to collect pedestals
00554   if ( fPedestalsSource != emcManageable::kNone && maxFailPed ) {
00555     pedDriver.SetSource( fPedestalsSource  ) ;
00556     fPedestals = dynamic_cast<emcPedestals5*>( dm->Collect(pedDriver, when) ) ;
00557     // (*1) ... here it might be that collection was not ok ...
00558     fCollectPedestalStatus = (fPedestals!=0) ;
00559     maxFailPed -= !fCollectPedestalStatus ;
00560     if(!fCollectPedestalStatus) {
00561       cout << "<E> emcRawDataCalibratorV2::CollectFromMDO() " << endl
00562            << "    Pedestal collection at "<<when<<" failed. Source: " <<fPedestalsSource<< endl ;
00563     } else {cout<<"<I> Pedestal collection succeded " << endl;}
00564   } else {cout<<"<I> Pedestal collection inhibited " << endl;}
00565 
00566   //  if( fVerbose>=1 && !fCollectPedestalStatus) {
00567 
00568   // Try to collect H/L Ratios
00569   if (!fUseOnlyLowGain && fHLRatiosSource != emcManageable::kNone && maxFailHLR ) {
00570     // (*1) ... here it might also be that collection was not ok ...
00571     hlrDriver.SetSource( fHLRatiosSource) ;
00572     fHLRatios = dynamic_cast<emcHLRatios*>( dm->Collect(hlrDriver, when) ) ;
00573     // (*1) ... here it might be that collection was not ok ...
00574     fCollectHLRatioStatus = (fHLRatios!=0) ;
00575     maxFailHLR -= !fCollectHLRatioStatus ;
00576     if(!fCollectHLRatioStatus) {
00577       cout << "<E> emcRawDataCalibratorV2::CollectFromMDO() " << endl
00578            << "    HLRatio collection failed." << endl ;
00579     } else {cout<<"<I> HLRatio collection succeded " << endl;}
00580   } else {cout<<"<I> HLRatio collection inhibited " << endl;}
00581 
00582   // Try to collect Q&A objects
00583   if ( fQASource != emcManageable::kNone ) {
00584 
00585     // Set some parameters for the qa object we want
00586     qaDriver.SetSource(fQASource) ;
00587 
00588     // FIXME: unclear if this is correctly made - call on every event
00589     qaDriver.SetExtraRejectListFilename(fExtraRejectListFilename.c_str()) ;
00590 
00591     // Collect it
00592     fQA = dynamic_cast<emcQAs*>( dm->Collect(qaDriver,when) ) ;
00593     if (!fQA) {
00594       cout << "<E> emcRawDataCalibratorV2::CollectFromMDO() " << endl
00595            << "    QA collection failed." << endl ;
00596     } else {cout<<"<I> QA collection succeded " << endl;}
00597     assert(fQA!=0) ;
00598   } else {cout<<"<I> QA collection inhibited " << endl;}
00599 
00600 } 
00601 
00602 //_____________________________________________________________________________
00603 bool 
00604 emcRawDataCalibratorV2::GetECalAtT0(const PHTimeStamp& when, 
00605                                     bool normalizationON) 
00606 {
00607   if (!fECalAtT0.empty()) 
00608     { 
00609       // we already have it 
00610       return true ;
00611     }
00612 
00613   emcDataManager* dm = emcDataManager::GetInstance();
00614   emcRawDataAccessor * rda = emcRawDataAccessor::GetInstance() ; 
00615   size_t ntowers = 144*rda->GetDynamicData()->getnSM() ;
00616   int* DataMap = rda->GetDynamicData()->getEmcMap();
00617 
00618   fECalAtT0.resize(ntowers,1.0) ;
00619 
00620   emcCalibrationData* sector[8];
00621 
00622   // Load the sectors initial calibration from the required source.
00623 
00624   for ( int isector = 0; isector < 8; ++isector ) 
00625     {
00626       sector[isector] = new emcCalibrationData
00627         (emcCalibrationData::kIniCal,isector);
00628 
00629       sector[isector]->SetSource(fIniCalSource);
00630       bool ok = dm->Read(*(sector[isector]),when);
00631       if (!ok) 
00632         {
00633           cerr << "<E> emcRawDataCalibratorV2::GetECalAtT0 : "
00634                << "cannot get sector " << isector 
00635                << " from source=" 
00636                << emcManageable::GetStorageName(fIniCalSource)
00637                << endl;
00638         }
00639     }
00640 
00641   // Populate the fECalAtT0 array from sectors initial calibrations
00642 
00643   for ( int item = 0; item < rda->GetDynamicData()->getEmcSize(); item++) 
00644     {
00645       int sn,ist;
00646       
00647       EmcIndexer::iPXiSiST(DataMap[item], sn, ist) ;
00648       
00649       float encal,norm0,one;
00650       
00651       if ( sn < 6 ) 
00652         {
00653           encal = sector[sn]->GetValue(ist,0);
00654           norm0 = sector[sn]->GetValue(ist,1);
00655           one = sector[sn]->GetValue(ist,2);
00656           assert(one==1.0);
00657           fECalAtT0[item] = encal*( normalizationON ? norm0 : 1. ) ;   
00658         }
00659       else if(sn>=6&&sn<8)
00660         {
00661           encal = sector[sn]->GetValue(ist,0) *
00662             sector[sn]->GetValue(ist,1)*
00663             sector[sn]->GetValue(ist,2);
00664           fECalAtT0[item] = encal;
00665         }
00666       
00667       fECalAtT0[item] *= fUseOnlyLowGain? 16. : 1.;
00668     }
00669   
00670   // clean up after ourselves.
00671   for ( int isector = 0; isector < 8; ++isector ) 
00672     {
00673       delete sector[isector];
00674     }
00675 
00676   return true ;
00677 }
00678 
00679 //_____________________________________________________________________________
00680 bool emcRawDataCalibratorV2::GetCollectionStatus(const char* type) const
00681 {
00682   string stype = type ;
00683   if ( stype == "Pedestals" ) {
00684     return fCollectPedestalStatus ;
00685   }
00686   else if ( stype == "HLRatios" ) {
00687     return fCollectHLRatioStatus ;
00688   }
00689   else if ( stype == "Gains" ) {
00690     return fCollectGainStatus ;
00691   }
00692   else if ( stype == "Tofs") {
00693     return fCollectTofStatus ;
00694   }
00695   else if ( stype == "*" ) {
00696     return 
00697       fCollectPedestalStatus &
00698       fCollectHLRatioStatus & 
00699       fCollectGainStatus &
00700       fCollectTofStatus ;
00701   }
00702   return false ;
00703 }
00704 
00705 
00706 //_____________________________________________________________________________
00707 void emcRawDataCalibratorV2::SetCollectionStatus(const char* type)
00708 {
00709   string stype = type ;
00710   if ( stype == "Pedestals" ) {
00711     fCollectPedestalStatus = true;
00712   }
00713   else if ( stype == "HLRatios" ) {
00714     fCollectHLRatioStatus  = true;
00715   }
00716   else if ( stype == "Gains" ) {
00717     fCollectGainStatus = true;
00718   }
00719   else if ( stype == "Tofs") {
00720     fCollectTofStatus = true;
00721   }
00722   else if ( stype == "*" ) {
00723     fCollectPedestalStatus = true;
00724     fCollectHLRatioStatus  = true; 
00725     fCollectGainStatus     = true;
00726     fCollectTofStatus      = true;
00727   }
00728 }
00729 
00730 //_____________________________________________________________________________
00731 
00732 void emcRawDataCalibratorV2::Print() const
00733 {
00734   cout << " emcRawDataCalibratorV2 setup : " << endl ;  
00735 
00736   cout  << " **** Pedestals  " ; 
00737   if ( fPedestalsSource == emcManageable::kFile_ASCII ) {
00738     cout << "are read from files " << endl ; 
00739   }
00740   else if ( fPedestalsSource == emcManageable::kDB_Objy  ) {
00741     cout << "are read from Database (Objy)" << endl ; 
00742   }
00743   else if ( fPedestalsSource == emcManageable::kDB_Pg  ) {
00744     cout << "are read from Database (PG)" << endl ; 
00745   }
00746   else {
00747     cout << " = 0 (collection disabled)" << endl ; 
00748   }
00749 
00750   cout << " **** high/low gain ratios  " ; 
00751   if ( fHLRatiosSource ==  emcManageable::kFile_ASCII ) {
00752     cout << "are read from files " << endl ; 
00753   }
00754   else if ( fHLRatiosSource ==  emcManageable::kDB_Objy ) {
00755     cout << "are read from Database (Objy)" << endl ; 
00756   }
00757   else if ( fHLRatiosSource ==  emcManageable::kDB_Pg ) {
00758     cout << "are read from Database (PG)" << endl ; 
00759   }
00760   else {
00761     cout << " = 16 " << endl ; 
00762   }
00763 
00764   cout << " **** Gains (current normalization)  " ; 
00765   if ( fGainsSource ==  emcManageable::kFile_ASCII ) {
00766     cout << "are read from files " << endl ; 
00767   }
00768   else if ( fGainsSource ==  emcManageable::kDB_Objy ) {
00769     cout << "are read from Database (Objy)" << endl ; 
00770   }
00771   else if ( fGainsSource ==  emcManageable::kDB_Pg ) {
00772     cout << "are read from Database (PG)" << endl ; 
00773   }
00774   else {
00775     cout << " = 1 " << endl ; 
00776   }
00777 
00778   cout << " **** ToF calibration (least counts and walks)  " ; 
00779   if ( fTofSource ==  emcManageable::kFile_ASCII ) {
00780     cout << "are read from files " << endl ; 
00781   }
00782   else if ( fTofSource ==  emcManageable::kDB_Objy ) {
00783     cout << "are read from Database (Objy)" << endl ; 
00784   }
00785   else if ( fTofSource ==  emcManageable::kDB_Pg ) {
00786     cout << "are read from Database (PG)" << endl ; 
00787   }
00788   else {
00789     cout << " = 1 " << endl ; 
00790   }
00791 
00792   cout << " **** Q&A " ;
00793   if ( fQASource == emcManageable::kFile_ASCII ) {
00794     cout << "are read from files " << endl ;
00795   }
00796   else if ( fQASource == emcManageable::kDB_Objy ) {
00797     cout << "are read from Database (Objy)" << endl ;
00798   }
00799   else if ( fQASource == emcManageable::kDB_Pg ) {
00800     cout << "are read from Database (PG)" << endl ;
00801   }
00802   else {
00803     cout << "are not read (perfect towers assumed) " << endl ;
00804   } 
00805 
00806   cout << " **** Initial Calibration " ;
00807   if ( fIniCalSource == emcManageable::kFile_ASCII) { 
00808     cout << "are read from files " << endl ;
00809   }
00810   else if ( fIniCalSource == emcManageable::kDB_Objy ) {
00811     cout << "are read from Database (Objy)" << endl ;
00812   }
00813   else if ( fIniCalSource == emcManageable::kDB_Pg ) {
00814     cout << "are read from Database (PG)" << endl ;
00815   }
00816   else if ( fIniCalSource == emcManageable::kDB_Construction ) {
00817     cout << "are read from construction DB " << endl ;
00818   }
00819   else {
00820     cout << " Huh ? : check your IniCal source !" << endl ;
00821   }
00822 
00823   cout << " **** High gain threshold = " <<  GetHighLowLimit() << endl ; 
00824   cout << " **** ADC threshold = " << GetThresholdADC() << endl ;
00825   cout << " **** Zero suppression is " <<     ((fZeroSuppression==true)?"ON":"OFF") << endl ;
00826   cout << " **** Will " <<((fUseAmpPedestals==true)? "SUBTRUCT ":"NOT SUBTRUCT") << " amplitude pedestals "<<endl ;
00827   cout << " **** Will use " <<((fUseOnlyLowGain==true)? " LOW GAIN LEG ONLY ":" BOTH GAIN LEGS") <<endl ;
00828 
00829 }
00830 //_____________________________________________________________________________
00831 //  Prints debug information for individual tower
00832 void  emcRawDataCalibratorV2::printData(const emcRawDataObject& rdo, const int item) const
00833 {
00834   if(item<0 || item>=rdo.GetMaxSize()) return;
00835   Float_t tdc ;
00836   Float_t hgpost,hgpre,lgpost,lgpre ;
00837   int amupre,amupost,amutac ;
00838   int data_error ;
00839   //  we need AMU cell addresses to correctly extract pedestals
00840   rdo.Get(item,tdc,hgpost,lgpost,hgpre,lgpre,
00841             amupre,amupost,amutac,data_error) ;
00842   cout<<"ITEM "<<item<<" AMU(pre,post,tac) " <<amupre<<"/"<<amupost<<"/"<<amutac;
00843   cout<<" H/L ";
00844   if(fCollectHLRatioStatus) cout<<fHLRatios->getValue(item); else cout<<"none";
00845   cout<<" C0 ";
00846   if(!fECalAtT0.empty()) cout<< fECalAtT0[item]; else cout<<"none ";
00847   cout<<" NORM(t) ";
00848   if(fCollectGainStatus) cout<< fGains->getValue(item,0)<<endl; else cout<<" none "<<endl;
00849   cout<<"HG: (post/pre) "<<hgpost<<"/"<<hgpre<<" LG: (post/pre) "<<lgpost<<"/"<<lgpre<<"  TAC "<<tdc<<endl;
00850   if(fCollectPedestalStatus) 
00851     cout<<"PEDESTALS: HG Post "<<
00852       fPedestals->getValue(item, amupost, "HG_Post")<<" HG pre "<<fPedestals->getValue(item, amupre, "HG_Pre")<<
00853       " LG Post "<<
00854       fPedestals->getValue(item, amupost, "LG_Post")<<" LG pre "<<fPedestals->getValue(item, amupre, "LG_Pre")<<
00855       " TAC "<<fPedestals->getValue(item, amutac, "TAC")<<endl; 
00856 }
00857 
00858 //_____________________________________________________________________________
00859 void emcRawDataCalibratorV2::Reset(void)
00860 {
00861   fPedestalsSource = emcManageable::kNone ; 
00862   fHLRatiosSource  = emcManageable::kNone ;  
00863   fGainsSource     = emcManageable::kNone ;  
00864   fTofSource       = emcManageable::kNone ;  
00865   fQASource        = emcManageable::kNone ;
00866   fIniCalSource    = emcManageable::kNone ;
00867   fCollectPedestalStatus = fCollectHLRatioStatus = false ;
00868   fCollectGainStatus    = fCollectTofStatus     = false;
00869   maxFailPed = maxFailHLR = maxFailGain = maxFailTof = 10;
00870   fECalAtT0.clear() ;
00871   fZeroSuppression = false;
00872   fQA = 0 ;
00873   SetExtraRejectListFilename();
00874   fPedestals = 0 ;
00875   fHLRatios = 0 ;
00876   fGains = 0 ;
00877   fLCTofs = 0 ;
00878   fWalkTofs = 0 ;
00879   fTofT0s = 0 ;
00880   fMustCollectForCDO = true ;
00881   fMustCollectForMDO = true ;
00882   tf=0;
00883 }
00884 
00885 //-------------------------------------------------------------------------
00886 bool emcRawDataCalibratorV2::SelectSource(const char* type, 
00887                                         emcManageable::EStorage source)
00888 {
00889   /* The validity of the source parameter depends on the mapping style
00890      of the calorimeter. If 144 words per FEM, all sources allowed. 
00891      If 192 words per FEM, no source at all allowed.
00892   */
00893   
00894   emcRawDataAccessor * rda = emcRawDataAccessor::GetInstance() ; 
00895 
00896   if (!rda) {
00897     cerr << "<E> emcRawDataCalibratorV2:: SelectSource - Cannot check source is valid because I cannot get access to RDA. So I am NOT changing the source." << endl ;
00898     return false ;
00899   }
00900   else {
00901     /* Check that the source is valid. 
00902        Basically, if we deal with 144 words per FEM, all sources allowed,
00903        if 192 words per FEM, valid source = none. */
00904     if ( rda->GetDynamicData()->getMapStyle() == false &&
00905          source != emcManageable::kNone ) {
00906       cerr << "<E> emcRawDataCalibratorV2::SelectSource - Map style is 192 words per FEM. Cannot use any source." << endl ;
00907       return false ;
00908     }
00909   }
00910  
00911   bool rv = true ; 
00912   string stype = type ;
00913   
00914   if ( stype == "Pedestals" ) 
00915     fPedestalsSource = source ; 
00916   
00917   else if ( stype == "HLRatios" ) 
00918     fHLRatiosSource = source ;
00919 
00920   else if ( stype == "Gains" ) 
00921     fGainsSource    = source ;
00922 
00923   else if ( stype == "ToF" ) 
00924     fTofSource    = source ;
00925 
00926   else if ( stype == "QAs" )
00927     fQASource = source ;
00928 
00929   else if ( stype == "IniCal" ) 
00930     fIniCalSource = source ; 
00931 
00932   else if ( stype == "*" ) {
00933     fPedestalsSource = source ; 
00934     fHLRatiosSource = source ;
00935     fGainsSource    = source ;
00936     fQASource = source ;
00937     fTofSource    = source ;   
00938     fIniCalSource = source ;
00939   }
00940   else {
00941     cerr << "emcRawDataCalibratorV2::SelectSource: " << type << " is an unknown type " << endl
00942          << "                                    Valid types are Pedestals, HLRatios, Gains, ToF " << endl ; 
00943     rv = false ; 
00944   }
00945   
00946   return rv ; 
00947   
00948 }
00949 
00950 //_________________________________________________________________________
00951 // Set Global T0 for every calorimeter Tower 
00952 // The simplest solution for now was to write an ASCII file without any DB connectivity and load it at will
00953 void emcRawDataCalibratorV2::SetTwrGlobalT0(char * filename){
00954   if (fTwrGlobalT0) {
00955     delete [] fTwrGlobalT0;
00956     fTwrGlobalT0 = NULL;
00957   }
00958   if(!filename)         return;
00959   ifstream fin(filename, std::ios::in);
00960   emcRawDataAccessor * rda = emcRawDataAccessor::GetInstance();
00961   assert(rda!=0);
00962   emcRawDataObject   * rdo = rda->GetRawDataObject() ;
00963   assert(rdo!=0);
00964   fTwrGlobalT0 = new float [rdo->GetMaxSize()];
00965   int lines = 0;
00966   int twr, sector, iX, iY, entries;
00967   float t0, rms;
00968   while(fin>>twr>>sector>>iX>>iY>>t0>>rms>>entries){
00969     // cout<<lines<<" "<<twr<<" "<<sector<<" "<<iX<<" "<<iY<<" "<<t0<<" "<<rms<<" "<<entries<<endl;
00970     assert(lines<rdo->GetMaxSize());
00971     fTwrGlobalT0[lines] = ((entries>2)? t0 : 0.);
00972     lines++;
00973   }
00974   assert(lines==rdo->GetMaxSize());
00975 }