source: trunk/Mars/msimcamera/MSimTrigger.cc@ 9932

Last change on this file since 9932 was 9574, checked in by tbretz, 14 years ago
*** empty log message ***
File size: 22.9 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of CheObs, the Modular Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appears in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 1/2009 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: CheObs Software Development, 2000-2009
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MSimTrigger
28//
29// This task takes the pure analog channels and simulates a trigger
30// electronics.
31//
32// In a first step several channels can be summed together by a look-up table
33// fRouteAC.
34//
35// In a second step from these analog channels the output of a discriminator
36// is calculated using a threshold and optional a fixed digital signal length.
37//
38// The signal length of the digital signal emitted by the discriminator
39// can either be bound to the time the signal is above the threshold
40// defined by fDiscriminatorThreshold if fDigitalSignalLength<0 or set to a
41// fixed length (fDigitalSignalLength>0).
42//
43// With a second look-up table fCoincidenceMap the analog channels are
44// checked for coincidences. The coincidence must at least be of the length
45// defined by fCoincidenceTime. The earliest coincide is then stored as
46// trigger position.
47//
48// If a minimum multiplicity m is given, m signals above threshold
49// in the coincidence patterns are enough to emit a trigger signal.
50//
51//
52// For MAGIC1:
53// - fDigitalSignalLength between 6ns and 12ns
54// - fCoincidenceTime between 0.25ns to 1ns
55//
56//
57// Input Containers:
58// IntendedPulsePos [MParameterD]
59// MAnalogChannels
60// MRawRunHeader
61//
62// Output Containers:
63// TriggerPos [MParameterD]
64// MRawEvtHeader
65//
66//////////////////////////////////////////////////////////////////////////////
67#include "MSimTrigger.h"
68
69#include "MLog.h"
70#include "MLogManip.h"
71
72#include "MParList.h"
73#include "MParameters.h"
74
75#include "MLut.h"
76#include "MArrayI.h"
77
78#include "MRawEvtHeader.h"
79#include "MRawRunHeader.h"
80
81#include "MAnalogSignal.h"
82#include "MAnalogChannels.h"
83#include "MDigitalSignal.h"
84
85#include "MTriggerPattern.h"
86
87#include "MPedestalCam.h"
88#include "MPedestalPix.h"
89
90ClassImp(MSimTrigger);
91
92using namespace std;
93
94// --------------------------------------------------------------------------
95//
96// Default Constructor.
97//
98MSimTrigger::MSimTrigger(const char *name, const char *title)
99 : fCamera(0), fPulsePos(0), fTrigger(0), fRunHeader(0),
100 fEvtHeader(0), fElectronicNoise(0), fGain(0),
101 fDiscriminatorThreshold(-1), fDigitalSignalLength(8), fCoincidenceTime(0.5),
102 fShiftBaseline(kTRUE), fUngainSignal(kTRUE), fSimulateElectronics(kTRUE),
103 fMinMultiplicity(-1)
104{
105 fName = name ? name : "MSimTrigger";
106 fTitle = title ? title : "Task to simulate trigger electronics";
107}
108
109// --------------------------------------------------------------------------
110//
111// Take two TObjArrays with a collection of digital signals.
112// Every signal from one array is compared with any from the other array.
113// For all signals which overlap and which have an overlap time >gate
114// a new digital signal is created storing start time and length of overlap.
115// They are collected in a newly allocated TObjArray. A pointer to this array
116// is returned.
117//
118// The user gains owenership of the object, i.e., the user is responsible of
119// deleting the memory.
120//
121TObjArray *MSimTrigger::CalcCoincidence(const TObjArray &arr1, const TObjArray &arr2/*, Float_t gate*/) const
122{
123 TObjArray *res = new TObjArray;
124
125 if (arr1.GetEntriesFast()==0 || arr2.GetEntriesFast()==0)
126 return res;
127
128 TIter Next1(&arr1);
129 MDigitalSignal *ttl1 = 0;
130 while ((ttl1=static_cast<MDigitalSignal*>(Next1())))
131 {
132 TIter Next2(&arr2);
133 MDigitalSignal *ttl2 = 0;
134 while ((ttl2=static_cast<MDigitalSignal*>(Next2())))
135 {
136 MDigitalSignal *ttl = new MDigitalSignal(*ttl1, *ttl2);
137 /*
138 if (ttl->GetLength()<=gate)
139 {
140 delete ttl;
141 continue;
142 }
143 */
144 res->Add(ttl);
145 }
146 }
147
148 res->SetOwner();
149
150 return res;
151}
152
153class Edge : public TObject
154{
155private:
156 Double_t fEdge;
157 Int_t fRising;
158
159public:
160 Edge(Double_t t, Int_t rising) : fEdge(t), fRising(rising) { }
161 Bool_t IsSortable() const { return kTRUE; }
162 Int_t Compare(const TObject *o) const { const Edge *e = static_cast<const Edge*>(o); if (e->fEdge<fEdge) return 1; if (e->fEdge>fEdge) return -1; return 0; }
163
164 Int_t IsRising() const { return fRising; }
165 Double_t GetEdge() const { return fEdge; }
166};
167
168// --------------------------------------------------------------------------
169//
170// Calculate a multiplicity trigger on the given array(s). The idx-array
171// conatins all channels which should be checked for coincidences
172// and the ttls array conatins the arrays with the digital signals.
173//
174// For the windows in which more or euqal than threshold channels have
175// a high signal a new MDigitalSignal is created. newly allocated
176// array with a collection of these trigger signals is returned.
177//
178TObjArray *MSimTrigger::CalcMinMultiplicity(const MArrayI &idx, const TObjArray &ttls, Int_t threshold) const
179{
180 // Create a new array for the rising and falling edges of the signals
181 TObjArray times;
182 times.SetOwner();
183
184 // Fill the array with edges from all digital signals of all our channels
185 for (UInt_t k=0; k<idx.GetSize(); k++)
186 {
187 TObjArray *arr = static_cast<TObjArray*>(ttls[idx[k]]);
188
189 TIter Next(arr);
190 MDigitalSignal *ttl = 0;
191 while ((ttl=static_cast<MDigitalSignal*>(Next())))
192 {
193 times.Add(new Edge(ttl->GetStart(), 1));
194 times.Add(new Edge(ttl->GetEnd(), -1));
195 }
196 }
197
198 // Sort them in time
199 times.Sort();
200
201 // Start with no channel active
202 Int_t lvl = 0;
203
204 TObjArray *res = new TObjArray;
205 res->SetOwner();
206
207 // First remove all edges which do not change the status
208 // "below threshold" or "above threshold"
209 for (int i=0; i<times.GetEntriesFast(); i++)
210 {
211 // Get i-th edge
212 const Edge &e = *static_cast<Edge*>(times.UncheckedAt(i));
213
214 // Claculate what the number of active channels after the edge is
215 const Int_t lvl1 = lvl + e.IsRising();
216
217 // Remove edge if number of active channels before and after the
218 // edge lower is lower than the threshold or higher than
219 // the threshold
220 if (lvl+1<threshold || lvl-1>=threshold)
221 delete times.RemoveAt(i);
222
223 // keep the (now) "previous" level
224 lvl = lvl1<0 ? 0 : lvl1;
225 }
226
227 // Remove the empty slots from the array
228 times.Compress();
229
230 //
231 for (int i=0; i<times.GetEntriesFast()-1; i++)
232 {
233 // get the current edge
234 const Edge &e0 = *static_cast<Edge*>(times.UncheckedAt(i));
235
236 // go ahead if this is a falling edge
237 if (e0.IsRising()!=1)
238 continue;
239
240 // get the following edge (must be a falling edge now)
241 const Edge &e1 = *static_cast<Edge*>(times.UncheckedAt(i+1));
242
243 // calculate the length of the digital signal
244 const Double_t len = e1.GetEdge()-e0.GetEdge();
245
246 // Create a digital trigger signal
247 MDigitalSignal *ds = new MDigitalSignal(e0.GetEdge(), len);
248 //ds->SetIndex(lvl);
249 res->Add(ds);
250 }
251
252 return res;
253}
254
255// --------------------------------------------------------------------------
256//
257// Check for the necessary parameter containers. Read the luts.
258//
259Int_t MSimTrigger::PreProcess(MParList *pList)
260{
261 fTrigger = (MParameterD*)pList->FindCreateObj("MParameterD", "TriggerPos");
262 if (!fTrigger)
263 return kFALSE;
264
265 fPulsePos = (MParameterD*)pList->FindObject("IntendedPulsePos", "MParameterD");
266 if (!fPulsePos)
267 {
268 *fLog << err << "IntendedPulsePos [MParameterD] not found... aborting." << endl;
269 return kFALSE;
270 }
271
272 fCamera = (MAnalogChannels*)pList->FindObject("MAnalogChannels");
273 if (!fCamera)
274 {
275 *fLog << err << "MAnalogChannels not found... aborting." << endl;
276 return kFALSE;
277 }
278
279 fRunHeader = (MRawRunHeader*)pList->FindObject("MRawRunHeader");
280 if (!fRunHeader)
281 {
282 *fLog << err << "MRawRunHeader not found... aborting." << endl;
283 return kFALSE;
284 }
285
286 fEvtHeader = (MRawEvtHeader*)pList->FindCreateObj("MRawEvtHeader");
287 if (!fEvtHeader)
288 return kFALSE;
289
290 if (!fSimulateElectronics)
291 {
292 *fLog << inf << "Simulation of electronics switched off... first photon will trigger." << endl;
293 return kTRUE;
294 }
295
296 fElectronicNoise = 0;
297 if (fShiftBaseline)
298 {
299 fElectronicNoise = (MPedestalCam*)pList->FindObject("ElectronicNoise", "MPedestalCam");
300 if (!fElectronicNoise)
301 {
302 *fLog << err << "ElectronicNoise [MPedestalCam] not found... aborting." << endl;
303 return kFALSE;
304 }
305 *fLog << inf << "Baseline will be shifted back to 0 for discriminator." << endl;
306 }
307
308 fGain = 0;
309 if (fUngainSignal)
310 {
311 fGain = (MPedestalCam*)pList->FindObject("Gain", "MPedestalCam");
312 if (!fGain)
313 {
314 *fLog << err << "Gain [MPedestalCam] not found... aborting." << endl;
315 return kFALSE;
316 }
317 *fLog << inf << "Discriminator will be multiplied by applied gain." << endl;
318 }
319
320 fRouteAC.Delete();
321 if (!fNameRouteAC.IsNull() && fRouteAC.ReadFile(fNameRouteAC)<0)
322 return kFALSE;
323
324 fCoincidenceMap.Delete();
325 if (!fNameCoincidenceMap.IsNull() && fCoincidenceMap.ReadFile(fNameCoincidenceMap)<0)
326 return kFALSE;
327
328 // ---------------- Consistency checks ----------------------
329
330 if (!fRouteAC.IsEmpty() && !fCoincidenceMap.IsEmpty() &&
331 fCoincidenceMap.GetMaxIndex()>fRouteAC.GetNumRows()-1)
332 {
333 *fLog << err;
334 *fLog << "ERROR - AC routing produces " << fRouteAC.GetNumRows() << " analog channels," << endl;
335 *fLog << " but the coincidence map expects at least " << fCoincidenceMap.GetMaxIndex()+1 << " channels." << endl;
336 return kERROR;
337 }
338
339 if (fDiscriminatorThreshold<=0)
340 {
341 *fLog << err << "ERROR - Discriminator threshold " << fDiscriminatorThreshold << " invalid." << endl;
342 return kFALSE;
343 }
344
345 if (fElectronicNoise && !fRouteAC.IsEmpty() && !fRouteAC.IsDefaultCol())
346 {
347 // FIXME: Apply to analog channels when summing
348 *fLog << warn << "WARNING - A baseline shift doesn't make sense for sum-channels... reset." << endl;
349 fElectronicNoise = 0;
350 }
351
352 if (fGain && !fRouteAC.IsEmpty() && !fRouteAC.IsDefaultCol())
353 {
354 // FIXME: Apply to analog channels when summing
355 *fLog << warn << "WARNING - Ungain doesn't make sense for sum-channels... reset." << endl;
356 fGain = 0;
357 }
358
359
360 // ---------------- Information output ----------------------
361
362 *fLog << inf;
363
364 if (fRouteAC.IsEmpty())
365 *fLog << "Re-routing/summing of analog channels before discriminator switched off." << endl;
366 else
367 *fLog << "Using " << fNameRouteAC << " for re-routing/summing of analog channels before discriminator." << endl;
368
369 if (fCoincidenceMap.IsEmpty() && fMinMultiplicity<=0)
370 *fLog << "No coincidences of digital channels will be checked. Signal-above-threshold trigger applied." << endl;
371 else
372 {
373 *fLog << "Using ";
374 if (fCoincidenceMap.IsEmpty())
375 *fLog << "the whole camera";
376 else
377 *fLog << "patterns from " << fNameCoincidenceMap;
378 *fLog << " to check for ";
379 if (fMinMultiplicity>0)
380 *fLog << fMinMultiplicity << " multiplicity." << endl;
381 else
382 *fLog << "coincidences of the digital channels." << endl;
383 }
384
385 *fLog << "Using discriminator threshold of " << fDiscriminatorThreshold << endl;
386
387 return kTRUE;
388}
389
390/*
391class MDigitalChannel : public TObjArray
392{
393private:
394 TObjArray fArray;
395
396public:
397 MDigitalSignal *GetSignal(UInt_t i) { return static_cast<MDigitalSignal*>(fArray[i]); }
398
399};
400*/
401
402#include "MCamEvent.h"
403class MTriggerSignal : public MParContainer, public MCamEvent
404{
405private:
406 TObjArray fSignals;
407
408public:
409 MTriggerSignal() { fSignals.SetOwner(); }
410
411 void Add(MDigitalSignal *signal) { fSignals.Add(signal); }
412
413 MDigitalSignal *GetSignal(UInt_t i) { return static_cast<MDigitalSignal*>(fSignals[i]); }
414
415 void Sort() { fSignals.Sort(); }
416
417 Int_t GetNumSignals() const { return fSignals.GetEntriesFast(); }
418
419 Float_t GetFirstTrigger() const
420 {
421 MDigitalSignal *sig = static_cast<MDigitalSignal*>(fSignals[0]);
422 return sig ? sig->GetStart() : -1;
423 }
424 Int_t GetFirstIndex() const
425 {
426 MDigitalSignal *sig = static_cast<MDigitalSignal*>(fSignals[0]);
427 return sig ? sig->GetIndex() : -1;
428 }
429 Bool_t GetPixelContent(Double_t&, Int_t, const MGeomCam&, Int_t) const
430 {
431 switch (1)
432 {
433 case 1: // yes/no
434 case 2: // first time
435 case 3: // length
436 case 4: // n
437 break;
438 }
439
440 return kTRUE;
441 }
442 void DrawPixelContent(Int_t) const
443 {
444 }
445};
446
447
448void MSimTrigger::SetTrigger(Double_t pos, Int_t idx)
449{
450 // FIXME: Jitter! (Own class?)
451 fTrigger->SetVal(pos);
452 fTrigger->SetReadyToSave();
453
454 // Trigger pattern to be set
455 // FIXME: Make flexible
456 const UInt_t pat = (UInt_t)~(MTriggerPattern::kTriggerLvl1 | (MTriggerPattern::kTriggerLvl1<<8));
457
458 // Flag this event as triggered by the lvl1 trigger (FIXME?)
459 fEvtHeader->SetTriggerPattern(pos<0 ? 0 : pat);
460 fEvtHeader->SetNumTrigLvl1((UInt_t)idx);
461 fEvtHeader->SetReadyToSave();
462}
463
464// --------------------------------------------------------------------------
465//
466Int_t MSimTrigger::Process()
467{
468 // Invalidate trigger
469 //fTrigger->SetVal(-1);
470 // Calculate the minimum and maximum time for a valid trigger
471 const Double_t freq = fRunHeader->GetFreqSampling()/1000.;
472 const Float_t nsamp = fRunHeader->GetNumSamplesHiGain();
473 const Float_t pulspos = fPulsePos->GetVal()/freq;
474
475 // Valid range in units of bins
476 const Float_t min = fCamera->GetValidRangeMin()+pulspos;
477 const Float_t max = fCamera->GetValidRangeMax()-(nsamp-pulspos);
478
479 if (!fSimulateElectronics)
480 {
481 SetTrigger(min, -1);
482 return kTRUE;
483 }
484
485 // ================== Simulate channel bundling ====================
486
487 // FIXME: Before we can bundle the channels we have to make a copy
488 // and simulate clipping
489
490 // Check if routing should be done
491 const Bool_t empty = fRouteAC.IsEmpty();
492
493 // If no channels are summed the number of patches stays the same
494 const UInt_t npatch = empty ? fCamera->GetNumChannels() : fRouteAC.GetEntriesFast();
495
496 // Use the given analog channels as default out. If channels are
497 // summed overwrite with a newly allocated set of analog channels
498 MAnalogChannels *patches = fCamera;
499 if (!empty)
500 {
501 // FIXME: Can we add gain and offset here into a new container?
502
503 patches = new MAnalogChannels(npatch, fCamera->GetNumSamples());
504 for (UInt_t i=0; i<npatch; i++)
505 {
506 const MArrayI &row = fRouteAC.GetRow(i);
507 for (UInt_t j=0; j<row.GetSize(); j++)
508 {
509 const UInt_t idx = row[j];
510
511 // FIXME: Shrinking the mapping table earlier (e.g.
512 // ReInit) would avoid a lot of if's
513 if (idx<fCamera->GetNumChannels())
514 (*patches)[i].AddSignal((*fCamera)[idx]);
515 }
516 }
517 }
518
519 // FIXME: Write patches
520
521 // ================== Simulate discriminators ====================
522
523 TObjArray ttls(npatch);
524 ttls.SetOwner();
525
526 for (UInt_t i=0; i<npatch; i++)
527 {
528 // FIXME: What if the gain was also allpied to the baseline?
529 const Double_t offset = fElectronicNoise ? (*fElectronicNoise)[i].GetPedestal() : 0;
530 const Double_t gain = fGain ? (*fGain)[i].GetPedestal() : 1;
531 ttls.AddAt((*patches)[i].Discriminate(fDiscriminatorThreshold*gain+offset, fDigitalSignalLength), i);
532 }
533
534 // FIXME: Write TTLs!
535
536 // If analog channels had been newly allocated free memmory
537 if (patches!=fCamera)
538 delete patches;
539
540 // =================== Simulate coincidences ======================
541
542 // If the map is empty we create a one-pixel-coincidence map
543 // FIMXE: This could maybe be accelerated if the Clone can be
544 // omitted in the loop
545 if (fCoincidenceMap.IsEmpty())
546 {
547 if (fMinMultiplicity>0)
548 fCoincidenceMap.SetDefaultRow(npatch);
549 else
550 fCoincidenceMap.SetDefaultCol(npatch);
551 }
552
553 // Create an array for the individual triggers
554 MTriggerSignal triggers;
555
556 Int_t cnt = 0;
557 Int_t rmlo = 0;
558 Int_t rmhi = 0;
559
560 for (int j=0; j<fCoincidenceMap.GetEntries(); j++)
561 {
562 const MArrayI &idx = fCoincidenceMap.GetRow(j);
563
564 TObjArray *arr = 0;
565
566 if (fMinMultiplicity>0)
567 {
568 arr = CalcMinMultiplicity(idx, ttls, fMinMultiplicity);
569 }
570 else
571 {
572 arr = CalcMinMultiplicity(idx, ttls, idx.GetSize());
573 /*
574 // Start with a copy of the first coincidence channel
575 arr = static_cast<TObjArray*>(ttls[idx[0]]->Clone());
576 arr->SetOwner();
577
578 // compare to all other channels in this coincidence patch, one by one
579 for (UInt_t k=1; k<idx.GetSize() && arr->GetEntriesFast()>0; k++)
580 {
581 TObjArray *res = CalcCoincidence(*arr, *static_cast<TObjArray*>(ttls[idx[k]]));//, fCoincidenceTime);
582
583 // Delete the original array and keep the new one
584 delete arr;
585 arr = res;
586 }*/
587 }
588
589 // Count the number of totally emitted coincidence signals
590 cnt += arr->GetEntriesFast();
591
592 // Remove all signals which are not in the valid digitization range
593 // (This is not the digitization window, but the region in which
594 // the analog channels contain usefull data)
595 // and which are shorter than the defined coincidence gate.
596 TIter Next(arr);
597 MDigitalSignal *ttl = 0;
598 while ((ttl=static_cast<MDigitalSignal*>(Next())))
599 {
600 if (ttl->GetLength()<fCoincidenceTime)
601 {
602 delete arr->Remove(ttl);
603 continue;
604 }
605
606 if (ttl->GetStart()<min)
607 {
608 delete arr->Remove(ttl);
609 rmlo++;
610 continue;
611 }
612 if (ttl->GetStart()>max)
613 {
614 delete arr->Remove(ttl);
615 rmhi++;
616 continue;
617 }
618
619 // Set trigger-channel index to keep this information
620 //ttl->SetIndex(j);
621 }
622
623 // Remove the empty slots
624 arr->Compress();
625
626 // If we have at least one trigger keep the earliest one.
627 // FIXME: The triggers might be ordered in time automatically:
628 // To be checked!
629 // FIXME: Simulate trigger dead-time!
630 if (arr->GetEntriesFast()>0)
631 {
632 ttl = static_cast<MDigitalSignal*>(arr->RemoveAt(0));
633 // Set trigger-channel index to keep this information
634 ttl->SetIndex(j);
635 triggers.Add(ttl);
636 }
637
638 // delete the allocated space
639 delete arr;
640 }
641
642 // There are usually not enough entries that it is worth to search
643 // for the earliest instead of just sorting and taking the first one
644 // FIXME: This could be improved if checking for IsSortable
645 // is omitted
646 triggers.Sort();
647 // FIXME: Store triggers! (+ Reversed pixels?)
648
649 SetTrigger(triggers.GetFirstTrigger(), triggers.GetFirstIndex());
650
651 // No trigger issued. Go on.
652 if (triggers.GetNumSignals()==0)
653 {
654 if (rmlo>0 || rmhi>0)
655 *fLog << inf2 << GetNumExecutions() << ": " << rmlo << "/" << rmhi << " trigger out of valid range. No trigger raised." << endl;
656 return kTRUE;
657 }
658
659 // Number of patches which have triggered out of the total number of
660 // Coincidence signals emitted. (If the total number is higher than
661 // the number of triggers either some triggers had to be removed or
662 // or a patch has emitted more than one trigger signal)
663 // FIXME: inf2?
664 *fLog << inf << GetNumExecutions() << ": ";
665 *fLog << setw(3) << triggers.GetNumSignals() << " triggers left out of ";
666 *fLog << setw(3) << cnt << " (" << rmlo << "/" << rmhi << " trigger out of valid range), T=" << fTrigger->GetVal();
667 *fLog << endl;
668
669 //# Trigger characteristics: gate length (ns), min. overlapping time (ns),
670 //# amplitude and FWHM of (gaussian) single phe response for trigger:
671 //trigger_prop 3.0 0.25 1.0 2.0
672
673 return kTRUE;
674}
675
676// --------------------------------------------------------------------------
677//
678// FileNameRouteac: routeac.txt
679// FileNameCoincidenceMap: coincidence.txt
680// DiscriminatorTheshold: 3.5
681// DigitalSignalLength: 8
682// CoincidenceTime: 0.5
683// SimulateElectronics: Yes
684//
685Int_t MSimTrigger::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
686{
687 Bool_t rc = kFALSE;
688 if (IsEnvDefined(env, prefix, "FileNameRouteAC", print))
689 {
690 rc = kTRUE;
691 fNameRouteAC = GetEnvValue(env, prefix, "FileNameRouteAC", fNameRouteAC);
692 }
693
694 if (IsEnvDefined(env, prefix, "FileNameCoincidenceMap", print))
695 {
696 rc = kTRUE;
697 fNameCoincidenceMap = GetEnvValue(env, prefix, "FileNameCoincidenceMap", fNameCoincidenceMap);
698 }
699
700 if (IsEnvDefined(env, prefix, "DiscriminatorThreshold", print))
701 {
702 rc = kTRUE;
703 fDiscriminatorThreshold = GetEnvValue(env, prefix, "DiscriminatorThreshold", fDiscriminatorThreshold);
704 }
705
706 if (IsEnvDefined(env, prefix, "DigitalSignalLength", print))
707 {
708 rc = kTRUE;
709 fDigitalSignalLength = GetEnvValue(env, prefix, "DigitalSignalLength", fDigitalSignalLength);
710 }
711
712 if (IsEnvDefined(env, prefix, "CoincidenceTime", print))
713 {
714 rc = kTRUE;
715 fCoincidenceTime = GetEnvValue(env, prefix, "CoincidenceTime", fCoincidenceTime);
716 }
717
718 if (IsEnvDefined(env, prefix, "SimulateElectronics", print))
719 {
720 rc = kTRUE;
721 fSimulateElectronics = GetEnvValue(env, prefix, "SimulateElectronics", fSimulateElectronics);
722 }
723
724 if (IsEnvDefined(env, prefix, "MinMultiplicity", print))
725 {
726 rc = kTRUE;
727 fMinMultiplicity = GetEnvValue(env, prefix, "MinMultiplicity", fMinMultiplicity);
728 }
729
730 return rc;
731}
Note: See TracBrowser for help on using the repository browser.