10#include <top/modules/TOPXTalkChargeShareSetter/TOPXTalkChargeShareSetterModule.h>
13#include <framework/datastore/StoreArray.h>
16#include <top/dataobjects/TOPRawDigit.h>
17#include <top/dataobjects/TOPRawWaveform.h>
18#include <top/dataobjects/TOPDigit.h>
43 "sum up charge of PrimaryChargeShare and SecondaryChargeShare", (
bool)
false);
45 "cut range of hittiming for chargeshare flag [ns]", (
float) 1);
47 "loose threshold for depth of pre valley [ADC counts], for corss talk identification", 20);
49 "tight threshold for depth of pre valley [ADC counts], identified as cross talk with loose threshold for the second peak amplitude",
52 "loose threshold for amplitude of the second peak [ADC counts] for cross talk identification. Defined as ADC count difference between the valley just after the main peak and the second peak, Used when the \"preValleyDepthTight\" was satisfied",
55 "tight threshold for amplitude ratio of the second peak to the main peak height [ADC counts]", 0.2);
57 "the number of samples by which the pre-valley should exist from the CFD timing, used for cross talk identification."
58 "Set negative value not to check existence of the pre-valley.", 5);
60 "the number of samples by which the second peak should exist from the CFD timing, used for cross talk identification."
61 "Set negative value not to check existence of the second peak.", 10);
86 std::map<int, TOPDigit*> hitInfoMap;
87 for (
auto& digit : digits) {
89 if (digit.getHitQuality() == TOPDigit::c_Junk)
continue;
91 const auto* rawDigit = digit.getRelated<
TOPRawDigit>();
92 if (!rawDigit)
continue;
95 if (waveform and
isCrossTalk(waveform->getWaveform(), TMath::FloorNint(digit.getRawTime()), digit.getPulseHeight()))
96 digit.setHitQuality(TOPDigit::c_CrossTalk);
100 unsigned int channelId = digit.getChannel();
101 double rawTime = digit.getRawTime();
102 for (
auto& digit2 : digits) {
103 if (digit2.getChannel() != channelId || digit2.getModuleID() != slotId)
continue;
104 if (digit2.getHitQuality() == TOPDigit::c_CrossTalk
106 digit.setHitQuality(TOPDigit::c_CrossTalk);
110 if (digit.getHitQuality() == TOPDigit::c_CrossTalk)
continue;
112 int globalPixelId = (digit.getModuleID() - 1) * 512 + digit.getPixelID() - 1;
113 while (hitInfoMap.count(globalPixelId) > 0)globalPixelId += 10000;
114 hitInfoMap[globalPixelId] = &digit;
120 for (
auto& digit : digits) {
122 if (digit.getHitQuality() == TOPDigit::c_Junk
123 || digit.getHitQuality() == TOPDigit::c_CrossTalk)
continue;
125 short pixelId = digit.getPixelID();
126 short slotId = digit.getModuleID();
127 short pmtId = digit.getPMTNumber();
128 double hitTime = digit.getTime();
129 double charge = digit.getIntegral();
130 bool isPrimaryChargeShare =
true;
131 std::vector<TOPDigit*> vSecondaryCandidates;
133 int adjacentPixelIds[] = { pixelId - 1 - c_NPixelsPerRow, pixelId - c_NPixelsPerRow, pixelId + 1 - c_NPixelsPerRow, pixelId + 1,
134 pixelId + 1 + c_NPixelsPerRow, pixelId + c_NPixelsPerRow, pixelId - 1 + c_NPixelsPerRow, pixelId - 1
137 for (
const auto& adjacentPixelId : adjacentPixelIds) {
138 if (adjacentPixelId > 0 && adjacentPixelId <= 512) {
139 int globalPixelId = (slotId - 1) * 512 + adjacentPixelId - 1;
140 while (hitInfoMap.count(globalPixelId) > 0) {
142 if (pmtId != hitInfoMap[globalPixelId]->getPMTNumber()
143 or TMath::Abs(hitTime - hitInfoMap[globalPixelId]->getTime()) >
m_timeCut) {
144 globalPixelId += 10000;
continue;
147 float adjacentIntegral = hitInfoMap[globalPixelId]->getIntegral();
149 if (charge > adjacentIntegral
150 or (charge == adjacentIntegral && pixelId > hitInfoMap[globalPixelId]->getPixelID())) {
151 vSecondaryCandidates.push_back(hitInfoMap[globalPixelId]);
152 hitInfoMap[globalPixelId]->setSecondaryChargeShare();
154 isPrimaryChargeShare =
false;
157 globalPixelId += 10000;
159 if (!isPrimaryChargeShare)
break;
163 if (isPrimaryChargeShare && vSecondaryCandidates.size() > 0) {
164 digit.setPrimaryChargeShare();
167 for (
auto& vSecondaryCandidate : vSecondaryCandidates) {
168 digit.setPulseHeight(digit.getPulseHeight() + vSecondaryCandidate->getPulseHeight());
169 vSecondaryCandidate->setPulseHeight(0.0);
171 digit.setIntegral(digit.getIntegral() + vSecondaryCandidate->getIntegral());
172 vSecondaryCandidate->setIntegral(0.0);
191 int nWfmSampling = wfm.size();
192 for (
int iWin = 0 ; iWin < 16 ; iWin++) {
196 if (jRawTime > 0 && jRawTime < nWfmSampling - 1 && wfm[jRawTime] < height / 2. && wfm[jRawTime + 1] > height / 2.) {
197 bool preValleyExist =
false;
198 short preValleyDepth = -1;
201 for (
int iSample = jRawTime ; iSample - 1 > 0 ; iSample--) {
203 else if (wfm[iSample] - wfm[iSample - 1] >= 0)
continue;
205 preValleyDepth = (-1) * wfm[iSample];
209 preValleyExist =
true;
215 if (!preValleyExist)
return false;
219 short valley_adc = 9999;
220 for (
int jSample = jRawTime ; jSample < nWfmSampling - 1 ; jSample++) {
222 if ((wfm[jSample + 1] - wfm[jSample])*sign > 0)
continue;
224 if (sign < 0 && valley_adc > height + 1)
225 valley_adc = wfm[jSample];
226 if (sign > 0 && valley_adc < height) {
233 sign = (sign > 0 ? -1 : 1);
void setDescription(const std::string &description)
Sets the description of the module.
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
T * getRelated(const std::string &name="", const std::string &namedRelation="") const
Get the object to or from which this object has a relation.
Accessor to arrays stored in the data store.
Class to store unpacked raw data (hits in feature-extraction format) It provides also calculation of ...
@ c_WindowSize
number of samples per window
int m_nSampleAfter
the number of samples by which the second peak should exist from the CFD timing, used for cross talk ...
virtual ~TOPXTalkChargeShareSetterModule() override
destructor
virtual void initialize() override
initialize
double m_nCrossTalkRingingSamples
the number of samples to identify the hit as a cross talk hit when there is another cross talk hit in...
bool m_checkPreValleyForXTalkId
require existence of pre-valley.
virtual void event() override
event
virtual void endRun() override
endRun
int m_preValleyDepthLoose
loose threshold for depth of pre valley [ADC counts], for corss talk identification
virtual void terminate() override
terminate
TOPXTalkChargeShareSetterModule()
Constructor: Sets the description, the properties and the parameters of the module.
int m_2ndPeakAmplitudeLoose
loose threshold for amplitude of the second peak [ADC counts] for cross talk identification.
virtual void beginRun() override
beginRun
bool isCrossTalk(std::vector< short > wfm, int iRawTime, short height)
Examine whether the give hit is cross talk hits using waveform information Thresholds for such as pre...
float m_timeCut
cut range of hittiming for chargeshare
int m_preValleyDepthTight
tight threshold for depth of pre valley [ADC counts], identified as cross talk with loose threshold f...
double m_2ndPeakAmplitudeRatioTight
tight threshold for amplitude ratio of the second peak to the main peak height [ADC counts]
bool m_sumChargeShare
sum charge of PrimaryChargeShare and SecondaryChargeShare
bool m_checkPostValleyForXTalkId
require existence of post-valley and 2nd peak.
int m_nSampleBefore
the number of samples by which the pre-valley should exist from the CFD timing, used for cross talk i...
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.
Abstract base class for different kinds of events.