#include <PulserLinearityCalScheme.h>
Inheritance diagram for PulserLinearityCalScheme:

Definition at line 28 of file PulserLinearityCalScheme.h.
| 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 | ( | ) |
| void PulserLinearityCalScheme::ConfigModified | ( | ) | [virtual] |
| 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] |
Int_t PulserLinearityCalScheme::fCalLin [private] |
Definition at line 58 of file PulserLinearityCalScheme.h.
Definition at line 63 of file PulserLinearityCalScheme.h.
Definition at line 69 of file PulserLinearityCalScheme.h.
Definition at line 68 of file PulserLinearityCalScheme.h.
Definition at line 70 of file PulserLinearityCalScheme.h.
Referenced by DecalLinFar(), DoReset(), GetLinFar(), and GetMeanCorrection().
Definition at line 62 of file PulserLinearityCalScheme.h.
Referenced by DecalLinNear(), DoReset(), and GetLinNear().
Definition at line 66 of file PulserLinearityCalScheme.h.
Referenced by DecalLinNear(), DoReset(), and GetLinNear().
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().
1.4.7