PulserLinearityCalScheme Class Reference

#include <PulserLinearityCalScheme.h>

Inheritance diagram for PulserLinearityCalScheme:

CalScheme CfgPromptConfigurable List of all members.

Public Member Functions

 PulserLinearityCalScheme ()
 ~PulserLinearityCalScheme ()
virtual void DoReset (const VldContext &vc)
virtual void ConfigModified ()
virtual void PrintConfig (std::ostream &os) const
virtual FloatErr GetLinearized (FloatErr rawcharge, const PlexStripEndId &seid) const
virtual FloatErr DecalLinearity (FloatErr lin, const PlexStripEndId &seid) const

Static Public Member Functions

static Bool_t FitIsOK (const CalPulserFits &fit)
static FloatErr GetCorrected (FloatErr incharge, const CalPulserFits &fit, Int_t flag)

Private Member Functions

virtual FloatErr GetLinNear (FloatErr rawcharge, const PlexStripEndId &seid) const
virtual FloatErr GetLinFar (FloatErr rawcharge, const PlexStripEndId &seid) const
virtual FloatErr DecalLinNear (FloatErr lin, const PlexStripEndId &seid) const
virtual FloatErr DecalLinFar (FloatErr lin, const PlexStripEndId &seid) const
MeanCor GetMeanCorrection (FloatErr incharge, const PlexStripEndId &seid, Int_t flag) const
std::pair< PlexPinDiodeId,
PlexPinDiodeId
GetPinDiodeId (const PlexStripEndId &seid) const

Private Attributes

Int_t fCalLin
PlexHandlefPlex
DbiResultPtr< PulserGainfNearGain
DbiResultPtr< PulserGainfFarGain
DbiResultPtr< PulserGainPinfPin
DbiResultPtr< CalPulserFitsfNearLow
DbiResultPtr< CalPulserFitsfNearHigh
DbiResultPtr< CalPulserFitsfFarLow
DbiResultPtr< CalPulserFitsfFarHigh
DbiResultPtr< CalPulserFitsfNearFar

Classes

struct  MeanCor

Detailed Description

Definition at line 28 of file PulserLinearityCalScheme.h.


Constructor & Destructor Documentation

PulserLinearityCalScheme::PulserLinearityCalScheme (  ) 

Definition at line 21 of file PulserLinearityCalScheme.cxx.

References Msg::kVerbose, and MSG.

00021                                                    : fPlex(0)
00022 {
00023 
00024 
00025  MSG("Calib",Msg::kVerbose) << "PulserLinearityCalScheme::PulserLinearityCalScheme" 
00026                             << endl;
00027  Registry r;
00028  InitializeConfig(r);
00029 }

PulserLinearityCalScheme::~PulserLinearityCalScheme (  ) 

Definition at line 32 of file PulserLinearityCalScheme.cxx.

00033 {
00034 }


Member Function Documentation

void PulserLinearityCalScheme::ConfigModified (  )  [virtual]

Reimplemented from CalScheme.

Definition at line 669 of file PulserLinearityCalScheme.cxx.

00670 {
00671 }

FloatErr PulserLinearityCalScheme::DecalLinearity ( FloatErr  lin,
const PlexStripEndId seid 
) const [virtual]

Reimplemented from CalScheme.

Definition at line 57 of file PulserLinearityCalScheme.cxx.

References DecalLinFar(), DecalLinNear(), PlexPlaneId::GetDetector(), Msg::kError, Detector::kFar, Detector::kNear, and MSG.

00059 {
00070 
00071   if(seid.GetDetector() == Detector::kNear) {
00072     return DecalLinNear(lin, seid);}
00073   if(seid.GetDetector() == Detector::kFar) {
00074     return DecalLinFar(lin, seid);}
00075 
00076   MSG("Calib",Msg::kError) << "Stripend with invalid detector, cannot apply non-linearity"<<endl;
00077   FloatErr result(0.,0.);
00078   return result;
00079 }

FloatErr PulserLinearityCalScheme::DecalLinFar ( FloatErr  lin,
const PlexStripEndId seid 
) const [private, virtual]

Definition at line 487 of file PulserLinearityCalScheme.cxx.

References PlexStripEndId::BuildPlnStripEndKey(), FitIsOK(), fNearFar, CalPulserFits::GetAdcMax(), GetCorrected(), ValueErr< T >::GetError(), CalPulserFits::GetFitType(), GetMeanCorrection(), DbiResultPtr< T >::GetRowByIndex(), ValueErr< T >::GetValue(), PlexStripEndId::IsValid(), PlexPlaneId::IsVetoShield(), Msg::kInfo, Msg::kWarning, MAXMSG, PulserLinearityCalScheme::MeanCor::meancor, PulserLinearityCalScheme::MeanCor::nstrips, PulserLinearityCalScheme::MeanCor::rmscor, and ValueErr< T >::SetError().

Referenced by DecalLinearity().

00489 {
00490   // Apply non-linearity to MC ADC value for the far detector.
00491 
00492   // No non-linearity for invalid stripends
00493   if( !seid.IsValid() ) {
00494     MAXMSG("Calib",Msg::kWarning,1) << seid << " is invalid: no non-linearity will be applied to invalid stripends" << endl;
00495     return lin;
00496   }
00497 
00498   // No non-linearity for veto-shield channels
00499   if( seid.IsVetoShield() ) {
00500     MAXMSG("Calib",Msg::kWarning,1) << "No non-linearity will be applied to veto-shield channels" << endl;
00501     return lin;
00502   }
00503 
00504   // For very low pulse-heights, return input value
00505   if(lin.GetValue() < 200.) return lin;
00506 
00507   // Find near-far fit for this stripend
00508   UInt_t seidkey = (UInt_t)seid.BuildPlnStripEndKey();
00509   const CalPulserFits* fit = fNearFar.GetRowByIndex(seidkey);
00510 
00511   // Check for a good fit
00512   if(fit != 0) {
00513     if(FitIsOK(*fit)) {
00514 
00515       // If we are below maximum of linear fit there is no non-linearity
00516       if(fit->GetFitType()==1 && lin.GetValue()<=fit->GetAdcMax()) {
00517         return lin;
00518       }
00519 
00520       else if(fit->GetFitType()>=5) {
00521 
00522       // We have a good Pole or Pole+Kicker fit. 
00523         FloatErr result = GetCorrected(lin,*fit,1);
00524         // Do not add extra error
00525         result.SetError(lin.GetError());
00526         return result;
00527       }
00528     }
00529   }
00530   else {
00531     MAXMSG("Calib",Msg::kWarning,20) << "No CALPULSERFITS entry for " << seid << endl;
00532   }
00533 
00534   // No fit, bad fit or we are above adcmax of a linear fit.
00535   // Use mean correction for other stripends on this pixel.
00536   MeanCor others = GetMeanCorrection(lin,seid,1);
00537   if(others.nstrips > 0) {
00538     MAXMSG("Calib",Msg::kInfo,20) <<"Using "<<others.nstrips<<" stripends to unlinearize "<<seid<<endl;
00539     FloatErr result = lin + FloatErr(others.meancor,others.rmscor);
00540     // Do not add extra error
00541     result.SetError(lin.GetError());
00542     return result;
00543   }
00544 
00545   // No other good stripends on this spot
00546   MAXMSG("Calib",Msg::kWarning,20) << "Stripend" << seid << " not unlinearized" << endl;
00547   return lin;
00548 
00549 }

FloatErr PulserLinearityCalScheme::DecalLinNear ( FloatErr  lin,
const PlexStripEndId seid 
) const [private, virtual]

Definition at line 246 of file PulserLinearityCalScheme.cxx.

References PlexStripEndId::BuildPlnStripEndKey(), fNearGain, fNearLow, fPin, CalPulserFits::GetChisq(), PlexPinDiodeId::GetEncoded(), ValueErr< T >::GetError(), PlexPinDiodeId::GetGain(), PulserGainPin::GetMean(), PulserGain::GetMean(), PulserGainPin::GetNumEntries(), PulserGain::GetNumEntries(), PulserGainPin::GetNumPoints(), PulserGain::GetNumPoints(), PulserGainPin::GetNumTriggers(), PulserGain::GetNumTriggers(), GetPinDiodeId(), DbiResultPtr< T >::GetRowByIndex(), CalPulserFits::GetSlope(), ValueErr< T >::GetValue(), CalPulserFits::GetXOffset(), Msg::kError, Msg::kWarning, MAXMSG, and ValueErr< T >::Set().

Referenced by DecalLinearity().

00248 {
00259 
00260   Float_t linchargev = lin.GetValue();
00261   Float_t linchargee = lin.GetError();
00262   std::pair< PlexPinDiodeId,PlexPinDiodeId >  pdids;
00263   PlexPinDiodeId pdidlo, pdidhi;
00264   FloatErr result;
00265   float topin = -9999.; //the pin value to be found
00266 
00267   UInt_t seidkey = (UInt_t)seid.BuildPlnStripEndKey();
00268 
00269   //number of points in the gain curve(stripend & pin)
00270   Int_t numpoints = 0;
00271   Int_t numpoints2 = 0;
00272 
00273   vector<float> pmtmeani; //zero-corrected 
00274   vector<float> pinmeani; //zero-corrected
00275 
00276   //Get PulserGain and PulserGainPin objects
00277   const PulserGain *pmt = fNearGain.GetRowByIndex(seidkey);
00278 
00279   // Get Pin diode pair
00280   pdids = GetPinDiodeId(seid);
00281   //Get low gain (gain =1)
00282   pdidhi = pdids.second;
00283   pdidlo = pdids.first;
00284   
00285   // For the moment only do near vs low
00286   const PulserGainPin *pin = 0;
00287   if (pdidlo.GetGain()==1) {
00288     pin  = fPin.GetRowByIndex(pdidlo.GetEncoded());
00289   } else {    
00290     pin = 0;
00291   }
00292 
00293 
00294   // Get fit results:    
00295   float linslp = -9999.;
00296   float linchi2 = -9999.;
00297   float linxoff = -9999.;
00298 
00299   // For now only NearEnd vs LowGainPin
00300   const CalPulserFits *linfit = fNearLow.GetRowByIndex(seidkey);
00301 
00302   if(linfit==0) {
00303     MAXMSG("Calib",Msg::kWarning,10) 
00304       << "No CalPulserFits Near-Low database row for StripEnd " 
00305       << seid << " indexed as " << seid.BuildPlnStripEndKey() << endl;
00306     linslp = 0.;
00307     linchi2 = 0;
00308     linxoff = 0;
00309 
00310   } else {
00311     
00312     linslp = linfit->GetSlope();
00313     linchi2 = linfit->GetChisq();
00314     linxoff = linfit->GetXOffset();
00315     
00316   }
00317   
00318   float rawchargev = -9999.;
00319 
00320   if (linfit && linslp>0. && linchi2>0 && linxoff>-100. //constants are reasonable
00321       &&linchargev>6000.){
00322     topin = linchargev/linslp + linxoff;
00323   }  
00324   else {
00325     result.Set(linchargev,linchargee);
00326     return result;
00327   }
00328 
00329   if (pmt && pin) {//value objects
00330     numpoints = pmt->GetNumPoints();
00331     numpoints2 = pin->GetNumPoints();
00332     
00333     if (numpoints!=numpoints2) {
00334       MAXMSG("Calib",Msg::kError,10) << "There are " << numpoints << " points at stripend and " 
00335                                << numpoints2 << " points at pin!!!" << endl;
00336     }
00337     
00338     // Get mean, nentries and ntriggers
00339     // Stripend
00340     const Float_t * pmtmean = pmt->GetMean(); 
00341     const Float_t * pmtent = pmt->GetNumEntries(); 
00342     const Float_t * pmttrg = pmt->GetNumTriggers();
00343     // Pin
00344     const Float_t * pinmean = pin->GetMean(); 
00345     const Float_t * pinent = pin->GetNumEntries(); 
00346     const Float_t * pintrg = pin->GetNumTriggers();
00347     
00348     for (int ipoint=0; ipoint< numpoints; ipoint++) {//loop through all the points
00349       if (pmttrg[ipoint]){//zero correction
00350         pmtmeani.push_back(pmtmean[ipoint]*pmtent[ipoint]/pmttrg[ipoint]);
00351       }
00352       else {
00353         pmtmeani.push_back(pmtmean[ipoint]);
00354       }
00355       
00356       if (pintrg[ipoint]){//zero correction
00357         pinmeani.push_back(pinmean[ipoint]*pinent[ipoint]/pintrg[ipoint]);
00358       }
00359       else {
00360         pinmeani.push_back(pinmean[ipoint]);
00361       }
00362       
00363       if ((ipoint>0 && topin<pinmeani[ipoint] && topin>=pinmeani[ipoint-1])//will interpolate 
00364            ||(ipoint==numpoints-1 && topin > pinmeani[ipoint])){//will extrapolate
00365 
00366         
00367         if ((pmtmeani[ipoint] - pmtmeani[ipoint-1])>0) {
00368           Float_t intslp = (pinmeani[ipoint] - pinmeani[ipoint-1])/
00369             (pmtmeani[ipoint] - pmtmeani[ipoint-1]);
00370           if (intslp>0) {
00371             // get the pin value for the raw adc
00372             rawchargev = pmtmeani[ipoint-1] + (topin-pinmeani[ipoint-1])/intslp;
00373           } else {
00374             MAXMSG("Calib",Msg::kError,10) << "Invalid slope: " << intslp << endl;
00375             rawchargev = -9999.;
00376           }
00377         } else {
00378           
00379           MAXMSG("Calib",Msg::kError,10) << "Invalid pin values: " << pinmeani[ipoint] << ", " 
00380                                    << pinmeani[ipoint-1] << endl;
00381           rawchargev=-9999.;
00382         }
00383       }
00384     }
00385   } else {
00386     MAXMSG("Calib",Msg::kError,10) <<"Can't get data from database for pmt and pin for stripend "<<seid<<endl; 
00387     rawchargev=-9999.;
00388   }
00389 
00390   if (rawchargev!=-9999.){
00391     result.Set(rawchargev,linchargee);
00392   }
00393   else result.Set(linchargev,linchargee);
00394   
00395   return result;
00396 }

void PulserLinearityCalScheme::DoReset ( const VldContext vc  )  [virtual]

Reimplemented from CalScheme.

Definition at line 681 of file PulserLinearityCalScheme.cxx.

References fNearFar, fNearGain, fNearHigh, fNearLow, fPin, fPlex, VldContext::GetDetector(), Msg::kDebug, Detector::kFar, Detector::kNear, Pulser::kNearEnd, Pulser::kNearFar, Pulser::kNearHigh, Pulser::kNearLow, MSG, and DbiResultPtr< T >::NewQuery().

00682 {
00683   // Use latest GC for linearity corrections (need to make sure data is there...).
00684   //
00685   //VldTimeStamp ts = vc.GetTimeStamp();
00686   // Gain curve values (near detector only):
00687   if (vc.GetDetector()==Detector::kNear) {
00688     fNearGain.NewQuery(vc,Pulser::kNearEnd);
00689     MSG("Calib",Msg::kDebug) << "Done querying PULSERGAIN." << endl;
00690     // Near Det task=1
00691     fPin.NewQuery(vc,1);
00692     MSG("Calib",Msg::kDebug) << "Done querying PULSERGAINPIN." << endl;
00693   }
00694 
00695   // Get fit results
00696   if (vc.GetDetector()==Detector::kNear) {
00697     fNearLow.NewQuery(vc,Pulser::kNearLow);
00698     fNearHigh.NewQuery(vc,Pulser::kNearHigh);
00699   }
00700   if (vc.GetDetector()==Detector::kFar) {
00701     fNearFar.NewQuery(vc,Pulser::kNearFar);
00702   }
00703 
00704   MSG("Calib",Msg::kDebug) << "Done querying CALPULSERFITS." << endl;
00705 
00706   if (fPlex) delete fPlex;
00707   MSG("Calib",Msg::kDebug) << "Delete Plex. " << fPlex << endl;
00708 
00709   fPlex = new PlexHandle(vc);
00710   MSG("Calib",Msg::kDebug) << "Get new plexhandle." << endl;
00711   
00712 }

Bool_t PulserLinearityCalScheme::FitIsOK ( const CalPulserFits fit  )  [static]

Definition at line 639 of file PulserLinearityCalScheme.cxx.

References MuELoss::e, CalPulserFits::GetChisq(), CalPulserFits::GetFitType(), CalPulserFits::GetMeanRes(), CalPulserFits::GetNPFit(), CalPulserFits::GetPar1(), and CalPulserFits::GetXOffset().

Referenced by DecalLinFar(), GetLinFar(), and GetMeanCorrection().

00640 {
00641   // Require Linear, Pole or Pole+Kicker Fit
00642   if(fit.GetFitType()<0) return false;
00643 
00644   // Require minimum number of constraints and reasonable chisq
00645   Int_t npar = 1;
00646   if(fit.GetFitType()==5) npar = 3;
00647   if(fit.GetFitType()==25) {
00648     npar = 5;
00649     if(fabs(fit.GetXOffset())>1.e-5) npar = 6;
00650   }
00651   if(fit.GetNPFit()-npar < 10) return false;
00652   if(fit.GetChisq()/(fit.GetNPFit()-npar) > 3.) return false;
00653 
00654   // Require good mean residual
00655   if(fit.GetMeanRes() > 1.) return false;
00656 
00657   // Require sensible parameters for Pole fits
00658   if(fit.GetFitType()>1) {
00659     if(fit.GetPar1()<10000. || fit.GetPar1()>20000.) return false;
00660   }
00661 
00662   // Fit OK
00663   return true;
00664 }

FloatErr PulserLinearityCalScheme::GetCorrected ( FloatErr  incharge,
const CalPulserFits fit,
Int_t  flag 
) [static]

Definition at line 553 of file PulserLinearityCalScheme.cxx.

References CalVaLinearity::FitFunction(), ValueErr< T >::GetError(), CalPulserFits::GetFitType(), CalPulserFits::GetMeanRes(), CalPulserFits::GetPar1(), CalPulserFits::GetPar2(), CalPulserFits::GetPar3(), CalPulserFits::GetPar4(), CalPulserFits::GetSlope(), ValueErr< T >::GetValue(), and CalPulserFits::GetXOffset().

Referenced by DecalLinFar(), GetLinFar(), and GetMeanCorrection().

00554 {
00555   // Calculate (un)linearized value and error using this fit
00556   // Flag = 0: calculate linearized value
00557   // Flag != 0: apply non-linearity (for MC)
00558 
00559   Double_t  x = incharge.GetValue();
00560   Double_t dx = incharge.GetError();
00561 
00562   Double_t par[8];
00563   par[0] = fit.GetFitType();
00564   if(flag == 0) par[0] -= 1.;
00565   par[1] = fit.GetPar1();
00566   par[2] = fit.GetPar2();
00567   par[3] = fit.GetPar3();
00568   par[4] = fit.GetPar4();
00569   par[5] = 0.;
00570   par[6] = fit.GetXOffset();
00571   par[7] = 1./fit.GetSlope();
00572 
00573   Double_t xcor = CalVaLinearity::FitFunction(&x,par);  
00574   xcor = (xcor-par[6])/par[7];
00575 
00576   // Set error on correction to max(mean residual, 0.5%) of the correction
00577   Double_t dxcor = fit.GetMeanRes();
00578   if(dxcor < 0.5) dxcor = 0.5;
00579   dxcor *= 0.01*fabs(xcor-x);
00580   dxcor = sqrt(dx*dx+dxcor*dxcor);
00581 
00582   FloatErr result(xcor,dxcor);
00583   return result;
00584 }

FloatErr PulserLinearityCalScheme::GetLinearized ( FloatErr  rawcharge,
const PlexStripEndId seid 
) const [virtual]

Reimplemented from CalScheme.

Definition at line 39 of file PulserLinearityCalScheme.cxx.

References PlexPlaneId::GetDetector(), GetLinFar(), GetLinNear(), Msg::kError, Detector::kFar, Detector::kNear, and MSG.

00041 {
00042   //Purpose: Convert from raw ADC to linearized ADC
00043   //In: raw ADC
00044   //Out: linearized ADC (siglin)
00045 
00046   if(seid.GetDetector() == Detector::kNear) {
00047     return GetLinNear(rawcharge, seid);}
00048   if(seid.GetDetector() == Detector::kFar) {
00049     return GetLinFar(rawcharge, seid);}
00050 
00051   MSG("Calib",Msg::kError) << "Stripend with invalid detector, cannot linearize"<<endl;
00052   FloatErr result(0.,0.);
00053   return result;
00054 }

FloatErr PulserLinearityCalScheme::GetLinFar ( FloatErr  rawcharge,
const PlexStripEndId seid 
) const [private, virtual]

Definition at line 400 of file PulserLinearityCalScheme.cxx.

References PlexStripEndId::BuildPlnStripEndKey(), FitIsOK(), fNearFar, CalPulserFits::GetAdcMax(), GetCorrected(), CalPulserFits::GetFitType(), GetMeanCorrection(), DbiResultPtr< T >::GetRowByIndex(), ValueErr< T >::GetValue(), PlexStripEndId::IsValid(), PlexPlaneId::IsVetoShield(), Msg::kDebug, Msg::kWarning, MAXMSG, PulserLinearityCalScheme::MeanCor::meancor, PulserLinearityCalScheme::MeanCor::nstrips, and PulserLinearityCalScheme::MeanCor::rmscor.

Referenced by GetLinearized().

00402 {
00403   // Return linearized ADC value for the far detector.
00404 
00405   // No correction for invalid stripends
00406   if( !seid.IsValid() ) {
00407     MAXMSG("Calib",Msg::kWarning,1) << seid << " is invalid: no linearity calibrations will be applied to invalid stripends" << endl;
00408     return rawcharge;
00409   }
00410 
00411   // No correction for veto-shield channels
00412   if( seid.IsVetoShield() ) {
00413     // dont' even compliain. --NJT
00414     //MAXMSG("Calib",Msg::kWarning,1) << "No linearity calibrations will be applied to veto-shield channels" << endl;
00415     return rawcharge;
00416   }
00417 
00418 
00419   // For very low pulse-heights, return input value
00420   if(rawcharge.GetValue() < 200.) return rawcharge;
00421 
00422   // Find near-far fit for this stripend
00423   UInt_t seidkey = (UInt_t)seid.BuildPlnStripEndKey();
00424   const CalPulserFits* fit = fNearFar.GetRowByIndex(seidkey);
00425 
00426   // Check for a good fit
00427   if(fit != 0) {
00428     if(FitIsOK(*fit)) {
00429 
00430       // If we are below maximum of linear fit there is no correction
00431       if(fit->GetFitType()==1 && rawcharge.GetValue()<=fit->GetAdcMax()) {
00432         return rawcharge;
00433       }
00434 
00435       else if(fit->GetFitType()>=5) {
00436 
00437       // We have a good Pole or Pole+Kicker fit. Use it for the central value, 
00438       // unless the inversion fails: this happens if the input value is >k1.
00439       // Also reject fits giving a negative correction.
00440       // If raw charge is within fit range use error from fit residual. 
00441       // If we are extrapolating above fit maximum, use other stripends
00442       // on same pixel to set error. If there are no other good stripends,
00443       // double error from this fit.
00444 
00445         FloatErr result = GetCorrected(rawcharge,*fit,0);
00446         if(result.GetValue()>=rawcharge.GetValue()) {
00447           if(rawcharge.GetValue()<=fit->GetAdcMax()) {
00448             return result;
00449           }
00450           MeanCor others = GetMeanCorrection(rawcharge,seid,0);
00451           if(others.nstrips>0) {
00452             Float_t diff = result.GetValue()-rawcharge.GetValue() - others.meancor;
00453             result += FloatErr(0.,fabs(diff));
00454           }
00455           else {
00456             result.SetError(2.*result.GetError());
00457           }
00458           return result;
00459         }
00460       }
00461     }
00462   }
00463   else {
00464     MAXMSG("Calib",Msg::kWarning,20) << "No CALPULSERFITS entry for " << seid << endl;
00465   }
00466 
00467   // No fit, bad fit or we are above adcmax of a linear fit.
00468   // Use mean correction for other stripends on this pixel.
00469   // Set error to be rms of these values.
00470   MeanCor others = GetMeanCorrection(rawcharge,seid,0);
00471   if(others.nstrips > 0) {
00472     MAXMSG("Calib",Msg::kDebug,20) <<"Using "<<others.nstrips<<" stripends to calibrate "<<seid<<endl;
00473     FloatErr result = rawcharge + FloatErr(others.meancor,others.rmscor);
00474     return result;
00475   }
00476 
00477   // No other good stripends on this spot
00478   MAXMSG("Calib",Msg::kWarning,20) << "Stripend" << seid << " not calibrated" << endl;
00479   FloatErr result(rawcharge.GetValue(),rawcharge.GetError());
00480   result *= FloatErr(1.,0.5);
00481   return result;
00482 
00483 }

FloatErr PulserLinearityCalScheme::GetLinNear ( FloatErr  rawcharge,
const PlexStripEndId seid 
) const [private, virtual]

Definition at line 82 of file PulserLinearityCalScheme.cxx.

References PlexStripEndId::BuildPlnStripEndKey(), fNearGain, fNearLow, fPin, CalPulserFits::GetChisq(), PlexPinDiodeId::GetEncoded(), ValueErr< T >::GetError(), PlexPinDiodeId::GetGain(), PulserGainPin::GetMean(), PulserGain::GetMean(), PulserGainPin::GetNumEntries(), PulserGain::GetNumEntries(), PulserGainPin::GetNumPoints(), PulserGain::GetNumPoints(), PulserGainPin::GetNumTriggers(), PulserGain::GetNumTriggers(), GetPinDiodeId(), DbiResultPtr< T >::GetRowByIndex(), CalPulserFits::GetSlope(), ValueErr< T >::GetValue(), CalPulserFits::GetXOffset(), Msg::kDebug, Msg::kError, Msg::kVerbose, Msg::kWarning, MAXMSG, MSG, and ValueErr< T >::Set().

Referenced by GetLinearized().

00084 {
00085   //Purpose: Convert from raw ADC to linearized ADC
00086   //It would find the Pin value in the gain curve of the requested channel for the given raw ADC value either through interpolation or extrapolation. Then multiply that pin value by the slope from a linear fit of the same gain curve in the linear region to take out the PMT saturation and get the linearized ADC.
00087   //In: raw ADC
00088   //Out: linearized ADC (siglin)
00089   //database tables needed: PULSERGAIN, PULSERGAINPIN, CALPULSERFITS
00090 
00091   Float_t rawchargev = rawcharge.GetValue();
00092   Float_t rawchargee = rawcharge.GetError();
00093   std::pair< PlexPinDiodeId,PlexPinDiodeId >  pdids;
00094   PlexPinDiodeId pdidlo, pdidhi;
00095   FloatErr result;
00096   float topin = -9999.; //the pin value to be found
00097 
00098   UInt_t seidkey = (UInt_t)seid.BuildPlnStripEndKey();
00099 
00100   //number of points in the gain curve(stripend & pin)
00101   Int_t numpoints = 0;
00102   Int_t numpoints2 = 0;
00103 
00104   vector<float> pmtmeani; //zero-corrected 
00105   vector<float> pinmeani; //zero-corrected
00106 
00107   //Get PulserGain and PulserGainPin objects
00108   const PulserGain *pmt = fNearGain.GetRowByIndex(seidkey);
00109 
00110   // Get Pin diode pair
00111   pdids = GetPinDiodeId(seid);
00112   //Get low gain (gain =1)
00113   pdidhi = pdids.second;
00114   pdidlo = pdids.first;
00115   
00116   // For the moment only do near vs low
00117   const PulserGainPin *pin = 0;
00118   if (pdidlo.GetGain()==1) {
00119     pin  = fPin.GetRowByIndex(pdidlo.GetEncoded());
00120   } else {    
00121     pin = 0;
00122   }
00123 
00124 
00125   // Get fit results:    
00126   float linslp = -9999.;
00127   float linchi2 = -9999.;
00128   float linxoff = -9999.;
00129 
00130   // For now only NearEnd vs LowGainPin
00131   const CalPulserFits *linfit = fNearLow.GetRowByIndex(seidkey);
00132 
00133   if(linfit==0) {
00134     MAXMSG("Calib",Msg::kWarning,10) 
00135       << "No CalPulserFits Near-Low database row for StripEnd " 
00136       << seid << " indexed as " << seid.BuildPlnStripEndKey() << endl;
00137     linslp = 0.;
00138     linchi2 = 0;
00139     linxoff = 0;
00140 
00141   } else {
00142     
00143     linslp = linfit->GetSlope();
00144     linchi2 = linfit->GetChisq();
00145     linxoff = linfit->GetXOffset();
00146     
00147   }
00148 
00149 
00150   if (pmt && pin) {//value objects
00151     //Get number of points 
00152     //Stripend
00153     numpoints = pmt->GetNumPoints();
00154     
00155     //Pin
00156     numpoints2 = pin->GetNumPoints();
00157     
00158     if (numpoints!=numpoints2) {
00159       MAXMSG("Calib",Msg::kError,10) << "There are " << numpoints << " points at stripend and " 
00160                                << numpoints2 << " points at pin!!!" << endl;
00161     }
00162     
00163     // Get mean, nentries and ntriggers
00164     // Stripend
00165     const Float_t * pmtmean = pmt->GetMean(); 
00166     const Float_t * pmtent = pmt->GetNumEntries(); 
00167     const Float_t * pmttrg = pmt->GetNumTriggers();
00168     // Pin
00169     const Float_t * pinmean = pin->GetMean(); 
00170     const Float_t * pinent = pin->GetNumEntries(); 
00171     const Float_t * pintrg = pin->GetNumTriggers();
00172     
00173     // Loop through points in PulserGain to find interval with rawcharge 
00174     
00175     for (int ipoint=0; ipoint< numpoints; ipoint++) {//loop through all the points
00176       if (pmttrg[ipoint]){//zero correction
00177         pmtmeani.push_back(pmtmean[ipoint]*pmtent[ipoint]/pmttrg[ipoint]);
00178       }
00179       else {
00180         pmtmeani.push_back(pmtmean[ipoint]);
00181       }
00182       
00183       if (pintrg[ipoint]){//zero correction
00184         pinmeani.push_back(pinmean[ipoint]*pinent[ipoint]/pintrg[ipoint]);
00185       }
00186       else {
00187         pinmeani.push_back(pinmean[ipoint]);
00188       }
00189       
00190       if ((ipoint>0 && rawchargev<pmtmeani[ipoint] && rawchargev>=pmtmeani[ipoint-1])||//will interpolate 
00191           (ipoint==numpoints-1 && rawchargev>pmtmeani[ipoint])){//will extrapolate
00192       
00193       
00194         // This interval contains rawcharge
00195         // Get pin value from interpolation or extrapolation (if ipoints==numpoints-1)
00196       
00197         // Check if there are enough entries (tables should only have numentries/numtriggers>95%)
00198         MSG("Calib",Msg::kDebug) << "numEntries at pmt: " << *(pmtent+ipoint) << endl;
00199         MSG("Calib",Msg::kDebug) << "numEntries at pin: " << *(pinent+ipoint) << endl;
00200         
00201         if ((pinmeani[ipoint] - pinmeani[ipoint-1])>0) {
00202           Float_t intslp = (pmtmeani[ipoint] - pmtmeani[ipoint-1])/
00203             (pinmeani[ipoint] - pinmeani[ipoint-1]);
00204           if (intslp>0) {
00205             // get the pin value for the raw adc
00206             topin = pinmeani[ipoint-1] + (rawchargev-pmtmeani[ipoint-1])/intslp;
00207           } else {
00208             MAXMSG("Calib",Msg::kError,10) << "Invalid slope: " << intslp << endl;
00209             topin = -9999.;
00210           }
00211         } else {
00212           
00213           MAXMSG("Calib",Msg::kError,10) << "Invalid pin values: " << pinmeani[ipoint] << ", " 
00214                                    << pinmeani[ipoint-1] << endl;
00215           topin=-9999.;
00216         }
00217       }
00218     }
00219   } else {
00220     MAXMSG("Calib",Msg::kError,10) <<"Can't get data from database for pmt and pin for stripend "<<seid<<endl; 
00221     topin=-9999.;
00222   }
00223   
00224   
00225     
00226   // Now need to convert back to adc using slope from linear fit:
00227   
00228   // Need to add errors....
00229   // ... and come up with better sanity checks before applying correction
00230   if (topin>0. //pin value is positive
00231       && linfit && linslp>0. && linchi2>0 && linxoff>-100. //constants are reasonable
00232       &&rawchargev>6000. //don't apply the calibration for raw adc less than 6000
00233       && pmtmeani[numpoints-1]>6000){ //gain curve didn't reach saturation, don't apply
00234     
00235     MSG("Calib",Msg::kVerbose)<< "pin value = " << topin << "  slope from table (fit) = " << linslp << "   Fit chi^2 = " << linchi2 <<  endl;
00236     result.Set((topin-linxoff)*linslp,rawchargee);
00237   }else{
00238     result.Set(rawchargev,rawchargee);
00239     //result.Set(0.,rawchargee);
00240   }
00241   return result;
00242 }

PulserLinearityCalScheme::MeanCor PulserLinearityCalScheme::GetMeanCorrection ( FloatErr  incharge,
const PlexStripEndId seid,
Int_t  flag 
) const [private]

Definition at line 588 of file PulserLinearityCalScheme.cxx.

References FitIsOK(), fNearFar, fPlex, GetCorrected(), PlexHandle::GetRawChannelId(), DbiResultPtr< T >::GetRowByIndex(), PlexHandle::GetSEIdAltL(), ValueErr< T >::GetValue(), PulserLinearityCalScheme::MeanCor::meancor, PulserLinearityCalScheme::MeanCor::nstrips, and PulserLinearityCalScheme::MeanCor::rmscor.

Referenced by DecalLinFar(), and GetLinFar().

00589 {
00590   // Find the average correction from other stripends on same pixel.
00591   // N.B. the average correction is the value which must be added to
00592   // the raw charge to obtain the (un)linearized value.
00593   // Flag = 0: calculate linearized value
00594   // Flag != 0: calculate non-linearity (for MC)
00595  
00596   MeanCor result;
00597 
00598   PlexSEIdAltL altlist = fPlex->GetSEIdAltL(fPlex->GetRawChannelId(seid));
00599   Int_t n = 0;
00600   Float_t sumcor = 0.;
00601   Float_t sumcor2 = 0.;
00602   for (PlexSEIdAltL::const_iterator it = altlist.begin(); it!=altlist.end();it++) {
00603     const CalPulserFits* fit = fNearFar.GetRowByIndex((*it).GetSEId().BuildPlnStripEndKey());
00604     if(fit != 0) {
00605       if(FitIsOK(*fit)) {
00606         Float_t cor;
00607         if(fit->GetFitType()==1) {cor = 0.;}
00608         else {cor = GetCorrected(incharge,*fit,flag).GetValue() - incharge.GetValue();}
00609         // If k1>adcmax, correction fit returns zero: don't use
00610         // Also do not use values above adcmax
00611         if(flag==0 && (cor<0. || incharge.GetValue()>fit->GetAdcMax())) {continue;}
00612         if(flag !=0 && (cor>0. || incharge.GetValue()+cor>fit->GetAdcMax())) {continue;}
00613           sumcor += cor;
00614           sumcor2 += cor*cor;
00615           n++;
00616       }
00617     }
00618   }
00619 
00620   if(n > 0) {
00621     sumcor /= n;
00622     sumcor2 = sumcor2/n - sumcor*sumcor;
00623     if(sumcor2 > 0.) {
00624       sumcor2 = sqrt(sumcor2);
00625     }
00626     else {
00627       sumcor2 = 0.05*sumcor;
00628     }
00629   }
00630 
00631   result.nstrips = n;
00632   result.meancor = sumcor;
00633   result.rmscor = sumcor2;
00634   return result;
00635 }

std::pair< PlexPinDiodeId, PlexPinDiodeId > PulserLinearityCalScheme::GetPinDiodeId ( const PlexStripEndId seid  )  const [private]

Definition at line 715 of file PulserLinearityCalScheme.cxx.

References fPlex, PlexHandle::GetLedId(), and PlexHandle::GetPinDiodeIds().

Referenced by DecalLinNear(), and GetLinNear().

00716 {
00720 
00721   PlexPinDiodeId pdid;  
00722   PlexLedId lid;
00723   std::pair< PlexPinDiodeId,PlexPinDiodeId > pdids;
00724 
00725   if (fPlex) {  
00726     lid = fPlex->GetLedId(seid);
00727     
00728     pdids = fPlex->GetPinDiodeIds(lid);
00729     //    cout << "PB, Led: " << lid.GetLedInBox() << ", " << lid.GetPulserBox() << endl;
00730     
00731   }
00732 
00733   return pdids;
00734   
00735 
00736 }

void PulserLinearityCalScheme::PrintConfig ( std::ostream &  os  )  const [virtual]

Reimplemented from CalScheme.

Definition at line 675 of file PulserLinearityCalScheme.cxx.

00676 {
00677 }


Member Data Documentation

Int_t PulserLinearityCalScheme::fCalLin [private]

Definition at line 58 of file PulserLinearityCalScheme.h.

DbiResultPtr<PulserGain> PulserLinearityCalScheme::fFarGain [private]

Definition at line 63 of file PulserLinearityCalScheme.h.

DbiResultPtr<CalPulserFits> PulserLinearityCalScheme::fFarHigh [private]

Definition at line 69 of file PulserLinearityCalScheme.h.

DbiResultPtr<CalPulserFits> PulserLinearityCalScheme::fFarLow [private]

Definition at line 68 of file PulserLinearityCalScheme.h.

DbiResultPtr<CalPulserFits> PulserLinearityCalScheme::fNearFar [private]

Definition at line 70 of file PulserLinearityCalScheme.h.

Referenced by DecalLinFar(), DoReset(), GetLinFar(), and GetMeanCorrection().

DbiResultPtr<PulserGain> PulserLinearityCalScheme::fNearGain [private]

Definition at line 62 of file PulserLinearityCalScheme.h.

Referenced by DecalLinNear(), DoReset(), and GetLinNear().

DbiResultPtr<CalPulserFits> PulserLinearityCalScheme::fNearHigh [private]

Definition at line 67 of file PulserLinearityCalScheme.h.

Referenced by DoReset().

DbiResultPtr<CalPulserFits> PulserLinearityCalScheme::fNearLow [private]

Definition at line 66 of file PulserLinearityCalScheme.h.

Referenced by DecalLinNear(), DoReset(), and GetLinNear().

DbiResultPtr<PulserGainPin> PulserLinearityCalScheme::fPin [private]

Definition at line 64 of file PulserLinearityCalScheme.h.

Referenced by DecalLinNear(), DoReset(), and GetLinNear().

PlexHandle* PulserLinearityCalScheme::fPlex [private]

Definition at line 60 of file PulserLinearityCalScheme.h.

Referenced by DoReset(), GetMeanCorrection(), and GetPinDiodeId().


The documentation for this class was generated from the following files:
Generated on Mon Nov 10 00:56:18 2014 for loon by  doxygen 1.4.7