source: trunk/Mars/msim/MPhotonData.cc@ 18547

Last change on this file since 18547 was 18545, checked in by tbretz, 10 years ago
Simulate the wavelength whenever it is set to zero (unspecified), set it to zero if the data stream does not contain it, print wavelength as decimal number the production height in m.
File size: 11.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, 12/2000 <mailto:thomas.bretz@epfl.ch>
19! Author(s): Qi Zhe, 06/2007 <mailto:qizhe@astro.uni-wuerzburg.de>
20!
21! Copyright: CheObs Software Development, 2000-2010
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MPhotonData
29//
30// Storage container to store Corsika events
31//
32// For details on the coordinate systems see our Wiki.
33//
34// Version 1:
35// ----------
36// * First implementation
37//
38// Version 2:
39// ----------
40// - fNumPhotons
41//
42/////////////////////////////////////////////////////////////////////////////
43#include "MPhotonData.h"
44
45#include <fstream>
46#include <iostream>
47
48#include <TMath.h>
49#include <TRandom.h>
50
51#include "MLog.h"
52#include "MLogManip.h"
53
54ClassImp(MPhotonData);
55
56using namespace std;
57
58// --------------------------------------------------------------------------
59//
60// Default constructor.
61//
62MPhotonData::MPhotonData(/*const char *name, const char *title*/)
63 : fPosX(0), fPosY(0), fCosU(0), fCosV(0), fTime(0), fWavelength(0),
64 /*fNumPhotons(1),*/ fProductionHeight(0), fPrimary(MMcEvtBasic::kUNDEFINED),
65 fTag(-1), fMirrorTag(-1), fWeight(1)
66{
67 // fName = name ? name : "MPhotonData";
68 // fTitle = title ? title : "Corsika Event Data Information";
69}
70
71/*
72MPhotonData::MPhotonData(const MPhotonData &ph)
73: fPosX(ph.fPosX), fPosY(ph.fPosY), fCosU(ph.fCosU), fCosV(ph.fCosV),
74fTime(ph.fTime), fWavelength(ph.fWavelength), fNumPhotons(ph.fNumPhotons),
75fProductionHeight(ph.fProductionHeight), fPrimary(ph.fPrimary),
76fTag(ph.fTag), fWeight(ph.fWeight)
77{
78}
79*/
80
81// --------------------------------------------------------------------------
82//
83// Copy function. Copy all data members into obj.
84//
85void MPhotonData::Copy(TObject &obj) const
86{
87 MPhotonData &d = static_cast<MPhotonData&>(obj);
88
89// d.fNumPhotons = fNumPhotons;
90 d.fPosX = fPosX;
91 d.fPosY = fPosY;
92 d.fCosU = fCosU;
93 d.fCosV = fCosV;
94 d.fWavelength = fWavelength;
95 d.fPrimary = fPrimary;
96 d.fTime = fTime;
97 d.fTag = fTag;
98 d.fWeight = fWeight;
99 d.fProductionHeight = fProductionHeight;
100
101 TObject::Copy(obj);
102}
103
104// --------------------------------------------------------------------------
105//
106// Return the square cosine of the Theta-angle == 1-CosU^2-CosV^2
107//
108Double_t MPhotonData::GetCosW2() const
109{
110 return 1 - GetSinW2();
111}
112
113// --------------------------------------------------------------------------
114//
115// Return the square sine of the Theta-angle == CosU^2+CosV^2
116//
117Double_t MPhotonData::GetSinW2() const
118{
119 return fCosU*fCosU + fCosV*fCosV;
120}
121
122// --------------------------------------------------------------------------
123//
124// return the cosine of the Theta-angle == sqrt(1-CosU^2-CosV^2)
125//
126Double_t MPhotonData::GetCosW() const
127{
128 return TMath::Sqrt(GetCosW2());
129}
130
131// --------------------------------------------------------------------------
132//
133// return the sine of the Theta-angle == sqrt(CosU^2+CosV^2)
134//
135Double_t MPhotonData::GetSinW() const
136{
137 return TMath::Sqrt(GetSinW2());
138}
139
140// --------------------------------------------------------------------------
141//
142// Return the theta angle in radians
143//
144Double_t MPhotonData::GetTheta() const
145{
146 return TMath::ASin(GetSinW());
147}
148
149// --------------------------------------------------------------------------
150//
151// Return a TQuaternion with the first three components x, y, and z
152// and the fourth component the time.
153//
154TQuaternion MPhotonData::GetPosQ() const
155{
156 return TQuaternion(GetPos3(), fTime);
157}
158
159// --------------------------------------------------------------------------
160//
161// return a TQuaternion with the first three components the direction
162// moving in space (GetDir3()) and the fourth component is the
163// one devided by the speed of light (converted to cm/ns)
164//
165// FIXME: v in air!
166//
167TQuaternion MPhotonData::GetDirQ() const
168{
169 return TQuaternion(GetDir3(), 1./(TMath::C()*100/1e9));
170}
171
172// --------------------------------------------------------------------------
173//
174// Set the wavelength to a random lambda^-2 distributed value
175// between wmin and wmax.
176//
177void MPhotonData::SimWavelength(Float_t wmin, Float_t wmax)
178{
179 if (fWavelength>0)
180 return;
181
182 const Double_t w = gRandom->Uniform(wmin, wmax);
183
184 fWavelength = TMath::Nint(wmin*wmax / w);
185}
186
187
188// --------------------------------------------------------------------------
189//
190// Set the data member according to the 8 floats read from a reflector-file.
191// This function MUST reset all data-members, no matter whether these are
192// contained in the input stream.
193//
194Int_t MPhotonData::FillRfl(Float_t f[8])
195{
196 // Check coordinate system!!!!
197 fWavelength = TMath::Nint(f[0]);
198 fPosX = f[1]; // [cm]
199 fPosY = f[2]; // [cm]
200 fCosU = f[3]; // cos to x
201 fCosV = f[4]; // cos to y
202 fTime = f[5]; // [ns]
203 fProductionHeight = f[6];
204
205 // f[7]: Camera inclination angle
206
207 fPrimary = MMcEvtBasic::kUNDEFINED;
208// fNumPhotons = 1;
209 fTag = -1;
210 fWeight = 1;
211
212 return kTRUE;
213}
214
215// --------------------------------------------------------------------------
216//
217// Set the data member according to the 7 floats read from a corsika-file.
218// This function MUST reset all data-members, no matter whether these are
219// contained in the input stream.
220//
221// Currently we exchange x and y and set y=-y to convert Corsikas coordinate
222// system intpo our own.
223//
224Int_t MPhotonData::FillCorsika(Float_t f[7], Int_t i)
225{
226 const UInt_t n = TMath::Nint(f[0]);
227
228 if (n==0)
229 // FIXME: Do we need to decode the rest anyway?
230 return kCONTINUE;
231
232 // Check reuse
233 if (i >=0)
234 {
235 const Int_t reuse = (n/1000)%100; // Force this to be 1!
236 if (reuse!=i)
237 return kCONTINUE;
238 }
239
240 // This seems to be special to mmcs
241 fWavelength = n%1000;
242 fPrimary = MMcEvtBasic::ParticleId_t(n/100000);
243
244 // x=north, y=west
245 //fPosX = f[1]; // [cm]
246 //fPosY = f[2]; // [cm]
247 //fCosU = f[3]; // cos to x
248 //fCosV = f[4]; // cos to y
249 // x=west, y=south
250 fPosX = f[2]; // [cm]
251 fPosY = -f[1]; // [cm]
252
253 fCosU = f[4]; // cos to x
254 fCosV = -f[3]; // cos to y
255
256 fTime = f[5]; // [ns]
257
258 fProductionHeight = f[6]; // [cm]
259
260 // Now reset all data members which are not in the stream
261 fTag = -1;
262 fWeight = 1;
263
264 return kTRUE;
265}
266
267// --------------------------------------------------------------------------
268//
269// Set the data member according to the 8 shorts read from a eventio-file.
270// This function MUST reset all data-members, no matter whether these are
271// contained in the input stream.
272//
273// Currently we exchange x and y and set y=-y to convert Corsikas coordinate
274// system into our own.
275//
276Int_t MPhotonData::FillEventIO(Short_t f[8])
277{
278 // From 5.5 compact_bunch:
279 // https://www.mpi-hd.mpg.de/hfm/~bernlohr/iact-atmo/iact_refman.pdf
280
281 // photons in this bunch f[6]/100.
282
283 fPosY = -f[0]/10.; // ypos relative to telescope [cm]
284 fPosX = f[1]/10.; // xpos relative to telescope [cm]
285 fCosV = -f[2]/30000.; // cos to y
286 fCosU = f[3]/30000.; // cos to x
287
288 fTime = f[4]/10.; // a relative arival time [ns]
289 fProductionHeight = pow(10, f[5]/1000.); // altitude of emission a.s.l. [cm]
290 fWavelength = TMath::Abs(f[7]); // wavelength [nm]: 0 undetermined, <0 already in p.e.
291
292 // Now reset all data members which are not in the stream
293 fPrimary = MMcEvtBasic::kUNDEFINED;
294 fTag = -1;
295 fWeight = 1;
296
297 return 1;
298}
299
300// --------------------------------------------------------------------------
301//
302// Set the data member according to the 8 floats read from a eventio-file.
303// This function MUST reset all data-members, no matter whether these are
304// contained in the input stream.
305//
306// Currently we exchange x and y and set y=-y to convert Corsikas coordinate
307// system into our own.
308//
309Int_t MPhotonData::FillEventIO(Float_t f[8])
310{
311 // photons in this bunch
312 const UInt_t n = TMath::Nint(f[6]);
313 if (n==0)
314 return 0;
315
316 fPosX = f[1]; // xpos relative to telescope [cm]
317 fPosY = -f[0]; // ypos relative to telescope [cm]
318 fCosU = f[3]; // cos to x
319 fCosV = -f[2]; // cos to y
320 //fTime = f[4]; // a relative arival time [ns]
321 //fProductionHeight = f[5]; // altitude of emission [cm]
322 fWavelength = 0; // so far always zeor = unspec. [nm]
323
324 // Now reset all data members which are not in the stream
325 fPrimary = MMcEvtBasic::kUNDEFINED;
326 fTag = -1;
327 fWeight = 1;
328
329 return n-1;
330}
331
332/*
333// --------------------------------------------------------------------------
334//
335// Read seven floats from the stream and call FillCorsika for them.
336//
337Int_t MPhotonData::ReadCorsikaEvt(istream &fin)
338{
339 Float_t f[7];
340 fin.read((char*)&f, 7*4);
341
342 const Int_t rc = FillCorsika(f);
343
344 return rc==kTRUE ? !fin.eof() : rc;
345}
346
347// --------------------------------------------------------------------------
348//
349// Read eight floats from the stream and call FillRfl for them.
350//
351Int_t MPhotonData::ReadRflEvt(istream &fin)
352{
353 Float_t f[8];
354 fin.read((char*)&f, 8*4);
355
356 const Int_t rc = FillRfl(f);
357
358 return rc==kTRUE ? !fin.eof() : rc;
359}
360*/
361
362// --------------------------------------------------------------------------
363//
364// Print contents. The tag and Weight are only printed if they are different
365// from the default.
366//
367void MPhotonData::Print(Option_t *) const
368{
369 gLog << inf << endl;
370// gLog << "Num Photons: " << fNumPhotons << " from " << MMcEvtBasic::GetParticleName(fPrimary) << endl;
371 gLog << "Origin: " << MMcEvtBasic::GetParticleName(fPrimary) << endl;
372 gLog << "Wavelength: " << dec << fWavelength << "nm" << endl;
373 gLog << "Pos X/Y Cos U/V: " << fPosX << "/" << fPosY << " " << fCosU << "/" << fCosV << endl;
374 gLog << "Time/Prod.Height: " << fTime << "ns/" << fProductionHeight/100 << "m" << endl;
375 if (fTag>=0)
376 gLog << "Tag: " << fTag << endl;
377 if (fWeight!=1)
378 gLog << "Weight: " << fWeight << endl;
379}
Note: See TracBrowser for help on using the repository browser.