source: branches/Mars_MC/msimcamera/MSimCamera.cc@ 17038

Last change on this file since 17038 was 17011, checked in by ftemme, 11 years ago
added the writing of several Header Keys to the fitsoutput of Ceres in MJSimulation.cc, the values of the HeaderKeys are mainly hardcoded; changed the name of the columns in the fitsoutput for MMcEvt.fEvtNumber, MRawEvtData.fStartCells to the corresponding name in real data files; removed the vetoing of several columns in the fitsout in MJSimulation.cc; implemented the substraction of the accoupling in MSimCamera.cc
File size: 11.8 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// MSimCamera
28//
29// This task initializes the analog channels with analog noise and simulated
30// the analog pulses from the photon signal.
31//
32// Input Containers:
33// MPhotonEvent
34// MPhotonStatistics
35// MRawRunHeader
36//
37// Output Containers:
38// MAnalogChannels
39//
40//////////////////////////////////////////////////////////////////////////////
41#include "MSimCamera.h"
42
43#include <TF1.h>
44#include <TRandom.h>
45
46#include "MLog.h"
47#include "MLogManip.h"
48
49#include "MSpline3.h"
50#include "MParSpline.h"
51
52#include "MParList.h"
53
54#include "MPhotonEvent.h"
55#include "MPhotonData.h"
56
57#include "MPedestalCam.h"
58#include "MPedestalPix.h"
59
60#include "MAnalogSignal.h"
61#include "MAnalogChannels.h"
62
63#include "MMcEvt.hxx" // To be replaced by a CheObs class
64#include "MRawRunHeader.h"
65
66ClassImp(MSimCamera);
67
68using namespace std;
69
70// --------------------------------------------------------------------------
71//
72// Default Constructor.
73//
74MSimCamera::MSimCamera(const char* name, const char *title)
75 : fEvt(0), fStat(0), fRunHeader(0), fElectronicNoise(0), fGain(0),
76 fCamera(0), fMcEvt(0), fSpline(0), fBaselineGain(kFALSE),
77 fDefaultOffset(-1), fDefaultNoise(-1), fDefaultGain(-1)
78
79{
80 fName = name ? name : "MSimCamera";
81 fTitle = title ? title : "Task to simulate the electronic noise and to convert photons into pulses";
82}
83
84// --------------------------------------------------------------------------
85//
86// Search for the necessayr parameter containers.
87// Setup spline for pulse shape.
88//
89Int_t MSimCamera::PreProcess(MParList *pList)
90{
91 fMcEvt = (MMcEvt*)pList->FindCreateObj("MMcEvt");
92 if (!fMcEvt)
93 return kFALSE;
94
95 fCamera = (MAnalogChannels*)pList->FindCreateObj("MAnalogChannels");
96 if (!fCamera)
97 return kFALSE;
98
99 fEvt = (MPhotonEvent*)pList->FindObject("MPhotonEvent");
100 if (!fEvt)
101 {
102 *fLog << err << "MPhotonEvent not found... aborting." << endl;
103 return kFALSE;
104 }
105
106 fStat = (MPhotonStatistics*)pList->FindObject("MPhotonStatistics");
107 if (!fStat)
108 {
109 *fLog << err << "MPhotonStatistics not found... aborting." << endl;
110 return kFALSE;
111 }
112
113 fRunHeader = (MRawRunHeader *)pList->FindObject("MRawRunHeader");
114 if (!fRunHeader)
115 {
116 *fLog << err << "MRawRunHeader not found... aborting." << endl;
117 return kFALSE;
118 }
119/*
120 fPulsePos = (MParameterD*)pList->FindObject("IntendedPulsePos", "MParameterD");
121 if (!fPulsePos)
122 {
123 *fLog << err << "IntendedPulsePos [MParameterD] not found... aborting." << endl;
124 return kFALSE;
125 }
126 */
127
128 // Create it here to make sure that MGeomApply will set the correct size
129 fElectronicNoise = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", "ElectronicNoise");
130 if (!fElectronicNoise)
131 return kFALSE;
132
133 fGain = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", "Gain");
134 if (!fGain)
135 return kFALSE;
136
137 fAccidentalPhotons = (MPedestalCam*)pList->FindObject("AccidentalPhotonRates","MPedestalCam");
138 if(!fAccidentalPhotons)
139 {
140 *fLog << err << "AccidentalPhotonRates [MPedestalCam] not found... aborting." << endl;
141 return kFALSE;
142 }
143
144 MParSpline *pulse = (MParSpline*)pList->FindObject("PulseShape", "MParSpline");
145 if (!pulse)
146 {
147 *fLog << err << "PulseShape [MParSpline] not found... aborting." << endl;
148 return kFALSE;
149 }
150
151 if (fRunHeader->GetFreqSampling()!=1000)
152 {
153 *fLog << err << "ERROR - Sampling frequencies others than 1GHz are not yet supported." << endl;
154 *fLog << warn << "FIXME - SCALE MPulsShape WITH THE SAMPLING FREQUENCY." << endl;
155 return kFALSE;
156 }
157
158 fSpline = pulse->GetSpline();
159 if (!fSpline)
160 {
161 *fLog << err << "No spline initialized." << endl;
162 return kFALSE;
163 }
164
165 // ---------------- Information output ----------------------
166
167 if (fBaselineGain)
168 *fLog << inf << "Gain is also applied to the electronic noise." << endl;
169
170 return kTRUE;
171}
172
173// --------------------------------------------------------------------------
174//
175// FIXME: For now this is a workaround to set a baseline and the
176// electronic (guassian noise)
177//
178Bool_t MSimCamera::ReInit(MParList *plist)
179{
180 for (int i=0; i<fElectronicNoise->GetSize(); i++)
181 {
182 MPedestalPix &ped = (*fElectronicNoise)[i];
183 if (fDefaultOffset>0)
184 ped.SetPedestal(fDefaultOffset);
185 if (fDefaultNoise>0)
186 ped.SetPedestalRms(fDefaultNoise);
187
188 ped.SetPedestalABoffset(0);
189 ped.SetNumEvents(0);
190
191
192 MPedestalPix &gain = (*fGain)[i];
193 if (fDefaultGain>0)
194 gain.SetPedestal(fDefaultGain);
195
196 gain.SetPedestalRms(0);
197 gain.SetPedestalABoffset(0);
198 gain.SetNumEvents(0);
199 }
200
201 return kTRUE;
202}
203
204// --------------------------------------------------------------------------
205//
206// fStat->GetMaxIndex must return the maximum index possible
207// (equiv. number of pixels) not just the maximum index stored!
208//
209Int_t MSimCamera::Process()
210{
211 // Calculate start time, end time and corresponding number of samples
212 const Double_t freq = fRunHeader->GetFreqSampling()/1000.;
213
214 // FIXME: Should we use a higher sampling here?
215
216 const Double_t start = fStat->GetTimeFirst()*freq;
217 const Double_t end = fStat->GetTimeLast() *freq;
218
219 const UInt_t nlen = TMath::CeilNint(end-start);
220
221 // Get number of pixels/channels
222 const UInt_t npix = fStat->GetMaxIndex()+1;
223
224 if (npix>(UInt_t)fElectronicNoise->GetSize())
225 {
226 *fLog << err << "ERROR - More indices (" << npix << ") ";
227 *fLog << "assigned than existing in camera (";
228 *fLog << fElectronicNoise->GetSize() << ")!" << endl;
229 return kERROR;
230 }
231
232 const Double_t pl = fSpline->GetXmin()*freq;
233 const Double_t pr = fSpline->GetXmax()*freq;
234
235 // Init the arrays and set the range which will contain valid data
236 fCamera->Init(npix, nlen);
237 fCamera->SetValidRange(TMath::FloorNint(pr), TMath::CeilNint(nlen+pl));
238
239 // Add electronic noise to empty channels
240 for (UInt_t i=0; i<npix; i++)
241 {
242 const MPedestalPix &pix = (*fElectronicNoise)[i];
243
244 const Double_t val = pix.GetPedestal();
245 const Double_t rms = pix.GetPedestalRms();
246
247 // FTemme: Implementation of AC-coupling:
248 // to calculate the value of the accoupling per slice I use the
249 // following equation:
250 // accouplingPerSlice = accidentalPhotonRate * (1 + crossTalkProb)
251 // * areaOfOnePulse / samplingRate;
252 // Therefore I need the following variables
253 Double_t accidentalPhotonRate = 0; // [MHz]
254 Float_t crossTalkProb = 0; // [1]
255 Double_t areaOfOnePulse = 0; // [ADC-Counts * s]
256 Double_t samplingRate = 0; // [slices * MHz]
257
258 // The accidental photon rate is stored in GHz, so we have to multiply
259 // with 1E3 to get MHz:
260 MPedestalPix &accPhoPix = (*fAccidentalPhotons)[i];
261 accidentalPhotonRate = accPhoPix.GetPedestal() * 1E3;
262
263 // I don't know how to get the variable fCrosstalkProb from
264 // the class APD (see MAvalanchePhotoDiode.h), because there is no
265 // getter for the APD array(fAPDs) in MSimAPD.
266 // So I set the crossTalkProb hardcoded to the value 0.15, which is
267 // equal to the value of the apd of type 4
268 crossTalkProb = 0.15;
269
270 // To get the area of one Pulse, I only need to calculate the Integral
271 // of the Pulse Shape, which is stored in fSpline. Because the spline is
272 // normalized to a maximal amplitude of 1.0, I had to multiply it with
273 // the Default gain:
274 areaOfOnePulse = fSpline->Integral() * fDefaultGain;
275
276 // The sampling rate I get from the RunHeader:
277 samplingRate = fRunHeader->GetFreqSampling();
278
279 Double_t accouplingPerSlice = accidentalPhotonRate * (1 + crossTalkProb)
280 * areaOfOnePulse / samplingRate;
281
282 // The accoupling is substracted from the timeline by decreasing the
283 // mean of the gaussian noise which is added
284
285 if (!fBaselineGain)
286 {
287 (*fCamera)[i].AddGaussianNoise(rms, val - accouplingPerSlice);
288 continue;
289 }
290 // Sorry, the name "pedestal" is misleading here
291 // FIXME: Simulate gain fluctuations
292 const Double_t gain = (*fGain)[i].GetPedestal();
293
294 // FIXME: We might add the base line here already.
295 // FIXME: How stable is the offset?
296 // FIXME: Should we write a container AppliedGain for MSImTrigger?
297
298 (*fCamera)[i].AddGaussianNoise(rms*gain, (val - accouplingPerSlice)*gain);
299 }
300
301 // FIXME: Simulate correlations with neighboring pixels
302
303 const Int_t num = fEvt->GetNumPhotons();
304
305 // A random shift, uniformely distributed within one slice, to make sure that
306 // the first photon is not always aligned identically with a sample edge.
307 // FIXME: Make it switchable
308 const Float_t rndm = gRandom->Uniform();
309
310 // FIXME: Shell we add a random shift of [0,1] samples per channel?
311 // Or maybe per channel and run?
312
313 Double_t tot = 0;
314
315 // Simulate pulses
316 for (Int_t i=0; i<num; i++)
317 {
318 const MPhotonData &ph = (*fEvt)[i];
319
320 const UInt_t idx = ph.GetTag();
321 const Double_t t = (ph.GetTime()-fStat->GetTimeFirst())*freq+rndm;// - fSpline->GetXmin();
322
323 // FIXME: Time jitter?
324 // FIXME: Add additional routing here?
325 // FIMXE: How stable is the gain?
326
327 if (ph.GetPrimary()!=MMcEvt::kNightSky && ph.GetPrimary()!=MMcEvt::kArtificial)
328 tot += ph.GetWeight();
329
330 // Sorry, the name "pedestal" is misleading here
331 // FIXME: Simulate gain fluctuations
332 const Double_t gain = (*fGain)[idx].GetPedestal();
333
334 // === FIXME === FIXME === FIXME === Frequency!!!!
335 (*fCamera)[idx].AddPulse(*fSpline, t, ph.GetWeight()*gain);
336 }
337
338 fMcEvt->SetPhotElfromShower(TMath::Nint(tot));
339
340 return kTRUE;
341}
342
343// --------------------------------------------------------------------------
344//
345// BaselineGain: Off
346//
347Int_t MSimCamera::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
348{
349 Bool_t rc = kFALSE;
350 if (IsEnvDefined(env, prefix, "BaselineGain", print))
351 {
352 rc = kTRUE;
353 fBaselineGain = GetEnvValue(env, prefix, "BaselineGain", fBaselineGain);
354 }
355
356 if (IsEnvDefined(env, prefix, "DefaultOffset", print))
357 {
358 rc = kTRUE;
359 fDefaultOffset = GetEnvValue(env, prefix, "DefaultOffset", fDefaultOffset);
360 }
361 if (IsEnvDefined(env, prefix, "DefaultNoise", print))
362 {
363 rc = kTRUE;
364 fDefaultNoise = GetEnvValue(env, prefix, "DefaultNoise", fDefaultNoise);
365 }
366 if (IsEnvDefined(env, prefix, "DefaultGain", print))
367 {
368 rc = kTRUE;
369 fDefaultGain = GetEnvValue(env, prefix, "DefaultGain", fDefaultGain);
370 }
371
372 return rc;
373}
Note: See TracBrowser for help on using the repository browser.