196 const EventContext& ctx = Gaudi::Hive::currentContext();
200 const uint32_t *cispar = theDQstatus->
cispar();
201 uint32_t dac = cispar[6];
202 uint32_t phase = cispar[5];
203 uint32_t cap = cispar[7];
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) {
256 if (theDQstatus->
isChEmpty(ros, drawer, chan))
continue;
265 if (NEvtDacMap ==
nullptr) {
275 double amp = (*it)->amplitude();
278 if ( (amp > 40.) || (gain == 0 && amp > 6.) || (!
m_removePed) ) {
281 if (!(theDQstatus->
isAdcDQgood(ros, drawer, chan, gain))) {
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();
346 if (!(theDQstatus->
isAdcDQgood(ros, drawer, chan, gain))) {
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;
431 double charge,
mean, mean2, meansq, rms, err, ratio;
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;
460 int fragId = (ros << 8) | drawer;
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();
476 m_nDAC[ros][drawer][chan][gain] = npt;
477 gr =
new TGraphErrors(npt);
478 grrms =
new TGraphErrors(npt);
481 m_calib[ros][drawer][chan][gain] = 0;
482 m_chi2[ros][drawer][chan][gain] = 0.0;
484 << ros <<
"/" << drawer <<
"/" << chan <<
"/" << gain );
497 maxPointInFitRange = 0.0;
499 for (; dacIter != dacIterE; ++dacIter) {
500 dac = (dacIter)->first;
501 mean = (dacIter)->second;
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);
514 charge = dac * dac2Charge;
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;
535 << ros <<
"/" << drawer
536 <<
"/" << chan <<
"/" << gain
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) ) {
547 << ros <<
"/" << drawer
548 <<
"/" << chan <<
"/" << gain
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);
629 << ros <<
"/" << drawer
630 <<
"/" << chan <<
"/" << gain
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);
639 << ros <<
"/" << drawer
640 <<
"/" << chan <<
"/" << gain
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",
657 << ros <<
"/" << drawer
658 <<
"/" << chan <<
"/" << gain
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) {
672 << ros <<
"/" << drawer
673 <<
"/" << chan <<
"/" << gain
676 <<
" avslope " << averSlope
678 <<
" => Put zero slope");
681 }
else if (maxCharge > minCharge) {
682 averSlope = (maxAmp-minAmp)/(maxCharge-minCharge);
683 if (slope > 10. * averSlope) {
685 << ros <<
"/" << drawer
686 <<
"/" << chan <<
"/" << gain
689 <<
" AVslope " << averSlope
691 <<
" => Put zero slope");
704 m_calib[ros][drawer][chan][gain] = slope;
705 if (fslope->GetNDF() == 0)
706 m_chi2[ros][drawer][chan][gain] = 0.0;
708 m_chi2[ros][drawer][chan][gain] = fslope->GetChisquare() / fslope->GetNDF();
711 if (TMath::Prob(fslope->GetChisquare(), fslope->GetNDF()) > 2.e-6) {
729 ratio = (slope / meanCalib[gain_ind]);
734 if (maxPointInFitRange > 600) {
762 for(
int i = 0; i <
NBITS; i++) {
771 << ros <<
" " << drawer <<
" " << chan <<
" " << gain <<
" " << i <<
"\n");
779 << ros <<
" " << drawer <<
" " << chan <<
" " << gain <<
" " << i <<
"\n");
789 grrms->SetName(
"scan_" +
arrayString(ros, drawer, chan, gain));
795 return StatusCode::SUCCESS;