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

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