00001 #include "AdReadoutFigs.h"
00002
00003 #include "StatisticsSvc/IStatisticsSvc.h"
00004 #include "Event/ReadoutHeader.h"
00005 #include "Event/DaqPmtCrate.h"
00006 #include "Event/DaqPmtChannel.h"
00007 #include "Conventions/Electronics.h"
00008
00009 #include "TH2.h"
00010 #include "TMath.h"
00011 #include "TList.h"
00012
00013 #include <sstream>
00014
00015
00016 char timeFormat[] = "#splitline{%H:%M:%S}{%b %d %Y}";
00017
00018
00019
00020
00021
00022
00023 AdReadoutFigs::AdReadoutFigs(const std::string& name,
00024 ISvcLocator* pSvcLocator)
00025 : GaudiAlgorithm(name,pSvcLocator),
00026 m_statsSvc(0),
00027 m_firstTriggerTime(0)
00028 {
00029 }
00030
00031 AdReadoutFigs::~AdReadoutFigs()
00032 {
00033 }
00034
00035 StatusCode AdReadoutFigs::initialize()
00036 {
00037
00038 StatusCode sc = this->service("StatisticsSvc",m_statsSvc,true);
00039 if(sc.isFailure()){
00040 error() << "Failed to get StatisticsSvc" << endreq;
00041 return sc;
00042 }
00043 return sc;
00044 }
00045
00046 StatusCode AdReadoutFigs::execute()
00047 {
00048
00049 DayaBay::ReadoutHeader* readoutHeader =
00050 get<DayaBay::ReadoutHeader>("/Event/Readout/ReadoutHeader");
00051 if(!readoutHeader){
00052 error() << "Failed to get readout header." << endreq;
00053 return StatusCode::FAILURE;
00054 }
00055
00056 const DayaBay::DaqCrate* daqCrate = readoutHeader->daqCrate();
00057 if(!daqCrate){
00058 error() << "Failed to get DAQ crate from header" << endreq;
00059 return StatusCode::FAILURE;
00060 }
00061
00062
00063 const DayaBay::DaqPmtCrate* pmtCrate
00064 = daqCrate->asPmtCrate();
00065 if(!pmtCrate){
00066
00067 return StatusCode::SUCCESS;
00068 }
00069
00070 if(!m_firstTriggerTime){
00071 m_firstTriggerTime = new TimeStamp(pmtCrate->triggerTime());
00072 }
00073
00074
00075 int runNumber = pmtCrate->runNumber();
00076 const DayaBay::Detector& detector = pmtCrate->detector();
00077 TH1F* triggerRate = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00078 detector,
00079 0, 0, TRIGGERRATE));
00080 TH1F* dtTrigger = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00081 detector,
00082 0, 0, DTTRIGGER));
00083 TH1F* logDtTrigger = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00084 detector,
00085 0, 0,
00086 LOGDTTRIGGER));
00087 TH1F* nChannels = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00088 detector,
00089 0, 0,
00090 NCHANNELS));
00091 TH2F* nChannelsVsTime = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00092 detector,
00093 0, 0,
00094 NCHANNELSVSTIME));
00095 TH2F* channelHits = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00096 detector,
00097 0, 0,
00098 CHANNELHITS));
00099 TH2F* channelDadcFine = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00100 detector,
00101 0, 0,
00102 CHANNELDADCFINE));
00103 TH2F* channelDadcCoarse = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00104 detector,
00105 0, 0,
00106 CHANNELDADCCOARSE));
00107 TH2F* tdcVsBoard = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00108 detector,
00109 0, 0,
00110 TDCVSBOARD));
00111
00112 if(pmtCrate->triggerTime().GetSeconds()-triggerRate->GetXaxis()->GetXmax() > 1800)
00113 {
00114
00115 error() << "An invalid gap of "
00116 << pmtCrate->triggerTime().GetSeconds()-triggerRate->GetXaxis()->GetXmax()
00117 << " seconds has been found in the data. Bailing..." << endreq;
00118 return StatusCode::FAILURE;
00119 }
00120
00121 while(pmtCrate->triggerTime().GetSeconds() >
00122 triggerRate->GetXaxis()->GetXmax()){
00123 this->extendRange(triggerRate, 60);
00124 }
00125 while(pmtCrate->triggerTime().GetSeconds() >
00126 nChannelsVsTime->GetXaxis()->GetXmax()){
00127 this->extendRange(nChannelsVsTime, 60);
00128 }
00129
00130 const DayaBay::DaqPmtCrate::PmtChannelPtrList& channels
00131 = pmtCrate->channelReadouts();
00132
00133 DayaBay::DaqPmtCrate::PmtChannelPtrList::const_iterator channelIter,
00134 channelEnd = channels.end();
00135
00136 triggerRate->Fill(pmtCrate->triggerTime().GetSeconds());
00137 nChannelsVsTime->Fill(pmtCrate->triggerTime().GetSeconds(), channels.size() );
00138
00139 if(m_lastTriggerTime.find(pmtCrate->detector()) != m_lastTriggerTime.end()){
00140 TimeStamp dtTriggerTime = pmtCrate->triggerTime();
00141 dtTriggerTime.Subtract(m_lastTriggerTime[pmtCrate->detector()]);
00142 dtTrigger->Fill(dtTriggerTime.GetSeconds());
00143 logDtTrigger->Fill(TMath::Log10(dtTriggerTime.GetSeconds()));
00144 }
00145
00146 nChannels->Fill( channels.size() );
00147
00148 for(channelIter = channels.begin(); channelIter!=channelEnd; channelIter++) {
00149 const DayaBay::DaqPmtChannel& channel = *(*channelIter);
00150
00151 int board = channel.channelId().board();
00152 int connector = channel.channelId().connector();
00153 TH1F* tdc = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00154 detector,
00155 board, connector,
00156 TDC));
00157 TH1F* adcFine = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00158 detector,
00159 board, connector,
00160 ADCFINE));
00161 TH1F* adcCoarse = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00162 detector,
00163 board, connector,
00164 ADCCOARSE));
00165 TH2F* dadcVsTimeFine = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00166 detector,
00167 board,
00168 connector,
00169 DADCVSTIMEFINE));
00170 TH2F* dadcVsPedFine = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00171 detector,
00172 board,
00173 connector,
00174 DADCVSPEDFINE));
00175 TH2F* dadcFineVsTdc = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00176 detector,
00177 board,
00178 connector,
00179 DADCFINEVSTDC));
00180 TH2F* pedFineVsTdc = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00181 detector,
00182 board,
00183 connector,
00184 PEDFINEVSTDC));
00185 while(pmtCrate->triggerTime().GetSeconds() >
00186 dadcVsTimeFine->GetXaxis()->GetXmax()){
00187 this->extendRange(dadcVsTimeFine, 60);
00188 }
00189
00190
00191 channelHits->Fill(board, connector);
00192
00193
00194 if(channel.hitCount()>0){
00195 if(channel.isHighGainAdc(0)){
00196 channelDadcFine->Fill(board, connector,
00197 channel.deltaAdc(0));
00198 channelDadcFine->SetNormFactor( channelDadcFine->GetNormFactor()+1 );
00199 }else{
00200 channelDadcCoarse->Fill(board, connector,
00201 channel.deltaAdc(0));
00202 channelDadcCoarse->SetNormFactor(channelDadcCoarse->GetNormFactor()+1);
00203 }
00204 }
00205
00206 for(unsigned int hitIdx=0; hitIdx<channel.hitCount(); hitIdx++){
00207 double epsilon = 0.01;
00208 tdcVsBoard->Fill(board + connector/double(NCONNECTORS) + epsilon,
00209 channel.tdc(hitIdx));
00210 tdc->Fill(channel.tdc(hitIdx));
00211 float deltaAdc = channel.deltaAdc(hitIdx);
00212 if(channel.isHighGainAdc(hitIdx)){
00213 adcFine->Fill(channel.adc(hitIdx));
00214 if(dadcVsTimeFine->GetYaxis()->GetXmin()<deltaAdc
00215 && dadcVsTimeFine->GetYaxis()->GetXmax()>deltaAdc){
00216 dadcVsTimeFine->Fill(pmtCrate->triggerTime().GetSeconds(), deltaAdc);
00217 }
00218 dadcVsPedFine->Fill(channel.preAdcAvg(hitIdx), deltaAdc);
00219 dadcFineVsTdc->Fill(channel.tdc(hitIdx), deltaAdc);
00220 pedFineVsTdc->Fill(channel.tdc(hitIdx), channel.preAdcAvg(hitIdx));
00221 }else{
00222 adcCoarse->Fill(channel.adc(hitIdx));
00223 }
00224 }
00225 }
00226
00227 channelHits->SetNormFactor( channelHits->GetNormFactor()+1 );
00228
00229 m_lastTriggerTime[pmtCrate->detector()] = pmtCrate->triggerTime();
00230
00231 return StatusCode::SUCCESS;
00232 }
00233
00234 StatusCode AdReadoutFigs::finalize()
00235 {
00236
00237 for(unsigned int normIdx=0; normIdx<m_normalize.size(); normIdx++){
00238 TH1* hist = m_normalize[normIdx];
00239 hist->Sumw2();
00240 if(hist->GetNormFactor()>0){
00241 double scale = 1./hist->GetNormFactor();
00242 hist->SetNormFactor(1);
00243 hist->Scale( scale );
00244 }
00245 hist->SetBit(TH1::kIsAverage);
00246 }
00247 m_normalize.clear();
00248
00249 std::map<int,TH1**>::iterator histIter, histEnd = m_shortCuts.end();
00250 for(histIter = m_shortCuts.begin(); histIter!=histEnd; histIter++){
00251 delete [] (histIter->second);
00252 histIter->second = 0;
00253 }
00254 if( m_statsSvc ) m_statsSvc->release();
00255 if(m_firstTriggerTime){
00256 delete m_firstTriggerTime;
00257 m_firstTriggerTime = 0;
00258 }
00259 return StatusCode::SUCCESS;
00260 }
00261
00263
00264 TH1* AdReadoutFigs::getOrMakeHist(int run, const DayaBay::Detector& detector,
00265 int board, int connector, int histogram)
00266 {
00267 int siteInt = 0;
00268 switch(detector.site()){
00269 case Site::kUnknown:
00270 siteInt = 0; break;
00271 case Site::kDayaBay:
00272 siteInt = 1; break;
00273 case Site::kLingAo:
00274 siteInt = 2; break;
00275 case Site::kFar:
00276 siteInt = 3; break;
00277 case Site::kSAB:
00278 siteInt = 4; break;
00279 default:
00280 error() << "Unknown site: " << detector.detName() << endreq;
00281 return 0;
00282 }
00283 int detectorInt = int(detector.detectorId());
00284 std::map<int,TH1**>::iterator histIter = m_shortCuts.find(run);
00285 TH1** histograms = 0;
00286 if( histIter == m_shortCuts.end() ){
00287
00288 histograms = new TH1*[MAXHISTS];
00289 for(int i=0; i<MAXHISTS; i++) histograms[i] = 0;
00290 m_shortCuts[run] = histograms;
00291 }else{
00292
00293 histograms = histIter->second;
00294 }
00295
00296 TH1* hist =
00297 histograms[siteInt * NDETECTORS * NBOARDS * NCONNECTORS * NHISTOGRAMS
00298 + detectorInt * NBOARDS * NCONNECTORS * NHISTOGRAMS
00299 + board * NCONNECTORS * NHISTOGRAMS
00300 + connector * NHISTOGRAMS
00301 + histogram];
00302 if(!hist){
00303
00304 std::string histName;
00305 if(detector.detectorId()){
00306 if(board){
00307
00308 switch(histogram){
00309 case TDC:
00310
00311 histName = "tdc";
00312 hist = new TH1F(histName.c_str(),
00313 "TDC",
00314 1000,300,1300);
00315 hist->GetXaxis()->SetTitle("TDC");
00316 hist->GetYaxis()->SetTitle("Entries");
00317 break;
00318 case ADCFINE:
00319
00320 histName = "adcFine";
00321 hist = new TH1F(histName.c_str(),
00322 "ADC (Fine Range)",
00323 4096,0,4096);
00324 hist->GetXaxis()->SetTitle("ADC");
00325 hist->GetYaxis()->SetTitle("Entries");
00326 break;
00327 case ADCCOARSE:
00328
00329 histName = "adcCoarse";
00330 hist = new TH1F(histName.c_str(),
00331 "ADC (Coarse Range)",
00332 4096,0,4096);
00333 hist->GetXaxis()->SetTitle("ADC");
00334 hist->GetYaxis()->SetTitle("Entries");
00335 break;
00336 case DADCVSTIMEFINE:
00337
00338 histName = "dadcVsTimeFine";
00339 hist = new TH2F(histName.c_str(),
00340 "#DeltaADC vs Time (Fine Range)",
00341 60,m_firstTriggerTime->GetSec(),
00342 m_firstTriggerTime->GetSec()+60,
00343 200,-100,100);
00344 hist->GetXaxis()->SetTitle("Run Time");
00345 hist->GetYaxis()->SetTitle("#DeltaADC");
00346 hist->GetXaxis()->SetTimeDisplay(1);
00347 hist->GetXaxis()->SetTimeFormat(timeFormat);
00348 hist->GetXaxis()->SetTimeOffset(0,"gmt");
00349 hist->GetXaxis()->SetNdivisions(505);
00350 break;
00351 case DADCVSPEDFINE:
00352
00353 histName = "dadcVsPedFine";
00354 hist = new TH2F(histName.c_str(),
00355 "#DeltaADC vs. PreADC (Fine Range)",
00356 200,0,200,200,-100,100);
00357 hist->GetXaxis()->SetTitle("PreADC");
00358 hist->GetYaxis()->SetTitle("#DeltaADC");
00359 break;
00360 case DADCFINEVSTDC:
00361
00362 histName = "dadcFineVsTdc";
00363 hist = new TH2F(histName.c_str(),
00364 "#DeltaADC vs. TDC (Fine Range)",
00365 100,300,1300,200,-100,100);
00366 hist->GetXaxis()->SetTitle("TDC");
00367 hist->GetYaxis()->SetTitle("#DeltaADC");
00368 break;
00369 case PEDFINEVSTDC:
00370
00371 histName = "pedFineVsTdc";
00372 hist = new TH2F(histName.c_str(),
00373 "PreADC vs. TDC (Fine Range)",
00374 100,300,1300,200,0,200);
00375 hist->GetXaxis()->SetTitle("TDC");
00376 hist->GetYaxis()->SetTitle("PreADC");
00377 break;
00378 default:
00379 error() << "Unknown Histogram: " << histogram << endreq;
00380 return 0;
00381 }
00382 }else{
00383
00384 switch(histogram){
00385 case TRIGGERRATE:
00386
00387 histName = "triggerRate";
00388 hist = new TH1F(histName.c_str(),"Trigger Rate",
00389 60,m_firstTriggerTime->GetSec(),
00390 m_firstTriggerTime->GetSec()+60);
00391 hist->GetXaxis()->SetTitle("Run Time");
00392 hist->GetYaxis()->SetTitle("Rate [Hz]");
00393 hist->GetXaxis()->SetTimeDisplay(1);
00394 hist->GetXaxis()->SetTimeFormat(timeFormat);
00395 hist->GetXaxis()->SetTimeOffset(0,"gmt");
00396 hist->GetXaxis()->SetNdivisions(505);
00397 break;
00398 case DTTRIGGER:
00399
00400 histName = "dtTrigger";
00401 hist = new TH1F(histName.c_str(),"Time Between Triggers",
00402 1000,0,0.015);
00403 hist->GetXaxis()->SetTitle("#Deltat [s]");
00404 break;
00405 case LOGDTTRIGGER:
00406
00407 histName = "logDtTrigger";
00408 hist = new TH1F(histName.c_str(),"Time Between Triggers",
00409 900,-8,1);
00410 hist->GetXaxis()->SetTitle("log_{10}(#Deltat / 1s)");
00411 break;
00412 case NCHANNELS:
00413
00414 histName = "nChannels";
00415 hist = new TH1F(histName.c_str(),
00416 "Number of Channels in Event",200,0,200);
00417 hist->GetXaxis()->SetTitle("Number of Channels");
00418 break;
00419 case NCHANNELSVSTIME:
00420
00421 histName = "nChannelsVsTime";
00422 hist = new TH2F(histName.c_str(),
00423 "Number of Channels in Event vs. Time",
00424 60,m_firstTriggerTime->GetSec(),
00425 m_firstTriggerTime->GetSec()+60,200,0,200);
00426 hist->GetXaxis()->SetTitle("Run Time");
00427 hist->GetYaxis()->SetTitle("Number of Channels");
00428 hist->GetXaxis()->SetTimeDisplay(1);
00429 hist->GetXaxis()->SetTimeFormat(timeFormat);
00430 hist->GetXaxis()->SetTimeOffset(0,"gmt");
00431 hist->GetXaxis()->SetNdivisions(505);
00432 break;
00433 case CHANNELHITS:
00434
00435 histName = "channelHits";
00436 hist = new TH2F(histName.c_str(),"Occupancy of FEE Channels",
00437 20,0.5,20.5,16,0.5,16.5);
00438 hist->GetXaxis()->SetTitle("FEE Board");
00439 hist->GetYaxis()->SetTitle("FEE Connector");
00440 m_normalize.push_back(hist);
00441 hist->SetNormFactor(0);
00442 hist->SetStats(0);
00443 break;
00444 case CHANNELDADCFINE:
00445
00446 histName = "channelDadcFine";
00447 hist = new TH2F(histName.c_str(),
00448 "Mean Fine #DeltaADC on FEE Channels",
00449 20,0.5,20.5,16,0.5,16.5);
00450 hist->GetXaxis()->SetTitle("FEE Board");
00451 hist->GetYaxis()->SetTitle("FEE Connector");
00452 m_normalize.push_back(hist);
00453 hist->SetNormFactor(0);
00454 hist->SetStats(0);
00455 break;
00456 case CHANNELDADCCOARSE:
00457
00458 histName = "channelDadcCoarse";
00459 hist = new TH2F(histName.c_str(),
00460 "Mean Coarse #DeltaADC on FEE Channels",
00461 20,0.5,20.5,16,0.5,16.5);
00462 hist->GetXaxis()->SetTitle("FEE Board");
00463 hist->GetYaxis()->SetTitle("FEE Connector");
00464 m_normalize.push_back(hist);
00465 hist->SetNormFactor(0);
00466 hist->SetStats(0);
00467 break;
00468 case TDCVSBOARD:
00469
00470 histName = "tdcVsBoard";
00471 hist = new TH2F(histName.c_str(),
00472 "TDC vs. Board",
00473 NBOARDS*NCONNECTORS,0,NBOARDS,1000,300,1300);
00474 hist->GetXaxis()->SetTitle("FEE Board");
00475 hist->GetYaxis()->SetTitle("TDC");
00476 break;
00477 default:
00478 error() << "Unknown Histogram: " << histogram << endreq;
00479 return 0;
00480 }
00481 }
00482 }
00483 debug() << "Making histogram: " << histName << endreq;
00484 m_statsSvc->put( this->getPath(run, detector.detName().c_str(), board,
00485 connector, histName.c_str()),
00486 hist );
00487 histograms[siteInt * NDETECTORS * NBOARDS * NCONNECTORS * NHISTOGRAMS
00488 + detectorInt * NBOARDS * NCONNECTORS * NHISTOGRAMS
00489 + board * NCONNECTORS * NHISTOGRAMS
00490 + connector * NHISTOGRAMS
00491 + histogram] = hist;
00492 }
00493
00494 return hist;
00495 }
00496
00497 std::string AdReadoutFigs::getPath(int run, const char* detectorName,
00498 int board, int connector,
00499 const char* histName)
00500 {
00501
00502 std::stringstream path;
00503 path << "/file1/diagnostics/run_" << std::setfill('0') << std::setw(7)
00504 << run;
00505 if(detectorName){
00506 path << "/detector_" << detectorName;
00507 if(board){
00508 path << "/channel_board" << std::setfill('0') << std::setw(2)
00509 << board << "_connector" << std::setfill('0') << std::setw(2)
00510 << connector;
00511 }
00512 }
00513 path << "/" << histName;
00514 return path.str();
00515 }
00516
00517 void AdReadoutFigs::extendRange(TH1* hist, int xBinsAdd, int yBinsAdd)
00518 {
00519
00520
00521 info() << "Extending histogram range: " << hist->GetName() << endreq;
00522 TH1* extension = 0;
00523 if(hist->IsA() == TH2F::Class()){
00524 extension = new TH2F("","",
00525 xBinsAdd + hist->GetNbinsX(),
00526 hist->GetXaxis()->GetXmin(),
00527 hist->GetXaxis()->GetXmax()
00528 + xBinsAdd*hist->GetXaxis()->GetBinWidth(0),
00529 yBinsAdd + hist->GetNbinsY(),
00530 hist->GetYaxis()->GetXmin(),
00531 hist->GetYaxis()->GetXmax()
00532 + yBinsAdd*hist->GetYaxis()->GetBinWidth(0));
00533 }else if(hist->IsA() == TH1F::Class()){
00534 extension = new TH1F("","",
00535 xBinsAdd + hist->GetNbinsX(),
00536 hist->GetXaxis()->GetXmin(),
00537 hist->GetXaxis()->GetXmax()
00538 + xBinsAdd*hist->GetXaxis()->GetBinWidth(0));
00539 }else{
00540 error() << "Cannot extend range of type: " << hist->ClassName() << endreq;
00541 return;
00542 }
00543 TList list;
00544 list.Add(extension);
00545 hist->Merge(&list);
00546 delete extension;
00547 return;
00548 }