source: trunk/MagicSoft/Mars/mpointing/MSrcPosCalc.cc@ 7216

Last change on this file since 7216 was 7216, checked in by tbretz, 19 years ago
*** empty log message ***
File size: 14.8 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): Thomas Bretz 3/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Author(s): Abelardo Moralejo 1/2005 <mailto:moralejo@pd.infn.it>
20!
21! Copyright: MAGIC Software Development, 2000-2005
22!
23!
24\* ======================================================================== */
25
26//////////////////////////////////////////////////////////////////////////////
27//
28// MSrcPosCalc
29//
30// Calculate the current source position in the camera from the (possibly
31// already corrected, by starguider) J2000 sky coordinates of the camera
32// center (contained in MPointingPos), and the source J2000 sky
33// coordinates contained in MSourcePos (of type MPointingPos as well). If
34// no MSourcePos is found in the parameter list, source position is
35// assumed to be the same for all events, that specified in MSrcPosCam
36// (if it already existed in the parameter list), or (0,0), the center of
37// the camera, if no MSrcPosCam was present in the parameter list. In both
38// cases, no calculation is necessary and then the PreProcess returns
39// kSKIP so that the task is removed from the task list.
40//
41// The conversion factor between the camera plain (mm) and the sky (deg)
42// is taken from MGeomCam. The time is taken from MTime, and the
43// coordinates of the observatory from MObservatory.
44//
45// Input Container:
46// MPointingPos
47// MObservatory
48// MGeomCam
49// MTime
50// [MSourcePos] (of type MPointingPos)
51//
52// Output Container:
53// MSrcPosCam
54//
55// To be done:
56// - a switch between using sky-coordinates and time or local-coordinates
57// from MPointingPos for determine the rotation angle
58///// NOTE, A. Moralejo: the above is not possible if MAstroSky2Local does not
59///// account for precession and nutation.
60//
61// - the center of rotation need not to be the camera center
62///// NOTE, A. Moralejo: I don't see the need for special code either.
63//
64//////////////////////////////////////////////////////////////////////////////
65#include "MSrcPosCalc.h"
66
67#include <TVector2.h>
68
69#include "MParList.h"
70
71#include "MLog.h"
72#include "MLogManip.h"
73
74#include "MGeomCam.h"
75#include "MObservatory.h"
76#include "MPointingPos.h"
77#include "MPointingDev.h"
78#include "MSrcPosCam.h"
79#include "MRawRunHeader.h"
80#include "MMcCorsikaRunHeader.h"
81
82#include "MAstro.h"
83#include "MVector3.h"
84#include "MAstroSky2Local.h"
85
86ClassImp(MSrcPosCalc);
87
88using namespace std;
89
90// --------------------------------------------------------------------------
91//
92// Initialize fY and fY with 0
93//
94MSrcPosCalc::MSrcPosCalc(const char *name, const char *title)
95 : fObservatory(NULL), fPointPos(NULL), fSourcePos(NULL), fDeviation(NULL),
96 fSrcPosCam(NULL), fSrcPosAnti(NULL), fGeom(NULL), fTime(NULL), fMode(kDefault)
97{
98 fName = name ? name : "MSrcPosCalc";
99 fTitle = title ? title : "Calculates the source position in the camera";
100
101 AddToBranchList("MTime.*");
102 AddToBranchList("MPointingPos.*");
103}
104
105// --------------------------------------------------------------------------
106//
107// delete fSourcePos if kIsOwner
108// set fSourcePos to NULL
109//
110void MSrcPosCalc::FreeSourcePos()
111{
112 if (fSourcePos && TestBit(kIsOwner))
113 delete fSourcePos;
114
115 fSourcePos = NULL;
116}
117
118// --------------------------------------------------------------------------
119//
120// ra [h]
121// dec [deg]
122//
123void MSrcPosCalc::SetSourcePos(Double_t ra, Double_t dec)
124{
125 FreeSourcePos();
126
127 fSourcePos = new MPointingPos("MSourcePos");
128 fSourcePos->SetSkyPosition(ra, dec);
129
130 SetOwner();
131}
132
133// --------------------------------------------------------------------------
134//
135// Return ra/dec as string
136//
137TString MSrcPosCalc::GetRaDec(const MPointingPos &pos) const
138{
139 const TString rstr = MAstro::Angle2Coordinate(pos.GetRa());
140 const TString dstr = MAstro::Angle2Coordinate(pos.GetDec());
141
142 return Form("Ra=%sh Dec=%sdeg", rstr.Data(), dstr.Data());
143}
144
145// --------------------------------------------------------------------------
146//
147// Search and if necessary create MSrcPosCam in the parameter list. Search
148// MSourcePos. If not found, do nothing else, and skip the task. If MSrcPosCam
149// did not exist before and has been created here, it will contain as source
150// position the camera center (0,0).
151// In the case that MSourcePos is found, go ahead in searching the rest of
152// necessary containers. The source position will be calculated for each
153// event in Process.
154//
155Int_t MSrcPosCalc::PreProcess(MParList *pList)
156{
157 fSrcPosCam = (MSrcPosCam*)pList->FindCreateObj("MSrcPosCam");
158 if (!fSrcPosCam)
159 return kFALSE;
160
161 fSrcPosAnti = (MSrcPosCam*)pList->FindCreateObj("MSrcPosCam", "MSrcPosAnti");
162 if (!fSrcPosAnti)
163 return kFALSE;
164
165 if (!fSourcePos)
166 {
167 fSourcePos = (MPointingPos*)pList->FindObject("MSourcePos", "MPointingPos");
168 if (!fSourcePos)
169 {
170 *fLog << warn;
171 *fLog << "MSourcePos [MPointPos] not found... The source position" << endl;
172 *fLog << "set in MSrcPosCam (camera center if not set explicitely)" << endl;
173 *fLog << "will be left unchanged if not wobble mode Monte Carlo." << endl;
174 return kTRUE;
175 }
176 }
177 // FIXME: Maybe we have to call FreeSourcePos in PostProcess()?
178
179 fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
180 if (!fGeom)
181 {
182 *fLog << err << "MGeomCam not found... aborting." << endl;
183 return kFALSE;
184 }
185
186 fPointPos = (MPointingPos*)pList->FindObject("MPointingPos");
187 if (!fPointPos)
188 {
189 *fLog << err << "MPointingPos not found... aborting." << endl;
190 return kFALSE;
191 }
192
193 fDeviation = (MPointingDev*)pList->FindObject("MPointingDev");
194
195 *fLog << inf;
196 //*fLog << "Pointing Position: " << GetRaDec(*fPointPos) << endl;
197 *fLog << "Source Position: " << GetRaDec(*fSourcePos) << endl;
198
199 // For the case ReInit is never called we try:
200 fObservatory = (MObservatory*)pList->FindObject("MObservatory");
201 fTime = (MTime*) pList->FindObject("MTime");
202 fRunType = MRawRunHeader::kRTNone;
203
204 return kTRUE;
205}
206
207// --------------------------------------------------------------------------
208//
209// If fIsWobbleMode==kFALSE set source position to v and anto-source
210// position to -v, if fIsWobbleMode==kTRUE vice versa.
211//
212void MSrcPosCalc::SetSrcPos(TVector2 v) const
213{
214 if (fMode==kWobble)
215 {
216 fSrcPosAnti->SetXY(v);
217 v *= -1;
218 fSrcPosCam->SetXY(v);
219 }
220 else
221 {
222 fSrcPosCam->SetXY(v);
223 v *= -1;
224 fSrcPosAnti->SetXY(v);
225 }
226}
227
228// --------------------------------------------------------------------------
229//
230// Checking for file type. If the file type is Monte Carlo the
231// source position is arbitrarily determined from the MC headers.
232//
233Bool_t MSrcPosCalc::ReInit(MParList *plist)
234{
235 if (fMode==kOffData)
236 {
237 SetSrcPos(TVector2());
238 return kTRUE;
239 }
240
241 MRawRunHeader *run = (MRawRunHeader*)plist->FindObject("MRawRunHeader");
242 if (!run)
243 {
244 *fLog << err << "MRawRunHeader not found... aborting." << endl;
245 return kFALSE;
246 }
247
248 fRunType = run->GetRunType();
249
250 if (fRunType!=MRawRunHeader::kRTMonteCarlo)
251 {
252 fObservatory = (MObservatory*)plist->FindObject("MObservatory");
253 if (!fObservatory)
254 {
255 *fLog << err << "MObservatory not found... aborting." << endl;
256 return kFALSE;
257 }
258 fTime = (MTime*)plist->FindObject("MTime");
259 if (!fTime)
260 {
261 *fLog << err << "MTime not found... aborting." << endl;
262 return kFALSE;
263 }
264 return kTRUE;
265 }
266
267 MMcCorsikaRunHeader *h = (MMcCorsikaRunHeader*)plist->FindObject("MMcCorsikaRunHeader");
268 if (!h)
269 {
270 *fLog << err << "MMcCorsikaRunHeader not found... aborting." << endl;
271 return kFALSE;
272 }
273
274 TVector2 v(0, 0);
275 if (h->GetWobbleMode()>0.5)
276 v.Set(120., 0.);
277 if (h->GetWobbleMode()<-0.5)
278 v.Set(-120., 0.);
279
280
281 SetSrcPos(v);
282
283 *fLog << inf;
284 *fLog << "Source Position set to x=" << fSrcPosCam->GetX() << "mm ";
285 *fLog << "y=" << fSrcPosCam->GetY() << "mm" << endl;
286
287 return kTRUE;
288}
289
290// --------------------------------------------------------------------------
291//
292// Loc0LocToCam
293//
294// Input : (theta0, phi0) direction for the position (0,0) in the camera
295// ( theta, phi) some other direction
296//
297// Output : (X, Y) position in the camera corresponding to (theta, phi)
298//
299TVector2 MSrcPosCalc::CalcXYinCamera(const MVector3 &pos0, const MVector3 &pos) const
300{
301 const Double_t theta0 = pos0.Theta();
302 const Double_t phi0 = pos0.Phi();
303
304 const Double_t theta = pos.Theta();
305 const Double_t phi = pos.Phi();
306
307 //--------------------------------------------
308
309 /* --- OLD ---
310 const Double_t YC0 = TMath::Cos(theta0)*TMath::Tan(theta)*TMath::Cos(phi-phi0) - TMath::Sin(theta0);
311 const Double_t YC1 = TMath::Cos(theta0) + TMath::Sin(theta0)*TMath::Tan(theta);
312 const Double_t YC = YC0 / YC1;
313
314 const Double_t XC0 = TMath::Cos(theta0) - YC*TMath::Sin(theta0);
315 const Double_t XC = -TMath::Sin(phi-phi0) * TMath::Tan(theta) * XC0;
316 */
317
318 /* --- NEW --- Same as MSrcPosCorrect::CalcXYinCamera */
319 const Double_t XC0 = TMath::Sin(theta)*TMath::Sin(phi-phi0);
320 const Double_t XC1 = TMath::Cos(theta0)*TMath::Cos(theta);
321 const Double_t XC2 = TMath::Sin(theta0)*TMath::Sin(theta)*TMath::Cos(phi-phi0);
322
323 const Double_t YC0 = TMath::Sin(theta0)*TMath::Cos(theta);
324 const Double_t YC1 = TMath::Cos(theta0)*TMath::Sin(theta)*TMath::Cos(phi-phi0);
325
326 const Double_t XC = - XC0 / (XC1 + XC2);
327 const Double_t YC = (-YC0+YC1) / (XC1 + XC2);
328
329 //--------------------------------------------
330 return TVector2(XC, YC);
331}
332
333// --------------------------------------------------------------------------
334//
335// Derotate fX/fY by the current rotation angle, set MSrcPosCam
336//
337Int_t MSrcPosCalc::Process()
338{
339 if (fRunType==MRawRunHeader::kRTMonteCarlo || !fSourcePos || !fTime || !fObservatory || fMode==kOffData)
340 return kTRUE;
341
342 // Set Sky coordinates of source, taken from container "MSourcePos"
343 // of type MPointingPos. The sky coordinates must be J2000, as the
344 // sky coordinates of the camera center that we get from the container
345 // "MPointingPos" filled by the Drive.
346 MVector3 pos; // pos: source position
347 pos.SetRaDec(fSourcePos->GetRaRad(), fSourcePos->GetDecRad());
348
349 // Convert sky coordinates of source to local coordinates. Warning! These are not the "true" local
350 // coordinates, since this transformation ignores precession and nutation effects.
351 const MAstroSky2Local conv(*fTime, *fObservatory);
352 pos *= conv;
353
354 // Set sky coordinates of camera center in pos0, and then convert to
355 // local. Same comment as above. These coordinates differ from the true
356 // local coordinates of the camera center that one could get from
357 // "MPointingPos", calculated by the Drive: the reason is that the Drive
358 // takes into account precession and nutation corrections, while
359 // MAstroSky2Local (as of Jan 27 2005 at least) does not. Since we just
360 // want to get the source position on the camera from the local
361 // coordinates of the center and the source, it does not matter that
362 // the coordinates contained in pos and pos0 ignore precession and
363 // nutation... since the shift would be the same in both cases. What
364 // would be wrong is to set in pos0 directly the local coordinates
365 // found in MPointingPos!
366 MVector3 pos0; // pos0: camera center
367 pos0.SetRaDec(fPointPos->GetRaRad(), fPointPos->GetDecRad());
368 pos0 *= conv;
369
370 TVector2 vx;
371 if (fDeviation)
372 {
373 vx = CalcXYinCamera(pos0, pos)*fGeom->GetCameraDist()*1000;
374 pos0.SetZdAz(pos0.Theta()-fDeviation->GetDevZdRad(),
375 pos0.Phi() -fDeviation->GetDevAzRad());
376 }
377
378 // Calculate source position in camera, and convert to mm:
379 TVector2 v = CalcXYinCamera(pos0, pos)*fGeom->GetCameraDist()*1000;
380 SetSrcPos(v);
381
382 return kTRUE;
383}
384
385// --------------------------------------------------------------------------
386//
387// Convert a coordinate stored in str into a double, stored in ret.
388// Returns kTRUE on success, otherwise kFALSE
389//
390// Allowed formats are:
391// 12.5
392// -12.5
393// +12.5
394// -12:30:00.0
395// 12:30:00.0
396// +12:30:00.0
397//
398Bool_t MSrcPosCalc::GetCoordinate(TString str, Double_t &ret) const
399{
400 str = str.Strip(TString::kBoth);
401
402 if (str.First(':')<0)
403 {
404 ret = str.Atof();
405 return kTRUE;
406 }
407
408 if (MAstro::Coordinate2Angle(str, ret))
409 return kTRUE;
410
411 *fLog << err << GetDescriptor() << endl;
412 *fLog << "Interpretation of Coordinate '" << str << "' not successfull... abort." << endl;
413 *fLog << "Corrdinate must have the format: '-12:30:00.0', '12:30:00.0' or '+12:30:00.0'" << endl;
414 return kFALSE;
415}
416
417// --------------------------------------------------------------------------
418//
419// Read the setup from a TEnv, eg:
420// MSrcPosCalc.SourceRa: ra
421// MSrcPosCalc.SourceDec: dec
422// MSrcPosCalc.SourcePos: ra dec
423//
424// For format of 'ra' and 'dec' see GetCoordinate()
425//
426// Coordinates are J2000.0
427//
428Int_t MSrcPosCalc::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
429{
430 Double_t ra=0;
431 Double_t dec=0;
432
433 if (IsEnvDefined(env, prefix, "SourceRaDec", print))
434 {
435 TString str = GetEnvValue(env, prefix, "SourceRaDec", "");
436 str = str.Strip(TString::kBoth);
437
438 const Ssiz_t pos = str.First(' ');
439 if (pos<0)
440 {
441 *fLog << err << GetDescriptor() << "SourceRaDec empty... abort." << endl;
442 return kERROR;
443 }
444
445 if (!GetCoordinate(str(0, pos), ra))
446 return kERROR;
447 if (!GetCoordinate(str(pos+1, str.Length()), dec))
448 return kERROR;
449
450 SetSourcePos(ra, dec);
451 return kTRUE;
452 }
453
454 Bool_t rc = kFALSE;
455 if (IsEnvDefined(env, prefix, "SourceRa", print))
456 {
457 TString str = GetEnvValue(env, prefix, "SourceRa", "");
458
459 if (!GetCoordinate(str, ra))
460 return kERROR;
461
462 rc = kTRUE;
463 }
464
465 if (IsEnvDefined(env, prefix, "SourceDec", print))
466 {
467 TString str = GetEnvValue(env, prefix, "SourceDec", "");
468
469 if (!GetCoordinate(str, dec))
470 return kERROR;
471
472 rc = kTRUE;
473 }
474
475 if (!rc)
476 return kFALSE;
477
478 SetSourcePos(ra, dec);
479 return kTRUE;
480}
Note: See TracBrowser for help on using the repository browser.