/* ======================================================================== *\ ! ! * ! * 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 01/2004 ! Author(s): Thomas Bretz 01/2004 ! ! Copyright: MAGIC Software Development, 2000-2007 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MExtractPedestal // // Pedestal Extractor base class // // Input Containers: // MRawEvtData // MRawRunHeader // MRawEvtHeader // MGeomCam // MPedestalCam // // Output Containers: // MPedestalCam // // This class should be used for pedestal extractors with the following facilities: // a) Standardized calculation of AB-noise, mean pedestals and RMS // b) Standardized treatment of area- and sector averaged pedestals values // c) Possibility to use a signal extractor to be applied on the pedestals // d) Possibility to handle two MPedestalCams: one for the signal extractor and // a second to be filled during the pedestal calculating process. // // ad a): Every calculated value is referred to one FADC slice (e.g. Mean pedestal per slice), // RMS per slice. // MExtractPedestal applies the following formula (1): // // Pedestal per slice = sum(x_i) / n / slices // PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / slices ) // AB-Offset per slice = (sumAB0 - sumAB1) / n / slices // // where x_i is the sum of "slices" FADC slices and sum means the sum over all // events. "n" is the number of events, "slices" is the number of summed FADC samples. // // Note that the slice-to-slice fluctuations are not Gaussian, but Poissonian, thus // asymmetric and they are correlated. // // It is important to know that the Pedestal per slice and PedRMS per slice depend // on the number of used FADC slices, as seen in the following plots: // //Begin_Html /* */ //End_Html // //Begin_Html /* */ //End_Html // // The plots show the inner and outer pixels, respectivly and have the following meaning: // // 1) The calculated mean pedestal per slice (from MPedCalcPedRun) // 2) The fitted mean pedestal per slice (from MHPedestalCam) // 3) The calculated pedestal RMS per slice (from MPedCalcPedRun) // 4) The fitted sigma of the pedestal distribution per slice // (from MHPedestalCam) // 5) The relative difference between calculation and histogram fit // for the mean // 6) The relative difference between calculation and histogram fit // for the sigma or RMS, respectively. // // The calculated means do not change significantly except for the case of 2 slices, // however the RMS changes from 5.7 per slice in the case of 2 extracted slices // to 8.3 per slice in the case of 26 extracted slices. This change is very significant. // // ad b) Every calculated value is referred to one FADC slice and one (averaged) pixel, // (e.g. Mean Pedestal per area index per slice per pixel, etc. ) // // MExtractPedestal applies the following formula (2): // // Averaged Pedestal per slice = sum(x_i) / n / slices / n_pix // PedRMS per slice = Sqrt( ( sum(x_i^2) - sum(x_i)^2/n ) / n-1 / slices / n_pix ) // AB-Offset per slice = (sumAB0 - sumAB1) / n / slices / n_pix // // where x_i is the sum of "slices" FADC slices and sum means the sum over all // events and all concerned pixels. // "n" is the number of events, "slices" is the number of summed FADC samples and // "n_pix" is the number of pixels belonging to the specific area index or camera sector. // // Calculating these averaged event-by-event values is very important to trace coherent // fluctuations. An example is given in the following plots: // //Begin_Html /* */ //End_Html // // The plots show the extracted pedestals of the inner pixels (obtained // with MHPedestalCam), averaged on an event-by-event basis from // run 13428 with switched off camera LV. // The meaning of the four plots is: // // 1) The distribution of the averaged pedestals // 2) The averaged pedestals vs. time. // One can see clearly the oscillation pattern // 3) The fourier transform of the averaged pedestals vs. time. // One can see clearly a peak at a certain frequency // 4) The projection of the fourier components with the non-exponential // (and therefore significant) outlier. // // ad c) Many signal extractors, especially those using a sliding window // have biases and their resolutions for zero-signals do not agree // with the pedestal RMS. For the F-Factor method in the calibration // and the image cleaning, however, both have to be known and measured. // // For this reason, a signal extractor can be handed over to the // pedestal extractor and applied on the pedestal events with the // function SetExtractor(). // The results will get stored in an MPedestalCam. // // Note that only extractors deriving from MExtractTimeAndCharge // can be used. // // ad d) The signal extractors themselves need a pedestal to be subtracted // from the FADC slices. // If the user wishes that the pededestals do not get overwritten by // the results from the signal extractor, a different named MPedestalCam // can be created with the function: SetNamePedestalOut(). // // See also: MPedestalCam, MPedestalPix, MPedCalcPedRun, MPedCalcFromLoGain // ///////////////////////////////////////////////////////////////////////////// #include "MExtractPedestal.h" #include "MParList.h" #include "MLog.h" #include "MLogManip.h" #include "MRawRunHeader.h" #include "MRawEvtHeader.h" #include "MRawEvtPixelIter.h" #include "MPedestalPix.h" #include "MPedestalCam.h" #include "MGeom.h" #include "MGeomCam.h" #include "MExtractTimeAndCharge.h" #include "MPedestalSubtractedEvt.h" ClassImp(MExtractPedestal); using namespace std; const TString MExtractPedestal::fgNamePedestalCam = "MPedestalCam"; const TString MExtractPedestal::fgNameRawEvtData = "MRawEvtData"; const UShort_t MExtractPedestal::fgCheckWinFirst = 0; const UShort_t MExtractPedestal::fgCheckWinLast = 29; const UShort_t MExtractPedestal::fgMaxSignalVar = 40; const UShort_t MExtractPedestal::fgMaxSignalAbs = 250; // -------------------------------------------------------------------------- // // Default constructor: // // Sets: // - all pointers to NULL // // Calls: // - Clear() // MExtractPedestal::MExtractPedestal(const char *name, const char *title) : fGeom(NULL), fPedestalsInter(NULL), fPedestalsOut(NULL), fExtractor(NULL), fSignal(0), fExtractWinFirst(0), fExtractWinSize(0), fUseSpecialPixels(kFALSE), fCounter(0) { fName = name ? name : "MExtractPedestal"; fTitle = title ? title : "Base class to calculate pedestals"; SetIntermediateStorage( kFALSE ); SetRandomCalculation ( kTRUE ); SetNamePedestalCamOut(); SetNamePedestalCamInter(); SetNameRawEvtData(); SetCheckRange(fgCheckWinFirst, fgCheckWinLast); SetMaxSignalVar(fgMaxSignalVar); SetMaxSignalAbs(fgMaxSignalAbs); Clear(); } // -------------------------------------------------------------------------- // // Call reset() of all Arays // void MExtractPedestal::ResetArrays() { // Reset contents of arrays. fSumx.Reset(); fSumx2.Reset(); fSumAB0.Reset(); fSumAB1.Reset(); fAreaSumx.Reset(); fAreaSumx2.Reset(); fAreaSumAB0.Reset(); fAreaSumAB1.Reset(); fAreaFilled.Reset(); fAreaValid.Reset(); fSectorSumx.Reset(); fSectorSumx2.Reset(); fSectorSumAB0.Reset(); fSectorSumAB1.Reset(); fSectorFilled.Reset(); fSectorValid.Reset(); fNumEventsUsed.Reset(); } // -------------------------------------------------------------------------- // // Resets Arrays: // // Sets: // - fRawEvt to NULL // - fRunHeader to NULL // void MExtractPedestal::Clear(const Option_t *o) { fRawEvt = NULL; fRunHeader = NULL; // If the size is yet set, set the size if (fSumx.GetSize()>0) ResetArrays(); } // -------------------------------------------------------------------------- // // Checks: // - if a window is odd // Bool_t MExtractPedestal::SetExtractWindow(UShort_t windowf, UShort_t windows) { Bool_t rc = kTRUE; if (windows==0) { *fLog << warn << GetDescriptor(); *fLog << " - WARNING: Window size in SetExtractWindow has to be > 0... adjusting to 2!" << endl; windows = 2; rc = kFALSE; } fExtractWinSize = windows; fExtractWinFirst = windowf; fExtractWinLast = fExtractWinFirst+fExtractWinSize-1; return rc; } // -------------------------------------------------------------------------- // // SetCheckRange: // // Exits, if the first argument is smaller than 0 // Exits, if the the last argument is smaller than the first // Bool_t MExtractPedestal::SetCheckRange(UShort_t chfirst, UShort_t chlast) { Bool_t rc = kTRUE; if (chlast<=chfirst) { *fLog << warn << GetDescriptor(); *fLog << " - WARNING: Last slice in SetCheckRange smaller than first slice... set to first+2" << endl; chlast = chfirst+1; rc = kFALSE; } fCheckWinFirst = chfirst; fCheckWinLast = chlast; return rc; } Bool_t MExtractPedestal::SetRangeFromExtractor(const MExtractor &ext, Bool_t logain) { const Bool_t haslogains = ext.GetLoGainFirst()!=0 && ext.GetLoGainLast()!=0; Bool_t rc1 = kTRUE; if (!haslogains) { // We assume that in case without lo-gains we // deal with pedestal events only rc1 = SetCheckRange(ext.GetHiGainFirst(), ext.GetHiGainLast()); } const Int_t f = logain && haslogains ? ext.GetLoGainFirst() : ext.GetHiGainFirst(); const Int_t l = logain && haslogains ? ext.GetLoGainLast() : ext.GetHiGainLast(); const Int_t w = (l-f+1); // Setup to use the hi-gain extraction window in the lo-gain // range (the start of the lo-gain range is added automatically // by MPedCalcFromLoGain) const Bool_t rc2 = SetExtractWindow(f, w); return rc1 && rc2; } // -------------------------------------------------------------------------- // // Check (and if neccesary: correct) the extraction and check ranges. // void MExtractPedestal::CheckExtractionWindow(UInt_t offset) { *fLog << inf; *fLog << "Requested CheckWindow is [" << fCheckWinFirst << "," << fCheckWinLast << "]." <GetNumSamples() not yet initialized!!! const UInt_t num = fRunHeader->GetNumSamplesHiGain()+fRunHeader->GetNumSamplesLoGain(); // Check upper bound for check window if (fCheckWinLast >= num) { *fLog << inf << "CheckWindow [" << fCheckWinFirst << "," << fCheckWinLast; *fLog << "] out of range [0," << num-1 << "]... "; *fLog << "reset upper edge to " << num-1 << "." << endl; fCheckWinLast = num-1; } // Now check lower bound for check window if (fCheckWinFirst>fCheckWinLast) { *fLog << err << "CheckWindow first slice " << fCheckWinFirst; *fLog << " greater than last slice " << fCheckWinLast; *fLog << "... reset to 0." << endl; fCheckWinFirst = 0; } // check upper bound for extaction window if (fExtractWinLast+offset >= num) { *fLog << inf << "ExtractWindow [" << fExtractWinFirst+offset << "," << fExtractWinLast+offset; *fLog << "] out of range [0," << num-1 << "]... "; *fLog << "reset upper edge to " << num-1 << "." << endl; fExtractWinLast = num-offset-1; } // Now check lower bound for check window if (fExtractWinFirst>fExtractWinLast) { *fLog << err << "ExtractWindow first slice " << fExtractWinFirst+offset; *fLog << " greater than last slice " << fExtractWinLast+offset; *fLog << "... reset to 0." << endl; fExtractWinFirst = 0; } // Calculate window size for extraction window fExtractWinSize = fExtractWinLast-fExtractWinFirst+1; // Check if use tries to do a fundamental pedestal extraction // with an odd number of slices if (fExtractor || TMath::Even(fExtractWinSize)) return; // Make sure the number of extracted slices is even fExtractWinLast += offset+fExtractWinLast==num-1 ? -1 : +1; *fLog << inf << "ExtractionWindow odd... set to ["; *fLog << fExtractWinFirst+offset << "," << fExtractWinLast+offset << "]" << endl; fExtractWinSize = fExtractWinLast-fExtractWinFirst+1; } // -------------------------------------------------------------------------- // // Look for the following input containers: // // - MRawEvtData // - MRawRunHeader // - MRawEvtHeader // - MGeomCam // // The following output containers are also searched and created if // they were not found: // // - MPedestalCam with the name fPedContainerName // Int_t MExtractPedestal::PreProcess(MParList *pList) { Clear(); fRawEvt = (MRawEvtData*)pList->FindObject(AddSerialNumber(fNameRawEvtData)); if (!fRawEvt) { *fLog << err << AddSerialNumber(fNameRawEvtData) << " not found... aborting." << endl; return kFALSE; } fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader")); if (!fRunHeader) { *fLog << err << AddSerialNumber("MRawRunHeader") << " not found... aborting." << endl; return kFALSE; } fGeom = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam")); if (!fGeom) { *fLog << err << AddSerialNumber("MGeomCam") << " not found... aborting." << endl; return kFALSE; } fSignal = (MPedestalSubtractedEvt*)pList->FindObject(AddSerialNumber("MPedestalSubtractedEvt")); if (!fSignal) { *fLog << err << AddSerialNumber("MPedestalSubtractedEvt") << " not found... aborting." << endl; return kFALSE; } if (!fPedestalsInter && fIntermediateStorage) { fPedestalsInter = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamInter)); if (!fPedestalsInter) return kFALSE; } if (!fPedestalsOut) { fPedestalsOut = (MPedestalCam*)pList->FindCreateObj("MPedestalCam", AddSerialNumber(fNamePedestalCamOut)); if (!fPedestalsOut) return kFALSE; } fCounter = 0; return fExtractor ? fExtractor->CallPreProcess(pList) : kTRUE; } //----------------------------------------------------------------------- // // Call Calc(). If fExtractor!=NULL enclose the call in setting the // NoiseCalculation to fRandomCalculation // Int_t MExtractPedestal::Process() { // // Necessary check for extraction of special pixels // together with data which does not yet have them // if (fSumx.GetSize()==0) return kTRUE; if (fExtractor) fExtractor->SetNoiseCalculation(fRandomCalculation); Calc(); if (fExtractor) fExtractor->SetNoiseCalculation(kFALSE); fPedestalsOut->SetNumEvents(fCounter); return kTRUE; } // --------------------------------------------------------------------------------- // // Sets the size (from MPedestalCam::GetSize() ) and resets the following arrays: // - fSumx // - fSumx2 // - fSumAB0 // - fSumAB1 // - fAreaSumx // - fAreaSumx2 // - fAreaSumAB0 // - fAreaSumAB1 // - fAreaFilled // - fAreaValid // - fSectorSumx // - fSectorSumx2 // - fSectorSumAB0 // - fSectorSumAB1 // - fSectorFilled // - fSectorValid // Bool_t MExtractPedestal::ReInit(MParList *pList) { // Necessary check for special pixels which might not yet have existed if (!fRawEvt) { if (fRunHeader->GetFormatVersion() > 3) return kTRUE; *fLog << err << "ERROR - " << fNameRawEvtData << " [MRawEvtData] has not "; *fLog << "been found and format version > 3... abort." << endl; return kFALSE; } // If the size is not yet set, set the size if (fSumx.GetSize()==0) { // Initialize the normal pixels (size of MPedestalCam already set by MGeomApply) const Int_t npixels = fPedestalsOut->GetSize(); fSumx. Set(npixels); fSumx2. Set(npixels); fSumAB0.Set(npixels); fSumAB1.Set(npixels); fNumEventsUsed.Set(npixels); if (fUseSpecialPixels) { // Initialize size of MPedestalCam in case of special pixels (not done by MGeomApply) const UShort_t nspecial = fRunHeader->GetNumSpecialPixels(); if (nspecial == 0) { *fLog << warn << "WARNING - Number of special pixels is 0." << endl; return kTRUE; } fPedestalsOut->InitSize((UInt_t)nspecial); } else { // Initialize the averaged areas and sectors (do not exist for special pixels) const Int_t areas = fPedestalsOut->GetNumAverageArea(); const Int_t sectors = fPedestalsOut->GetNumAverageSector(); fAreaSumx. Set(areas); fAreaSumx2. Set(areas); fAreaSumAB0.Set(areas); fAreaSumAB1.Set(areas); fAreaFilled.Set(areas); fAreaValid .Set(areas); fSectorSumx. Set(sectors); fSectorSumx2. Set(sectors); fSectorSumAB0.Set(sectors); fSectorSumAB1.Set(sectors); fSectorFilled.Set(sectors); fSectorValid .Set(sectors); for (Int_t i=0; iClassName() << "... " << flush; if (!fExtractor->ReInit(pList)) return kFALSE; SetRangeFromExtractor(*fExtractor); // fSignal->GetNumSamples() not yet initialized!!! const UInt_t num = fRunHeader->GetNumSamples(); if (fExtractWinLast >= num) { *fLog << err; *fLog << "ERROR - Selected fExtractWinLast " << fExtractWinLast; *fLog << " out of range (>=" << num<< ")." << endl; return kFALSE; } } else if (fRunHeader->GetNumSamplesLoGain()==0 && (fCheckWinFirst!=0 || fCheckWinLast!=0)) { *fLog << inf << "Data has no lo-gains... resetting check window to extraction window." << endl; SetCheckRange(fExtractWinFirst, fExtractWinLast); } //CheckExtractionWindow(); return kTRUE; } // --------------------------------------------------------------------------------- // // PostProcess the extractor if available // Int_t MExtractPedestal::PostProcess() { return fExtractor ? fExtractor->CallPostProcess() : kTRUE; } // --------------------------------------------------------------------------------- // // Check whether the signal variation between fCheckWinFirst and fCheckWinLast // exceeds fMaxSignalVar or the signal is greater than fMaxSignalAbs // Bool_t MExtractPedestal::CheckVariation(UInt_t idx) const { // This is the fast workaround to put hi- and lo-gains together USample_t *slices = fSignal->GetSamplesRaw(idx); // Start 'real' work USample_t max = 0; USample_t min = (USample_t)-1; // Find the maximum and minimum signal per slice in the high gain window for (USample_t *slice=slices+fCheckWinFirst; slice<=slices+fCheckWinLast; slice++) { if (*slice > max) max = *slice; if (*slice < min) min = *slice; } max /= fRunHeader->GetScale(); min /= fRunHeader->GetScale(); // If the maximum in the high gain window is smaller than return max-minpixel.GetNumSamples()-start) // range = pixel.GetNumSamples()-start; const Int_t idx = pixel.GetPixelId(); // Do some handling if maxpos is last slice? const Int_t maxposhi = fRandomCalculation ? 0 : fSignal->GetMaxPos(idx, start, start+range-1); const Float_t *sig = fSignal->GetSamples(idx); // The pedestal is extracted with the hi-gain extractor (eg. digital // filter weights) but from the lo-gains Float_t dummy[3]; Float_t sum = 0; fExtractor->FindTimeAndChargeHiGain2(sig+start, range, sum, dummy[0], dummy[1], dummy[2], 0, maxposhi); return sum; } // --------------------------------------------------------------------------------- // // Sum slices from fExtractWinFirst to fExtractWinLast. The total sum is // returned. ab0 and ab1 will contain the total sum splitted by the // AB-flag. If the AB-flag is invalid ab0=ab1=0 is returned. // UInt_t MExtractPedestal::CalcSums(const MRawEvtPixelIter &pixel, Int_t offset, UInt_t &ab0, UInt_t &ab1) const { const Int_t first = fExtractWinFirst+offset; USample_t *ptr = fSignal->GetSamplesRaw(pixel.GetPixelId())+first; USample_t *end = ptr + fExtractWinSize; Int_t abflag = pixel.HasABFlag() + first; UInt_t ab[2] = { 0, 0 }; while (ptrGetNumHiGainSamples() : fExtractWinSize; var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize; abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize; // The pedestal extracted with the extractor is divided by // the number of hi-gain samples because the calibration // multiplies by this number // scale to 256 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale(); ped /= scale; abOffs /= scale; // 5. Calculate the RMS from the Variance: const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale; // abOffs contains only half of the signal as ped. // Therefor abOffs is not the full, but the half amplitude (*fPedestalsOut)[pixid].Set(ped, rms, abOffs, nevts); } // --------------------------------------------------------------------------------- // // Calculates for area idx "aidx" with "napix" valid pixels: // // Ped per slice = sum / nevts / fExtractWinSize / napix; // RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / napix } // ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / napix; // // Stores the results in MPedestalCam::GetAverageArea(aidx) // void MExtractPedestal::CalcAreaResults(const UInt_t aidx) { const UInt_t nevts = fAreaFilled[aidx]; if (nevts<2) return; const UInt_t napix = fAreaValid[aidx]; if (napix<1) return; const Double_t sum = fAreaSumx[aidx]; const Double_t sum2 = fAreaSumx2[aidx]; // 1. Calculate the mean of the sums: Double_t ped = sum/nevts; // 2. Calculate the Variance of the sums: Double_t var = (sum2/napix-sum*sum/nevts)/(nevts-1.); // 3. Calculate the amplitude of the 150MHz "AB" noise Double_t abOffs = (fAreaSumAB0[aidx] - fAreaSumAB1[aidx]) / nevts; // 4. Scale the mean, variance and AB-noise to the number of slices: ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize; var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize; abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize; // The pedestal extracted with the extractor is divided by // the number of hi-gain samples because the calibration // multiplies by this number // scale to 256 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale(); // 5. Scale the mean, variance and AB-noise to the number of pixels: ped /= napix*scale; abOffs /= napix*scale; // 6. Calculate the RMS from the Variance: const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale; // abOffs contains only half of the signal as ped. // Therefor abOffs is not the full, but the half amplitude fPedestalsOut->GetAverageArea(aidx).Set(ped, rms, abOffs, nevts); } // --------------------------------------------------------------------------------- // // Calculates for sector idx "sector" with "nspix" valid pixels: // // Ped per slice = sum / nevts / fExtractWinSize / nspix; // RMS per slice = sqrt { (sum2 - sum*sum/nevts) / (nevts-1) / fExtractWinSize / nspix } // ABOffset per slice = (fSumAB0[idx] - fSumAB1[idx]) / nevts / fExtractWinSize / nspix; // // Stores the results in MPedestalCam::GetAverageSector(sector) // void MExtractPedestal::CalcSectorResults(const UInt_t sector) { const UInt_t nevts = fSectorFilled[sector]; if (nevts<2) return; const UInt_t nspix = fSectorValid[sector]; if (nspix<1) return; const Double_t sum = fSectorSumx[sector]; const Double_t sum2 = fSectorSumx2[sector]; // 1. Calculate the mean of the sums: Double_t ped = sum/nevts; // 2. Calculate the Variance of the sums: Double_t var = (sum2/nspix-sum*sum/nevts)/(nevts-1.); // 3. Calculate the amplitude of the 150MHz "AB" noise Double_t abOffs = (fSectorSumAB0[sector] - fSectorSumAB1[sector]) / nevts; // 4. Scale the mean, variance and AB-noise to the number of slices: ped /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize; var /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize; abOffs /= fExtractor ? fExtractor->GetNumHiGainSamples() : fExtractWinSize; // The pedestal extracted with the extractor is divided by // the number of hi-gain samples because the calibration // multiplies by this number // scale to 256 const UInt_t scale = fExtractor ? 1 : fRunHeader->GetScale(); // 5. Scale the mean, variance and AB-noise to the number of pixels: ped /= nspix*scale; abOffs /= nspix*scale; // 6. Calculate the RMS from the Variance: const Double_t rms = var<0 ? 0 : TMath::Sqrt(var)/scale; // abOffs contains only half of the signal as ped. // Therefor abOffs is not the full, but the half amplitude fPedestalsOut->GetAverageSector(sector).Set(ped, rms, abOffs, nevts); } // -------------------------------------------------------------------------- // // Loop over the pixels to get the averaged pedestal // void MExtractPedestal::CalcPixResult() { for (UInt_t idx=0; idxGetName():fNamePedestalCamInter.Data()) << " (" << fPedestalsInter << ")" << endl; *fLog << "Name of output MPedestalCam: " << (fPedestalsOut?fPedestalsOut->GetName():fNamePedestalCamOut.Data()) << " (" << fPedestalsOut << ")" << endl; *fLog << "Intermediate Storage is " << (fIntermediateStorage?"on":"off") << endl; *fLog << "Special pixel mode " << (fUseSpecialPixels?"on":"off") << endl; if (fExtractor) { *fLog << "Extractor used: " << fExtractor->ClassName() << " ("; *fLog << (fRandomCalculation?"":"non-") << "random)" << endl; } *fLog << "ExtractWindow from slice " << fExtractWinFirst << " to " << fExtractWinLast << " incl." << endl; *fLog << "CheckWindow from slice " << fCheckWinFirst << " to " << fCheckWinLast << " incl." << endl; *fLog << "Max.allowed signal variation: " << fMaxSignalVar << endl; *fLog << "Max.allowed signal absolute: " << fMaxSignalAbs << endl; } // -------------------------------------------------------------------------- // // The following resources are available: // ExtractWindowFirst: 15 // ExtractWindowSize: 6 // PedestalUpdate: yes // RandomCalculation: yes // Int_t MExtractPedestal::ReadEnv(const TEnv &env, TString prefix, Bool_t print) { Bool_t rc=kFALSE; // find resource for fUseSpecialPixels if (IsEnvDefined(env, prefix, "UseSpecialPixels", print)) { SetUseSpecialPixels(GetEnvValue(env, prefix, "UseSpecialPixels", fUseSpecialPixels)); rc = kTRUE; } if (IsEnvDefined(env, prefix, "IntermediateStorage", print)) { SetIntermediateStorage(GetEnvValue(env, prefix, "IntermediateStorage", fIntermediateStorage)); rc = kTRUE; } // find resource for random calculation if (IsEnvDefined(env, prefix, "RandomCalculation", print)) { SetRandomCalculation(GetEnvValue(env, prefix, "RandomCalculation", fRandomCalculation)); rc = kTRUE; } // Find resources for ExtractWindow Int_t ef = fExtractWinFirst; Int_t es = fExtractWinSize; if (IsEnvDefined(env, prefix, "ExtractWinFirst", print)) { ef = GetEnvValue(env, prefix, "ExtractWinFirst", ef); rc = kTRUE; } if (IsEnvDefined(env, prefix, "ExtractWinSize", print)) { es = GetEnvValue(env, prefix, "ExtractWinSize", es); rc = kTRUE; } SetExtractWindow(ef,es); // Find resources for CheckWindow Int_t cfs = fCheckWinFirst; Int_t cls = fCheckWinLast; if (IsEnvDefined(env, prefix, "CheckWinFirst", print)) { cfs = GetEnvValue(env, prefix, "CheckWinFirst", cfs); rc = kTRUE; } if (IsEnvDefined(env, prefix, "CheckWinLast", print)) { cls = GetEnvValue(env, prefix, "CheckWinLast", cls); rc = kTRUE; } SetCheckRange(cfs,cls); // find resource for maximum signal variation if (IsEnvDefined(env, prefix, "MaxSignalVar", print)) { SetMaxSignalVar(GetEnvValue(env, prefix, "MaxSignalVar", fMaxSignalVar)); rc = kTRUE; } if (IsEnvDefined(env, prefix, "MaxSignalAbs", print)) { SetMaxSignalAbs(GetEnvValue(env, prefix, "MaxSignalAbs", fMaxSignalAbs)); rc = kTRUE; } // find resource for MPedestalCam if (IsEnvDefined(env, prefix, "NamePedestalCamInter", print)) { SetNamePedestalCamInter(GetEnvValue(env, prefix, "NamePedestalCamInter", fNamePedestalCamInter)); rc = kTRUE; } if (IsEnvDefined(env, prefix, "NamePedestalCamOut", print)) { SetNamePedestalCamOut(GetEnvValue(env, prefix, "NamePedestalCamOut", fNamePedestalCamOut)); rc = kTRUE; } return rc; }