6 #include "GaudiKernel/IToolSvc.h"
7 #include "GaudiKernel/MsgStream.h"
8 #include "GaudiKernel/Service.h"
9 #include "GaudiKernel/ThreadLocalContext.h"
28 #include "TObjString.h"
30 #include "TGraphErrors.h"
36 const IInterface* pParent)
40 , m_cablingSvc(
"TileCablingSvc",
name)
42 , m_scanMapRMS(nullptr)
45 declareInterface<ITileCalibTool>(
this);
120 std::vector<int>
v = { 0x10d };
131 std::ostringstream
os;
133 os <<
" 0x" << std::hex <<
fragID << std::dec;
136 ATH_MSG_INFO(
"Special settings in histograms for demonstrator modules (frag IDs):" <<
os.str());
186 return StatusCode::SUCCESS;
192 return StatusCode::SUCCESS;
200 const EventContext& ctx = Gaudi::Hive::currentContext();
208 int cap_ind = (cap > 10) ? 0 : 1;
210 for (
int i=0;
i<4; ++
i)
220 if (cispar[6] == 120) {
236 for (; itColl != itCollEnd; ++itColl) {
238 int fragId = (*itColl)->identify();
240 int gain_offset = (demonstrator) ? 2 : 0;
241 double charge = chargeAll[cap_ind+gain_offset];
244 it = (*itColl)->begin();
245 itEnd = (*itColl)->end();
247 for (;
it != itEnd; ++
it) {
269 if (NEvtDacMap ==
nullptr) {
279 double amp = (*it)->amplitude();
287 <<
" channel: " <<
chan
289 <<
" due to DQ error found." );
291 (*NDigitalErrorsDacMap)[
dac] += 1;
297 (*NEvtDacMap)[
dac] += 1;
298 (*MeanDacMap)[
dac] += amp;
299 (*MeanSqDacMap)[
dac] += amp*amp;
318 for (; digItColl != digItCollEnd; ++digItColl) {
323 if (digIt != digItEnd) {
325 int fragId = (*digItColl)->identify();
327 int gain_offset = (demonstrator) ? 2 : 0;
328 double charge = chargeAll[cap_ind+gain_offset];
335 int numSamples = (*digIt)->NtimeSamples();
336 if (numSamples != 7) {
341 for (; digIt != digItEnd; ++digIt) {
343 adc_id = (*digIt)->adc_HWID();
347 std::vector<float> theDigits = (*digIt)->samples();
356 for(
unsigned int sampNum = 0; sampNum < theDigits.size(); sampNum++) {
361 int quotient = theDigits[sampNum];
365 if((quotient % 2) == 1) {
370 quotient = quotient / 2;
377 std::vector<float> theDigits = (*digIt)->samples();
378 float maxSampVal = -1.;
381 for (
unsigned int sampNum = 0; sampNum < theDigits.size(); sampNum++) {
382 if (theDigits[sampNum] > maxSampVal) {
383 maxSampVal = theDigits[sampNum];
384 maxSampNum = sampNum + 1;
388 if (maxSampNum == 1 || maxSampNum == 7) {
390 }
else if (maxSampNum == 2 || maxSampNum == 6) {
402 return StatusCode::SUCCESS;
413 meanCalib[0] = 1.295;
414 meanCalib[1] = 81.454;
416 meanCalib[2] = 1.26282;
417 meanCalib[3] = 40.9303;
436 int nevt, ndigerr = 0;
439 double maxPointInFitRange;
442 TF1 *fslope =
new TF1(
"fslope",
"[0]*x", 0, 1000);
452 for (; adcIter != adcIterE; ++adcIter) {
453 hwid = (adcIter)->
first;
454 MeanDacMap = (adcIter)->
second;
466 int gain_offset = (demonstrator) ? 2 : 0;
467 int gain_ind =
gain + gain_offset;
470 double prevMean = 0.0, deltaMean = 0.0, averSlope = 0.0;
471 double prevCharge = 0.0, deltaCharge = 0.0, deltaChargeMin = 999999.;
472 double prevSlope = 0.0, slope = 0.0, maxGoodAmp=0.0, minGoodAmp = 999999.;
473 double maxGoodCharge =
m_linfitMax[gain_ind], minGoodCharge = 999999.;
474 double maxCharge = 0.0, minCharge = 999999., maxAmp = 0.0, minAmp = 999999.;
475 bool signalInRange =
true;
479 npt = MeanDacMap->size();
481 gr =
new TGraphErrors(npt);
482 grrms =
new TGraphErrors(npt);
501 maxPointInFitRange = 0.0;
503 for (; dacIter != dacIterE; ++dacIter) {
506 meansq = (*MeanSqDacMap)[
dac];
507 nevt = (*NEvtDacMap)[
dac];
508 ndigerr = (*NDigitalErrorsDacMap)[
dac];
512 meansq = meansq / nevt;
514 rms = (meansq <= mean2) ? 0. : sqrt(meansq - mean2);
515 err = sqrt(
rms *
rms / nevt + 0.5 * 0.5);
527 deltaMean =
mean - prevMean;
528 deltaCharge =
charge - prevCharge;
529 if (deltaCharge != 0) {
530 slope = deltaMean / deltaCharge;
531 if (deltaCharge<deltaChargeMin) deltaChargeMin = deltaCharge;
537 signalInRange =
false;
543 <<
" => Ignoring this point ");
545 if (prevSlope != 0) {
546 double R = std::abs(slope/prevSlope);
547 double R1 = (nptGood>1) ? (slope / averSlope) : 1.;
548 if (
R<0.025 || (nptGood>2 && R1>2.5 &&
R>2.5) || (nptGood==2 && R1>4.1) ) {
555 <<
" dC " << deltaCharge
556 <<
" dA " << deltaMean
557 <<
" expected dA " << prevSlope*deltaCharge
558 <<
" aver dA " << averSlope*deltaCharge
560 <<
" => Removing this point ");
567 if (
mean>maxGoodAmp) maxGoodAmp =
mean;
568 if (
mean<minGoodAmp) minGoodAmp =
mean;
576 averSlope += (slope - averSlope) / nptGood;
586 if (
rms < 0.01) badPts++;
587 if (
mean > maxPointInFitRange) maxPointInFitRange =
mean;
588 if (
rms > maxRMS) maxRMS =
rms;
593 if (prevSlope !=0 ) {
594 double R = slope / prevSlope;
595 if (
R>0.4 &&
R<2.5) {
598 prevSlope = (prevSlope + slope)/2.;
602 if (
R>0.4 &&
R<2.5) {
606 }
else if (nptGood < 3 && signalInRange && charge >=
m_linfitMax[gain_ind] &&
mean <
m_maxAmp[gain_ind] && prevSlope != 0) {
607 double R = slope/prevSlope;
608 if (
R>0.9 &&
R<1.1) {
617 gr->SetPointError(
pt, 0.0,
err);
620 grrms->SetPointError(
pt, 0.0,
rms);
626 for (
int i=npt-1;
i>=
pt; --
i)
629 slope = (prevMean > 0 && prevCharge > 0) ? prevMean/prevCharge :
m_defaultCalib[gain_ind];
630 fslope->SetParameter(0, slope);
635 <<
" up to " << maxGoodCharge
636 <<
" pC; N good points " << nptGood);
639 if (deltaChargeMin>999.) deltaChargeMin = 0.1;
640 else deltaChargeMin *= 0.5;
641 gr->Fit(
"fslope",
"q",
"", minGoodCharge-deltaChargeMin, maxGoodCharge+deltaChargeMin);
645 <<
" minC " << minGoodCharge
646 <<
" maxC " << maxGoodCharge
647 <<
" deltaC " << deltaChargeMin*2
648 <<
" minA " << minGoodAmp
649 <<
" maxA " << maxGoodAmp
650 <<
" nptG " << nptGood
651 <<
" slope " << slope
652 <<
" fit " << fslope->GetParameter(0));
654 const char * bms[3] = {
"No good points to fit ",
655 "Only one point to fit ",
656 "Only two points to fit "};
657 const char * ems[3] = {
" => Put zero slope",
665 <<
" slope " << slope
666 <<
" fit " << fslope->GetParameter(0)
669 slope = (nptGood > 0) ? fslope->GetParameter(0) : 0.;
672 if (maxGoodCharge > minGoodCharge) {
673 averSlope = (maxGoodAmp-minGoodAmp)/(maxGoodCharge-minGoodCharge);
674 if (slope > 2.5 * averSlope) {
680 <<
" avslope " << averSlope
682 <<
" => Put zero slope");
685 }
else if (maxCharge > minCharge) {
686 averSlope = (maxAmp-minAmp)/(maxCharge-minCharge);
687 if (slope > 10. * averSlope) {
693 <<
" AVslope " << averSlope
695 <<
" => Put zero slope");
709 if (fslope->GetNDF() == 0)
715 if (TMath::Prob(fslope->GetChisquare(), fslope->GetNDF()) > 2.e-6) {
733 ratio = (slope / meanCalib[gain_ind]);
738 if (maxPointInFitRange > 600) {
799 return StatusCode::SUCCESS;
806 TTree *
t =
new TTree(
m_ntupleID.c_str(),
"TileCalib-Ntuple");
807 t->Branch(
"RunNumber", &
runNumber,
"runNo/I");
808 t->Branch(
"calib", *
m_calib,
"calib[5][64][48][2]/F");
809 t->Branch(
"qflag", *
m_qflag,
"qflag[5][64][48][2]/I");
810 t->Branch(
"nDAC", *
m_nDAC,
"nDAC[5][64][48][2]/I");
811 t->Branch(
"nDigitalErrors", *
m_nDigitalErrors,
"nDigitalErrors[5][64][48][2]/I");
812 t->Branch(
"chi2", *
m_chi2,
"chi2[5][64][48][2]/F");
813 t->Branch(
"BitStatus", *
m_bitStatus,
"BitStatus[5][64][48][2][4]/s");
817 ATH_MSG_WARNING(
"Impossible to get ITileStuckBitsProbsTool and stuck bits probabilities!");
828 m_scanMap->Write(
"cisScans", TObject::kSingleKey);
829 m_scanMapRMS->Write(
"cisScansRMS", TObject::kSingleKey);
831 return StatusCode::SUCCESS;
838 return StatusCode::SUCCESS;