00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012 #include "PulserTimeCalScheme.h"
00013 #include "MessageService/MsgService.h"
00014 #include "Plex/PlexHandle.h"
00015 #include "Plex/PlexSEIdAltL.h"
00016 #include "Plex/PlexStripEndId.h"
00017 #include "DatabaseInterface/DbiValidityRec.h"
00018 #include "Validity/VldRange.h"
00019 #include "Calibrator.h"
00020
00021 CVSID("$Id: PulserTimeCalScheme.cxx,v 1.22 2006/08/30 16:24:25 tagg Exp $");
00022 ClassImp(PulserTimeCalScheme)
00023
00024
00025 const RawChannelId kVaRcid(Detector::kFar,ElecType::kVA,0,0);
00026
00027 PulserTimeCalScheme::PulserTimeCalScheme()
00028 {
00029 Registry r;
00030
00031 r.Set("UseMuonCalibration",1);
00032 r.Set("UsePulserCalibration",0);
00033 r.Set("UseShieldCalibration",1);
00034 r.Set("UseJumps",1);
00035 r.Set("JumpTask",1);
00036 r.Set("DoWalkCorrection",1);
00037 r.Set("PulserLed1",2);
00038 r.Set("PulserLed2",3);
00039 r.Set("PulserLed3",4);
00040 r.Set("DefaultTimingCardSetting",260.);
00041
00042 r.Set("ReferenceDate",20040930);
00043 r.Set("ReferenceTime",0);
00044 r.Set("MuonTask","Andys");
00045 InitializeConfig(r);
00046 }
00047
00048
00049 void PulserTimeCalScheme::ConfigModified()
00050 {
00051 Int_t refDate = 0;
00052 Int_t refTime = 0;;
00053
00054 const char* taskname;
00055
00056 bool ok = true;
00057 ok = ok && GetConfig().Get("UseMuonCalibration",fUseMuonCalibration);
00058 ok = ok && GetConfig().Get("UseShieldCalibration",fUseShieldCalibration);
00059 ok = ok && GetConfig().Get("UsePulserCalibration",fUsePulserCalibration);
00060 ok = ok && GetConfig().Get("UseJumps",fUseJumps);
00061 ok = ok && GetConfig().Get("JumpTask",fJumpTask);
00062 ok = ok && GetConfig().Get("DoWalkCorrection",fDoWalkCorrection);
00063 ok = ok && GetConfig().Get("DefaultTimingCardSetting",fDefaultTimingCardSetting);
00064
00065 ok = ok && GetConfig().Get("ReferenceDate",refDate);
00066 ok = ok && GetConfig().Get("ReferenceTime",refTime);
00067 for(int i=0;i<kMaxLeds; i++) {
00068 ok = ok && GetConfig().Get(Form("PulserLed%d",i+1),fPulserLed[i]);
00069 }
00070 ok = ok && GetConfig().Get("MuonTask",taskname);
00071
00072 if(!ok){
00073 MSG("Calib",Msg::kWarning) << "PulserTimeCalScheme couldn't configure properly!" << endl;
00074 GetConfig().PrettyPrint(std::cerr);
00075 }
00076
00077 if (0==strcasecmp(taskname,"Andys" )){ fMuonTask = 1; }
00078 else if(0==strcasecmp(taskname,"Brians")){ fMuonTask = 0; }
00079 else{
00080
00081 MSG("Calib",Msg::kWarning) << "PulserTimeCalScheme doesn't recognise task " << taskname << endl;
00082 }
00083
00084 fReferenceTime = VldTimeStamp(refDate,refTime,0);
00085
00086
00087 Reset(GetContext(),true);
00088 }
00089
00090
00091 void PulserTimeCalScheme::PrintConfig( std::ostream& os ) const
00092 {
00093 char taskname[100];
00094 switch(fMuonTask) {
00095 case 0: sprintf(taskname,"Brians"); break;
00096 case 1: sprintf(taskname,"Andys"); break;
00097 default: sprintf(taskname,"Task %d",fMuonTask); break;
00098 }
00099
00100 os << " UseMuonCalibration: " << ((fUseMuonCalibration)?("On"):("Off")) << endl;
00101 os << " MuonTask: " << taskname << endl;
00102 os << " UseShieldCalibration: " << ((fUseShieldCalibration)?("On"):("Off")) << endl;
00103 os << " UseJumps: " << ((fUseJumps)?("On"):("Off")) << endl;
00104 os << " JumpTask: " << fJumpTask << endl;
00105 os << " UsePulserCalibration: " << ((fUsePulserCalibration)?("On"):("Off")) << endl;
00106 os << " DoWalkCorrection: " << ((fDoWalkCorrection)?("On"):("Off")) << endl;
00107 os << " Reference date: " << fReferenceTime.AsString() << endl;
00108 os << " PulserLeds to use: ";
00109 for(int i=0;i<kMaxLeds;i++) {
00110 os << fPulserLed[i];
00111 if(i!=kMaxLeds-1) os << ",";
00112 }
00113 os << endl;
00114
00115 }
00116
00117
00118 void PulserTimeCalScheme::DoReset( const VldContext& context )
00119 {
00120 MSG("Calib",Msg::kVerbose) << "PulserTimeCalScheme::DoReset()" << endl;
00121
00122 if(fUseMuonCalibration) {
00123 fMuonResPtr.NewQuery(context,fMuonTask);
00124
00125 if(fMuonResPtr.GetNumRows()==0) {
00126 MAXMSG("Calib",Msg::kWarning,10)
00127 << "No rows in CALTIMECALIBRATION with validity context "
00128 << context.AsString() << " No muon timing calibration will be applied." << endl;
00129 IncrementErrors(kTimeCalibrator,kMissingTable);
00130 }
00131 }
00132
00133 if(fUseShieldCalibration && context.GetDetector()==Detector::kFar) {
00134 fShieldResPtr.NewQuery(context,99);
00135 if(fShieldResPtr.GetNumRows()==0) {
00136 MAXMSG("Calib",Msg::kWarning,10)
00137 << "No rows for FD shield timing calibration CALTIMECALIBRATION task "
00138 << 99 << " with validity context "
00139 << context.AsString() << endl;
00140 IncrementErrors(kTimeCalibrator,kMissingTable);
00141 }
00142 }
00143
00144 if(fUseJumps) {
00145 fJumpResPtr.NewQuery(context,fJumpTask);
00146
00147 }
00148
00149 VldContext refContext(context.GetDetector(),
00150 context.GetSimFlag(),
00151 fReferenceTime);
00152
00153 if(fUsePulserCalibration) {
00154
00155
00156
00157 for(int iled=0;iled<kMaxLeds;iled++) {
00158 fDriftPtr[iled].NewQuery(context,fPulserLed[iled]);
00159 if(fDriftPtr[iled].GetNumRows()==0) {
00160 MAXMSG("Calib",Msg::kWarning,10)
00161 << "No rows in PULSERTIMEDRIFT task " << fPulserLed[iled] << " with validity context "
00162 << context.AsString() << endl;
00163 IncrementErrors(kTimeCalibrator,kMissingTable);
00164 }
00165
00166
00167 fDriftRefPtr[iled].NewQuery(refContext,fPulserLed[iled]);
00168 if(fDriftRefPtr[iled].GetNumRows()==0) {
00169 MAXMSG("Calib",Msg::kWarning,10)
00170 << "No rows in PULSERTIMEDRIFT task " << fPulserLed[iled] << " with reference context "
00171 << refContext.AsString() << endl;
00172 IncrementErrors(kTimeCalibrator,kMissingTable);
00173 }
00174
00175 }
00176
00177
00178
00179 fTimingCardResPtr.NewQuery(context,0);
00180 if(fTimingCardResPtr.GetNumRows()==0) {
00181 MAXMSG("Calib",Msg::kWarning,10)
00182 << "No rows in PULSERTIMINGCARDSETTING with validity context "
00183 << context.AsString() << endl;
00184 IncrementErrors(kTimeCalibrator,kMissingTable);
00185 }
00186
00187 fTimingCardReferencePtr.NewQuery(refContext,0);
00188 if(fTimingCardReferencePtr.GetNumRows()==0) {
00189 MAXMSG("Calib",Msg::kWarning,10)
00190 << "No rows in PULSERTIMINGCARDSETTING with reference context "
00191 << refContext.AsString() << endl;
00192 IncrementErrors(kTimeCalibrator,kMissingTable);
00193 }
00194
00195 }
00196 }
00197
00198
00199 DoubleErr PulserTimeCalScheme::GetCalibratedTime(DoubleErr rawtime,
00200 FloatErr rawcharge,
00201 const PlexStripEndId& seid) const
00202 {
00214
00215
00216 DoubleErr time = rawtime;
00217
00218 if(seid.IsVetoShield()) {
00219
00220
00221 if(fUseShieldCalibration) time = CalibrateShield(time,rawcharge,seid,true);
00222 } else {
00223
00224
00225
00226 if(GetContext().GetDetector()==Detector::kFar) {
00227 PlexHandle plex(GetContext());
00228 RawChannelId rcid = plex.GetRawChannelId(seid);
00229 if(fUseJumps) time = CalibrateByJumps(time,rcid,true);
00230 if(fUsePulserCalibration) time = CalibrateByPulser(time,rcid,true);
00231 }
00232 if(fUseMuonCalibration) time = CalibrateByMuon(time,seid,true);
00233 if(fDoWalkCorrection) time-= WalkCorrection(rawcharge,seid);
00234 }
00235
00236 return time;
00237 }
00238
00239
00240 DoubleErr PulserTimeCalScheme::DecalTime(DoubleErr caltime,
00241 FloatErr rawcharge,
00242 const PlexStripEndId& seid) const
00243 {
00257
00258
00259 DoubleErr time = caltime;
00260
00261 if(seid.IsVetoShield()) {
00262
00263
00264 if(fUseShieldCalibration) time = CalibrateShield(time,rawcharge,seid,false);
00265
00266 } else {
00267
00268
00269
00270 if(GetContext().GetDetector()==Detector::kFar) {
00271 PlexHandle plex(GetContext());
00272 RawChannelId rcid = plex.GetRawChannelId(seid);
00273 if(fUseJumps) time = CalibrateByJumps(time,rcid,false);
00274 if(fUsePulserCalibration) time = CalibrateByPulser(time,rcid,false);
00275 }
00276 if(fUseMuonCalibration) time = CalibrateByMuon(time,seid,false);
00277 if(fDoWalkCorrection) time+= WalkCorrection(rawcharge,seid);
00278 }
00279
00280 return time;
00281 }
00282
00283
00284
00285 DoubleErr PulserTimeCalScheme::CalibrateByJumps(DoubleErr rawtime,
00286 const RawChannelId& rcid,
00287 Bool_t calibrate) const
00288 {
00289
00290 UInt_t index = CalTimeJump::GetIndex(rcid);
00291
00292
00293
00294 const CalTimeJump* jump = fJumpResPtr.GetRowByIndex(index);
00295 if(jump) {
00296 if(calibrate)
00297 return rawtime - (double)jump->GetJump();
00298 else
00299 return rawtime + (double)jump->GetJump();
00300 }
00301
00302
00303
00304 return rawtime;
00305 }
00306
00307
00308 DoubleErr PulserTimeCalScheme::CalibrateByMuon(DoubleErr rawtime,
00309 const PlexStripEndId& seid,
00310 Bool_t calibrate) const
00311 {
00312
00313 const CalTimeCalibration* dpgc = fMuonResPtr.GetRowByIndex(seid.BuildPlnStripEndKey());
00314
00315 if(dpgc==0) {
00316 if(fMuonResPtr.GetNumRows()>0) {
00317 MAXMSG("Calib",Msg::kWarning,10)
00318 << "PulserTimeCalScheme: No database row for StripEnd " << seid.AsString() << "\n";
00319
00320 IncrementErrors(kTimeCalibrator,kMissingRow,seid);
00321 }
00322 return rawtime + DoubleErr(0,20.*Munits::ns);
00323 }
00324 if(calibrate)
00325 return (rawtime/(double)dpgc->GetScale()) - (double)dpgc->GetOffset();
00326
00327
00328
00329
00330 return (rawtime + (double)dpgc->GetOffset())*(double)dpgc->GetScale();
00331 }
00332
00333
00334
00335
00336 DoubleErr PulserTimeCalScheme::CalibrateByPulser(DoubleErr rawtime,
00337 const RawChannelId& rcid,
00338 Bool_t calibrate) const
00339 {
00340
00341 UInt_t index = PulserTimeDrift::GetIndex(rcid);
00342
00343 const PulserTimeDrift* drift = 0;
00344 const PulserTimeDrift* driftref = 0;
00345
00346
00347 Int_t whichled = 0;
00348 bool driftok = GetPulserCalibration(whichled,index,drift,driftref);
00349
00350
00351 while(!driftok){
00352 whichled++;
00353 if(whichled<kMaxLeds) {
00354 driftok = GetPulserCalibration(whichled,index,drift,driftref);
00355 MSG("Calib",Msg::kDebug) << "PulserTiming: " << rcid.AsString() << " Fell back to LED " << fPulserLed[whichled] << endl;
00356 } else {
00357 MAXMSG("Calib",Msg::kWarning,10)
00358 << "PulserTimeCalScheme: Failed to find calibration for channel "
00359 << rcid.AsString() << " index " << index << " in primary or fallback tables.\n";
00360 IncrementErrors(kTimeCalibrator,kMissingRow,rcid);
00361 return rawtime + DoubleErr(0,50.*Munits::ns);
00362 }
00363 }
00364
00365
00366
00367 const PulserTimingCardSetting* cardSetting =
00368 fTimingCardResPtr.GetRowByIndex(rcid.GetCrate());
00369 const PulserTimingCardSetting* refCardSetting =
00370 fTimingCardReferencePtr.GetRowByIndex(rcid.GetCrate());
00371
00372 Double_t tpmt_delay_ns = fDefaultTimingCardSetting;
00373 Double_t ref_delay_ns = fDefaultTimingCardSetting;
00374
00375
00376 if(cardSetting==0) {
00377 if(fTimingCardResPtr.GetNumRows()>0) {
00378 MAXMSG("Calib",Msg::kWarning,10) << "Incomplete PulserTimingCardSettings table!" << endl;
00379 }
00380 IncrementErrors(kTimeCalibrator,kMissingRow,rcid);
00381 } else {
00382 tpmt_delay_ns = cardSetting->GetDelayNanoSecs();
00383 }
00384
00385
00386
00387 if(refCardSetting==0) {
00388 if(fTimingCardReferencePtr.GetNumRows()>0) {
00389 MAXMSG("Calib",Msg::kWarning,10) << "Incomplete PulserTimingCardSettings table!" << endl;
00390 }
00391 IncrementErrors(kTimeCalibrator,kMissingRow,rcid);
00392 } else {
00393 ref_delay_ns = cardSetting->GetDelayNanoSecs();
00394 }
00395
00396
00397
00398
00399
00400 double crate_offset_t = (tpmt_delay_ns - ref_delay_ns)*Munits::ns;
00401
00402
00403
00404 double drift_tdcs = (drift->GetMean() - driftref->GetMean());
00405 double drift_err = (drift->GetRms() / sqrt(drift->GetEntries()));
00406 double convert = Calibrator::Instance().GetTDCConvert(kVaRcid);
00407 DoubleErr drift_t(drift_tdcs * convert,
00408 drift_err * convert);
00409
00410
00411
00412
00413 DoubleErr offset = drift_t - crate_offset_t;
00414
00415 if(calibrate)
00416 return rawtime - offset;
00417
00418
00419 return rawtime + offset;
00420 }
00421
00422 Bool_t
00423 PulserTimeCalScheme::GetPulserCalibration(Int_t iled, UInt_t index,
00424 const PulserTimeDrift* &drift,
00425 const PulserTimeDrift* &ref) const
00426 {
00427
00428
00429
00430 drift = fDriftPtr[iled].GetRowByIndex(index);
00431 ref = fDriftRefPtr[iled].GetRowByIndex(index);
00432
00433
00434 if(drift==0) return false;
00435 if(ref==0) return false;
00436
00437
00438
00439
00440
00441
00442
00443 if( drift->GetRms() >= sqrt(drift->GetEntries())*0.2 ) return false;
00444 if( ref->GetRms() >= sqrt( ref->GetEntries())*0.2 ) return false;
00445
00446
00447 return true;
00448 }
00449
00450
00451
00452
00453 DoubleErr PulserTimeCalScheme::WalkCorrection(FloatErr rawcharge,
00454 const PlexStripEndId&) const
00455 {
00461
00462
00463 if(GetContext().GetDetector()==Detector::kFar) {
00464
00465 const float kParData[4] = { 5.44066e+00,
00466 -5.94887e-01,
00467 -7.36609e-02,
00468 7.66637e-03 };
00469
00470 const float kParMC[4] = { 4.18608e+00,
00471 -3.75033e-01,
00472 -9.50218e-02,
00473 9.52560e-03 };
00474
00475 const float* par = kParData;
00476 if(GetContext().GetSimFlag()==SimFlag::kMC) par = kParMC;
00477
00478 if(rawcharge<=0) rawcharge = 1;
00479 double cx = log(rawcharge()/2.3);
00480 double walk = (
00481 par[0]
00482 + (par[1] * cx)
00483 + (par[2] * cx *cx)
00484 + (par[3] * cx * cx *cx)
00485 );
00486
00487 return walk / Munits::c_light;
00488
00489 }
00490
00491 return 0;
00492 }
00493
00494
00495 DoubleErr PulserTimeCalScheme::CalibrateShield(DoubleErr rawtime,
00496 FloatErr rawcharge,
00497 const PlexStripEndId& seid,
00498 Bool_t calibrate) const
00499 {
00500
00501 const CalTimeCalibration* dpgc = fShieldResPtr.GetRowByIndex(seid.BuildPlnStripEndKey());
00502
00503 if(dpgc==0) {
00504 if(fShieldResPtr.GetNumRows()>0) {
00505 MAXMSG("Calib",Msg::kWarning,10)
00506 << "PulserTimeCalScheme: No database row for shield StripEnd " << seid.AsString() << "\n";
00507 IncrementErrors(kTimeCalibrator,kMissingRow,seid);
00508 }
00509 return rawtime - DoubleErr(-30.0*Munits::ns,
00510 20.*Munits::ns);
00511 }
00512
00513
00514 if(rawcharge<1) rawcharge=1;
00515 Double_t logq = log(rawcharge);
00516
00517 Double_t walk = 0;
00518 if(fDoWalkCorrection) {
00519 const float kgainadjust=60./90.;
00520 walk = WalkCorrection(rawcharge*kgainadjust,seid);
00521 walk += dpgc->GetSlewC1()
00522 + dpgc->GetSlewC2()*logq
00523 + dpgc->GetSlewC3()*logq*logq
00524 + dpgc->GetSlewC4()*logq*logq*logq;
00525 }
00526
00527
00528 if(calibrate)
00529 return rawtime - walk + (double)dpgc->GetOffset();
00530
00531
00532 return rawtime + walk - (double)dpgc->GetScale();
00533
00534 }
00535