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

Generated on Fri Mar 28 15:38:22 2008 for loon by  doxygen 1.3.9.1