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

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