/* ======================================================================== *\ ! ! * ! * 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 02/2004 ! ! Copyright: MAGIC Software Development, 2000-2004 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MHCalibrationRelTimeCam // // Fills the extracted relative arrival times of MArrivalTimeCam into // the MHGausEvents-classes MHCalibrationRelTimePix for every: // // - Pixel, stored in the TObjArray's MHCalibrationCam::fHiGainArray // or MHCalibrationCam::fHiGainArray, respectively, depending if // MArrivalTimePix::IsLoGainUsed() is set. // // - Average pixel per AREA index (e.g. inner and outer for the MAGIC camera), // stored in the TObjArray's MHCalibrationCam::fAverageHiGainAreas and // MHCalibrationCam::fAverageHiGainAreas // // - Average pixel per camera SECTOR (e.g. sectors 1-6 for the MAGIC camera), // stored in the TObjArray's MHCalibrationCam::fAverageHiGainSectors // and MHCalibrationCam::fAverageHiGainSectors // // Every relative time is calculated as the difference between the individual // pixel arrival time and the one of pixel 1 (hardware number: 2). // The relative times are filled into a histogram and an array, in order to perform // a Fourier analysis (see MHGausEvents). The signals are moreover averaged on an // event-by-event basis and written into the corresponding average pixels. // // The histograms are fitted to a Gaussian, mean and sigma with its errors // and the fit probability are extracted. If none of these values are NaN's and // if the probability is bigger than MHGausEvents::fProbLimit (default: 0.5%), // the fit is declared valid. // Otherwise, the fit is repeated within ranges of the previous mean // +- MHGausEvents::fPickupLimit (default: 5) sigma (see MHGausEvents::RepeatFit()) // In case this does not make the fit valid, the histogram means and RMS's are // taken directly (see MHGausEvents::BypassFit()) and the following flags are set: // - MBadPixelsPix::SetUncalibrated( MBadPixelsPix::kRelTimeNotFitted ) and // - MBadPixelsPix::SetUnsuitable( MBadPixelsPix::kUnreliableRun ) // // Outliers of more than MHGausEvents::fPickupLimit (default: 5) sigmas // from the mean are counted as Pickup events (stored in MHGausEvents::fPickup) // // The class also fills arrays with the signal vs. event number, creates a fourier // spectrum (see MHGausEvents::CreateFourierSpectrum()) and investigates if the // projected fourier components follow an exponential distribution. // In case that the probability of the exponential fit is less than // MHGausEvents::fProbLimit (default: 0.5%), the following flags are set: // - MBadPixelsPix::SetUncalibrated( MBadPixelsPix::kRelTimeOscillating ) and // - MBadPixelsPix::SetUnsuitable( MBadPixelsPix::kUnreliableRun ) // // This same procedure is performed for the average pixels. // // The following results are written into MCalibrationRelTimeCam: // // - MCalibrationPix::SetMean() // - MCalibrationPix::SetMeanErr() // - MCalibrationPix::SetSigma() // - MCalibrationPix::SetSigmaErr() // - MCalibrationPix::SetProb() // - MCalibrationPix::SetNumPickup() // // For all averaged areas, the fitted sigma is multiplied with the square root of // the number involved pixels in order to be able to compare it to the average of // sigmas in the camera. // ///////////////////////////////////////////////////////////////////////////// #include "MHCalibrationRelTimeCam.h" #include "MHCalibrationRelTimePix.h" #include "MLog.h" #include "MLogManip.h" #include "MParList.h" #include "MCalibrationRelTimeCam.h" #include "MCalibrationPix.h" #include "MArrivalTimeCam.h" #include "MArrivalTimePix.h" #include "MGeomCam.h" #include "MGeomPix.h" #include "MBadPixelsCam.h" #include "MBadPixelsPix.h" ClassImp(MHCalibrationRelTimeCam); using namespace std; const UInt_t MHCalibrationRelTimeCam::fgReferencePixel = 1; // -------------------------------------------------------------------------- // // Default Constructor. // // Sets: // - fReferencePixel to fgReferencePixel // MHCalibrationRelTimeCam::MHCalibrationRelTimeCam(const char *name, const char *title) { fName = name ? name : "MHCalibrationRelTimeCam"; fTitle = title ? title : "Histogram class for the relative time calibration of the camera"; SetReferencePixel(); } // -------------------------------------------------------------------------- // // Gets or creates the pointers to: // - MCalibrationRelTimeCam // // Searches pointer to: // - MArrivalTimeCam // // Initializes, if empty to MGeomCam::GetNumPixels(): // - MHCalibrationCam::fHiGainArray, MHCalibrationCam::fLoGainArray // // Initializes, if empty to MGeomCam::GetNumAreas() for: // - MHCalibrationCam::fAverageHiGainAreas, MHCalibrationCam::fAverageLoGainAreas // // Initializes, if empty to MGeomCam::GetNumSectors() for: // - MHCalibrationCam::fAverageHiGainSectors, MHCalibrationCam::fAverageLoGainSectors // // Calls MHCalibrationCam::InitHists() for every entry in: // - MHCalibrationCam::fHiGainArray, MHCalibrationCam::fLoGainArray // - MHCalibrationCam::fAverageHiGainAreas, MHCalibrationCam::fAverageLoGainAreas // - MHCalibrationCam::fAverageHiGainSectors, MHCalibrationCam::fAverageLoGainSectors // // Sets Titles and Names for the Histograms // - MHCalibrationCam::fAverageHiGainAreas // - MHCalibrationCam::fAverageHiGainSectors // // Sets number of bins to MHCalibrationCam::fAverageNbins for: // - MHCalibrationCam::fAverageHiGainAreas, MHCalibrationCam::fAverageLoGainAreas // - MHCalibrationCam::fAverageHiGainSectors, MHCalibrationCam::fAverageLoGainSectors // Bool_t MHCalibrationRelTimeCam::ReInitHists(MParList *pList) { fCam = (MCalibrationCam*)pList->FindObject("MCalibrationRelTimeCam"); if (!fCam) { fCam = (MCalibrationCam*)pList->FindCreateObj(AddSerialNumber("MCalibrationRelTimeCam")); if (!fCam) { gLog << err << "Cannot find nor create MCalibrationRelTimeCam ... abort." << endl; return kFALSE; } else fCam->Init(*fGeom); } MArrivalTimeCam *signal = (MArrivalTimeCam*)pList->FindObject("MArrivalTimeCam"); if (!signal) { *fLog << err << "MArrivalTimeCam not found... abort." << endl; return kFALSE; } const Int_t npixels = fGeom->GetNumPixels(); const Int_t nsectors = fGeom->GetNumSectors(); const Int_t nareas = fGeom->GetNumAreas(); if (fHiGainArray->GetEntries()==0) { fHiGainArray->Expand(npixels); for (Int_t i=0; iGetEntries()==0) { fLoGainArray->Expand(npixels); for (Int_t i=0; iGetEntries()==0) { fAverageHiGainAreas->Expand(nareas); for (Int_t j=0; jSetTitle("Rel. Arr. Times HiGain Area Idx "); GetAverageHiGainArea(j).SetNbins(fAverageNbins); InitHists(GetAverageHiGainArea(j),fCam->GetAverageBadArea(j),j); } } if (fAverageLoGainAreas->GetEntries()==0) { fAverageLoGainAreas->Expand(nareas); for (Int_t j=0; jSetTitle("Rel. Arr. Times LoGain Area Idx "); GetAverageLoGainArea(j).SetNbins(fAverageNbins); InitHists(GetAverageLoGainArea(j),fCam->GetAverageBadArea(j),j); } } if (fAverageHiGainSectors->GetEntries()==0) { fAverageHiGainSectors->Expand(nsectors); for (Int_t j=0; jSetTitle("Rel. Arr. Times HiGain Sector "); GetAverageHiGainSector(j).SetNbins(fAverageNbins); InitHists(GetAverageHiGainSector(j),fCam->GetAverageBadSector(j),j); } } if (fAverageLoGainSectors->GetEntries()==0) { fAverageLoGainSectors->Expand(nsectors); for (Int_t j=0; jSetTitle("Rel. Arr. Times LoGain Sector "); GetAverageLoGainSector(j).SetNbins(fAverageNbins); InitHists(GetAverageLoGainSector(j),fCam->GetAverageBadSector(j),j); } } return kTRUE; } // ------------------------------------------------------------------------------- // // Retrieves pointer to MArrivalTimeCam: // // Retrieves from MGeomCam: // - number of pixels // - number of pixel areas // - number of sectors // // Fills HiGain or LoGain histograms (MHGausEvents::FillHistAndArray()), respectively // depending on MArrivalTimePix::IsLoGainUsed(), with: // - MArrivalTimePix::GetArrivalTime(pixid) - MArrivalTimePix::GetArrivalTime(1); // (i.e. the time difference between pixel i and pixel 1 (hardware number: 2) ) // Bool_t MHCalibrationRelTimeCam::FillHists(const MParContainer *par, const Stat_t w) { MArrivalTimeCam *arrtime = (MArrivalTimeCam*)par; if (!arrtime) { gLog << err << "No argument in MArrivalTime::Fill... abort." << endl; return kFALSE; } const Int_t npixels = fGeom->GetNumPixels(); const Int_t nareas = fGeom->GetNumAreas(); const Int_t nsectors = fGeom->GetNumSectors(); Float_t sumareahi [nareas], sumarealo [nareas]; Float_t sumsectorhi[nsectors], sumsectorlo[nsectors]; Int_t numareahi [nareas], numarealo [nareas]; Int_t numsectorhi[nsectors], numsectorlo[nsectors]; memset(sumareahi, 0, nareas * sizeof(Float_t)); memset(sumarealo, 0, nareas * sizeof(Float_t)); memset(sumsectorhi, 0, nsectors*sizeof(Float_t)); memset(sumsectorlo, 0, nsectors*sizeof(Float_t)); memset(numareahi, 0, nareas * sizeof(Float_t)); memset(numarealo, 0, nareas * sizeof(Float_t)); memset(numsectorhi, 0, nsectors*sizeof(Float_t)); memset(numsectorlo, 0, nsectors*sizeof(Float_t)); const MArrivalTimePix &refpix = (*arrtime)[fReferencePixel]; const Float_t reftime = refpix.IsLoGainUsed() ? refpix.GetArrivalTimeLoGain() : refpix.GetArrivalTimeHiGain(); for (Int_t i=0; iGetSize(); i++) { MBadPixelsPix &bad = (*fBadPixels)[i]; if (bad.IsUncalibrated( MBadPixelsPix::kRelTimeNotFitted )) bad.SetUnsuitable( MBadPixelsPix::kUnreliableRun ); if (bad.IsUncalibrated( MBadPixelsPix::kRelTimeOscillating)) bad.SetUnsuitable( MBadPixelsPix::kUnreliableRun ); } } // -------------------------------------------------------------------------- // // The types are as follows: // // Fitted values: // ============== // // 0: Fitted Mean Relative Arrival Time in ns (MHGausEvents::GetMean()*MHCalibrationRelTimePix::GetFADCSliceWidth()) // 1: Error Mean Relative Arrival Time in ns (MHGausEvents::GetMeanErr()*MHCalibrationRelTimePix::GetFADCSliceWidth()) // 2: Sigma fitted Relative Arrival Time in ns (MHGausEvents::GetSigma()*MHCalibrationRelTimePix::GetFADCSliceWidth()) // 3: Error Sigma Relative Arrival Time in ns (MHGausEvents::GetSigmaErr()*MHCalibrationRelTimePix::GetFADCSliceWidth()) // // Useful variables derived from the fit results: // ============================================= // // 4: Returned probability of Gauss fit (calls: MHGausEvents::GetProb()) // // Localized defects: // ================== // // 5: Gaus fit not OK (calls: MHGausEvents::IsGausFitOK()) // 6: Fourier spectrum not OK (calls: MHGausEvents::IsFourierSpectrumOK()) // Bool_t MHCalibrationRelTimeCam::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const { if (fHiGainArray->GetSize() <= idx) return kFALSE; const MHCalibrationRelTimePix &pix = (MHCalibrationRelTimePix&)(*this)[idx]; const Float_t fadc2ns = pix.GetFADCSliceWidth(); switch (type) { case 0: val = pix.GetMean()*fadc2ns; break; case 1: val = pix.GetMeanErr()*fadc2ns; break; case 2: val = pix.GetSigma()*fadc2ns; break; case 3: val = pix.GetSigmaErr()*fadc2ns; break; case 4: val = pix.GetProb(); break; case 5: if (!pix.IsGausFitOK()) val = 1.; break; case 6: if (!pix.IsFourierSpectrumOK()) val = 1.; break; default: return kFALSE; } return kTRUE; } // -------------------------------------------------------------------------- // // Calls MHGausEvents::DrawClone() for pixel idx // void MHCalibrationRelTimeCam::DrawPixelContent(Int_t idx) const { (*this)[idx].DrawClone(); }