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

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