/* ======================================================================== *\ ! ! * ! * 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 08/2004 ! ! Copyright: MAGIC Software Development, 2000-2004 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // MCalibrationTestCalc // // PreProcess(): Initialize pointers to MHCalibrationTestCam // // ReInit(): MCalibrationCam::InitSize(NumPixels) is called from MGeomApply (which allocates // memory in a TClonesArray of type MCalibrationChargePix) // Initializes pointer to MBadPixelsCam // // Process(): Nothing to be done, histograms getting filled by MHCalibrationTestCam // // PostProcess(): Print out interpolation results to file // // Input Containers: // MHCalibrationTestCam // MBadPixelsCam // MGeomCam // // Output Containers: // none // ////////////////////////////////////////////////////////////////////////////// #include "MCalibrationTestCalc.h" #include #include #include #include "MLog.h" #include "MLogManip.h" #include "MParList.h" #include "MGeomCam.h" #include "MGeomPix.h" #include "MHCamera.h" #include "MHCalibrationTestCam.h" #include "MHCalibrationTestPix.h" #include "MCalibrationTestCam.h" #include "MCalibrationTestPix.h" #include "MBadPixelsCam.h" #include "MBadPixelsPix.h" ClassImp(MCalibrationTestCalc); using namespace std; const Float_t MCalibrationTestCalc::fgPhotErrLimit = 4.5; // -------------------------------------------------------------------------- // // Default constructor. // // Sets the pointer to fTestCam and fGeom to NULL // Sets outputpath to "." // Sets outputfile to "TestCalibStat.txt" // Sets fPhotErrLimit to fgPhotErrLimit // // Calls: // - Clear() // MCalibrationTestCalc::MCalibrationTestCalc(const char *name, const char *title) : fBadPixels(NULL), fTestCam(NULL), fCam(NULL), fGeom(NULL) { fName = name ? name : "MCalibrationTestCalc"; fTitle = title ? title : "Task to output the results of MHCalibrationTestCam "; SetPhotErrLimit(); SetOutputPath(); SetOutputFile(); } // ----------------------------------------------------------------------------------- // // The following containers are searched and created if they were not found: // // - MBadPixelsCam // Int_t MCalibrationTestCalc::PreProcess(MParList *pList) { // // Containers that are created in case that they are not there. // fBadPixels = (MBadPixelsCam*)pList->FindCreateObj(AddSerialNumber("MBadPixelsCam")); if (!fBadPixels) { *fLog << err << "Could not find or create MBadPixelsCam ... aborting." << endl; return kFALSE; } fCam = (MCalibrationTestCam*)pList->FindCreateObj("MCalibrationTestCam"); if (!fCam) { *fLog << err << "Could not find or create MCalibrationTestCam ... aborting." << endl; return kFALSE; } return kTRUE; } // -------------------------------------------------------------------------- // // Search for the following input containers and abort if not existing: // - MGeomCam // - MHCalibrationTestCam // // Bool_t MCalibrationTestCalc::ReInit(MParList *pList ) { fGeom = (MGeomCam*)pList->FindObject("MGeomCam"); if (!fGeom) { *fLog << err << "No MGeomCam found... aborting." << endl; return kFALSE; } fTestCam = (MHCalibrationTestCam*)pList->FindObject("MHCalibrationTestCam"); if (!fTestCam) { *fLog << err << "Cannot find MHCalibrationTestCam... aborting" << endl; *fLog << err << "Maybe you forget to call an MFillH for the MHCalibrationTestCam before..." << endl; return kFALSE; } return kTRUE; } // ---------------------------------------------------------------------------------- // // Nothing to be done in Process, but have a look at MHCalibrationTestCam, instead // Int_t MCalibrationTestCalc::Process() { return kTRUE; } // ----------------------------------------------------------------------- // // Return if number of executions is null. // // Print out some statistics // Int_t MCalibrationTestCalc::PostProcess() { if (GetNumExecutions()==0) return kFALSE; // // Re-direct the output to an ascii-file from now on: // MLog asciilog; asciilog.SetOutputFile(GetOutputFile(),kTRUE); SetLogStream(&asciilog); // // Finalize calibration statistics // FinalizeCalibratedPhotons(); FinalizeNotInterpolated(); const Int_t maxbad = CalcMaxNumBadPixelsCluster(); *fLog << inf << endl; *fLog << GetDescriptor() << ": Pixel Interpolation status:" << endl; if (fGeom->InheritsFrom("MGeomCamMagic")) { *fLog << " " << setw(7) << "Not interpolateable Pixels: " << Form("%s%3i%s%3i","Inner: ",fCam->GetNumUninterpolated(0), " Outer: ",fCam->GetNumUninterpolated(1)) << endl; *fLog << " " << setw(7) << "Biggest not-interpolateable cluster: " << maxbad << endl; } fCam->SetNumUninterpolatedInMaxCluster(maxbad); *fLog << endl; SetLogStream(&gLog); return kTRUE; } // ------------------------------------------------------------------------ // // // First loop: Calculate a mean and mean RMS of calibrated photons per area index // Include only MHCalibrationTestPix's which are not empty (not interpolated) // // Second loop: Get weighted mean number of calibrated photons and its RMS // excluding those deviating by more than fPhotErrLimit // sigmas from the mean (obtained in first loop). Set // MBadPixelsPix::kDeviatingNumPhots if excluded. // void MCalibrationTestCalc::FinalizeCalibratedPhotons() const { const UInt_t npixels = fGeom->GetNumPixels(); const UInt_t nareas = fGeom->GetNumAreas(); const UInt_t nsectors = fGeom->GetNumSectors(); Double_t lowlim [nareas]; Double_t upplim [nareas]; Double_t areaphotons [nareas], sectorphotons [nsectors]; Double_t areavars [nareas], sectorvars [nsectors]; Double_t fittedmean [nareas], fittedsigma [nareas]; Int_t numareavalid[nareas], numsectorvalid[nsectors]; memset(lowlim ,0, nareas * sizeof(Double_t)); memset(upplim ,0, nareas * sizeof(Double_t)); memset(fittedmean ,0, nareas * sizeof(Double_t)); memset(fittedsigma ,0, nareas * sizeof(Double_t)); memset(areaphotons ,0, nareas * sizeof(Double_t)); memset(areavars ,0, nareas * sizeof(Double_t)); memset(numareavalid ,0, nareas * sizeof(Int_t )); memset(sectorphotons ,0, nsectors * sizeof(Double_t)); memset(sectorvars ,0, nsectors * sizeof(Double_t)); memset(numsectorvalid,0, nsectors * sizeof(Int_t )); // // First loop: Get mean number of calibrated photons and the RMS // The loop is only to recognize later pixels with very deviating numbers // MHCamera camphotons(*fGeom,"Camphotons","Photons in Camera"); for (UInt_t i=0; iGetAverageArea(aidx); avpix.SetNumPhotons (areamean); avpix.SetNumPhotonsErr(areaerr ); lowlim [aidx] = areamean - fPhotErrLimit*areaerr; upplim [aidx] = areamean + fPhotErrLimit*areaerr; TArrayI area(1); area[0] = aidx; TH1D *hist = camphotons.ProjectionS(TArrayI(),area,"_py",100); hist->Fit("gaus","Q"); const Double_t mean = hist->GetFunction("gaus")->GetParameter(1); const Double_t sigma = hist->GetFunction("gaus")->GetParameter(2); const Int_t ndf = hist->GetFunction("gaus")->GetNDF(); if (ndf < 2) { *fLog << warn << GetDescriptor() << ": Cannot use a Gauss fit to the number of calibrated photons " << "in the camera with area index: " << aidx << endl; *fLog << warn << GetDescriptor() << ": Number of dof.: " << ndf << " is smaller than 2 " << endl; *fLog << warn << GetDescriptor() << ": Will use the simple mean and rms " << endl; delete hist; continue; } const Double_t prob = hist->GetFunction("gaus")->GetProb(); if (prob < 0.001) { *fLog << warn << GetDescriptor() << ": Cannot use a Gauss fit to the number of calibrated photons " << "in the camera with area index: " << aidx << endl; *fLog << warn << GetDescriptor() << ": Fit probability " << prob << " is smaller than 0.001 " << endl; *fLog << warn << GetDescriptor() << ": Will use the simple mean and rms " << endl; delete hist; continue; } fittedmean [aidx] = mean; fittedsigma[aidx] = sigma; avpix.SetNumPhotons (mean ); avpix.SetNumPhotonsErr(sigma); lowlim [aidx] = mean - fPhotErrLimit*sigma; upplim [aidx] = mean + fPhotErrLimit*sigma; *fLog << inf << GetDescriptor() << ": Fitted number of calib. equiv. Cher. photons in area index " << aidx << ": " << Form("%7.2f +- %6.2f",fittedmean[aidx],fittedsigma[aidx]) << endl; delete hist; } *fLog << endl; memset(numareavalid,0,nareas*sizeof(Int_t)); memset(areaphotons ,0,nareas*sizeof(Double_t)); memset(areavars ,0,nareas*sizeof(Double_t)); // // Second loop: Get mean number of calibrated photons and its RMS excluding // pixels deviating by more than fPhotErrLimit sigma. // for (UInt_t i=0; i upplim[aidx] ) { *fLog << warn << GetDescriptor() << ": Number of photons: " << Form("%8.2f out of %3.1f sigma limit: ",nphot,fPhotErrLimit) << Form("[%8.2f,%8.2f] pixel%4i",lowlim[aidx],upplim[aidx],i) << endl; MBadPixelsPix &bad = (*fBadPixels)[i]; bad.SetUncalibrated( MBadPixelsPix::kDeviatingNumPhots ); bad.SetUnsuitable ( MBadPixelsPix::kUnsuitableRun ); continue; } areavars [aidx] += nphotpera*nphotpera; areaphotons [aidx] += nphotpera; numareavalid [aidx] ++; sectorvars [sector] += nphotpera*nphotpera; sectorphotons [sector] += nphotpera; numsectorvalid[sector] ++; } *fLog << endl; for (UInt_t aidx=0; aidxGetAverageArea(aidx); if (areavars[aidx] < 0. || areaphotons[aidx] <= 0.) { *fLog << warn << GetDescriptor() << ": Mean number of photons per area in area index " << aidx << " could not be calculated! Mean: " << areaphotons[aidx] << " Variance: " << areavars[aidx] << endl; avpix.SetExcluded(); continue; } const Float_t areaerr = TMath::Sqrt(areavars[aidx]); avpix.SetNumPhotonsPerArea (areaphotons[aidx]); avpix.SetNumPhotonsPerAreaErr(areaerr ); *fLog << inf << GetDescriptor() << ": Mean number of equiv. Cher. photons " << "per area in area idx " << aidx << ": " << Form("%5.3f+-%5.4f [ph/mm^2]",areaphotons[aidx],areaerr) << endl; } *fLog << endl; for (UInt_t sector=0; sectorGetAverageSector(sector); if (sectorvars[sector] < 0. || sectorphotons[sector] <= 0.) { *fLog << warn << GetDescriptor() << ": Mean number of calibrated photons per area in sector " << sector << " could not be calculated! Mean: " << sectorphotons[sector] << " Variance: " << sectorvars[sector] << endl; avpix.SetExcluded(); continue; } const Float_t sectorerr = TMath::Sqrt(sectorvars[sector]); avpix.SetNumPhotonsPerArea (sectorphotons[sector]); avpix.SetNumPhotonsPerAreaErr(sectorerr ); *fLog << inf << GetDescriptor() << ": Mean number of equiv. Cher. photons " << "per area in sector " << sector << ": " << Form("%5.3f+-%5.4f [ph/mm^2]",sectorphotons[sector],sectorerr) << endl; } return; } // ----------------------------------------------------------------------------------------------- // // Print out statistics about not interpolated pixels // void MCalibrationTestCalc::FinalizeNotInterpolated() { const Int_t areas = fGeom->GetNumAreas(); TArrayI *newarr[areas]; for (Int_t aidx=0; aidxGetSize(); i++) { const Int_t aidx = (*fGeom)[i].GetAidx(); if ((*fCam)[i].IsExcluded()) { const Int_t size = newarr[aidx]->GetSize(); newarr[aidx]->Set(size+1); newarr[aidx]->AddAt(i,size); } } Int_t num = 0; for (Int_t aidx = 0; aidxGetSize(); i++) { *fLog << newarr[aidx]->At(i) << " "; num++; } fCam->SetNumUninterpolated(newarr[aidx]->GetSize(),aidx); *fLog << endl; } *fLog << " " << setw(7) << num << " total not interpolateable pixels " << endl; } Int_t MCalibrationTestCalc::CalcMaxNumBadPixelsCluster() { TArrayI arr(0); for (Int_t i=0; iGetSize(); i++) if ((*fCam)[i].IsExcluded()) { const Int_t s = arr.GetSize(); arr.Set(s+1); arr[s] = i; } const Int_t size = arr.GetSize(); if (size == 0) return 0; if (size == 1) return 1; TArrayI knownpixels(0); Int_t clustersize = 1; Int_t oldclustersize = 0; // // Loop over the not-interpolateable pixels: // for (Int_t i=0; i oldclustersize) oldclustersize = clustersize; clustersize = 1; } return oldclustersize; } void MCalibrationTestCalc::LoopNeighbours( const TArrayI &arr, TArrayI &knownpixels, Int_t &clustersize, const Int_t idx ) { const MGeomPix &pix = (*fGeom)[idx]; const Byte_t neighbours = pix.GetNumNeighbors(); // // Loop over the next neighbours: // - Check if they are already in the list of known pixels // - If not, call loopneighbours for the rest // - grow clustersize for those // for (Int_t i=0;i=0;j--) if (newid == knownpixels.At(j)) { known = kTRUE; break; } if (known) continue; for (Int_t k=0;k