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

Last change on this file since 6867 was 6346, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 12.7 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! 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 "MParList.h"
69
70#include "MLog.h"
71#include "MLogManip.h"
72
73#include "MGeomCam.h"
74#include "MObservatory.h"
75#include "MPointingPos.h"
76#include "MSrcPosCam.h"
77
78#include "MAstro.h"
79#include "MVector3.h"
80#include "MAstroSky2Local.h"
81
82ClassImp(MSrcPosCalc);
83
84using namespace std;
85
86// --------------------------------------------------------------------------
87//
88// Initialize fY and fY with 0
89//
90MSrcPosCalc::MSrcPosCalc(const char *name, const char *title)
91 : fObservatory(NULL), fPointPos(NULL), fSourcePos(NULL), fSrcPosCam(NULL),
92 fGeom(NULL), fTime(NULL)
93{
94 fName = name ? name : "MSrcPosCalc";
95 fTitle = title ? title : "Calculates the source position in the camera";
96}
97
98// --------------------------------------------------------------------------
99//
100// delete fSourcePos if kIsOwner
101// set fSourcePos to NULL
102//
103void MSrcPosCalc::FreeSourcePos()
104{
105 if (fSourcePos && TestBit(kIsOwner))
106 delete fSourcePos;
107
108 fSourcePos = NULL;
109}
110
111// --------------------------------------------------------------------------
112//
113// ra [h]
114// dec [deg]
115//
116void MSrcPosCalc::SetSourcePos(Double_t ra, Double_t dec)
117{
118 FreeSourcePos();
119
120 fSourcePos = new MPointingPos("MSourcePos");
121 fSourcePos->SetSkyPosition(ra, dec);
122
123 SetOwner();
124}
125
126// --------------------------------------------------------------------------
127//
128// Return ra/dec as string
129//
130TString MSrcPosCalc::GetRaDec(const MPointingPos &pos) const
131{
132 const TString rstr = MAstro::Angle2Coordinate(pos.GetRa());
133 const TString dstr = MAstro::Angle2Coordinate(pos.GetDec());
134
135 return Form("Ra=%sh Dec=%sdeg", rstr.Data(), dstr.Data());
136}
137
138// --------------------------------------------------------------------------
139//
140// Search and if necessary create MSrcPosCam in the parameter list. Search MSourcePos.
141// If not found, do nothing else, and skip the task. If MSrcPosCam did not exist
142// before and has been created here, it will contain as source position the camera
143// center (0,0).
144// In the case that MSourcePos is found, go ahead in searching the rest of necessary
145// containers. The source position will be calculated for each event in Process.
146//
147Int_t MSrcPosCalc::PreProcess(MParList *pList)
148{
149 fSrcPosCam = (MSrcPosCam*)pList->FindCreateObj("MSrcPosCam");
150 if (!fSrcPosCam)
151 return kFALSE;
152
153 if (!fSourcePos)
154 {
155 fSourcePos = (MPointingPos*)pList->FindObject("MSourcePos", "MPointingPos");
156 if (!fSourcePos)
157 {
158 *fLog << warn << "MSourcePos [MPointPos] not found... The source position" << endl;
159 *fLog << warn << "set in MSrcPosCam (camera center if not set explicitely) will" << endl;
160 *fLog << warn << "be left unchanged, same for all events." << endl;
161 return kSKIP;
162 }
163 }
164 // FIXME: Maybe we have to call FreeSourcePos in PostProcess()?
165
166 fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
167 if (!fGeom)
168 {
169 *fLog << err << "MGeomCam not found... aborting." << endl;
170 return kFALSE;
171 }
172
173 fPointPos = (MPointingPos*)pList->FindObject("MPointingPos");
174 if (!fPointPos)
175 {
176 *fLog << err << "MPointingPos not found... aborting." << endl;
177 return kFALSE;
178 }
179
180 fObservatory = (MObservatory*)pList->FindObject("MObservatory");
181 if (!fObservatory)
182 {
183 *fLog << err << "MObservatory not found... aborting." << endl;
184 return kFALSE;
185 }
186
187 fTime = (MTime*)pList->FindObject("MTime");
188 if (!fTime)
189 {
190 *fLog << err << "MTime not found... aborting." << endl;
191 return kFALSE;
192 }
193
194 *fLog << inf;
195 *fLog << "Pointing Position: " << GetRaDec(*fPointPos) << endl;
196 *fLog << "Source Position: " << GetRaDec(*fSourcePos) << endl;
197
198 return kTRUE;
199}
200
201// --------------------------------------------------------------------------
202//
203// Loc0LocToCam
204//
205// Input : (theta0, phi0) direction for the position (0,0) in the camera
206// ( theta, phi) some other direction
207//
208// Output : (X, Y) position in the camera corresponding to (theta, phi)
209//
210TVector2 MSrcPosCalc::CalcXYinCamera(const MVector3 &pos0, const MVector3 &pos) const
211{
212 const Double_t theta0 = pos0.Theta();
213 const Double_t phi0 = pos0.Phi();
214
215 const Double_t theta = pos.Theta();
216 const Double_t phi = pos.Phi();
217
218 //--------------------------------------------
219
220 // pos0[3] = TMath::Cos(theta0)
221
222 const Double_t YC0 = TMath::Cos(theta0)*TMath::Tan(theta)*TMath::Cos(phi-phi0) - TMath::Sin(theta0);
223 const Double_t YC1 = TMath::Cos(theta0) + TMath::Sin(theta0)*TMath::Tan(theta);
224 const Double_t YC = YC0 / YC1;
225
226 //--------------------------------------------
227
228 const Double_t XC0 = TMath::Cos(theta0) - YC*TMath::Sin(theta0);
229 const Double_t XC = -TMath::Sin(phi-phi0) * TMath::Tan(theta) * XC0;
230
231 //--------------------------------------------
232 return TVector2(XC, YC);
233}
234
235// --------------------------------------------------------------------------
236//
237// Derotate fX/fY by the current rotation angle, set MSrcPosCam
238//
239Int_t MSrcPosCalc::Process()
240{
241 // *fLog << dbg << "Camera center : Zd=" << fPointPos->GetZd() << " Az=" << fPointPos->GetAz() << endl;
242 // *fLog << dbg << "Camera center : RA=" << fPointPos->GetRa() << " Dec=" << fPointPos->GetDec() << endl;
243 // *fLog << dbg << "MJD: " << fTime->GetMjd() << ", time [ms]: " << fTime->GetTime() << endl;
244
245 MVector3 pos, pos0; // pos: source position; pos0: camera center
246
247 if (fSourcePos)
248 {
249 // Set Sky coordinates of source, taken from container "MSourcePos" of type MPointingPos. The sky
250 // coordinates must be J2000, as the sky coordinates of the camera center that we get from the container
251 // "MPointingPos" filled by the Drive.
252
253 pos.SetRaDec(fSourcePos->GetRaRad(), fSourcePos->GetDecRad());
254
255 // *fLog << dbg << "Sky position of source: Ra=" << fSourcePos->GetRa() <<
256 // " Dec=" << fSourcePos->GetDec() << endl;
257 }
258
259 // Convert sky coordinates of source to local coordinates. Warning! These are not the "true" local
260 // coordinates, since this transformation ignores precession and nutation effects.
261 const MAstroSky2Local conv(*fTime, *fObservatory);
262
263 pos *= conv;
264
265
266 // Set sky coordinates of camera center in pos0, and then convert to local. Same comment as above. These
267 // coordinates differ from the true local coordinates of the camera center that one could get from
268 // "MPointingPos", calculated by the Drive: the reason is that the Drive takes into account precession
269 // and nutation corrections, while MAstroSky2Local (as of Jan 27 2005 at least) does not. Since we just
270 // want to get the source position on the camera from the local coordinates of the center and the source,
271 // it does not matter that the coordinates contained in pos and pos0 ignore precession and nutation...
272 // since the shift would be the same in both cases. What would be wrong is to set in pos0 directly the
273 // local coordinates found in MPointingPos!
274
275 pos0.SetRaDec(fPointPos->GetRaRad(), fPointPos->GetDecRad());
276 pos0 *= conv;
277
278 // *fLog << dbg << "From MAstroSky2Local, without precession and nutation corrections:" << endl;
279 // *fLog << dbg << "- Camera center (2) from RA,dec and time : Zd=" << pos0.Theta()*180./TMath::Pi()
280 // << " Az=" << pos0.Phi()*180./TMath::Pi() << endl;
281 // *fLog << dbg << "- Local position of source: Zd=" << pos.Theta()*TMath::RadToDeg() << " Az=" << pos.Phi()*TMath::RadToDeg() << endl;
282
283
284 // Calculate source position in camera, and convert to mm:
285 TVector2 v = CalcXYinCamera(pos0, pos)*fGeom->GetCameraDist()*1000;
286
287 fSrcPosCam->SetXY(v);
288
289 // v *= fGeom->GetConvMm2Deg();
290 // *fLog << dbg << "X=" << v.X() << " deg, Y=" << v.Y() << " deg" << endl;
291 // *fLog << *fTime << endl;
292 // *fLog << endl;
293
294 return kTRUE;
295}
296
297// --------------------------------------------------------------------------
298//
299// Convert a coordinate stored in str into a double, stored in ret.
300// Returns kTRUE on success, otherwise kFALSE
301//
302// Allowed formats are:
303// 12.5
304// -12.5
305// +12.5
306// -12:30:00.0
307// 12:30:00.0
308// +12:30:00.0
309//
310Bool_t MSrcPosCalc::GetCoordinate(TString str, Double_t &ret) const
311{
312 str = str.Strip(TString::kBoth);
313
314 if (str.First(':')<0)
315 return atof(str);
316
317 if (MAstro::Coordinate2Angle(str, ret))
318 return kTRUE;
319
320 *fLog << err << GetDescriptor() << endl;
321 *fLog << "Interpretation of Coordinate '" << str << "' not successfull... abort." << endl;
322 *fLog << "Corrdinate must have the format: '-12:30:00.0', '12:30:00.0' or '+12:30:00.0'" << endl;
323 return kFALSE;
324}
325
326// --------------------------------------------------------------------------
327//
328// Read the setup from a TEnv, eg:
329// MSrcPosCalc.SourceRa: ra
330// MSrcPosCalc.SourceDec: dec
331// MSrcPosCalc.SourcePos: ra dec
332//
333// For format of 'ra' and 'dec' see GetCoordinate()
334//
335// Coordinates are J2000.0
336//
337Int_t MSrcPosCalc::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
338{
339 Double_t ra=0;
340 Double_t dec=0;
341
342 if (IsEnvDefined(env, prefix, "SourceRaDec", print))
343 {
344 TString str = GetEnvValue(env, prefix, "SourceRaDec", "");
345 str = str.Strip(TString::kBoth);
346
347 const Ssiz_t pos = str.First(' ');
348 if (pos<0)
349 {
350 *fLog << err << GetDescriptor() << "SourceRaDec empty... abort." << endl;
351 return kERROR;
352 }
353
354 if (!GetCoordinate(str(0, pos), ra))
355 return kERROR;
356 if (!GetCoordinate(str(pos+1, str.Length()), dec))
357 return kERROR;
358
359 SetSourcePos(ra, dec);
360 return kTRUE;
361 }
362
363 Bool_t rc = kFALSE;
364 if (IsEnvDefined(env, prefix, "SourceRa", print))
365 {
366 TString str = GetEnvValue(env, prefix, "SourceRa", "");
367
368 if (!GetCoordinate(str, ra))
369 return kERROR;
370
371 rc = kTRUE;
372 }
373
374 if (IsEnvDefined(env, prefix, "SourceDec", print))
375 {
376 TString str = GetEnvValue(env, prefix, "SourceDec", "");
377
378 if (!GetCoordinate(str, dec))
379 return kERROR;
380
381 rc = kTRUE;
382 }
383
384 if (!rc)
385 return kFALSE;
386
387 SetSourcePos(ra, dec);
388 return kTRUE;
389}
Note: See TracBrowser for help on using the repository browser.