source: trunk/MagicSoft/Mars/msignal/MExtractTimeAndChargeDigitalFilter.cc@ 7350

Last change on this file since 7350 was 7194, checked in by tbretz, 19 years ago
*** empty log message ***
File size: 41.4 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC 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 appear 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): Hendrik Bartko, 09/2004 <mailto:hbartko@mppmu.mpg.de>
19! Author(s): Markus Gaug, 05/2004 <mailto:markus@ifae.es>
20! Author(s): Diego Tescaro, 05/2004 <mailto:tescaro@pd.infn.it>
21!
22! Copyright: MAGIC Software Development, 2000-2004
23!
24!
25\* ======================================================================== */
26//////////////////////////////////////////////////////////////////////////////
27//
28// MExtractTimeAndChargeDigitalFilter
29//
30// Hendrik has promised to write more documentation
31//
32// The following variables have to be set by the derived class and
33// do not have defaults:
34// - fNumHiGainSamples
35// - fNumLoGainSamples
36// - fSqrtHiGainSamples
37// - fSqrtLoGainSamples
38//
39// The reading of automatic weights files (color, type) can be switched
40// off using EnableAutomaticWeights(kFALSE).
41//
42// An empty name or "-" as the weights file name is a synonym for
43// setting all weights to 1
44//
45// Input Containers:
46// MRawEvtData
47// MRawRunHeader
48// MPedestalCam
49// [MCalibrationPattern]
50//
51// Output Containers:
52// MArrivalTimeCam
53// MExtractedSignalCam
54//
55//////////////////////////////////////////////////////////////////////////////
56#include "MExtractTimeAndChargeDigitalFilter.h"
57
58#include <errno.h>
59#include <fstream>
60
61#include <TH1.h>
62#include <TH2.h>
63#include <TMatrix.h>
64
65#include "MLog.h"
66#include "MLogManip.h"
67
68#include "MParList.h"
69
70#include "MRawRunHeader.h"
71#include "MCalibrationPattern.h"
72#include "MExtractedSignalCam.h"
73
74#include "MPedestalPix.h"
75
76ClassImp(MExtractTimeAndChargeDigitalFilter);
77
78using namespace std;
79
80const Byte_t MExtractTimeAndChargeDigitalFilter::fgHiGainFirst = 0;
81const Byte_t MExtractTimeAndChargeDigitalFilter::fgHiGainLast = 15;
82const Byte_t MExtractTimeAndChargeDigitalFilter::fgLoGainFirst = 1;
83const Byte_t MExtractTimeAndChargeDigitalFilter::fgLoGainLast = 14;
84const Int_t MExtractTimeAndChargeDigitalFilter::fgWindowSizeHiGain = 4;
85const Int_t MExtractTimeAndChargeDigitalFilter::fgWindowSizeLoGain = 6;
86const Int_t MExtractTimeAndChargeDigitalFilter::fgBinningResolutionHiGain = 10;
87const Int_t MExtractTimeAndChargeDigitalFilter::fgBinningResolutionLoGain = 10;
88const Int_t MExtractTimeAndChargeDigitalFilter::fgSignalStartBinHiGain = 4;
89const Int_t MExtractTimeAndChargeDigitalFilter::fgSignalStartBinLoGain = 4;
90const Float_t MExtractTimeAndChargeDigitalFilter::fgOffsetLoGain = 1.7; // 5 ns
91const Float_t MExtractTimeAndChargeDigitalFilter::fgLoGainStartShift = -1.8;
92
93// --------------------------------------------------------------------------
94//
95// Default constructor.
96//
97// Calls:
98// - SetWindowSize();
99// - SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast)
100// - SetBinningResolution();
101//
102// Sets all weights to 1.
103//
104MExtractTimeAndChargeDigitalFilter::MExtractTimeAndChargeDigitalFilter(const char *name, const char *title)
105 : fTimeShiftHiGain(0.), fTimeShiftLoGain(0.), fAutomaticWeights(kTRUE), fRandomIter(0)
106{
107 fName = name ? name : "MExtractTimeAndChargeDigitalFilter";
108 fTitle = title ? title : "Digital Filter";
109
110 SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast);
111 SetWindowSize();
112 SetBinningResolution();
113 SetSignalStartBin();
114
115 SetOffsetLoGain(fgOffsetLoGain);
116 SetLoGainStartShift(fgLoGainStartShift);
117}
118
119// ---------------------------------------------------------------------------------------
120//
121// Checks:
122// - if a window is bigger than the one defined by the ranges, set it to the available range
123//
124// Sets:
125// - fNumHiGainSamples to: (Float_t)fWindowSizeHiGain
126// - fNumLoGainSamples to: (Float_t)fWindowSizeLoGain
127//
128void MExtractTimeAndChargeDigitalFilter::SetWindowSize(Int_t windowh, Int_t windowl)
129{
130
131 if (windowh != fgWindowSizeHiGain)
132 *fLog << warn << GetDescriptor()
133 << ": ATTENTION!!! If you are not Hendrik Bartko, do NOT use a different window size than the default." << endl;
134 if (windowl != fgWindowSizeLoGain)
135 *fLog << warn << GetDescriptor()
136 << ": ATTENTION!!! If you are not Hendrik Bartko, do NOT use a different window size than the default" << endl;
137
138 fWindowSizeHiGain = windowh;
139 fWindowSizeLoGain = windowl;
140
141 const Int_t availhirange = (Int_t)(fHiGainLast-fHiGainFirst+1);
142
143 if (fWindowSizeHiGain > availhirange)
144 {
145 *fLog << warn << GetDescriptor() << ": Hi Gain window size: " << Form("%2i",fWindowSizeHiGain);
146 *fLog << " is bigger than available range: [" << Form("%2i", (int)fHiGainFirst);
147 *fLog << "," << Form("%21", (int)fHiGainLast) << "]" << endl;
148
149 fHiGainLast = fHiGainFirst + fWindowSizeHiGain;
150
151 *fLog << warn << GetDescriptor() << ": Will set the upper range to: " << (int)fHiGainLast << endl;
152 }
153
154 if (fWindowSizeHiGain < 2)
155 {
156 fWindowSizeHiGain = 2;
157 *fLog << warn << GetDescriptor() << ": High Gain window size set to two samples" << endl;
158 }
159
160 if (fLoGainLast != 0 && fWindowSizeLoGain != 0)
161 {
162 const Int_t availlorange = (Int_t)(fLoGainLast-fLoGainFirst+1);
163
164 if (fWindowSizeLoGain > availlorange)
165 {
166 *fLog << warn << GetDescriptor() << ": Lo Gain window size: " << Form("%2i",fWindowSizeLoGain);
167 *fLog << " is bigger than available range: [" << Form("%2i", (int)fLoGainFirst);
168 *fLog << "," << Form("%21", (int)fLoGainLast) << "]" << endl;
169
170 fLoGainLast = fLoGainFirst + fWindowSizeLoGain;
171
172 *fLog << warn << GetDescriptor() << ": Will set the upper range to: " << (int)fLoGainLast << endl;
173 }
174
175 if (fWindowSizeLoGain<2)
176 {
177 fWindowSizeLoGain = 2;
178 *fLog << warn << GetDescriptor() << ": Low Gain window size set to two samples" << endl;
179 }
180 }
181 //
182 // We need here the effective number of samples which is about 2.5 in the case of a window
183 // size of 6. The exact numbers have to be found still.
184 //
185 fNumHiGainSamples = (Float_t)fWindowSizeHiGain/2.4;
186 fNumLoGainSamples = (Float_t)fWindowSizeLoGain/2.4;
187 fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples);
188 fSqrtLoGainSamples = TMath::Sqrt(fNumLoGainSamples);
189
190}
191
192// --------------------------------------------------------------------------
193//
194// Executing MExtractTimeAndCharge::PreProcess and searching for
195// MCalibrationPattern
196//
197Int_t MExtractTimeAndChargeDigitalFilter::PreProcess(MParList *pList)
198{
199 if (!MExtractTimeAndCharge::PreProcess(pList))
200 return kFALSE;
201
202 fCalibPattern = (MCalibrationPattern*)pList->FindObject("MCalibrationPattern");
203 return kTRUE;
204}
205
206// --------------------------------------------------------------------------
207//
208// The weights are determined using GetAutimaticWeights().
209//
210// kFALSE is returned if it returned an error.
211// kTRUE is returned if no new weights were set.
212//
213// If new weights are set
214// fTimeShiftHiGain
215// fTimeShiftLoGain
216// fNumHiGainSamples
217// fNumLoGainSamples
218// fSqrtHiGainSamples
219// fSqrtLoGainSamples
220// and
221// fSignals->SetUsedFADCSlices(...)
222// is updated accordingly.
223//
224Bool_t MExtractTimeAndChargeDigitalFilter::GetWeights()
225{
226 switch (GetAutomaticWeights())
227 {
228 case kERROR: // An error occured
229 return kFALSE;
230 case kFALSE: // No new weights set
231 return kTRUE;
232 }
233
234 // New weights set
235 fTimeShiftHiGain = 0.5 + 1./fBinningResolutionHiGain + fHiGainFirst;
236 fTimeShiftLoGain = 0.5 + 1./fBinningResolutionLoGain;
237
238 //
239 // We need here the effective number of samples which is about 2.5 in the case of a window
240 // size of 6. The exact numbers have to be found still.
241 //
242 fNumHiGainSamples = (Float_t)fWindowSizeHiGain/2.4;
243 fNumLoGainSamples = (Float_t)fWindowSizeLoGain/2.4;
244 fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples);
245 fSqrtLoGainSamples = TMath::Sqrt(fNumLoGainSamples);
246
247 // From MExtractTimeAndCharge::ReInit
248 if (fSignals)
249 fSignals->SetUsedFADCSlices(fHiGainFirst, fHiGainLast+fHiLoLast, fNumHiGainSamples,
250 fLoGainFirst, fLoGainLast, fNumLoGainSamples);
251 return kTRUE;
252}
253
254// --------------------------------------------------------------------------
255//
256// InitArrays
257//
258// Gets called in the ReInit() and initialized the arrays
259//
260Bool_t MExtractTimeAndChargeDigitalFilter::InitArrays()
261{
262 if (!fRunHeader)
263 return kFALSE;
264
265 const Int_t rangehi = (Int_t)(fHiGainLast - fHiGainFirst + 1 + fHiLoLast);
266 const Int_t rangelo = (Int_t)(fLoGainLast - fLoGainFirst + 1);
267
268 fHiGainSignal.Set(rangehi);
269 fLoGainSignal.Set(rangelo);
270
271 return GetWeights();
272}
273
274// --------------------------------------------------------------------------
275//
276// Check if reading a new weights file is necessary because the calibration
277// pattern has changed. (Cannot be done in ReInit, because at this time
278// the calibration pattern is not available.
279// Then process the event.
280//
281Int_t MExtractTimeAndChargeDigitalFilter::Process()
282{
283 // Change Weights if the calibration patter changes
284 if (!GetWeights())
285 return kERROR;
286
287 // Process event
288 return MExtractTimeAndCharge::Process();
289}
290
291void MExtractTimeAndChargeDigitalFilter::CalcBinningResArrays()
292{
293
294 fArrBinningResHiGain.Set(fWindowSizeHiGain);
295 fArrBinningResHalfHiGain.Set(fWindowSizeHiGain);
296
297 for (int i=0; i<fWindowSizeHiGain; i++)
298 {
299 fArrBinningResHiGain[i] = fBinningResolutionHiGain*i;
300 fArrBinningResHalfHiGain[i] = fArrBinningResHiGain[i] + fBinningResolutionHalfHiGain;
301 }
302
303 fArrBinningResLoGain.Set(fWindowSizeLoGain);
304 fArrBinningResHalfLoGain.Set(fWindowSizeLoGain);
305
306 for (int i=0; i<fWindowSizeLoGain; i++)
307 {
308 fArrBinningResLoGain[i] = fBinningResolutionLoGain*i;
309 fArrBinningResHalfLoGain[i] = fArrBinningResLoGain[i] + fBinningResolutionHalfLoGain;
310 }
311}
312
313// --------------------------------------------------------------------------
314//
315// Apply the digital filter algorithm to the high-gain slices.
316//
317void MExtractTimeAndChargeDigitalFilter::FindTimeAndChargeHiGain(Byte_t *ptr, Byte_t *logain, Float_t &sum, Float_t &dsum,
318 Float_t &time, Float_t &dtime,
319 Byte_t &sat, const MPedestalPix &ped, const Bool_t abflag)
320{
321
322 Int_t range = fHiGainLast - fHiGainFirst + 1;
323
324 const Byte_t *end = ptr + range;
325 Byte_t *p = ptr;
326 Byte_t maxpos = 0;
327
328 //
329 // Preparations for the pedestal subtraction (with AB-noise correction)
330 //
331 const Float_t pedes = ped.GetPedestal();
332 const Float_t ABoffs = ped.GetPedestalABoffset();
333
334 const Float_t pedmean[2] = { pedes + ABoffs, pedes - ABoffs };
335
336 range += fHiLoLast;
337 fMaxBinContent = 0;
338 //
339 // Check for saturation in all other slices
340 //
341 Int_t ids = fHiGainFirst;
342 Float_t *sample = fHiGainSignal.GetArray();
343 while (p<end)
344 {
345 *sample++ = (Float_t)*p - pedmean[(ids++ + abflag) & 0x1];
346
347 if (*p > fMaxBinContent)
348 {
349 maxpos = p-ptr;
350 if (maxpos > 1 && maxpos < (range - fWindowSizeHiGain + 1))
351 fMaxBinContent = *p;
352 }
353
354 if (*p++ >= fSaturationLimit)
355 if (!sat)
356 sat = ids-3;
357 }
358
359 //
360 // Slide with a window of size fWindowSizeHiGain over the sample
361 // and multiply the entries with the corresponding weights
362 //
363 if (IsNoiseCalculation())
364 {
365 if (fRandomIter == fBinningResolutionHiGain)
366 fRandomIter = 0;
367 for (Int_t ids=0; ids < fWindowSizeHiGain; ids++)
368 {
369 const Int_t idx = fArrBinningResHiGain[ids] + fRandomIter;
370 sum += fAmpWeightsHiGain [idx]*fHiGainSignal[ids];
371 }
372 fRandomIter++;
373 return;
374 }
375
376 if (fHiLoLast != 0)
377 {
378
379 end = logain + fHiLoLast;
380
381 while (logain<end)
382 {
383
384 *sample++ = (Float_t)*logain - pedmean[(ids++ + abflag) & 0x1];
385
386 if (*logain++ >= fSaturationLimit)
387 if (!sat)
388 sat = ids-3;
389 }
390 }
391
392 //
393 // allow no saturated slice
394 //
395 // if (sat > 0)
396 // return;
397
398 Float_t time_sum = 0.;
399 Float_t fmax = -9999.;
400 Float_t ftime_max = 0.;
401 Int_t max_p = 0;
402
403 //
404 // Calculate the sum of the first fWindowSize slices
405 //
406 for (Int_t i=0;i<range-fWindowSizeHiGain+1;i++)
407 {
408 sum = 0.;
409 time_sum = 0.;
410
411 //
412 // Slide with a window of size fWindowSizeHiGain over the sample
413 // and multiply the entries with the corresponding weights
414 //
415 for (Int_t sample=0; sample < fWindowSizeHiGain; sample++)
416 {
417 const Int_t idx = fBinningResolutionHiGain*sample+fBinningResolutionHalfHiGain;
418 const Float_t pex = fHiGainSignal[sample+i];
419 sum += fAmpWeightsHiGain [idx]*pex;
420 time_sum += fTimeWeightsHiGain[idx]*pex;
421 }
422
423 if (sum>fmax)
424 {
425 fmax = sum;
426 ftime_max = time_sum;
427 max_p = i;
428 }
429 } /* for (Int_t i=0;i<range-fWindowSizeHiGain+1;i++) */
430
431 if (fmax==0)
432 return;
433
434 ftime_max /= fmax;
435 Int_t t_iter = Int_t(ftime_max*fBinningResolutionHiGain);
436 Int_t sample_iter = 0;
437
438 while ( t_iter > fBinningResolutionHalfHiGain-1 || t_iter < -fBinningResolutionHalfHiGain )
439 {
440 if (t_iter > fBinningResolutionHalfHiGain-1)
441 {
442 t_iter -= fBinningResolutionHiGain;
443 max_p--;
444 sample_iter--;
445 }
446 if (t_iter < -fBinningResolutionHalfHiGain)
447 {
448 t_iter += fBinningResolutionHiGain;
449 max_p++;
450 sample_iter++;
451 }
452 }
453
454 sum = 0.;
455 time_sum = 0.;
456 if (max_p < 0)
457 max_p = 0;
458 if (max_p+fWindowSizeHiGain > range)
459 max_p = range-fWindowSizeHiGain;
460 //
461 // Slide with a window of size fWindowSizeHiGain over the sample
462 // and multiply the entries with the corresponding weights
463 //
464 for (Int_t sample=0; sample < fWindowSizeHiGain; sample++)
465 {
466 const Int_t idx = fArrBinningResHalfHiGain[sample] + t_iter;
467 const Int_t ids = max_p + sample;
468 const Float_t pex = fHiGainSignal[ids];
469 sum += fAmpWeightsHiGain [idx]*pex;
470 time_sum += fTimeWeightsHiGain[idx]*pex;
471 }
472
473 if (sum == 0)
474 return;
475
476 time = max_p + fTimeShiftHiGain + (Float_t)fHiGainFirst /* this shifts the time to the start of the rising edge */
477 - ((Float_t)t_iter)/fBinningResolutionHiGain;
478
479 const Float_t timefineadjust = time_sum/sum;
480
481 if (TMath::Abs(timefineadjust) < 4./fBinningResolutionHiGain)
482 time -= timefineadjust;
483
484}
485
486// --------------------------------------------------------------------------
487//
488// Apply the digital filter algorithm to the low-gain slices.
489//
490void MExtractTimeAndChargeDigitalFilter::FindTimeAndChargeLoGain(Byte_t *ptr, Float_t &sum, Float_t &dsum,
491 Float_t &time, Float_t &dtime,
492 Byte_t &sat, const MPedestalPix &ped, const Bool_t abflag)
493{
494
495 const Int_t range = fLoGainLast - fLoGainFirst + 1;
496
497 const Byte_t *end = ptr + range;
498 Byte_t *p = ptr;
499 //
500 // Prepare the low-gain pedestal
501 //
502 const Float_t pedes = ped.GetPedestal();
503 const Float_t ABoffs = ped.GetPedestalABoffset();
504
505 const Float_t pedmean[2] = { pedes + ABoffs, pedes - ABoffs };
506
507 //
508 // Check for saturation in all other slices
509 //
510 Float_t *sample = fLoGainSignal.GetArray();
511 Int_t ids = fLoGainFirst;
512 while (p<end)
513 {
514 *sample++ = (Float_t)*p - pedmean[(ids++ + abflag) & 0x1];
515
516 if (*p++ >= fSaturationLimit)
517 sat++;
518 }
519
520 //
521 // Slide with a window of size fWindowSizeLoGain over the sample
522 // and multiply the entries with the corresponding weights
523 //
524 if (IsNoiseCalculation())
525 {
526 if (fRandomIter == fBinningResolutionLoGain)
527 fRandomIter = 0;
528 for (Int_t ids=0; ids < fWindowSizeLoGain; ids++)
529 {
530 const Int_t idx = fArrBinningResLoGain[ids] + fRandomIter;
531 sum += fAmpWeightsLoGain [idx]*fLoGainSignal[ids];
532 }
533 return;
534 }
535
536 Float_t time_sum = 0.;
537 Float_t fmax = 0.;
538 Float_t ftime_max = 0.;
539 Int_t max_p = 0;
540
541 //
542 // Calculate the sum of the first fWindowSize slices
543 //
544 for (Int_t i=0;i<range-fWindowSizeLoGain+1;i++)
545 {
546 sum = 0.;
547 time_sum = 0.;
548
549 //
550 // Slide with a window of size fWindowSizeLoGain over the sample
551 // and multiply the entries with the corresponding weights
552 //
553 for (Int_t sample=0; sample < fWindowSizeLoGain; sample++)
554 {
555 const Int_t idx = fArrBinningResHalfLoGain[sample];
556 const Float_t pex = fLoGainSignal[sample+i];
557 sum += fAmpWeightsLoGain [idx]*pex;
558 time_sum += fTimeWeightsLoGain[idx]*pex;
559 }
560
561 if (sum>fmax)
562 {
563 fmax = sum;
564 ftime_max = time_sum;
565 max_p = i;
566 }
567 } /* for (Int_t i=0;i<range-fWindowSizeLoGain+1;i++) */
568
569 time = 0;
570 if (fmax==0)
571 return;
572
573 ftime_max /= fmax;
574 Int_t t_iter = Int_t(ftime_max*fBinningResolutionLoGain);
575 Int_t sample_iter = 0;
576
577 while ( t_iter > fBinningResolutionHalfLoGain-1 || t_iter < -fBinningResolutionHalfLoGain )
578 {
579 if (t_iter > fBinningResolutionHalfLoGain-1)
580 {
581 t_iter -= fBinningResolutionLoGain;
582 max_p--;
583 sample_iter--;
584 }
585 if (t_iter < -fBinningResolutionHalfLoGain)
586 {
587 t_iter += fBinningResolutionLoGain;
588 max_p++;
589 sample_iter++;
590 }
591 }
592
593 sum = 0.;
594 time_sum = 0.;
595
596 //
597 // Slide with a window of size fWindowSizeLoGain over the sample
598 // and multiply the entries with the corresponding weights
599 //
600 for (Int_t sample=0; sample < fWindowSizeLoGain; sample++)
601 {
602 const Int_t idx = fArrBinningResHalfLoGain[sample] + t_iter;
603 const Int_t ids = max_p + sample;
604 const Float_t pex = ids < 0 ? 0. : ( ids >= range ? 0. : fLoGainSignal[ids]);
605 sum += fAmpWeightsLoGain [idx]*pex;
606 time_sum += fTimeWeightsLoGain[idx]*pex;
607 }
608
609 if (sum == 0)
610 return;
611
612 time = max_p + fTimeShiftLoGain + (Float_t)fLoGainFirst /* this shifts the time to the start of the rising edge */
613 - ((Float_t)t_iter)/fBinningResolutionLoGain;
614
615 const Float_t timefineadjust = time_sum/sum;
616
617 if (TMath::Abs(timefineadjust) < 4./fBinningResolutionLoGain)
618 time -= timefineadjust;
619
620}
621
622// --------------------------------------------------------------------------
623//
624// Read the setup from a TEnv, eg:
625// MJPedestal.MExtractor.WindowSizeHiGain: 6
626// MJPedestal.MExtractor.WindowSizeLoGain: 6
627// MJPedestal.MExtractor.BinningResolutionHiGain: 10
628// MJPedestal.MExtractor.BinningResolutionLoGain: 10
629// MJPedestal.MExtractor.WeightsFile: filename
630// MJPedestal.MExtractor.AutomaticWeights: off
631//
632Int_t MExtractTimeAndChargeDigitalFilter::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
633{
634
635 Byte_t hw = fWindowSizeHiGain;
636 Byte_t lw = fWindowSizeLoGain;
637 Bool_t rc = kFALSE;
638
639 if (IsEnvDefined(env, prefix, "AutomaticWeights", print))
640 {
641 EnableAutomaticWeights(GetEnvValue(env, prefix, "AutomaticWeights", fAutomaticWeights));
642 rc = kTRUE;
643 }
644
645 if (IsEnvDefined(env, prefix, "WindowSizeHiGain", print))
646 {
647 hw = GetEnvValue(env, prefix, "WindowSizeHiGain", hw);
648 rc = kTRUE;
649 }
650 if (IsEnvDefined(env, prefix, "WindowSizeLoGain", print))
651 {
652 lw = GetEnvValue(env, prefix, "WindowSizeLoGain", lw);
653 rc = kTRUE;
654 }
655
656 if (rc)
657 SetWindowSize(hw, lw);
658
659 Bool_t rc2 = kFALSE;
660 Int_t brh = fBinningResolutionHiGain;
661 Int_t brl = fBinningResolutionLoGain;
662
663 if (IsEnvDefined(env, prefix, "BinningResolutionHiGain", print))
664 {
665 brh = GetEnvValue(env, prefix, brh);
666 rc2 = kTRUE;
667 }
668 if (IsEnvDefined(env, prefix, "BinningResolutionLoGain", print))
669 {
670 brl = GetEnvValue(env, prefix, brl);
671 rc2 = kTRUE;
672 }
673
674 if (rc2)
675 {
676 SetBinningResolution(brh, brl);
677 rc = kTRUE;
678 }
679
680 if (IsEnvDefined(env, prefix, "WeightsFile", print))
681 {
682 SetNameWeightsFile(GetEnvValue(env, prefix, "WeightsFile", ""));
683 rc = kTRUE;
684 }
685
686 return MExtractTimeAndCharge::ReadEnv(env, prefix, print) ? kTRUE : rc;
687}
688
689//----------------------------------------------------------------------------
690//
691// If automatic weights are requested, no default weights (name.IsNull())
692// are requested, fRunHeader is available and fRunHeader->IsMonteCarloRun()
693// is true prepend "MC_" in from of the name.
694//
695// return poth+name;
696//
697TString MExtractTimeAndChargeDigitalFilter::CompileWeightFileName(TString path, const TString &name) const
698{
699 if (fAutomaticWeights && !name.IsNull() && fRunHeader && fRunHeader->IsMonteCarloRun())
700 path += "MC_";
701
702 path += name;
703
704 return path;
705}
706
707//----------------------------------------------------------------------------
708//
709// Read a pre-defined weights file into the class.
710// This is mandatory for the extraction
711//
712// If filenname is empty, then all weights will be set to 1.
713//
714// Returns:
715// kTRUE: new weights set
716// kFALSE: no weights set
717// kERROR: error
718//
719Int_t MExtractTimeAndChargeDigitalFilter::ReadWeightsFile(TString filename, TString path)
720{
721 if (filename.IsNull())
722 {
723 fAmpWeightsHiGain .Set(fBinningResolutionHiGain*fWindowSizeHiGain);
724 fAmpWeightsLoGain .Set(fBinningResolutionLoGain*fWindowSizeLoGain);
725 fTimeWeightsHiGain.Set(fBinningResolutionHiGain*fWindowSizeHiGain);
726 fTimeWeightsLoGain.Set(fBinningResolutionLoGain*fWindowSizeLoGain);
727
728 fAmpWeightsHiGain.Reset(1);
729 fTimeWeightsHiGain.Reset(1);
730 fAmpWeightsLoGain.Reset(1);
731 fTimeWeightsLoGain.Reset(1);
732 return kTRUE;
733 }
734
735 // Add "MC_" in front of the filename if necessary
736 filename = CompileWeightFileName(path, filename);
737
738 //filename = MJob::ExpandPath(filename);
739
740 if (fNameWeightsFileSet==filename)
741 return kFALSE; // No file read
742
743 ifstream fin(filename.Data());
744 if (!fin)
745 {
746 *fLog << err << GetDescriptor() << ": ERROR - Cannot open file " << filename << ": ";
747 *fLog << strerror(errno) << endl;
748 return kERROR;
749 }
750
751 *fLog << all << GetDescriptor() << ": Reading weights in " << filename << "..." << flush;
752
753 Int_t len = 0;
754 Int_t cnt = 0;
755 Int_t line = 0;
756 Bool_t hi = kFALSE;
757 Bool_t lo = kFALSE;
758
759 TString str;
760
761 while (1)
762 {
763 str.ReadLine(fin);
764 if (!fin)
765 break;
766
767 line++;
768
769 if (str.Contains("# High Gain Weights:"))
770 {
771 if (hi)
772 {
773 *fLog << err << "ERROR - 'High Gain Weights' found twice in line #" << line << "." << endl;
774 return kERROR;
775 }
776
777 if (2!=sscanf(str.Data(), "# High Gain Weights:%2i %2i", &fWindowSizeHiGain, &fBinningResolutionHiGain))
778 {
779 *fLog << err << "ERROR - Wrong number of arguments in line #" << line << ":" << endl;
780 *fLog << str << endl;
781 return kERROR;
782 }
783
784 len = fBinningResolutionHiGain*fWindowSizeHiGain;
785 fAmpWeightsHiGain .Set(len);
786 fTimeWeightsHiGain.Set(len);
787 hi = kTRUE;
788 continue;
789 }
790
791 if (str.Contains("# Low Gain Weights:"))
792 {
793 if (lo)
794 {
795 *fLog << err << "ERROR - 'Lo Gain Weights' found twice in line #" << line << "." << endl;
796 return kERROR;
797 }
798
799 if (2!=sscanf(str.Data(),"# Low Gain Weights:%2i %2i", &fWindowSizeLoGain, &fBinningResolutionLoGain))
800 {
801 *fLog << err << "ERROR - Wrong number of arguments in line #" << line << ":" << endl;
802 *fLog << str << endl;
803 return kERROR;
804 }
805
806 len = fBinningResolutionLoGain*fWindowSizeLoGain;
807 fAmpWeightsLoGain .Set(len);
808 fTimeWeightsLoGain.Set(len);
809 lo = kTRUE;
810 continue;
811 }
812
813 // Handle lines with comments
814 if (str.Contains("#"))
815 continue;
816
817 // Nothing found so far
818 if (len == 0)
819 continue;
820
821 if (2!=sscanf(str.Data(), "%f %f",
822 lo ? &fAmpWeightsLoGain [cnt] : &fAmpWeightsHiGain [cnt],
823 lo ? &fTimeWeightsLoGain[cnt] : &fTimeWeightsHiGain[cnt]))
824 {
825 *fLog << err << "ERROR - Wrong number of arguments in line #" << line << ":" << endl;
826 *fLog << str << endl;
827 return kERROR;
828 }
829
830 if (++cnt == len)
831 {
832 len = 0;
833 cnt = 0;
834 }
835 }
836
837 if (cnt != len)
838 {
839 *fLog << err << "ERROR - Size mismatch in weights file " << filename << endl;
840 return kERROR;
841 }
842
843 if (!hi)
844 {
845 *fLog << err << "ERROR - No correct header found in weights file " << filename << endl;
846 return kERROR;
847 }
848
849 *fLog << "done." << endl;
850
851 *fLog << inf << " File contains " << fWindowSizeHiGain << " hi-gain slices ";
852 *fLog << "with a resolution of " << fBinningResolutionHiGain << endl;
853
854 *fLog << inf << " File contains " << fWindowSizeLoGain << " lo-gain slices ";
855 *fLog << "with a resolution of " << fBinningResolutionLoGain << endl;
856
857 CalcBinningResArrays();
858
859 switch (fWindowSizeHiGain)
860 {
861 case 4:
862 SetResolutionPerPheHiGain(0.036);
863 break;
864 case 6:
865 SetResolutionPerPheHiGain(0.021);
866 break;
867 default:
868 *fLog << warn << "Could not set the high-gain extractor resolution per phe for window size "
869 << fWindowSizeHiGain << endl;
870 }
871
872 switch (fWindowSizeLoGain)
873 {
874 case 4:
875 SetResolutionPerPheLoGain(0.005);
876 break;
877 case 6:
878 SetResolutionPerPheLoGain(0.004);
879 break;
880 default:
881 *fLog << warn << "Could not set the low-gain extractor resolution per phe for window size "
882 << fWindowSizeLoGain << endl;
883 }
884
885 fNameWeightsFileSet = filename;
886
887 return kTRUE;
888}
889
890
891//----------------------------------------------------------------------------
892//
893// The default (+ prepending possible "MC_") is read for:
894//
895// - RunType: Pedestal (independant of fAutomaticWeights)
896// - fAutomaticWeights disabled
897//
898// if fAutomaticWeights enabled:
899// - fNameWeightsFile.IsNull()
900// - !fCalibPattern
901// - fCalibPattern->GetPulserColor()==MCalibrationCam::kNONE
902//
903// If automatic weights are enabled, the case above didn't take place and
904// fNameWeightsFile starts with "calibration_weights_"
905// - the color (blue, UV) is replaced by the appropriate one
906// taken from the calibration pattern
907//
908// In most cases a debug output is printed. Further output about the color
909// determination can be switched on with debug level > 5;
910//
911// Returns:
912// kFALSE: No new weights set
913// kTRUE: New weights set
914// kERROR: Error
915//
916Int_t MExtractTimeAndChargeDigitalFilter::GetAutomaticWeights()
917{
918 const Ssiz_t pos = fNameWeightsFile.Last('/')+1;
919 const Ssiz_t len = fNameWeightsFile.Length();
920
921 // Split file name in path and name
922 TString path = fNameWeightsFile(0, pos>=0?pos:len);
923 TString name = fNameWeightsFile(pos>=0?pos:0, len);
924
925 // Remove trailing "MC_" for automatic weights
926 if (fAutomaticWeights && name.BeginsWith("MC_"))
927 name.Remove(0, 3);
928
929 // In case of a pedetsal run no calibration pattern can be available
930 // the default weights are always used.
931 if (fRunHeader->GetRunType()==MRawRunHeader::kRTPedestal)
932 {
933 *fLog << dbg << "Pedestal file... using default weights: " << fNameWeightsFile << endl;
934 return ReadWeightsFile(name, path);
935 }
936
937 // If automatic weights are switched off use default weights
938 if (!fAutomaticWeights)
939 {
940 *fLog << dbg << "Automatic weights switched off... using default weights: " << fNameWeightsFile << endl;
941 return ReadWeightsFile(name, path);
942 }
943
944 // If automatic weights are switched on but no filename is given raise error
945 if (fNameWeightsFile.IsNull())
946 {
947 *fLog << err << "ERROR - Cannot get automatic weights without default filename." << endl;
948 return kERROR;
949 }
950
951 // If this is no pedestal run, automatic weights are requested and a
952 // filename for the weights file is given pedestal-extraction from
953 // cosmics data is assumed.
954 if (!fCalibPattern)
955 {
956 *fLog << dbg << "No decoded calibration pattern available... using default weights: " << fNameWeightsFile << endl;
957 return ReadWeightsFile(name, path);
958 }
959
960 const Bool_t debug = gLog.GetDebugLevel()>5;
961
962 // If no calibration pattern is available do not change the
963 // current weighs or current weights file name.
964 if (fCalibPattern->GetPulserColor()==MCalibrationCam::kNONE)
965 {
966 // If we are extracting data and the calibration pattern is kNONE
967 // we assume that it is a data file without interleaved events
968 // and calibration pattern information available.
969 if ((fRunHeader->GetRunType()!=MRawRunHeader::kRTData && !fRunHeader->IsMonteCarloRun()) || debug)
970 *fLog << dbg << "No calibration color set so far... guessing default: " << fNameWeightsFile << endl;
971
972 return ReadWeightsFile(name, path);
973 }
974
975 if (debug)
976 {
977 *fLog << dbg << endl;
978 *fLog << underline << GetDescriptor() << endl;
979 *fLog << " Trying to get automatic weight for " << fNameWeightsFile << endl;
980 *fLog << " Run type: ";
981 }
982
983 if (name.BeginsWith("calibration_weights_") && fCalibPattern)
984 {
985 if (debug)
986 *fLog << " Calibration with color " << fCalibPattern->GetPulserColorStr() << ", setting ";
987 switch (fCalibPattern->GetPulserColor())
988 {
989 case MCalibrationCam::kBLUE: // 2
990 case MCalibrationCam::kGREEN: // 1
991 if (debug)
992 *fLog << "blue/green, ";
993 name.ReplaceAll("UV", "blue");
994 break;
995
996 case MCalibrationCam::kUV: // 3
997 case MCalibrationCam::kCT1: // 0
998 if (debug)
999 *fLog << "UV/CT1, ";
1000 name.ReplaceAll("blue", "UV");
1001 break;
1002 case MCalibrationCam::kNONE:
1003 break;
1004 default: // kNone + etc
1005 *fLog << err << "ERROR - Cannot get automatic weights for " << fCalibPattern->GetPulserColorStr() << endl;
1006 return kERROR;
1007 }
1008 }
1009
1010 return ReadWeightsFile(name, path);
1011}
1012
1013//----------------------------------------------------------------------------
1014//
1015// Create the weights file
1016// Beware that the shape-histogram has to contain the pulse starting at bin 1
1017//
1018Bool_t MExtractTimeAndChargeDigitalFilter::WriteWeightsFile(TString filename, TH1F *shapehi, TH2F *autocorrhi,
1019 TH1F *shapelo, TH2F *autocorrlo )
1020{
1021
1022 const Int_t nbinshi = shapehi->GetNbinsX();
1023 Float_t binwidth = shapehi->GetBinWidth(1);
1024
1025 TH1F *derivativehi = new TH1F(Form("%s%s",shapehi->GetName(),"_der"),
1026 Form("%s%s",shapehi->GetTitle()," derivative"),
1027 nbinshi,
1028 shapehi->GetBinLowEdge(1),
1029 shapehi->GetBinLowEdge(nbinshi)+binwidth);
1030
1031 //
1032 // Calculate the derivative of shapehi
1033 //
1034 for (Int_t i = 1; i<nbinshi+1;i++)
1035 {
1036 derivativehi->SetBinContent(i,
1037 ((shapehi->GetBinContent(i+1)-shapehi->GetBinContent(i-1))/2./binwidth));
1038 derivativehi->SetBinError(i,
1039 (sqrt(shapehi->GetBinError(i+1)*shapehi->GetBinError(i+1)
1040 +shapehi->GetBinError(i-1)*shapehi->GetBinError(i-1))/2./binwidth));
1041 }
1042
1043 //
1044 // normalize the shapehi, such that the integral for fWindowSize slices is one!
1045 //
1046 Float_t sum = 0;
1047 Int_t lasttemp = fBinningResolutionHiGain * (fSignalStartBinHiGain + fWindowSizeHiGain);
1048 lasttemp = lasttemp > nbinshi ? nbinshi : lasttemp;
1049
1050 for (Int_t i=fBinningResolutionHiGain*fSignalStartBinHiGain; i<lasttemp; i++) {
1051 sum += shapehi->GetBinContent(i);
1052 }
1053 sum /= fBinningResolutionHiGain;
1054
1055 shapehi->Scale(1./sum);
1056 derivativehi->Scale(1./sum);
1057
1058 //
1059 // read in the noise auto-correlation function:
1060 //
1061 TMatrix Bhi(fWindowSizeHiGain,fWindowSizeHiGain);
1062
1063 for (Int_t i=0; i<fWindowSizeHiGain; i++){
1064 for (Int_t j=0; j<fWindowSizeHiGain; j++){
1065 Bhi[i][j]=autocorrhi->GetBinContent(i+1,j+1); //+fSignalStartBinHiGain +fSignalStartBinHiGain
1066 }
1067 }
1068 Bhi.Invert();
1069
1070 const Int_t nsizehi = fWindowSizeHiGain*fBinningResolutionHiGain;
1071 fAmpWeightsHiGain.Set(nsizehi);
1072 fTimeWeightsHiGain.Set(nsizehi);
1073
1074 //
1075 // Loop over relative time in one BinningResolution interval
1076 //
1077 Int_t start = fBinningResolutionHiGain*(fSignalStartBinHiGain + 1);
1078
1079 for (Int_t i = -fBinningResolutionHalfHiGain+1; i<=fBinningResolutionHalfHiGain; i++)
1080 {
1081
1082 TMatrix g(fWindowSizeHiGain,1);
1083 TMatrix gT(1,fWindowSizeHiGain);
1084 TMatrix d(fWindowSizeHiGain,1);
1085 TMatrix dT(1,fWindowSizeHiGain);
1086
1087 for (Int_t count=0; count < fWindowSizeHiGain; count++){
1088
1089 g[count][0]=shapehi->GetBinContent(start
1090 +fBinningResolutionHiGain*count+i);
1091 gT[0][count]=shapehi->GetBinContent(start
1092 +fBinningResolutionHiGain*count+i);
1093 d[count][0]=derivativehi->GetBinContent(start
1094 +fBinningResolutionHiGain*count+i);
1095 dT[0][count]=derivativehi->GetBinContent(start
1096 +fBinningResolutionHiGain*count+i);
1097 }
1098
1099 TMatrix m_denom = (gT*(Bhi*g))*(dT*(Bhi*d)) - (dT*(Bhi*g))*(dT*(Bhi*g));
1100 Float_t denom = m_denom[0][0]; // ROOT thinks, m_denom is still a matrix
1101
1102 TMatrix m_first = dT*(Bhi*d); // ROOT thinks, m_first is still a matrix
1103 Float_t first = m_first[0][0]/denom;
1104
1105 TMatrix m_last = gT*(Bhi*d); // ROOT thinks, m_last is still a matrix
1106 Float_t last = m_last[0][0]/denom;
1107
1108 TMatrix m1 = gT*Bhi;
1109 m1 *= first;
1110
1111 TMatrix m2 = dT*Bhi;
1112 m2 *=last;
1113
1114 TMatrix w_amp = m1 - m2;
1115
1116 TMatrix m_first1 = gT*(Bhi*g);
1117 Float_t first1 = m_first1[0][0]/denom;
1118
1119 TMatrix m_last1 = gT*(Bhi*d);
1120 Float_t last1 = m_last1 [0][0]/denom;
1121
1122 TMatrix m11 = dT*Bhi;
1123 m11 *=first1;
1124
1125 TMatrix m21 = gT*Bhi;
1126 m21 *=last1;
1127
1128 TMatrix w_time= m11 - m21;
1129
1130 for (Int_t count=0; count < fWindowSizeHiGain; count++)
1131 {
1132 const Int_t idx = i+fBinningResolutionHalfHiGain+fBinningResolutionHiGain*count-1;
1133 fAmpWeightsHiGain [idx] = w_amp [0][count];
1134 fTimeWeightsHiGain[idx] = w_time[0][count];
1135 }
1136
1137 } // end loop over i
1138
1139 //
1140 // Low Gain histograms
1141 //
1142 TH1F *derivativelo = NULL;
1143 if (shapelo)
1144 {
1145 const Int_t nbinslo = shapelo->GetNbinsX();
1146 binwidth = shapelo->GetBinWidth(1);
1147
1148 derivativelo = new TH1F(Form("%s%s",shapelo->GetName(),"_der"),
1149 Form("%s%s",shapelo->GetTitle()," derivative"),
1150 nbinslo,
1151 shapelo->GetBinLowEdge(1),
1152 shapelo->GetBinLowEdge(nbinslo)+binwidth);
1153
1154 //
1155 // Calculate the derivative of shapelo
1156 //
1157 for (Int_t i = 1; i<nbinslo+1;i++)
1158 {
1159 derivativelo->SetBinContent(i,
1160 ((shapelo->GetBinContent(i+1)-shapelo->GetBinContent(i-1))/2./binwidth));
1161 derivativelo->SetBinError(i,
1162 (sqrt(shapelo->GetBinError(i+1)*shapelo->GetBinError(i+1)
1163 +shapelo->GetBinError(i-1)*shapelo->GetBinError(i-1))/2./binwidth));
1164 }
1165
1166 //
1167 // normalize the shapelo, such that the integral for fWindowSize slices is one!
1168 //
1169 sum = 0;
1170 lasttemp = fBinningResolutionLoGain * (fSignalStartBinLoGain + fWindowSizeLoGain);
1171 lasttemp = lasttemp > nbinslo ? nbinslo : lasttemp;
1172
1173 for (Int_t i=fBinningResolutionLoGain*fSignalStartBinLoGain; i<lasttemp; i++)
1174 sum += shapelo->GetBinContent(i);
1175
1176 sum /= fBinningResolutionLoGain;
1177
1178 shapelo->Scale(1./sum);
1179 derivativelo->Scale(1./sum);
1180
1181 //
1182 // read in the noise auto-correlation function:
1183 //
1184 TMatrix Blo(fWindowSizeLoGain,fWindowSizeLoGain);
1185
1186 for (Int_t i=0; i<fWindowSizeLoGain; i++){
1187 for (Int_t j=0; j<fWindowSizeLoGain; j++){
1188 Blo[i][j]=autocorrlo->GetBinContent(i+1+fSignalStartBinLoGain,j+1+fSignalStartBinLoGain);
1189 }
1190 }
1191 Blo.Invert();
1192
1193 const Int_t nsizelo = fWindowSizeLoGain*fBinningResolutionLoGain;
1194 fAmpWeightsLoGain.Set(nsizelo);
1195 fTimeWeightsLoGain.Set(nsizelo);
1196
1197 //
1198 // Loop over relative time in one BinningResolution interval
1199 //
1200 Int_t start = fBinningResolutionLoGain*fSignalStartBinLoGain + fBinningResolutionHalfLoGain;
1201
1202 for (Int_t i = -fBinningResolutionHalfLoGain+1; i<=fBinningResolutionHalfLoGain; i++)
1203 {
1204
1205 TMatrix g(fWindowSizeLoGain,1);
1206 TMatrix gT(1,fWindowSizeLoGain);
1207 TMatrix d(fWindowSizeLoGain,1);
1208 TMatrix dT(1,fWindowSizeLoGain);
1209
1210 for (Int_t count=0; count < fWindowSizeLoGain; count++){
1211
1212 g[count][0] = shapelo->GetBinContent(start
1213 +fBinningResolutionLoGain*count+i);
1214 gT[0][count]= shapelo->GetBinContent(start
1215 +fBinningResolutionLoGain*count+i);
1216 d[count][0] = derivativelo->GetBinContent(start
1217 +fBinningResolutionLoGain*count+i);
1218 dT[0][count]= derivativelo->GetBinContent(start
1219 +fBinningResolutionLoGain*count+i);
1220 }
1221
1222 TMatrix m_denom = (gT*(Blo*g))*(dT*(Blo*d)) - (dT*(Blo*g))*(dT*(Blo*g));
1223 Float_t denom = m_denom[0][0]; // ROOT thinks, m_denom is still a matrix
1224
1225 TMatrix m_first = dT*(Blo*d); // ROOT thinks, m_first is still a matrix
1226 Float_t first = m_first[0][0]/denom;
1227
1228 TMatrix m_last = gT*(Blo*d); // ROOT thinks, m_last is still a matrix
1229 Float_t last = m_last[0][0]/denom;
1230
1231 TMatrix m1 = gT*Blo;
1232 m1 *= first;
1233
1234 TMatrix m2 = dT*Blo;
1235 m2 *=last;
1236
1237 TMatrix w_amp = m1 - m2;
1238
1239 TMatrix m_first1 = gT*(Blo*g);
1240 Float_t first1 = m_first1[0][0]/denom;
1241
1242 TMatrix m_last1 = gT*(Blo*d);
1243 Float_t last1 = m_last1 [0][0]/denom;
1244
1245 TMatrix m11 = dT*Blo;
1246 m11 *=first1;
1247
1248 TMatrix m21 = gT*Blo;
1249 m21 *=last1;
1250
1251 TMatrix w_time= m11 - m21;
1252
1253 for (Int_t count=0; count < fWindowSizeLoGain; count++)
1254 {
1255 const Int_t idx = i+fBinningResolutionHalfLoGain+fBinningResolutionLoGain*count-1;
1256 fAmpWeightsLoGain [idx] = w_amp [0][count];
1257 fTimeWeightsLoGain[idx] = w_time[0][count];
1258 }
1259
1260 } // end loop over i
1261 }
1262
1263 ofstream fn(filename.Data());
1264
1265 fn << "# High Gain Weights: " << fWindowSizeHiGain << " " << fBinningResolutionHiGain << endl;
1266 fn << "# (Amplitude) (Time) " << endl;
1267
1268 for (Int_t i=0; i<nsizehi; i++)
1269 fn << "\t" << fAmpWeightsHiGain[i] << "\t" << fTimeWeightsHiGain[i] << endl;
1270
1271 fn << "# Low Gain Weights: " << fWindowSizeLoGain << " " << fBinningResolutionLoGain << endl;
1272 fn << "# (Amplitude) (Time) " << endl;
1273
1274 for (Int_t i=0; i<nsizehi; i++)
1275 fn << "\t" << fAmpWeightsLoGain[i] << "\t" << fTimeWeightsLoGain[i] << endl;
1276
1277 delete derivativehi;
1278 if (derivativelo)
1279 delete derivativelo;
1280
1281 return kTRUE;
1282}
1283
1284void MExtractTimeAndChargeDigitalFilter::Print(Option_t *o) const
1285{
1286 if (IsA()==Class())
1287 *fLog << GetDescriptor() << ":" << endl;
1288
1289 MExtractTimeAndCharge::Print(o);
1290 *fLog << " Time Shift HiGain: " << fTimeShiftHiGain << " LoGain: " << fTimeShiftLoGain << endl;
1291 *fLog << " Window Size HiGain: " << fWindowSizeHiGain << " LoGain: " << fWindowSizeLoGain << endl;
1292 *fLog << " Binning Res HiGain: " << fBinningResolutionHiGain << " LoGain: " << fBinningResolutionHiGain << endl;
1293 *fLog << " Weights File desired: " << (fNameWeightsFile.IsNull()?"-":fNameWeightsFile) << endl;
1294 if (!fNameWeightsFileSet.IsNull())
1295 *fLog << " Weights File set: " << fNameWeightsFileSet << endl;
1296
1297 TString opt(o);
1298 if (!opt.Contains("weights"))
1299 return;
1300
1301 *fLog << endl;
1302 *fLog << inf << "Using the following weights: " << endl;
1303 *fLog << "Hi-Gain:" << endl;
1304 for (Int_t i=0; i<fBinningResolutionHiGain*fWindowSizeHiGain; i++)
1305 *fLog << " " << fAmpWeightsHiGain[i] << " \t " << fTimeWeightsHiGain[i] << endl;
1306
1307 *fLog << "Lo-Gain:" << endl;
1308 for (Int_t i=0; i<fBinningResolutionLoGain*fWindowSizeLoGain; i++)
1309 *fLog << " " << fAmpWeightsLoGain[i] << " \t " << fTimeWeightsLoGain[i] << endl;
1310}
Note: See TracBrowser for help on using the repository browser.