source: trunk/Mars/mimage/MStereoPar.cc@ 13768

Last change on this file since 13768 was 8916, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 9.3 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC 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 appear 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): Abelardo Moralejo 11/2003 <mailto:moralejo@pd.infn.it>
19!
20! Copyright: MAGIC Software Development, 2000-2008
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MStereoPar
28//
29// Storage Container for shower parameters estimated using the information
30// from two telescopes (presently for MC studies)
31//
32//
33/////////////////////////////////////////////////////////////////////////////
34#include "MStereoPar.h"
35
36#include <fstream>
37
38#include <TMath.h>
39
40#include "MLog.h"
41#include "MLogManip.h"
42
43#include "MHillas.h"
44#include "MGeomCam.h"
45#include "MPointingPos.h"
46
47ClassImp(MStereoPar);
48
49using namespace std;
50
51// --------------------------------------------------------------------------
52//
53// Default constructor.
54//
55MStereoPar::MStereoPar(const char *name, const char *title)
56{
57 fName = name ? name : "MStereoPar";
58 fTitle = title ? title : "Stereo image parameters";
59}
60
61// --------------------------------------------------------------------------
62//
63void MStereoPar::Reset()
64{
65 fCoreX = 0.;
66 fCoreY = 0.;
67 fSourceX = 0.;
68 fSourceY = 0.;
69}
70
71// --------------------------------------------------------------------------
72//
73// Transformation of coordinates, from a point on the camera x, y , to
74// the directon cosines of the corresponding direction, in the system of
75// coordinates in which X-axis is North, Y-axis is west, and Z-axis
76// points to the zenith. The transformation has been taken from TDAS 01-05,
77// although the final system of coordinates is not the same defined there,
78// but the one defined in Corsika (for convenience).
79//
80// rc is the distance from the reflector center to the camera. CTphi and
81// CTtheta indicate the telescope orientation. The angle CTphi is the
82// azimuth of the vector going along the telescope axis from the camera
83// towards the reflector, measured from the North direction anticlockwise
84// ( being West: phi=pi/2, South: phi=pi, East: phi=3pi/2 )
85//
86// rc and x,y must be given in the same units!
87//
88TVector3 MStereoPar::CamToDir(const MGeomCam &geom, const MPointingPos &pos, Float_t x, Float_t y) const
89{
90 const Double_t rc = geom.GetCameraDist()*1e3;
91
92 const Double_t CTphi = pos.GetAzRad();
93 const Double_t CTtheta = pos.GetZdRad();
94
95 //
96 // We convert phi to the convention defined in TDAS 01-05
97 //
98 const Double_t sinphi = sin(TMath::TwoPi()-CTphi);
99 const Double_t cosphi = cos(CTphi);
100
101 const Double_t costheta = cos(CTtheta);
102 const Double_t sintheta = sin(CTtheta);
103
104 const Double_t xc = x/rc;
105 const Double_t yc = y/rc;
106
107 const Double_t norm = 1/sqrt(1+xc*xc+yc*yc);
108
109 const Double_t xref = xc * norm;
110 const Double_t yref = yc * norm;
111 const Double_t zref = -1 * norm;
112
113 const Double_t cosx = xref * sinphi + yref * costheta*cosphi - zref * sintheta*cosphi;
114 const Double_t cosy = -xref * cosphi + yref * costheta*sinphi - zref * sintheta*sinphi;
115 const Double_t cosz = yref * sintheta + zref * costheta;
116
117 // Now change from system A of TDAS 01-05 to Corsika system:
118 return TVector3(cosx, -cosy, -cosz);
119}
120
121TVector3 MStereoPar::CamToDir(const MGeomCam &geom, const MPointingPos &pos, const TVector2 &p) const
122{
123 return CamToDir(geom, pos, p.X(), p.Y());
124}
125
126void MStereoPar::CalcCT(const MHillas &h, const MPointingPos &p, const MGeomCam &g, TVector2 &cv1, TVector2 &cv2) const
127{
128 //
129 // Get the direction corresponding to the c.o.g. of the image on
130 // the camera.
131 //
132 // ct1_a, Direction from ct1 to the shower c.o.g.
133 //
134 const TVector3 a = CamToDir(g, p, h.GetMeanX(), h.GetMeanY());
135
136 //
137 // Now we get another (arbitrary) point along the image long axis,
138 // fMeanX + cosdelta, fMeanY + sindelta, and calculate the direction
139 // to which it corresponds.
140 //
141 const TVector3 c = CamToDir(g, p, h.GetMeanX()+h.GetCosDelta(), h.GetMeanY()+h.GetSinDelta());
142
143 //
144 // The vectorial product of the latter two vectors is a vector
145 // perpendicular to the plane which contains the shower axis and
146 // passes through the telescope center (center of reflector).
147 // The vectorial product of that vector and (0,0,1) is a vector on
148 // the horizontal plane pointing from the telescope center to the
149 // shower core position on the z=0 plane (ground).
150 //
151 const Double_t coreVersorX = a.Z()*c.X() - a.X()*c.Z();
152 const Double_t coreVersorY = a.Z()*c.Y() - a.X()*c.Z();
153
154 //
155 // Now we calculate again the versor, now assuming that the source
156 // direction is paralel to the telescope axis (camera position 0,0)
157 // This increases the precision of the core determination if the showers
158 // actually come from that direction (like for gammas from a point source)
159
160 const TVector3 b = CamToDir(g, p, 0, 0);
161
162 const Double_t coreVersorX_best = a.Z()*b.X() - a.X()*b.Z();
163 const Double_t coreVersorY_best = a.Z()*b.Y() - a.Y()*b.Z();
164
165 cv1.Set(coreVersorX, coreVersorY);
166 cv2.Set(coreVersorX_best, coreVersorY_best);
167}
168
169TVector2 MStereoPar::VersorToCore(const TVector2 &v1, const TVector2 &v2, const TVector2 &p1, const TVector2 &p2) const
170{
171 const TVector2 dp = p1 - p2;
172
173 //
174 // Estimate core position:
175 //
176 const Double_t t =
177 (dp.X() - v2.X()/v2.Y()*dp.Y())/(v2.X()/v2.Y()*v1.Y() - v1.X());
178
179 // Core will have the same units as p1/p2
180 return p1 + v1*t;
181}
182
183Double_t MStereoPar::CalcImpact(const TVector2 &w, const TVector2 &v, const TVector2 &p) const
184{
185 const TVector2 d = v-p;
186
187 const Double_t f = d*w;
188
189 return TMath::Sqrt( d.Mod2() - f*f );
190}
191
192Double_t MStereoPar::CalcImpact(const TVector3 &v, const TVector2 &p) const
193{
194 const TVector2 w = v.XYvector();
195 return CalcImpact(w, w, p);
196}
197
198Double_t MStereoPar::CalcImpact(const TVector2 &core, const TVector2 &p, const MPointingPos &point) const
199{
200 const TVector2 pt(-sin(point.GetZdRad()) * cos(point.GetAzRad()),
201 -sin(point.GetZdRad()) * sin(point.GetAzRad()));
202
203 return CalcImpact(pt, core, p);
204}
205
206// --------------------------------------------------------------------------
207//
208// Calculation of shower parameters
209//
210void MStereoPar::Calc(const MHillas &hillas1, const MPointingPos &pos1, const MGeomCam &geom1, const Float_t ct1_x, const Float_t ct1_y,
211 const MHillas &hillas2, const MPointingPos &pos2, const MGeomCam &geom2, const Float_t ct2_x, const Float_t ct2_y)
212{
213 TVector2 coreVersor1, coreVersor1_best;
214 CalcCT(hillas1, pos1, geom1, coreVersor1, coreVersor1_best);
215
216 TVector2 coreVersor2, coreVersor2_best;
217 CalcCT(hillas2, pos2, geom2, coreVersor2, coreVersor2_best);
218
219 const TVector2 p1(ct1_x, ct1_y);
220 const TVector2 p2(ct2_x, ct2_y);
221
222 // Estimate core position:
223 const TVector2 core = VersorToCore(coreVersor1, coreVersor2, p1, p2);
224
225 // Now the estimated core position assuming the source is
226 // located in the center of the camera
227 const TVector2 core2 = VersorToCore(coreVersor1_best, coreVersor2_best, p1, p2);
228
229 // Copy results to data members
230 //
231 // Be careful, the coordinates in MMcEvt.fCoreX,fCoreY are actually
232 // those of the vector going *from the shower core to the telescope*.
233 // Ours are those of the vector which goes from telescope 1 to the
234 // core estimated core.
235 //
236 fCoreX = core.X();
237 fCoreY = core.Y();
238
239 fCoreX2 = core2.X();
240 fCoreY2 = core2.Y();
241
242 // Now estimate the source location on the camera by intersecting
243 // major axis of the ellipses. This assumes both telescopes are
244 // pointing paralel! We introduce the camera scale to account for
245 // the use of telescopes with different focal distances.
246 //
247 const TVector2 v1(hillas1.GetSinDelta(), hillas1.GetCosDelta());
248 const TVector2 v2(hillas2.GetSinDelta(), hillas2.GetCosDelta());
249
250 const TVector2 h1 = hillas1.GetMean()*geom1.GetConvMm2Deg();
251 const TVector2 h2 = hillas2.GetMean()*geom2.GetConvMm2Deg();
252
253 const TVector2 src = VersorToCore(v1, v2, h1, h2);
254
255 // Reconstructed source positon
256 fSourceX = src.X();
257 fSourceY = src.Y();
258
259 // Squared angular distance from reconstr. src pos to camera center.
260 fTheta2 = src.Mod2();
261
262 // Get the direction corresponding to the intersection of axes
263 const TVector3 srcdir = CamToDir(geom1, pos1, src/geom1.GetConvMm2Deg());
264
265 fCT1Impact = CalcImpact(srcdir, p1);
266 fCT2Impact = CalcImpact(srcdir, p2);
267
268 // Now calculate i.p. assuming source is point-like and placed in
269 // the center of the camera.
270 fCT1Impact2 = CalcImpact(core2, p1, pos1);
271 fCT2Impact2 = CalcImpact(core2, p2, pos2);
272
273 SetReadyToSave();
274}
Note: See TracBrowser for help on using the repository browser.