source: trunk/MagicSoft/Mars/msimcamera/MSimCamera.cc@ 9422

Last change on this file since 9422 was 9413, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 9.1 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 "MPulseShape.h"
51
52#include "MParList.h"
53//#include "MParameters.h"
54
55#include "MPhotonEvent.h"
56#include "MPhotonData.h"
57
58#include "MPedestalCam.h"
59#include "MPedestalPix.h"
60
61#include "MAnalogSignal.h"
62#include "MAnalogChannels.h"
63
64#include "MMcEvt.hxx" // To be replaced by a CheObs class
65#include "MRawRunHeader.h"
66
67ClassImp(MSimCamera);
68
69using namespace std;
70
71// --------------------------------------------------------------------------
72//
73// Default Constructor.
74//
75MSimCamera::MSimCamera(const char* name, const char *title)
76 : fEvt(0), fStat(0), fRunHeader(0), fElectronicNoise(0), fGain(0),
77 fCamera(0), fMcEvt(0), fSpline(0), fBaselineGain(kFALSE)
78{
79 fName = name ? name : "MSimCamera";
80 fTitle = title ? title : "Task to simulate the electronic noise and to convert photons into pulses";
81}
82
83// --------------------------------------------------------------------------
84//
85// Search for the necessayr parameter containers.
86// Setup spline for pulse shape.
87//
88Int_t MSimCamera::PreProcess(MParList *pList)
89{
90 fMcEvt = (MMcEvt*)pList->FindCreateObj("MMcEvt");
91 if (!fMcEvt)
92 return kFALSE;
93
94 fCamera = (MAnalogChannels*)pList->FindCreateObj("MAnalogChannels");
95 if (!fCamera)
96 return kFALSE;
97
98 fEvt = (MPhotonEvent*)pList->FindObject("MPhotonEvent");
99 if (!fEvt)
100 {
101 *fLog << err << "MPhotonEvent not found... aborting." << endl;
102 return kFALSE;
103 }
104
105 fStat = (MPhotonStatistics*)pList->FindObject("MPhotonStatistics");
106 if (!fStat)
107 {
108 *fLog << err << "MPhotonStatistics not found... aborting." << endl;
109 return kFALSE;
110 }
111
112 fRunHeader = (MRawRunHeader *)pList->FindObject("MRawRunHeader");
113 if (!fRunHeader)
114 {
115 *fLog << err << "MRawRunHeader not found... aborting." << endl;
116 return kFALSE;
117 }
118/*
119 fPulsePos = (MParameterD*)pList->FindObject("IntendedPulsePos", "MParameterD");
120 if (!fPulsePos)
121 {
122 *fLog << err << "IntendedPulsePos [MParameterD] not found... aborting." << endl;
123 return kFALSE;
124 }
125 */
126
127 // Create it here to make sure that MGeomApply will set the correct size
128 fElectronicNoise = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", "ElectronicNoise");
129 if (!fElectronicNoise)
130 return kFALSE;
131
132 fGain = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", "Gain");
133 if (!fGain)
134 return kFALSE;
135
136 MPulseShape *pulse = (MPulseShape*)pList->FindObject("MPulseShape");
137 if (!pulse)
138 {
139 *fLog << err << "MPulseShape not found... aborting." << endl;
140 return kFALSE;
141 }
142
143 if (fRunHeader->GetFreqSampling()!=1000)
144 {
145 *fLog << err << "ERROR - Sampling frequencies others than 1GHz are not yet supported." << endl;
146 *fLog << warn << "FIXME - SCALE MPulsShape WITH THE SAMPLING FREQUENCY." << endl;
147 return kFALSE;
148 }
149
150 fSpline = pulse->GetSpline();
151 if (!fSpline)
152 {
153 *fLog << err << "No spline initialized." << endl;
154 return kFALSE;
155 }
156
157 // ---------------- Information output ----------------------
158
159 if (fBaselineGain)
160 *fLog << inf << "Gain is also applied to the electronic noise." << endl;
161
162 return kTRUE;
163}
164
165// --------------------------------------------------------------------------
166//
167// FIXME: For now this is a workaround to set a baseline and the
168// electronic (guassian noise)
169//
170Bool_t MSimCamera::ReInit(MParList *plist)
171{
172 for (int i=0; i<fElectronicNoise->GetSize(); i++)
173 {
174 // 64 -> Dynamic range 12 bit left
175 MPedestalPix &ped = (*fElectronicNoise)[i];
176 ped.SetPedestal(15*64); // Baseline at 15 like in MAGIC
177 ped.SetPedestalRms(1.5*64); //2.0); // 1.5 bit noise for a gain of 64
178 ped.SetPedestalABoffset(0);
179 ped.SetNumEvents(0);
180
181 // 256 scale from 8bit to 16bit
182 // 8 signal height of one phe
183 MPedestalPix &gain = (*fGain)[i];
184 gain.SetPedestal(4*64); // This allows a maximum of 200phe/pix
185 gain.SetPedestalRms(0);
186 gain.SetPedestalABoffset(0);
187 gain.SetNumEvents(0);
188 }
189 return kTRUE;
190}
191
192// --------------------------------------------------------------------------
193//
194// fStat->GetMaxIndex must return the maximum index possible
195// (equiv. number of pixels) not just the maximum index stored!
196//
197Int_t MSimCamera::Process()
198{
199 // Calculate start time, end time and corresponding number of samples
200 const Double_t freq = fRunHeader->GetFreqSampling()/1000.;
201
202 // FIXME: Should we use a higher sampling here?
203
204 const Double_t start = fStat->GetTimeFirst()*freq;
205 const Double_t end = fStat->GetTimeLast() *freq;
206
207 const UInt_t nlen = TMath::CeilNint(end-start);
208
209 // Get number of pixels/channels
210 const UInt_t npix = fStat->GetMaxIndex()+1;
211
212 if (npix>(UInt_t)fElectronicNoise->GetSize())
213 {
214 *fLog << err << "ERROR - More indices (" << npix << ") ";
215 *fLog << "assigned than existing in camera (";
216 *fLog << fElectronicNoise->GetSize() << ")!" << endl;
217 return kERROR;
218 }
219
220 const Double_t pl = fSpline->GetXmin()*freq;
221 const Double_t pr = fSpline->GetXmax()*freq;
222
223 // Init the arrays and set the range which will contain valid data
224 fCamera->Init(npix, nlen);
225 fCamera->SetValidRange(TMath::FloorNint(pr), TMath::CeilNint(nlen+pl));
226
227 // Add electronic noise to empty channels
228 for (UInt_t i=0; i<npix; i++)
229 {
230 const MPedestalPix &pix = (*fElectronicNoise)[i];
231
232 const Double_t val = pix.GetPedestal();
233 const Double_t rms = pix.GetPedestalRms();
234
235 if (!fBaselineGain)
236 {
237 (*fCamera)[i].AddGaussianNoise(rms, val);
238 continue;
239 }
240 // Sorry, the name "pedestal" is misleading here
241 // FIXME: Simulate gain fluctuations
242 const Double_t gain = (*fGain)[i].GetPedestal();
243
244 // FIXME: We might add the base line here already.
245 // FIXME: How stable is the offset?
246 // FIXME: Should we write a container AppliedGain for MSImTrigger?
247 (*fCamera)[i].AddGaussianNoise(rms*gain, val*gain);
248 }
249
250 // FIXME: Simulate correlations with neighboring pixels
251
252 const Int_t num = fEvt->GetNumPhotons();
253
254 // A random shift, uniformely distributed within one slice, to make sure that
255 // the first photon is not always aligned identically with a sample edge.
256 // FIXME: Make it switchable
257 const Float_t rndm = gRandom->Uniform();
258
259 // FIXME: Shell we add a random shift of [0,1] samples per channel?
260 // Or maybe per channel and run?
261
262 Double_t tot = 0;
263
264 // Simulate pulses
265 for (Int_t i=0; i<num; i++)
266 {
267 const MPhotonData &ph = (*fEvt)[i];
268
269 const UInt_t idx = ph.GetTag();
270 const Double_t t = (ph.GetTime()-fStat->GetTimeFirst())*freq+rndm;// - fSpline->GetXmin();
271
272 // FIXME: Time jitter?
273 // FIXME: Add additional routing here?
274 // FIMXE: How stable is the gain?
275
276 if (ph.GetPrimary()!=MMcEvt::kNightSky)
277 tot += ph.GetWeight();
278
279 // Sorry, the name "pedestal" is misleading here
280 // FIXME: Simulate gain fluctuations
281 const Double_t gain = (*fGain)[idx].GetPedestal();
282
283 // === FIXME === FIXME === FIXME === Frequency!!!!
284 (*fCamera)[idx].AddPulse(*fSpline, t, ph.GetWeight()*gain);
285 }
286
287 fMcEvt->SetPhotElfromShower(TMath::Nint(tot));
288
289 return kTRUE;
290}
291
292// --------------------------------------------------------------------------
293//
294// BaselineGain: Off
295//
296Int_t MSimCamera::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
297{
298 Bool_t rc = kFALSE;
299 if (IsEnvDefined(env, prefix, "BaselineGain", print))
300 {
301 rc = kTRUE;
302 fBaselineGain = GetEnvValue(env, prefix, "BaselineGain", fBaselineGain);
303 }
304
305 return rc;
306}
Note: See TracBrowser for help on using the repository browser.