emcCalibrationDataHelper.C

Go to the documentation of this file.
00001 #include "emcCalibrationDataHelper.h"
00002 
00003 #include <cassert>
00004 #include <cmath>
00005 #include <algorithm>
00006 #include <cmath>
00007 #include <cctype>
00008 #include <sstream>
00009 
00010 #include "emcCalibrationData.h"
00011 #include "emcCalFEM.h"
00012 #include "emcCalFEMFactory.h"
00013 #include "emcDataManager.h"
00014 #include "emcFEMList.h"
00015 #include "emcGainBaseLineCalculator.h"
00016 #include "EmcIndexer.h"
00017 #include "emcTimeStamp.h"
00018 #include "emcTracedFEM.h"
00019 #include "emcTracedValue.h"
00020 
00021 #ifdef DEBUG
00022 #  include "TBenchmark.h"
00023 #  include "TSystem.h"
00024 #endif
00025 
00026 using namespace std;
00027 
00028 //_____________________________________________________________________________
00029 emcCalibrationDataHelper::emcCalibrationDataHelper(int runnumber,
00030                                                    bool initall,
00031                                                    emcManageable::EStorage src,
00032                                                    const char* parts)
00033 {
00034   emcTimeStamp ets;
00035 
00036   ets.SetSource(src);
00037 
00038   emcDataManager* dm = emcDataManager::GetInstance();
00039 
00040   bool ok = dm->Read(ets, runnumber);
00041 
00042   PHTimeStamp ts;
00043 
00044   if ( ok )
00045     {
00046       ts = ets.getTimeStamp();
00047     }
00048   else
00049     {
00050       ts.setToSystemTime();
00051       cerr << "emcCalibrationDataHelper::emcCalibrationDataHelper : "
00052            << "could not find timestamp for run " << runnumber
00053            << "Using timestamp=now=" << ts << endl;
00054     }
00055   ctor(runnumber, ts, initall, src, parts);
00056 }
00057 
00058 //_____________________________________________________________________________
00059 emcCalibrationDataHelper::emcCalibrationDataHelper(int runnumber,
00060                                                    const PHTimeStamp& ts,
00061                                                    bool initall,
00062                                                    emcManageable::EStorage src,
00063                                                    const char* parts)
00064 {
00065   ctor(runnumber, ts, initall, src, parts);
00066 }
00067 
00068 //_____________________________________________________________________________
00069 void
00070 emcCalibrationDataHelper::ctor(int runnumber,
00071                                const PHTimeStamp& ts,
00072                                bool initall,
00073                                emcManageable::EStorage src,
00074                                const char* parts)
00075 {
00076   fInitAll = initall;
00077 
00078   fRunNumber = runnumber;
00079 
00080   fTimeStamp = ts;
00081 
00082   fMaxNumberOfFEMs = 172; // FIXME: for online, need more than that.
00083 
00084   fFemList = new emcFEMList(parts);
00085 
00086   std::vector<std::string> flavours;
00087 
00088   flavours.push_back("HLRatios");
00089   flavours.push_back("Pedestals5");
00090   flavours.push_back("Gains");
00091   flavours.push_back("Gains:BLR:0:xmax:-3:-9:-15:92446");
00092   flavours.push_back("Gains:BLR:0:x:ZS:AVOFRATIO:164777");
00093   flavours.push_back("LCTofs");
00094   flavours.push_back("WalkTofs");
00095   flavours.push_back("TofT0Bs");
00096 
00097   for ( size_t i = 0; i < flavours.size(); ++i )
00098     {
00099       Flavour f(flavours[i]);
00100 
00101       for ( int ifem = 0; ifem < fMaxNumberOfFEMs; ++ifem )
00102         {
00103           if ( fFemList->hasFEM(ifem) )
00104             {
00105               f.append(ifem);
00106             }
00107         }
00108 
00109       fKnownFlavours.push_back(f);
00110     }
00111 
00112   for ( size_t i = 0; i < fKnownFlavours.size(); ++i )
00113     {
00114       Flavour& f = fKnownFlavours[i];
00115       fData[f.name()].resize(f.size(), 0);
00116       fSources[f.name()] = src;
00117     }
00118 
00119   fCalibData["IniCal"].resize(8, 0);
00120   fCalibData["TofSectorOffset"].resize(8, 0);
00121 
00122   fSources["TofSectorOffset"] = src;
00123   fSources["IniCal"] = src;
00124 
00125   if ( initall )
00126     {
00127       initAll();
00128     }
00129 }
00130 
00131 //_____________________________________________________________________________
00132 emcCalibrationDataHelper::~emcCalibrationDataHelper()
00133 {
00134   TMAPITER it;
00135 
00136   for ( it = fData.begin(); it != fData.end(); ++it )
00137     {
00138       std::vector<emcCalFEM*>& vec = it->second;
00139       for ( size_t i = 0; i < vec.size(); ++i )
00140         {
00141           delete vec[i];
00142           vec[i] = 0;
00143         }
00144     }
00145 
00146   TCMAPITER itc;
00147 
00148   for ( itc = fCalibData.begin(); itc != fCalibData.end(); ++itc )
00149     {
00150       std::vector<emcCalibrationData*>& vec = itc->second;
00151       for ( size_t i = 0; i < vec.size(); ++i )
00152         {
00153           delete vec[i];
00154           vec[i] = 0;
00155         }
00156     }
00157 
00158   delete fFemList;
00159 }
00160 
00161 //_____________________________________________________________________________
00162 emcCalFEM*
00163 emcCalibrationDataHelper::collect(int femAbsolutePosition,
00164                                   const string& what)
00165 {
00166   //
00167   // This method is for collecting emcCalFEM-type objects
00168   // 
00169   // the what parameter MUST correspond to something which is collectable
00170   // otherwise you'll get a null pointer back.
00171   //
00172 
00173   assert(fTimeStamp != 0);
00174 
00175   emcDataManager* dm = emcDataManager::GetInstance();
00176 
00177   if ( source(what) == emcManageable::kNone )
00178     {
00179       // create default here.
00180       return emcCalFEMFactory::CreateDefault(what.c_str(), femAbsolutePosition);
00181     }
00182 
00183   emcCalFEM* calfem =
00184     emcCalFEMFactory::Create(what.c_str(), femAbsolutePosition);
00185 
00186   if (!calfem)
00187     {
00188       return 0;
00189     }
00190 
00191   calfem->SetSource(source(what));
00192 
00193   int code = femAbsolutePosition;
00194 
00195   if ( dm->GetVerboseLevel() )
00196     {
00197       cout << "<I> emcCalibrationDataHelper::collect "
00198            << "for FEM#" << femAbsolutePosition
00199            << " (flavor " << calfem->GetCategory()
00200            << ")"
00201            << endl;
00202     }
00203 
00204   bool ok = dm->Read(*calfem, fTimeStamp, code);
00205 
00206   if (!ok)
00207     {
00208 
00209       string category = calfem->GetCategory();
00210 
00211       // create default objects instead
00212       cout << "<W> emcCalibrationDataHelper::collect : "
00213            << "Creating default calibration object (flavour "
00214            << setw(10) << setfill(' ') << category
00215            << ") for FEM#"
00216            << setw(3) << setfill('0') << femAbsolutePosition
00217            << setfill(' ') << endl;
00218 
00219 
00220       PHTimeStamp t1, t2;
00221       t1.setTics(0);
00222       t2.setToFarFuture();
00223       delete calfem;
00224 
00225       calfem = emcCalFEMFactory::CreateDefault(category.c_str(),
00226                                                femAbsolutePosition,
00227                                                t1, t2);
00228     } // ! ok
00229 
00230   return calfem;
00231 }
00232 
00233 //_____________________________________________________________________________
00234 emcCalibrationData*
00235 emcCalibrationDataHelper::collectCalibData(const std::string& what,
00236                                            size_t number)
00237 {
00238   //
00239   // This method is for collecting emcCalibrationData-type objects.
00240   //
00241 
00242   assert(fTimeStamp != 0);
00243 
00244   emcDataManager* dm = emcDataManager::GetInstance();
00245 
00246   emcCalibrationData::EType type;
00247 
00248   if ( what == "IniCal" )
00249     {
00250       type = emcCalibrationData::kIniCal;
00251     }
00252   else if ( what == "TofSectorOffset" )
00253     {
00254       type = emcCalibrationData::kTofSectorOffset;
00255     }
00256   else
00257     {
00258       cerr << "emcCalibrationDataHelper::collectCalibData : type "
00259            << what << " is not supported"
00260            << endl;
00261       return 0;
00262     }
00263 
00264   emcCalibrationData* cd = new emcCalibrationData(type, number);
00265 
00266   if ( source(what) == emcManageable::kNone )
00267     {
00268       cout << "<WARNING> emcCalibrationDataHelper::collectCalibData : "
00269            << "source of "
00270            << what << " is \"none\". "
00271            << "That may be fine. I return a default object."
00272            << endl;
00273       // should create a default object here.
00274       // for now, assume the default ctor is ok
00275       return cd;
00276     }
00277 
00278   cd->SetSource(source(what));
00279 
00280   if ( dm->GetVerboseLevel() )
00281     {
00282       cout << "<I> emcCalibrationDataHelper::collectCalibData for type "
00283            << what << " number " << number
00284            << endl;
00285     }
00286 
00287   bool ok = false;
00288 
00289   if ( type == emcCalibrationData::kTofSectorOffset && 
00290        source(what) == emcManageable::kFile_ASCII)
00291     {
00292       ok = dm->Read(*cd,fRunNumber);
00293     }
00294   else
00295     {
00296       ok = dm->Read(*cd, fTimeStamp);
00297     }
00298 
00299   if ( !ok )
00300     {
00301       cerr << "<E> emcCalibrationDataHelper::collectCalibData for type "
00302            << what << " number " << number << " failed !"
00303            << endl;
00304       return 0;
00305     }
00306   else
00307     {
00308       return cd;
00309     }
00310 }
00311 
00312 //_____________________________________________________________________________
00313 const
00314 emcCalFEM*
00315 emcCalibrationDataHelper::getCalibration(int femAbsolutePosition,
00316                                          const char* whatKind)
00317 {
00318   return getCalibration(femAbsolutePosition, string(whatKind));
00319 }
00320 
00321 //_____________________________________________________________________________
00322 const emcCalFEM*
00323 emcCalibrationDataHelper::getCalibration(int femAbsolutePosition,
00324                                          const string& whatKind)
00325 {
00326   TMAPITER it = fData.find(whatKind);
00327   
00328   if ( it != fData.end() )
00329     {
00330       vector<emcCalFEM*>& vec = it->second;
00331       if ( femAbsolutePosition < 0 ||
00332            femAbsolutePosition >= static_cast<int>(vec.size()) )
00333         {
00334           cerr << "emcCalibrationDataHelper::getCalibration : "
00335                << "femAbsolutePosition (" << femAbsolutePosition
00336                << ") out of bounds (0.." << vec.size()-1
00337                << ") kind=" << whatKind
00338                << endl;
00339           return 0;
00340         }
00341       else
00342         {
00343           emcCalFEM* calfem = vec[femAbsolutePosition];
00344           if ( !calfem )
00345           {
00346                 std::string kind = whatKind;
00347                 std::string::size_type pos = whatKind.find_first_of(':');
00348                 if ( pos != std::string::npos )
00349                     {
00350                       kind = whatKind.substr(0,pos);
00351                           calfem = vec[femAbsolutePosition] 
00352                                 = getCalibration(femAbsolutePosition,kind)->clone();
00353                           patch(*calfem,whatKind.substr(pos+1));
00354                     }
00355                 else
00356                     {
00357                           calfem = vec[femAbsolutePosition]
00358                                 = collect(femAbsolutePosition, kind);
00359                     }
00360           }
00361           return calfem;
00362         }
00363     }
00364   else
00365     {
00366       cerr << "emcCalibrationDataHelper::getCalibration : unknown kind "
00367            << whatKind
00368            << endl;
00369       return 0;
00370     }
00371 }
00372 
00373 //_____________________________________________________________________________
00374 const emcCalibrationData*
00375 emcCalibrationDataHelper::getCalibrationData(const std::string& what,
00376                                              size_t number)
00377 {
00378   TCMAPITER it = fCalibData.find(what);
00379 
00380   if ( it != fCalibData.end() )
00381     {
00382       std::vector<emcCalibrationData*>& vec = it->second;
00383       if ( number >= vec.size() )
00384         {
00385           cerr << "emcCalibrationDataHelper::getCalibrationData : number ("
00386                << number << " out of bounds (0.." << vec.size()
00387                << endl;
00388           return 0;
00389         }
00390       else
00391         {
00392           emcCalibrationData* cd = vec[number];
00393           if ( !cd )
00394             {
00395               cd = vec[number] = collectCalibData(what, number);
00396             }
00397           return cd;
00398         }
00399     }
00400   else
00401     {
00402       cerr << "emcCalibrationDataHelper::getCalibrationData : unknown kind "
00403            << what
00404            << endl;
00405       return 0;
00406     }
00407 }
00408 
00409 //_____________________________________________________________________________
00410 const emcCalibrationData*
00411 emcCalibrationDataHelper::getCalibrationData(const char* what, size_t number)
00412 {
00413   return getCalibrationData(string(what), number);
00414 }
00415 
00416 //_____________________________________________________________________________
00417 const emcCalFEM*
00418 emcCalibrationDataHelper::getCalibrationFast(int femAbsolutePosition,
00419                                              const char* whatKind)
00420 {
00421   return getCalibrationFast(femAbsolutePosition, string(whatKind));
00422 }
00423 
00424 //_____________________________________________________________________________
00425 const emcCalFEM*
00426 emcCalibrationDataHelper::getCalibrationFast(int femAbsolutePosition,
00427                                              const string& whatKind)
00428 {
00429   TMAPITER it = fData.find(whatKind);
00430 
00431   if ( it != fData.end() )
00432     {
00433       vector<emcCalFEM*>& vec = it->second;
00434       return vec[femAbsolutePosition];
00435     }
00436   else
00437     {
00438       return 0;
00439     }
00440 }
00441 
00442 //_____________________________________________________________________________
00443 float
00444 emcCalibrationDataHelper::getEnergyCalibration(int towerid)
00445 {
00446   if ( fECalAtT0.empty() )
00447     {
00448       initECalAtT0(true);
00449     }
00450 
00451   if ( towerid >= 0 && towerid < static_cast<int>(fECalAtT0.size()) )
00452     {
00453       return fECalAtT0[towerid];
00454     }
00455   else
00456     {
00457       return 0.0;
00458     }
00459 }
00460 
00461 
00462 //_____________________________________________________________________________
00463 float
00464 emcCalibrationDataHelper::getEnergyCalibrationFast(int towerid)
00465 {
00466   return fECalAtT0[towerid];
00467 }
00468 
00469 //_____________________________________________________________________________
00470 float
00471 emcCalibrationDataHelper::getGainBaseLine(int isector,
00472                                           const char* what,
00473                                           const char* details,
00474                                           bool reallySilent)
00475 {
00476   std::string previousDetails(gainBaseLineCalculationDetails(isector));
00477         
00478   if ( !previousDetails.empty() &&
00479        previousDetails != details )
00480     {
00481       // Force re-initialization
00482       if ( !reallySilent )
00483         {
00484           std::cout << "<W> emcCalibrationDataHelper::getGainBaseLine : "
00485                     << "details changed. Recomputing average for sector "
00486                     << isector
00487                     << std::endl;
00488         }
00489       initGainBaseLine(isector, details);
00490     }
00491 
00492   TBLMAPITER it = fGainBaseLine.find(isector);
00493 
00494   if ( ! ( it != fGainBaseLine.end() ) )
00495     {
00496       initGainBaseLine(isector, details);
00497       it = fGainBaseLine.find(isector);
00498     }
00499 
00500   std::string swhat = what;
00501   if ( swhat == "value" )
00502     {
00503       return it->second.value();
00504     }
00505 
00506   if ( swhat == "error" )
00507     {
00508       return it->second.error();
00509     }
00510 
00511   if ( swhat == "skewness" ) 
00512     {
00513       return it->second.skewness();
00514     }
00515 
00516   if ( swhat == "kurtosis" )
00517     {
00518       return it->second.kurtosis();
00519     }
00520 
00521   // by default, return value
00522   return it->second.value();
00523 }
00524 
00525 //_____________________________________________________________________________
00526 const char* 
00527 emcCalibrationDataHelper::gainBaseLineCalculationDetails(int isector) const
00528 {
00529         std::map<int,std::string>::const_iterator it = 
00530                         fGainBaseLineCalculationDetails.find(isector);
00531         if ( it != fGainBaseLineCalculationDetails.end() )
00532         {
00533                 return it->second.c_str();
00534         }
00535         return "";
00536 }
00537 
00538 //_____________________________________________________________________________
00539 void
00540 emcCalibrationDataHelper::initAll(void)
00541 {
00542   cout << "emcCalibrationDataHelper::initAll : using TimeStamp="
00543        << fTimeStamp << endl;
00544 
00545 #ifdef DEBUG
00546   TBenchmark* g = new TBenchmark;
00547 #endif
00548 
00549   for ( size_t i = 0; i < fKnownFlavours.size(); ++i )
00550     {
00551       Flavour& f = fKnownFlavours[i];
00552 
00553 #ifdef DEBUG
00554       std::ostringstream name;
00555       name << gSystem->BaseName(__FILE__) << ":" << __LINE__ 
00556            << ":Collect time for " << f.name();
00557       g->Start(name.str().c_str());
00558 #endif
00559 
00560       Flavour::const_iterator it;
00561 
00562       size_t n = 0;
00563       for ( it = f.begin(); it != f.end(); ++it )
00564         {
00565           const emcCalFEM* calfem =
00566             getCalibration(*it, f.name().c_str());
00567           assert(calfem != 0);
00568           ++n;
00569         }
00570 #ifdef DEBUG
00571       g->Show(name.str().c_str());
00572 #endif
00573     }
00574   initECalAtT0(true);
00575 
00576   for ( size_t is = 0; is < 8; ++is ) 
00577     {
00578       if ( fFemList->hasSector(EmcIndexer::EmcSectorId(is)) )
00579         {
00580           getCalibrationData("TofSectorOffset", is);
00581         }
00582     }
00583 }
00584 
00585 //_____________________________________________________________________________
00586 void
00587 emcCalibrationDataHelper::initECalAtT0(bool normalizationON)
00588 {
00589   size_t ntowers = 172 * 144;
00590 
00591   fECalAtT0.clear();
00592   fECalAtT0.resize(ntowers);
00593 
00594   // Populate the fECalAtT0 array from sectors initial calibrations
00595 
00596   for ( size_t item = 0; item < ntowers; ++item )
00597     {
00598       int sn, ist;
00599 
00600       EmcIndexer::iPXiSiST(item, sn, ist);
00601 
00602       if ( fFemList->hasSector(EmcIndexer::EmcSectorId(sn)) )
00603         {
00604 
00605           float encal, norm0, one;
00606 
00607           const emcCalibrationData* sector = getCalibrationData("IniCal", sn);
00608           assert(sector != 0);
00609 
00610           if ( sn < 6 )
00611             {
00612               encal = sector->GetValue(ist, 0);         
00613               norm0 = sector->GetValue(ist, 1);
00614               one = sector->GetValue(ist, 2);
00615               assert( (fRunNumber>50000 && one == 1.0) || // Run2->
00616                       (one==0.0)); // Up to Run2
00617               fECalAtT0[item] = encal * ( normalizationON ? norm0 : 1. ) ;
00618             }
00619           else
00620             {
00621               encal = sector->GetValue(ist, 0) *
00622                 sector->GetValue(ist, 1) *
00623                 sector->GetValue(ist, 2);
00624               fECalAtT0[item] = encal;
00625             }
00626         }
00627     }
00628 }
00629 
00630 //_____________________________________________________________________________
00631 void
00632 emcCalibrationDataHelper::initGainBaseLine(int isector,
00633                                            const char* details)
00634 {
00635   float x;
00636   float sigma;
00637   float skewness;
00638   float kurtosis;
00639 
00640   bool ok = emcGainBaseLineCalculator::getBaseLine(this,
00641                                                    isector,details,
00642                                                    x,sigma,skewness,kurtosis);
00643 
00644   if ( ok )
00645     {
00646       fGainBaseLine[isector] = BaseLine(x, sqrt(sigma), skewness, kurtosis); 
00647     }
00648   else
00649     {
00650       std::cerr << "emcCalibrationDataHelper::initGainBaseLine : "
00651                 << "something went wrong."
00652                 << "Returning default value of 1.0"
00653                 << std::endl;
00654       fGainBaseLine[isector] = BaseLine(1, 0, 0, 0);
00655     }
00656   fGainBaseLineCalculationDetails[isector] = details;
00657 }
00658 
00659 //_____________________________________________________________________________
00660 void
00661 emcCalibrationDataHelper::patch(emcCalFEM& calfem, 
00662                                 const std::string& how)
00663 {
00664   // ok, this is not the best flexible code ever written...
00665   // it does its job, it was written quickly and required
00666   // minimum amount of code changes...
00667   // But please be my guest if you want to improve it...
00668 
00669   std::string::size_type p1 = how.find_first_of(':');
00670   std::string::size_type p2 = how.find_last_of(':');
00671 
00672   if ( p1 == std::string::npos || p2 == std::string::npos )
00673     {
00674       std::cerr << __FILE__ << ":" << __LINE__ << " ERROR ! how="
00675                 << how << " is not correct ! Patch inactive"
00676                 << std::endl;      
00677       return;
00678     }
00679 
00680   std::string what = how.substr(0,p1);
00681 
00682   if ( what != "BLR" )
00683     {
00684        std::cerr << __FILE__ << ":" << __LINE__ << " ERROR ! how="
00685                 << how << " not known to me! Patch inactive"
00686                 << std::endl;     
00687        return;
00688     }
00689 
00690   std::string details = how.substr(p1+1);
00691 
00692   emcTracedFEM* gains = dynamic_cast<emcTracedFEM*>(&calfem);
00693 
00694   int isector,ism;
00695   EmcIndexer::PXSM144_iSiSM144(gains->AbsolutePosition(),isector,ism);
00696    
00697   float factor = 1.0/getGainBaseLine(isector,"value",details.c_str(),true);
00698 
00699   for ( size_t ichannel = 0; ichannel < gains->size(); ++ichannel )
00700     {
00701       gains->FirstItem(ichannel);
00702       emcTracedValue* tv;
00703       while ( ( tv = gains->NextItem() ) )
00704         {
00705           tv->Set(tv->GetX(),tv->GetConstant()*factor,
00706                   tv->GetSlope()*factor,
00707                   tv->isConstant());
00708         }      
00709     }
00710 }
00711 
00712 //_____________________________________________________________________________
00713 emcManageable::EStorage
00714 emcCalibrationDataHelper::source(const string& what)
00715 {
00716   map<string, emcManageable::EStorage>::const_iterator it =
00717     fSources.find(what);
00718   if ( it != fSources.end() )
00719     {
00720       return it->second;
00721     }
00722   else
00723     {
00724       return emcManageable::kNone;
00725     }
00726 }
00727 
00728 //_____________________________________________________________________________
00729 bool
00730 emcCalibrationDataHelper::setSource(const string& what, 
00731                                     emcManageable::EStorage datasource)
00732 {
00733   if ( fInitAll )
00734     {
00735       std::cerr << __FILE__ << ":" << __LINE__ 
00736                 << " Can no longer change data source now, as "
00737                 << " initall constructor argument was used."
00738                 << std::endl;
00739       return false;
00740     }
00741 
00742   map<string, emcManageable::EStorage>::iterator it =
00743     fSources.find(what);
00744   if ( it != fSources.end() )
00745     {
00746       emcManageable::EStorage old = it->second;
00747       it->second = datasource;
00748       std::cout << __FILE__ << ":" << __LINE__ << " Changed " << what
00749                 << " data source from " 
00750                 << emcManageable::GetStorageName(old)
00751                 << " to " 
00752                 << emcManageable::GetStorageName(datasource)
00753                 << std::endl;
00754       return true;
00755     }
00756   else
00757     {
00758       if ( what == "QAs" || what == "RejectList" )
00759         {
00760           // those 2 are not dealt with by this object, but
00761           // by emcBadModules class.
00762           // Nevertheless, do not clutter standard output
00763           // with a warning about that.
00764           return false;
00765         }
00766       else
00767         {
00768           // this case really warrants a message on the standard error.
00769           std::cerr << __FILE__ << ":" << __LINE__ << " Unknown calibration type : "
00770                     << what
00771                     << std::endl;
00772           return false;
00773         }
00774     }
00775 }
00776 
00777 
00778 
00779 
00780 
00781 
00782 
00783