Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

QuadLinearityCalScheme.cxx

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 #include "QuadLinearityCalScheme.h"
00010 #include "MessageService/MsgService.h"
00011 #include "PulserCalibration/PulserConventions.h"
00012 #include <limits>
00013 
00014 ClassImp(QuadLinearityCalScheme)
00015 CVSID("$Id: QuadLinearityCalScheme.cxx,v 1.10 2008/10/14 21:04:46 tagg Exp $");
00016 //......................................................................
00017 
00018 const int kFitType = 44;
00019 
00020 QuadLinearityCalScheme::QuadLinearityCalScheme() 
00021 {
00022  MSG("Calib",Msg::kVerbose) << "QuadLinearityCalScheme::QuadLinearityCalScheme" 
00023                             << endl;
00024  Registry r;
00025  r.Set("PulseToBucketCorrection",0.44);
00026  r.Set("BucketMode",1);
00027 
00028  InitializeConfig(r);
00029 }
00030 
00031 //......................................................................
00032 QuadLinearityCalScheme::~QuadLinearityCalScheme()
00033 {
00034 }
00035 
00036 
00037 //......................................................................
00038 
00039 FloatErr QuadLinearityCalScheme::GetLinearized(FloatErr rawadc, 
00040                                                const PlexStripEndId& seid) const
00041 {
00042   //Purpose: Convert from raw ADC to linearized ADC
00043   //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.
00044   //In: raw ADC
00045   //Out: linearized ADC (siglin)
00046 
00047   // Get fit:
00048   const CalPulserFits* row = fFitTable.GetRowByIndex(seid.BuildPlnStripEndKey());
00049   
00050   Float_t beta = 0; // The nonlinearity parameter, in ADC^-1. Should be -ve
00051   Float_t dbeta = 0.; // The error on beta.
00052   Float_t maxadc = 0; // The max ADC value pulsed by the system
00053   Float_t meanres = rawadc; // The mean residual, in ADC counts.
00054   if(row) {
00055     beta = row->GetPar1();
00056     dbeta = row->GetPar2();
00057     maxadc = row->GetAdcMax();
00058     meanres = row->GetMeanRes();
00059   } else {
00060     if(fFitTable.GetNumRows()>0) {
00061       MAXMSG("Calib",Msg::kWarning,10) << "No CALPULSERFITS quadratic fit for " << seid.AsString() << endl;
00062       IncrementErrors(kLinCalibrator,kMissingRow,seid);
00063     }
00064   }
00065 
00066   if(fBucketMode) {
00067     beta /= fPulseToBucketCorrection;
00068     dbeta /= fPulseToBucketCorrection;
00069   }
00070 
00071   // Apply the nonlinearity correction.
00072 
00073   Float_t err2 = rawadc.GetError2(); // error squared
00074   Float_t cal = rawadc;
00075   
00076   // Total saturation limit:
00077   float s = 1.+4.*rawadc*beta;
00078   if(s<0) {
00079     IncrementErrors(kLinCalibrator,kBadInput,seid);
00080     s=0;
00081     err2 += pow(rawadc - 1.0/(-4.*beta),2); // Increase error by distance to saturation.
00082   } else {
00083     // The correct way to calibrate:
00084     if(beta<0) cal = 1.0/(2.*beta) * (sqrt(s) - 1.0);     
00085   }
00086 
00087   const float kMaxMeanRes = sqrt(std::numeric_limits<float>::max())*1e-6;
00088   if(meanres>kMaxMeanRes) meanres = kMaxMeanRes;
00089   if(cal>2500)  
00090     err2 += meanres*meanres; // Add on mean residual as error
00091 
00092   if(rawadc>maxadc) {
00093     // We're out of bounds. Apply an additional error
00094     // as the error on beta times the correction.
00095     IncrementErrors(kLinCalibrator,kDataInsufficient,seid);
00096     Float_t temp = (cal-rawadc)*(dbeta);
00097     if(beta!=0) temp = temp/beta;
00098     err2 += temp*temp;
00099   }
00100   FloatErr retval;
00101   retval.SetValueError2(cal,err2);
00102   return retval;
00103 }
00104 
00105 //......................................................................
00106 
00107 FloatErr QuadLinearityCalScheme::DecalLinearity(FloatErr lin, 
00108                                                 const PlexStripEndId& seid) const
00109 {
00120 
00121   const CalPulserFits* row = fFitTable.GetRowByIndex(seid.BuildPlnStripEndKey());
00122   
00123   Float_t beta = 0; // The nonlinearity parameter, in ADC^-1. Should be -ve
00124   Float_t dbeta = 0.; // The error on beta.
00125   Float_t maxadc = 0; // The max ADC value pulsed by the system
00126   Float_t meanres = lin; // Mean residual, in ADC counts.
00127   if(row) {
00128     beta = row->GetPar1();
00129     dbeta = row->GetPar2();
00130     maxadc = row->GetAdcMax();
00131     meanres = row->GetMeanRes();
00132   } else {
00133     if(fFitTable.GetNumRows()>0) {
00134       MAXMSG("Calib",Msg::kWarning,10) << "No CALPULSERFITS quadratic fit for " << seid.AsString() << endl;
00135       IncrementErrors(kLinCalibrator,kMissingRow,seid);
00136     }
00137   }
00138 
00139   if(fBucketMode) {
00140     beta /= fPulseToBucketCorrection;
00141     dbeta /= fPulseToBucketCorrection;
00142   }
00143 
00144   // Apply the nonlinearity correction.
00145 
00146   Float_t x   = lin.GetValue();
00147   Float_t err2 = lin.GetError2(); // error squared
00148   Float_t nonlin = x * (1.0 + x*beta);
00149   
00150   const float kMaxMeanRes = sqrt(std::numeric_limits<float>::max())*1e-6;
00151   if(meanres>kMaxMeanRes) meanres = kMaxMeanRes;
00152   if(x>2500) 
00153     err2 += meanres*meanres;
00154 
00155   if(x>maxadc) {
00156     // We're out of bounds. Apply an additional error
00157     // as the error on beta times the correction.
00158     IncrementErrors(kLinCalibrator,kBadInput,seid);
00159     Float_t temp = (lin-nonlin)*(dbeta);
00160     if(beta!=0) temp = temp/beta;
00161     err2 += temp*temp;
00162   }
00163 
00164 
00165   FloatErr retval;
00166   retval.SetValueError2(nonlin,err2);
00167   return retval;
00168 }
00169 
00170 //......................................................................
00171 
00172 void QuadLinearityCalScheme::ConfigModified() 
00173 {
00174   Bool_t ok = true;
00175   ok = ok& GetConfig().Get("PulseToBucketCorrection",fPulseToBucketCorrection);
00176   ok = ok& GetConfig().Get("BucketMode",fBucketMode);
00177   if(!ok) MSG("Calib",Msg::kError) << "QuadLinearityCalScheme has a configration problem!" << endl;
00178 }
00179 
00180 //......................................................................
00181 //
00182 void QuadLinearityCalScheme::PrintConfig( std::ostream& os ) const
00183 {
00184   os << "  Calibration mode:           ";
00185   if(fBucketMode) os << "Bucket-by-bucket" << endl;
00186   else            os << "Total Pulseheight" << endl;
00187   os << "  Pulse-to-Bucket correction: " << fPulseToBucketCorrection << endl; 
00188 }
00189 
00190 //......................................................................
00191 
00192 void QuadLinearityCalScheme::DoReset(const VldContext& vc)
00193 {
00194   // Check validity.
00195   if(vc.GetDetector() != Detector::kNear) {
00196     MAXMSG("Calib",Msg::kWarning,10) << "** WARNING: You are using the QuadLinearityCalScheme " << endl;
00197     MAXMSG("Calib",Msg::kWarning,10) << "** on non-Near data. This will not correctly calibrate your data." << endl;
00198     MAXMSG("Calib",Msg::kWarning,10) << "** Try: Calibrator::Instance().Set(\"LinCalibrator=PulserLinearityCalScheme\");" << endl;
00199   }
00200   // Requery table.
00201   fFitTable.NewQuery(vc,kFitType);
00202 
00203   if(fFitTable.GetNumRows()==0) {
00204     MAXMSG("Calib",Msg::kWarning,10)
00205       << "No data in CALPULSERFITS task " << kFitType << " vc = " << vc.AsString() << endl;
00206     IncrementErrors(kLinCalibrator,kMissingTable);
00207   }
00208 
00209    
00210 }
00211 //......................................................................

Generated on Mon Feb 15 11:07:27 2010 for loon by  doxygen 1.3.9.1