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

|
|
Definition at line 21 of file PulserLinearityCalScheme.cxx. References MSG. 00021 : fPlex(0) 00022 { 00023 00024 00025 MSG("Calib",Msg::kVerbose) << "PulserLinearityCalScheme::PulserLinearityCalScheme" 00026 << endl; 00027 Registry r; 00028 InitializeConfig(r); 00029 }
|
|
|
Definition at line 32 of file PulserLinearityCalScheme.cxx. 00033 {
00034 }
|
|
|
Reimplemented from CalScheme. Definition at line 669 of file PulserLinearityCalScheme.cxx. 00670 {
00671 }
|
|
||||||||||||
|
Inverse-calibration for use by Monte-Carlo Purpose: Apply nonlinearity function. Input: Linear charge expected from a perfect phototube, Strip end Output: Realistic charge after PMT and electronics nonlinearity Reimplemented from CalScheme. Definition at line 57 of file PulserLinearityCalScheme.cxx. References DecalLinFar(), DecalLinNear(), FloatErr, PlexPlaneId::GetDetector(), 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 }
|
|
||||||||||||
|
Definition at line 487 of file PulserLinearityCalScheme.cxx. References PlexStripEndId::BuildPlnStripEndKey(), FitIsOK(), FloatErr, fNearFar, CalPulserFits::GetAdcMax(), GetCorrected(), ValueErr< T >::GetError(), CalPulserFits::GetFitType(), GetMeanCorrection(), DbiResultPtr< T >::GetRowByIndex(), ValueErr< T >::GetValue(), PlexStripEndId::IsValid(), PlexPlaneId::IsVetoShield(), 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 }
|
|
||||||||||||
|
Inverse-calibration for use by Monte-Carlo Purpose: Apply nonlinearity function. Input: Linear charge expected from a perfect phototube, Strip end Output: Realistic charge after PMT and electronics nonlinearity Definition at line 246 of file PulserLinearityCalScheme.cxx. References PlexStripEndId::BuildPlnStripEndKey(), FloatErr, 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(), 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 }
|
|
|
Reimplemented from CalScheme. Definition at line 681 of file PulserLinearityCalScheme.cxx. References fNearFar, fNearGain, fNearHigh, fNearLow, fPin, fPlex, VldContext::GetDetector(), 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 }
|
|
|
Definition at line 639 of file PulserLinearityCalScheme.cxx. References 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 }
|
|
||||||||||||||||
|
Definition at line 553 of file PulserLinearityCalScheme.cxx. References CalVaLinearity::FitFunction(), FloatErr, 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 }
|
|
||||||||||||
|
Purpose: Apply linearity correction In: drifted-corrected or raw ADC, strip end Out: linearized adc (siglin) Must be implimented by: LinCalibrator Reimplemented from CalScheme. Definition at line 39 of file PulserLinearityCalScheme.cxx. References FloatErr, PlexPlaneId::GetDetector(), GetLinFar(), GetLinNear(), 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 }
|
|
||||||||||||
|
Definition at line 400 of file PulserLinearityCalScheme.cxx. References PlexStripEndId::BuildPlnStripEndKey(), FitIsOK(), FloatErr, fNearFar, CalPulserFits::GetAdcMax(), GetCorrected(), ValueErr< T >::GetError(), CalPulserFits::GetFitType(), GetMeanCorrection(), DbiResultPtr< T >::GetRowByIndex(), ValueErr< T >::GetValue(), PlexStripEndId::IsValid(), PlexPlaneId::IsVetoShield(), MAXMSG, PulserLinearityCalScheme::MeanCor::meancor, PulserLinearityCalScheme::MeanCor::nstrips, PulserLinearityCalScheme::MeanCor::rmscor, and ValueErr< T >::SetError(). 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 }
|
|
||||||||||||
|
Definition at line 82 of file PulserLinearityCalScheme.cxx. References PlexStripEndId::BuildPlnStripEndKey(), FloatErr, 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(), 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 }
|
|
||||||||||||||||
|
Definition at line 588 of file PulserLinearityCalScheme.cxx. References FitIsOK(), FloatErr, fNearFar, fPlex, CalPulserFits::GetAdcMax(), GetCorrected(), CalPulserFits::GetFitType(), 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 }
|
|
|
Return PinDiodeId given a StripEndId 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 }
|
|
|
Prints out the current configuration status Should be overridden by implimentation. Reimplemented from CalScheme. Definition at line 675 of file PulserLinearityCalScheme.cxx. 00676 {
00677 }
|
|
|
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 67 of file PulserLinearityCalScheme.h. Referenced by DoReset(). |
|
|
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(). |
|
|
Definition at line 60 of file PulserLinearityCalScheme.h. Referenced by DoReset(), GetMeanCorrection(), and GetPinDiodeId(). |
1.3.9.1