source: tags/Mars-V2.0/mpointing/MPointingDevCalc.cc

Last change on this file was 8731, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 21.2 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, 07/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2007
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MPointingDevCalc
28//
29// Calculates the pointing deviation from the starguider information.
30//
31// There are some quality parameters to steer which are the valid
32// starguider data points:
33//
34// * MPointingDevCalc.NumMinStars: 8
35// Minimum number of identified stars required to accep the data
36//
37// * MPointingDevCalc.NsbLevel: 3.0
38// Minimum deviation (in rms) from the the mean allowed for the
39// measured NSB (noise in the ccd camera)
40//
41// * MPointingDevCalc.NsbMin: 30
42// - minimum NSB to be used in mean/rms calculation
43//
44// * MPointingDevCalc.NsbMax: 60
45// - maximum NSB to be used in mean/rms calculation
46//
47// * MPointingDevCalc.MaxAbsDev: 15
48// - Maximum absolute deviation which is consideres as valid (arcmin)
49//
50// Starguider data which doens't fullfill this requirements is ignored.
51// If the measures NSB==0 (file too old, starguider didn't write down
52// these values) the checks based on NSB and NumMinStar are skipped.
53//
54// The calculation of NSB mean and rms is reset for each file (ReInit)
55//
56// If your starguider data doesn't fullfill this requirement the latest
57// value which could be correctly calculated is used instead. If the time
58// for which no valid value can be calculated exceeds one minute
59// the return value is reset to 0/0. The maximum time allowed without
60// a valid value can be setup using:
61//
62// * MPointingDevCalc.MaxAge: 1
63// Maximum time before the starguider is reset to 0/0 in minutes
64//
65// Note, that the starguider itself is not well calibrated. Therefore
66// it is necessary to do a starguider calibration in our software.
67//
68// There are two options:
69//
70// * Simple starguider calibration using offsets in the camera plane
71//
72// The starguider is calibrated by taking its values (dZd/dAz)
73// adding them to the source position, calculating the source position
74// in the camera plane and adding the offsets. To switch off the
75// full starguider calibration do:
76//
77// * MPointingDevCalc.PointingModels:
78//
79// To set the offsets (in units of degree) use
80//
81// * MPointingDevCalc.Dx: -0.001
82// * MPointingDevCalc.Dy: -0.004
83//
84// * A starguider calibration using a pointing model calculated
85// from calibration data, so called TPoints
86//
87// Because the pointing model can change from time to time
88// you can give the run-number from which on a new pointing
89// model is valid. The run itself is included, e.g.:
90//
91// * MPointingDevCalc.PointingModels: 85240 89180
92// * MPointingDevCalc.FilePrefix: resources/starguider
93//
94// mean that for all runs<85240 the simple offset correction is used.
95// For runs >=85240 and <89180 the file resources/starguider0085240.txt
96// and for runs >=89180 the file resources/starguider0089180.txt is
97// used. To setup a default file for all runs before 85240 setup
98// a low number (eg. 0 or 1)
99//
100// In the case a pointing model is used additional offsets in
101// the x/y-camera plane (in units of deg) can be set using the DX
102// and DY parameters of the pointing model. The fDx and fDy data
103// members of this class are ignored. To overwrite the starguider
104// calibrated offset in either Az or Zd with a constant, you
105// can use the PX/PY directive in the pointing model. (To enable
106// the overwrite set the third column, the error, to a value
107// greater than zero)
108//
109//
110// At the PostProcessing step a table with statistics is print if the
111// debug level is greater or equal 3 (in most applications it is switched
112// on by -v3)
113//
114//
115// Pointing Models:
116// ----------------
117//
118// What we know so far about (maybe) important changes in cosy:
119//
120// 18.03.2006: The camera holding has been repaired and the camera got
121// shifted a little bit.
122//
123// 16.04.2006: Around this date a roque lamp focussing hass been done
124//
125// 25.04.2006: A missalignment intrduced with the roque adjust has been
126// corrected
127//
128// The starguider pointing model for the time before 18.3.2006 and after
129// April 2006 (in fact there are no TPoints until 07/2006 to check it)
130// and for the period 07/2006 to (at least) 06/2007 are very similar.
131//
132// The pointing model for the time between 18.3.2006 and 04/2006 is
133// clearly different, mainly giving different Azimuth values between
134// Zenith and roughly ~25deg, and a slight offset on both axes.
135//
136// 10.5.2006: pos1 -= pos0 commented (What was the mentioned fix?)
137// 29.6.2006: repaired
138//
139// 23.3.2006: new starguider algorithm
140//
141// 17.3.2005: Fixed units of "nompos" in MDriveCom
142//
143//
144// New pointing models have been installed (if the pointing model
145// is different, than the previous one it might mean, that also
146// the starguider calibration is different.)
147//
148// 29. Apr. 2004 ~25800
149// 5. Aug. 2004 ~32000
150// 19. Aug. 2004 ~33530
151// 7. Jun. 2005 ~57650
152// 8. Jun. 2005
153// 9. Jun. 2005 ~57860
154// 12. Sep. 2005 ~68338
155// 24. Nov. 2005 ~75562
156// 17. Oct. 2006 ~103130
157// 17. Jun. 2007 ~248193
158//
159// From 2.2.2006 beginnig of the night (21:05h, run >=81855) to 24.2.2006
160// beginning of the the night (20:34h, run<83722) the LEDs did not work.
161// In the time after this incident the shift crew often forgot to switch on
162// the LEDs at the beginning of the night!
163//
164// [2006-03-07 00:10:58] In the daytime, we raised the position of the
165// 9 o'clock LED by one screw hole to make it visible when the TPoint
166// Lid is closed. (< run 84980)
167//
168//
169// ToDo:
170// -----
171//
172// * Is 0/0 the best assumption if the starguider partly fails?
173//
174//
175// Input Container:
176// MRawRunHeader
177// MReportStarguider
178//
179// Output Container:
180// MPointingDev
181//
182/////////////////////////////////////////////////////////////////////////////
183#include "MPointingDevCalc.h"
184
185#include "MLog.h"
186#include "MLogManip.h"
187
188#include "MParList.h"
189
190#include "MAstro.h"
191#include "MPointing.h"
192#include "MPointingDev.h"
193#include "MRawRunHeader.h"
194#include "MReportStarguider.h"
195
196ClassImp(MPointingDevCalc);
197
198using namespace std;
199
200const TString MPointingDevCalc::fgFilePrefix="resources/starguider";
201
202// --------------------------------------------------------------------------
203//
204// Destructor. Call Clear() and delete fPointingModels if any.
205//
206MPointingDevCalc::~MPointingDevCalc()
207{
208 Clear();
209}
210
211// --------------------------------------------------------------------------
212//
213// Delete fPointing and set pointing to NULL
214//
215void MPointingDevCalc::Clear(Option_t *o)
216{
217 if (fPointing)
218 delete fPointing;
219
220 fPointing = NULL;
221}
222
223// --------------------------------------------------------------------------
224//
225// Sort the entries in fPoinitngModels
226//
227void MPointingDevCalc::SortPointingModels()
228{
229 const int n = fPointingModels.GetSize();
230
231 TArrayI idx(n);
232
233 TMath::Sort(n, fPointingModels.GetArray(), idx.GetArray(), kFALSE);
234
235 const TArrayI arr(fPointingModels);
236
237 for (int i=0; i<n; i++)
238 fPointingModels[i] = arr[idx[i]];
239}
240
241// --------------------------------------------------------------------------
242//
243// Set new pointing models
244//
245void MPointingDevCalc::SetPointingModels(const TString &models)
246{
247 fPointingModels.Set(0);
248
249 if (models.IsNull())
250 return;
251
252 TObjArray *arr = models.Tokenize(" ");
253
254 const int n = arr->GetEntries();
255 fPointingModels.Set(n);
256
257 for (int i=0; i<n; i++)
258 fPointingModels[i] = atoi((*arr)[i]->GetName());
259
260 delete arr;
261
262 SortPointingModels();
263}
264
265// --------------------------------------------------------------------------
266//
267// Return a string with the pointing models, seperated by a space.
268//
269TString MPointingDevCalc::GetPointingModels() const
270{
271 TString rc;
272 for (int i=0; i<fPointingModels.GetSize(); i++)
273 rc += Form ("%d ", fPointingModels[i]);
274
275 return rc;
276}
277
278// --------------------------------------------------------------------------
279//
280// Add a number to the pointing models
281//
282void MPointingDevCalc::AddPointingModel(UInt_t runnum)
283{
284 const int n = fPointingModels.GetSize();
285 for (int i=0; i<n; i++)
286 if ((UInt_t)fPointingModels[i]==runnum)
287 {
288 *fLog << warn << "WARNING - Pointing model " << runnum << " already in list... ignored." << endl;
289 return;
290 }
291
292 fPointingModels.Set(n+1);
293 fPointingModels[n] = runnum;
294
295 SortPointingModels();
296}
297
298// --------------------------------------------------------------------------
299//
300// Find the highest number in the array which is lower or equal num.
301//
302UInt_t MPointingDevCalc::FindPointingModel(UInt_t num)
303{
304 const int n = fPointingModels.GetSize();
305 if (n==0)
306 return (UInt_t)-1;
307
308 // Loop over all pointing models
309 for (int i=0; i<n; i++)
310 {
311 // The number stored in the array did not yet overtake the runnumber
312 if ((UInt_t)fPointingModels[i]<num)
313 continue;
314
315 // The first pointing model is later than this run: use a default
316 if (i==0)
317 return (UInt_t)-1;
318
319 // The last entry in the array is the right one.
320 return fPointingModels[i-1];
321 }
322
323 // Runnumber is after last entry of pointing models. Use the last one.
324 return fPointingModels[n-1];
325}
326
327// --------------------------------------------------------------------------
328//
329// Clear the pointing model. If run-number >= 87751 read the new
330// pointing model with fFilePrefix
331//
332Bool_t MPointingDevCalc::ReadPointingModel(const MRawRunHeader &run)
333{
334 const UInt_t num = FindPointingModel(run.GetRunNumber());
335
336 // No poinitng models are defined. Use simple dx/dy-calibration
337 if (num==(UInt_t)-1)
338 {
339 Clear();
340 return kTRUE;
341 }
342
343 // compile the name for the starguider files
344 // The file with the number 00000000 is the default file
345 TString fname = Form("%s%08d.txt", fFilePrefix.Data(), num);
346
347 if (!fPointing)
348 fPointing = new MPointing;
349
350 if (fname==fPointing->GetName())
351 {
352 *fLog << inf << fname << " already loaded." << endl;
353 return kTRUE;
354 }
355
356 return fPointing->Load(fname);
357}
358
359// --------------------------------------------------------------------------
360//
361// Check the file/run type from the run-header and if it is a data file
362// load starguider calibration.
363//
364Bool_t MPointingDevCalc::ReInit(MParList *plist)
365{
366 MRawRunHeader *run = (MRawRunHeader*)plist->FindObject("MRawRunHeader");
367 if (!run)
368 {
369 *fLog << err << "MRawRunHeader not found... aborting." << endl;
370 return kFALSE;
371 }
372
373 fNsbSum = 0;
374 fNsbSq = 0;
375 fNsbCount = 0;
376
377 fRunType = run->GetRunType();
378
379 switch (fRunType)
380 {
381 case MRawRunHeader::kRTData:
382 if (!fReport)
383 *fLog << warn << "MReportStarguider not found... skipped." << endl;
384 return ReadPointingModel(*run);
385
386 case MRawRunHeader::kRTMonteCarlo:
387 return kTRUE;
388
389 case MRawRunHeader::kRTPedestal:
390 *fLog << err << "Cannot work in a pedestal Run!... aborting." << endl;
391 return kFALSE;
392
393 case MRawRunHeader::kRTCalibration:
394 *fLog << err << "Cannot work in a calibration Run!... aborting." << endl;
395 return kFALSE;
396
397 default:
398 *fLog << err << "Run Type " << fRunType << " unknown!... aborting." << endl;
399 return kFALSE;
400 }
401
402 return kTRUE;
403}
404
405// --------------------------------------------------------------------------
406//
407// Search for 'MPointingPos'. Create if not found.
408//
409Int_t MPointingDevCalc::PreProcess(MParList *plist)
410{
411 fDeviation = (MPointingDev*)plist->FindCreateObj("MPointingDev");
412 fReport = (MReportStarguider*)plist->FindObject("MReportStarguider");
413
414 // We use kRTNone here as a placeholder for data runs.
415 fRunType = MRawRunHeader::kRTNone;
416 fLastMjd = -1;
417
418 fSkip.Reset();
419
420 return fDeviation ? kTRUE : kFALSE;
421}
422
423// --------------------------------------------------------------------------
424//
425// Increase fSkip[i] by one. If the data in fDeviation is outdated (older
426// than fMaxAge) and the current report should be skipped reset DevZdAz and
427// DevXY and fSkip[6] is increased by one.
428//
429void MPointingDevCalc::Skip(Int_t i)
430{
431 fSkip[i]++;
432
433 const Double_t diff = (fReport->GetMjd()-fLastMjd)*1440; // [min] 1440=24*60
434 if (diff<fMaxAge && fLastMjd>0)
435 return;
436
437 fDeviation->SetDevZdAz(0, 0);
438 fDeviation->SetDevXY(0, 0);
439 fSkip[6]++;
440}
441
442// --------------------------------------------------------------------------
443//
444// Do a full starguider calibration using a pointing model for the starguider.
445//
446void MPointingDevCalc::DoCalibration(Double_t devzd, Double_t devaz) const
447{
448 if (!fPointing)
449 {
450 // Do a simple starguider calibration using a simple offset in x and y
451 fDeviation->SetDevZdAz(devzd, devaz);
452
453 // Linear starguider calibration taken from April/May data
454 // For calibration add MDriveReport::GetErrorZd/Az !
455 fDeviation->SetDevXY(fDx, fDy); // 1arcmin ~ 5mm
456
457 return;
458 }
459
460 // Get the nominal position the star is at the sky
461 // Unit: deg
462 ZdAz nom(fReport->GetNominalZd(), fReport->GetNominalAz());
463 nom *= TMath::DegToRad();
464
465 // Get the mispointing measured by the telescope. It is
466 // calculate as follows:
467 //
468 // The mispointing measured by the starguider:
469 // ZdAz mis(devzd, devaz);
470 // mis *= TMath::DegToRad();
471
472 // The pointing model is the conversion from the real pointing
473 // position of the telescope into the pointing position measured
474 // by the starguider.
475 //
476 // To keep as close to the fitted model we use the forward correction.
477
478 // Position at which the starguider camera is pointing in real:
479 // pointing position = nominal position - dev
480 //
481 // The position measured as the starguider's pointing position
482 ZdAz pos(nom); // cpos = sao - dev
483 pos -= ZdAz(devzd, devaz)*TMath::DegToRad();
484
485 // Now we convert the starguider's pointing position into the
486 // telescope pointing position (the pointing model converts
487 // the telescope pointing position into the starguider pointing
488 // position)
489 ZdAz point = fPointing->CorrectBack(pos); //FWD!!!
490
491 // MSrcPosCalc uses the following condition to calculate the
492 // source position in the camera:
493 // real pointing pos = nominal pointing pos - dev
494 // --> dev = nominal - real
495 // Therefor we calculate dev as follows:
496 ZdAz dev(nom);
497 dev -= point;
498 dev *= TMath::RadToDeg();
499
500 /*
501 // We chose the other way. It is less accurate because is is the
502 // other was than the poinitng model was fittet, but it is more
503 // accurate because the nominal (i.e. real) pointing position
504 // is less accurately known than the position returned by the
505 // starguider.
506 //
507 // Calculate the deviation which would be measured by the starguider
508 // if applied to a perfectly pointing telescope.
509 ZdAz dev = fPointing->Correct(nom);
510 dev -= nom;
511
512 // Now add these offsets and the starguider measured offsets to
513 // the real pointing deviation of the telescope (note, that
514 // signs here are just conventions)
515 dev += ZdAz(devzd, devaz)*TMath::DegToRad(); // --> nom-mis
516 dev *= TMath::RadToDeg();
517 */
518
519 // Check if the starguider pointing model requests overwriting
520 // of the values with constants (e.g. 0)
521 devaz = fPointing->IsPxValid() ? fPointing->GetPx() : dev.Az();
522 devzd = fPointing->IsPyValid() ? fPointing->GetPy() : dev.Zd();
523
524 fDeviation->SetDevZdAz(devzd, devaz);
525 fDeviation->SetDevXY(fPointing->GetDxy());
526}
527
528Int_t MPointingDevCalc::ProcessStarguiderReport()
529{
530 Double_t devzd = fReport->GetDevZd(); // [arcmin]
531 Double_t devaz = fReport->GetDevAz(); // [arcmin]
532 if (devzd==0 && devaz==0)
533 {
534 Skip(1);
535 return kTRUE;
536 }
537
538 if (!fReport->IsMonitoring())
539 {
540 Skip(2);
541 return kTRUE;
542 }
543
544 devzd /= 60; // Convert from arcmin to deg
545 devaz /= 60; // Convert from arcmin to deg
546
547 const Double_t nsb = fReport->GetSkyBrightness();
548 if (nsb>0)
549 {
550 if (nsb>fNsbMin && nsb<fNsbMax)
551 {
552 fNsbSum += nsb;
553 fNsbSq += nsb*nsb;
554 fNsbCount++;
555 }
556
557 if (fNsbCount>0)
558 {
559 const Double_t sum = fNsbSum/fNsbCount;
560 const Double_t sq = fNsbSq /fNsbCount;
561
562 const Double_t rms = fNsbLevel*TMath::Sqrt(sq - sum*sum);
563
564 if (nsb<sum-rms || nsb>sum+rms)
565 {
566 Skip(3);
567 return kTRUE;
568 }
569 }
570
571 if (fReport->GetNumIdentifiedStars()<fNumMinStars)
572 {
573 Skip(4);
574 return kTRUE;
575 }
576 }
577
578 // >= 87751 (31.3.06 12:00)
579
580 // Calculate absolute deviation
581 const Double_t dev = MAstro::GetDevAbs(fReport->GetNominalZd(), devzd, devaz);
582
583 // Sanity check... larger deviation are strange and ignored
584 if (dev*60>fMaxAbsDev)
585 {
586 Skip(5);
587 return kTRUE;
588 }
589
590 DoCalibration(devzd, devaz);
591
592 fSkip[0]++;
593 fLastMjd = fReport->GetMjd();
594
595 return kTRUE;
596}
597
598// --------------------------------------------------------------------------
599//
600// See class description.
601//
602Int_t MPointingDevCalc::Process()
603{
604 switch (fRunType)
605 {
606 case MRawRunHeader::kRTNone:
607 case MRawRunHeader::kRTData:
608 return fReport ? ProcessStarguiderReport() : kTRUE;
609
610 case MRawRunHeader::kRTMonteCarlo:
611 fSkip[0]++;
612 fDeviation->SetDevZdAz(0, 0);
613 fDeviation->SetDevXY(0, 0);
614 return kTRUE;
615 }
616 return kTRUE;
617}
618
619// --------------------------------------------------------------------------
620//
621// Print execution statistics
622//
623Int_t MPointingDevCalc::PostProcess()
624{
625 if (GetNumExecutions()==0)
626 return kTRUE;
627
628 *fLog << inf << endl;
629 *fLog << GetDescriptor() << " execution statistics:" << endl;
630 PrintSkipped(fSkip[1], "Starguider deviation not set, is exactly 0/0");
631 PrintSkipped(fSkip[2], "Starguider was not monitoring (eg. LEDs off)");
632 PrintSkipped(fSkip[3], Form("NSB out of %.1f sigma range", fNsbLevel));
633 PrintSkipped(fSkip[4], Form("Number of identified stars < %d", fNumMinStars));
634 PrintSkipped(fSkip[5], Form("Absolute deviation > %.1farcmin", fMaxAbsDev));
635 PrintSkipped(fSkip[6], Form("Events set to 0 because older than %.1fmin", fMaxAge));
636 *fLog << " " << (int)fSkip[0] << " (" << Form("%5.1f", 100.*fSkip[0]/GetNumExecutions()) << "%) Evts survived calculation!" << endl;
637 *fLog << endl;
638
639 return kTRUE;
640}
641
642// --------------------------------------------------------------------------
643//
644// MPointingDevCalc.NumMinStars: 8
645// MPointingDevCalc.NsbLevel: 3.0
646// MPointingDevCalc.NsbMin: 30
647// MPointingDevCalc.NsbMax: 60
648// MPointingDevCalc.MaxAbsDev: 15
649// MPointingDevCalc.MaxAge: 1.0
650// MPointingDevCalc.Dx: -0.001
651// MPointingDevCalc.Dy: -0.004
652//
653// For a detailed description see the class reference.
654//
655Int_t MPointingDevCalc::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
656{
657 Bool_t rc = kFALSE;
658 if (IsEnvDefined(env, prefix, "NumMinStars", print))
659 {
660 SetNumMinStars(GetEnvValue(env, prefix, "NumMinStars", (Int_t)fNumMinStars));
661 rc = kTRUE;
662 }
663 if (IsEnvDefined(env, prefix, "NsbLevel", print))
664 {
665 SetNsbLevel(GetEnvValue(env, prefix, "NsbLevel", fNsbLevel));
666 rc = kTRUE;
667 }
668 if (IsEnvDefined(env, prefix, "NsbMin", print))
669 {
670 SetNsbMin(GetEnvValue(env, prefix, "NsbMin", fNsbMin));
671 rc = kTRUE;
672 }
673 if (IsEnvDefined(env, prefix, "NsbMax", print))
674 {
675 SetNsbMax(GetEnvValue(env, prefix, "NsbMax", fNsbMax));
676 rc = kTRUE;
677 }
678 if (IsEnvDefined(env, prefix, "MaxAbsDev", print))
679 {
680 SetMaxAbsDev(GetEnvValue(env, prefix, "MaxAbsDev", fMaxAbsDev));
681 rc = kTRUE;
682 }
683 if (IsEnvDefined(env, prefix, "Dx", print))
684 {
685 fDx = GetEnvValue(env, prefix, "Dx", fDx);
686 rc = kTRUE;
687 }
688 if (IsEnvDefined(env, prefix, "Dy", print))
689 {
690 fDy = GetEnvValue(env, prefix, "Dy", fDy);
691 rc = kTRUE;
692 }
693 if (IsEnvDefined(env, prefix, "MaxAge", print))
694 {
695 fMaxAge = GetEnvValue(env, prefix, "MaxAge", fMaxAge);
696 rc = kTRUE;
697 }
698 if (IsEnvDefined(env, prefix, "FilePrefix", print))
699 {
700 fFilePrefix = GetEnvValue(env, prefix, "FilePrefix", fFilePrefix);
701 rc = kTRUE;
702 }
703 if (IsEnvDefined(env, prefix, "PointingModels", print))
704 {
705 SetPointingModels(GetEnvValue(env, prefix, "PointingModels", GetPointingModels()));
706 rc = kTRUE;
707 }
708
709 return rc;
710}
Note: See TracBrowser for help on using the repository browser.