ATLAS Offline Software
Loading...
Searching...
No Matches
CscCalcPed.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "CscCalcPed.h"
6
7#include "GaudiKernel/Chrono.h"
14
15#include "TF1.h"
16
17#include <iostream>
18#include <fstream>
19#include <bitset>
20#include <inttypes.h>
21
22namespace MuonCalib {
23
24 CscCalcPed::CscCalcPed(const std::string& name, ISvcLocator* pSvcLocator) :
25 AthAlgorithm(name,pSvcLocator),
27 m_numBits(12),
28 m_bitProds(nullptr),
29 m_bitCorrelation(nullptr),
30 m_peds(nullptr),
31 m_noises(nullptr),
32 m_rmses(nullptr),
33 m_f001s(nullptr),
34 m_onlineTHoldBreaches(nullptr),
35 m_eventCnt(0),
36 m_crossTalkFix(nullptr)
37 {
38 declareProperty("OutputFile", m_outputFileName = "output.cal");
39 declareProperty("TitlePrefix",m_titlePrefix = ""); //Prefix appended to title of histograms and graphs
40 declareProperty("TitlePostfix",m_titlePostfix = ""); //Prefix appended to title of histograms and graphs
41 declareProperty("PedAmpHighBound", m_ampHistHighBound = 2600);
42 declareProperty("PedAmpLowBound", m_ampHistLowBound = 1800);
43 declareProperty("PedAmpNumBins", m_ampHistNumBins = 800);
44 declareProperty("ExpectedChamberLayer", m_expectedChamberLayer = 2);
45 declareProperty("ThresholdMultiplier", m_thresholdMultiplier = 3.1);
46 declareProperty("DoBitHists", m_doBitHists = false);
47 declareProperty("CalOutputVersion", m_calOutputVersion="03-00");
48 declareProperty("DoCorrelation", m_doCorrelation = false);
49
50 declareProperty("DoSampHists", m_doSampleHists = false);
51 declareProperty("NumSamplesExpected", m_numSamplesExpected = 4);
52 declareProperty("DoF001", m_doF001 = true);
53
54 declareProperty("OnlineCalibFile", m_onlineDbFile = "", "File with data currently stored in online configuration database");
55 declareProperty("CompareOnlineCalibFile",m_doOnlineDbFile = true, "Compare new to online data?");
56
57
58 //Can't do correlation without bitHists
59 if(!m_doBitHists){
60 m_doCorrelation = false;
61 }
62 }
63
65 {
66 ATH_MSG_INFO("CscCalcPed::initialize() called");
67
69 ATH_MSG_FATAL("Either specify an OnlineCalibFile or set CompareOnlineCalibFile to false");
70 return StatusCode::FAILURE;
71 }
72
73 //*******Register services and tools *********/
75
76 ATH_CHECK(m_idHelperSvc.retrieve());
77
78 ATH_CHECK(m_readKey.initialize());
79
80 m_chronoSvc = service("ChronoStatSvc");
81 ATH_CHECK(m_chronoSvc.isValid());
82
84
85 // Histograms are owned by ROOT.
86 m_ampHists.clear();
87 if(m_doSampleHists) m_sampHists.clear();
88 if(m_doBitHists) m_bitHists.clear();
89
90 //Loop through ids to find out what hash range we're working on (in case we're using some
91 //unusual geometry)
92 const std::vector<Identifier> &ids = m_idHelperSvc->cscIdHelper().idVector();
93
94
96
97 for(const auto &thisChamberId: ids)
98 {
99 std::vector<Identifier> stripVect;
100 m_idHelperSvc->cscIdHelper().idChannels(thisChamberId,stripVect);
101
102
103
104 for(const auto & thisStrip: stripVect)
105 {
106 IdentifierHash stripHash;
107 m_idHelperSvc->cscIdHelper().get_channel_hash(thisStrip,stripHash);
108 if((unsigned int)stripHash > m_maxStripHash)
109 m_maxStripHash = (int)stripHash;
110 }//End strip loop
111 }//end chamber loop
112
113
114 //Now creating ampHists. It wasn't done in last loop since there
115 //is no gaurantee that it will come out in strip order, and we assume
116 //later that m_ampHists's index = stripHash
117 ATH_MSG_DEBUG("Preparing ampHists. Only allowing those for " << " chamberLayer " << m_expectedChamberLayer);
118 for(unsigned int stripItr = 0 ; stripItr <=m_maxStripHash; stripItr++)
119 {
120
121 IdentifierHash stripHash =stripItr;
122 Identifier stripId;
123 IdContext channelContext = m_idHelperSvc->cscIdHelper().channel_context();
124 m_idHelperSvc->cscIdHelper().get_id(stripHash, stripId, &channelContext);
125
126 int chamLayer = m_idHelperSvc->cscIdHelper().chamberLayer(stripId);
127 if(chamLayer == m_expectedChamberLayer) //Only second chamber layer exists
128 {
129 int stationEta = m_idHelperSvc->cscIdHelper().stationEta(stripId);
130 int stationPhi = m_idHelperSvc->cscIdHelper().stationPhi(stripId);
131 int stripNumber = m_idHelperSvc->cscIdHelper().strip(stripId);
132 int wireLayer = m_idHelperSvc->cscIdHelper().wireLayer(stripId);
133 char orientation = m_idHelperSvc->cscIdHelper().measuresPhi(stripId) ? 'Y':'X';
134
135
136 char name[30],titleSeed[600];
137 TH1I* hist = nullptr;
138
139 int stationName = m_idHelperSvc->cscIdHelper().stationName(stripId);
140 //Amplitude histogram
141 sprintf(name, "ampHist%u",stripItr);
142 sprintf(titleSeed, "Amplitude Histogram for eta %d, sector %d, layer %d%c, strip %d",
143 stationEta,(2*stationPhi+50 - stationName),wireLayer,orientation,stripNumber);
144 std::string title = m_titlePrefix + titleSeed + m_titlePostfix;
145
146 hist = new TH1I(name,title.c_str(),m_ampHistNumBins,m_ampHistLowBound,
148 hist->GetXaxis()->SetTitle("Amplitude (ADC value)");
149 hist->GetYaxis()->SetTitle("Counts");
150 m_ampHists.push_back(hist);
151
152 if(m_doSampleHists) {
153 std::vector<TH1I*> tempVect;
154 for(int cnt = 0; cnt < m_numSamplesExpected ; cnt++) {
155 sprintf(name, "sampHist%u_%d",stripItr,cnt);
156 sprintf(titleSeed, "Amplitude Histogram for eta %d, sector %d, layer %d%c, strip %d, sample %d",
157 stationEta,(2*stationPhi+50 - stationName),wireLayer,orientation,stripNumber,cnt);
158
159 hist = new TH1I(name,title.c_str(),m_ampHistNumBins,m_ampHistLowBound,
161 tempVect.push_back(hist);
162
163 }
164 m_sampHists.push_back(std::move(tempVect));
165 }
166
167 if(m_doBitHists)
168 {
169 //Bit histogram (for looking for stuck-bits)
170 sprintf(name, "bitHist%u",stripItr);
171 sprintf(titleSeed, "Bit histogram for eta %d, sector %d, layer %d%c strip %d",
172 stationEta,(2*stationPhi+50 - stationName),wireLayer,orientation,stripNumber);
173 title = m_titlePrefix + titleSeed + m_titlePostfix;
174 hist = new TH1I(name, title.c_str(), m_numBits, 0, m_numBits); //12 bits
175 hist->GetXaxis()->SetTitle("Bit");
176 hist->GetYaxis()->SetTitle("Counts");
177 m_bitHists.push_back(hist);
178 if(m_doCorrelation) {
179 (*m_bitProds)[stripItr] = new TH2F(TString::Format("bitProds%d",stripItr),"Bit products", m_numBits,0,m_numBits, m_numBits, 0, m_numBits);
180
181 }
182 }
183 }
184 else
185 {
186 m_ampHists.push_back(nullptr);
187 if(m_doBitHists) m_bitHists.push_back(nullptr);
188 if(m_doSampleHists) m_sampHists.push_back(std::vector<TH1I*>());
189 }
190 }//end strip loop
191
192 //Setup result collections. These will be passed to storegate for any monitoring later
193 m_peds = new CscCalibResultCollection("ped");
194 m_noises = new CscCalibResultCollection("noise");
196 if(m_doF001){
197 ATH_MSG_DEBUG("Doing f001");
198 //For f001 values
199 m_f001s = new CscCalibResultCollection("f001");
200
201 //Initializing for comparing new values to an online database file
203
204 //How many samples failed the online threshold test of f001 +2*RMS
205 //(f001 and RMS read from a file from online configuration db)
206 m_onlineTHoldBreaches = new CscCalibResultCollection("OnlTHoldBreaches");
207
208
209
210 //Vector we use to count the online thresholds
212
213 //Retrieve current online thresholds
215 std::ifstream ifile; ifile.open(m_onlineDbFile.c_str());
216 if(!ifile.is_open()){
217 ATH_MSG_FATAL("Failed to open online database file " << m_onlineDbFile);
218 return StatusCode::FAILURE;
219 }
220 std::string buf;
221 ifile >> buf; // skip 32 at start of file
222 unsigned int onlineId;
223 unsigned int hashId;
224 double rms;
225 double f001;
226
227 if(!ifile){
228 ATH_MSG_FATAL("Problem with file after one word read in.");
229 return StatusCode::FAILURE;
230 }
231
232
233 ATH_MSG_DEBUG("Reading in online thresholds from file " << m_onlineDbFile);
234 ATH_MSG_DEBUG("First (junk) word: " << buf);
235 int chanCnt = 0;
236 while(ifile >> std::hex >> onlineId >> std::dec) {
237 chanCnt++;
238 onlineToOfflineHashId(onlineId,hashId);
239
240 ifile >> buf >> buf >> buf >> buf >> rms >> buf >> f001;
241 double thold = f001 + 2*rms;
242 ATH_MSG_VERBOSE("onlid: " << std::hex << onlineId << std::dec << " hash: " << hashId << " rms: " << rms << " f001: " << f001 << " thold: " << thold);
243 m_onlineThresholds.at(hashId) = thold;
244 if(!ifile)
245 ATH_MSG_VERBOSE("input file is done, ready to close!");
246 else
247 ATH_MSG_VERBOSE("Input file still good!");
248
249
250 }
251 if(chanCnt != 30720){
252 ATH_MSG_FATAL("Did not retrieve expected 30720 channels from online database! Retrieved: " << chanCnt);
253 ATH_MSG_FATAL("Last onlineId read: " << std::hex << onlineId << std::dec);
254 return StatusCode::FAILURE;
255 }
256
257 }//if m_doOnlineDBFile
258 }//db file
259
260 ATH_MSG_INFO("highest strip hash id is " << m_maxStripHash);
261
262 //If we're doing correlation plots, set up the product histogram array
263 if(m_doCorrelation){
265 m_bitProds->resize(m_maxStripHash+1);
266 }
267
268
269
270
271
272 ATH_MSG_INFO("m_prods value: " << m_bitProds << "\ndoCorrelation" << m_doCorrelation);
273 return StatusCode::SUCCESS;
274 }
275
276 //Execute loops through all strips and fills histograms
278 {
279 ATH_MSG_DEBUG("Begin execute");
280 //collectEventInfo collects infomation about each event by filling ampHistCollection and peaktHist.
281 StatusCode sc = collectEventInfo();
282
283 if(!sc.isSuccess())
284 {
285 ATH_MSG_ERROR("There was an error collecting information from the RDO this event.");
286 return StatusCode::RECOVERABLE;
287 }
288 ATH_MSG_DEBUG("End execute");
289 return StatusCode::SUCCESS;
290 } //end execute()
291
292 StatusCode CscCalcPed::finalize() {
293 if(m_eventCnt ==0)
294 {
295 ATH_MSG_FATAL("No events processed!");
296 return StatusCode::FAILURE;
297 }
298 else
299 ATH_MSG_INFO("In finalize() after analyzing " << m_eventCnt << " events ");
300
301 StatusCode sc;
302
303 ATH_MSG_INFO("not dump all hists!");
304
305 //calculateParameters() finds means and fits gain curves from the data in
306 //m_ampHistCollection and/or m_peaktHist
308 if(!sc.isSuccess())
309 {
310 ATH_MSG_FATAL("Calculation of parameters failed!");
311 return StatusCode::FAILURE;
312 }
313 ATH_MSG_DEBUG("Finished calculating parameters");
314
315
316 //writeCalibrationFile() writes the calculated parameters into a calibration fie.
318 if(!sc.isSuccess())
319 {
320 ATH_MSG_FATAL("Calculation of parameters failed!");
321 return StatusCode::FAILURE;
322 }
323
324 //Record report (ampHists) and results to storegate for future algorithms
325 //like COOL database storage or monitoring to collect
327 if (!sc.isSuccess())
328 {
329 ATH_MSG_FATAL("Failed recording data in storegate");
330 return StatusCode::FAILURE;
331 }
332
333 ATH_MSG_INFO("Finished finalize");
334 return StatusCode::SUCCESS;
335 }//end finalize()
336
337
338 //Collect event info is run every event, gathering amplitutdes and peakting times.
340 {
341 //start the timer
342 Chrono chrono(m_chronoSvc,"collectEventInfo");
343
344
345 m_eventCnt++;
346 ATH_MSG_DEBUG("Collecting event info for event " << m_eventCnt);
347 //Below might need to be changed depending on how we get data
348 const CscRawDataContainer* rawDataContainer;
349 StatusCode sc_read = evtStore()->retrieve(rawDataContainer, "CSCRDO");
350 if (sc_read != StatusCode::SUCCESS)
351 {
352 ATH_MSG_FATAL("Could not find event");
353 return StatusCode::FAILURE;
354 }
355
356 ATH_MSG_VERBOSE("Retrieved RDO from storegate ");
357
358 if(rawDataContainer->size() == 0)
359 {
360 ATH_MSG_FATAL("no rods in RDO!");
361 return StatusCode::FAILURE;
362 }
363
364 ATH_MSG_VERBOSE("There are " << rawDataContainer->size() << " rods in the RDO");
365
366 IdContext channelContext = m_idHelperSvc->cscIdHelper().channel_context();
367
368 //Loop over RODs (data from 2 chambers), each of which is in
369 //a single CscRawaData collection
370
371 for(const auto rod : *rawDataContainer)
372 {
373 Chrono chronoRod(m_chronoSvc,"RodItr");
374 ATH_MSG_VERBOSE("Examining a ROD");
375
376 ATH_MSG_VERBOSE("There are " << rod->size() << " clusters in the ROD");
377 if(rod->size() >0)
378 {
379 //Loop over strips in rod
380
381
382 for(const auto cluster: *rod)
383 {
384 Chrono chronoClus(m_chronoSvc,"ClusterItr");
385 int numStrips = cluster->width();
386 int samplesPerStrip = (cluster->samples()).size()/numStrips;
387
388 ATH_MSG_VERBOSE("About to collect info from " << numStrips << " strips");
389 for(int stripItr = 0; stripItr <numStrips; stripItr++)
390 {
391
392 Chrono chronoStrip(m_chronoSvc,"stripItr");
393 // WP Added
394 Identifier channelId =m_cscRdoDecoderTool->channelIdentifier(cluster, &m_idHelperSvc->cscIdHelper(), stripItr);
395 IdentifierHash cscChannelHashId;
396 m_idHelperSvc->cscIdHelper().get_channel_hash(channelId, cscChannelHashId);
397
399 int stripHash = cscChannelHashId;
400
401 Identifier stripId;
402 m_idHelperSvc->cscIdHelper().get_id(stripHash, stripId, &channelContext);
403
404
405 Chrono chronoAfterId(m_chronoSvc,"afterID1");
406
407 if( m_idHelperSvc->cscIdHelper().chamberLayer(channelId) != m_expectedChamberLayer)
408 {
409 ATH_MSG_WARNING("Wrong chamber layer a hash ("
410 << stripHash << ") from the wrong multilayer has appeared in the data. Its string id is " << m_idHelperSvc->cscIdHelper().show_to_string(stripId)
411 << " " << m_idHelperSvc->cscIdHelper().show_to_string(channelId));
412
413 ATH_MSG_INFO("WP added (1) "
414 << m_idHelperSvc->cscIdHelper().stationEta(stripId) << " " << m_idHelperSvc->cscIdHelper().measuresPhi(stripId) << " "
415 << stripHash << " " << cscChannelHashId);
416
417 ATH_MSG_INFO("WP added (2) "
418 << m_idHelperSvc->cscIdHelper().stationEta(stripId) << " " << m_idHelperSvc->cscIdHelper().measuresPhi(stripId) << " "
419 << stripId << " " << channelId);
420
421 stripId = m_idHelperSvc->cscIdHelper().channelID(
422 m_idHelperSvc->cscIdHelper().stationName(stripId),
423 m_idHelperSvc->cscIdHelper().stationEta(stripId),
424 m_idHelperSvc->cscIdHelper().stationPhi(stripId),
425 2,
426 m_idHelperSvc->cscIdHelper().wireLayer(stripId),
427 m_idHelperSvc->cscIdHelper().measuresPhi(stripId),
428 m_idHelperSvc->cscIdHelper().strip(stripId)
429 );
430 IdentifierHash newHash;
431 m_idHelperSvc->cscIdHelper().get_channel_hash(stripId, newHash );
432 stripHash = newHash;
433 ATH_MSG_DEBUG("New hash " << stripHash);
434 }
435 else{
436 if(m_idHelperSvc->cscIdHelper().measuresPhi(stripId))
437 ATH_MSG_VERBOSE(" good id Measures Phi");
438 else
439 ATH_MSG_VERBOSE(" good id is eta");
440 }
441
442 Chrono chronoAfterId2(m_chronoSvc,"afterID2");
443
444 //Get samples. Each shows amplitude of pulse at different
445 //time slice.
446 std::vector<uint16_t> samples;
447 cluster->samples(stripItr,samplesPerStrip,samples);
448
449 //Test for threshold breach...
450 size_t sampCnt = 0;
451
452
453 for(const auto & thisSample: samples)
454 {
455 m_ampHists[stripHash]->Fill(thisSample);
457 m_sampHists[stripHash][sampCnt]->Fill(thisSample);
458 if(m_doBitHists && sampCnt==1)
459 {
460 TH2F* prodHist = nullptr;
461 if(m_bitProds)
462 prodHist = (*m_bitProds)[stripHash];
463 if(!fillBitHist(m_bitHists[stripHash],thisSample, prodHist).isSuccess())
464 ATH_MSG_WARNING("Failed recording bits for strip " << stripHash);
465 }//end if(m_doBitHists)
466
467 if(m_doOnlineDbFile){//m_doF001){
468 //test if any samples are obvoe the online threshold
469 if (thisSample > m_onlineThresholds[stripHash] ){
471 ATH_MSG_VERBOSE("StripHash: " << stripHash <<
472 " has online threshold breach. Sample: " << thisSample << " Thold: "
473 << m_onlineThresholds[stripHash]);
474 }
475 }
476 sampCnt++;
477 }//end Sample loop
478 }//end strip loop
479 }//end cluster loop
480 }
481 else
482 ATH_MSG_DEBUG("There is an empty rod (CscRawDataContainer).");
483 }//end rod loop
484 ATH_MSG_DEBUG("end collectEventInfo()");
485 return StatusCode::SUCCESS;
486 }// end collectEventInfo()
487
488
489 //Calculate parameters is called during finalize,
490 //calculates the parameter values.
492 {
493 Chrono chrono(m_chronoSvc,"calculateParameters");
494
495
496 //**********Calculate all the parameters from data collected during execute*****************//
497
498 for(unsigned int stripHash = 0 ;stripHash <= m_maxStripHash; stripHash++)
499 {
500 if(stripHash < 50 || stripHash%1000 == 0)
501 {
502 ATH_MSG_INFO("Analyzing strip with hash " << stripHash << " out of " << m_maxStripHash);
503 ATH_MSG_VERBOSE((float)clock()/((float)CLOCKS_PER_SEC) << " is the time");
504 }
505
506 TH1I * ampHist = m_ampHists[stripHash];
507 if(ampHist)
508 {
509 ATH_MSG_VERBOSE("Have data for strip hash " << stripHash);
510 if(ampHist->GetEntries() >0) //If strip wasn't tested, it won't have entries
511 {
512 //Following Schernau's work
513 float histMean = ampHist->GetMean();
514 float histRMS = ampHist->GetRMS();
515 float histRMSError = ampHist->GetRMSError();
516
517 float lowbound = histMean - 3*histRMS;
518 float highbound = histMean + 3*histRMS;
519 ATH_MSG_VERBOSE("About to fit...");
520
521 int result = ampHist->Fit("gaus","QL","",lowbound,highbound);
522 ATH_MSG_VERBOSE("Result is " << result);
523 TF1 * fittedFunction = ampHist->GetFunction("gaus");
524 double meanError = fittedFunction->GetParError(1);
525 double sigma = fittedFunction->GetParameter(2);
526 double sigmaError = fittedFunction->GetParError(2);
527 double chi2 = fittedFunction->GetChisquare();
528 int ndf = fittedFunction->GetNDF();
529
530 m_peds->push_back(new CscCalibResult(stripHash,histMean,meanError,chi2,ndf));
531 m_noises->push_back(new CscCalibResult(stripHash,sigma,sigmaError,chi2,ndf));
532 m_rmses->push_back(new CscCalibResult(stripHash,histRMS,histRMSError,0,0));
533
534
535
536 //Integrated threshold (f001) calculation
537 if(m_doF001){
538 int num = (int)ampHist->GetEntries();
539 int thr = ampHist->GetNbinsX() + 1; // start at overflow bin
540 double maxSum = 0.001*num; // 99.90 of pedestals under thr
541 //double maxSum = 0.0001*num; // 99.99 of pedestals under thr
542
543 double sum = 0;
544 do{
545 sum += ampHist->GetBinContent(thr);
546 thr--;
547 } while ((thr>0)&&(sum<maxSum));
548
549 //double threshold = ampHist->GetXaxis()->GetBinLowEdge(thr) +2; //For some reason +2 here matches Michael Schernau's +1
550 double threshold = ampHist->GetXaxis()->GetBinLowEdge(thr) +1; //For some reason +2 here matches Michael Schernau's +1
551 m_f001s->push_back(new CscCalibResult(stripHash,threshold,0,0,0));
552
554 m_onlineTHoldBreaches->push_back(new CscCalibResult(stripHash,m_onlineThresholdFailureCount[stripHash],0));
555 }
556 }
557 }
558 }
559 else
560 ATH_MSG_VERBOSE("Don't have data for strip hash " << stripHash);
561 }//end loop over strips
562
563
564 //don't need it anymore, clear ram taken by m_failure tests
565 ATH_MSG_DEBUG("Clearing m_onlineThresholdFailureCount");
567
568
569 ATH_MSG_INFO("Completed calculating parameters.");
570
571 return StatusCode::SUCCESS;
572 }//End calculateParameters()
573
574 //writeCalibrationFile() dumps the parameters to disk
576 {
577 Chrono chrono(m_chronoSvc,"writeFile");
578 //***Take conditions data held in summary histograms and print to the calibration file***//
579 ATH_MSG_INFO("Parameters calculated, preparing to output to file: " << m_outputFileName << " Types 1 and " << m_calOutputVersion);
580
582
583 if(m_calOutputVersion == "00-00"){
584 return calOutput0();
585 }
586 else if(m_calOutputVersion == "03-00") {
587 return calOutput3();
588 }
589 else{
590 ATH_MSG_WARNING("Don't know how to write calibration file version " << m_calOutputVersion);
591 return StatusCode::RECOVERABLE;
592 }
593 // this part of the code cannot be reached since one of the if statements before already exits the code
594 // return StatusCode::SUCCESS;
595 }
596
598
599 std::ofstream out;
600 out.open(m_outputFileName.c_str());
601 if(!out.is_open())
602 {
603 ATH_MSG_ERROR("Can't open file " << m_outputFileName.c_str());
604 return StatusCode::RECOVERABLE;
605 }
606
607 out << "00-00 ";
608 out << m_peds->size() << " ";
609 out << "ped ";
610 out << "noise ";
611 out << "rms ";
612 out << "END_HEADER\n";
613
614 ATH_MSG_DEBUG("Begining loop over all " << m_peds->size() << " channels data was collected for.");
615
616 //form is:hashID chamber LayerOrientationStrip parametervalue parametervalue
619 CscCalibResultCollection::iterator noiseItr = m_noises->begin();
621 for(;pedItr!= pedEnd;++pedItr,++noiseItr, ++rmsItr)//,tholdItr++)
622 {
623 int hashId = (*pedItr)->hashId();
624 double ped = (*pedItr)->value();
625 double noise = (*noiseItr)->value();
626 double rms = (*rmsItr)->value();
627
628 ATH_MSG_DEBUG("we're on hash " << hashId << " with pedestal " << ped << "and noise " << noise);
629 Identifier id;
630 IdContext channelContext = m_idHelperSvc->cscIdHelper().channel_context();
631 m_idHelperSvc->cscIdHelper().get_id(hashId,id, &channelContext);
632
633 Identifier chamberId = m_idHelperSvc->cscIdHelper().elementID(id);
634 if(!m_idHelperSvc->cscIdHelper().valid(chamberId))
635 {
636 ATH_MSG_WARNING(chamberId.getString() << " is not a valid id!");
637 ATH_MSG_WARNING("identifier is: " << m_idHelperSvc->cscIdHelper().show_to_string(chamberId));
638 }
639
640 IdentifierHash chamberHash;
641 m_idHelperSvc->cscIdHelper().get_module_hash(id,chamberHash);
642
643 //print out values.
644 out << hashId;
645 out <<" " << chamberHash;
646 out << " " << m_idHelperSvc->cscIdHelper().show_to_string(id) << " ";
647 out << " " << ped;
648 out << " " << noise;
649 out << " " << rms;
650 out << "\n" ;
651 } //end loop over hash Ids
652
653 out.close(); //done writing
654 ATH_MSG_INFO("File written");
655 return StatusCode::SUCCESS;
656 }//end calOutput0
657
658 //calOutput1 prints out calibration output file in format Michael Schernau's
659 //online software likes to read
661
662 std::ofstream out;
663 std::string onlineFileName = m_outputFileName + "_online";
664
665 out.open(onlineFileName.c_str());
666 if(!out.is_open())
667 {
668 ATH_MSG_ERROR("Can't open online file " << m_outputFileName.c_str());
669 return StatusCode::RECOVERABLE;
670 }
671
672 out << "32\n";
673
674 ATH_MSG_DEBUG("Begining loop over all " << m_peds->size() << " channels data was collected for.");
675
677 const CscCondDbData* readCdo{*readHandle};
678
679 //form is:hashID chamber LayerOrientationStrip parametervalue parametervalue
682 CscCalibResultCollection::iterator noiseItr = m_noises->begin();
685 for(;pedItr!= pedEnd;++pedItr,++noiseItr, ++rmsItr, ++f001Itr)//,tholdItr++)
686 {
687 int hashId = (*pedItr)->hashId();
688 double ped = (*pedItr)->value();
689 double noise = (*noiseItr)->value();
690 //double rms = (*rmsItr)->value();
691 double f001 = (*f001Itr)->value();
692
693 //double thold = (*tholdItr)->value();
694 std::string onlineHexId;
695
696 //Online ids are same as "string ids" used internally in COOL db.
697 readCdo->indexToStringId(&m_idHelperSvc->cscIdHelper(), hashId, "CHANNEL", onlineHexId).ignore();
698
699 ATH_MSG_DEBUG("we're on hash " << hashId << " with pedestal " << ped << "and noise " << noise);
700 Identifier id;
701 IdContext channelContext = m_idHelperSvc->cscIdHelper().channel_context();
702 m_idHelperSvc->cscIdHelper().get_id(hashId,id, &channelContext);
703
704 Identifier chamberId = m_idHelperSvc->cscIdHelper().elementID(id);
705 if(!m_idHelperSvc->cscIdHelper().valid(chamberId))
706 {
707 ATH_MSG_WARNING(chamberId.getString() << " is not a valid id!");
708 ATH_MSG_WARNING("identifier is: " << m_idHelperSvc->cscIdHelper().show_to_string(chamberId));
709 }
710
711 char orientationChar = (m_idHelperSvc->cscIdHelper().measuresPhi(id) ? 'Y':'X');
712
713
714 IdentifierHash chamberHash;
715 m_idHelperSvc->cscIdHelper().get_module_hash(id,chamberHash);
716
717 //print out values.
718 out.setf(std::ios::right);//right aligned columns
719 out << std::setfill('0') << std::setw(8) << onlineHexId;
720 out <<" "
721 << std::setw(2) << chamberHash << orientationChar << (m_idHelperSvc->cscIdHelper().wireLayer(id)-1)
722 <<" "
723 << std::setw(3) << m_idHelperSvc->cscIdHelper().strip(id) -1 << " " ;
724 out.setf(std::ios::fixed);
725
726
727 out << " " << std::setprecision(3) << std::setw(8) << ped << " 0000.00";
728 out << " " << std::setprecision(3) << std::setw(8) << noise << " 0000.000";
729 out << " " << f001;
730 out << "\n" ;
731 } //end loop over hash Ids
732
733 out.close(); //done writing
734 ATH_MSG_INFO("File written");
735 return StatusCode::SUCCESS;
736 }//end calOutput1
737
738 //calOutput3 outputs version 03-00 calibration files, which are what the most recent version
739 //of CscCoolReadWrite takes for input
741 std::ofstream out;
742 out.open(m_outputFileName.c_str());
743 if(!out.is_open())
744 {
745 ATH_MSG_ERROR("Can't open output 3 type file " << m_outputFileName.c_str() << " for writing ");
746 return StatusCode::RECOVERABLE;
747 }
748 out << "03-00 <END_HEADER>";
749
753 if(m_doF001)
755 out << "\n<END_FILE>";
756 out.close();
757
758 return StatusCode::SUCCESS;
759 }
760
761
762 //Outputs a single parameter in version 03-00
763 void CscCalcPed::outputParameter3(const CscCalibResultCollection & results, std::ofstream & out){
764
766 const CscCondDbData* readCdo{*readHandle};
767
768 out << "\n";
769 out << "<NEW_PAR> " << results.parName() << "\n";
770 std::string idString;
771
772 CscCalibResultCollection::const_iterator resItr = results.begin();
773 CscCalibResultCollection::const_iterator resEnd = results.end();
774 for(; resItr != resEnd; ++resItr){
775 unsigned int hashId = (*resItr)->hashId();
776 double value = (*resItr)->value();
777 std::string idString;
778
779 readCdo->indexToStringId(&m_idHelperSvc->cscIdHelper(), hashId, "CHANNEL", idString).ignore();
780
781 out << idString << " " << value << "\n";
782 }
783
784 out << "<END_PAR>" ;
785 }
786
787
788
789 //Record ampHist and calib results to storegate for monitoring and maybe other
790 //programs
792 {
793 StatusCode sc = StatusCode::SUCCESS;
794
795 bool thereIsAnError = false;
796
797 std::string histKey = "cscPedCalibReport";
798 ATH_MSG_DEBUG("Recording pedestal amplitude histograms to TDS with key " << histKey);
799
800 //CscCalibReport has extraraneous monitoring information
801 CscCalibReportPed * report = new CscCalibReportPed("pedAmps");
802 report->setPedAmpHists(std::move(m_ampHists));
803 report->setBitHists(std::move(m_bitHists));
804 if(m_doSampleHists){
805 report->setSampHists(std::move(m_sampHists));
806 }
807 if(m_bitProds){
808 report->setBitCorrelation( makeBitCorrelation());
809 }
810
811 CscCalibReportContainer * repCont = new CscCalibReportContainer(histKey);
812 repCont->push_back(report);
813
814 sc = evtStore()->record(repCont, histKey);
815 if(!sc.isSuccess())
816 {
817 ATH_MSG_ERROR("Failed to record CscCalibReportPed to storegate");
818 thereIsAnError = true;
819 delete repCont;
820 }
821
822
823 //CscCalibResult contains the actual parameters that we recorded, mostly things that should be entered
824 //into cool
825 std::string key = "CscCalibResultPed";
826 ATH_MSG_DEBUG("Recording calibration results to TDS with key " << key);
827
828 CscCalibResultContainer * calibResults
829 = new CscCalibResultContainer("CscCalibResultPed");
830 calibResults->push_back(m_peds);
831 calibResults->push_back(m_noises);
832 calibResults->push_back(m_rmses);
833 calibResults->push_back(m_f001s);
835 calibResults->push_back(m_onlineTHoldBreaches);
836
837 sc = evtStore()->record(calibResults,key);
838 if(!sc.isSuccess())
839 {
840 ATH_MSG_ERROR("Failed to record data to storegate");
841 thereIsAnError = true;
842 delete calibResults;
843 }
844
845 if(thereIsAnError)
846 return StatusCode::RECOVERABLE;
847
848 return StatusCode::SUCCESS;
849 }
850
851 //Does bit correlation study. Likely will be dropped
852 std::vector<TH2F*> CscCalcPed::makeBitCorrelation() {
853
854 std::vector<TH2F*> correlations;
855 if(!m_bitProds || !m_doBitHists)
856 return correlations;
857
858 correlations.resize(m_maxStripHash +1);
859
860 for(unsigned int hashItr =0; hashItr <= m_maxStripHash; hashItr++) {
861 IdentifierHash stripHash =hashItr;
862 Identifier stripId;
863 IdContext channelContext = m_idHelperSvc->cscIdHelper().channel_context();
864 m_idHelperSvc->cscIdHelper().get_id(stripHash, stripId, &channelContext);
865
866 int chamLayer = m_idHelperSvc->cscIdHelper().chamberLayer(stripId);
867 if(chamLayer == m_expectedChamberLayer) //Only second chamber layer exists
868 {
869 int stationName = m_idHelperSvc->cscIdHelper().stationName(stripId);
870 //int stationEta = m_idHelperSvc->cscIdHelper().stationEta(stripId);
871 int stationPhi = m_idHelperSvc->cscIdHelper().stationPhi(stripId);
872 int stripNumber = m_idHelperSvc->cscIdHelper().strip(stripId);
873 int wireLayer = m_idHelperSvc->cscIdHelper().wireLayer(stripId);
874 char orientation = m_idHelperSvc->cscIdHelper().measuresPhi(stripId) ? 'Y':'X';
875
876 int sector = 2*stationPhi + 50 - stationName;
877
878 std::stringstream name;
879 name << "h_bitCorr_sector_" << std::setfill('0') << std::setw(2) << sector <<
880 "_lay_" << wireLayer << orientation << "_strip_" << std::setw(3) << stripNumber;
881 std::stringstream title;
882 title << "h_bitCorr_sector_" << std::setfill('0') << std::setw(2) << sector <<
883 "_lay_" << wireLayer << orientation << "_strip_" << std::setw(3) << stripNumber;
884
885 TH2F* correlationHist = new TH2F(
886 name.str().c_str(),
887 title.str().c_str(),
890 );
891 correlations[hashItr] = correlationHist;
892
893 //each amphis is filled exaclty the number of times the bits are sampled,
894 //so its a good place to get n
895 double n = m_ampHists[hashItr]->GetEntries();
896 TH1I * bitHist = m_bitHists[hashItr];
897 TH2F * bitProds = (*m_bitProds)[hashItr];
898 for(unsigned int bit1 = 1; bit1 <=m_numBits; bit1++){
899 for(unsigned int bit2 = 1; bit2 <=bit1; bit2++){
900
901 float xy = bitProds->GetBinContent(bit1,bit2);
902 float x = bitHist->GetBinContent(bit1);
903 float y = bitHist->GetBinContent(bit2);
904
905 float r;
906 float denom = (n*x-x*x)*(n*y-y*y);
907 if(denom <= 0 )
908 r= 0;
909 else
910 r = (n*xy - x*y)/std::sqrt(denom);
911
912 //Pearson r
913 correlationHist->SetBinContent(bit1,bit2,r);
914 if(bit1!=bit2)
915 correlationHist->SetBinContent(bit2,bit1,r);
916
917
918 }
919 }
920 }
921 }
922 return correlations;
923 }//end makeBitCorrelations
924
925
926 void CscCalcPed::onlineToOfflineHashId(const unsigned int & onlineId, unsigned int &hashId) const
927 {
928 int stationName = ((onlineId >> 16)&0x1) + 50;
929 int phi = ((onlineId >> 13)&0x7)+1;
930 int eta = ((((onlineId >> 12)&0x1) == 1) ? 1:-1);
931 int chamLay = ((onlineId>>11)&0x1) +1;
932 int wireLay = ((onlineId>>9)&0x3) +1;
933 int measuresPhi = ((onlineId >> 8)&0x1);
934 int strip;
935
936 // Online and offline phi ids are flipped on A wheel
937 if( measuresPhi && eta == 1){
938 strip = 48 - ((onlineId)&0xff) ; //equivalent: 49 -( onlineId&0xff +1)
939 }
940 else {
941 strip = ((onlineId)&0xff) +1;
942 }
943
944 Identifier chanId = m_idHelperSvc->cscIdHelper().channelID(stationName,eta,phi,chamLay,wireLay,measuresPhi,strip);
945
946 IdentifierHash chanHash;
947 m_idHelperSvc->cscIdHelper().get_channel_hash(chanId, chanHash);
948
949 hashId = (unsigned int)chanHash;
950
951 }
952
953 }//end namespace MuonCalib
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static Double_t sc
#define y
#define x
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
StatusCode indexToStringId(const CscIdHelper *, const unsigned int &, const std::string &, std::string &) const
This container provides access to collections of CSC RDOs and a mechanism for recording them.
Derived DataVector<T>.
Definition DataVector.h:795
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataModel_detail::iterator< DataVector > iterator
Definition DataVector.h:842
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
Definition IdContext.h:26
size_t size() const
Duplicate of fullSize for backwards compatability.
This is a "hash" representation of an Identifier.
std::string getString() const
Provide a string form of the identifier - hexadecimal.
std::string m_titlePostfix
Definition CscCalcPed.h:91
CscCalibResultCollection * m_noises
Definition CscCalcPed.h:124
CscCalibResultCollection * m_peds
Definition CscCalcPed.h:123
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Services and tools.
Definition CscCalcPed.h:83
unsigned int m_ampHistNumBins
Definition CscCalcPed.h:105
SmartIF< IChronoStatSvc > m_chronoSvc
Definition CscCalcPed.h:84
unsigned int m_ampHistHighBound
Definition CscCalcPed.h:105
DataVector< TH2F > * m_bitProds
Definition CscCalcPed.h:119
StatusCode initialize(void)
basic required functions
StatusCode fillBitHist(TH1I *bitHist, const uint16_t &val, TH2F *bitProds)
Definition CscCalcPed.h:139
const unsigned int m_numBits
Definition CscCalcPed.h:107
StatusCode execute(void)
StatusCode calOutput1()
StatusCode finalize(void)
StatusCode calculateParameters()
Finalize functions.
DataVector< TH1F > * m_bitCorrelation
Definition CscCalcPed.h:120
StatusCode storeGateRecord()
CscCalibResultCollection * m_f001s
Definition CscCalcPed.h:126
std::vector< std::vector< TH1I * > > m_sampHists
Definition CscCalcPed.h:117
std::string m_onlineDbFile
filename for file with online database information
Definition CscCalcPed.h:100
unsigned int m_maxStripHash
Internally global variables.
Definition CscCalcPed.h:103
void onlineToOfflineHashId(const unsigned int &onlineId, unsigned int &hashId) const
CscCalcPed(const std::string &name, ISvcLocator *pSvcLocator)
std::vector< TH1I * > m_bitHists
Definition CscCalcPed.h:118
StatusCode collectEventInfo()
event loop functions
std::vector< int > m_onlineThresholdFailureCount
Definition CscCalcPed.h:122
std::vector< int > m_onlineThresholds
Definition CscCalcPed.h:121
std::string m_calOutputVersion
Definition CscCalcPed.h:92
std::string m_titlePrefix
Definition CscCalcPed.h:91
StatusCode calOutput3()
void outputParameter3(const CscCalibResultCollection &results, std::ofstream &out)
CscCalibResultCollection * m_onlineTHoldBreaches
Definition CscCalcPed.h:127
StatusCode writeCalibrationFile()
std::vector< TH2F * > makeBitCorrelation()
SG::ReadCondHandleKey< CscCondDbData > m_readKey
Definition CscCalcPed.h:86
std::vector< TH1I * > m_ampHists
Definition CscCalcPed.h:116
StatusCode calOutput0()
ToolHandle< Muon::ICSC_RDO_Decoder > m_cscRdoDecoderTool
Definition CscCalcPed.h:85
unsigned int m_ampHistLowBound
Definition CscCalcPed.h:105
CscCalibResultCollection * m_rmses
Definition CscCalcPed.h:125
std::string m_outputFileName
Parameters input through joboptions.
Definition CscCalcPed.h:90
double chi2(TH1 *h0, TH1 *h1)
int r
Definition globals.cxx:22
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts