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

Last change on this file since 9256 was 9256, 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
45#include "MLog.h"
46#include "MLogManip.h"
47
48#include "MSpline3.h"
49
50#include "MParList.h"
51
52#include "MPhotonEvent.h"
53#include "MPhotonData.h"
54
55#include "MAnalogSignal.h"
56#include "MAnalogChannels.h"
57
58#include "MRawRunHeader.h"
59
60ClassImp(MSimCamera);
61
62using namespace std;
63
64// --------------------------------------------------------------------------
65//
66// Default Constructor.
67//
68MSimCamera::MSimCamera(const char* name, const char *title)
69: fEvt(0), fStat(0), fRunHeader(0), fCamera(0), fSpline(0),
70 fFunction("exp(-(x/2)^2/2)"), fNpx(25), fXmin(-25), fXmax(25)
71{
72 fName = name ? name : "MSimCamera";
73 fTitle = title ? title : "Task to simulate the electronic noise and to convert photons into pulses";
74}
75
76// --------------------------------------------------------------------------
77//
78// Call Clear()
79//
80MSimCamera::~MSimCamera()
81{
82 Clear();
83}
84
85// --------------------------------------------------------------------------
86//
87// Delete fSpline if set and set it to 0
88//
89void MSimCamera::Clear(Option_t *)
90{
91 if (fSpline)
92 delete fSpline;
93 fSpline=0;
94}
95
96// --------------------------------------------------------------------------
97//
98// Read the intended pulse shape from a file and initialize the spline
99// accordingly
100//
101Bool_t MSimCamera::ReadFile(const char *fname)
102{
103 if (!fRunHeader)
104 return kFALSE;
105
106 if (fname)
107 fFileName = fname;
108
109 *fLog << inf << "Reading pulse shape from " << fFileName << endl;
110
111 const TGraph g(fFileName);
112 if (g.GetN()==0)
113 {
114 *fLog << err << "ERROR - No data points from " << fFileName << "." << endl;
115 return kFALSE;
116 }
117
118 // option: b1/e1 b2/e2 (first second derivative?)
119 // option: valbeg/valend (first second derivative?)
120
121 Clear();
122 fSpline = new MSpline3(g, fRunHeader->GetFreqSampling()/1000.);
123
124 return kTRUE;
125}
126
127void MSimCamera::SetFunction(const TF1 &f)
128{
129 // FIXME: Use TF1 directly? (In most cases this seems to be slower)
130 if (!fRunHeader)
131 return;// kFALSE;
132
133 // option: b1/e1 b2/e2 (first second derivative?)
134 // option: valbeg/valend (first second derivative?)
135
136 // if (f.GetNpar()==0)
137 // No SUPPORT
138
139 Clear();
140 fSpline = new MSpline3(f, fRunHeader->GetFreqSampling()/1000.);
141
142 fFunction = f.GetTitle();
143}
144
145Bool_t MSimCamera::SetFunction(const char *func, Int_t n, Double_t xmin, Double_t xmax)
146{
147 // FIXME: Use TF1 directly? (In most cases this seems to be slower)
148 TF1 f("f", func, xmin, xmax);
149 f.SetNpx(n);
150
151 SetFunction(f);
152
153 return kTRUE;
154}
155
156// --------------------------------------------------------------------------
157//
158// SetReadyToSave for fRunHeader
159//
160Bool_t MSimCamera::ReInit(MParList *pList)
161{
162 // make that the run-header gets written to the file
163 fRunHeader->SetReadyToSave();
164
165 return kTRUE;
166}
167
168// --------------------------------------------------------------------------
169//
170// Search for the necessayr parameter containers.
171// Setup spline for pulse shape.
172//
173Int_t MSimCamera::PreProcess(MParList *pList)
174{
175 fCamera = (MAnalogChannels*)pList->FindCreateObj("MAnalogChannels");
176 if (!fCamera)
177 return kFALSE;
178
179 fEvt = (MPhotonEvent*)pList->FindObject("MPhotonEvent");
180 if (!fEvt)
181 {
182 *fLog << err << "MPhotonEvent not found... aborting." << endl;
183 return kFALSE;
184 }
185
186 fStat = (MPhotonStatistics*)pList->FindObject("MPhotonStatistics");
187 if (!fStat)
188 {
189 *fLog << err << "MPhotonStatistics not found... aborting." << endl;
190 return kFALSE;
191 }
192
193 fRunHeader = (MRawRunHeader *)pList->FindObject("MRawRunHeader");
194 if (!fRunHeader)
195 {
196 *fLog << err << "MRawRunHeader not found... aborting." << endl;
197 return kFALSE;
198 }
199
200
201 // FIMXE: Move to ReInit in case fRunHeader is read form file?
202 if (!fFileName.IsNull())
203 return ReadFile(fFileName);
204
205 if (!fFunction.IsNull())
206 return SetFunction(fFunction, fNpx, fXmin, fXmax);
207
208 if (!fSpline)
209 {
210 *fLog << err << "No spline initialized." << endl;
211 return kFALSE;
212 }
213
214 return kTRUE;
215}
216
217// --------------------------------------------------------------------------
218//
219// fStat->GetMaxIndex must return the maximum index possible
220// (equiv. number of pixels) not just the maximum index stored!
221//
222Int_t MSimCamera::Process()
223{
224 // Calculate start time, end time and corresponding number of samples
225 const Double_t freq = fRunHeader->GetFreqSampling()/1000.;
226
227 const Double_t start = fStat->GetTimeFirst()*freq + fSpline->GetXmin();
228 const Double_t end = fStat->GetTimeLast() *freq + fSpline->GetXmax();
229
230 const UInt_t nlen = TMath::CeilNint(end-start);
231
232 // FIXME: Jitter the start point of digitization by one sample [0;1]
233 // FIXME: TAKE PULSE WIDTH out of the calculation and start at TimeFirst
234
235 // Get number of pixels/channels
236 const UInt_t npix = fStat->GetMaxIndex()+1;
237
238 // Init the arrays and set the range which will contain valid data
239 fCamera->Init(npix, nlen);
240 fCamera->SetValidRange(0 -TMath::FloorNint(fSpline->GetXmin()),
241 nlen-TMath::CeilNint( fSpline->GetXmax()));
242
243 // Add electronic noise to empty channels
244 for (UInt_t i=0; i<npix; i++)
245 {
246 // FIXME: We might add the base line here already.
247 (*fCamera)[i].AddGaussianNoise(22.5/64);
248 }
249
250 // FIXME: Simulate correlations with neighboring pixels
251
252 const Int_t num = fEvt->GetNumPhotons();
253
254 // Simulate pulses
255 for (Int_t i=0; i<num; i++)
256 {
257 const MPhotonData &ph = (*fEvt)[i];
258
259 const UInt_t idx = ph.GetTag();
260 const Double_t t = (ph.GetTime()-fStat->GetTimeFirst())*freq - fSpline->GetXmin();
261
262 // FIXME: Time jitter?
263 // FIXME: Add additional routing here?
264
265 (*fCamera)[idx].AddPulse(*fSpline, t, ph.GetWeight());
266 }
267
268 return kTRUE;
269}
270
271// --------------------------------------------------------------------------
272//
273// FileName: pulse-shape.txt
274// Function.Name: gaus
275// Function.Npx: 50
276// Function.Xmin: -5
277// Function.Xmax: 5
278//
279Int_t MSimCamera::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
280{
281 Bool_t rc = kFALSE;
282 if (IsEnvDefined(env, prefix, "FileName", print))
283 {
284 rc = kTRUE;
285 SetFileName(GetEnvValue(env, prefix, "FileName", fFileName));
286 }
287
288 if (IsEnvDefined(env, prefix, "Function.Name", print))
289 {
290 rc = kTRUE;
291 SetFunction(GetEnvValue(env, prefix, "Function.Name", fFunction));
292
293 if (IsEnvDefined(env, prefix, "Function.Npx", print))
294 fNpx = GetEnvValue(env, prefix, "Function.Npx", fNpx);
295 if (IsEnvDefined(env, prefix, "Function.Xmin", print))
296 fXmin = GetEnvValue(env, prefix, "Function.Xmin", fXmin);
297 if (IsEnvDefined(env, prefix, "Function.Xmax", print))
298 fXmax = GetEnvValue(env, prefix, "Function.Xmax", fXmax);
299 }
300
301 return rc;
302}
303
304/*
305MSimCameraFiles::Process()
306{
307 // fCorsikaHeader->GetEvtNumber() --> fMcEvt->SetEvtNumber()
308 // fCorsikaHeader->GetTotalEnergy() --> fMcEvt->SetEnergy()
309 // fCorsikaHeader->GetParticleID() --> fMcEvt->SetParticleID()
310 // fCorsikaHeader->GetImpact() --> fMcEvt->SetImpact()
311 // fCorsikaHeader->GetTheta() --> fMcEvt->SetTheta()
312 // fCorsikaHeader->GetPhi() --> fMcEvt->SetPhi()
313 // fPointingPos->GetTheta() --> fMcEvt->SetTelescopeTheta()
314 // fPointingPos->GetPhi() --> fMcEvt->SetTelescopePhi()
315 // fStats->GetTimeFirst() --> fMcEvt->SetTimeFirst()
316 // fStats->GetTimeLast() --> fMcEvt->SetTimeLast()
317 // fMcEvt->SetReuse()
318 // MMcCorsikaRunHeader: fSlopeSpec, fELowLim, fEUppLim;
319
320 fMcEvt->Fill(*fCorsikaHeader, *fPointingPos, *fStats);
321
322 return kTRUE;
323}
324*/
325
Note: See TracBrowser for help on using the repository browser.