/* ======================================================================== *\ ! ! * ! * 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 ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MCalibrationChargePix // // Storage container of the calibrated Charge of one pixel. // // The following values are initialized to meaningful values: // // - The Electronic Rms to 1.5 per FADC slice // - The uncertainty about the Electronic RMS to 0.3 per slice // - The F-Factor is assumed to have been measured in Munich to 1.13 - 1.17. // with the Munich definition of the F-Factor, thus: // F = Sigma(Out)/Mean(Out) * Mean(In)/Sigma(In) // Mean F-Factor (gkFFactor) = 1.15 // Error F-Factor (gkFFactorErr) = 0.02 // // The following variables are calculated inside this class: // - fLoGainPedRmsSquare and fLoGainPedRmsSquareVar (see CalcLoGainPedestal()) // - fRSigmaSquare and fRSigmaSquareVar (see CalcReducedSigma() ) // - fPheFFactorMethod and fPheFFactorMethodVar (see CalcFFactor() ) // - fMeanConvFADC2Phe and fMeanConvFADC2PheVar (see CalcConvFFactor() ) // // The following variables are set by MHCalibrationChargeCam: // - fAbsTimeMean and fAbsTimeRms // - all variables in MCalibrationPix // // The following variables are set by MCalibrationChargeCalc: // - fPed, fPedVar and fPedRms // - fMeanConvFADC2Phe // - fConvFADC2PheVar // - fSigmaConvFADC2Phe // - fTotalFFactorFFactorMethod // - fTotalFFactorFFactorMethodVar // // The following variables are not yet implemented: // - fConversionHiLo and fConversionHiLoVar (now set fixed to 10. +- 2.5) // // Error of all variables are calculated by error-propagation. Note that internally, // all error variables contain Variances in order to save the CPU-intensive square rooting // // Low-Gain variables are stored internally unconverted, i.e. directly from the summed // FADC slices extraction results, but can be retrieved converted to High-Gain amplifications // by calls to: GetConvertedMean() or GetConvertedSigma() // // See also: MCalibrationChargeCam, MCalibrationChargeCalc, // MHCalibrationChargeCam, MHCalibrationChargePix // // // ClassVersion 3: // + fNumSaturated // // Class Version 4: // + Float_t fConversionHiLoSigma; // Sigma of conversion factor betw. Hi and Lo Gain // - Float_t fMeanConvFADC2PheVar; // Variance conversion factor (F-factor method) // + Float_t fMeanConvFADC2PheStatVar; // Variance conversion factor, only stat. error // + Float_t fMeanConvFADC2PheSystVar; // Variance conversion factor, only syst. error // - Float_t fMeanFFactorFADC2PhotVar; // Variance mean F-Factor photons (F-factor method) // + Float_t fMeanFFactorFADC2PhotVar; // Variance mean F-Factor photons, only stat. error // - Float_t fPheFFactorMethod; // Number Phe's calculated (F-factor method) // - Float_t fPheFFactorMethodVar; // Variance number of Phe's (F-factor method) // + Float_t fPheFFactorMethod; // Number Phe's calculated with F-factor method) // + Float_t fPheFFactorMethodStatVar; // Variance number of Phe's, only stat. error // + Float_t fPheFFactorMethodSystVar; // Variance number of Phe's, only syst. error // ///////////////////////////////////////////////////////////////////////////// #include "MCalibrationChargePix.h" #include "MLog.h" #include "MLogManip.h" #include "MBadPixelsPix.h" ClassImp(MCalibrationChargePix); using namespace std; const Float_t MCalibrationChargePix::gkElectronicPedRms = 1.0; const Float_t MCalibrationChargePix::gkElectronicPedRmsErr = 0.35; const Float_t MCalibrationChargePix::gkFFactor = 1.15; const Float_t MCalibrationChargePix::gkFFactorErr = 0.02; const Float_t MCalibrationChargePix::fgConversionHiLo = 10.; const Float_t MCalibrationChargePix::fgConversionHiLoErr = 0.05; const Float_t MCalibrationChargePix::fgConversionHiLoSigma = 2.5; const Float_t MCalibrationChargePix::fgPheFFactorMethodLimit = 1.; const Float_t MCalibrationChargePix::fgConvFFactorRelErrLimit = 0.85; // -------------------------------------------------------------------------- // // Default Constructor: // // Sets: // - fCalibFlags to 0 // - fConversionHiLo to fgConversionHiLo // - fConversionHiLoVar to square of fgConversionHiLoErr // - fConvFFactorelErrLimit to fgConvFFactorRelErrLimit*fgConvFFactorelErrLimit // - fPheFFactorLimit to fgPheFFactorLimit // // Calls: // - Clear() // MCalibrationChargePix::MCalibrationChargePix(const char *name, const char *title) : fCalibFlags(0), fNumSaturated(0) { fName = name ? name : "MCalibrationChargePix"; fTitle = title ? title : "Container of the fit results of MHCalibrationChargePixs "; // // At the moment, we don't have a database, yet, // so we get it from the configuration file // SetConversionHiLo(); SetConversionHiLoErr(); SetPheFFactorMethodLimit(); SetConvFFactorRelErrLimit(); Clear(); } // ------------------------------------------------------------------------ // // Sets: // - all flags to kFALSE // - all variables to -1. // // Calls: // - MCalibrationPix::Clear() // void MCalibrationChargePix::Clear(Option_t *o) { SetFFactorMethodValid ( kFALSE ); fRSigmaSquare = -1.; fRSigmaSquareVar = -1.; fPed = -1.; fPedRms = -1.; fPedVar = -1.; fLoGainPedRmsSquare = -1.; fLoGainPedRmsSquareVar = -1.; fAbsTimeMean = -1.; fAbsTimeRms = -1.; fPheFFactorMethod = -1.; fPheFFactorMethodStatVar = -1.; fPheFFactorMethodSystVar = -1.; fMeanConvFADC2Phe = -1.; fMeanConvFADC2PheStatVar = -1.; fMeanConvFADC2PheSystVar = -1.; fMeanFFactorFADC2Phot = -1.; fMeanFFactorFADC2PhotVar = -1.; fNumSaturated = 0; MCalibrationPix::Clear(); } // ----------------------------------------------------- // void MCalibrationChargePix::Copy(TObject& object) const { MCalibrationChargePix &pix = (MCalibrationChargePix&)object; MCalibrationPix::Copy(pix); // // Copy the data members // pix.fAbsTimeMean = fAbsTimeMean ; pix.fAbsTimeRms = fAbsTimeRms ; pix.fCalibFlags = fCalibFlags ; pix.fConversionHiLo = fConversionHiLo ; pix.fConversionHiLoVar = fConversionHiLoVar ; pix.fConversionHiLoSigma = fConversionHiLoSigma ; pix.fConvFFactorRelVarLimit = fConvFFactorRelVarLimit ; pix.fLoGainPedRmsSquare = fLoGainPedRmsSquare ; pix.fLoGainPedRmsSquareVar = fLoGainPedRmsSquareVar ; pix.fMeanConvFADC2Phe = fMeanConvFADC2Phe ; pix.fMeanConvFADC2PheStatVar = fMeanConvFADC2PheStatVar ; pix.fMeanConvFADC2PheSystVar = fMeanConvFADC2PheSystVar ; pix.fMeanFFactorFADC2Phot = fMeanFFactorFADC2Phot ; pix.fMeanFFactorFADC2PhotVar = fMeanFFactorFADC2PhotVar ; pix.fPed = fPed ; pix.fPedVar = fPedVar ; pix.fPedRms = fPedRms ; pix.fPedRmsVar = fPedRmsVar ; pix.fPheFFactorMethod = fPheFFactorMethod ; pix.fPheFFactorMethodStatVar = fPheFFactorMethodStatVar ; pix.fPheFFactorMethodSystVar = fPheFFactorMethodSystVar ; pix.fPheFFactorMethodLimit = fPheFFactorMethodLimit ; pix.fRSigmaSquare = fRSigmaSquare ; pix.fRSigmaSquareVar = fRSigmaSquareVar ; pix.fNumSaturated = fNumSaturated ; } // -------------------------------------------------------------------------- // // Set F-Factor Method Validity Bit from outside // void MCalibrationChargePix::SetFFactorMethodValid(const Bool_t b ) { b ? SETBIT(fCalibFlags, kFFactorMethodValid) : CLRBIT(fCalibFlags, kFFactorMethodValid); } // -------------------------------------------------------------------------- // // Set pedestals from outside (done by MCalibrationChargeCalc) // void MCalibrationChargePix::SetPedestal(const Float_t ped, const Float_t pedrms, const Float_t pederr) { fPed = ped; fPedRms = pedrms; fPedVar = pederr*pederr; } // -------------------------------------------------------------------------- // // Set pedestals from outside (done by MCalibrationChargeCalc) // void MCalibrationChargePix::SetPed(const Float_t ped, const Float_t pederr) { fPed = ped; fPedVar = pederr*pederr; } // -------------------------------------------------------------------------- // // Set pedestals RMS from outside (done by MHCalibrationChargeCam) // void MCalibrationChargePix::SetPedRMS( const Float_t pedrms, const Float_t pedrmserr) { fPedRms = pedrms; fPedRmsVar = pedrmserr*pedrmserr; } // Inline Functions: // ----------------- // // GetConversionHiLoErr: // Get the conversion Error Hi-Gain to Low-Gain: // If fConversionHiLoVar is smaller than 0 (i.e. has not yet // been set), return -1. // // GetPedRms(): Get the pedestals RMS: Test bit kHiGainSaturation: // If yes, return square root of fLoGainPedRmsSquare (if greater than 0, // otherwise -1.), If no, return fPedRms // // GetConvertedMean(): Get the Low Gain Mean Charge converted to High Gain // amplification: Returns fLoGainMean multiplied with fConversionHiLo if // IsHiGainSaturation(), else return fHiGainMean // // GetConvertedMeanErr(): Get the Error of the converted Low Gain Mean: // Returns -1 if the variable fLoGainMean or fLoGainMeanVar are smaller than 0. // Returns the square root of the quadratic sum of the relative variances of // the fLoGainMean and fConversionHiLo, mulitplied with GetConvertedMean() // in case of HiGain Saturation, // else return GetMeanErr() // // GetConvertedSigma(): Get the Low Gain Sigma converted to High Gain // amplification: Returns fLoGainSigma multiplied with fConversionHiLo // if IsHiGainSaturation() else return fHiGainSigma // // GetConvertedSigmaErr(): Get the Error of the converted Sigma: // Returns -1 if the variable fLoGainSigma or fLoGainSigmaVar are smaller than 0. // if IsHiGainSaturatio() // returns the square root of the quadratic sum of the relative variances of // the fLoGainSigma and fConversionHiLo, mulitplied with GetConvertedSigma() // else returns GetSigmaErr() // // GetConvertedRSigma(): Get the converted reduced Sigma: // If fRSigmaSquare is smaller than 0 (i.e. has not yet been set), return -1. // Test bit kHiGainSaturation: // If yes, return square root of fRSigmaSquare, multiplied with fConversionHiLo, // If no , return square root of fRSigmaSquare // // GetRSigma(): Get the reduced Sigma: // If fRSigmaSquare is smaller than 0 (i.e. has not yet been set), return -1. // // GetConvertedRSigmaSquare(): Get the reduced Sigma Square: // If fRSigmaSquare is smaller than 0 (i.e. has not yet been set), return -1. // Test bit kHiGainSaturation: // If yes, return fRSigmaSquare, multiplied with fConversionHiLo^2, // If no , return fRSigmaSquare // // GetPheFFactorMethodErr(): Get the error on the number of photo-electrons // (F-Factor Method): If fPheFFactorMethodVar is smaller than 0 (i.e. has // not yet been set), return -1. Else returns the square root of // fPheFFactorMethodVar // // GetMeanFFactorFADC2PhotErr(): Get the error on the mean total F-Factor // of the signal readout (F-Factor Method): If fMeanFFactorFADC2PhotVar // is smaller than 0 (i.e. has not yet been set), return -1. Else returns // the square root of fMeanFFactorFADC2PhotVar // // GetPheFFactorMethodRelVar(): Get the relative variance on the number of // photo-electrons (F-Factor Method): If fPheFFactorMethodVar is smaller // than 0 (i.e. has not yet been set), return -1. If fPheFFactorMethod // is 0, return -1. Else returns fPheFFactorMethodVar / fPheFFactorMethod^2 // // GetMeanConvFADC2PheErr(): Get the error on the mean conversion factor // (FFactor  Method): If fMeanConvFADC2PheVar is smaller than 0 (i.e. has // not yet been set), return -1. Else returns the square root of // fMeanConvFADC2PheVar // -------------------------------------------------------------------------- // // Get the relative variance of the conversion factor between higain and logain: // - If fConversionHiLo is 0, return -1. // - If fConversionHiLoVar is smaller than 0, return -1. // - Else returns: fConversionHiLoVar / fConversionHiLo^2 // const Float_t MCalibrationChargePix::GetConversionHiLoRelVar() const { if (fConversionHiLoVar < 0.) return -1.; if (fConversionHiLo == 0.) return -1.; return fConversionHiLoVar / (fConversionHiLo * fConversionHiLo); } // -------------------------------------------------------------------------- // // Get the relative variance of the electronics pedestal RMS // - returns rel. variance of gkElectronicPedRms // const Float_t MCalibrationChargePix::GetElectronicPedRmsRelVar() const { return gkElectronicPedRmsErr * gkElectronicPedRmsErr / gkElectronicPedRms / gkElectronicPedRms; } // -------------------------------------------------------------------------- // // Get the relative variance of the conversion factor between higain and logain: // - If gkFFactor is 0, return -1. // - If gkFFactorErr is smaller than 0, return -1. // - Else returns: gkFFactorErr^2 / gkFFactor*^2 // const Float_t MCalibrationChargePix::GetFFactorRelVar() const { if (gkFFactorErr < 0.) return -1.; if (gkFFactor == 0.) return -1.; return gkFFactorErr * gkFFactorErr / (gkFFactor * gkFFactor); } // -------------------------------------------------------------------------- // // Get the Error of the pedestals RMS: // - Test bit kHiGainSaturation: // If yes, return square root of (0.25*fLoGainPedRmsSquareVar/ fLoGainPedRmsSquare) (if greater than 0, otherwise -1.) // If no , return square root of (fPedVar) (if greater than 0, otherwise -1.), divided by 2. // Float_t MCalibrationChargePix::GetPedRmsErr() const { if (IsHiGainSaturation()) if (fLoGainPedRmsSquareVar < 0.) return -1.; else return TMath::Sqrt(0.25*fLoGainPedRmsSquareVar/fLoGainPedRmsSquare); else if (fPedVar < 0.) return -1.; else return TMath::Sqrt(fPedVar)/2.; } // -------------------------------------------------------------------------- // // Get the error of the converted reduced Sigma: // - If fRSigmaSquareVar is smaller than 0 (i.e. has not yet been set), return -1. // - Calculate the absolute variance of the reduced sigma with the formula: // reduced sigma variance = 0.25 * fRSigmaSquareVar / fRSigmaSquare // - Test bit kHiGainSaturation: // If yes, returns the square root of the quadratic sum of the relative variances of the // reduced sigma and fConversionHiLo, mulitplied with GetRSigma() // Else returns the square root of rel. (0.25*fRSigmaSquareVar / fRSigmaSquare) // Float_t MCalibrationChargePix::GetConvertedRSigmaErr() const { if (fRSigmaSquareVar < 0) return -1; // // SigmaSquareVar = 4. * Sigma * Sigma * Var(sigma) // ==> Var(sigma) = 0.25 * SigmaSquareVar / (Sigma * Sigma) // const Float_t rsigmaVar = 0.25 * fRSigmaSquareVar / fRSigmaSquare; if (IsHiGainSaturation()) return TMath::Sqrt(rsigmaVar/fRSigmaSquare + GetConversionHiLoRelVar()) * GetRSigma(); else return TMath::Sqrt(rsigmaVar); } // -------------------------------------------------------------------------- // // Get the error of the reduced Sigma: // - If fRSigmaSquareVar is smaller than 0 (i.e. has not yet been set), return -1. // - Calculate the absolute variance of the reduced sigma with the formula: // reduced sigma variance = 0.25 * fRSigmaSquareVar / fRSigmaSquare // Float_t MCalibrationChargePix::GetRSigmaErr() const { if (fRSigmaSquareVar < 0) return -1; // // SigmaSquareVar = 4. * Sigma * Sigma * Var(sigma) // ==> Var(sigma) = 0.25 * SigmaSquareVar / (Sigma * Sigma) // return TMath::Sqrt(0.25 * fRSigmaSquareVar / fRSigmaSquare); } // -------------------------------------------------------------------------- // // Get the reduced Sigma per Charge: // - If GetRSigma() is smaller or equal 0. (i.e. has not yet been set), return -1. // - If GetMean() is 0. or -1. (i.e. has not yet been set), return -1. // - Return GetRSigma() / GetMean() // Float_t MCalibrationChargePix::GetRSigmaPerCharge() const { const Float_t rsigma = GetRSigma(); if (rsigma <= 0) return -1.; const Float_t mean = GetMean(); if (mean == 0. || mean == -1.) return -1.; return rsigma / mean; } // -------------------------------------------------------------------------- // // Get the error of the reduced Sigma per Charge: // - If GetRSigmaRelVar() is smaller or equal 0. (i.e. has not yet been set), return -1. // - If GetMeanRelVar() is smaller or equal 0. (i.e. has not yet been set), return -1. // - Return the propagated error of GetRSigmaPerCharge() // Float_t MCalibrationChargePix::GetRSigmaPerChargeErr() const { const Float_t rsigmarelvar = GetRSigmaRelVar(); if (rsigmarelvar <= 0) return -1.; const Float_t meanrelvar = GetMeanRelVar(); if (meanrelvar <= 0.) return -1.; return TMath::Sqrt(rsigmarelvar + meanrelvar) * GetRSigmaPerCharge(); } // -------------------------------------------------------------------------- // // Get the relative variance of the reduced Sigma: // - If fRSigmaSquareVar is smaller than 0 (i.e. has not yet been set), return -1. // - Calculate the relative variance of the reduced sigma squares with the formula: // reduced sigma rel. variance = 0.25 * fRSigmaSquareVar / fRSigmaSquare / fRSigmaSquare // - Test bit kHiGainSaturation: // If yes, returns the sum of the relative variances of the reduced sigma and fConversionHiLo // Else returns the relative variance of the reduced sigma // Float_t MCalibrationChargePix::GetRSigmaRelVar() const { if (fRSigmaSquareVar < 0) return -1; // // SigmaSquareVar = 4. * Sigma * Sigma * Var(sigma) // ==> Var(sigma) = 0.25 * SigmaSquareVar / (Sigma * Sigma) // return 0.25 * fRSigmaSquareVar / ( fRSigmaSquare * fRSigmaSquare ); } // -------------------------------------------------------------------------- // // Test bit kFFactorMethodValid // Bool_t MCalibrationChargePix::IsFFactorMethodValid() const { return TESTBIT(fCalibFlags, kFFactorMethodValid); } // ---------------------------------------------------------------------------- // // - If fSigma is smaller than 0 (i.e. has not yet been set), return kFALSE // - If fPedRms is smaller than 0 (i.e. has not yet been set), return kFALSE // // Calculate the reduced sigma of the low-Gain FADC slices: // - Test bit IsHiGainSaturation() for the Sigma: // If yes, take fLoGainSigma and fLoGainSigmaVar // If no , take fHiGainSigma and fHiGainSigmaVar // // - Test bit IsHiGainSaturation() for the pedRMS: // If yes, take fLoGainPedRmsSquare and fLoGainPedRmsSquareVar // If no , take fPedRms and fPedVar // // - Calculate the reduced sigma with the formula: // fRSigmaSquare = Sigma*Sigma - pedRMS*pedRMS // // - If fRSigmaSquare is smaller than 0, give a warning and return kFALSE // // - Calculate the variance of the reduced sigma with the formula: // fRSigmaSquareVar = 4.* (sigmaVar*Sigma*Sigma + pedRmsVar*pedRMS*pedRMS) // // A back-transformation to the corr. amplification factor of the High-Gain is done // in GetRSigma() and GetRSigmaErr() // Bool_t MCalibrationChargePix::CalcReducedSigma(const Float_t extractorres) { if (GetSigma() < 0.) return kFALSE; if (GetPedRms() < 0.) return kFALSE; const Float_t sigma = IsHiGainSaturation() ? fLoGainSigma : fHiGainSigma ; const Float_t sigmavar = IsHiGainSaturation() ? fLoGainSigmaVar : fHiGainSigmaVar; const Float_t pedRmsSquare = IsHiGainSaturation() ? fLoGainPedRmsSquare : fPedRms*fPedRms; const Float_t pedRmsSquareVar = IsHiGainSaturation() ? fLoGainPedRmsSquareVar : 0.25*fPedVar*pedRmsSquare; const Float_t extractorresVar = extractorres * extractorres; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " HiGainSaturation: " << IsHiGainSaturation() << " Sigma: " << sigma << " Var.Sigma: " << sigmavar << " PedRmsSquare: " << pedRmsSquare << " pedRmsSquareVar: " << pedRmsSquareVar << " extractorresVar: " << extractorresVar << endl; } const Float_t sigmaSquare = sigma * sigma; const Float_t sigmaSquareVar = 4. * sigmavar * sigmaSquare; // // Calculate the reduced sigmas // fRSigmaSquare = sigmaSquare - pedRmsSquare - extractorresVar; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " Red.Sigma Square: " << fRSigmaSquare << endl; } if (fRSigmaSquare <= 0.) { if (IsDebug()) *fLog << warn << "WARNING: Cannot calculate the reduced sigma: smaller than 0 in pixel " << fPixId << endl; return kFALSE; } fRSigmaSquareVar = 4. * (sigmaSquareVar + pedRmsSquareVar); if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " Var.Red.Sigma Square: " << fRSigmaSquareVar << endl; } return kTRUE; } // ------------------------------------------------------------------ // // If fRSigmaSquare is smaller than 0 (i.e. has not yet been set), // return kFALSE // // Calculate the number of photo-electrons with the F-Factor method: // - Test bit IsHiGainSaturation() for the Mean Sum of FADC slices: // If yes, take fLoGainMean and fLoGainMeanVar // If no , take fHiGainMean and fHiGainMeanVar // // - Test bit IsHiGainSaturation() for the pedRMS: // If yes, take fLoGainPedRmsSquare and fLoGainPedRmsSquareVar // If no , take fPedRms and fPedVar // // - Calculate the number of photo-electrons with the formula: // fPheFFactorMethod = gkFFactor*gkFFactor * Mean * Mean / fRSigmaSquare // // - Calculate the Variance on the photo-electrons with the formula: // fPheFFactorMethodVar = ( 4. * gkFFactorErr * gkFFactorErr / ( gkFFactor * gkFFactor ) // + 4. * Mean Var. / ( Mean * Mean ) // + fRSigmaSquareVar / fRSigmaSquare // ) * fPheFFactorMethod * fPheFFactorMethod // // - If fPheFFactorMethod is less than fPheFFactorMethodLimit, // set kFFactorMethodValid to kFALSE and return kFALSE // Bool_t MCalibrationChargePix::CalcFFactor() { SetFFactorMethodValid(kFALSE); if (fRSigmaSquare < 0.) return kFALSE; // // Square all variables in order to avoid applications of square root // const Float_t meanSquare = GetMean() * GetMean(); const Float_t meanSquareRelVar = 4.* GetMeanRelVar(); const Float_t ffactorsquare = gkFFactor * gkFFactor; const Float_t ffactorsquareRelVar = 4.* GetFFactorRelVar(); const Float_t rsigmaSquareRelVar = fRSigmaSquareVar / fRSigmaSquare / fRSigmaSquare; // // Calculate the number of phe's from the F-Factor method // (independent on Hi Gain or Lo Gain) // fPheFFactorMethod = ffactorsquare * meanSquare / fRSigmaSquare; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " F-Factor Square: " << ffactorsquare << " Mean Square: " << meanSquare << " Red.Sigma Square: " << fRSigmaSquare << " Photo-electrons: " << fPheFFactorMethod << endl; } if (fPheFFactorMethod < fPheFFactorMethodLimit) return kFALSE; // // Calculate the Error of Nphe // const Float_t pheRelVar = meanSquareRelVar + rsigmaSquareRelVar; fPheFFactorMethodStatVar = pheRelVar * fPheFFactorMethod * fPheFFactorMethod; fPheFFactorMethodSystVar = ffactorsquareRelVar * fPheFFactorMethod * fPheFFactorMethod; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " Rel.Var.F-Factor Square: " << ffactorsquareRelVar << " Rel.Var. Mean Square: " << meanSquareRelVar << " Rel.Var. Red.Sigma Square: " << rsigmaSquareRelVar << " Rel.Var. Photo-electrons: " << pheRelVar << endl; } if (fPheFFactorMethodStatVar < 0. ) return kFALSE; return kTRUE; } // ------------------------------------------------------------------ // // If fPheFFactorMethod is smaller than 0 (i.e. has not yet been set), // return kFALSE // // If GetCovertedMean() is smaller than 0 (i.e. has not yet been set), // return kFALSE // // Calculate fMeanConvFADC2Phe with the following formula: // // fMeanConvFADC2Phe = fPheFFactorMethod / GetConvMean(); // // Calculate the rel. variance of fMeanConvFADC2Phe, taking into account that // in the calculation of the number of phe's one mean square has already been used. // Now, dividing by another mean, one mean calcels out, one cannot directly propagate // the errors, but instead havs to take into account this cancellation: // // convrelvar = ffactorsquareRelVar + GetMeanRelVar() + rsigmaSquareRelVar; // // If confrelvar is smaller than 0. or greater than fConvFFactorRelVarLimit, // return kFALSE // // Calculate the variance of fMeanConvFADC2Phe with the formula: // // fMeanConvFADC2PheVar = convrelvar * fMeanConvFADC2Phe * fMeanConvFADC2Phe; // // Set kFFactorMethodValid to kTRUE and // return kTRUE // Bool_t MCalibrationChargePix::CalcConvFFactor() { if (fPheFFactorMethod <= 0.) return kFALSE; const Float_t convmean = GetConvertedMean(); if (convmean <= 0.) return kFALSE; fMeanConvFADC2Phe = fPheFFactorMethod / convmean; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " Converted Mean: " << convmean << " Conversion FADC2Phe: " << fMeanConvFADC2Phe << endl; } const Float_t ffactorsquareRelVar = 4.* GetFFactorRelVar(); const Float_t rsigmaSquareRelVar = fRSigmaSquareVar / fRSigmaSquare / fRSigmaSquare; // // In the calculation of the number of phe's one mean square has already been used. // Now, we divide by another mean, so one mean calcels out, we cannot directly propagate // the errors, but have to take account of this cancellation: // Float_t convrelvar = GetMeanRelVar() + rsigmaSquareRelVar; if (IsHiGainSaturation()) convrelvar += GetConversionHiLoRelVar(); const Float_t limit = IsHiGainSaturation() ? fConvFFactorRelVarLimit * 4. : fConvFFactorRelVarLimit; // // Also have to take into account the pixels labelled MBadPixelsPix::kChargeSigmaNotValid which do not // have a fRSigmaSquareVar, calculate their error directly! // if (fRSigmaSquareVar < 0.) convrelvar = GetMeanRelVar() + GetPheFFactorMethodRelVar(); if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " Rel.Var.Red.Sigma: " << rsigmaSquareRelVar << " Rel.Var.Mean: " << GetMeanRelVar() << " Rel.Var.F-Factor: " << ffactorsquareRelVar << " Rel.Var.Conversion FADC2Phe: " << convrelvar << endl; } if (convrelvar > limit || convrelvar < 0.) { *fLog << warn << GetDescriptor() << ": Conv. F-Factor Method Rel. Var.: " << Form("%4.3f out of limits: [0,%3.2f] in pixel:%4i",convrelvar,limit,fPixId) << endl; return kFALSE; } fMeanConvFADC2PheStatVar = convrelvar * fMeanConvFADC2Phe * fMeanConvFADC2Phe; fMeanConvFADC2PheSystVar = ffactorsquareRelVar * fMeanConvFADC2Phe * fMeanConvFADC2Phe; SetFFactorMethodValid(kTRUE); return kTRUE; } // ---------------------------------------------------------------------------------- // // If photflux is smaller or equal 0, return kFALSE // // Calculate the total F-Factor with the formula: // fMeanFFactorFADC2Phot = Sqrt ( fRSigmaSquare ) / GetMean() * sqrt(nphotons) // // Calculate the error of the total F-Factor // Bool_t MCalibrationChargePix::CalcMeanFFactor( const Float_t nphotons, const Float_t nphotonsrelvar ) { if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " Number photons: " << nphotons << " Rel.Var.Number photons: " << nphotonsrelvar << " Red.Sigma Square: " << fRSigmaSquare << " Mean: " << GetMean() << endl; } if (nphotons <= 0.) { *fLog << warn << GetDescriptor() << ": Assumed photon flux is smaller or equal 0." << endl; return kFALSE; } if (nphotonsrelvar < 0.) { *fLog << warn << GetDescriptor() << ": Assumed photon flux variance is smaller than 0." << endl; return kFALSE; } fMeanFFactorFADC2Phot = TMath::Sqrt(fRSigmaSquare * nphotons) / GetMean() ; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " F-Factor FADC2Phot: " << fMeanFFactorFADC2Phot << endl; } if (fMeanFFactorFADC2Phot < 0.) { *fLog << warn << GetDescriptor() << ": F-Factor photons to FADC counts smaller than 0." << endl; return kFALSE; } const Float_t ffactorrelvar = 0.25 * fRSigmaSquareVar / ( fRSigmaSquare * fRSigmaSquare) + GetMeanRelVar() + 0.25 * nphotonsrelvar; fMeanFFactorFADC2PhotVar = ffactorrelvar * fMeanFFactorFADC2Phot * fMeanFFactorFADC2Phot; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " Rel.Var.Red.Sigma: " << 0.25 * fRSigmaSquareVar / ( fRSigmaSquare * fRSigmaSquare) << " Rel.Var.Mean: " << GetMeanRelVar() << " Rel.Var.photons: " << 0.25 * nphotonsrelvar << " Rel.Var.F-Factor FADC2Phot: " << ffactorrelvar << endl; } return kTRUE; } // ---------------------------------------------------------------------------- // // - If fPed is smaller than 0 (i.e. has not yet been set), return. // - If fPedVar is smaller than 0 (i.e. has not yet been set), return. // // Calculate the electronic pedestal RMS with the formula: // - elec. pedestal = gkElectronicPedRms * sqrt(logainsamples) // // Calculate the night sky background ped. RMS contribution ("NSB") in the high-gain // from the high gain Pedestal RMS with the formula: // - HiGain NSB square = fPedRms * fPedRms - elec.ped.* elec.ped. // - Var(HiGain NSB square) = fPedVar * fPedRms * fPedRms + 4.*elecPedRmsVar * elec.ped.* elec.ped. // // If HiGain NSB square is smaller than 0., set it to zero. (but not the error!) // // Convert the NSB ped. RMS contribution to the low-gain with the formula: // - LoGain NSB square = HiGain NSB square / (fConversionHiLo*fConversionHiLo) // - Var(LoGain NSB square) = ( Var(HiGain NSB square) / (HiGain NSB square * HiGain NSB square) // + GetConversionHiLoRelVar() // ) * LoGain NSB square * LoGain NSB square // // - Low Gain Ped RMS Square = LoGain NSB square + elec.ped. square // Var (Low Gain Ped RMS Square) = Var(LoGain NSB square) + Var(elec.ped. square) // void MCalibrationChargePix::CalcLoGainPedestal(Float_t logainsamples) { if (fPedRms < 0.) return; if (fPedVar < 0.) return; const Float_t elecPedRms = gkElectronicPedRms * TMath::Sqrt(logainsamples); const Float_t elecPedRmsVar = GetElectronicPedRmsRelVar() * elecPedRms * elecPedRms; Float_t pedRmsSquare = fPedRms * fPedRms; Float_t pedRmsSquareVar = fPedVar * pedRmsSquare; // fPedRmsErr = fPedErr/2. // // We do not know the Low Gain Pedestal RMS, so we have to retrieve it // from the High Gain: // // We extract the pure NSB contribution: // const Float_t elecRmsSquare = elecPedRms * elecPedRms; const Float_t elecRmsSquareVar = 4.*elecPedRmsVar * elecRmsSquare; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " Ped.Rms Square: " << pedRmsSquare << " Elec.Rms Square: " << elecRmsSquare << " Ped.Rms.Square Var.: " << pedRmsSquareVar << " Elec.Rms Square Var.: " << elecRmsSquareVar << endl; } Float_t higainNsbSquare = pedRmsSquare - elecRmsSquare; Float_t higainNsbSquareVar = (pedRmsSquareVar + elecRmsSquareVar); if (higainNsbSquare < 0.001) higainNsbSquare = 0.; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " HiGain NSB Square: " << higainNsbSquare << " Var.HiGain NSB Square: " << higainNsbSquareVar << endl; } // // Now, we divide the NSB by the conversion factor and // add it quadratically to the electronic noise // const Float_t conversionSquare = fConversionHiLo * fConversionHiLo; const Float_t conversionSquareRelVar = 4.* GetConversionHiLoRelVar(); const Float_t logainNsbSquare = higainNsbSquare / conversionSquare; // // Calculation of variance of: c = a/b // Delta(c)^2 = ( Delta(a)^2 + a^2/b^2*(Delta(b)^2 ) / b^2 // const Float_t logainNsbSquareVar = ( higainNsbSquareVar + conversionSquareRelVar * higainNsbSquare * higainNsbSquare ) / conversionSquare / conversionSquare; fLoGainPedRmsSquare = logainNsbSquare + elecRmsSquare; fLoGainPedRmsSquareVar = logainNsbSquareVar + elecRmsSquareVar; if (IsDebug()) { *fLog << dbginf << "ID: " << GetPixId() << " LoGain Ped Rms Square: " << fLoGainPedRmsSquare << " Var.Ped Rms Square: " << fLoGainPedRmsSquareVar << endl; } }