00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00066
00067 #include "JobControl/JobCModuleRegistry.h"
00068 #include "JobControl/JobCommand.h"
00069 #include "PulserCalibration/PulserDBModule.h"
00070 #include "MessageService/MsgService.h"
00071 #include "MinosObjectMap/MomNavigator.h"
00072 #include "PulserCalibration/PulserSummaryList.h"
00073 #include "PulserCalibration/PulserSummary.h"
00074 #include "Validity/VldContext.h"
00075 #include "Validity/VldRange.h"
00076 #include "Validity/VldTimeStamp.h"
00077 #include "DatabaseInterface/DbiWriter.h"
00078 #include "DatabaseInterface/DbiResultPtr.h"
00079 #include "DatabaseInterface/DbiTableProxy.h"
00080 #include "DatabaseInterface/DbiDBProxy.h"
00081 #include "DatabaseInterface/DbiCache.h"
00082 #include "PulserCalibration/PulserDrift.h"
00083 #include "PulserCalibration/PulserDriftPin.h"
00084 #include "PulserCalibration/PulserConventions.h"
00085 #include "RawData/RawRecord.h"
00086 #include "RawData/RawHeader.h"
00087 #include "RawData/RawDaqHeader.h"
00088
00089 #include "TROOT.h"
00090 #include "TFolder.h"
00091
00092 ClassImp(PulserDBModule)
00093
00094
00095
00096 CVSID("$Id: PulserDBModule.cxx,v 1.16 2007/08/28 18:42:32 tjyang Exp $");
00097 JOBMODULE(PulserDBModule,"PulserDBModule","Collate summaries, write to DB");
00098
00099
00100
00101 PulserDBModule::PulserDBModule(): fGainLog(0)
00102 {
00103 fGCValid = 3600*24*62;
00104 fDPValid = 3600*24*1;
00105 fLongTime = 3600*24*365*20;
00106 fRunStart = false;
00107 fFileStart = false;
00108 fGainPin[0] = fGainPin[1] = 0;
00109 }
00110
00111 PulserDBModule::~PulserDBModule()
00112 {
00113
00114 }
00115
00116
00117
00118 JobCResult PulserDBModule::Reco(MomNavigator *mom)
00119 {
00120
00121 static int runnew, subrunnew;
00122 static int runold=0;
00123 static int subrunold=0;
00124
00125
00126 TIter iter = mom->FragmentIter();
00127 while (TObject *obj = iter.Next()) {
00128 RawRecord *rawrec = dynamic_cast<RawRecord *>(obj);
00129 if (rawrec) {
00130
00131 const RawDaqHeader* daqHead =
00132 dynamic_cast<const RawDaqHeader*>(rawrec->GetRawHeader());
00133
00134 if (daqHead){
00135 runnew = daqHead->GetRun();
00136 subrunnew = daqHead->GetSubRun();
00137 MSG("Pulser",Msg::kDebug) <<
00138 "run, subrun: " << runnew << "' " << subrunnew <<endl;
00139 }
00140
00141 if ((runold!=0) &&(runnew!=runold || subrunnew!=subrunold)){
00142 MSG("Pulser",Msg::kInfo) <<"Calling Endfile() with runold="<<runold<<endl;
00143 EndFile();
00144 }
00145
00146 if ((runold!=0) && runnew!=runold){
00147 MSG("Pulser",Msg::kInfo) <<"Calling EndRun() with runold="<<runold<<endl;
00148 MSG("Pulser",Msg::kInfo) <<"Starting new run: "<<runnew<<endl;
00149 EndRun();
00150 }
00151
00152 runold=runnew;
00153 subrunold=subrunnew;
00154 }
00155 }
00156
00157
00158 PulserSummaryList *psl = dynamic_cast<PulserSummaryList *>
00159 (mom->GetFragment("PulserSummaryList"));
00160 if (psl==0) {
00161 MSG("Pulser",Msg::kVerbose) <<"No pulser summary list here\n";
00162 return JobCResult::kFailed;
00163 }
00164 MSG("Pulser",Msg::kDebug) <<"Got pulser summary "<<psl->GetPointIndex()
00165 <<" of "<<psl->GetExpectedPoints()<<endl;
00166
00167 if (fRunStart) {
00168
00169 }
00170 switch(psl->GetExpectedPoints()) {
00171 case 0:
00172
00173 MSG("Pulser",Msg::kInfo) <<"Dropping LI summary with "<<
00174 psl->GetTriggers()<<" pulses: Pulser is off!"<<endl;
00175 break;
00176 case 1:
00177
00178
00179 MSG("Pulser",Msg::kInfo) <<"Doug Point: not written"<<endl;
00180
00181 break;
00182 default:
00183
00184 MSG("Pulser",Msg::kInfo) <<"GainCurve"<<endl;
00185 GainCurve(psl);
00186 break;
00187 };
00188 return JobCResult::kPassed;
00189
00190 }
00191
00192 void PulserDBModule::BeginRun()
00193 {
00194 fRunStart = true;
00195 MSG("Pulser",Msg::kDebug) << "PulserDBModule::BeginRun()\n";
00196 }
00197
00198 void PulserDBModule::EndRun()
00199 {
00200 MSG("Pulser",Msg::kDebug) << "PulserDBModule::EndRun()\n";
00201
00202 if (fGainLog) {
00203 MergeBack();
00204 MergeForward();
00205 if (fGainLog->IsComplete()) {
00206 WriteGC();
00207 DropGC();
00208 }
00209 WriteTempGC();
00210 }
00211
00212 PulserSummaryList *psl = dynamic_cast<PulserSummaryList *>(gROOT->GetRootFolder()->FindObject("Loon/Pulser/PulserSummaryList"));
00213
00214 if (psl){
00215 MSG("Pulser",Msg::kDebug) << "PulserDBModule::EndRun(): rescue the last point"<<endl;
00216
00217 switch(psl->GetExpectedPoints()) {
00218 case 0:
00219
00220 MSG("Pulser",Msg::kInfo) <<"Dropping LI summary with "<<
00221 psl->GetTriggers()<<" pulses: Pulser is off!"<<endl;
00222 break;
00223 case 1:
00224
00225
00226 MSG("Pulser",Msg::kInfo) <<"Doug Point: not written"<<endl;
00227
00228 break;
00229 default:
00230
00231 MSG("Pulser",Msg::kInfo) <<"GainCurve"<<endl;
00232 GainCurve(psl);
00233 break;
00234 };
00235 delete psl;
00236 }
00237
00238 TFolder *lf = dynamic_cast<TFolder *>
00239 (gROOT->GetRootFolder()->FindObject("Loon"));
00240 if (lf) {
00241 TObject *obj = lf->FindObject("Pulser");
00242 if (obj){
00243 lf->Remove(obj);
00244 MSG("Pulser",Msg::kDebug) << "PulserDBModule::EndRun(): directory Pulser removed"<<endl;
00245 }
00246 }
00247
00248
00249 }
00250
00251 void PulserDBModule::EndJob()
00252 {
00253 MSG("Pulser",Msg::kDebug) << "PulserDBModule::EndJob()\n";
00254 EndRun();
00255 }
00256
00257 void PulserDBModule::BeginFile()
00258 {
00259 fFileStart = true;
00260 MSG("Pulser",Msg::kDebug) << "PulserDBModule::BeginFile()\n";
00261 }
00262
00263 void PulserDBModule::EndFile()
00264 {
00265 MSG("Pulser",Msg::kInfo) << "PulserDBModule::EndFile()\n";
00266 }
00267
00268 void PulserDBModule::DriftPoint(PulserSummaryList *psl)
00269 {
00270 fCurrentContext = psl->GetVldContext();
00271 VldTimeStamp start = fCurrentContext.GetTimeStamp();
00272 VldTimeStamp end = start;
00273 end.Add(VldTimeStamp(fDPValid,0));
00274 VldRange vr(fCurrentContext.GetDetector(),fCurrentContext.GetSimFlag(),start,
00275 end, "PulserDBModule");
00276 VldTimeStamp create = start;
00277 create.Add(VldTimeStamp(fCodeVersion,0));
00278 int aggNo = psl->GetAggregateNo();
00279
00280
00281 DbiWriter<PulserDrift> writer(vr,aggNo,Pulser::kNearEnd);
00282 MSG("Pulser",Msg::kDebug)<<"Writing database "<<fCurrentContext<<endl;
00283 for (std::map<Int_t,PulserSummary>::const_iterator it=psl->GetNearBegin();
00284 it!=psl->GetNearEnd(); it++) {
00285 const PulserSummary &ps = (*it).second;
00286 PulserDrift pd(psl->GetAggregateNo(),ps);
00287 writer<<pd;
00288 }
00289
00290
00291 DbiWriter<PulserDrift> fwriter(vr,aggNo,Pulser::kFarEnd);
00292 for (std::map<Int_t,PulserSummary>::const_iterator it=psl->GetFarBegin();
00293 it!=psl->GetFarEnd(); it++) {
00294 const PulserSummary &ps = (*it).second;
00295 PulserDrift pd(psl->GetAggregateNo(),ps);
00296 fwriter<<pd;
00297 }
00298
00299
00300 DbiWriter<PulserDriftPin> pwriter(vr,aggNo,Pulser::kNearEnd);
00301 PulserDriftPin pdp(psl->GetAggregateNo(),psl->GetHighPin());
00302 PulserDriftPin pdpl(psl->GetAggregateNo(),psl->GetLowPin());
00303 pwriter << pdp << pdpl;
00304
00305 pwriter.Close();
00306 fwriter.Close();
00307 writer.Close();
00308 }
00309
00310
00311
00312 void PulserDBModule::GainCurve(PulserSummaryList *psl)
00313 {
00314 fCurrentContext = psl->GetVldContext();
00315 if (AddToGC(psl)) {
00316
00317
00318 MSG("Pulser",Msg::kDebug)<<"Added point to GC\n";
00319 }
00320 else {
00321 if (!fFileStart) {
00322
00323
00324
00325
00326
00327
00328
00329
00330 MSG("Pulser",Msg::kError) <<"New point does not match existing gaincurve\n";
00331 MSG("Pulser",Msg::kError) <<"Dropping existing GC and trying to carry on\n";
00332 MSG("Pulser",Msg::kError) <<"Please report this error to the experts now\n";
00333 DropGC();
00334 AddToGC(psl);
00335 }
00336 if (fFileStart) {
00337
00338
00339
00340
00341 DropGC();
00342 AddToGC(psl);
00343 }
00344 }
00345 fFileStart = false;
00346 fRunStart = false;
00347
00348
00349
00350
00351
00352
00353
00354 MergeBack();
00355 if (fGainLog->IsComplete()) {
00356 WriteGC();
00357 DropGC();
00358 }
00359
00360 }
00361
00362
00363 bool PulserDBModule::MergeBack()
00364 {
00365 if (fGainLog->GetFirstPoint()==1) return false;
00366
00367
00368 VldTimeStamp ts = fGainLog->GetTimeStart();
00369 ts.Add(VldTimeStamp(-2,0));
00370 VldContext vld(fCurrentContext.GetDetector(),
00371 fCurrentContext.GetSimFlag(),ts);
00372 DbiResultPtr<PulserGainLog> pglrp(vld,Pulser::kTempData);
00373
00374 if (pglrp.GetNumRows()==0) return false;
00375
00376 const PulserGainLog *pgl = pglrp.GetRow(0);
00377 if (fGainLog->Add(*pgl)) {
00378
00379 DbiResultPtr<PulserGain> nearend(vld,Pulser::kNearEnd | Pulser::kTempData);
00380 if (nearend.GetNumRows()==0) {
00381 MSG("Pulser",Msg::kFatal)<< "Database Integrity Error."<<endl;
00382 MSG("Pulser",Msg::kFatal)<< "Near End Gain doesn't match GainLog"<<endl;
00383 return false;
00384 }
00385 for (std::map<Int_t,PulserGain>::iterator it = fGainMapNear.begin();
00386 it !=fGainMapNear.end(); it++) {
00387 PulserGain &pg = (*it).second;
00388 const PulserGain * otherpg = nearend.GetRowByIndex(pg.GetStripEnd());
00389 if (!pg.Add(*otherpg)) {
00390
00391 MSG("Pulser",Msg::kFatal)<<"Could add GainLog but not Gain for stripend with key "<<pg.GetStripEnd()<<endl;
00392 assert(0);
00393 }
00394 }
00395
00396 DbiResultPtr<PulserGain> farend(vld,Pulser::kFarEnd | Pulser::kTempData);
00397 if (vld.GetDetector()==Detector::kFar){
00398 if (farend.GetNumRows()==0) {
00399 MSG("Pulser",Msg::kFatal)<< "Database Integrity Error."<<endl;
00400 MSG("Pulser",Msg::kFatal)<< "Far End Gain doesn't match GainLog"<<endl;
00401 return false;
00402 }
00403 for (std::map<Int_t,PulserGain>::iterator it = fGainMapFar.begin();
00404 it !=fGainMapFar.end(); it++) {
00405 PulserGain &pg = (*it).second;
00406 const PulserGain * otherpg = farend.GetRowByIndex(pg.GetStripEnd());
00407 if (!pg.Add(*otherpg)) {
00408
00409 MSG("Pulser",Msg::kFatal)<<"Could add GainLog but not Gain for Far stripend with key "<<pg.GetStripEnd()<<endl;
00410 assert(0);
00411 }
00412 }
00413 }
00414
00415 DbiResultPtr<PulserGainPin> pins(vld,Pulser::kNearEnd | Pulser::kTempData);
00416 if (pins.GetNumRows()==0) {
00417 MSG("Pulser",Msg::kFatal)<< "Database Integrity Error."<<endl;
00418 MSG("Pulser",Msg::kFatal)<< "Pin Gain doesn't match GainLog"<<endl;
00419 return false;
00420 }
00421 const PulserGainPin * otherpin[2];
00422 for (int k=0;k<2;k++) {
00423 otherpin[k] = pins.GetRowByIndex(fGainPin[k]->GetIndex(0));
00424 if (!(fGainPin[k]->Add(*otherpin[k]))) {
00425 MSG("Pulser",Msg::kFatal)<<"Could add GainLog but not Gain for Pin "<<fGainPin[k]->GetIndex(0)<<endl;
00426 assert(0);
00427 }
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 if (WriteTempGC()) {
00441 DeleteGC(&nearend);
00442 if (vld.GetDetector()==Detector::kFar) DeleteGC(&farend);
00443 DeleteGC(&pins);
00444 DeleteGC(&pglrp);
00445 }
00446 else {
00447 MSG("Pulser",Msg::kError)<< "Failed to delete old bits of gaincurve from temp DB.\n";
00448 return false;
00449 }
00450
00451
00452 }
00453 else return false;
00454
00455 return MergeBack();
00456 }
00457
00458 bool PulserDBModule::MergeForward()
00459 {
00460 if (fGainLog->GetLastPoint()==fGainLog->GetNumPoints()) return false;
00461
00462
00463 VldTimeStamp ts = fGainLog->GetTimeEnd();
00464 VldContext vld(fCurrentContext.GetDetector(),
00465 fCurrentContext.GetSimFlag(),ts);
00466 DbiResultPtr<PulserGainLog> pglrp(vld,Pulser::kTempData);
00467
00468
00469 pglrp.NextQuery();
00470
00471
00472 if (pglrp.GetNumRows()==0) return false;
00473
00474 const PulserGainLog *pgl = pglrp.GetRow(0);
00475 if (fGainLog->Add(*pgl)) {
00476
00477 }
00478 else return false;
00479
00480 return MergeForward();
00481 }
00482
00483
00484
00485
00486 void PulserDBModule::DropGC()
00487 {
00488
00489 fGainMapNear.clear();
00490 fGainMapFar.clear();
00491 delete fGainPin[0];
00492 delete fGainPin[1];
00493 delete fGainLog;
00494 fGainPin[0]=0;
00495 fGainPin[1]=0;
00496 fGainLog=0;
00497 }
00498
00499 bool PulserDBModule::WriteGC()
00500 {
00501 return DoWriteGC(Pulser::kRealData);
00502 }
00503
00504
00505 bool PulserDBModule::WriteTempGC()
00506 {
00507 VldTimeStamp ts = fGainLog->GetTimeStart();
00508 VldContext vld(fCurrentContext.GetDetector(),
00509 fCurrentContext.GetSimFlag(),ts);
00510 DbiResultPtr<PulserGain> near;
00511 DbiResultPtr<PulserGain> far;
00512 DbiResultPtr<PulserGainPin> pins;
00513 DbiResultPtr<PulserGainLog> gainlog;
00514
00515 bool del_n = GetCurrentFromDB(near,vld,Pulser::kNearEnd | Pulser::kTempData);
00516 bool del_f = GetCurrentFromDB(far,vld,Pulser::kFarEnd | Pulser::kTempData);
00517 bool del_p = GetCurrentFromDB(pins,vld,Pulser::kNearEnd | Pulser::kTempData);
00518 bool del_g = GetCurrentFromDB(gainlog,vld,Pulser::kNearEnd | Pulser::kTempData);
00519
00520 bool result = DoWriteGC(Pulser::kTempData);
00521
00522
00523 if (result && gainlog.GetValidityRec()->GetVldRange().GetTimeStart()==fGainLog->GetTimeStart()) {
00524
00525
00526 if (del_n) result &=DeleteGC(&near);
00527 if (del_f) result &=DeleteGC(&far);
00528 if (del_p) result &=DeleteGC(&pins);
00529 if (del_g) result &=DeleteGC(&gainlog);
00530 }
00531 return result;
00532 }
00533
00534 bool PulserDBModule::DoWriteGC(int temp)
00535 {
00536 VldTimeStamp start = fGainLog->GetTimeStart();
00537 VldTimeStamp end = start;
00538 end.Add(VldTimeStamp(fGCValid,0));
00539 VldRange vr(fCurrentContext.GetDetector(),fCurrentContext.GetSimFlag(),start,
00540 end, "PulserDBModule");
00541 VldTimeStamp create = start;
00542 create.Add(VldTimeStamp(fCodeVersion,0));
00543
00544 int aggNo = fGainLog->GetAggregateNo();
00545 MSG("Pulser",Msg::kDebug)<<"In DoWriteGC. Aggregate Number: "<<aggNo<<endl;
00546
00547
00548
00549 DbiWriter<PulserGainLog> logwriter(vr,aggNo,temp);
00550 if (temp & Pulser::kTempData) logwriter.SetDbName("litemp");
00551 MSG("Pulser",Msg::kDebug)<<"Writing database "<<fCurrentContext
00552 <<" gaincurve starts at "<<start<<endl;
00553 logwriter << *fGainLog;
00554
00555
00556 DbiWriter<PulserGain> writer(vr,aggNo,Pulser::kNearEnd | temp);
00557 if (temp & Pulser::kTempData) writer.SetDbName("litemp");
00558 for (std::map<Int_t,PulserGain>::iterator it = fGainMapNear.begin();
00559 it !=fGainMapNear.end(); it++) {
00560 PulserGain &pg = (*it).second;
00561 writer << pg;
00562 }
00563
00564
00565
00566 DbiWriter<PulserGain> fwriter(vr,aggNo,Pulser::kFarEnd | temp);
00567 if (temp & Pulser::kTempData) fwriter.SetDbName("litemp");
00568 for (std::map<Int_t,PulserGain>::iterator it = fGainMapFar.begin();
00569 it !=fGainMapFar.end(); it++) {
00570 PulserGain &pg = (*it).second;
00571 fwriter << pg;
00572 }
00573
00574
00575
00576 DbiWriter<PulserGainPin> pwriter(vr,aggNo,Pulser::kNearEnd | temp);
00577 if (temp & Pulser::kTempData) pwriter.SetDbName("litemp");
00578 pwriter << *(fGainPin[0]) << *(fGainPin[1]);
00579
00580 bool result=true;
00581 logwriter.TableProxy().GetCache()->SetStale();
00582 pwriter.TableProxy().GetCache()->SetStale();
00583 fwriter.TableProxy().GetCache()->SetStale();
00584 writer.TableProxy().GetCache()->SetStale();
00585
00586 result &=logwriter.Close();
00587 result &=pwriter.Close();
00588 result &=fwriter.Close();
00589 result &=writer.Close();
00590 return result;
00591
00592
00593
00594 }
00595
00596 bool PulserDBModule::AddToGC(PulserSummaryList *psl)
00597 {
00598
00599
00600
00601
00602 if (!fGainLog) {
00603
00604
00605
00606 fGainLog = new PulserGainLog(fCodeVersion);
00607 fGainPin[0] = new PulserGainPin();
00608 fGainPin[1] = new PulserGainPin();
00609 }
00610 if (fGainLog->Add(psl)) {
00611
00612 MSG("Pulser",Msg::kDebug)<<"In AddToGC (1). GetAggregateNo: " << ", " << fGainLog->GetAggregateNo() << endl;
00613
00614
00615
00616 bool result=true;
00617 result &= fGainPin[0]->AddPoint(psl->GetPointIndex(),psl->GetHighPin(),psl->GetAggregateNo(),psl->GetExpectedPoints());
00618 result &= fGainPin[1]->AddPoint(psl->GetPointIndex(),psl->GetLowPin(),psl->GetAggregateNo(),psl->GetExpectedPoints());
00619 for (std::map<Int_t,PulserSummary>::const_iterator it = psl->GetNearBegin(); it!=psl->GetNearEnd() ; it++) {
00620
00621 result &= fGainMapNear[(*it).first].AddPoint(psl->GetPointIndex(),(*it).second,psl->GetAggregateNo(),psl->GetExpectedPoints());
00622 }
00623 for (std::map<Int_t,PulserSummary>::const_iterator it = psl->GetFarBegin();
00624 it!=psl->GetFarEnd() ; it++) {
00625
00626 result &= fGainMapFar[(*it).first].AddPoint(psl->GetPointIndex(),(*it).second,psl->GetAggregateNo(),psl->GetExpectedPoints());
00627 }
00628 if (!result) {
00629 MSG("Pulser",Msg::kFatal)<<"Internal inconsistency. This can't happen.\n";
00630 assert(0);
00631 }
00632
00633 MSG("Pulser",Msg::kDebug)<<"In AddToGC. Aggregate Number(psl): " << psl->GetAggregateNo() << endl;
00634
00635 MSG("Pulser",Msg::kDebug)<<"In AddToGC. Aggregate Number(log): " << fGainLog->GetAggregateNo() << endl;
00636
00637 return result;
00638 }
00639 return false;
00640 }
00641
00642 template <class T>
00643 bool PulserDBModule::DeleteGC(DbiResultPtr<T> *p)
00644 {
00645 const DbiValidityRec *vrec = p->GetValidityRec();
00646 int seqno = vrec->GetSeqNo();
00647 int dbno = vrec->GetDbNo();
00648
00649 DbiTableProxy &t = p->TableProxy();
00650 const DbiDBProxy &dbproxy = t.GetDBProxy();
00651
00652
00653 bool result = dbproxy.RemoveSeqNo(seqno,dbno);
00654 t.GetCache()->SetStale();
00655 return result;
00656 }
00657
00658
00659 template <class T>
00660 bool PulserDBModule::GetCurrentFromDB(DbiResultPtr<T> & rp, VldContext &vld,int task)
00661 {
00662 rp.NewQuery(vld,task);
00663 if (rp.GetNumRows()==0) return false;
00664
00665 const T* obj = rp.GetRow(0);
00666 if (obj->GetFirstPoint()!=fGainLog->GetFirstPoint()) return false;
00667
00668 return true;
00669
00670 }