00001
00002
00003
00004
00005
00006
00008
00009 #include "Calibrator/Calibrator.h"
00010 #include "CMap/CMap.h"
00011 #include "JobControl/Exception.h"
00012 #include "Geometry/geo.h"
00013 #include "Database/Table.h"
00014 #include "TMath.h"
00015 #include "TSystem.h"
00016 #include "TFile.h"
00017 #include <iostream>
00018
00019 using namespace std;
00020 using namespace calib;
00021
00022 Calibrator* Calibrator::fInstance = 0;
00023
00024
00025
00026 Calibrator::Calibrator() :
00027 fCurrTimeStamp(0),
00028 fCurrDetector(rawdata::kNear),
00029 fCurrGeo(0),
00030 fPEACperMIP(0), fPEACperMIPErr(0),
00031 fLoadedFineTimeDistros(0)
00032 {
00033 fADCtoPE.clear();
00034 fMIPtoGeV.clear();
00035 fMIPtoGeVErr.clear();
00036 fFTDistNDX.clear();
00037 fFTDistNDY.clear();
00038 fFTDistFDX.clear();
00039 fFTDistFDY.clear();
00040 }
00041
00042
00043
00044
00045 void Calibrator::SetContext(TTimeStamp timestamp,
00046 rawdata::det_id_ detector,
00047 const geo::Geometry &geometry) {
00048 fCurrTimeStamp = timestamp;
00049 fCurrDetector = detector;
00050 fCurrGeo = &geometry;
00051 LoadFineTimeDistros();
00052
00053
00054
00055
00056
00057
00058
00059 }
00060
00061
00062
00063 Calibrator& Calibrator::Instance(TTimeStamp timestamp,
00064 rawdata::det_id_ detector,
00065 const geo::Geometry &geometry) {
00066 if (!fInstance)
00067 fInstance = new Calibrator;
00068 fInstance->SetContext(timestamp, detector, geometry);
00069 return *fInstance;
00070 }
00071
00072
00073
00074
00075
00076 bool Calibrator::LoadADCtoPE()
00077 {
00078 fADCtoPE.clear();
00079
00080 std::string dbFile = "ADCtoPE.xml";
00081
00082 db::Table* table = new db::Table(dbFile);
00083
00084 if (!table) return false;
00085
00086 if (table->Connect()) {
00087 table->Init(fCurrTimeStamp.GetSec());
00088
00089 if (table->empty()) return false;
00090
00091 table->Disconnect();
00092 }
00093
00094
00095 std::string str1 = "Channel";
00096 std::string str2 = "PEperADC";
00097 int chan;
00098 float val;
00099 for (unsigned int i=0; i<table->size(); ++i) {
00100 (*table)[i].Get(str1,chan);
00101 (*table)[i].Get(str2,val);
00102 fADCtoPE[chan] = val;
00103 }
00104
00105 delete table;
00106
00107 return true;
00108 }
00109
00110
00111
00112
00113
00114 bool Calibrator::LoadPEtoSigCor()
00115 {
00116 fPEtoSigCor.clear();
00117
00118 std::string dbFile = "PEtoSigCor.xml";
00119
00120 db::Table* table = new db::Table(dbFile);
00121
00122 if (!table) return false;
00123
00124 if (table->Connect()) {
00125 table->Init(fCurrTimeStamp.GetSec());
00126
00127 if (table->empty()) return false;
00128
00129 table->Disconnect();
00130 }
00131
00132
00133 std::string str1 = "Channel";
00134 std::string str2 = "SCperPE";
00135 int chan;
00136 float val;
00137 for (unsigned int i=0; i<table->size(); ++i) {
00138 (*table)[i].Get(str1,chan);
00139 (*table)[i].Get(str2,val);
00140 fPEtoSigCor[chan] = val;
00141 }
00142
00143 delete table;
00144
00145 return true;
00146 }
00147
00148
00149
00150
00151
00152 bool Calibrator::LoadSCtoPEAC()
00153 {
00154 fSCtoPEAC.clear();
00155
00156 std::string dbFile = "SigCortoPEAC.xml";
00157
00158 db::Table* table = new db::Table(dbFile);
00159
00160 if (!table) return false;
00161
00162 if (table->Connect()) {
00163 table->Init(fCurrTimeStamp.GetSec());
00164
00165 if (table->empty()) return false;
00166
00167 table->Disconnect();
00168 }
00169
00170
00171 std::string str1 = "Channel";
00172 std::string str2 = "A1";
00173 std::string str3 = "A2";
00174 std::string str4 = "L1";
00175 std::string str5 = "L2";
00176 int chan;
00177 for (unsigned int i=0; i<table->size(); ++i) {
00178 attlen a;
00179 (*table)[i].Get(str1,chan);
00180 (*table)[i].Get(str2,a.a1);
00181 (*table)[i].Get(str2+"Err",a.a1sig);
00182 (*table)[i].Get(str3,a.a2);
00183 (*table)[i].Get(str3+"Err",a.a2sig);
00184 (*table)[i].Get(str4,a.l1);
00185 (*table)[i].Get(str4+"Err",a.l1sig);
00186 (*table)[i].Get(str5,a.l2);
00187 (*table)[i].Get(str5+"Err",a.l2sig);
00188
00189 fSCtoPEAC[chan] = a;
00190 }
00191
00192 delete table;
00193
00194 return true;
00195 }
00196
00197
00198
00199
00200
00201 bool Calibrator::LoadPEACtoMIP()
00202 {
00203 fPEACperMIP = 1.;
00204
00205 std::string dbFile = "PEACtoMIP.xml";
00206
00207 db::Table* table = new db::Table(dbFile);
00208
00209 if (!table) return false;
00210
00211 if (table->Connect()) {
00212 table->Init(fCurrTimeStamp.GetSec());
00213
00214 if (table->empty()) return false;
00215
00216 table->Disconnect();
00217 }
00218
00219 std::string str1 = "PEACperMIP";
00220 (*table)[0].Get(str1,fPEACperMIP);
00221
00222 delete table;
00223
00224 return true;
00225 }
00226
00227
00228
00229
00230
00231 bool Calibrator::LoadMIPtoGeV()
00232 {
00233 fMIPtoGeV.clear();
00234
00235 std::string dbFile = "MIPtoGeV.xml";
00236
00237 db::Table* table = new db::Table(dbFile);
00238
00239 if (!table) return false;
00240
00241 if (table->Connect()) {
00242 table->Init(fCurrTimeStamp.GetSec());
00243
00244 if (table->empty()) return false;
00245
00246 table->Disconnect();
00247 }
00248
00249 float val;
00250 char buf[20];
00251 std::string str1;
00252 for (int i=0; i<5; ++i) {
00253 sprintf(buf,"par%d",i);
00254 str1 = buf;
00255 (*table)[0].Get(str1,val);
00256 fMIPtoGeV.push_back(val);
00257 }
00258
00259 delete table;
00260
00261 if (fMIPtoGeV.empty()) return false;
00262
00263 return true;
00264 }
00265
00266
00267
00268
00269
00270 bool Calibrator::LoadFineTimeDistros()
00271 {
00272 fFTDistNDX.clear();
00273 fFTDistNDY.clear();
00274 fFTDistFDX.clear();
00275 fFTDistFDY.clear();
00276
00277
00278 std::string dbFile = "FTDistroND.xml";
00279
00280 db::Table* table = new db::Table(dbFile);
00281
00282 if (!table) return false;
00283
00284 if (table->Connect()) {
00285 table->Init(fCurrTimeStamp.GetSec());
00286
00287 if (table->empty()) return false;
00288
00289 table->Disconnect();
00290 }
00291
00292 float x,y;
00293 std::string strx = "x";
00294 std::string stry = "y";
00295 for (unsigned int i=0; i<table->size(); ++i) {
00296 (*table)[i].Get(strx,x);
00297 (*table)[i].Get(stry,y);
00298 fFTDistNDX.push_back(x);
00299 fFTDistNDY.push_back(y);
00300 }
00301
00302 delete table;
00303
00304
00305 dbFile = "FTDistroFD.xml";
00306
00307 table = new db::Table(dbFile);
00308
00309 if (!table) return false;
00310
00311 if (table->Connect()) {
00312 table->Init(fCurrTimeStamp.GetSec());
00313
00314 if (table->empty()) return false;
00315
00316 table->Disconnect();
00317 }
00318
00319 for (unsigned int i=0; i<table->size(); ++i) {
00320 (*table)[i].Get(strx,x);
00321 (*table)[i].Get(stry,y);
00322 fFTDistFDX.push_back(x);
00323 fFTDistFDY.push_back(y);
00324 }
00325
00326 delete table;
00327
00328 fLoadedFineTimeDistros = 1;
00329
00330 return true;
00331 }
00332
00333
00334
00335
00336
00337 void Calibrator::MakeCellHit(const RawDigit *rawdigit, CellHit *cellhit) {
00338
00339
00340 (*((RawDigit*)cellhit)) = (*rawdigit);
00341
00342 cmap::CMap& cmap = cmap::CMap::Instance(fCurrTimeStamp,fCurrDetector);
00343
00344
00345 cellhit->SetStatus(0);
00346 cellhit->SetCell (cmap.GetCell(rawdigit));
00347 cellhit->SetPlane (cmap.GetPlane(rawdigit));
00348 cellhit->SetView (fCurrGeo->Plane(cellhit->Plane()).View());
00349 cellhit->SetTNS (GetTNS(rawdigit));
00350 cellhit->SetPE (GetPE(rawdigit));
00351 cellhit->SetPECorr(cellhit->PE()*GetPECorrFactor(rawdigit));
00352 }
00353
00354
00355 float Calibrator::GetPE(const RawDigit *rawdigit) {
00356
00357
00358
00359 float gain = 1.43;
00360 return rawdigit->ADC(0)/gain;
00361 }
00362
00363
00364 float Calibrator::GetPECorrFactor(const RawDigit* ) {
00365
00366
00367 return 1.0;
00368 }
00369
00370
00371 float Calibrator::GetTNS(const RawDigit *rawdigit) {
00372
00373
00374
00375
00376 Double_t t = 0;
00377
00378
00379
00380
00381 if (rawdigit->NADC()<=1) {
00382
00383
00384 t = rawdigit->TDC(0)*62.5;
00385
00386 }
00387 else {
00388
00389
00390
00391
00392
00393
00394 Double_t peakadc = rawdigit->ADC(0);
00395 Double_t x = (rawdigit->ADC(1))/peakadc;
00396 Double_t y = (rawdigit->ADC(2))/peakadc;
00397
00398
00399
00400 Double_t Xa = 0.0;
00401 Double_t Ya = 1.0;
00402 Double_t Xb = 0.0;
00403 Double_t Yb = (fCurrDetector==rawdata::kNear?0.90:0.885);
00404 Double_t Xc = 1.0;
00405 Double_t Yc = 0.800;
00406
00407
00408
00409
00410 Double_t L1 = sqrt((Yb-Ya)*(Yb-Ya)+(Xb-Xa)*(Xb-Xa));
00411 Double_t L2 = sqrt((Yc-Yb)*(Yc-Yb)+(Xc-Xb)*(Xc-Xb));
00412
00413
00414 Double_t U1 = ((x-Xa)*(Xb-Xa)+(y-Ya)*(Yb-Ya))/L1/L1;
00415 if (U1<0) U1=0;
00416 if (U1>0.99999) U1=0.99999;
00417 Double_t PX1 = Xa + U1*(Xb-Xa);
00418 Double_t PY1 = Ya + U1*(Yb-Ya);
00419 Double_t D1 = sqrt((PX1-x)*(PX1-x)+(PY1-y)*(PY1-y));
00420
00421
00422 Double_t U2 = ((x-Xb)*(Xc-Xb)+(y-Yb)*(Yc-Yb))/L2/L2;
00423 if (U2<0) U2=0;
00424 if (U2>0.99999) U2=0.99999;
00425 Double_t PX2 = Xb + U2*(Xc-Xb);
00426 Double_t PY2 = Yb + U2*(Yc-Yb);
00427 Double_t D2 = sqrt((PX2-x)*(PX2-x)+(PY2-y)*(PY2-y));
00428
00429
00430 Double_t U;
00431 if (D1<D2) U = U1*L1/(L1+L2);
00432 else U = (L1+U2*L2)/(L1+L2);
00433
00434
00435 vector<float>& ftx = fFTDistNDX;
00436 vector<float>& fty = fFTDistNDY;
00437 if (fCurrDetector == rawdata::kFar) {
00438 ftx = fFTDistFDX;
00439 fty = fFTDistFDY;
00440 }
00441
00442 unsigned int bin=1;
00443 if (U < ftx[0])
00444 bin = 0;
00445 else
00446 for (; bin<ftx.size()-1; ++bin) {
00447 if (U >= ftx[bin-1] && U < ftx[bin]) break;
00448 }
00449 if (bin == ftx.size()) {
00450
00451 std::cout << "In GetTNS(): bin=" << bin << " u=" << U << std::endl;
00452 bin=ftx.size()-1;
00453 }
00454 Double_t timefrac = 0.5*( fty[bin] + fty[bin-1]);
00455
00456
00457 Double_t gap = (fCurrDetector==rawdata::kNear?125.0:500.0);
00458
00459 t = rawdigit->TDC(0)*62.5 - timefrac*gap;
00460 }
00461
00462 return t;
00463 }
00464
00465
00466
00467
00468
00469
00470 void Calibrator::MakeRecoHit(const CellHit *cellhit, RecoHit *recohit, float w) {
00471
00472
00473 (*((CellHit*)recohit)) = (*cellhit);
00474
00475
00476 recohit->SetW(w);
00477
00478
00479 Double_t xyzd[4];
00480 GetXYZD(cellhit,w,xyzd);
00481
00482 recohit->SetX (xyzd[0]);
00483 recohit->SetY (xyzd[1]);
00484 recohit->SetZ (xyzd[2]);
00485
00486 recohit->SetT (GetT (cellhit,xyzd[3]));
00487 recohit->SetPEAtt(GetPEAtt(cellhit,xyzd[3]));
00488
00489 recohit->SetMIP (recohit->PEAtt() * GetMIPScale(cellhit));
00490 recohit->SetGeV (recohit->MIP() * GetGeVScale(cellhit));
00491 }
00492
00493
00494 float Calibrator::GetT(const CellHit *cellhit, float dist_to_readout) {
00495
00496 Double_t speedOfFiberTransport = 15.3;
00497
00498
00499
00500 return (cellhit->TNS()-dist_to_readout/speedOfFiberTransport);
00501 }
00502
00503
00504 float Calibrator::GetPEAtt(const CellHit *cellhit, float dist_to_readout) {
00505
00506
00507
00508 Double_t F0 = 5.744;
00509 Double_t L0 = 315.3;
00510 Double_t F1 = 1.546;
00511 Double_t L1 = 3329.;
00512
00513 Double_t attenuation = F0*TMath::Exp(-dist_to_readout/L0) +
00514 F1*TMath::Exp(-dist_to_readout/L1);
00515
00516 return cellhit->PECorr() / attenuation;
00517 }
00518
00519
00520 float Calibrator::GetMIPScale(const CellHit* ) {
00521
00522 return 0.033;
00523 }
00524
00525
00526 float Calibrator::GetGeVScale(const CellHit* ) {
00527
00528
00529 return 0.013;
00530 }
00531
00532
00533 void Calibrator::GetXYZD(const CellHit *cellhit, float w, double *xyzd) {
00534
00535
00536
00537
00538 UInt_t plane = cellhit->Plane();
00539 UInt_t cell = cellhit->Cell();
00540 if (plane>=fCurrGeo->NPlanes()) {
00541 throw geo::Exception(__FILE__,__LINE__,geo::Exception::BAD_PLANE_NUMBER);
00542 }
00543 const geo::PlaneGeo& p = fCurrGeo->Plane(plane);
00544 if (cell>=p.Ncells()) {
00545 throw geo::Exception(__FILE__,__LINE__,geo::Exception::BAD_CELL_NUMBER);
00546 }
00547 const geo::CellGeo& c = p.Cell(cell);
00548
00549
00550
00551
00552
00553 c.GetCenter(xyzd);
00554 if (cellhit->View()==geo::kX)
00555 xyzd[1] = w;
00556 else
00557 xyzd[0] = w;
00558 Double_t localxyz[3];
00559 c.WorldToLocal(xyzd,localxyz);
00560 xyzd[3] = c.DistToReadOut(localxyz[2]);
00561 }
00562