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;
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
00168
00169
00170
00171
00172
00173 assert(fTimeStamp != 0);
00174
00175 emcDataManager* dm = emcDataManager::GetInstance();
00176
00177 if ( source(what) == emcManageable::kNone )
00178 {
00179
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
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 }
00229
00230 return calfem;
00231 }
00232
00233
00234 emcCalibrationData*
00235 emcCalibrationDataHelper::collectCalibData(const std::string& what,
00236 size_t number)
00237 {
00238
00239
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
00274
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
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
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
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) ||
00616 (one==0.0));
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
00665
00666
00667
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
00761
00762
00763
00764 return false;
00765 }
00766 else
00767 {
00768
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