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