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

Last change on this file since 6901 was 6874, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 13.0 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 "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 fSrcPosAnti(NULL), fGeom(NULL), fTime(NULL), fIsWobbleMode(kFALSE)
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 fSrcPosAnti = (MSrcPosCam*)pList->FindCreateObj("MSrcPosCam", "MSrcPosAnti");
154 if (!fSrcPosAnti)
155 return kFALSE;
156
157 if (!fSourcePos)
158 {
159 fSourcePos = (MPointingPos*)pList->FindObject("MSourcePos", "MPointingPos");
160 if (!fSourcePos)
161 {
162 *fLog << warn << "MSourcePos [MPointPos] not found... The source position" << endl;
163 *fLog << warn << "set in MSrcPosCam (camera center if not set explicitely) will" << endl;
164 *fLog << warn << "be left unchanged, same for all events." << endl;
165 return kSKIP;
166 }
167 }
168 // FIXME: Maybe we have to call FreeSourcePos in PostProcess()?
169
170 fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
171 if (!fGeom)
172 {
173 *fLog << err << "MGeomCam not found... aborting." << endl;
174 return kFALSE;
175 }
176
177 fPointPos = (MPointingPos*)pList->FindObject("MPointingPos");
178 if (!fPointPos)
179 {
180 *fLog << err << "MPointingPos not found... aborting." << endl;
181 return kFALSE;
182 }
183
184 fObservatory = (MObservatory*)pList->FindObject("MObservatory");
185 if (!fObservatory)
186 {
187 *fLog << err << "MObservatory not found... aborting." << endl;
188 return kFALSE;
189 }
190
191 fTime = (MTime*)pList->FindObject("MTime");
192 if (!fTime)
193 {
194 *fLog << err << "MTime not found... aborting." << endl;
195 return kFALSE;
196 }
197
198 *fLog << inf;
199 *fLog << "Pointing Position: " << GetRaDec(*fPointPos) << endl;
200 *fLog << "Source Position: " << GetRaDec(*fSourcePos) << endl;
201
202 return kTRUE;
203}
204
205// --------------------------------------------------------------------------
206//
207// Loc0LocToCam
208//
209// Input : (theta0, phi0) direction for the position (0,0) in the camera
210// ( theta, phi) some other direction
211//
212// Output : (X, Y) position in the camera corresponding to (theta, phi)
213//
214TVector2 MSrcPosCalc::CalcXYinCamera(const MVector3 &pos0, const MVector3 &pos) const
215{
216 const Double_t theta0 = pos0.Theta();
217 const Double_t phi0 = pos0.Phi();
218
219 const Double_t theta = pos.Theta();
220 const Double_t phi = pos.Phi();
221
222 //--------------------------------------------
223
224 // pos0[3] = TMath::Cos(theta0)
225
226 const Double_t YC0 = TMath::Cos(theta0)*TMath::Tan(theta)*TMath::Cos(phi-phi0) - TMath::Sin(theta0);
227 const Double_t YC1 = TMath::Cos(theta0) + TMath::Sin(theta0)*TMath::Tan(theta);
228 const Double_t YC = YC0 / YC1;
229
230 //--------------------------------------------
231
232 const Double_t XC0 = TMath::Cos(theta0) - YC*TMath::Sin(theta0);
233 const Double_t XC = -TMath::Sin(phi-phi0) * TMath::Tan(theta) * XC0;
234
235 //--------------------------------------------
236 return TVector2(XC, YC);
237}
238
239// --------------------------------------------------------------------------
240//
241// Derotate fX/fY by the current rotation angle, set MSrcPosCam
242//
243Int_t MSrcPosCalc::Process()
244{
245 // *fLog << dbg << "Camera center : Zd=" << fPointPos->GetZd() << " Az=" << fPointPos->GetAz() << endl;
246 // *fLog << dbg << "Camera center : RA=" << fPointPos->GetRa() << " Dec=" << fPointPos->GetDec() << endl;
247 // *fLog << dbg << "MJD: " << fTime->GetMjd() << ", time [ms]: " << fTime->GetTime() << endl;
248
249 MVector3 pos, pos0; // pos: source position; pos0: camera center
250
251 if (fSourcePos)
252 {
253 // Set Sky coordinates of source, taken from container "MSourcePos" of type MPointingPos. The sky
254 // coordinates must be J2000, as the sky coordinates of the camera center that we get from the container
255 // "MPointingPos" filled by the Drive.
256
257 pos.SetRaDec(fSourcePos->GetRaRad(), fSourcePos->GetDecRad());
258
259 // *fLog << dbg << "Sky position of source: Ra=" << fSourcePos->GetRa() <<
260 // " Dec=" << fSourcePos->GetDec() << endl;
261 }
262
263 // Convert sky coordinates of source to local coordinates. Warning! These are not the "true" local
264 // coordinates, since this transformation ignores precession and nutation effects.
265 const MAstroSky2Local conv(*fTime, *fObservatory);
266 pos *= conv;
267
268
269 // Set sky coordinates of camera center in pos0, and then convert to local. Same comment as above. These
270 // coordinates differ from the true local coordinates of the camera center that one could get from
271 // "MPointingPos", calculated by the Drive: the reason is that the Drive takes into account precession
272 // and nutation corrections, while MAstroSky2Local (as of Jan 27 2005 at least) does not. Since we just
273 // want to get the source position on the camera from the local coordinates of the center and the source,
274 // it does not matter that the coordinates contained in pos and pos0 ignore precession and nutation...
275 // since the shift would be the same in both cases. What would be wrong is to set in pos0 directly the
276 // local coordinates found in MPointingPos!
277
278 pos0.SetRaDec(fPointPos->GetRaRad(), fPointPos->GetDecRad());
279 pos0 *= conv;
280
281 // *fLog << dbg << "From MAstroSky2Local, without precession and nutation corrections:" << endl;
282 // *fLog << dbg << "- Camera center (2) from RA,dec and time : Zd=" << pos0.Theta()*180./TMath::Pi()
283 // << " Az=" << pos0.Phi()*180./TMath::Pi() << endl;
284 // *fLog << dbg << "- Local position of source: Zd=" << pos.Theta()*TMath::RadToDeg() << " Az=" << pos.Phi()*TMath::RadToDeg() << endl;
285
286
287 // Calculate source position in camera, and convert to mm:
288 TVector2 v = CalcXYinCamera(pos0, pos)*fGeom->GetCameraDist()*1000;
289 if (fIsWobbleMode)
290 {
291 fSrcPosAnti->SetXY(v);
292 v *= -1;
293 fSrcPosCam->SetXY(v);
294 }
295 else
296 {
297 fSrcPosCam->SetXY(v);
298 v *= -1;
299 fSrcPosAnti->SetXY(v);
300 }
301
302 // v *= fGeom->GetConvMm2Deg();
303 // *fLog << dbg << "X=" << v.X() << " deg, Y=" << v.Y() << " deg" << endl;
304 // *fLog << *fTime << endl;
305 // *fLog << endl;
306
307 return kTRUE;
308}
309
310// --------------------------------------------------------------------------
311//
312// Convert a coordinate stored in str into a double, stored in ret.
313// Returns kTRUE on success, otherwise kFALSE
314//
315// Allowed formats are:
316// 12.5
317// -12.5
318// +12.5
319// -12:30:00.0
320// 12:30:00.0
321// +12:30:00.0
322//
323Bool_t MSrcPosCalc::GetCoordinate(TString str, Double_t &ret) const
324{
325 str = str.Strip(TString::kBoth);
326
327 if (str.First(':')<0)
328 return atof(str);
329
330 if (MAstro::Coordinate2Angle(str, ret))
331 return kTRUE;
332
333 *fLog << err << GetDescriptor() << endl;
334 *fLog << "Interpretation of Coordinate '" << str << "' not successfull... abort." << endl;
335 *fLog << "Corrdinate must have the format: '-12:30:00.0', '12:30:00.0' or '+12:30:00.0'" << endl;
336 return kFALSE;
337}
338
339// --------------------------------------------------------------------------
340//
341// Read the setup from a TEnv, eg:
342// MSrcPosCalc.SourceRa: ra
343// MSrcPosCalc.SourceDec: dec
344// MSrcPosCalc.SourcePos: ra dec
345//
346// For format of 'ra' and 'dec' see GetCoordinate()
347//
348// Coordinates are J2000.0
349//
350Int_t MSrcPosCalc::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
351{
352 Double_t ra=0;
353 Double_t dec=0;
354
355 if (IsEnvDefined(env, prefix, "SourceRaDec", print))
356 {
357 TString str = GetEnvValue(env, prefix, "SourceRaDec", "");
358 str = str.Strip(TString::kBoth);
359
360 const Ssiz_t pos = str.First(' ');
361 if (pos<0)
362 {
363 *fLog << err << GetDescriptor() << "SourceRaDec empty... abort." << endl;
364 return kERROR;
365 }
366
367 if (!GetCoordinate(str(0, pos), ra))
368 return kERROR;
369 if (!GetCoordinate(str(pos+1, str.Length()), dec))
370 return kERROR;
371
372 SetSourcePos(ra, dec);
373 return kTRUE;
374 }
375
376 Bool_t rc = kFALSE;
377 if (IsEnvDefined(env, prefix, "SourceRa", print))
378 {
379 TString str = GetEnvValue(env, prefix, "SourceRa", "");
380
381 if (!GetCoordinate(str, ra))
382 return kERROR;
383
384 rc = kTRUE;
385 }
386
387 if (IsEnvDefined(env, prefix, "SourceDec", print))
388 {
389 TString str = GetEnvValue(env, prefix, "SourceDec", "");
390
391 if (!GetCoordinate(str, dec))
392 return kERROR;
393
394 rc = kTRUE;
395 }
396
397 if (!rc)
398 return kFALSE;
399
400 SetSourcePos(ra, dec);
401 return kTRUE;
402}
Note: See TracBrowser for help on using the repository browser.