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

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