/* ======================================================================== *\ ! ! * ! * 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): Oscar Blanch 12/2001 ! Author(s): Thomas Bretz 08/2002 ! Author(s): Stefan Ruegamer ! ! Copyright: MAGIC Software Development, 2000-2006 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MBadPixelsTreat // // You can use MBadPixelsTreat::SetUseInterpolation to replaced the // bad pixels by the average of its neighbors instead of unmapping // them. If you want to include the central pixel use // MBadPixelsTreat::SetUseCentralPixel. The bad pixels are taken from // an existing MBadPixelsCam. // // It check if there are enough neighbors to calculate the mean // If not, unmap the pixel. The minimum number of good neighbors // should be set using SetNumMinNeighbors // // If you want to interpolate unreliable pixels and unsuitable // (broken) pixels use SetHardTreatment(). // // // Options: // -------- // SetHardTreatment: Also interpolate unreliable pixels not only unsuitable // SetUseInterpolation: Interpolate pixels instead of unmapping them // SetUseCentralPixel: also use the pixel itself for interpolation // SetProcessPedestalRun: process the pedestals once per run/file // SetProcessPedestalEvt: process the pedestal once per event // SetProcessTimes: do interpolation of the arrival time // // If the arrival time treatment is switched on and "MPedPhotFromExtractor" // and "MPedPhotFromExtractorRndm" are found the pixel is filled with // a random gaus calculated from these two MPedPhotCams in the case // the pixels is detected as background. // // // Input Containers: // MSignalCam // MPedPhotCam // MBadPixelsCam // [MGeomCam] // // Output Containers: // MSignalCam // ///////////////////////////////////////////////////////////////////////////// #include "MBadPixelsTreat.h" #include #include #include #include //#include "MArrayD.h" // Used instead of TArrayD because operator[] has no range check #include "MLog.h" #include "MLogManip.h" #include "MParList.h" #include "MGeomPix.h" #include "MGeomCam.h" #include "MSignalPix.h" #include "MSignalCam.h" #include "MPedPhotPix.h" #include "MPedPhotCam.h" #include "MBadPixelsPix.h" #include "MBadPixelsCam.h" ClassImp(MBadPixelsTreat); using namespace std; static const TString gsDefName = "MBadPixelsTreat"; static const TString gsDefTitle = "Task to treat bad pixels (interpolation, unmapping)"; // -------------------------------------------------------------------------- // // Default constructor. // MBadPixelsTreat::MBadPixelsTreat(const char *name, const char *title) : fGeomCam(0), fEvt(0), fBadPixels(0), fPedPhot1(0), fPedPhot2(0), fFlags(0), fNumMinNeighbors(3), fMaxArrivalTimeDiff(0.9) { fName = name ? name : gsDefName.Data(); fTitle = title ? title : gsDefTitle.Data(); SetUseInterpolation(); SetProcessPedestal(); SetProcessTimes(); } // -------------------------------------------------------------------------- // // Returns the status of a pixel. If kHardTreatment is set a pixel must // be unsuitable or uriliable to be treated. If not it is treated only if // it is unsuitable // (IsBad() checks for any flag) // Bool_t MBadPixelsTreat::IsPixelBad(Int_t idx) const { return TESTBIT(fFlags, kHardTreatment) ? (*fBadPixels)[idx].IsBad():(*fBadPixels)[idx].IsUnsuitable(); } void MBadPixelsTreat::AddNamePedPhotCam(const char *name) { fNamePedPhotCams.Add(new TObjString(name)); } // -------------------------------------------------------------------------- // // - Try to find or create MBlindPixels in parameter list. // - get the MSignalCam from the parlist (abort if missing) // - if no pixels are given by the user try to determin the starfield // from the monte carlo run header. // Int_t MBadPixelsTreat::PreProcess (MParList *pList) { fBadPixels = (MBadPixelsCam*)pList->FindObject(AddSerialNumber("MBadPixelsCam")); if (!fBadPixels) { *fLog << err << AddSerialNumber("MBadPixelsCam") << " not found... aborting." << endl; return kFALSE; } fEvt = (MSignalCam*)pList->FindObject(AddSerialNumber("MSignalCam")); if (!fEvt) { *fLog << err << AddSerialNumber("MSignalCam") << " not found... aborting." << endl; return kFALSE; } fGeomCam = 0; if (!IsUseInterpolation()) return kTRUE; fGeomCam = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam")); if (!fGeomCam) { *fLog << err << AddSerialNumber("MGeomCam") << " not found - can't use interpolation... abort." << endl; *fLog << " Use MBadPixelsTreat::SetUseInterpolation(kFALSE) to switch interpolation" << endl; *fLog << " off and use unmapping instead." << endl; return kFALSE; } const Bool_t proc = IsProcessPedestalEvt() || IsProcessPedestalRun(); if (fNamePedPhotCams.GetSize()>0 && !proc) { *fLog << err << "Pedestal list contains entries, but pedestal treatment is switched off... abort." << endl; return kFALSE; } if (proc) { if (fNamePedPhotCams.GetSize()==0) { *fLog << inf << "No container names specified... using default: MPedPhotCam." << endl; AddNamePedPhotCam(); } fPedPhotCams.Clear(); TIter Next(&fNamePedPhotCams); TObject *o=0; while ((o=Next())) { TObject *p = pList->FindObject(AddSerialNumber(o->GetName()), "MPedPhotCam"); if (!p) { *fLog << err << AddSerialNumber(o->GetName()) << " [MPedPhotCam] not found... aborting." << endl; return kFALSE; } fPedPhotCams.Add(p); } } if (IsProcessTimes()) { fPedPhot1 = (MPedPhotCam*)pList->FindObject("MPedPhotFromExtractor", "MPedPhotCam"); fPedPhot2 = (MPedPhotCam*)pList->FindObject("MPedPhotFromExtractorRndm", "MPedPhotCam"); *fLog << inf << "Additional no-signal-interpolation switched "; *fLog << (fPedPhot1 && fPedPhot2 ? "on" : "off"); *fLog << "." << endl; } if (IsProcessPedestalEvt()) *fLog << inf << "Processing Pedestals once per event..." << endl; if (IsProcessPedestalRun()) *fLog << inf << "Processing Pedestals once per run..." << endl; if (IsProcessTimes()) *fLog << inf << "Processing Arrival Times once per event..." << endl; return kTRUE; } // -------------------------------------------------------------------------- // // Replaces each pixel (signal, signal error, pedestal, pedestal rms) // by the average of its surrounding pixels. // If TESTBIT(fFlags, kUseCentralPixel) is set the central pixel is also // included. // void MBadPixelsTreat::InterpolateSignal() const { const UShort_t entries = fGeomCam->GetNumPixels(); // // Loop over all pixels // for (UShort_t i=0; iGetPixRatio(i); nphot *= ratio; perr *= ratio; // // Loop over all its neighbors // const Int_t n = gpix.GetNumNeighbors(); for (int j=0; jGetPixRatio(nidx); // //The error is calculated as the quadratic sum of the errors // const MSignalPix &evtpix = (*fEvt)[nidx]; nphot += nratio*evtpix.GetNumPhotons(); perr += nratio*Pow2(evtpix.GetErrorPhot()); num++; } // Check if there are enough neighbors to calculate the mean // If not, unmap the pixel. The maximum number of blind neighbors // should be 2 if (numGetPixRatio(i); ped *= ratio; rms *= ratio; // // Loop over all its neighbors // const Int_t n = gpix.GetNumNeighbors(); for (int j=0; jGetPixRatio(nidx); const MPedPhotPix &nppix = pedphot[nidx]; // //The error is calculated as the quadratic sum of the errors // ped += nratio*nppix.GetMean(); rms += nratio*Pow2(nppix.GetRms()); num++; } // Check if there are enough neighbors to calculate the mean // If not, unmap the pixel. The minimum number of good neighbors // should be fNumMinNeighbors if (numReCalc(*fGeomCam, fBadPixels); } } // -------------------------------------------------------------------------- // void MBadPixelsTreat::InterpolateTimes() const { const Int_t n = fEvt->GetNumPixels(); for (int i=0; i 3) || (cnt < 2 && n2 == 3)) if (cntmax) max = tm1; } // If less than two nbeighbors belong to a shower the pixel doesn't // belong to the shower, too. Set the arrival time to a uniform // random value, otherwise use the mean value of the pixels belonging // to the shower. if (cnt2<=2) { sum2 = gRandom->Uniform(max-min)+min; // FIXME? Set Seed value? // Proceed with a treatment of the signal of empty pixels // better than the interpolation. (FIXME: Maybe a function // different from a gaussian could be a better choice...) if (fPedPhot1 && fPedPhot2) { const Int_t aidx = gpix.GetAidx(); const Double_t mean = fPedPhot1->GetArea(aidx).GetMean(); const Double_t rms = fPedPhot2->GetArea(aidx).GetRms(); const Double_t phe = gRandom->Gaus(mean, rms); (*fEvt)[i].SetNumPhotons(phe); } } else sum2 /= cnt2*2; (*fEvt)[i].SetArrivalTime(sum2); } } // -------------------------------------------------------------------------- // // Removes all blind pixels from the analysis by setting their state // to unused. // void MBadPixelsTreat::Unmap() const { const UShort_t entries = fEvt->GetNumPixels(); // // remove the pixels in fPixelsIdx if they are set to be used, // (set them to 'unused' state) // for (UShort_t i=0; i