/* ======================================================================== *\ ! ! * ! * 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 12/2000 ! Author(s): Harald Kornmayer 01/2001 ! Author(s): Markus Gaug 03/2004 ! ! Copyright: MAGIC Software Development, 2000-2008 ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MGeomCam // // This is the base class of different camera geometries. It creates // a pixel object for a given number of pixels and defines the // interface of how to acccess the geometry information. // // We use a TObjArray for possible future usage (it is much more flexible // than a TClonesArray so that it can store more types of pixels (eg // fake pixels which are not really existing) // // Version 1: // ---------- // - first implementation // // Version 2: // ---------- // - added fPixRatio // - added fPixRatioSqrt // // Version 3: // ---------- // - added fNumAreas // - added fNumSectors // // Version 4: // ---------- // - added fMaxRadius // - added fMinRadius // // Version 5: // ---------- // - added fNumPixInSector // - added fNumPixWithAidx // - removed fNumSectors // - removed fNumAreas // ///////////////////////////////////////////////////////////////////////////// #include "MGeomCam.h" #include // TMath #include // IsA()->New() #include // TArrayI #include // TVector2 #include "MLog.h" #include "MLogManip.h" #include "MGeomPix.h" ClassImp(MGeomCam); using namespace std; // -------------------------------------------------------------------------- // // Default Constructor. Initializes a Camera Geometry with npix pixels. All // pixels are deleted when the corresponding array is deleted. // MGeomCam::MGeomCam(UInt_t npix, Float_t dist, const char *name, const char *title) : fNumPixels(npix), fCamDist(dist), fConvMm2Deg(kRad2Deg/(dist*1000)), fPixels(npix), fMaxRadius(1), fMinRadius(1), fPixRatio(npix), fPixRatioSqrt(npix) { fName = name ? name : "MGeomCam"; fTitle = title ? title : "Storage container for a camera geometry"; // // make sure that the destructor delete all contained objects // fPixels.SetOwner(); // For root versions <5.18 AddAt is mandatory, for newer // root-version the []-operator can be used safely for (UInt_t i=0; iCopy(c[i]); } // -------------------------------------------------------------------------- // // Returns a reference of the i-th entry (the pixel with the software idx i) // The access is unchecked (for speed reasons!) accesing non existing // entries may crash the program! // MGeomPix &MGeomCam::operator[](Int_t i) { return *static_cast(fPixels.UncheckedAt(i)); } // -------------------------------------------------------------------------- // // Returns a reference of the i-th entry (the pixel with the software idx i) // The access is unchecked (for speed reasons!) accesing non existing // entries may crash the program! // MGeomPix &MGeomCam::operator[](Int_t i) const { return *static_cast(fPixels.UncheckedAt(i)); } // -------------------------------------------------------------------------- // // Calculate and fill the arrays storing the ratio of the area of a pixel // i to the pixel 0 and its square root. // The precalculation is done for speed reasons. Having an event the // ratio would be calculated at least once for each pixel which is // an enormous amount of numerical calculations, which are time // consuming and which can be avoided doing the precalculation. // void MGeomCam::CalcPixRatio() { const Double_t a0 = (*this)[0].GetA(); for (UInt_t i=0; i=fNumPixInSector.GetSize()) fNumPixInSector.Set(s+1); fNumPixInSector[s]++; } } // -------------------------------------------------------------------------- // // Calculate the highest area index+1 of all pixels, please make sure // the the area indices are continous. // void MGeomCam::CalcNumAreas() { for (UInt_t i=0; i=fNumPixWithAidx.GetSize()) fNumPixWithAidx.Set(s+1); fNumPixWithAidx[s]++; } } // -------------------------------------------------------------------------- // // Calculate the maximum radius of the camera. This is ment for GUI layout. // void MGeomCam::CalcMaxRadius() { fMaxRadius.Set(GetNumAreas()+1); fMinRadius.Set(GetNumAreas()+1); for (UInt_t i=0; id ? r-d : 0; if (maxr>fMaxRadius[s+1]) fMaxRadius[s+1] = maxr; if (minrfMaxRadius[0]) fMaxRadius[0] = maxr; } } // -------------------------------------------------------------------------- // // sort neighbours from angle of -180 degree to -180 degree // // where right side of main pixel contains negative degrees // and left side positive degrees // // angle measured from top (0 degree) to bottom (180 degree) // ^ - | + // // | _ | _ // // | / \|/ \ // // 30 degree -+- | | | // // | / \ / \ / \ // // 90 degree -+- | | X | | // // | \ / \ / \ / // // 150 degree -+- | | | // // | \_/|\_/ // // | | // // | - | + // // ------------------> // // // void MGeomCam::SortNeighbors() { for (unsigned int i=0; i=fNumPixels || j>=fNumPixels) return -1; return (*this)[i].GetDist((*this)[j]); } // -------------------------------------------------------------------------- // // Returns the angle between of pixels i wrt pixel j (default=0). The angle // is returned in the range between -pi and pi (atan2) and 2*pi if i or j // is out of range. // Float_t MGeomCam::GetAngle(UShort_t i, UShort_t j) const { if (i>=fNumPixels || j>=fNumPixels) return TMath::TwoPi(); return (*this)[i].GetAngle((*this)[j]); } // -------------------------------------------------------------------------- // // The maximum possible distance from the origin. // Float_t MGeomCam::GetMaxRadius() const { return fMaxRadius[0]; } // -------------------------------------------------------------------------- // // The minimum possible distance from the origin. // Float_t MGeomCam::GetMinRadius() const { return fMinRadius[0]; } // -------------------------------------------------------------------------- // // Have to call the radii of the subcameras starting to count from 1 // Float_t MGeomCam::GetMaxRadius(const Int_t i) const { return i<0 || i>=(Int_t)GetNumAreas() ? -1 : fMaxRadius[i+1]; } // -------------------------------------------------------------------------- // // Have to call the radii of the subcameras starting to count from 1 // Float_t MGeomCam::GetMinRadius(const Int_t i) const { return i<0 || i>=(Int_t)GetNumAreas() ? -1 : fMinRadius[i+1]; } // -------------------------------------------------------------------------- // // returns the ratio of the area of the pixel with index 0 to the pixel // with the specified index i. 0 Is returned if the index argument is // out of range. // Float_t MGeomCam::GetPixRatio(UInt_t i) const { // Former: (*this)[0].GetA()/(*this)[i].GetA(); // The const_cast is necessary to support older root version return i(fPixRatio)[i] : 0; } // -------------------------------------------------------------------------- // // returns the square root of the ratio of the area of the pixel with // index 0 to the pixel with the specified index i. 0 Is returned if // the index argument is out of range. // Float_t MGeomCam::GetPixRatioSqrt(UInt_t i) const { // The const_cast is necessary to support older root version return i(fPixRatioSqrt)[i] : 0; } // -------------------------------------------------------------------------- // // Check if the position given in the focal plane (so z can be ignored) // is a position which might hit the detector. It is meant to be a rough // and fast estimate not a precise calculation. All positions dicarded // must not hit the detector. All positions accepted might still miss // the detector. // Bool_t MGeomCam::HitDetector(const MQuaternion &v, Double_t offset) const { const Double_t max = fMaxRadius[0]/10+offset; // cm --> mm return v.R2()TMath::Hypot(pix.GetX()-(*this)[i].GetX(), pix.GetY()-(*this)[i].GetY())) arr[n++] = i; } arr.Set(n); } // -------------------------------------------------------------------------- // // Add all indices to arr of all neighbors around idx in a radius r. // The center pixel is also returned. // void MGeomCam::GetNeighbors(TArrayI &arr, UInt_t idx, Float_t r) const { if (idx>=GetNumPixels()) { arr.Set(0); return; } const MGeomPix &pix = (*this)[idx]; GetNeighbors(arr, pix, r); } // -------------------------------------------------------------------------- // // Add all pixels to list of all neighbors around pix in a radius r. // The center pixel is also returned. // void MGeomCam::GetNeighbors(TList &arr, const MGeomPix &pix, Float_t r) const { for (unsigned int i=0; iTMath::Hypot(pix.GetX()-(*this)[i].GetX(), pix.GetY()-(*this)[i].GetY())) arr.Add(fPixels.UncheckedAt(i)); } } // -------------------------------------------------------------------------- // // Add all pixels to list of all neighbors around idx in a radius r. // The center pixel is also returned. // void MGeomCam::GetNeighbors(TList &arr, UInt_t idx, Float_t r) const { if (idx>=GetNumPixels()) return; const MGeomPix &pix = (*this)[idx]; GetNeighbors(arr, pix, r); } // -------------------------------------------------------------------------- // // Return direction of p2 w.r.t. p1. For more details // see MGeomPix::GetDirection // Int_t MGeomCam::GetDirection(UInt_t p1, UInt_t p2) const { if (p1>fNumPixels || p2>fNumPixels) return -1; return operator[](p1).GetDirection(operator[](p2)); } // -------------------------------------------------------------------------- // // Get index of neighbor of pixel idx in direction dir, if existing. // Int_t MGeomCam::GetNeighbor(UInt_t idx, Int_t dir) const { if (idx>fNumPixels) return -1; const MGeomPix &pix=operator[](idx); // // search for the neighbor in the given direction // for (int i=0; i0. // If you ever read broken contents from a split branch you // MUST call this function after reading. // void MGeomCam::StreamerWorkaround() { if (fNumPixels==0 || !fPixels.IsEmpty()) return; TObject *cam = (TObject*)IsA()->New(); cam->Copy(*this); delete cam; } // -------------------------------------------------------------------------- // // This is a custom made streamer. Due to a bug in TObjArray::operator[] // old root-versions didn't correctly store the contents of the TObjArray. // If such a file is detected (TObjArray empty) a new MGeomCam is created // with IsA()->New() and its contents is copied to this. Unfortunately // this won't work for all MGeomCam derivatives which need arguments // in the constructor and MGeomCam itself (no derivative). Fortunately // in prodoction we have never stored anything else than MGeomCamMagic yet. // The bug in root can be worked around using AddAt instead of operator[]. // void MGeomCam::Streamer(TBuffer &b) { if (b.IsReading()) { MGeomCam::Class()->ReadBuffer(b, this); StreamerWorkaround(); } else MGeomCam::Class()->WriteBuffer(b, this); }