/* ======================================================================== *\ ! ! * ! * 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): Markus Gaug 11/2003 ! ! Copyright: MAGIC Software Development, 2000-2001 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // // MCalibrationCam // // // // Hold the Calibration information for all pixels in the camera // // // // The Classes MCalibrationPix's are stored in a TClonesArray // // The Class MCalibrationBlindPix and the MCalibrationPINDiode // // are stored in separate pointers // // // ///////////////////////////////////////////////////////////////////////////// #include "MCalibrationCam.h" #include "MCalibrationPix.h" #include "MCalibrationBlindPix.h" #include "MCalibrationConfig.h" #include #include "MLog.h" #include "MLogManip.h" #include "MGeomCam.h" ClassImp(MCalibrationCam); using namespace std; // -------------------------------------------------------------------------- // // Default constructor. // Creates a TClonesArray of MHCalibrationPix objects, initialized to 0 entries // Creates an MCalibrationBlindPix and an MCalibrationPINDiode // MCalibrationCam::MCalibrationCam(const char *name, const char *title) : fMeanNrPhotAvailable(kFALSE) { fName = name ? name : "MCalibrationCam"; fTitle = title ? title : "Storage container for the Calibration Information in the camera"; fPixels = new TClonesArray("MCalibrationPix",0); fBlindPixel = new MCalibrationBlindPix(); fPINDiode = new MCalibrationPINDiode(); } // -------------------------------------------------------------------------- // // Delete the TClonesArray or MCalibrationPix's // Delete the MCalibrationPINDiode and the MCalibrationBlindPix // MCalibrationCam::~MCalibrationCam() { // // delete fPixels should delete all Objects stored inside // delete fPixels; delete fBlindPixel; delete fPINDiode; } // -------------------------------------------------------------------------- // // This function return the size of the FILLED MCalibrationCam // It is NOT the size of the array fPixels !!! // Note that with every call to AddPixels, GetSize() might change // Int_t MCalibrationCam::GetSize() const { // // Here it is important to use GetEntriesFast, // We get the array index of the last "filled" fPixel entry // (Not the number of "filled" fPixels!!) // return fPixels->GetEntriesFast(); } // -------------------------------------------------------------------------- // // Get i-th pixel (pixel number) // MCalibrationPix &MCalibrationCam::operator[](Int_t i) { return *static_cast(fPixels->UncheckedAt(i)); } // -------------------------------------------------------------------------- // // Get i-th pixel (pixel number) // MCalibrationPix &MCalibrationCam::operator[](Int_t i) const { return *static_cast(fPixels->UncheckedAt(i)); } Bool_t MCalibrationCam::AddPixel(Int_t idx) { // // Check bounds first // if (!CheckBounds(idx)) InitSize(idx); // // in case, new cannot allocate memory, // return FALSE // return (new ((*fPixels)[idx]) MCalibrationPix(idx)); } // -------------------------------------------------------------------------- // // Return a pointer to the pixel with the requested idx. // NULL if it doesn't exist. // MCalibrationPix *MCalibrationCam::GetCalibrationPix(Int_t idx) const { if (idx<0) return NULL; if (!CheckBounds(idx)) return NULL; // return (*this)[idx]; return (MCalibrationPix*)fPixels->At(idx); } // -------------------------------------------------------------------------- // // Check if position i is inside bounds // Bool_t MCalibrationCam::CheckBounds(Int_t i) const { return i < fPixels->GetEntriesFast(); } Bool_t MCalibrationCam::IsPixelUsed(Int_t idx) const { if (!CheckBounds(idx)) return kFALSE; return (&(*this)[idx]); } Bool_t MCalibrationCam::IsPixelFitted(Int_t idx) const { if (!IsPixelUsed(idx)) return kFALSE; return ((*this)[idx].GetRQ() > 0. && (*this)[idx].GetErrRQ() > 0.); } void MCalibrationCam::Clear(Option_t *o) { fPixels->ForEach(TObject, Clear)(); } // // Perform the fits of the charges // If i=-1, then all pixels will be fitted // Otherwise only the one with index i // // The number of succesful fits is returned // UShort_t MCalibrationCam::FitQ(Int_t i) { UShort_t nsuccess = 0; // invalidate i if it exceeds the number of entries in fPixels if (i > fPixels->GetEntriesFast()) { *fLog << warn << "Tried to fit pixel out of allowed range " << endl; return 0; } if (i == -1) // loop over all events { Int_t id = 0; TIter Next(fPixels); MCalibrationPix *pix; while ((pix=(MCalibrationPix*)Next())) { if (!IsPixelUsed(id++)) continue; if (pix->FitQ()) nsuccess++; } } else // fit only the pixel with index i { if (!IsPixelUsed(i)) return 0; if((*this)[i].FitQ()) nsuccess++; } return nsuccess; } // // Perform the fits of the charges of all pixels // plus the blind pixel and the PIN Diode // // The number of succesful fits is returned // UShort_t MCalibrationCam::FitAllQ() { // FIXME: Once the blind pixel is fully working, // there must be some penalty in case the // fit does not succeed // UShort_t nsuccess = 0; Int_t id = 0; TIter Next(fPixels); MCalibrationPix *pix; while ((pix=(MCalibrationPix*)Next())) { if (!IsPixelUsed(id++)) continue; if (pix->FitQ()) nsuccess++; } if (fBlindPixel->FitQ()) nsuccess++; if (fPINDiode->FitQ()) nsuccess++; return nsuccess; } // // Perform the fits of the arrival times // If i=-1, then all pixels will be fitted // Otherwise only the one with index i // // The number of succesful fits is returned // UShort_t MCalibrationCam::FitT(Int_t i) { UShort_t nsuccess = 0; // invalidate i if it exceeds the number of entries in fPixels if (i > fPixels->GetEntriesFast()) { *fLog << warn << "Tried to fit pixel out of allowed range " << endl; return 0; } if (i == -1) // loop over all events { Int_t id = 0; TIter Next(fPixels); MCalibrationPix *pix; while ((pix=(MCalibrationPix*)Next())) { if (!IsPixelUsed(id++)) continue; if (pix->FitT()) nsuccess++; } } else // fit only the pixel with index i { if((*this)[i].FitT()) nsuccess++; } return nsuccess; } // // Perform the fits of the times of all pixels // plus the blind pixel and the PIN Diode // // The number of succesful fits is returned // UShort_t MCalibrationCam::FitAllT() { // FIXME: Once the blind pixel is fully working, // there must be some penalty in case the // fit does not succeed // UShort_t nsuccess = 0; Int_t id = 0; TIter Next(fPixels); MCalibrationPix *pix; while ((pix=(MCalibrationPix*)Next())) { if (!IsPixelUsed(id++)) continue; if (pix->FitT()) nsuccess++; } if (fBlindPixel->FitT()) nsuccess++; if (fPINDiode->FitT()) nsuccess++; return nsuccess; } void MCalibrationCam::CutEdges() { fBlindPixel->GetHist()->CutAllEdges(); TIter Next(fPixels); MCalibrationPix *pix; while ((pix=(MCalibrationPix*)Next())) { pix->GetHist()->CutAllEdges(); } return; } // --------------------------------------------------------------------- // // This function simply allocates memory via the ROOT command: // (TObject**) TStorage::ReAlloc(fCont, newSize * sizeof(TObject*), // fSize * sizeof(TObject*)); // newSize corresponds to size in our case // fSize is the old size (in most cases: 0) // void MCalibrationCam::InitSize(Int_t size) { // // check if we have already initialized to size // if (CheckBounds(size)) return; // // It is important to use Expand and NOT ExpandCreate, because // we want to keep all pixel not used with a NULL pointer. // fPixels->Expand(size); // // Set all entries to the null pointer. // Later we fill the array per pixId with the contruction: new (fPixels[i]) MCalibrationPix(pixid) // To check, if pixels is already filled, we test the NULL pointer (see IsPixelUsed) // for (Int_t i=0; i< size; i++) { MCalibrationPix *pix = &(*this)[i]; pix = NULL; } } void MCalibrationCam::Print(Option_t *o) const { *fLog << all << GetDescriptor() << ":" << endl; int id = 0; TIter Next(fPixels); MCalibrationPix *pix; while ((pix=(MCalibrationPix*)Next())) { if (!IsPixelUsed(id)) continue; *fLog << id << ": "; *fLog << pix->GetQ() << " " << pix->GetRQ() << endl; id++; } } Bool_t MCalibrationCam::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const { if (!IsPixelFitted(idx)) return kFALSE; switch (type) { case 0: val = (*this)[idx].GetQ(); break; case 1: val = (*this)[idx].GetErrQ(); break; case 2: val = (*this)[idx].GetSigmaQ(); break; case 3: val = (*this)[idx].GetErrSigmaQ(); break; case 4: val = (*this)[idx].GetQProb(); break; case 5: val = (*this)[idx].GetT(); break; case 6: val = (*this)[idx].GetSigmaT(); break; case 7: val = (*this)[idx].GetTProb(); break; case 8: val = (*this)[idx].GetPed(); break; case 9: val = (*this)[idx].GetPedRms(); break; case 10: val = (*this)[idx].GetRQ(); break; case 11: val = (*this)[idx].GetErrRQ(); break; default: return kFALSE; } return val>=0; } void MCalibrationCam::DrawPixelContent(Int_t num) const { *fLog << warn << "MCalibrationCam::DrawPixelContent - not available." << endl; } Bool_t MCalibrationCam::CalcNrPhotInnerPixel() { if (!fBlindPixel->IsValid()) return kFALSE; const Float_t mean = fBlindPixel->GetLambda(); // const Float_t merr = fBlindPixel->GetErrLambda(); switch (fColor) { case kECGreen: fMeanNrPhotInnerPix = mean / (gkCalibrationBlindPixelQEGreen *TMath::Power(10,gkCalibrationBlindPixelAttGreen) *gkCalibrationBlindPixelArea); break; case kECBlue: fMeanNrPhotInnerPix = mean / (gkCalibrationBlindPixelQEBlue *TMath::Power(10,gkCalibrationBlindPixelAttBlue) *gkCalibrationBlindPixelArea); break; case kECUV: fMeanNrPhotInnerPix = mean / (gkCalibrationBlindPixelQEUV *TMath::Power(10,gkCalibrationBlindPixelAttUV) *gkCalibrationBlindPixelArea); break; } fMeanNrPhotAvailable = kTRUE; return kTRUE; } Bool_t MCalibrationCam::GetConversionFactor(Int_t ipx, Float_t &mean, Float_t &err) { if (ipx < 0 || !IsPixelFitted(ipx)) return kFALSE; if (!fMeanNrPhotAvailable) if (!CalcNrPhotInnerPixel()) return kFALSE; mean = fMeanNrPhotInnerPix / (*this)[ipx].GetRQ(); // // Not yet ready , sorry // err = 100000000000.; return kTRUE; }