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

PulserDriftCalScheme.cxx

Go to the documentation of this file.
00001 
00002 // $Id: PulserDriftCalScheme.cxx,v 1.18 2006/06/15 01:57:48 rhatcher Exp $
00003 //
00004 // Calibrator for new PulserCalibration drift correction
00005 //
00006 // pa@hep.ucl.ac.uk
00007 //
00008 // $Log: PulserDriftCalScheme.cxx,v $
00009 // Revision 1.18  2006/06/15 01:57:48  rhatcher
00010 // Initialize all elements of the "Drift" struct after creating it, not all
00011 // paths through the code set each element.
00012 //
00013 // Revision 1.17  2006/04/19 18:50:38  rhatcher
00014 // Change DetectorType:: to Detector:: everywhere.
00015 //
00016 // Revision 1.16  2006/01/26 10:28:13  cpw1
00017 // Fix for new CALPULSERFITS
00018 //
00019 // Revision 1.15  2006/01/25 17:31:45  rhatcher
00020 // In FitIsOK() comment out line using CalPulserFit::GetNumPoints() because
00021 // that method not longer exists for CalPulserFit.
00022 //
00023 // Revision 1.14  2006/01/25 13:48:33  cpw1
00024 // Use zero-corrected values and implement checks on fits
00025 //
00026 // Revision 1.13  2005/09/28 09:30:23  cpw1
00027 // Add option to use CalPulserFits method
00028 //
00029 // Revision 1.12  2005/05/13 18:07:14  tagg
00030 // Make a few warnings MAXMSG from MSG.
00031 //
00032 // Revision 1.11  2005/04/09 10:33:42  hartnell
00033 //
00034 // Get rid of "Only 343 entries for..." messages here too.
00035 //
00036 // Revision 1.10  2005/03/22 12:37:04  tagg
00037 // Set up to use errors system.
00038 //
00039 // Applies a 50% error if no drift data can be found.
00040 // Does NOT apply any error associated with drift point; I'm not yet
00041 // confident enough in Phil's code to figure this out.
00042 //
00043 // Tidy up code so to remove redundant call level.
00044 //
00045 // Revision 1.9  2005/02/01 17:33:17  tagg
00046 // Very cosmetic changes to code to get working with gcc 3.4. Mostly
00047 // extra top-level semicolons (what a drag!) and getting CVSID in the
00048 // right place (i.e. before #including DbiResultPtr.tpl)
00049 //
00050 // Revision 1.8  2005/01/28 20:21:00  cbs
00051 // Removed the 2 hour time lag in GetTemperature() for CalDet.
00052 // Fixed a bug in the CalDet2003Check() functions in Pulser*CalScheme.cxx
00053 // Commented out the CalDet2003Check() and the check that the channel is of
00054 // type VA before applying the temperature calibration in the
00055 // Pulser*CalScheme::ApplyCalib() and Pulser*CalScheme::InverseCalib().
00056 // The VA check needs to go back in if temperature calibrations are ever
00057 // switched on for Near, Far detectors.
00058 //
00059 // Revision 1.7  2004/12/07 15:38:35  cbs
00060 // VA temperature correction now gets applied to QIE hits during
00061 // CalDet 2003 N/F running
00062 //
00063 // Revision 1.6  2004/12/06 18:17:07  cbs
00064 // Fixed a small mistake in the application of the temperature correction
00065 //
00066 // Revision 1.5  2004/12/06 15:27:25  cbs
00067 // Added code to Drift/SigLin CalSchemes to perform a temperature correction
00068 // to the siglin values. A correction factor of 0.22% / degree C is applied
00069 // to all hits from VA channels. The reference temperature is 18 degC.
00070 //
00071 // Modified the existing temperature correction in StripToStripCalScheme.
00072 // A factor of 0.08% / degree C is applied to all hits from all channels to
00073 // correct for residual measured changes in response at CalDet after the
00074 // VA dependence had been removed.
00075 //
00076 // The code uses GetTemperature() to get the current temperature.
00077 //
00078 // Revision 1.4  2004/11/15 18:52:19  phil.adamson
00079 // If we can't calibrate a strip, try a nearby one.
00080 //
00081 // Revision 1.3  2004/11/04 23:21:12  phil.adamson
00082 // Fix stupid error
00083 //
00084 // Revision 1.2  2004/11/04 22:17:37  phil.adamson
00085 // Minor fix for new calib
00086 //
00087 // Revision 1.1  2004/11/04 04:46:53  phil.adamson
00088 // New for new LI calib
00089 //
00091 #include "Calibrator/PulserDriftCalScheme.h"
00092 #include "Calibrator.h"
00093 #include "MessageService/MsgService.h"
00094 #include "Plex/PlexSEIdAltL.h"
00095 #include "Plex/PlexStripEndId.h"
00096 #include "Plex/PlexPinDiodeId.h"
00097 #include "Plex/PlexHandle.h"
00098 #include "DatabaseInterface/DbiValidityRec.h"
00099 #include "Validity/VldRange.h"
00100 #include "Validity/VldTimeStamp.h"
00101 #include "PulserCalibration/PulserConventions.h"
00102 #include "PulserCalibration/PulserPinScale.h"
00103 #include "PulserCalibration/PulserXScale.h"
00104 
00105 ClassImp(PulserDriftCalScheme)
00106 CVSID("$Id: PulserDriftCalScheme.cxx,v 1.18 2006/06/15 01:57:48 rhatcher Exp $");
00107 
00108 
00109 //......................................................................
00110 PulserDriftCalScheme::PulserDriftCalScheme(): fPlex(0)
00111 {
00112    MSG("Calib",Msg::kVerbose) 
00113      << "PulserDriftCalScheme::PulserDriftCalScheme" 
00114      << endl;
00115 
00116    Registry r;
00117    r.Set("CalMode",0);
00118    r.Set("MinNumPulses",500);
00119    r.Set("VATemperatureCalibration","off");
00120    InitializeConfig(r);
00121 
00122    fRefTemp = 18.0; //reference temperature
00123    fVATempCorFactor = -0.0022; //frac diff in VA electronics response with temp
00124 
00125 }
00126 
00127 //......................................................................
00128 void PulserDriftCalScheme::DoReset( const VldContext& vc )
00129 {
00133    // Reference tables should be for fixed context
00134    VldTimeStamp ts(2005,6,2,0,0,0);
00135    VldContext ref(vc.GetDetector(),vc.GetSimFlag(),ts);
00136    fXScale.NewQuery(ref,Pulser::kNearEnd);
00137    fFarXScale.NewQuery(ref,Pulser::kFarEnd);
00138    fPinScale.NewQuery(ref,0);
00139    fNearLow.NewQuery(ref,Pulser::kNearLow);
00140    fFarLow.NewQuery(ref,Pulser::kFarLow);
00141    fNearHigh.NewQuery(ref,Pulser::kNearHigh);
00142    fFarHigh.NewQuery(ref,Pulser::kFarHigh);
00143    fNearFar.NewQuery(ref,Pulser::kNearFar);
00144 
00145    // Drift values
00146    fNearDrift.NewQuery(vc,Pulser::kNearEnd);
00147    fFarDrift.NewQuery(vc,Pulser::kFarEnd);
00148    fPinDrift.NewQuery(vc,Pulser::kNearEnd);
00149    if (fPlex) delete fPlex;
00150    fPlex = new PlexHandle(vc);
00151   
00152    // Don't bother with warning messages, but do increment errors.
00153 
00154   if(fXScale.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00155   if(fFarXScale.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00156   if(fNearLow.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00157   if(fFarLow.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00158   if(fNearHigh.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00159   if(fFarHigh.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00160   if(fNearFar.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00161   if(fNearDrift.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00162   if(fFarDrift.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00163   if(fPinDrift.GetNumRows()<=0) IncrementErrors(kDriftCalibrator,kMissingTable);
00164 }
00165 
00166 //......................................................................
00167 void PulserDriftCalScheme::ConfigModified()
00168 {
00169   
00170   const char* str_tempcal;
00171 
00172   bool ok = true;
00173   ok = ok && GetConfig().Get("CalMode",     fCalMode);
00174   ok = ok && GetConfig().Get("MinNumPulses",fMinNumPulses);
00175   ok = ok && GetConfig().Get("VATemperatureCalibration",str_tempcal);
00176   if(!ok) MSG("Calib",Msg::kWarning) << "PulserDriftCalibrator "
00177                                           << " Problem when configuring. " <<endl;
00178   
00179   // Interpret strings.
00180   if(strcasecmp(str_tempcal,"on")==0) fDoTempCal = true;
00181   else fDoTempCal = false;
00182 
00183 }
00184 //......................................................................
00185 void PulserDriftCalScheme::PrintConfig( std::ostream& os ) const
00186 {
00187   os << "  CalMode:      " << fCalMode << endl;
00188   os << "  MinNumPulses: " << fMinNumPulses << endl;
00189   os << "  VA Temperature calibration is " << ((fDoTempCal)?"on":"off") << endl;
00190   if(fDoTempCal) {
00191     os << "  VA Temp Correction Factor = 1 / [ 1 - " 
00192        << fVATempCorFactor << "*(" 
00193        << fRefTemp << " - temp) ]" << endl;
00194   }
00195 }
00196 
00197 
00198 //......................................................................
00199 FloatErr  PulserDriftCalScheme::GetDriftCorrected(FloatErr rawcharge, 
00200                                            const PlexStripEndId& seid) const
00201 {
00210 
00211   //check for VA temperature correction and that channel is VA:
00212   float tempCor = 1.0;
00213   if(fPlex && fDoTempCal) {    
00214     //if(fPlex->GetRawChannelId(seid).GetElecType()==ElecType::kVA ||
00215     // this->CalDet2003Check())
00216     tempCor = GetVATemperatureCorrection();
00217   }
00218 
00219   // Drift correction = "xscale" * driftPIN/driftADC
00220   // where xscale is our calibration base, and looks like ADC/PIN
00221   // and comes from the slope of the first gaincurve at the low end.
00222 
00223   Drift d = GetDriftPoint(seid);
00224   if (d.adc > 0) {
00225     Float_t value = rawcharge * (float)( d.xscale * d.pin/d.adc * tempCor);
00226     Float_t error2 = (float) (d.erradc * d.erradc / (d.adc * d.adc));
00227     if ( d.pin > 0) {error2+= d.errpin*d.errpin/(d.pin*d.pin);}
00228     if ( d.xscale > 0) {error2 += d.errxscale*d.errxscale/(d.xscale*d.xscale);}
00229     return FloatErr(value,value*sqrt(error2));
00230   }
00231   else {
00232     // Go through other stripends sharing this pixel spot
00233     PlexSEIdAltL altlist = fPlex->GetSEIdAltL(fPlex->GetRawChannelId(seid));
00234     for (PlexSEIdAltL::const_iterator it = altlist.begin();
00235          it!=altlist.end();it++) {
00236       Drift d = GetDriftPoint((*it).GetSEId());
00237       if (d.adc > 0) {
00238         MAXMSG("Calib",Msg::kWarning,20) 
00239           << "Using stripend "<<(*it).GetSEId()<<" to calibrate "<<seid<<endl;
00240       Float_t value = rawcharge * (float)( d.xscale * d.pin/d.adc * tempCor);
00241       Float_t error2 = (float) (d.erradc * d.erradc / (d.adc * d.adc));
00242       if ( d.pin > 0) {error2+= d.errpin*d.errpin/(d.pin*d.pin);}
00243       if ( d.xscale > 0) {error2 += d.errxscale*d.errxscale/(d.xscale*d.xscale);}
00244       return FloatErr(value,value*sqrt(error2));
00245       }
00246     }
00247   }
00248 
00249   // Try other strips on same plane for Anatael.
00250 
00251   int numstrips = seid.NumberOfStrips();
00252   PlexStripEndId otherstrip = seid;
00253   for (int n = 0; n< numstrips; n++) {
00254     otherstrip.SetStrip(n);
00255     Drift d = GetDriftPoint(otherstrip);
00256     if (d.adc > 0) {
00257       Float_t value = rawcharge * (float)( d.xscale * d.pin/d.adc * tempCor);
00258       Float_t error2 = (float) (d.erradc * d.erradc / (d.adc * d.adc));
00259       if ( d.pin > 0) {error2+= d.errpin*d.errpin/(d.pin*d.pin);}
00260       if ( d.xscale > 0) {error2 += d.errxscale*d.errxscale/(d.xscale*d.xscale);}
00261       return FloatErr(value,value*sqrt(error2));
00262     }
00263   }
00264 
00265   MAXMSG("Calib",Msg::kWarning,20) 
00266     << "No drift point for  StripEnd " << seid.AsString()
00267     << " so NOT CALIBRATING THIS CHANNEL\n";
00268   
00269   IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00270   FloatErr result = rawcharge * tempCor;
00271   result*=FloatErr(1,0.5); // Add another 50% error.
00272   return result;
00273 }   
00274 
00275 
00276 FloatErr PulserDriftCalScheme::DecalDrift(FloatErr undrifted, 
00277                                           const PlexStripEndId& seid) const
00278 {
00279 
00280   //check for temperature correction:
00281   float tempCor = 1.0;
00282   if(fPlex && fDoTempCal) {    
00283     //if(fPlex->GetRawChannelId(seid).GetElecType()==ElecType::kVA ||
00284     // this->CalDet2003Check())       
00285     tempCor = GetVATemperatureCorrection();
00286   }
00287 
00288   // Drift correction = "xscale" * driftPIN/driftADC
00289   // where xscale is our calibration base, and looks like ADC/PIN
00290   // and comes from the slope of the first gaincurve at the low end.
00291   
00292   Drift d = GetDriftPoint(seid);
00293   if (d.adc > 0) {
00294     return undrifted * (float)((1.0/d.xscale) * (d.adc/d.pin) / tempCor); // FIXME: No error returned
00295   }
00296   else {
00297     // Go through other stripends sharing this pixel spot
00298     PlexSEIdAltL altlist = fPlex->GetSEIdAltL(fPlex->GetRawChannelId(seid));
00299     for (PlexSEIdAltL::const_iterator it = altlist.begin();
00300          it!=altlist.end();it++) {
00301       Drift d = GetDriftPoint((*it).GetSEId());
00302       if (d.adc > 0) {
00303         MAXMSG("Calib",Msg::kWarning,20) 
00304           << "Using stripend "<<(*it).GetSEId()<<" to uncalibrate "<<seid<<endl;
00305         return undrifted * (float)((1.0/d.xscale) * (d.adc/d.pin) / tempCor); // FIXME: No error returned
00306       }
00307       
00308     }
00309   }
00310   
00311   MAXMSG("Calib",Msg::kWarning,20) 
00312     << "No drift point for  StripEnd " << seid.AsString()
00313     << " so NOT UNCALIBRATING THIS CHANNEL\n";
00314   
00315   IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00316   FloatErr result = undrifted / tempCor;
00317   result *= FloatErr(1,0.5); // Add 50% error
00318   return result;
00319 }   
00320 
00321 
00322 
00323 FloatErr PulserDriftCalScheme::GetDriftPinDiodeValue(PlexLedId ledid, Int_t highOrLow) const
00324 {
00336 
00337    PlexHandle ph(GetContext());
00338    std::pair<PlexPinDiodeId,PlexPinDiodeId> myPins = 
00339       ph.GetPinDiodeIds(ledid); // NB first = low, second = high
00340    
00341    if(highOrLow==0) {//high ==0  low ==1
00342      const PulserDriftPin *highpin =fPinDrift.GetRowByIndex(myPins.second.GetEncoded());
00343      if(highpin==0) {
00344        MSG("Calib",Msg::kWarning) 
00345           << "No Drift Point database row for Pin " << myPins.second 
00346           << " (indexed as " << myPins.second.GetEncoded() << " there are "
00347           << fPinDrift.GetNumRows() << " rows\n.";
00348        IncrementErrors(kDriftCalibrator,kMissingRow,ledid);
00349        return -1;
00350      }  
00351      else {
00352        MSG("Calib",Msg::kDebug) 
00353           << "Got Drift Point database row for Pin " << myPins.second 
00354           << " (indexed as " << myPins.second.GetEncoded() << " )\n";
00355        if(highpin->GetNumEntries()<fMinNumPulses) {
00356         MSG("Calib",Msg::kWarning) 
00357            << "Only " << highpin->GetNumEntries() << " entries for  " 
00358            << myPins.second 
00359            << " (indexed as " << myPins.first.GetEncoded() << " )" << endl;
00360         return -1;
00361        }
00362        Float_t value = highpin->ZCMean();
00363        Float_t error = highpin->ZCError();
00364        return FloatErr(value,error);
00365        //       return FloatErr(highpin->ZCMean(),highpin->ZCError());
00366      }
00367    }
00368    else if(highOrLow==1) { //low gain pin 
00369      const PulserDriftPin *lowpin =fPinDrift.GetRowByIndex(myPins.first.GetEncoded());
00370      if(lowpin==0) {
00371        MSG("Calib",Msg::kWarning) 
00372           << "No Drift Point database row for Pin " << myPins.first
00373           << " (indexed as " << myPins.first.GetEncoded() << " )\n";
00374        return -1;
00375      }  
00376      else {
00377        MSG("Calib",Msg::kDebug) 
00378           << "Got Drift Point database row for Pin " << myPins.first 
00379           << " (indexed as " << myPins.first.GetEncoded() << " )\n";
00380        if(lowpin->GetNumEntries()<fMinNumPulses) {
00381          MSG("Calib",Msg::kWarning) 
00382             << "Only " << lowpin->GetNumEntries() << " entries for  " 
00383             << myPins.first
00384             << " (indexed as " << myPins.first.GetEncoded() << " )" << endl;
00385          return -1;
00386        }
00387        return FloatErr(lowpin->ZCMean(),lowpin->ZCError());
00388      }
00389    }           
00390    
00391    return -1;
00392 }
00393 
00394 //......................................................................
00395 
00396 
00397 
00398 
00399 PulserDriftCalScheme::Drift 
00400   PulserDriftCalScheme::GetDriftPoint(PlexStripEndId seid) const
00401 {
00402   Drift drift;
00403   drift.adc = drift.pin = drift.xscale = drift.erradc = 
00404     drift.errpin = drift.errxscale = 0;  // initialize values in struct
00405 
00406   // First find drift data for strip
00407   
00408   const PulserDrift *neardrift =
00409     fNearDrift.GetRowByIndex(seid.BuildPlnStripEndKey());
00410   if(neardrift==0) {
00411     MAXMSG("Calib",Msg::kWarning,20) 
00412       << "No Near Drift Point database row for StripEnd " << seid 
00413       << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00414     IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00415     return GetDriftFar(seid);
00416   }
00417   MSG("Calib",Msg::kDebug) 
00418     << "Got Near Drift row for StripEnd " << seid 
00419     << " (indexed as " << seid.BuildPlnStripEndKey() << " )"
00420     << " aggregate. " << neardrift->GetAggregateNo() << endl;
00421 
00422 
00423   if(neardrift->GetNumEntries()<fMinNumPulses) {
00424     MAXMSG("Calib",Msg::kWarning,20) 
00425       << "Only " << neardrift->GetNumEntries() << " entries for  " 
00426       << seid
00427       << " (indexed as " << seid.BuildPlnStripEndKey() << " )" << endl;
00428     IncrementErrors(kDriftCalibrator,kDataInsufficient,seid);
00429     return GetDriftFar(seid);
00430   }
00431 
00432   drift.adc = neardrift->ZCMean();
00433   drift.erradc = neardrift->ZCError();
00434   if (drift.adc<1) return GetDriftFar(seid);
00435   if (drift.adc>8000) {
00436     // If the near side has a big number, try to use the far side.
00437     // If the far side doesn't have data, we'll have to use the near side, 
00438     // even though it's a big number.
00439        Drift fardrift = GetDriftFar(seid);
00440           if (fardrift.adc>0) return fardrift;
00441   }
00442   
00443   // Now need to get PIN info
00444 
00445   PlexLedId veryTempLedId = PlexLedId(neardrift->GetAggregateNo());
00446   PlexLedId tempLedId = PlexLedId(GetContext().GetDetector(),
00447                                   veryTempLedId.GetPulserBox(),
00448                                   veryTempLedId.GetLedInBox());
00449  
00450   FloatErr highpin=GetDriftPinDiodeValue(tempLedId, 0); // high gain
00451   FloatErr lowpin=GetDriftPinDiodeValue(tempLedId, 1); // low gain
00452 
00453   // Phil's scheme: use both pins and PulserXscale table
00454   if (fCalMode == 0 ) {
00455     const PulserPinScale *pinscale = fPinScale.GetRowByIndex(neardrift->GetAggregateNo());
00456     if (pinscale==0) {
00457       MAXMSG("Calib",Msg::kWarning,50) 
00458        << "No PinScale database row for StripEnd " 
00459        << seid 
00460        << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00461      IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00462      return GetDriftFar(seid);
00463     }  
00464     MSG("Calib",Msg::kDebug) 
00465       << "Got PinScale row for " 
00466       << " aggregate. " << pinscale->GetAggregateNo() << endl;
00467   
00468     drift.pin = pinscale->ScalePins(highpin.GetValue(),lowpin.GetValue());
00469     if (drift.pin < 0) return GetDriftFar(seid);
00470 
00471     const PulserXScale *xscale = 
00472       fXScale.GetRowByIndex(seid.BuildPlnStripEndKey());
00473     if(xscale==0) {
00474       MSG("Calib",Msg::kWarning) 
00475         << "No XScale database row for StripEnd " 
00476         << seid 
00477         << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00478       IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00479       return GetDriftFar(seid);
00480     }  
00481     MSG("Calib",Msg::kDebug) 
00482       << "Got XScale row for StripEnd " << seid 
00483       << " (indexed as " << seid.BuildPlnStripEndKey() << " )"
00484       << " aggregate. " << xscale->GetAggregateNo() << endl;
00485 
00486     drift.xscale = xscale->GetXScale();
00487     return drift; 
00488   }
00489 
00490   // Pat's scheme: use CalPulserFits table and high gain pin for preference
00491   else {
00492     // Check high-gain pin
00493     if(highpin.GetValue() > 100.) {
00494       const CalPulserFits *fitptrh = 
00495          fNearHigh.GetRowByIndex(seid.BuildPlnStripEndKey());
00496       // Check fit
00497       if(fitptrh!=0) {
00498         if(FitIsOK(*fitptrh)) {
00499           MSG("Calib",Msg::kDebug) 
00500             << "Good CalPulserFits Near-High row for StripEnd " << seid 
00501             << " (indexed as " << seid.BuildPlnStripEndKey() << " )"
00502             << " aggregate " << fitptrh->GetAggregateNo() << endl;
00503           drift.pin = highpin.GetValue();
00504           drift.errpin = highpin.GetError();
00505           drift.xscale = fitptrh->GetSlope();
00506           drift.errxscale = fitptrh->GetSlopeErr();
00507           return drift;
00508         }
00509       }
00510       if(fitptrh==0) {
00511         MSG("Calib",Msg::kWarning) 
00512           << "No CalPulserFits Near-High database row for StripEnd " 
00513           << seid 
00514           << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00515         IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00516       }
00517     }
00518     // Near-high no good: use far in preference to low-gain pin
00519     Drift fardrift = GetDriftFar(seid);
00520     if(fardrift.adc > 0) {return fardrift;}
00521     // Far no good, so try low-gain pin
00522     if(lowpin.GetValue() > 100.) {
00523       const CalPulserFits *fitptrl = 
00524          fNearLow.GetRowByIndex(seid.BuildPlnStripEndKey());
00525       // Check fit
00526       if(fitptrl!=0) {
00527         if(FitIsOK(*fitptrl)) {
00528           MSG("Calib",Msg::kInfo) 
00529             << "Good CalPulserFits Near-Low row for StripEnd " << seid 
00530             << " (indexed as " << seid.BuildPlnStripEndKey() << " )"
00531             << " aggregate " << fitptrl->GetAggregateNo() << endl;
00532           drift.pin = lowpin.GetValue();
00533           drift.errpin = lowpin.GetError();
00534           drift.xscale = fitptrl->GetSlope();
00535           drift.errxscale = fitptrl->GetSlopeErr();
00536           return drift;
00537         }
00538       }
00539       if(fitptrl==0) {
00540         MSG("Calib",Msg::kWarning) 
00541           << "No CalPulserFits Near-Low database row for StripEnd " 
00542           << seid 
00543           << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00544         IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00545       }
00546     }
00547     // If we get to here we have failed to find good data
00548     return DriftZero();
00549   }
00550 
00551 }  
00552 
00553 
00554 PulserDriftCalScheme::Drift PulserDriftCalScheme::GetDriftFar(PlexStripEndId seid) const
00555 {
00556   // Return drift point bits using the far end, or zeros if we can't manage it
00557   Drift drift;
00558   drift.adc = drift.pin = drift.xscale = drift.erradc = 
00559     drift.errpin = drift.errxscale = 0;  // initialize values in struct
00560 
00561    const PulserDrift *fardrift =
00562      fFarDrift.GetRowByIndex(seid.BuildPlnStripEndKey());
00563    
00564    if(fardrift==0) {
00565      MAXMSG("Calib",Msg::kWarning,20) 
00566        << "No Far Drift Point database row for StripEnd " << seid 
00567        << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00568      IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00569      return DriftZero();
00570    }
00571    MSG("Calib",Msg::kDebug) 
00572      << "Got Far Drift row for StripEnd " << seid 
00573      << " (indexed as " << seid.BuildPlnStripEndKey() << " )"
00574      << " aggregate. " << fardrift->GetAggregateNo() << endl;
00575    if(fardrift->GetNumEntries()<fMinNumPulses) {
00576      MAXMSG("Calib",Msg::kWarning,20) 
00577        << "Only " << fardrift->GetNumEntries() << " entries for  " 
00578        << seid
00579        << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00580      IncrementErrors(kDriftCalibrator,kDataInsufficient,seid);
00581      return DriftZero();
00582    }
00583 
00584    drift.adc = fardrift->ZCMean();
00585    drift.erradc = fardrift->ZCError();
00586    if (drift.adc < 1) return DriftZero();
00587 
00588    PlexLedId veryTempLedId = PlexLedId(fardrift->GetAggregateNo());
00589    PlexLedId tempLedId = PlexLedId(GetContext().GetDetector(),
00590                                    veryTempLedId.GetPulserBox(),
00591                                    veryTempLedId.GetLedInBox());
00592 
00593   //Now need to get PIN info.
00594 
00595   FloatErr highpin=GetDriftPinDiodeValue(tempLedId, 0); // high gain
00596   FloatErr lowpin=GetDriftPinDiodeValue(tempLedId, 1); // low gain
00597 
00598   // Phil's scheme using both pins
00599   if(fCalMode == 0) {
00600     const PulserPinScale *pinscale = fPinScale.GetRowByIndex(fardrift->GetAggregateNo());
00601     if (pinscale==0) {
00602       MAXMSG("Calib",Msg::kWarning,50) 
00603        << "No PinScale database row for StripEnd " 
00604        << seid 
00605        << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00606      IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00607      return DriftZero();
00608     }  
00609     MSG("Calib",Msg::kDebug) 
00610       << "Got PinScale row for " 
00611       << " aggregate. " << pinscale->GetAggregateNo() << endl;
00612   
00613     drift.pin = pinscale->ScalePins(highpin.GetValue(),lowpin.GetValue());
00614     if (drift.pin < 0) return DriftZero();
00615 
00616      const PulserXScale *xscale = 
00617        fFarXScale.GetRowByIndex(seid.BuildPlnStripEndKey());
00618      if(xscale==0) {
00619        MSG("Calib",Msg::kWarning) 
00620          << "No Far XScale database row for StripEnd " 
00621          << seid 
00622          << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00623        IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00624        return DriftZero();
00625      }  
00626      MSG("Calib",Msg::kDebug) 
00627        << "Got XScale row for StripEnd " << seid 
00628        << " (indexed as " << seid.BuildPlnStripEndKey() << " )"
00629        << " aggregate. " << xscale->GetAggregateNo() << endl;
00630 
00631      drift.xscale = xscale->GetXScale();
00632      return drift;
00633   }
00634   else {
00635     // Pat's scheme using CalPulserFits
00636     // Check for good high-gain pin
00637     if(highpin.GetValue() > 100.) {
00638       const CalPulserFits *fitptrh = 
00639          fFarHigh.GetRowByIndex(seid.BuildPlnStripEndKey());
00640       // Check for good fit
00641       if(fitptrh!=0) {
00642         if(FitIsOK(*fitptrh)) {
00643           MSG("Calib",Msg::kInfo) 
00644           << "Good CalPulserFits Far-High row for StripEnd " << seid 
00645           << " (indexed as " << seid.BuildPlnStripEndKey() << " )"
00646           << " aggregate " << fitptrh->GetAggregateNo() << endl;
00647           drift.pin = highpin.GetValue();
00648           drift.errpin = highpin.GetError();
00649           drift.xscale = fitptrh->GetSlope();
00650           drift.errxscale = fitptrh->GetSlopeErr();
00651           return drift;
00652         }
00653       }
00654       if(fitptrh==0) {
00655          MSG("Calib",Msg::kWarning) 
00656            << "No CalPulserFits Far-High database row for StripEnd " 
00657            << seid 
00658            << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00659          IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00660       }
00661     }
00662     // If we get to here, need to use low-gain pin
00663     if(lowpin.GetValue() > 100.) {
00664       const CalPulserFits *fitptrl = 
00665          fFarLow.GetRowByIndex(seid.BuildPlnStripEndKey());
00666       // Check for good fit
00667       if(fitptrl!=0) {
00668         if(FitIsOK(*fitptrl)) {
00669           MSG("Calib",Msg::kInfo) 
00670             << "Good CalPulserFits Far-Low row for StripEnd " << seid 
00671             << " (indexed as " << seid.BuildPlnStripEndKey() << " )"
00672             << " aggregate " << fitptrl->GetAggregateNo() << endl;
00673           drift.pin = lowpin.GetValue();
00674           drift.errpin = lowpin.GetError();
00675           drift.xscale = fitptrl->GetSlope();
00676           drift.errxscale = fitptrl->GetSlopeErr();
00677           return drift;
00678         }
00679       }
00680       if(fitptrl==0) {
00681         MSG("Calib",Msg::kWarning) 
00682           << "No CalPulserFits Far-Low database row for StripEnd " 
00683           << seid 
00684           << " (indexed as " << seid.BuildPlnStripEndKey() << " )\n";
00685           IncrementErrors(kDriftCalibrator,kMissingRow,seid);
00686       }
00687     }
00688     // If we get here nothing is good
00689     return DriftZero();    
00690   }
00691 }
00692 
00693 PulserDriftCalScheme::Drift PulserDriftCalScheme::DriftZero() const
00694 {
00695   Drift d;
00696   d.adc = 0;
00697   d.pin = 0;
00698   d.xscale = 0;
00699   d.erradc = 0;
00700   d.errpin = 0;
00701   d.errxscale = 0;
00702   return d;
00703 }
00704 
00705 //......................................................................
00706 Float_t PulserDriftCalScheme::GetVATemperatureCorrection() const
00707 {
00708   //======================================================================
00709   // Purpose: Do VA temperature correction
00710   //======================================================================
00711   
00712   float temp = Calibrator::Instance().GetTemperature();
00713 
00714   float correction = 1 - fVATempCorFactor * (fRefTemp - temp);
00715   
00716   return 1./correction;
00717 
00718   MSG("Calib",Msg::kVerbose) << "Got Temperature Correction of: " 
00719                              << correction << endl;
00720 
00721 }
00722 
00723 //......................................................................
00724 Bool_t PulserDriftCalScheme::CalDet2003Check() const
00725 {
00726   const VldContext &vldc = GetContext();
00727   //is this CalDet:
00728   if(vldc.GetDetector()!=Detector::kCalDet) return false;
00729   //is this 2003:
00730   VldTimeStamp vldstart = VldTimeStamp(2003,8,22,0,0,0); //T7 Sept 2003 N/F
00731   VldTimeStamp vldend   = VldTimeStamp(2003,9,26,0,0,0); //Run Nums: 70000's
00732   if(vldc.GetTimeStamp()<vldstart) return false;
00733   if(vldc.GetTimeStamp()>=vldend) return false;
00734   //must be CalDet 2003
00735   return true;
00736 }
00737 //......................................................................
00738 Bool_t PulserDriftCalScheme::FitIsOK(const CalPulserFits& fit) const
00739 {
00740   if(fit.GetNPFit() < 3) return false;
00741   if(fit.GetChisq() < 0 || fit.GetChisq() > 100) return false;
00742   if(fit.GetSlope() == 0) return false;
00743   if(fit.GetSlopeErr()/fit.GetSlope() > 0.01) return false;
00744   return true;
00745 }

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