8282// / \htmlonly <style>div.image img[src="trigger.png"]{width:500px;}</style> \endhtmlonly
8383// /
8484// / The following figure shows the integralThreshold trigger definition for a NLDBD
85- // / event. tStart and tEnd define the acquision window, centered on the time
86- // / when the signal integral is above the threshold defined. tStart has been
85+ // / event. fTimeStart and fTimeEnd define the acquisition window, centered on the time
86+ // / when the signal integral is above the threshold defined. fTimeStart has been
8787// / shifted by a triggerDelay = 60 samples * 200ns
8888// /
89- // / 
89+ // / 
9090// /
9191// / * **triggerDelay**: The time start obtained by the trigger mode
9292// / definition can be shifted using this parameter. The shift is
113113// /
114114// / <hr>
115115// /
116+
116117#include " TRestDetectorSignalToRawSignalProcess.h"
118+
117119using namespace std ;
118120
119121ClassImp (TRestDetectorSignalToRawSignalProcess);
@@ -181,115 +183,130 @@ void TRestDetectorSignalToRawSignalProcess::Initialize() {
181183TRestEvent* TRestDetectorSignalToRawSignalProcess::ProcessEvent (TRestEvent* inputEvent) {
182184 fInputSignalEvent = (TRestDetectorSignalEvent*)inputEvent;
183185
184- if (fInputSignalEvent ->GetNumberOfSignals () <= 0 ) return nullptr ;
186+ if (fInputSignalEvent ->GetNumberOfSignals () <= 0 ) {
187+ return nullptr ;
188+ }
185189
186- if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Debug) fOutputRawSignalEvent ->PrintEvent ();
190+ if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Debug) {
191+ fOutputRawSignalEvent ->PrintEvent ();
192+ }
187193
188194 fOutputRawSignalEvent ->SetID (fInputSignalEvent ->GetID ());
189195 fOutputRawSignalEvent ->SetSubID (fInputSignalEvent ->GetSubID ());
190196 fOutputRawSignalEvent ->SetTimeStamp (fInputSignalEvent ->GetTimeStamp ());
191197 fOutputRawSignalEvent ->SetSubEventTag (fInputSignalEvent ->GetSubEventTag ());
192198
193- // The time event window is defined (tStart, tEnd)
194- Double_t tStart = std::numeric_limits<double >::quiet_NaN ();
195- Double_t tEnd = 10000 ;
196199 if (fTriggerMode == " firstDeposit" ) {
197- tStart = fInputSignalEvent ->GetMinTime () - fTriggerDelay * fSampling ;
198- tEnd = fInputSignalEvent ->GetMinTime () + (fNPoints - fTriggerDelay ) * fSampling ;
200+ fTimeStart = fInputSignalEvent ->GetMinTime () - fTriggerDelay * fSampling ;
201+ fTimeEnd = fInputSignalEvent ->GetMinTime () + (fNPoints - fTriggerDelay ) * fSampling ;
199202 } else if (fTriggerMode == " integralThreshold" ) {
200- Double_t maxT = fInputSignalEvent -> GetMaxTime () ;
201- Double_t minT = fInputSignalEvent ->GetMinTime ();
202-
203- for ( Double_t t = minT - fNPoints * fSampling ; t <= maxT + fNPoints * fSampling ; t = t + 0.5 ) {
204- Double_t en = fInputSignalEvent -> GetIntegralWithTime (t, t + ( fSampling * fNPoints ) / 2 .);
205-
206- if (en > fIntegralThreshold ) {
207- tStart = t - fTriggerDelay * fSampling ;
208- tEnd = t + ( fNPoints - fTriggerDelay ) * fSampling ;
203+ bool thresholdReached = false ;
204+ for ( Double_t t = fInputSignalEvent ->GetMinTime () - fNPoints * fSampling ;
205+ t <= fInputSignalEvent -> GetMaxTime () + fNPoints * fSampling ; t = t + 0.5 ) {
206+ Double_t energy = fInputSignalEvent -> GetIntegralWithTime (t, t + ( fSampling * fNPoints ) / 2 .);
207+
208+ if (energy > fIntegralThreshold ) {
209+ fTimeStart = t - fTriggerDelay * fSampling ;
210+ fTimeEnd = t + ( fNPoints - fTriggerDelay ) * fSampling ;
211+ thresholdReached = true ;
209212 }
210213 }
211- } else {
212- if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Warning) {
213- cout << " REST WARNING. TRestDetectorSignalToRawSignalProcess. fTriggerMode not "
214- " recognized!"
215- << endl;
216- cout << " Setting fTriggerMode to firstDeposit" << endl;
217- }
218-
219- fTriggerMode = " firstDeposit" ;
220-
221- tStart = fInputSignalEvent ->GetMinTime () - fTriggerDelay * fSampling ;
222- tEnd = fInputSignalEvent ->GetMinTime () + (fNPoints - fTriggerDelay ) * fSampling ;
223- }
224-
225- if (std::isnan (tStart)) {
226- if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Warning) {
227- cout << endl;
228- cout << " REST WARNING. TRestDetectorSignalToRawSignalProcess. tStart was not "
229- " defined."
230- << endl;
231- cout << " Setting tStart = 0. tEnd = fNPoints * fSampling" << endl;
232- cout << endl;
214+ if (!thresholdReached) {
215+ RESTWarning << " Integral threshold for trigger not reached" << RESTendl;
216+ fTimeStart = 0 ;
217+ fTimeEnd = fNPoints * fSampling ;
233218 }
234-
235- tEnd = fNPoints * fSampling ;
236219 }
237220
238- if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Debug) {
239- cout << " tStart : " << tStart << " us " << endl;
240- cout << " tEnd : " << tEnd << " us " << endl;
241- }
221+ RESTDebug << " fTimeStart : " << fTimeStart << " us " << RESTendl;
222+ RESTDebug << " fTimeEnd : " << fTimeEnd << " us " << RESTendl;
242223
243224 for (int n = 0 ; n < fInputSignalEvent ->GetNumberOfSignals (); n++) {
244- vector<Double_t> sData (fNPoints );
245- for (int i = 0 ; i < fNPoints ; i++) sData [i] = 0 ;
246-
247- TRestDetectorSignal* sgnl = fInputSignalEvent ->GetSignal (n);
248- Int_t signalID = sgnl->GetSignalID ();
225+ vector<Double_t> data (fNPoints , fCalibrationOffset );
226+ TRestDetectorSignal* signal = fInputSignalEvent ->GetSignal (n);
227+ Int_t signalID = signal->GetSignalID ();
249228
250- for (int m = 0 ; m < sgnl ->GetNumberOfPoints (); m++) {
251- Double_t t = sgnl ->GetTime (m);
252- Double_t d = sgnl ->GetData (m);
229+ for (int m = 0 ; m < signal ->GetNumberOfPoints (); m++) {
230+ Double_t t = signal ->GetTime (m);
231+ Double_t d = signal ->GetData (m);
253232
254- if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Debug && n < 3 && m < 5 )
233+ if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Debug && n < 3 && m < 5 ) {
255234 cout << " Signal : " << n << " Sample : " << m << " T : " << t << " Data : " << d << endl;
235+ }
256236
257- if (t > tStart && t < tEnd ) {
237+ if (t > fTimeStart && t < fTimeEnd ) {
258238 // convert physical time (in us) to timeBin
259- Int_t timeBin = (Int_t)round ((t - tStart ) / fSampling );
239+ Int_t timeBin = (Int_t)round ((t - fTimeStart ) / fSampling );
260240
261- if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Warning)
241+ if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Warning) {
262242 if (timeBin < 0 || timeBin > fNPoints ) {
263243 cout << " Time bin out of range!!! bin value : " << timeBin << endl;
264244 timeBin = 0 ;
265245 }
246+ }
266247
267- RESTDebug << " Adding data : " << sgnl->GetData (m) << " to Time Bin : " << timeBin << RESTendl;
268- sData [timeBin] += fGain * sgnl->GetData (m);
248+ RESTDebug << " Adding data : " << signal->GetData (m) << " to Time Bin : " << timeBin
249+ << RESTendl;
250+ data[timeBin] += fCalibrationGain * signal->GetData (m);
269251 }
270252 }
271253
272- if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Warning)
273- for (int x = 0 ; x < fNPoints ; x++)
274- if (sData [x] < -32768 . || sData [x] > 32768 .)
275- cout << " REST Warning : data is outside short range : " << sData [x] << endl;
254+ if (IsShapingEnabled ()) {
255+ const auto shapingFunction = [](Double_t t) -> Double_t {
256+ if (t <= 0 ) {
257+ return 0 ;
258+ }
259+ // function is normalized such that its absolute maximum is 1.0
260+ // max is at x = 1.1664004483744728
261+ return TMath::Exp (-3.0 * t) * TMath::Power (t, 3.0 ) * TMath::Sin (t) * 22.68112123672292 ;
262+ };
263+
264+ vector<Double_t> dataAfterShaping (fNPoints , fCalibrationOffset );
265+ for (int i = 0 ; i < fNPoints ; i++) {
266+ const Double_t value = data[i] - fCalibrationOffset ;
267+ if (value <= 0 ) {
268+ // Only positive values are possible, 0 means no signal in this bin
269+ continue ;
270+ }
271+ for (int j = 0 ; j < fNPoints ; j++) {
272+ dataAfterShaping[j] += value * shapingFunction (((j - i) * fSampling ) / fShapingTime );
273+ }
274+ }
275+ data = dataAfterShaping;
276+ }
276277
277- TRestRawSignal rSgnl ;
278- rSgnl .SetSignalID (signalID);
278+ TRestRawSignal rawSignal ;
279+ rawSignal .SetSignalID (signalID);
279280 for (int x = 0 ; x < fNPoints ; x++) {
280- if (sData [x] < -32768 . || sData [x] > 32768 .) fOutputRawSignalEvent ->SetOK (false );
281+ double value = round (data[x]);
282+ if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Warning) {
283+ if (value < numeric_limits<Short_t>::min () || value > numeric_limits<Short_t>::max ()) {
284+ RESTWarning << " value (" << value << " ) is outside short range ("
285+ << numeric_limits<Short_t>::min () << " , " << numeric_limits<Short_t>::max ()
286+ << " )" << RESTendl;
287+ }
288+ }
281289
282- Short_t value = (Short_t)round (sData [x]);
283- rSgnl.AddPoint (value);
290+ if (value < numeric_limits<Short_t>::min ()) {
291+ value = numeric_limits<Short_t>::min ();
292+ fOutputRawSignalEvent ->SetOK (false );
293+ } else if (value > numeric_limits<Short_t>::max ()) {
294+ value = numeric_limits<Short_t>::max ();
295+ fOutputRawSignalEvent ->SetOK (false );
296+ }
297+ rawSignal.AddPoint ((Short_t)value);
284298 }
285299
286- if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Debug) rSgnl.Print ();
300+ if (GetVerboseLevel () >= TRestStringOutput::REST_Verbose_Level::REST_Debug) {
301+ rawSignal.Print ();
302+ }
287303 RESTDebug << " Adding signal to raw signal event" << RESTendl;
288- fOutputRawSignalEvent ->AddSignal (rSgnl);
304+
305+ fOutputRawSignalEvent ->AddSignal (rawSignal);
289306 }
290307
291308 RESTDebug << " TRestDetectorSignalToRawSignalProcess. Returning event with N signals "
292- << fOutputRawSignalEvent ->GetNumberOfSignals () << RESTendl;
309+ << fOutputRawSignalEvent ->GetNumberOfSignals () << RESTendl;
293310
294311 return fOutputRawSignalEvent ;
295312}
@@ -299,10 +316,48 @@ TRestEvent* TRestDetectorSignalToRawSignalProcess::ProcessEvent(TRestEvent* inpu
299316// / TRestDetectorSignalToRawSignalProcess metadata section
300317// /
301318void TRestDetectorSignalToRawSignalProcess::InitFromConfigFile () {
302- fSampling = GetDblParameterWithUnits (" sampling" );
303- fNPoints = StringToInteger (GetParameter (" Npoints" , " 512" ));
304- fTriggerMode = GetParameter (" triggerMode" , " firstDeposit" );
305- fTriggerDelay = StringToInteger (GetParameter (" triggerDelay" , 100 ));
306- fGain = StringToDouble (GetParameter (" gain" , " 100" ));
307- fIntegralThreshold = StringToDouble (GetParameter (" integralThreshold" , " 1229" ));
319+ auto nPoints = GetParameter (" nPoints" );
320+ if (nPoints == PARAMETER_NOT_FOUND_STR) {
321+ nPoints = GetParameter (" Npoints" , fNPoints );
322+ }
323+ fNPoints = StringToInteger (nPoints);
324+
325+ fTriggerMode = GetParameter (" triggerMode" , fTriggerMode );
326+ const set<string> validTriggerModes = {" firstDeposit" , " integralThreshold" , " fixed" };
327+ if (validTriggerModes.count (fTriggerMode .Data ()) == 0 ) {
328+ RESTError << " Trigger mode set to: '" << fTriggerMode
329+ << " ' which is not a valid trigger mode. Please use one of the following trigger modes: " ;
330+ for (const auto & triggerMode : validTriggerModes) {
331+ RESTError << triggerMode << " " ;
332+ }
333+ RESTError << RESTendl;
334+ exit (1 );
335+ }
336+
337+ fSampling = GetDblParameterWithUnits (" sampling" , fSampling );
338+ fTriggerDelay = StringToInteger (GetParameter (" triggerDelay" , fTriggerDelay ));
339+ fIntegralThreshold = StringToDouble (GetParameter (" integralThreshold" , fIntegralThreshold ));
340+ fTriggerFixedStartTime = GetDblParameterWithUnits (" triggerFixedStartTime" , fTriggerFixedStartTime );
341+
342+ fCalibrationGain = StringToDouble (GetParameter (" gain" , fCalibrationGain ));
343+ fCalibrationOffset = StringToDouble (GetParameter (" offset" , fCalibrationOffset ));
344+ fCalibrationEnergy = Get2DVectorParameterWithUnits (" calibrationEnergy" , fCalibrationEnergy );
345+ fCalibrationRange = Get2DVectorParameterWithUnits (" calibrationRange" , fCalibrationRange );
346+
347+ if (IsLinearCalibration ()) {
348+ const auto range = numeric_limits<Short_t>::max () - numeric_limits<Short_t>::min ();
349+ fCalibrationGain = range * (fCalibrationRange .Y () - fCalibrationRange .X ()) /
350+ (fCalibrationEnergy .Y () - fCalibrationEnergy .X ());
351+ fCalibrationOffset = range * (fCalibrationRange .X () - fCalibrationGain * fCalibrationEnergy .X ()) +
352+ numeric_limits<Short_t>::min ();
353+ }
354+
355+ fShapingTime = GetDblParameterWithUnits (" shapingTime" , fShapingTime );
356+ }
357+
358+ void TRestDetectorSignalToRawSignalProcess::InitProcess () {
359+ if (fTriggerMode == " fixed" ) {
360+ fTimeStart = fTriggerFixedStartTime - fTriggerDelay * fSampling ;
361+ fTimeEnd = fTimeStart + fNPoints * fSampling ;
362+ }
308363}
0 commit comments