/* ======================================================================== *\ ! ! * ! * 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 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // MExtractBlindPixel // // Extracts the signal from a fixed window in a given range. // // Call: SetRange(fHiGainFirst, fHiGainLast, fLoGainFirst, fLoGainLast) // to modify the ranges. The "lo-gain" ranges are used for the NSB rejection // whereas the high-gain ranges for blind pixel signal extraction. "High-gain" // ranges can extend to the slices stored as "low-gain" in MRawEvtPixelIter // Defaults are: // // fHiGainFirst = fgHiGainFirst = 12 // fHiGainLast = fgHiGainLast = 16 // fLoGainFirst = fgLoGainFirst = 0 // fLoGainLast = fgLoGainLast = 10 // ////////////////////////////////////////////////////////////////////////////// #include "MExtractBlindPixel.h" #include "MLog.h" #include "MLogManip.h" #include "MParList.h" #include "MRawEvtData.h" #include "MRawRunHeader.h" #include "MRawEvtPixelIter.h" #include "MExtractedSignalBlindPixel.h" #include "MPedestalCam.h" #include "MPedestalPix.h" ClassImp(MExtractBlindPixel); using namespace std; const Int_t MExtractBlindPixel::fgBlindPixelIdx = 559; const Int_t MExtractBlindPixel::fgNSBFilterLimit = 70; const Byte_t MExtractBlindPixel::fgHiGainFirst = 10; const Byte_t MExtractBlindPixel::fgHiGainLast = 29; const Byte_t MExtractBlindPixel::fgLoGainFirst = 0; const Byte_t MExtractBlindPixel::fgLoGainLast = 6; const Float_t MExtractBlindPixel::fgResolution = 0.003; // -------------------------------------------------------------------------- // // Default constructor. // // Initializes: // - fBlindPixelIdx to fgBlindPixelIdx // - fNSBFilterLimit to fgNSBFilterLimit // - fResolution to fgResolution // // Calls: // - SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast); // MExtractBlindPixel::MExtractBlindPixel(const char *name, const char *title) : fHiGainSignal(NULL), fHiGainFirstDeriv(NULL), fHiGainSecondDeriv(NULL) { fName = name ? name : "MExtractBlindPixel"; fTitle = title ? title : "Task to extract the signal from the FADC slices"; AddToBranchList("MRawEvtData.*"); fBlindPixelIdx.Set(1); SetBlindPixelIdx(); SetResolution(); SetNSBFilterLimit(); SetRange(fgHiGainFirst, fgHiGainLast, fgLoGainFirst, fgLoGainLast); } MExtractBlindPixel::~MExtractBlindPixel() { if (fHiGainSignal) delete fHiGainSignal; if (fHiGainFirstDeriv) delete fHiGainFirstDeriv; if (fHiGainSecondDeriv) delete fHiGainSecondDeriv; } void MExtractBlindPixel::SetRange(Byte_t hifirst, Byte_t hilast, Byte_t lofirst, Byte_t lolast) { MExtractor::SetRange(hifirst,hilast,lofirst,lolast); fNumHiGainSamples = (Float_t)(fHiGainLast-fHiGainFirst+1); fNumLoGainSamples = (Float_t)(fLoGainLast-fLoGainFirst+1); fSqrtHiGainSamples = TMath::Sqrt(fNumHiGainSamples); fSqrtLoGainSamples = TMath::Sqrt(fNumLoGainSamples); fHiLoFirst = 0; fHiLoLast = 0; } // -------------------------------------------------------------------------- // // The PreProcess searches for the following input containers: // - MRawEvtData // // The following output containers are also searched and created if // they were not found: // // - MExtractedBlindPixel // Int_t MExtractBlindPixel::PreProcess(MParList *pList) { if (!MExtractor::PreProcess(pList)) return kFALSE; fBlindPixel = (MExtractedSignalBlindPixel*)pList->FindCreateObj(AddSerialNumber("MExtractedSignalBlindPixel")); if (!fBlindPixel) return kFALSE; fBlindPixel->SetBlindPixelIdx(fBlindPixelIdx.At(0)); fBlindPixel->SetUsedFADCSlices(fHiGainFirst, fHiGainLast); MPedestalPix &pedpix = (*fPedestals)[fBlindPixelIdx.At(0)]; if (&pedpix) { fBlindPixel->SetPed ( pedpix.GetPedestal() * fNumLoGainSamples ); fBlindPixel->SetPedErr ( pedpix.GetPedestalRms()* fNumLoGainSamples / TMath::Sqrt((Float_t)fPedestals->GetTotalEntries()) ); fBlindPixel->SetPedRms ( pedpix.GetPedestalRms()* TMath::Sqrt((Float_t)fNumLoGainSamples) ); fBlindPixel->SetPedRmsErr( fBlindPixel->GetPedErr()/2. ); } return kTRUE; } // -------------------------------------------------------------------------- // // // The ReInit searches for: // - MRawRunHeader::GetNumSamplesHiGain() // - MRawRunHeader::GetNumSamplesLoGain() // // In case that the variables fHiGainLast and fLoGainLast are smaller than // the even part of the number of samples obtained from the run header, a // warning is given an the range is set back accordingly. A call to: // - SetRange(fHiGainFirst, fHiGainLast-diff, fLoGainFirst, fLoGainLast) or // - SetRange(fHiGainFirst, fHiGainLast, fLoGainFirst, fLoGainLast-diff) // is performed in that case. The variable diff means here the difference // between the requested range (fHiGainLast) and the available one. Note that // the functions SetRange() are mostly overloaded and perform more checks, // modifying the ranges again, if necessary. // Bool_t MExtractBlindPixel::ReInit(MParList *pList) { if (fHiGainSignal) delete fHiGainSignal; if (fHiGainFirstDeriv) delete fHiGainFirstDeriv; if (fHiGainSecondDeriv) delete fHiGainSecondDeriv; const Int_t firstdesired = (Int_t)fHiGainFirst; Int_t lastavailable = (Int_t)fRunHeader->GetNumSamplesHiGain()-1; if (firstdesired > lastavailable) { const Int_t diff = firstdesired - lastavailable; *fLog << endl; *fLog << warn << GetDescriptor() << Form("%s%2i%s%2i%s",": Selected First Hi Gain FADC slice ", (int)fHiGainFirst, " ranges out of the available limits: [0,",lastavailable,"].") << endl; *fLog << warn << GetDescriptor() << Form("%s%2i%s",": Will start with slice ",diff," of the Low-Gain for the High-Gain extraction") << endl; fHiLoFirst = diff; } Int_t lastdesired = (Int_t)fHiGainLast; lastavailable = (Int_t)fRunHeader->GetNumSamplesHiGain()-1; if (lastdesired > lastavailable) { Int_t diff = lastdesired - lastavailable; lastavailable += (Int_t)fRunHeader->GetNumSamplesLoGain()-1; if (lastdesired > lastavailable) { *fLog << endl; *fLog << warn << GetDescriptor() << Form("%s%2i%s%2i%s",": Selected Last Hi Gain FADC slice ", (int)fHiGainLast, " ranges out of the available limits: [0,",lastavailable,"].") << endl; *fLog << warn << GetDescriptor() << Form("%s%2i",": Will reduce upper limit by ",diff) << endl; fHiGainLast = (Int_t)fRunHeader->GetNumSamplesLoGain() - 1; diff = (Int_t)fRunHeader->GetNumSamplesLoGain() - 1; } fHiLoLast = diff; } const Int_t range = fHiLoFirst ? fHiLoLast - fHiLoFirst + 1 : fHiGainLast - fHiGainFirst + fHiLoLast + 1; fHiGainSignal = new Float_t[range]; memset(fHiGainSignal,0,range*sizeof(Float_t)); fHiGainFirstDeriv = new Float_t[range]; memset(fHiGainFirstDeriv,0,range*sizeof(Float_t)); fHiGainSecondDeriv = new Float_t[range]; memset(fHiGainSecondDeriv,0,range*sizeof(Float_t)); *fLog << endl; *fLog << inf << GetDescriptor() << ": Taking " << range << " FADC samples from " << Form("%s%2i",fHiLoFirst ? "Low Gain slice " : " High Gain slice ", fHiLoFirst ? (Int_t)fHiLoFirst : (Int_t)fHiGainFirst) << " to (including) " << Form("%s%2i",fHiLoLast ? "Low Gain slice " : " High Gain slice ", fHiLoLast ? (Int_t)fHiLoLast : (Int_t)fHiGainLast ) << endl; return kTRUE; } // -------------------------------------------------------------------------- // // FindSignalHiGain: // // - Loop from ptr to (ptr+fHiGainLast-fHiGainFirst) // - Sum up contents of *ptr // - If *ptr is greater than fSaturationLimit, raise sat by 1 // - If fHiLoLast is set, loop from logain to (logain+fHiLoLast) // - Add contents of *logain to sum // void MExtractBlindPixel::FindSignalHiGain(Byte_t *ptr, Byte_t *logain, Float_t &sum, Byte_t &sat) const { Int_t summ = 0; Byte_t *p = ptr; Byte_t *end = ptr + fHiGainLast - fHiGainFirst + 1; if (fHiLoFirst == 0) { while (p= fSaturationLimit) sat++; } } p = logain + fHiLoFirst; end = logain + fHiLoLast; while (p= fSaturationLimit) sat++; } sum = (Float_t)summ; } // -------------------------------------------------------------------------- // // FindSignalPhe: // // - Loop from ptr to (ptr+fHiGainLast-fHiGainFirst) // - Sum up contents of *ptr // - If *ptr is greater than fSaturationLimit, raise sat by 1 // - If fHiLoLast is set, loop from logain to (logain+fHiLoLast) // - Add contents of *logain to sum // void MExtractBlindPixel::FindAmplitude(Byte_t *ptr, Byte_t *logain, Float_t &sum, Byte_t &sat) const { Int_t range = 0; Int_t count = 0; Float_t abmaxpos = 0.; Byte_t *p = ptr; Byte_t *end; Byte_t max = 0; Byte_t maxpos = 0; Int_t summ = 0; if (fHiLoFirst == 0) { range = fHiGainLast - fHiGainFirst + 1; end = ptr + range; // // Check for saturation in all other slices // while (++p max) { max = *p; maxpos = count; } range++; count++; if (*p >= fSaturationLimit) { sat++; break; } } } if (fHiLoLast != 0) { p = logain + fHiLoFirst; end = logain + fHiLoLast + 1; while (p max) { max = *p; maxpos = count; } range++; count++; if (*p++ >= fSaturationLimit) { sat++; break; } } } // sum = (Float_t)summ; // return; // // allow one saturated slice // if (sat > 1) return; // // Don't start if the maxpos is too close to the left limit. // if (maxpos < 2) return; Float_t pp; fHiGainSecondDeriv[0] = 0.; fHiGainFirstDeriv[0] = 0.; for (Int_t i=1;i=0;k--) fHiGainSecondDeriv[k] = (fHiGainSecondDeriv[k]*fHiGainSecondDeriv[k+1] + fHiGainFirstDeriv[k])/6.; // // Now find the maximum // Float_t step = 0.2; // start with step size of 1ns and loop again with the smaller one Float_t lower = (Float_t)maxpos-1.; Float_t upper = (Float_t)maxpos; Float_t x = lower; Float_t y = 0.; Float_t a = 1.; Float_t b = 0.; Int_t klo = maxpos-1; Int_t khi = maxpos; Float_t klocont = fHiGainSignal[klo]; Float_t khicont = fHiGainSignal[khi]; sum = (Float_t)khicont; abmaxpos = lower; // // Search for the maximum, starting in interval maxpos-1. If no maximum is found, go to // interval maxpos+1. // while (x sum) { sum = y; abmaxpos = x; } } if (abmaxpos > upper-0.1) { upper = (Float_t)maxpos+1; lower = (Float_t)maxpos; x = lower; a = 1.; b = 0.; khi = maxpos+1; klo = maxpos; klocont = fHiGainSignal[klo]; khicont = fHiGainSignal[khi]; while (x sum) { sum = y; abmaxpos = x; } } } const Float_t up = abmaxpos+step-0.055; const Float_t lo = abmaxpos-step+0.055; const Float_t maxpossave = abmaxpos; x = abmaxpos; a = upper - x; b = x - lower; step = 0.04; // step size of 83 ps while (x sum) { sum = y; abmaxpos = x; } } if (abmaxpos < klo + 0.02) { klo--; khi--; klocont = fHiGainSignal[klo]; khicont = fHiGainSignal[khi]; upper--; lower--; } x = maxpossave; a = upper - x; b = x - lower; while (x>lo) { x -= step; a += step; b -= step; y = a* klocont + b* khicont + (a*a*a-a)*fHiGainSecondDeriv[klo] + (b*b*b-b)*fHiGainSecondDeriv[khi]; if (y > sum) { sum = y; abmaxpos = x; } } } // -------------------------------------------------------------------------- // // FindSignalFilter: // // - Loop from ptr to (ptr+fLoGainLast-fLoGainFirst) // - Sum up contents of *ptr // - If *ptr is greater than fSaturationLimit, raise sat by 1 // void MExtractBlindPixel::FindSignalFilter(Byte_t *ptr, Int_t &sum, Byte_t &sat) const { Byte_t *end = ptr + fLoGainLast - fLoGainFirst + 1; while (ptr= fSaturationLimit) sat++; } } // -------------------------------------------------------------------------- // // Calculate the integral of the FADC time slices and store them as a new // pixel in the MExtractedBlindPixel container. // Int_t MExtractBlindPixel::Process() { MRawEvtPixelIter pixel(fRawEvt); fBlindPixel->Clear(); for (Int_t id=0;id fNSBFilterLimit) { fBlindPixel->SetExtractedSignal(-1.); fBlindPixel->SetNumSaturated(sat); fBlindPixel->SetReadyToSave(); continue; } Float_t newsum = 0.; sat = 0; FindSignalHiGain(pixel.GetHiGainSamples()+fHiGainFirst, pixel.GetLoGainSamples(), newsum, sat); fBlindPixel->SetExtractedSignal(newsum,id); fBlindPixel->SetNumSaturated(sat,id); } fBlindPixel->SetReadyToSave(); return kTRUE; }