13 #include "TGraphErrors.h"
25 const IInterface*
parent) :
79 return StatusCode::SUCCESS;
86 ATH_MSG_DEBUG(
"CscCalibMonToolSlope : in bookHistograms()" );
91 int highbound,lowbound,
nbins;
98 name =
"h_csc_calib_numSignificant";
99 title =
"Number of significant results.";
101 yaxis =
"Num channels with bad value.";
105 m_h_numBad->GetYaxis()->SetTitle(yaxis.c_str());
106 m_h_numBad->GetXaxis()->SetTitle(xaxis.c_str());
173 name =
"h_csc_calib_deadOverview";
174 title =
"Number of dead channels";
186 name =
"h_csc_calib_slopeMissingChans";
187 title =
"Number of dead channels";
188 xaxis =
"Channel (Hash ID)";
200 std::string peaktDataName =
"peakt";
201 std::string peaktDataTitle =
"Peaking Time";
202 std::string peaktSubDir =
"Peakt";
204 std::string slopeDataName =
"slope";
205 std::string slopeDataTitle =
"Pulser Gain Slope";
206 std::string slopeSubDir =
"Slope";
208 std::string slopeRatioDataName =
"slopeRatio";
209 std::string slopeRatioDataTitle =
"Ratio of N : N+1 Channel Slopes";
210 std::string slopeRatioSubDir =
"SlopeRatio";
212 std::string interceptDataName =
"intercept";
213 std::string interceptDataTitle =
"Intercept";
214 std::string interceptSubDir =
"Intercept";
216 std::string chi2DataName =
"chi2";
217 std::string chi2DataTitle =
"Chi^2/ndf for gain slope fit";
218 std::string chi2SubDir =
"Chi2";
220 std::string deadDataName =
"dead";
221 std::string deadDataTitle =
"Dead";
222 std::string deadSubDir =
"Dead";
224 std::string fitResDataName =
"fitRes";
225 std::string fitResDataTitle =
"Fit Return Value";
226 std::string fitResSubDir =
"FitResult";
229 std::string newCatName =
"new";
230 std::string newCatTitle =
"New";
232 std::string oldCatName =
"old";
233 std::string oldCatTitle =
"COOL";
235 std::string diffCatName =
"diff";
236 std::string diffCatTitle =
"Difference Between New and COOL";
239 std::string peaktAxisLabel =
"Peaking Time (ns)";
240 std::string peaktDiffAxisLabel =
"Peaking Time Difference (ns)";
241 int peaktNumBins = 100;
242 float peaktLowBound = 0;
243 float peaktHighBound = 100;
245 std::string slopeAxisLabel =
"Gain (fC/ADC)";
246 std::string slopeDiffAxisLabel =
"Gain Difference (fC/ADC)";
247 int slopeNumBins =300;
248 float slopeLowBound = 0;
249 float slopeHighBound = 5;
251 std::string slopeRatioAxisLabel =
"Ratio of N/(N+1) channel";
252 int slopeRatioNumBins = 500;
253 float slopeRatioLowBound = 0;
254 float slopeRatioHighBound = 5;
256 std::string interceptAxisLabel =
"Intercept (ADC counts)";
257 int interceptNumBins = 200;
258 float interceptLowBound = -100;
259 float interceptHighBound = 100;
261 std::string chi2AxisLabel =
"Chi^2/ndf";
262 int chi2NumBins = 1000;
263 float chi2LowBound = 0;
264 float chi2HighBound = 3000;
266 std::string deadAxisLabel =
"Is Dead";
268 float deadLowBound = -1.5;
269 float deadHighBound = 1.5;
271 std::string fitResAxisLabel =
"Fit Return Value";
272 int fitResNumBins =10000;
273 float fitResLowBound = 0;
274 float fitResHighBound = 10000;
318 newCatTitle, peaktAxisLabel, peaktNumBins, peaktLowBound, peaktHighBound, peaktSubDir) );
322 peaktAxisLabel, peaktNumBins, peaktLowBound, peaktHighBound, peaktSubDir) );
326 peaktDiffAxisLabel, peaktNumBins, peaktLowBound, peaktHighBound, peaktSubDir) );
330 newCatTitle, slopeAxisLabel, slopeNumBins, slopeLowBound, slopeHighBound, slopeSubDir) );
334 "", slopeRatioAxisLabel, slopeRatioNumBins, slopeRatioLowBound, slopeRatioHighBound, slopeRatioSubDir) );
338 slopeAxisLabel, slopeNumBins, slopeLowBound, slopeHighBound, slopeSubDir) );
342 slopeDiffAxisLabel, slopeNumBins, slopeLowBound, slopeHighBound, slopeSubDir) );
346 "", interceptAxisLabel, interceptNumBins, interceptLowBound, interceptHighBound,
350 chi2AxisLabel, chi2NumBins, chi2LowBound, chi2HighBound, chi2SubDir) );
353 deadAxisLabel, deadNumBins, deadLowBound, deadHighBound, deadSubDir) );
356 fitResAxisLabel, fitResNumBins, fitResLowBound, fitResHighBound, fitResSubDir) );
359 return StatusCode::SUCCESS;
376 ATH_MSG_DEBUG(
"CscCalibMonToolSlope : in handleParameter()" );
439 simpleSet.
diffs = nullptr ;
446 ATH_MSG_INFO(
"CscCalibMonToolSlope : Did not recognize parameter name "
447 <<
parName <<
". This is usually ok." );
448 return StatusCode::FAILURE;
483 return StatusCode::SUCCESS;
490 ATH_MSG_DEBUG(
"CscCalibMonToolSlope : in retrieveHistos()" );
502 ATH_MSG_ERROR(
" Cannot retrieve object from storegate with key "
503 <<
m_histKey <<
" aborting retrieving hists " );
504 return StatusCode::RECOVERABLE;
506 if(repCont->
size() != 1)
509 <<
" does not have a size of one. Do not know how to proceed, so aborting"
510 <<
" retrieving calibration histograms." );
511 return StatusCode::RECOVERABLE;
519 <<
". Aborting retrieving histograms." );
520 return StatusCode::RECOVERABLE;
522 if(slopeReport->
getLabel() !=
"calGraphs")
525 <<
". Aborting hist retrieval" );
526 return StatusCode::RECOVERABLE;
530 const std::map <int,TProfile*> * ampProfs = slopeReport->
getAmpProfs();
533 ATH_MSG_ERROR(
"There are no amplitude profiles in the slope report! Can't find dead chans." );
534 return StatusCode::RECOVERABLE;
538 for(
const auto & [attenuationVal, pProfile] : *ampProfs){
540 const float atten = attenuationVal * 0.5f;
550 std::string dataName =
"amp_atten" + attenStr;
551 std::string dataTitle =
"ADC response at attenuation " + attenStr +
" db" ;
552 std::string axisLabel =
"ADC";
553 unsigned int numBins = 300;
556 std::string subDir =
"AmpAtten" + attenStr;
559 for(
unsigned int stripHash = 0; stripHash <
m_maxHashId; stripHash++){
560 ampColl->
data[stripHash] = pProfile->GetBinContent(stripHash +1);
568 const std::vector<float> * fitResVec = slopeReport->
getFitResults();
573 ATH_MSG_DEBUG(
"About to generate fractional deviation graphs" );
575 ATH_MSG_WARNING(
"Failed to generate fractional deviation graphs. Continuing anyway.." );
586 ATH_MSG_DEBUG(
"Picking detailed graphs to output to root file" );
594 <<
". Aborting hist retrieval." );
595 return StatusCode::RECOVERABLE;
602 ATH_MSG_INFO(
"No bit histogram vector found from calibration. "
603 <<
" Won't be in monitoring output file. " );
609 for(
unsigned int idItr = 0; idItr <
m_maxHashId; idItr++)
618 int stationSize =
m_idHelperSvc->cscIdHelper().stationName(chanId);
621 int wireLayer =
m_idHelperSvc->cscIdHelper().wireLayer(chanId);
622 int measuresPhi =
m_idHelperSvc->cscIdHelper().measuresPhi(chanId);
627 std::string calGraphPath =
getFullPath(geoPath,
"CalGraphs",
"");
628 std::string fracPath =
getFullPath(geoPath,
"FracProf",
"");
629 std::string bitHistPath =
getFullPath(geoPath,
"BitHists",
"");
632 TGraphErrors * sourceGraph =
633 const_cast<TGraphErrors*
>((*calGraphs)[idItr]);
637 << idItr <<
" doesn't exist in CscCalibReport object!" );
640 std::stringstream
name;
643 <<
"_sector_" << sector
644 <<
"_layer_" << wireLayer
645 <<
"_" << (measuresPhi ?
"trans" :
"prec")
647 << std::setfill (
'0') << std::setw (measuresPhi ? 2 : 3)
650 sourceGraph->SetName(
name.str().c_str());
651 ATH_MSG_DEBUG(
"CalGraph axis title: " << sourceGraph->GetXaxis()->GetTitle() );
660 ATH_MSG_ERROR(
"There is no fractional profile available for hash "
661 << idItr <<
". Quitting retrieveHistos()." );
664 std::stringstream fracName;
667 <<
"_sector_" << sector
668 <<
"_layer_" << wireLayer
669 <<
"_" << (measuresPhi ?
"trans" :
"prec")
671 << std::setfill (
'0') << std::setw (measuresPhi ? 2 : 3)
674 sourceProf->SetName(fracName.str().c_str());
683 TH1I * bitHist =
const_cast<TH1I*
>((*bitHists)[idItr]);
687 << idItr <<
" Quiting out of detailed histogram loop." );
691 std::stringstream name2;
694 <<
"_sector_" << sector
695 <<
"_layer_" << wireLayer
696 <<
"_" << (measuresPhi ?
"trans" :
"prec")
698 << std::setfill (
'0') << std::setw (measuresPhi ? 2 : 3)
701 bitHist->SetName(name2.str().c_str());
714 return StatusCode::SUCCESS;
720 ATH_MSG_DEBUG(
"CscCalibMonToolSlope : in makeFracGraphs()" );
724 ATH_MSG_ERROR(
"No calGraphs in slopeReport. Not going to make fractional deviation"
726 return StatusCode::RECOVERABLE;
730 const std::vector <Identifier> &
ids =
m_idHelperSvc->cscIdHelper().idVector();
731 for(
const auto & thisChamberId:
ids)
734 unsigned int stationSize =
m_idHelperSvc->cscIdHelper().stationName(thisChamberId);
739 std::vector <Identifier> stripVect;
740 m_idHelperSvc->cscIdHelper().idChannels(thisChamberId,stripVect);
741 for(
const auto & thisStrip : stripVect)
745 m_idHelperSvc->cscIdHelper().get_channel_hash(thisStrip,stripHash);
752 const TGraphErrors * graph = (*calGraphs)[stripHash];
759 TF1 * func = graph->GetFunction(
"simpleFunc");
761 ATH_MSG_DEBUG(
"Could not retrieve function, skipping this graph" );
769 int nPoints = graph->GetN();
781 std::stringstream nameStream;
782 nameStream.setf(std::ios::right,std::ios::adjustfield);
786 <<
"_sector_" << std::setw (2) << std::setfill (
'0') << sector
787 <<
"_layer_" <<
layer
788 <<
"_strip_" <<
strip;
789 std::stringstream titleStream;
790 titleStream <<
"Fractional Deviation of Measured ADC From Fit ADC for Precision Direction"
791 <<
", Sector " << sector
793 <<
", Layer " <<
layer
794 <<
", Strip " <<
strip;
796 =
new TProfile(nameStream.str().c_str(), titleStream.str().c_str(), nPoints,
798 fracProf->GetXaxis()->SetTitle(
"Pulser Attenuator Settings in dB (not auscaled axis) ");
799 fracProf->GetYaxis()->SetTitle(
"ADC response");
802 float intercept = func->GetParameter(0);
803 float slope = func->GetParameter(1);
808 double adc,
db, calcAdc;
810 for(
int itr = 0; itr < nPoints; itr++)
815 graph->GetPoint(itr,
db,
adc);
816 calcAdc = intercept + slope*
std::pow(10,
db/-20);
817 double frac = (
adc - calcAdc)/( calcAdc - intercept);
831 fracProf->Fill(itr +1,
frac);
836 std::stringstream binLabel;
838 fracProf->GetXaxis()->SetBinLabel(itr+1, binLabel.str().c_str());
844 ATH_MSG_ERROR(
"Tried to assign fracProf with stripHash " << stripHash
846 return StatusCode::RECOVERABLE;
864 return StatusCode::SUCCESS;
876 std::set <int> newDead, newUndead;
881 ATH_MSG_ERROR(
"No pulsed chambers stored in slopeReport! Skipping dead channel collecting!" );
882 return StatusCode::RECOVERABLE;
885 const std::map <int,TProfile*> * ampProfs = slopeReport.
getAmpProfs();
888 ATH_MSG_ERROR(
"There are no amplitude profiles in the slope report! Can't find dead chans." );
889 return StatusCode::RECOVERABLE;
892 std::map <int,TProfile*>::const_iterator profItr = ampProfs->begin();
894 int pulserLevel = profItr->first;
895 ATH_MSG_INFO(
"Looking for dead channels. Lowest attenuation level is "
902 const TProfile * ampProf = profItr->second;
905 ATH_MSG_ERROR(
"There is no profile for this attenuation level! Skipping dead channel finding!" );
906 return StatusCode::RECOVERABLE;
910 <<
" chambers pulsed." );
922 bool wasDead, isDead;
924 for(
unsigned int hashItr = 0; hashItr <=
m_maxHashId ; hashItr++)
927 m_idHelperSvc->cscIdHelper().get_id(hashItr,
id, &channelContext);
928 int chamberLayer =
m_idHelperSvc->cscIdHelper().chamberLayer(
id);
930 m_idHelperSvc->cscIdHelper().get_module_hash(
id, chamberHash);
932 if(chamberLayer == 2 && pulsedChambers->count((
int)chamberHash))
935 ATH_CHECK(readCdo->readChannelStatus(hashItr, statusWord));
937 wasDead = statusWord & 0x1;
939 adc = ampProf->GetBinContent( hashItr + 1 );
942 if(isDead && !wasDead)
945 newDead.insert(hashItr);
947 diffDeadVals[hashItr] = 1;
950 if(!isDead && wasDead)
952 ATH_MSG_INFO(
"PREVIOUSLY DEAD CHANNEL NOW LIVE! Hash: " << hashItr );
953 newUndead.insert(hashItr);
955 diffDeadVals[hashItr] = -1;
961 currentDeadVals[hashItr] = 1;
979 if(newDead.size() || newUndead.size())
982 <<
" newly dead channels and " << newUndead.size()
983 <<
" newly live channels" );
984 std::ofstream
out(
"deadInfo.cal");
985 out <<
"00-00 " << newDead.size() + newUndead.size() <<
" dead_stat END_HEADER\n";
987 for(
const auto & thisDeadChannel:newDead)
990 m_idHelperSvc->cscIdHelper().get_id(thisDeadChannel,
id, &channelContext);
993 out << thisDeadChannel <<
" " << (
int)chamHash <<
" "
994 <<
m_idHelperSvc->cscIdHelper().show_to_string(
id, &channelContext) <<
" 1\n";
997 for(
const auto undeadChannel : newUndead)
1000 m_idHelperSvc->cscIdHelper().get_id(undeadChannel,
id, &channelContext);
1003 out << undeadChannel <<
" " << (
int)chamHash <<
" "
1004 <<
m_idHelperSvc->cscIdHelper().show_to_string(
id, &channelContext)
1013 ATH_MSG_ERROR(
"Lowest pulser level isn't low enough to count as a dead channel test. Skipping." );
1014 return StatusCode::RECOVERABLE;
1018 return StatusCode::SUCCESS;
1024 for(
int i = 0 ;
i < numEntries;
i++)
1033 <<
") vectors have different numbers of entries!" );