12 #include <top/modules/TOPGainEfficiencyMonitor/TOPLaserHitSelectorModule.h>
15 #include <framework/datastore/StoreArray.h>
18 #include <top/dataobjects/TOPDigit.h>
49 setDescription(
"TOP pixel-by-pixel gain analysis - first step : create hit timing-pulse charge histogram");
52 m_timeHistogramBinning.push_back(140);
53 m_timeHistogramBinning.push_back(-55);
54 m_timeHistogramBinning.push_back(15);
55 m_chargeHistogramBinning.push_back(125);
56 m_chargeHistogramBinning.push_back(-50);
57 m_chargeHistogramBinning.push_back(2450);
58 m_chargeHistogramBinning.push_back(150);
59 m_chargeHistogramBinning.push_back(-500);
60 m_chargeHistogramBinning.push_back(29500);
62 addParam(
"timeHistogramBinning", m_timeHistogramBinning,
63 "histogram binning (the number of bins, lower limit, upper limit) for hit timing distribution (should be integer value)",
64 m_timeHistogramBinning);
65 addParam(
"chargeHistogramBinning", m_chargeHistogramBinning,
66 "histogram binning (the number of bins, lower limit, upper limit) for pulse charge distribution (should be integer value)",
67 m_chargeHistogramBinning);
71 addParam(
"useDoublePulse", m_useDoublePulse,
72 "set true when you require both of double calibration pulses for reference timing. You need to enable offline feature extraction.",
74 addParam(
"minHeightFirstCalPulse", m_calibrationPulseThreshold1,
"pulse height threshold for the first cal. pulse",
76 addParam(
"minHeightSecondCalPulse", m_calibrationPulseThreshold2,
"pulse height threshold for the second cal. pulse",
78 addParam(
"nominalDeltaT", m_calibrationPulseInterval,
"nominal DeltaT (time interval of the double calibration pulses) [ns]",
80 addParam(
"nominalDeltaTRange", m_calibrationPulseIntervalRange,
81 "acceptable DeltaT range from the nominal value before calibration [ns]",
83 addParam(
"windowSelect", m_windowSelect,
84 "select window number (All=0, Odd=2, Even=1)",
86 addParam(
"includePrimaryChargeShare", m_includePrimaryChargeShare,
87 "set ture when you require without primary chargeshare cut for making 2D histogram",
89 addParam(
"includeAllChargeShare", m_includeAllChargeShare,
90 "set ture when you require without all chargeshare cut for making 2D histogram",
94 TOPLaserHitSelectorModule::~TOPLaserHitSelectorModule() {}
96 void TOPLaserHitSelectorModule::initialize()
104 void TOPLaserHitSelectorModule::defineHisto()
106 for (
int iPixel = 0 ; iPixel < c_NPixelPerModule * c_NModule ; iPixel++) {
108 short slotId = (iPixel / c_NPixelPerModule) + 1;
109 short pixelId = (iPixel % c_NPixelPerModule) + 1;
110 short pmtId = ((pixelId - 1) % c_NPixelPerRow) / c_NChannelPerPMTRow + c_NPMTPerRow * ((pixelId - 1) / (c_NPixelPerModule / 2)) + 1;
111 short pmtChId = (pixelId - 1) % c_NChannelPerPMTRow + c_NChannelPerPMTRow * ((pixelId - 1) %
112 (c_NPixelPerModule / 2) / c_NPixelPerRow) + 1;
114 std::ostringstream pixelstr;
115 pixelstr <<
"s" << std::setw(2) << std::setfill(
'0') << slotId <<
"_PMT"
116 << std::setw(2) << std::setfill(
'0') << pmtId
117 <<
"_" << std::setw(2) << std::setfill(
'0') << pmtChId;
119 std::ostringstream hnameForgain;
120 hnameForgain <<
"hTimeHeight_gain_" << pixelstr.str();
121 std::ostringstream htitleForgain;
122 htitleForgain <<
"2D distribution of hit timing and pulse height for Gain" << pixelstr.str();
123 m_TimeHeightHistogramForFit[iPixel] =
new TH2F(hnameForgain.str().c_str(), htitleForgain.str().c_str(),
124 m_timeHistogramBinning[0], m_timeHistogramBinning[1], m_timeHistogramBinning[2],
125 m_chargeHistogramBinning[0], m_chargeHistogramBinning[1],
126 m_chargeHistogramBinning[2]);
128 std::ostringstream hnameForIntegral;
129 hnameForIntegral <<
"hTimeIntegral_gain_" << pixelstr.str();
130 std::ostringstream htitleForIntegral;
131 htitleForIntegral <<
"2D distribution of hit timing and integral for Gain" << pixelstr.str();
132 m_TimeIntegralHistogramForFit[iPixel] =
new TH2F(hnameForIntegral.str().c_str(), htitleForIntegral.str().c_str(),
133 m_timeHistogramBinning[0], m_timeHistogramBinning[1], m_timeHistogramBinning[2],
134 m_chargeHistogramBinning[3], m_chargeHistogramBinning[4],
135 m_chargeHistogramBinning[5]);
137 std::ostringstream hnameForeff;
138 hnameForeff <<
"hTimeHeight_efficiency_" << pixelstr.str();
139 std::ostringstream htitleForeff;
140 htitleForeff <<
"2D distribution of hit timing and pulse height for efficiency" << pixelstr.str();
141 m_TimeHeightHistogramForHitRate[iPixel] =
new TH2F(hnameForeff.str().c_str(), htitleForeff.str().c_str(),
142 m_timeHistogramBinning[0], m_timeHistogramBinning[1], m_timeHistogramBinning[2],
143 m_chargeHistogramBinning[0], m_chargeHistogramBinning[1],
144 m_chargeHistogramBinning[2]);
147 const short nAsic = c_NPixelPerModule / c_NChannelPerAsic * c_NChannelPerPMT;
148 m_nCalPulseHistogram =
new TH1F(
"hNCalPulse",
"number of calibration pulses identificed for each asic",
149 nAsic, -0.5, nAsic - 0.5);
152 void TOPLaserHitSelectorModule::beginRun()
156 void TOPLaserHitSelectorModule::event()
160 std::map<short, float> refTimingMap;
161 std::map<short, std::vector<hitInfo_t> >
165 for (
const auto& digit : digits) {
167 short slotId = digit.getModuleID();
168 short pixelId = digit.getPixelID();
169 short globalPixelId = (slotId - 1) * c_NPixelPerModule + pixelId - 1;
170 if (digit.getHitQuality() == TOPDigit::c_CalPulse) {
171 calPulsesMap[globalPixelId].push_back((
hitInfo_t) { (float)digit.getTime(), (float)digit.getPulseHeight() });
177 for (
const auto& calPulse : calPulsesMap) {
179 short globalPixelId = calPulse.first;
180 short globalAsicId = globalPixelId / c_NChannelPerAsic;
181 std::vector<hitInfo_t> vec = calPulse.second;
182 double calPulseTiming = 9999999;
183 unsigned nCalPulseCandidates = vec.size();
184 if (!m_useDoublePulse) {
185 double maxPulseHeight = -1;
186 double maxHeightTiming = 9999999;
187 for (
unsigned iVec = 0 ; iVec < nCalPulseCandidates ; iVec++) {
188 if (maxPulseHeight < vec[iVec].m_height) {
189 maxPulseHeight = vec[iVec].m_height;
190 maxHeightTiming = vec[iVec].m_time;
193 if (maxPulseHeight > m_calibrationPulseThreshold1)
194 calPulseTiming = maxHeightTiming;
196 for (
unsigned iVec = 0 ; iVec < nCalPulseCandidates ; iVec++) {
197 for (
unsigned jVec = 0 ; jVec < nCalPulseCandidates ; jVec++) {
199 if (iVec == jVec || vec[iVec].m_time > vec[jVec].m_time)
continue;
200 if (vec[iVec].m_height > m_calibrationPulseThreshold1
201 && vec[jVec].m_height > m_calibrationPulseThreshold2
202 && TMath::Abs(vec[jVec].m_time - vec[iVec].m_time - m_calibrationPulseInterval) < m_calibrationPulseIntervalRange) {
206 if (refTimingMap.count(globalAsicId) == 0 || refTimingMap[globalAsicId] > vec[iVec].m_time)
207 calPulseTiming = vec[iVec].m_time;
213 if (calPulseTiming < 9999998) {
214 refTimingMap[globalAsicId] = calPulseTiming;
215 m_nCalPulseHistogram->Fill(globalAsicId);
220 for (
const auto& digit : digits) {
221 short slotId = digit.getModuleID();
222 short pixelId = digit.getPixelID();
223 short globalPixelId = (slotId - 1) * c_NPixelPerModule + pixelId - 1;
224 short globalAsicId = globalPixelId / c_NChannelPerAsic;
226 if (digit.getHitQuality() == TOPDigit::c_Junk
227 || digit.getHitQuality() == TOPDigit::c_CrossTalk)
continue;
229 float hitTime = digit.getTime() - refTimingMap[globalAsicId];
230 float pulseHeight = digit.getPulseHeight();
231 float Integral = digit.getIntegral();
232 short windowNumberOfHit = (short)(digit.getFirstWindow()) + (
short)(digit.getRawTime() / 64);
233 if (m_windowSelect && windowNumberOfHit % 2 != (m_windowSelect - 1))
continue;
235 if (m_includeAllChargeShare) {
236 m_TimeHeightHistogramForHitRate[globalPixelId]->Fill(hitTime, pulseHeight);
237 m_TimeIntegralHistogramForFit[globalPixelId]->Fill(hitTime, Integral);
238 m_TimeHeightHistogramForFit[globalPixelId]->Fill(hitTime, pulseHeight);
242 if (!digit.isSecondaryChargeShare()) {
243 m_TimeHeightHistogramForHitRate[globalPixelId]->Fill(hitTime, pulseHeight);
244 if (m_includePrimaryChargeShare) {
245 m_TimeIntegralHistogramForFit[globalPixelId]->Fill(hitTime, Integral);
246 m_TimeHeightHistogramForFit[globalPixelId]->Fill(hitTime, pulseHeight);
251 if (digit.isSecondaryChargeShare() || digit.isPrimaryChargeShare())
continue;
252 m_TimeIntegralHistogramForFit[globalPixelId]->Fill(hitTime, Integral);
253 m_TimeHeightHistogramForFit[globalPixelId]->Fill(hitTime, pulseHeight);
258 void TOPLaserHitSelectorModule::endRun()
262 void TOPLaserHitSelectorModule::terminate()