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

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