10#include <top/modules/TOPGainEfficiencyMonitor/TOPLaserHitSelectorModule.h>
13#include <framework/datastore/StoreArray.h>
16#include <top/dataobjects/TOPDigit.h>
47 setDescription(
"TOP pixel-by-pixel gain analysis - first step : create hit timing-pulse charge histogram");
61 "histogram binning (the number of bins, lower limit, upper limit) for hit timing distribution (should be integer value)",
64 "histogram binning (the number of bins, lower limit, upper limit) for pulse charge distribution (should be integer value)",
70 "set true when you require both of double calibration pulses for reference timing. You need to enable offline feature extraction.",
79 "acceptable DeltaT range from the nominal value before calibration [ns]",
82 "select window number (All=0, Odd=2, Even=1)",
85 "set ture when you require without primary chargeshare cut for making 2D histogram",
88 "set ture when you require without all chargeshare cut for making 2D histogram",
104 for (
int iPixel = 0 ; iPixel < c_NPixelPerModule * c_NModule ; iPixel++) {
106 short slotId = (iPixel / c_NPixelPerModule) + 1;
107 short pixelId = (iPixel % c_NPixelPerModule) + 1;
108 short pmtId = ((pixelId - 1) % c_NPixelPerRow) / c_NChannelPerPMTRow + c_NPMTPerRow * ((pixelId - 1) / (c_NPixelPerModule / 2)) + 1;
109 short pmtChId = (pixelId - 1) % c_NChannelPerPMTRow + c_NChannelPerPMTRow * ((pixelId - 1) %
110 (c_NPixelPerModule / 2) / c_NPixelPerRow) + 1;
112 std::ostringstream pixelstr;
113 pixelstr <<
"s" << std::setw(2) << std::setfill(
'0') << slotId <<
"_PMT"
114 << std::setw(2) << std::setfill(
'0') << pmtId
115 <<
"_" << std::setw(2) << std::setfill(
'0') << pmtChId;
117 std::ostringstream hnameForgain;
118 hnameForgain <<
"hTimeHeight_gain_" << pixelstr.str();
119 std::ostringstream htitleForgain;
120 htitleForgain <<
"2D distribution of hit timing and pulse height for Gain" << pixelstr.str();
126 std::ostringstream hnameForIntegral;
127 hnameForIntegral <<
"hTimeIntegral_gain_" << pixelstr.str();
128 std::ostringstream htitleForIntegral;
129 htitleForIntegral <<
"2D distribution of hit timing and integral for Gain" << pixelstr.str();
135 std::ostringstream hnameForeff;
136 hnameForeff <<
"hTimeHeight_efficiency_" << pixelstr.str();
137 std::ostringstream htitleForeff;
138 htitleForeff <<
"2D distribution of hit timing and pulse height for efficiency" << pixelstr.str();
145 const short nAsic = c_NPixelPerModule / c_NChannelPerAsic * c_NChannelPerPMT;
146 m_nCalPulseHistogram =
new TH1F(
"hNCalPulse",
"number of calibration pulses identificed for each asic",
147 nAsic, -0.5, nAsic - 0.5);
158 std::map<short, float> refTimingMap;
159 std::map<short, std::vector<hitInfo_t> >
163 for (
const auto& digit : digits) {
165 short slotId = digit.getModuleID();
166 short pixelId = digit.getPixelID();
167 short globalPixelId = (slotId - 1) * c_NPixelPerModule + pixelId - 1;
168 if (digit.getHitQuality() == TOPDigit::c_CalPulse) {
169 calPulsesMap[globalPixelId].push_back((
hitInfo_t) { (float)digit.getTime(), (float)digit.getPulseHeight() });
175 for (
const auto& calPulse : calPulsesMap) {
177 short globalPixelId = calPulse.first;
178 short globalAsicId = globalPixelId / c_NChannelPerAsic;
179 std::vector<hitInfo_t> vec = calPulse.second;
180 double calPulseTiming = 9999999;
181 unsigned nCalPulseCandidates = vec.size();
183 double maxPulseHeight = -1;
184 double maxHeightTiming = 9999999;
185 for (
unsigned iVec = 0 ; iVec < nCalPulseCandidates ; iVec++) {
186 if (maxPulseHeight < vec[iVec].m_height) {
187 maxPulseHeight = vec[iVec].m_height;
188 maxHeightTiming = vec[iVec].m_time;
192 calPulseTiming = maxHeightTiming;
194 for (
unsigned iVec = 0 ; iVec < nCalPulseCandidates ; iVec++) {
195 for (
unsigned jVec = 0 ; jVec < nCalPulseCandidates ; jVec++) {
197 if (iVec == jVec || vec[iVec].m_time > vec[jVec].m_time)
continue;
204 if (refTimingMap.count(globalAsicId) == 0 || refTimingMap[globalAsicId] > vec[iVec].m_time)
205 calPulseTiming = vec[iVec].m_time;
211 if (calPulseTiming < 9999998) {
212 refTimingMap[globalAsicId] = calPulseTiming;
218 for (
const auto& digit : digits) {
219 short slotId = digit.getModuleID();
220 short pixelId = digit.getPixelID();
221 short globalPixelId = (slotId - 1) * c_NPixelPerModule + pixelId - 1;
222 short globalAsicId = globalPixelId / c_NChannelPerAsic;
224 if (digit.getHitQuality() == TOPDigit::c_Junk
225 || digit.getHitQuality() == TOPDigit::c_CrossTalk)
continue;
227 float hitTime = digit.getTime() - refTimingMap[globalAsicId];
228 float pulseHeight = digit.getPulseHeight();
229 float Integral = digit.getIntegral();
230 short windowNumberOfHit = (short)(digit.getFirstWindow()) + (
short)(digit.getRawTime() / 64);
240 if (!digit.isSecondaryChargeShare()) {
249 if (digit.isSecondaryChargeShare() || digit.isPrimaryChargeShare())
continue;
HistoModule.h is supposed to be used instead of Module.h for the modules with histogram definitions t...
void setDescription(const std::string &description)
Sets the description of the module.
Accessor to arrays stored in the data store.
bool m_useDoublePulse
set true when you require both of double calibration pulses for reference timing
float m_calibrationPulseInterval
nominal DeltaT value (time interval of two calibration signals) in a unit of ns
float m_calibrationPulseIntervalRange
tolerable shift of DeltaT from its nominal before calibration in a unit of ns
float m_calibrationPulseThreshold2
minimum pulse height for the secon calibration pulse to be qualified as calibration signals
std::vector< int > m_timeHistogramBinning
histogram binning of hit timing distribution, in the order of number of bins, lower limit,...
TH2F * m_TimeHeightHistogramForFit[c_NPixelPerModule *c_NModule]
array of histogram pointer to 2D histogram of hit timing vs pulse height distribution for each pixel ...
std::vector< int > m_chargeHistogramBinning
histogram binning of pulse height distribution, in the order of number of bins, lower limit,...
bool m_includePrimaryChargeShare
set true when you require without chargeshare cut for making 2D histogram
TH2F * m_TimeHeightHistogramForHitRate[c_NPixelPerModule *c_NModule]
array of histogram pointer to 2D histogram of hit timing vs pulse height distribution for each pixel ...
TH2F * m_TimeIntegralHistogramForFit[c_NPixelPerModule *c_NModule]
array of histogram pointer to 2D histogram of hit timing vs integral distribution for each pixel (all...
float m_calibrationPulseThreshold1
minimum pulse height for the first calibration pulse to be qualified as calibration signals
bool m_includeAllChargeShare
set true when you require without chargeshare cut for making 2D histogram
int m_windowSelect
select window number is [All=0, Odd=2, Even=1]
TH1F * m_nCalPulseHistogram
histogram to store the number of events with calibration pulse(s) identified for each asic (1,...
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
virtual void endRun() override
End-of-run action.
virtual void terminate() override
Termination action.
virtual ~TOPLaserHitSelectorModule()
Destructor.
virtual void beginRun() override
Called when entering a new run.
TOPLaserHitSelectorModule()
Constructor.
virtual void defineHisto() override
create timing-height 2D histograms for all 8192 pixels
Abstract base class for different kinds of events.
structure to hold hit information, used in double cal.