00001 #include "AdCalibFigs.h"
00002
00003 #include "StatisticsSvc/IStatisticsSvc.h"
00004 #include "Event/ReadoutHeader.h"
00005 #include "Event/CalibReadoutHeader.h"
00006 #include "Event/CalibReadoutPmtCrate.h"
00007 #include "Event/CalibReadoutPmtChannel.h"
00008 #include "Conventions/Electronics.h"
00009
00010 #include "TH2.h"
00011 #include "TMath.h"
00012 #include "TList.h"
00013
00014 #include <sstream>
00015
00016 char timeFormat_AdCalibFigs[] = "#splitline{%H:%M:%S}{%b %d %Y}";
00017
00018
00019
00020
00021
00022
00023 AdCalibFigs::AdCalibFigs(const std::string& name,
00024 ISvcLocator* pSvcLocator)
00025 : GaudiAlgorithm(name,pSvcLocator),
00026 m_statsSvc(0),
00027 m_firstTriggerTime(0)
00028 {
00029 }
00030
00031 AdCalibFigs::~AdCalibFigs()
00032 {
00033 }
00034
00035 StatusCode AdCalibFigs::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 AdCalibFigs::execute()
00047 {
00048
00049 DayaBay::CalibReadoutHeader* calibHeader =
00050 get<DayaBay::CalibReadoutHeader>("/Event/CalibReadout/CalibReadoutHeader");
00051 if(!calibHeader){
00052 error() << "Failed to get calibrated readout header." << endreq;
00053 return StatusCode::FAILURE;
00054 }
00055
00056 const DayaBay::CalibReadout* readout = calibHeader->calibReadout();
00057 if(!readout){
00058 error() << "Failed to get calibrated readout from header" << endreq;
00059 return StatusCode::FAILURE;
00060 }
00061
00062 if(!readout->detector().isAD()){
00063
00064 return StatusCode::SUCCESS;
00065 }
00066
00067
00068 const DayaBay::CalibReadoutPmtCrate* pmtReadout
00069 = dynamic_cast<const DayaBay::CalibReadoutPmtCrate*>(readout);
00070 if(!pmtReadout){
00071 error() << "Failed to get PMT readout" << endreq;
00072 return StatusCode::FAILURE;
00073 }
00074
00075 int runNumber = 0;
00076 {
00077
00078 DayaBay::ReadoutHeader* readoutHeader =
00079 get<DayaBay::ReadoutHeader>("/Event/Readout/ReadoutHeader");
00080 if(!readoutHeader){
00081 error() << "Failed to get readout header." << endreq;
00082 return StatusCode::FAILURE;
00083 }
00084
00085 const DayaBay::DaqCrate* ro = readoutHeader->daqCrate();
00086 if(!ro){
00087 error() << "Failed to get readout from header" << endreq;
00088 return StatusCode::FAILURE;
00089 }
00090
00091 runNumber = ro->runNumber();
00092 }
00093
00094 if(!m_firstTriggerTime){
00095 m_firstTriggerTime = new TimeStamp(readout->triggerTime());
00096 }
00097
00098
00099 const DayaBay::Detector& detector = readout->detector();
00100 TH1F* adCharge = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00101 detector,
00102 0, 0, ADCHARGE));
00103 TH1F* logAdCharge = dynamic_cast<TH1F*>(this->getOrMakeHist(runNumber,
00104 detector,
00105 0, 0,
00106 LOGADCHARGE));
00107 TH2F* pmtCharge = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00108 detector,
00109 0, 0,
00110 PMTCHARGE));
00111 TH2F* adChargeVsTime = dynamic_cast<TH2F*>(this->getOrMakeHist(runNumber,
00112 detector,
00113 0, 0,
00114 ADCHARGEVSTIME));
00115 TH2F* adChargeVsDtTrigger = dynamic_cast<TH2F*>(this->getOrMakeHist(
00116 runNumber,
00117 detector,
00118 0, 0,
00119 ADCHARGEVSDTTRIGGER));
00120 TH2F* maxPmtChargeVsAdCharge = dynamic_cast<TH2F*>(this->getOrMakeHist(
00121 runNumber,
00122 detector,
00123 0, 0,
00124 MAXPMTCHARGEVSADCHARGE));
00125 TH2F* nChannelsVsAdCharge = dynamic_cast<TH2F*>(this->getOrMakeHist(
00126 runNumber,
00127 detector,
00128 0, 0,
00129 NCHANNELSVSADCHARGE));
00130 while(readout->triggerTime().GetSeconds() >
00131 adChargeVsTime->GetXaxis()->GetXmax()){
00132 this->extendRange(adChargeVsTime, 60);
00133 }
00134
00135 const DayaBay::CalibReadoutPmtCrate::PmtChannelReadouts& channels
00136 = pmtReadout->channelReadout();
00137
00138 DayaBay::CalibReadoutPmtCrate::PmtChannelReadouts::const_iterator channelIter,
00139 channelEnd = channels.end();
00140
00141 double adSumCharge = 0;
00142 double maxPmtCharge = 0;
00143 for(channelIter = channels.begin(); channelIter!=channelEnd; channelIter++) {
00144 const DayaBay::CalibReadoutPmtChannel& channel = *channelIter;
00145
00146 DayaBay::AdPmtSensor pmtId( channel.pmtSensorId().fullPackedData() );
00147 int column = pmtId.column();
00148 int ring = pmtId.ring();
00149
00150
00151 double charge = channel.sumCharge();
00152 pmtCharge->Fill(column, ring, charge);
00153 adSumCharge += charge;
00154 if( charge > maxPmtCharge ) maxPmtCharge = charge;
00155 }
00156
00157 if(m_lastTriggerTime.find(readout->detector()) != m_lastTriggerTime.end()){
00158 TimeStamp dtTriggerTime = readout->triggerTime();
00159 dtTriggerTime.Subtract(m_lastTriggerTime[readout->detector()]);
00160 if(adSumCharge>0){
00161 adChargeVsDtTrigger->Fill(dtTriggerTime.GetSeconds()*1e6,
00162 TMath::Log10( adSumCharge ) );
00163 }
00164 }
00165
00166 adCharge->Fill( adSumCharge );
00167 if(adSumCharge>0){
00168 double logAdSumCharge = TMath::Log10( adSumCharge );
00169 logAdCharge->Fill( logAdSumCharge );
00170 if(adChargeVsTime->GetYaxis()->GetXmin()<logAdSumCharge
00171 && adChargeVsTime->GetYaxis()->GetXmax()>logAdSumCharge){
00172 adChargeVsTime->Fill(readout->triggerTime().GetSeconds(), logAdSumCharge );
00173 }
00174 maxPmtChargeVsAdCharge->Fill(logAdSumCharge, maxPmtCharge/adSumCharge);
00175 nChannelsVsAdCharge->Fill(logAdSumCharge, channels.size());
00176 }
00177
00178 pmtCharge->SetNormFactor( pmtCharge->GetNormFactor()+1 );
00179 m_lastTriggerTime[readout->detector()] = readout->triggerTime();
00180
00181 return StatusCode::SUCCESS;
00182 }
00183
00184 StatusCode AdCalibFigs::finalize()
00185 {
00186
00187 for(unsigned int normIdx=0; normIdx<m_normalize.size(); normIdx++){
00188 TH1* hist = m_normalize[normIdx];
00189 hist->Sumw2();
00190 if(hist->GetNormFactor()>0){
00191 double scale = 1./hist->GetNormFactor();
00192 hist->SetNormFactor(1);
00193 hist->Scale( scale );
00194 }
00195 hist->SetBit(TH1::kIsAverage);
00196 }
00197 m_normalize.clear();
00198
00199 std::map<int,TH1**>::iterator histIter, histEnd = m_shortCuts.end();
00200 for(histIter = m_shortCuts.begin(); histIter!=histEnd; histIter++){
00201 delete [] (histIter->second);
00202 histIter->second = 0;
00203 }
00204 if( m_statsSvc ) m_statsSvc->release();
00205 if(m_firstTriggerTime){
00206 delete m_firstTriggerTime;
00207 m_firstTriggerTime = 0;
00208 }
00209 return StatusCode::SUCCESS;
00210 }
00211
00213
00214 TH1* AdCalibFigs::getOrMakeHist(int run, const DayaBay::Detector& detector,
00215 int column, int ring, int histogram)
00216 {
00217 int siteInt = 0;
00218 switch(detector.site()){
00219 case Site::kUnknown:
00220 siteInt = 0; break;
00221 case Site::kDayaBay:
00222 siteInt = 1; break;
00223 case Site::kLingAo:
00224 siteInt = 2; break;
00225 case Site::kFar:
00226 siteInt = 3; break;
00227 case Site::kSAB:
00228 siteInt = 4; break;
00229 default:
00230 error() << "Unknown site: " << detector.detName() << endreq;
00231 return 0;
00232 }
00233 int detectorInt = int(detector.detectorId());
00234 std::map<int,TH1**>::iterator histIter = m_shortCuts.find(run);
00235 TH1** histograms = 0;
00236 if( histIter == m_shortCuts.end() ){
00237
00238 histograms = new TH1*[MAXCALIBHISTS];
00239 for(int i=0; i<MAXCALIBHISTS; i++) histograms[i] = 0;
00240 m_shortCuts[run] = histograms;
00241 }else{
00242
00243 histograms = histIter->second;
00244 }
00245
00246 TH1* hist =
00247 histograms[siteInt * NDETECTORS * NCOLUMNS * NRINGS * NCALIBHISTOGRAMS
00248 + detectorInt * NCOLUMNS * NRINGS * NCALIBHISTOGRAMS
00249 + column * NRINGS * NCALIBHISTOGRAMS
00250 + ring * NCALIBHISTOGRAMS
00251 + histogram];
00252 if(!hist){
00253
00254 std::string histName;
00255 if(detector.detectorId()){
00256
00257 switch(histogram){
00258 case ADCHARGE:
00259
00260 histName = "adCharge";
00261 hist = new TH1F(histName.c_str(),"AD Calibrated Charge",
00262 1100,-100,1000);
00263 hist->GetXaxis()->SetTitle("Photoelectrons");
00264 hist->GetYaxis()->SetTitle("Events");
00265 break;
00266 case LOGADCHARGE:
00267
00268 histName = "logAdCharge";
00269 hist = new TH1F(histName.c_str(),"AD Calibrated Charge",
00270 800,-1,7);
00271 hist->GetXaxis()->SetTitle("log_{10}( Photoelectrons )");
00272 hist->GetYaxis()->SetTitle("Events");
00273 break;
00274 case PMTCHARGE:
00275
00276 histName = "pmtCharge";
00277 hist = new TH2F(histName.c_str(),"Mean PMT Charge by Column/Ring",
00278 49,0.25,24.75,19,-0.75,8.75);
00279 hist->GetXaxis()->SetTitle("PMT Column");
00280 hist->GetYaxis()->SetTitle("PMT Ring");
00281 hist->SetStats(0);
00282 m_normalize.push_back(hist);
00283 hist->SetNormFactor(0);
00284 break;
00285 case ADCHARGEVSTIME:
00286
00287 histName = "adChargeVsTime";
00288 hist = new TH2F(histName.c_str(),
00289 "AD Charge vs. Time",
00290 60,m_firstTriggerTime->GetSec(),
00291 m_firstTriggerTime->GetSec()+60,
00292 200,-1,7);
00293 hist->GetXaxis()->SetTitle("Run Time");
00294 hist->GetYaxis()->SetTitle("log_{10}( Photoelectrons )");
00295 hist->GetXaxis()->SetTimeDisplay(1);
00296 hist->GetXaxis()->SetTimeFormat(timeFormat_AdCalibFigs);
00297 hist->GetXaxis()->SetTimeOffset(0,"gmt");
00298 hist->GetXaxis()->SetNdivisions(505);
00299 break;
00300 case ADCHARGEVSDTTRIGGER:
00301
00302 histName = "adChargeVsDtTrigger";
00303 hist = new TH2F(histName.c_str(),"AD Charge vs time to last event",
00304 200,0,100,200,-1,7);
00305 hist->GetXaxis()->SetTitle("#DeltaT [us]");
00306 hist->GetYaxis()->SetTitle("log_{10}( Photoelectrons )");
00307 break;
00308 case MAXPMTCHARGEVSADCHARGE:
00309
00310 histName = "maxPmtChargeVsAdCharge";
00311 hist = new TH2F(histName.c_str(),"Fraction of Charge in one PMT",
00312 200,-1,7,110,0,1.1);
00313 hist->GetXaxis()->SetTitle("log_{10}( Photoelectrons )");
00314 hist->GetYaxis()->SetTitle("PMT / Total");
00315 break;
00316 case NCHANNELSVSADCHARGE:
00317
00318 histName = "nChannelsVsAdCharge";
00319 hist = new TH2F(histName.c_str(),
00320 "Number of hit channels vs. Total AD Charge",
00321 200,-1,7,200,0,200);
00322 hist->GetXaxis()->SetTitle("log_{10}( Photoelectrons )");
00323 hist->GetYaxis()->SetTitle("Hit Channels");
00324 break;
00325 default:
00326 error() << "Unknown Histogram: " << histogram << endreq;
00327 return 0;
00328 }
00329 }
00330
00331 debug() << "Making histogram: " << histName << endreq;
00332 m_statsSvc->put( this->getPath(run, detector.detName().c_str(), column,
00333 ring, histName.c_str()),
00334 hist );
00335 histograms[siteInt * NDETECTORS * NCOLUMNS * NRINGS * NCALIBHISTOGRAMS
00336 + detectorInt * NCOLUMNS * NRINGS * NCALIBHISTOGRAMS
00337 + column * NRINGS * NCALIBHISTOGRAMS
00338 + ring * NCALIBHISTOGRAMS
00339 + histogram] = hist;
00340 }
00341
00342 return hist;
00343 }
00344
00345 std::string AdCalibFigs::getPath(int run, const char* detectorName,
00346 int column, int ring,
00347 const char* histName)
00348 {
00349
00350 std::stringstream path;
00351 path << "/file1/diagnostics/run_" << std::setfill('0') << std::setw(7)
00352 << run;
00353 if(detectorName){
00354 path << "/detector_" << detectorName;
00355 if(column){
00356 path << "/channel_column" << std::setfill('0') << std::setw(2)
00357 << column << "_ring" << std::setfill('0') << std::setw(2)
00358 << ring;
00359 }
00360 }
00361 path << "/" << histName;
00362 return path.str();
00363 }
00364
00365 void AdCalibFigs::extendRange(TH1* hist, int xBinsAdd, int yBinsAdd)
00366 {
00367
00368
00369 info() << "Extending histogram range: " << hist->GetName() << endreq;
00370 TH1* extension = 0;
00371 if(hist->IsA() == TH2F::Class()){
00372 extension = new TH2F("","",
00373 xBinsAdd + hist->GetNbinsX(),
00374 hist->GetXaxis()->GetXmin(),
00375 hist->GetXaxis()->GetXmax()
00376 + xBinsAdd*hist->GetXaxis()->GetBinWidth(0),
00377 yBinsAdd + hist->GetNbinsY(),
00378 hist->GetYaxis()->GetXmin(),
00379 hist->GetYaxis()->GetXmax()
00380 + yBinsAdd*hist->GetYaxis()->GetBinWidth(0));
00381 }else if(hist->IsA() == TH1F::Class()){
00382 extension = new TH1F("","",
00383 xBinsAdd + hist->GetNbinsX(),
00384 hist->GetXaxis()->GetXmin(),
00385 hist->GetXaxis()->GetXmax()
00386 + xBinsAdd*hist->GetXaxis()->GetBinWidth(0));
00387 }else{
00388 error() << "Cannot extend range of type: " << hist->ClassName() << endreq;
00389 return;
00390 }
00391 TList list;
00392 list.Add(extension);
00393 hist->Merge(&list);
00394 delete extension;
00395 return;
00396 }