/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz, 3/2004 ! ! Copyright: MAGIC Software Development, 2000-2004 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MAstroCamera // ============ // // A tools displaying stars from a catalog in the camera display. // PRELIMINARY!! // // // Usage: // ------ // For a usage example see macros/starfield.C // // To be able to reflect the star-light you need the geometry of the // mirror and the distance of the plain screen. // // You can get the mirror geometry from a MC file and the distance of // the screen from MGeomCam. // // // Algorithm: // ---------- // The caluclation of the position of the reflection in the camera is // done by: // - Rotation of the star-field such that the camera is looking into // the pointing direction // - Calculation of the reflected star-light vector by calling // MGeomMirror::GetReflection (which returns the point at which // the vector hits the camera plain) // - Depending on the draw-option you get each reflected point, the // reflection on a virtual ideal mirror or the reflection on each // individual mirror // // // GUI: // ---- // * You can use the the cursor keys to change the pointing position // and plus/minus to change the time by a quarter of an hour. // // ToDo: // ----- // * possibility to overwrite distance from mirror to screen // * read the mirror geometry directly from the MC input file // ///////////////////////////////////////////////////////////////////////////// #include "MAstroCamera.h" #include // kKey_* #include // TH2D #include // TMarker #include // gPad #include "MLog.h" #include "MLogManip.h" #include "MGeomCam.h" #include "MGeomMirror.h" #include "MTime.h" #include "MAstroSky2Local.h" #include "MObservatory.h" #include "../mhist/MHCamera.h" // FIXME: This dependancy is very bad! // HOW TO GET RID OF IT? Move MHCamera to mgeom? ClassImp(MAstroCamera); using namespace std; // -------------------------------------------------------------------------- // // Create a virtual MGeomMirror which is in the center of the coordinate // system and has a normal vector in z-direction. // MAstroCamera::MAstroCamera() : fGeom(0), fMirrors(0) { fMirror0 = new MGeomMirror; fMirror0->SetMirrorContent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1); } // -------------------------------------------------------------------------- // // Delete fGeom, fMirrors and the virtual 0-Mirror fMirror0 // MAstroCamera::~MAstroCamera() { if (fGeom) delete fGeom; if (fMirrors) delete fMirrors; delete fMirror0; } // -------------------------------------------------------------------------- // // Set a list of mirrors. The Mirrors must be of type MGeomMirror and // stored in a TClonesArray // void MAstroCamera::SetMirrors(TClonesArray &arr) { if (arr.GetClass()!=MGeomMirror::Class()) { cout << "ERROR - TClonesArray doesn't contain objects of type MGeomMirror... ignored." << endl; return; } const Int_t n = arr.GetSize(); if (!fMirrors) fMirrors = new TClonesArray(MGeomMirror::Class(), n); fMirrors->ExpandCreate(n); for (int i=0; iGetNumMirror(); for (int i=0; iGetMirror(i).GetReflection(w, fGeom->GetCameraDist())*1000; spot *= 1./num; */ const TVector3 spot = fMirror0->GetReflection(w, fGeom->GetCameraDist())*1000; v.Set(spot(0), spot(1)); const Float_t max = fGeom->GetMaxRadius()*0.70; return v.X()>-max && v.Y()>-max && v.X()GetListOfPrimitives()); while ((o=Next())) { if (o->InheritsFrom(gROOT->GetClass(name))) return o; if (o->InheritsFrom("TPad")) if ((o = FindObjectInPad(name, (TVirtualPad*)o))) return o; } return NULL; } // -------------------------------------------------------------------------- // // Options: // // '*' Draw the mean of the reflections on all mirrors // '.' Draw a dot for the reflection on each individual mirror // 'h' To create a TH2D of the star-light which is displayed // 'c' Use the underlaying MHCamera as histogram // '0' Draw the reflection on a virtual perfect mirror // // If the Pad contains an object MHCamera of type MHCamera it is used. // Otherwise a new object is created. // void MAstroCamera::AddPrimitives(TString o) { if (!fTime || !fObservatory || !fMirrors) { cout << "Missing data..." << endl; return; } if (o.IsNull()) o = "*."; const Bool_t hasnull = o.Contains("0", TString::kIgnoreCase); const Bool_t hashist = o.Contains("h", TString::kIgnoreCase); const Bool_t hasmean = o.Contains("*", TString::kIgnoreCase); const Bool_t hasdot = o.Contains(".", TString::kIgnoreCase); const Bool_t usecam = o.Contains("c", TString::kIgnoreCase); // Get camera MHCamera *camera=(MHCamera*)FindObjectInPad("MHCamera", gPad); if (camera) { if (!camera->GetGeometry() || camera->GetGeometry()->IsA()!=fGeom->IsA()) camera->SetGeometry(*fGeom); } else { camera = new MHCamera(*fGeom); camera->SetName("MHCamera"); camera->SetStats(0); camera->SetInvDeepBlueSeaPalette(); camera->SetBit(kCanDelete); camera->Draw(); } camera->SetTitle(GetPadTitle()); gPad->cd(1); if (!usecam) { if (camera->GetEntries()==0) camera->SetBit(MHCamera::kNoLegend); } else { camera->Reset(); camera->SetYTitle("arb.cur"); } TH2 *h=0; if (hashist) { TH2F hist("","", 90, -650, 650, 90, -650, 650); hist.SetMinimum(0); h = (TH2*)hist.DrawCopy("samecont1"); } const TRotation rot(GetGrid(kTRUE)); MVector3 *radec; TIter Next(&fList); while ((radec=(MVector3*)Next())) { const Double_t mag = radec->Magnitude(); TVector3 star(*radec); // Rotate Star into telescope system star *= rot; TVector3 mean; Int_t num = 0; MGeomMirror *mirror = 0; TIter NextM(fMirrors); while ((mirror=(MGeomMirror*)NextM())) { const TVector3 spot = mirror->GetReflection(star, fGeom->GetCameraDist())*1000; // calculate mean of all 'stars' hitting the camera plane // by taking the sum of the intersection points between // the light vector and the camera plane mean += spot; if (hasdot) { TMarker *m=new TMarker(spot(0), spot(1), 1); m->SetMarkerColor(kMagenta); m->SetMarkerStyle(kDot); AddMap(m); } if (h) h->Fill(spot(0), spot(1), pow(10, -mag/2.5)); if (usecam) camera->Fill(spot(0), spot(1), pow(10, -mag/2.5)); num++; } // transform meters into millimeters (camera display works with mm) mean *= 1./num; DrawStar(mean(0), mean(1), *radec, !hasmean, Form("x=%.1fmm y=%.1fmm", mean(0), mean(1))); if (hasnull) { TVector3 star(*radec); star *= rot; const TVector3 spot = fMirror0->GetReflection(star, fGeom->GetCameraDist())*1000; DrawStar(spot(0), spot(1), *radec, !hasmean, Form("x=%.1fmm y=%.1fmm", mean(0), mean(1))); } } } // ------------------------------------------------------------------------ // // Execute a gui event on the camera // void MAstroCamera::ExecuteEvent(Int_t event, Int_t mp1, Int_t mp2) { if (event==kKeyPress && fTime) switch (mp2) { case kKey_Plus: fTime->SetMjd(fTime->GetMjd()+0.25/24); Update(kTRUE); return; case kKey_Minus: fTime->SetMjd(fTime->GetMjd()-0.25/24); Update(kTRUE); return; } MAstroCatalog::ExecuteEvent(event, mp1, mp2); }