15 using namespace Diana;
23 fPulseLabel = GetString(
"PulseLabel",
"DAQ@Pulse",
false);
24 ev.RequireByLabel<
QPulse>(fPulseLabel);
27 fValidityKind = GetString(
"ValidityKind",
"dataset",
false);
28 if(fValidityKind !=
"dataset" && fValidityKind !=
"run") {
29 Panic(
"ValidityKind must be set to dataset or run");
35 fAlignmentOn = GetBool(
"AlignmentOn",
false);
36 fOutput = GetString(
"Output",
"avgpulses.root");
37 fSubtractBaseline = GetBool(
"SubtractBaseline",
false);
38 if(fSubtractBaseline) fNumBaselinePoints = GetInt(
"BaselineNumPoints",0);
40 fMaxShift = GetInt(
"MaxShift",10);
41 fFractionalShift = GetBool(
"FractionalShift",
true);
45 ev.Require<
QHeader>(
"DAQ",
"Header");
47 ev.RequireByLabel<
QPulse>(fPulseLabel);
55 const int run = header.
GetRun();
57 int chanId = ev.
Get<
QPulseInfo>(
"DAQ",
"PulseInfo").GetChannelId();
59 if (run != fCurrentRun)
63 if(GetIteration()== 1) fSRuns.push_back(fCurrentRun);
66 if( GetIteration() == 1 && fChannelData.find(chanId) == fChannelData.end()) {
68 size_t fNumSamples = pulse.Size();
70 thisChanData.
fAvgPulse.Resize(fNumSamples);
78 fChannelData[chanId] = thisChanData;
86 double maxPos = pulse.GetMaxIndex();
87 if(GetIteration() == 1)
98 float stepreal = delay - thisChanData.
fAlignPos;
99 int stepint = (int) stepreal;
100 stepreal = stepreal - stepint;
102 QVector shifted = pulse;
107 if(stepint < fMaxShift && stepint > -fMaxShift)
110 shifted.Differentiate();
113 int derivMeanSize = int(0.02*pulse.Size());
114 QVector beginDeriv(derivMeanSize);
115 QVector endDeriv(derivMeanSize);
117 for(
int i = 0; i < derivMeanSize; i++)
119 beginDeriv[i] = shifted[i];
120 endDeriv[i] = shifted[shifted.Size() - 1 -i];
122 double derivMeanBegin = beginDeriv.Sum(derivMeanSize)/derivMeanSize;
123 double derivMeanEnd = endDeriv.Sum(derivMeanSize)/derivMeanSize;
126 shifted.Shift(-stepint);
129 for(
int i = 0; i < stepint; i++)
131 shifted[shifted.Size() - stepint +i] += derivMeanEnd;
136 for(
int i = 0; i < stepint; i++)
138 shifted[i] -= derivMeanBegin;
143 shifted.Integrate(pulse[0]);
144 if (fFractionalShift)
146 shifted.ShiftReal(-stepreal);
147 if (stepreal >0) shifted[shifted.Size() - 1] = shifted[shifted.Size() - 2] + derivMeanEnd;
148 else if (stepreal <0) shifted[0] = shifted[1] - derivMeanBegin;
168 std::map<int,ChannelData>::iterator chanIter = fChannelData.begin();
169 while(chanIter != fChannelData.end()) {
171 int chanId = chanIter->first;
173 if(chanIter!=fChannelData.begin()){
175 int prevChan = (chanId-1);
176 int prevEntry = (chanIter->first);
178 if(prevEntry != (prevChan)) {
179 Error(
"Missing channel %d - Could not build AP",(prevChan));}
181 if(chanIter!= --fChannelData.end()){
183 int nextChan = (chanId+1);
184 int nextEntry = (chanIter->first);
186 if(nextEntry != (nextChan)) {
187 Error(
"Missing channel %d - Could not build AP",(nextChan));}
193 if(fAlignmentOn && GetIteration() == 1) {
196 Debug(
"Channel[%d]: Number of events: %d, PeakMode %f",
200 Debug(
"Channel[%d]: Number of events: %d", chanId, thisChanData.
fNumPulses);
205 if(fAlignmentOn) algo =
"Aligned";
206 else algo =
"Normal";
208 if (fSubtractBaseline)
210 double AvgBaseline = 0;
211 QVector AvgBaselineVector;
213 if(fNumBaselinePoints <=0) {
214 nbsamples = int (thisChanData.
fAvgPulse.GetMaxIndex()*3./4);
216 nbsamples = fNumBaselinePoints;
218 for (
int k = 0; k < nbsamples; ++k)
220 AvgBaseline += thisChanData.
fAvgPulse[k];
222 AvgBaseline /= nbsamples;
223 AvgBaselineVector.Resize(thisChanData.
fAvgPulse.Size());
224 AvgBaselineVector.Initialize(AvgBaseline);
225 thisChanData.
fAvgPulse-= AvgBaselineVector;
226 char buf[128]; snprintf(buf,128,
"_%.2d",chanId);
237 if(fValidityKind==
"dataset"){
239 GlobalHandle<QInt> dHandle(
"Dataset");
240 GlobalData().Get(
"",&dHandle,
"");
241 int dataset = dHandle.Get();
242 aphandle.SetDataset(dataset);
244 else if (fValidityKind==
"run"){
245 if (fSRuns.size()==1){
246 aphandle.SetRun(fSRuns[0]);
248 else Error(
"ValidityKind set to run is not permitted when reading multiple runs.");
250 else Error(
"ValidityKind can be set only to run or dataset. Check cfg.");
253 GlobalData().Set(&aphandle, fOutput);
257 Error(
"Could not build average pulse for channel %i: , 0 events passing the selection cuts",chanId);
262 if(fAlignmentOn && GetIteration() == 1) SetRunAgain(
true);
263 else SetRunAgain(
false);
#define REGISTER_MODULE(clazz)
Diana::QVector fPeakPositions
Module to form idealized pulses by averaging.
virtual void Do(Diana::QEvent &ev)
global handle for average pulse
void SetSourceRuns(const std::vector< int > &sourceRuns)
Set the list of source runs.
void SetNumEvents(int nEvents)
Set the number of events in the average.
const Q & GetByLabel(const QEventLabel &label) const
Get a QObject in read mode by label.
void Get(const char *owner, ReadHandle< Q > &handle) const
Get a QObject Handle in read mode.
Raw event: bolometer channel, trigger positions and types.
Raw event: sampled waveform.
the Diana namespace is needed because sometimes we use Qt libraries, that use same class names of our...