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

Last change on this file since 9492 was 9425, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 10.0 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// MSimRandomPhotons
28//
29// Simulate poissonian photons. Since the distribution of the arrival time
30// differences of these photons is an exonential we can simulate them
31// using exponentially distributed time differences between two consecutive
32// photons.
33//
34// FIXME: We should add the wavelength distribution.
35//
36// Input Containers:
37// fNameGeomCam [MGeomCam]
38// MPhotonEvent
39// MPhotonStatistics
40// MCorsikaEvtHeader
41// [MCorsikaRunHeader]
42//
43// Output Containers:
44// MPhotonEvent
45// AccidentalPhotonRate [MPedestalCam]
46//
47//////////////////////////////////////////////////////////////////////////////
48#include "MSimRandomPhotons.h"
49
50#include <TRandom.h>
51
52#include "MMath.h" // RndmExp
53
54#include "MLog.h"
55#include "MLogManip.h"
56
57#include "MParList.h"
58
59#include "MGeomCam.h"
60#include "MGeom.h"
61
62#include "MPhotonEvent.h"
63#include "MPhotonData.h"
64
65#include "MPedestalCam.h"
66#include "MPedestalPix.h"
67
68#include "MCorsikaRunHeader.h"
69
70#include "MSpline3.h"
71#include "MParSpline.h"
72#include "MReflector.h"
73
74ClassImp(MSimRandomPhotons);
75
76using namespace std;
77
78// --------------------------------------------------------------------------
79//
80// Default Constructor.
81//
82MSimRandomPhotons::MSimRandomPhotons(const char* name, const char *title)
83 : fGeom(0), fEvt(0), fStat(0), /*fEvtHeader(0),*/ fRunHeader(0),
84 fRates(0), fSimulateWavelength(kFALSE), fNameGeomCam("MGeomCam")
85{
86 fName = name ? name : "MSimRandomPhotons";
87 fTitle = title ? title : "Simulate possonian photons (like NSB or dark current)";
88}
89
90// --------------------------------------------------------------------------
91//
92// Check for the necessary containers
93//
94Int_t MSimRandomPhotons::PreProcess(MParList *pList)
95{
96 fGeom = (MGeomCam*)pList->FindObject(fNameGeomCam, "MGeomCam");
97 if (!fGeom)
98 {
99 *fLog << inf << fNameGeomCam << " [MGeomCam] not found..." << endl;
100
101 fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
102 if (!fGeom)
103 {
104 *fLog << err << "MGeomCam not found... aborting." << endl;
105 return kFALSE;
106 }
107 }
108
109 fEvt = (MPhotonEvent*)pList->FindObject("MPhotonEvent");
110 if (!fEvt)
111 {
112 *fLog << err << "MPhotonEvent not found... aborting." << endl;
113 return kFALSE;
114 }
115
116 fStat = (MPhotonStatistics*)pList->FindObject("MPhotonStatistics");
117 if (!fStat)
118 {
119 *fLog << err << "MPhotonStatistics not found... aborting." << endl;
120 return kFALSE;
121 }
122
123 fRates = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", "AccidentalPhotonRates");
124 if (!fRates)
125 return kFALSE;
126
127 /*
128 fEvtHeader = (MCorsikaEvtHeader*)pList->FindObject("MCorsikaEvtHeader");
129 if (!fEvtHeader)
130 {
131 *fLog << err << "MCorsikaEvtHeader not found... aborting." << endl;
132 return kFALSE;
133 }*/
134
135 fRunHeader = 0;
136 if (fSimulateWavelength)
137 {
138 fRunHeader = (MCorsikaRunHeader*)pList->FindObject("MCorsikaRunHeader");
139 if (!fRunHeader)
140 {
141 *fLog << err << "MCorsikaRunHeader not found... aborting." << endl;
142 return kFALSE;
143 }
144 }
145
146 MReflector *r = (MReflector*)pList->FindObject("Reflector", "MReflector");
147 if (!r)
148 {
149 *fLog << err << "Reflector [MReflector] not found... aborting." << endl;
150 return kFALSE;
151 }
152
153 const MParSpline *s1 = (MParSpline*)pList->FindObject("PhotonDetectionEfficiency", "MParSpline");
154 const MParSpline *s2 = (MParSpline*)pList->FindObject("ConesAngularAcceptance", "MParSpline");
155 const MParSpline *s3 = (MParSpline*)pList->FindObject("MirrorReflectivity", "MParSpline");
156
157 const Double_t d2 = fGeom->GetCameraDist()*fGeom->GetCameraDist();
158 const Double_t pde = s1 && s1->GetSpline() ? s1->GetSpline()->Integral() : 1;
159 const Double_t sr = s2 && s2->GetSpline() ? s2->GetSpline()->IntegralSolidAngle() : 1;
160 const Double_t mir = s3 && s3->GetSpline() ? s3->GetSpline()->Integral() : 1;
161 const Double_t Ar = r->GetA()/1e4;
162
163 // Conversion factor to convert pixel area to steradians (because it
164 // is a rather small area we can assume it is flat)
165 const Double_t conv = fGeom->GetConvMm2Deg()*TMath::DegToRad();
166
167 // Multiply all relevant efficiencies
168 MParSpline *s4 = (MParSpline*)s1->Clone();
169 s4->Multiply(*s3->GetSpline());
170
171 const Double_t nm = s4 && s4->GetSpline() ? s4->GetSpline()->Integral() : 1;
172
173 delete s4;
174
175 // /100 to convert the pixel area from mm^2 to cm^2
176 fScale = nm * TMath::Min(Ar, sr*d2) * conv*conv;
177
178 *fLog << inf;
179 *fLog << "Effective cone acceptance: " << Form("%.2f", sr*d2) << "m^2" << endl;
180 *fLog << "Reflector area: " << Form("%.2f", Ar) << "m^2" << endl;
181 *fLog << "Resulting eff. collection area: " << Form("%.1f", TMath::Min(Ar, sr*d2)) << "m^2" << endl;
182 *fLog << "Eff. wavelength band (PDE): " << Form("%.1f", pde) << "nm" << endl;
183 *fLog << "Eff. wavelength band (Mirror): " << Form("%.1f", mir) << "nm" << endl;
184 *fLog << "Eff. wavelength band (PDE+MIR): " << Form("%.1f", nm) << "nm" << endl;
185 *fLog << "Pixel area of " << fNameGeomCam << "[0]: " << Form("%.2e", (*fGeom)[0].GetA()*conv*conv) << "sr" << endl;
186 //*fLog << "Effective angular acceptance: " << sr << "sr" << endl;
187 //*fLog << "Resulting NSB frequency: " << fFreqNSB*nm*Ar*1000 << "MHz/sr" << endl;
188 *fLog << "Resulting Freq. in " << fNameGeomCam << "[0]: " << Form("%.2f", fFreqNSB*(*fGeom)[0].GetA()*fScale*1000) << "MHz" << endl;
189
190 // const MMcRunHeader *mcrunheader = (MMcRunHeader*)pList->FindObject("MMcRunHeader");
191 // Set NumPheFromDNSB
192
193 // # Number of photons from the diffuse NSB (nphe / ns 0.1*0.1 deg^2 239 m^2) and
194 // nsb_mean 0.20
195 // Magic pixel: 0.00885361 deg
196 // dnsbpix = 0.2*50/15
197 // ampl = MMcFadcHeader->GetAmplitud()
198 // sqrt(pedrms*pedrms + dnsbpix*ampl*ampl/ratio)
199
200 return kTRUE;
201}
202
203Bool_t MSimRandomPhotons::ReInit(MParList *pList)
204{
205 // Overwrite the default set by MGeomApply
206 fRates->Init(*fGeom);
207 return kTRUE;
208}
209
210// --------------------------------------------------------------------------
211//
212// Check for the necessary containers
213//
214Int_t MSimRandomPhotons::Process()
215{
216 // Get array from event container
217 // const Int_t num = fEvt->GetNumPhotons();
218 //
219 // Do not produce pure pedestal events!
220 // if (num==0)
221 // return kTRUE;
222
223 // Get array from event container
224 // FIXME: Use statistics container instead
225 const UInt_t npix = fGeom->GetNumPixels();
226
227 // This is the possible window in which the triggered digitization
228 // may take place.
229 const Double_t start = fStat->GetTimeFirst();
230 const Double_t end = fStat->GetTimeLast();
231
232 // Loop over all pixels
233 for (UInt_t idx=0; idx<npix; idx++)
234 {
235 // Scale the rate with the pixel size.
236 const Double_t rate = fFreqFixed+fFreqNSB*(*fGeom)[idx].GetA()*fScale;
237
238 (*fRates)[idx].SetPedestal(rate);
239
240 // Calculate the average distance between two consequtive photons
241 const Double_t avglen = 1./rate;
242
243 // Start producing photons at time "start"
244 Double_t t = start;
245 while (1)
246 {
247 // Get a random time for the photon.
248 // The differences are exponentially distributed.
249 t += MMath::RndmExp(avglen);
250
251 // Check if we reached the end of the useful time window
252 if (t>end)
253 break;
254
255 // Add a new photon
256 // FIXME: SLOW!
257 MPhotonData &ph = fEvt->Add();
258
259 // Set source to NightSky, time to t and tag to pixel index
260 ph.SetPrimary(MMcEvtBasic::kNightSky);
261 ph.SetWeight();
262 ph.SetTime(t);
263 ph.SetTag(idx);
264
265 // fProductionHeight, fPosX, fPosY, fCosU, fCosV (irrelevant) FIXME: Reset?
266
267 if (fRunHeader)
268 {
269 const Float_t wmin = fRunHeader->GetWavelengthMin();
270 const Float_t wmax = fRunHeader->GetWavelengthMax();
271
272 ph.SetWavelength(TMath::Nint(gRandom->Uniform(wmin, wmax)));
273 }
274 }
275 }
276
277 // Re-sort the photons by time!
278 fEvt->Sort(kTRUE);
279
280 // Update maximum index
281 fStat->SetMaxIndex(npix-1);
282
283 // Shrink
284 return kTRUE;
285}
286
287// --------------------------------------------------------------------------
288//
289// Read the parameters from the resource file.
290//
291// FrequencyFixed: 0.040
292// FrequencyNSB: 0.040
293//
294// The fixed frequency is given in units fitting the units of the time.
295// Usually the time is given in nanoseconds thus, e.g., 0.040 means 40MHz.
296//
297// The FrequencyNSB is scaled by the area of the pixel in cm^2. Therefore
298// 0.040 would mean 40MHz/cm^2
299//
300Int_t MSimRandomPhotons::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
301{
302 Bool_t rc = kFALSE;
303 if (IsEnvDefined(env, prefix, "FrequencyFixed", print))
304 {
305 rc = kTRUE;
306 fFreqFixed = GetEnvValue(env, prefix, "FrequencyFixed", fFreqFixed);
307 }
308
309 if (IsEnvDefined(env, prefix, "FrequencyNSB", print))
310 {
311 rc = kTRUE;
312 fFreqNSB = GetEnvValue(env, prefix, "FrequencyNSB", fFreqNSB);
313 }
314
315 return rc;
316}
Note: See TracBrowser for help on using the repository browser.