source: trunk/Mars/msignal/MTreatSaturation.cc@ 17862

Last change on this file since 17862 was 17862, checked in by tbretz, 10 years ago
That's the best algorithm I could find within limited time. I think it is precise to a few percent level (5-15%)
File size: 4.7 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): Thomas Bretz, 2014 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2014
21!
22!
23\* ======================================================================== */
24
25//////////////////////////////////////////////////////////////////////////////
26//
27// MTreatSaturation
28//
29//////////////////////////////////////////////////////////////////////////////
30#include "MTreatSaturation.h"
31
32#include <algorithm>
33
34#include <TRandom.h>
35
36#include "MLog.h"
37#include "MLogManip.h"
38
39#include "MParList.h"
40
41#include "MRawRunHeader.h"
42#include "MExtralgoSpline.h"
43
44#include "MArrivalTimeCam.h"
45#include "MArrivalTimePix.h"
46
47#include "MExtractedSignalCam.h"
48#include "MExtractedSignalPix.h"
49
50#include "MPedestalSubtractedEvt.h"
51
52ClassImp(MTreatSaturation);
53
54using namespace std;
55
56// --------------------------------------------------------------------------
57//
58// Default constructor.
59//
60MTreatSaturation::MTreatSaturation(const char *name, const char *title)
61 : fRaw(0), fEvt(0)
62{
63 fName = name ? name : "MTreatSaturation";
64 fTitle = title ? title : "Base class for replacing saturation with pulses";
65}
66
67// --------------------------------------------------------------------------
68//
69Int_t MTreatSaturation::PreProcess(MParList *pList)
70{
71 fRaw = (MRawEvtData*)pList->FindObject("MRawEvtData");
72 if (!fRaw)
73 {
74 *fLog << err << "MRawEvtData not found... aborting." << endl;
75 return kFALSE;
76 }
77
78 fEvt = (MPedestalSubtractedEvt*)pList->FindObject("MPedestalSubtractedEvt");
79 if (!fEvt)
80 {
81 *fLog << err << "MPedestalSubtractedEvt not found... aborting." << endl;
82 return kFALSE;
83 }
84 return kTRUE;
85}
86
87// --------------------------------------------------------------------------
88//
89Int_t MTreatSaturation::Process()
90{
91 const UInt_t fHiGainFirst = 50;
92 const UInt_t fHiGainLast = 225;
93
94 const UInt_t npix = fEvt->GetNumPixels();
95
96 const UInt_t rangehi = fHiGainLast - fHiGainFirst - 1;
97
98 if (fDev1.GetSize()!=rangehi)
99 {
100 fDev1.Set(rangehi);
101 fDev2.Set(rangehi);
102 }
103
104 for (UInt_t ch=0; ch<npix; ch++)
105 {
106 Float_t *ptr = fEvt->GetSamples(ch);
107
108 const Float_t *pbeg = ptr+fHiGainFirst+1;
109 const Float_t *pend = ptr+fHiGainLast-1;
110
111 // Find maximum
112 const Float_t *pmax = pbeg;
113 for (const Float_t *p=pbeg; p<pend; p++)
114 if (*p>*pmax)
115 pmax = p;
116
117 // Is there any chance for saturation?
118 if (*pmax<1800)
119 continue;
120
121 // Determine a rough estimate for the average baseline
122 double baseline = 0;
123 for (const Float_t *p=ptr+10; p<ptr+50; p++)
124 baseline += *ptr;
125 baseline /= 40;
126
127 // Do a spline interpolation to find the crossing of 1.8V
128 // before and after the maximum
129 MExtralgoSpline s(pbeg, rangehi, fDev1.GetArray(), fDev2.GetArray());
130 s.SetExtractionType(MExtralgoSpline::kAmplitudeRel);
131
132 const double leading = s.SearchYdn(pmax-pbeg, 1800);
133 const double falling = s.SearchYup(pmax-pbeg, 1800);
134 const double width = falling-leading;
135
136 // If the width above 1.8V is below 3 samples... go ahead as usual.
137 if (width>3)
138 {
139 // Estimate the amplitude and the arrival time from the width
140 const double amplitude = (1800-baseline)/(0.898417 - 0.0187633*width + 0.000163919*width*width - 6.87369e-7*width*width*width + 1.13264e-9*width*width*width*width);
141 const double deltat = -1.41371-0.0525846*width + 93.2763/(width+13.196);
142 const double time0 = leading-deltat-1;
143
144 const Int_t beg = TMath::FloorNint(leading);
145 const Int_t end = TMath::CeilNint(falling);
146
147 ptr += fHiGainFirst+1;
148 for (Int_t i=beg-5; i<end+5; i++)
149 {
150 const double x = i-time0;
151 const double v = amplitude*(1-1/(1+exp(x/2.14)))*exp(-x/38.8)+baseline;
152 if (v>ptr[i])
153 ptr[i] = v;
154 }
155 }
156 }
157
158 return kTRUE;
159}
160
Note: See TracBrowser for help on using the repository browser.