14 #include "GaudiKernel/IToolSvc.h"
15 #include "GaudiKernel/MsgStream.h"
16 #include "GaudiKernel/Service.h"
17 #include "GaudiKernel/ThreadLocalContext.h"
26 #include "TObjString.h"
28 #include "TGraphErrors.h"
34 const IInterface* pParent)
38 , m_cablingSvc(
"TileCablingSvc",
name)
40 , m_scanMapRMS(nullptr)
43 declareInterface<ITileCalibTool>(
this);
127 std::ostringstream
os;
129 os <<
" 0x" << std::hex <<
fragID << std::dec;
132 ATH_MSG_INFO(
"Special settings in histograms for demonstrator modules (frag IDs):" <<
os.str());
182 return StatusCode::SUCCESS;
188 return StatusCode::SUCCESS;
196 const EventContext& ctx = Gaudi::Hive::currentContext();
204 int cap_ind = (cap > 10) ? 0 : 1;
206 for (
int i=0;
i<4; ++
i)
216 if (cispar[6] == 120) {
232 for (; itColl != itCollEnd; ++itColl) {
234 int fragId = (*itColl)->identify();
236 int gain_offset = (demonstrator) ? 2 : 0;
237 double charge = chargeAll[cap_ind+gain_offset];
240 it = (*itColl)->begin();
241 itEnd = (*itColl)->end();
243 for (;
it != itEnd; ++
it) {
265 if (NEvtDacMap ==
nullptr) {
275 double amp = (*it)->amplitude();
283 <<
" channel: " <<
chan
285 <<
" due to DQ error found." );
287 (*NDigitalErrorsDacMap)[
dac] += 1;
293 (*NEvtDacMap)[
dac] += 1;
294 (*MeanDacMap)[
dac] += amp;
295 (*MeanSqDacMap)[
dac] += amp*amp;
314 for (; digItColl != digItCollEnd; ++digItColl) {
319 if (digIt != digItEnd) {
321 int fragId = (*digItColl)->identify();
323 int gain_offset = (demonstrator) ? 2 : 0;
324 double charge = chargeAll[cap_ind+gain_offset];
331 int numSamples = (*digIt)->NtimeSamples();
332 if (numSamples != 7) {
337 for (; digIt != digItEnd; ++digIt) {
339 adc_id = (*digIt)->adc_HWID();
343 std::vector<float> theDigits = (*digIt)->samples();
352 for(
unsigned int sampNum = 0; sampNum < theDigits.size(); sampNum++) {
357 int quotient = theDigits[sampNum];
361 if((quotient % 2) == 1) {
366 quotient = quotient / 2;
373 std::vector<float> theDigits = (*digIt)->samples();
374 float maxSampVal = -1.;
377 for (
unsigned int sampNum = 0; sampNum < theDigits.size(); sampNum++) {
378 if (theDigits[sampNum] > maxSampVal) {
379 maxSampVal = theDigits[sampNum];
380 maxSampNum = sampNum + 1;
384 if (maxSampNum == 1 || maxSampNum == 7) {
386 }
else if (maxSampNum == 2 || maxSampNum == 6) {
398 return StatusCode::SUCCESS;
409 meanCalib[0] = 1.295;
410 meanCalib[1] = 81.454;
412 meanCalib[2] = 1.26282;
413 meanCalib[3] = 40.9303;
432 int nevt, ndigerr = 0;
435 double maxPointInFitRange;
438 TF1 *fslope =
new TF1(
"fslope",
"[0]*x", 0, 1000);
448 for (; adcIter != adcIterE; ++adcIter) {
449 hwid = (adcIter)->
first;
450 MeanDacMap = (adcIter)->
second;
462 int gain_offset = (demonstrator) ? 2 : 0;
463 int gain_ind =
gain + gain_offset;
466 double prevMean = 0.0, deltaMean = 0.0, averSlope = 0.0;
467 double prevCharge = 0.0, deltaCharge = 0.0, deltaChargeMin = 999999.;
468 double prevSlope = 0.0, slope = 0.0, maxGoodAmp=0.0, minGoodAmp = 999999.;
469 double maxGoodCharge =
m_linfitMax[gain_ind], minGoodCharge = 999999.;
470 double maxCharge = 0.0, minCharge = 999999., maxAmp = 0.0, minAmp = 999999.;
471 bool signalInRange =
true;
475 npt = MeanDacMap->size();
477 gr =
new TGraphErrors(npt);
478 grrms =
new TGraphErrors(npt);
497 maxPointInFitRange = 0.0;
499 for (; dacIter != dacIterE; ++dacIter) {
502 meansq = (*MeanSqDacMap)[
dac];
503 nevt = (*NEvtDacMap)[
dac];
504 ndigerr = (*NDigitalErrorsDacMap)[
dac];
508 meansq = meansq / nevt;
510 rms = (meansq <= mean2) ? 0. : sqrt(meansq - mean2);
511 err = sqrt(
rms *
rms / nevt + 0.5 * 0.5);
523 deltaMean =
mean - prevMean;
524 deltaCharge =
charge - prevCharge;
525 if (deltaCharge != 0) {
526 slope = deltaMean / deltaCharge;
527 if (deltaCharge<deltaChargeMin) deltaChargeMin = deltaCharge;
533 signalInRange =
false;
539 <<
" => Ignoring this point ");
541 if (prevSlope != 0) {
542 double R = std::abs(slope/prevSlope);
543 double R1 = (nptGood>1) ? (slope / averSlope) : 1.;
544 if (
R<0.025 || (nptGood>2 && R1>2.5 &&
R>2.5) || (nptGood==2 && R1>4.1) ) {
551 <<
" dC " << deltaCharge
552 <<
" dA " << deltaMean
553 <<
" expected dA " << prevSlope*deltaCharge
554 <<
" aver dA " << averSlope*deltaCharge
556 <<
" => Removing this point ");
563 if (
mean>maxGoodAmp) maxGoodAmp =
mean;
564 if (
mean<minGoodAmp) minGoodAmp =
mean;
572 averSlope += (slope - averSlope) / nptGood;
582 if (
rms < 0.01) badPts++;
583 if (
mean > maxPointInFitRange) maxPointInFitRange =
mean;
584 if (
rms > maxRMS) maxRMS =
rms;
589 if (prevSlope !=0 ) {
590 double R = slope / prevSlope;
591 if (
R>0.4 &&
R<2.5) {
594 prevSlope = (prevSlope + slope)/2.;
598 if (
R>0.4 &&
R<2.5) {
602 }
else if (nptGood < 3 && signalInRange && charge >=
m_linfitMax[gain_ind] &&
mean <
m_maxAmp[gain_ind] && prevSlope != 0) {
603 double R = slope/prevSlope;
604 if (
R>0.9 &&
R<1.1) {
613 gr->SetPointError(
pt, 0.0,
err);
616 grrms->SetPointError(
pt, 0.0,
rms);
622 for (
int i=npt-1;
i>=
pt; --
i)
625 slope = (prevMean > 0 && prevCharge > 0) ? prevMean/prevCharge :
m_defaultCalib[gain_ind];
626 fslope->SetParameter(0, slope);
631 <<
" up to " << maxGoodCharge
632 <<
" pC; N good points " << nptGood);
635 if (deltaChargeMin>999.) deltaChargeMin = 0.1;
636 else deltaChargeMin *= 0.5;
637 gr->Fit(
"fslope",
"q",
"", minGoodCharge-deltaChargeMin, maxGoodCharge+deltaChargeMin);
641 <<
" minC " << minGoodCharge
642 <<
" maxC " << maxGoodCharge
643 <<
" deltaC " << deltaChargeMin*2
644 <<
" minA " << minGoodAmp
645 <<
" maxA " << maxGoodAmp
646 <<
" nptG " << nptGood
647 <<
" slope " << slope
648 <<
" fit " << fslope->GetParameter(0));
650 const char * bms[3] = {
"No good points to fit ",
651 "Only one point to fit ",
652 "Only two points to fit "};
653 const char * ems[3] = {
" => Put zero slope",
661 <<
" slope " << slope
662 <<
" fit " << fslope->GetParameter(0)
665 slope = (nptGood > 0) ? fslope->GetParameter(0) : 0.;
668 if (maxGoodCharge > minGoodCharge) {
669 averSlope = (maxGoodAmp-minGoodAmp)/(maxGoodCharge-minGoodCharge);
670 if (slope > 2.5 * averSlope) {
676 <<
" avslope " << averSlope
678 <<
" => Put zero slope");
681 }
else if (maxCharge > minCharge) {
682 averSlope = (maxAmp-minAmp)/(maxCharge-minCharge);
683 if (slope > 10. * averSlope) {
689 <<
" AVslope " << averSlope
691 <<
" => Put zero slope");
705 if (fslope->GetNDF() == 0)
711 if (TMath::Prob(fslope->GetChisquare(), fslope->GetNDF()) > 2.e-6) {
729 ratio = (slope / meanCalib[gain_ind]);
734 if (maxPointInFitRange > 600) {
795 return StatusCode::SUCCESS;
802 TTree *
t =
new TTree(
m_ntupleID.c_str(),
"TileCalib-Ntuple");
803 t->Branch(
"RunNumber", &
runNumber,
"runNo/I");
804 t->Branch(
"calib", *
m_calib,
"calib[5][64][48][2]/F");
805 t->Branch(
"qflag", *
m_qflag,
"qflag[5][64][48][2]/I");
806 t->Branch(
"nDAC", *
m_nDAC,
"nDAC[5][64][48][2]/I");
807 t->Branch(
"nDigitalErrors", *
m_nDigitalErrors,
"nDigitalErrors[5][64][48][2]/I");
808 t->Branch(
"chi2", *
m_chi2,
"chi2[5][64][48][2]/F");
809 t->Branch(
"BitStatus", *
m_bitStatus,
"BitStatus[5][64][48][2][4]/s");
813 ATH_MSG_WARNING(
"Impossible to get ITileStuckBitsProbsTool and stuck bits probabilities!");
824 m_scanMap->Write(
"cisScans", TObject::kSingleKey);
825 m_scanMapRMS->Write(
"cisScansRMS", TObject::kSingleKey);
827 return StatusCode::SUCCESS;
834 return StatusCode::SUCCESS;