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

PmtDriftCalScheme.cxx

Go to the documentation of this file.
00001 
00002 // $Id: PmtDriftCalScheme.cxx,v 1.4 2006/04/19 18:50:38 rhatcher Exp $
00003 //
00004 // Calibrator for using even newer PMT-by-PMT drift correction.
00005 // Fast! Compact! Nubile!
00006 //
00007 // n.tagg1@physics.ox.ac.uk
00008 //
00009 //
00011 #include "Calibrator/PmtDriftCalScheme.h"
00012 #include "Calibrator.h"
00013 #include "MessageService/MsgService.h"
00014 #include "Plex/PlexHandle.h"
00015 #include "DatabaseInterface/DbiValidityRec.h"
00016 #include "Validity/VldRange.h"
00017 #include "Conventions/Munits.h"
00018 #include <math.h>
00019 
00020 ClassImp(PmtDriftCalScheme)
00021 CVSID("$Id: PmtDriftCalScheme.cxx,v 1.4 2006/04/19 18:50:38 rhatcher Exp $");
00022 
00023 
00024 //......................................................................
00025 PmtDriftCalScheme::PmtDriftCalScheme()
00026 {
00027    MSG("Calib",Msg::kVerbose) 
00028      << "PmtDriftCalScheme::PmtDriftCalScheme" 
00029      << endl;
00030 
00031    Registry r;
00032    r.Set("DoPixelCorrection",1);
00033    r.Set("Mode","PhotonStat");
00034    r.Set("ReferenceDate",20050101);
00035    r.Set("ReferenceTime",000010);
00036 
00037    InitializeConfig(r);
00038 }
00039 
00040 //......................................................................
00041 void PmtDriftCalScheme::ConfigModified()
00042 {
00043   const char* str_mode;
00044 
00045   int refdate;
00046   int reftime;
00047 
00048   bool ok = true;
00049   ok = ok && GetConfig().Get("DoPixelCorrection",fDoPixelCorrection);
00050   ok = ok && GetConfig().Get("ReferenceDate",refdate);
00051   ok = ok && GetConfig().Get("ReferenceTime",reftime);
00052   ok = ok && GetConfig().Get("Mode",str_mode);
00053   if(!ok) MSG("Calib",Msg::kWarning) << "PulserDriftCalibrator "
00054                                      << " Problem when configuring. " <<endl;
00055   
00056   // Interpret date.
00057   fReferenceTime = VldTimeStamp(refdate,reftime,0);
00058 
00059   // Interpret strings.
00060   if(strcasecmp(str_mode,"PhotonStat")==0) fTask = CalPmtDrift::kPhotonStat;
00061   else if(strcasecmp(str_mode,"PinDrift")==0) fTask = CalPmtDrift::kPinDrift;
00062   else {
00063     fTask = CalPmtDrift::kPhotonStat;
00064     MSG("Calib",Msg::kError) << "Could not interpret mode " << str_mode 
00065                              << ". Defaulting to PhotonStat." << std::endl;
00066   }
00067 
00068   // Ensure the DB has been fixed up.
00069   Reset(GetContext(),true);
00070 }
00071 
00072 //......................................................................
00073 void PmtDriftCalScheme::DoReset( const VldContext& vc )
00074 {
00078 
00080   // Build context for reference point.
00081   VldContext refContext(vc.GetDetector(),
00082                         vc.GetSimFlag(),
00083                         fReferenceTime);
00084 
00085 
00087   // Build context for prev, cur, and next drift points.
00088   // There IS a better way to do this, by querying the DB directly.
00089   // But that is time consuming and dificult.
00090   int pointInterval = (int)(3.0 * Munits::hour/Munits::second);;
00091   if(vc.GetDetector() == Detector::kNear) pointInterval = (int)(1.0*Munits::hour/Munits::second);
00092   
00093   VldContext driftVC[3];
00094   driftVC[0] = VldContext(vc.GetDetector(),
00095                           vc.GetSimFlag(),
00096                           vc.GetTimeStamp() - VldTimeStamp(pointInterval,0));
00097   driftVC[1] = vc;
00098   driftVC[2] = VldContext(vc.GetDetector(),
00099                           vc.GetSimFlag(),
00100                           vc.GetTimeStamp() + VldTimeStamp(pointInterval,0));
00101 
00102   
00104   // Actually get the tables. Note the order: 
00105   // it should work well with the L1 cache for
00106   // forward scanning.
00107   fRefDrift.NewQuery(refContext,fTask);
00108   fDrift[0].NewQuery(vc,fTask);
00109   fDrift[1].NewQuery(vc,fTask);
00110   fDrift[2].NewQuery(vc,fTask);
00111 
00112 
00113   // Error message: no reference rows.
00114   if(fRefDrift.GetNumRows() == 0) {
00115     IncrementErrors(kDriftCalibrator,kMissingTable);
00116     MAXMSG("Calib",Msg::kError,10) 
00117       << "No rows in CALPMTDRIFT reference table task=" << fTask
00118       << "  cx=" << refContext.AsString() << std::endl;
00119   }
00120   
00121   // Error message: no current rows.
00122   if(fDrift[1].GetNumRows() == 0) {
00123     IncrementErrors(kDriftCalibrator,kMissingTable);
00124     MAXMSG("Calib",Msg::kWarning,10) 
00125       << "No rows in CALPMTDRIFT table task=" << fTask
00126       << "  cx=" << vc.AsString() << std::endl;
00127   }
00128   
00129 }
00130 
00131 
00132 //......................................................................
00133 void PmtDriftCalScheme::PrintConfig( std::ostream& os ) const
00134 {
00135   os << " PMT Drift Scheme: " << endl;
00136   os << "  DoPixelCorrection: " << fDoPixelCorrection << endl;
00137   os << "  ReferenceTime:     " << fReferenceTime.AsString() << endl;
00138   os << "  Mode:              " << GetConfig().GetCharString("Mode")
00139      << " (task=" << fTask << ")" << endl;
00140 }
00141 
00142 
00143 //......................................................................
00144 FloatErr  PmtDriftCalScheme::GetDriftCorrected(FloatErr rawcharge, 
00145                                            const PlexStripEndId& seid) const
00146 {
00155 
00156   return rawcharge/GetDrift(seid);
00157 }
00158 
00159 //......................................................................
00160 FloatErr PmtDriftCalScheme::DecalDrift(FloatErr undrifted, 
00161                                        const PlexStripEndId& seid) const
00162 {
00171   return undrifted*GetDrift(seid);
00172 }
00173 
00174 //......................................................................
00175 FloatErr  PmtDriftCalScheme::GetDrift(const PlexStripEndId& seid ) const
00176 {
00183 
00184   FloatErr drift1 = GetDrift(seid,1);
00185 
00186   if(drift1 > 0.2 && drift1 < 5.0) // Sanity check!
00187     return drift1;
00188 
00189   // Ok, now we have a problem. Attempt to ignore this point, and use the surronding ones.
00190 
00191   FloatErr drift0 = GetDrift(seid,0);
00192   FloatErr drift2 = GetDrift(seid,2);
00193 
00194   FloatErr drift(0,0);
00195   float n = 0;
00196   if(drift0 > 0.2 && drift0 < 5.0) { drift+= drift0; n+=1; };
00197   if(drift2 > 0.2 && drift2 < 5.0) { drift+= drift2; n+=1; };
00198 
00199   if(n==0) {
00200     IncrementErrors(kDriftCalibrator,kDataInsufficient);
00201     return FloatErr(1,0.5); // Return 1 with a big error.
00202   }
00203 
00204   // Use 1 or 2 of the prev/next points, depending on how many are good.
00205   // Add a systematic error corresponding to the change from d0 to d2.
00206   drift /= n;
00207   drift *= FloatErr(1.0, fabs(drift0.GetValue() - drift2.GetValue())*0.5); 
00208 
00209   return drift;
00210 }
00211 
00212 
00213 //......................................................................
00214 FloatErr  PmtDriftCalScheme::GetDrift(const PlexStripEndId& seid, int whichContext) const
00215 {
00219   // Find the PMT.
00220   PlexHandle plex(GetContext());
00221   PlexPixelSpotId psid = plex.GetPixelSpotId(seid);
00222   
00223   UInt_t index = psid.GetUniquePmtEncodedValue();
00224   
00225   const CalPmtDrift* drift = fDrift[whichContext].GetRowByIndex(index);
00226   const CalPmtDrift* ref   = fRefDrift.GetRowByIndex(index);
00227 
00228   if(drift==0) {
00229     MAXMSG("Calib",Msg::kWarning,10) 
00230       << "No drift data for strip " << seid.AsString() 
00231       << " PMT " << psid.AsString("t")
00232       << " index " << index << endl;
00233       IncrementErrors(kDriftCalibrator,kMissingRow);
00234       return FloatErr(0.0,0.0); // Return 0 to trigger error.
00235   }
00236 
00237   if(ref==0) {
00238     MAXMSG("Calib",Msg::kError,10) 
00239       << "No reference drift data for strip " << seid.AsString() << " PMT " << psid.AsString()
00240       << " index " << index << endl;
00241       IncrementErrors(kDriftCalibrator,kMissingRow);
00242       return FloatErr(1.0,0.5); // Add 50% error. Don't attempt interpolation.
00243   }
00244   
00245   FloatErr gain   (drift->GetDrift(),drift->GetStatError());
00246   gain += FloatErr(0.0,              drift->GetSysError());
00247 
00248   FloatErr gref(ref->GetDrift()); // Set reference point to zero error; let the s2s deal with this.
00249 
00250   if((gain<=0) || (gref<=0)) {
00251     // One of the gains is faulty, so use the backup plan:
00252     IncrementErrors(kDriftCalibrator,kDataInsufficient);
00253     gain = FloatErr(drift->GetCrudeDrift(),drift->GetCrudeDrift()*0.25);
00254     gref = FloatErr(ref  ->GetCrudeDrift(),  ref->GetCrudeDrift()*0.25);
00255   }
00256 
00257   FloatErr relativeDrift = gain/gref;
00258 
00259   if(fDoPixelCorrection) relativeDrift *= GetPixelCorrection(psid);
00260   
00261   return relativeDrift;
00262 }   
00263 
00264 
00265 //.........................................................................
00266 FloatErr PmtDriftCalScheme::GetPixelCorrection(const PlexPixelSpotId& /*psid*/) const
00267 {
00268   //FloatErr peGain;
00269   //FloatErr width;
00270   //Calibrator::Instance().DecalGainAndWidth(peGain,width,psid);
00271   //Apply formula here:
00272   
00273   return FloatErr(1.0,0.0); // Default.
00274 }

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