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

AlgDeMuxBeam Class Reference

#include <AlgDeMuxBeam.h>

Inheritance diagram for AlgDeMuxBeam:

AlgBase List of all members.

Public Member Functions

 AlgDeMuxBeam ()
virtual ~AlgDeMuxBeam ()
virtual void Trace (const char *c) const
virtual void RunAlg (AlgConfig &acd, CandHandle &ch, CandContext &cx)

Private Member Functions

void DeMuxFirstNPlanesTest (DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr)
void FindShowerWindowSolution (DmxPlaneItr &windowPlaneItr, Float_t cog, Int_t firstPlane, Int_t lastPlane)
void SetFirstNPlanes (DmxPlaneItr &planeItr, Float_t slope, Float_t intercept)
void SetMuonRegionWindow (DmxPlaneItr &planeItr, Float_t slope, Float_t intercept, bool setAll)
void SetShowerRegionWindow (DmxPlaneItr &planeItr, Float_t slope, Float_t intercept)
void UseShowerSlidingWindow (DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, DmxStatus *status)
void UseMuonSlidingWindow (DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, DmxStatus *status)
void UseReverseMuonSlidingWindow (DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, DmxStatus *status)
void RegionLinearFit (Float_t &slope, Float_t &intercept, Float_t &chiSqr, Float_t *x, Float_t *y, Float_t *sigma, Float_t *residual, Int_t numPoints)
void FindFitOverNPlanes (Float_t *x, Float_t *y, Float_t *sigma, Float_t *residual, Float_t &slope, Float_t &intercept, Int_t numPoints, Int_t *planeNum)
Float_t FindRegionMatedChargeFraction (DmxPlaneItr &validPlaneItr)
void ReconcileShowerAndMuonRegions (DmxPlaneItr &planeItr, CandDeMuxDigitHandleItr &cdhit)
void DeMuxFirstNPlanes (DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, CandDeMuxDigitHandleItr &cdhit)
Float_t FindDigitCoG (DmxPlaneItr &validPlaneItr, CandDeMuxDigitHandleItr &cdhit)
void FindFit (DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, Double_t &a1, Double_t &a2, Double_t &a3, Double_t &a4, Double_t &bestChi2, Int_t leverArm, Int_t *hypotheses)
void FindFitForHypothesisSet (DmxPlaneItr &planeItr, Double_t &prevChiSq, Double_t &a1, Double_t &a2, Double_t &a3, Double_t &a4, Int_t *hypotheses, Int_t leverArm)
Bool_t FindPlanesToDropFromFit (DmxPlaneItr &planeItr, Double_t a1, Double_t a2, Double_t a3, Double_t a4, Int_t leverArm)
void FindRMSOfPlanes (DmxPlaneItr &planeItr, Int_t leverArm, Int_t *hypsToUse, Float_t &cog, Float_t &rms)

Private Attributes

Float_t fFinalShowerRegionSlope
Float_t fFinalShowerRegionIntercept
Float_t fInitialMuonRegionSlope
Float_t fInitialMuonRegionIntercept
Float_t fDigitResetCut
Int_t fMaxBadResidual
Float_t fMaxResidual
Float_t fMaxMuonRemovalFraction
Int_t fMaxStripAdjustment
Int_t fMinMuonPlanesRequired
Float_t fMinMatedChargeFrac
Int_t fMuonPlanesInSet
Float_t fMuonSlopeLimit
Int_t fMuonStartPlaneNumber
Float_t fMuonStartPlaneZPos
Int_t fPlanesInSet
Int_t fStrayCut
Int_t fStrayPlanes
Int_t fNumberOfHypotheses
Float_t fShowerMuonTransverseDifference
VldContext fVldContext

Constructor & Destructor Documentation

AlgDeMuxBeam::AlgDeMuxBeam  ) 
 

Definition at line 71 of file AlgDeMuxBeam.cxx.

00071                            :
00072         fMaxResidual(0.1),
00073         fMaxMuonRemovalFraction(0.2),
00074         fMuonPlanesInSet(5),
00075         fMuonStartPlaneNumber(500),
00076         fStrayCut(12),
00077         fStrayPlanes(0)
00078 {
00079   //default constructor
00080 }

AlgDeMuxBeam::~AlgDeMuxBeam  )  [virtual]
 

Definition at line 84 of file AlgDeMuxBeam.cxx.

00085 {
00086 }


Member Function Documentation

void AlgDeMuxBeam::DeMuxFirstNPlanes DmxPlaneItr &  planeItr,
DmxPlaneItr &  validPlaneItr,
CandDeMuxDigitHandleItr &  cdhit
[private]
 

Definition at line 2007 of file AlgDeMuxBeam.cxx.

References FindFit(), DmxPlane::GetCoG(), DmxPlane::GetPlaneType(), DmxPlane::GetZPosition(), MSG, SetFirstNPlanes(), and DmxPlane::SetStrips().

02009 {
02010         
02011         Int_t hypsToUse[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ;
02012         Int_t leverArm = (Int_t)validPlaneItr.SizeSelect();
02013         if(leverArm > fPlanesInSet) leverArm = fPlanesInSet;
02014         //find the bounds for the first n planes
02015         
02016         MSG("AlgDeMuxBeam", Msg::kDebug) << "In DeMuxFirstNPlanes with lever arm = " 
02017                                                                 << leverArm << endl;
02018         
02019         //useA2 is the slope, useA1 is the intercept
02020         
02021         //variables to keep track of the best reconstruction
02022         Double_t useA1 = -10000.;
02023         Double_t useA2 = -10000.;
02024         Double_t useA3 = -10000.;
02025         Double_t useA4 = -10000.;
02026         Double_t bestChi2 = 1.e20;
02027         
02028         cdhit.ResetFirst();
02029         validPlaneItr.ResetFirst();
02030         planeItr.ResetFirst();
02031         
02032         if(leverArm  == 2){
02033                 
02034                 //only two planes in the set.  if they are shower planes, just set it 
02035                 //each plane to the best hypothesis.  valid muon planes are already set.
02036                 //get the slope and intercept for a straight line through the two and 
02037                 //then set all remaining planes based on that
02038                 
02039                 Float_t z1 = 0., z2 = 0.;
02040                 Float_t tPos1 = 0., tPos2 = 0.;
02041                 Int_t ctr = 0;
02042                 DmxPlane *plane = 0;
02043                 while( (plane = validPlaneItr()) ){
02044                         
02045                         if(plane->GetPlaneType() == DmxPlaneTypes::kShower) plane->SetStrips();
02046                         if(ctr == 0){
02047                                 z1 = plane->GetZPosition();
02048                                 tPos1 = plane->GetCoG();
02049                         }
02050                         else{
02051                                 z2 = plane->GetZPosition();
02052                                 tPos2 = plane->GetCoG();
02053                         }
02054                         ++ctr;
02055                 }//end loop to find the first and last plane tpos and zpos
02056                 
02057                 if(z1 != z2) useA2 = (tPos2 - tPos1)/(z2 - z1);
02058                 useA1 = tPos2 - useA2*z2;
02059         }//end if only 2 valid planes
02060         else if(leverArm==3){
02061                 //evaluate the rms of the centers of gravity - take the tightest
02062                 //distribution
02063                 for(Int_t ia = 1; ia < 4; ++ia){
02064                         hypsToUse[0] = ia;
02065                         for(Int_t ib = 1; ib < 4; ++ib){
02066                                 hypsToUse[1] = ib;
02067                                 for(Int_t ic = 1; ic < 4; ++ic){
02068                                         hypsToUse[2] = ic;
02069                                         
02070                                         FindFit(planeItr, validPlaneItr, useA1, useA2, useA3, useA4, bestChi2,
02071                                                         leverArm, hypsToUse);
02072                                 }
02073                         }
02074                 }
02075         }//end if lever arm = 3 
02076         else if(leverArm == 4){
02077                 for(Int_t ia = 1; ia < 4; ++ia){
02078                         hypsToUse[0] = ia;
02079                         for(Int_t ib = 1; ib < 4; ++ib){
02080                                 hypsToUse[1] = ib;
02081                                 for(Int_t ic = 1; ic < 4; ++ic){
02082                                         hypsToUse[2] = ic;
02083                                         for(Int_t id = 1; id < 4; ++id){
02084                                                 hypsToUse[3] = id;
02085                                                 
02086                                                 FindFit(planeItr, validPlaneItr, useA1, useA2, useA3, useA4, bestChi2,
02087                                                                 leverArm, hypsToUse);
02088                                                 
02089                                         }
02090                                 }
02091                         }
02092                 }
02093         }//end if 4 plane lever arm
02094         else if(leverArm == 5){
02095                 for(Int_t ia = 1; ia < 4; ++ia){
02096                         hypsToUse[0] = ia;
02097                         for(Int_t ib = 1; ib < 4; ++ib){
02098                                 hypsToUse[1] = ib;
02099                                 for(Int_t ic = 1; ic < 4; ++ic){
02100                                         hypsToUse[2] = ic;
02101                                         for(Int_t id = 1; id < 4; ++id){
02102                                                 hypsToUse[3] = id;
02103                                                 for(Int_t ie = 1; ie < 4; ++ie){
02104                                                         hypsToUse[4] = ie;
02105                                                         
02106                                                         FindFit(planeItr, validPlaneItr, useA1, useA2, useA3, useA4, bestChi2,
02107                                                                         leverArm, hypsToUse);
02108                                                         
02109                                                 }
02110                                         }
02111                                 }
02112                         }
02113                 }
02114         }
02115         else if(leverArm == 6){
02116                 for(Int_t ia = 1; ia < 4; ++ia){
02117                         hypsToUse[0] = ia;
02118                         for(Int_t ib = 1; ib < 4; ++ib){
02119                                 hypsToUse[1] = ib;
02120                                 for(Int_t ic = 1; ic < 4; ++ic){
02121                                         hypsToUse[2] = ic;
02122                                         for(Int_t id = 1; id < 4; ++id){
02123                                                 hypsToUse[3] = id;
02124                                                 for(Int_t ie = 1; ie < 4; ++ie){
02125                                                         hypsToUse[4] = ie;
02126                                                         for(Int_t ig = 1; ig < 4; ++ig){
02127                                                                 hypsToUse[5] = ig;
02128                                                                 
02129                                                                 FindFit(planeItr, validPlaneItr, useA1, useA2, useA3, useA4, bestChi2,
02130                                                                                 leverArm, hypsToUse);
02131                                                         }
02132                                                 }
02133                                         }
02134                                 }
02135                         }
02136                 }
02137         }//end if lever arm = 6 planes
02138         
02139         MSG("AlgDeMuxBeam", Msg::kDebug) << "\tfinal fit" << "\t" << useA1 << "\t" << useA2 
02140                                                                 << "\t" << bestChi2 << endl; 
02141         
02142         SetFirstNPlanes(planeItr, useA2, useA1);
02143         
02144         return;
02145 }

void AlgDeMuxBeam::DeMuxFirstNPlanesTest DmxPlaneItr &  planeItr,
DmxPlaneItr &  validPlaneItr
[private]
 

Definition at line 645 of file AlgDeMuxBeam.cxx.

References fFinalShowerRegionIntercept, fFinalShowerRegionSlope, FindFitOverNPlanes(), fVldContext, DmxMuonPlane::GetCoG(), DmxShowerPlane::GetHypothesis(), DmxShowerPlane::GetHypothesisCoG(), DmxMuonPlane::GetInitialCoG(), DmxMuonPlane::GetInitialStripCoG(), DmxHypothesis::GetMatedSignalRatio(), DmxPlane::GetPlaneCharge(), DmxPlane::GetPlaneNumber(), DmxPlane::GetPlaneType(), UgliGeomHandle::GetStripHandle(), UgliStripHandle::GetTPos(), DmxPlane::GetZPosition(), MSG, and SetFirstNPlanes().

Referenced by RunAlg().

00647 {
00648         Int_t leverArm = (Int_t)validPlaneItr.SizeSelect();
00649         if(leverArm > fPlanesInSet) leverArm = fPlanesInSet;
00650         Int_t planeCtr = 0;
00651         
00652         //loop over the valid planes and take the first leverArm planes.
00653         DmxPlane *plane = 0;
00654         DmxShowerPlane *showerPlane = 0;
00655         DmxMuonPlane *muonPlane = 0;
00656         
00657         validPlaneItr.ResetFirst();
00658         
00659         Float_t matedCharge = 0.;
00660         Float_t planeCharge = 0.;
00661         Float_t maxMatedCharge = 0.;
00662         Int_t maxMatedChargeHyp = 0;
00663         Float_t zPos[] = {0., 0., 0., 0., 0., 0.};
00664         Float_t tPos[] = {0., 0., 0., 0., 0., 0.};
00665         Float_t weight[] = {1., 1., 1., 1., 1., 1.};
00666         Float_t residual[] = {0., 0., 0., 0., 0., 0.};
00667         Int_t planeNum[] = {0,0,0,0,0,0};
00668         Float_t slope = 0.;
00669         Float_t intercept = 0.;
00670         Float_t averageRMS = 0.;
00671         Int_t rmsCtr = 0;
00672         
00673         //now loop over all hypotheses in turn for the planes and see which set gives you 
00674         //the most mated signal over the leverArm planes
00675         for(Int_t i = 0; i<fNumberOfHypotheses; ++i){
00676                 
00677                 validPlaneItr.ResetFirst();
00678                 planeCtr = 0;
00679                 matedCharge = 0.;
00680                 rmsCtr = 0;
00681                 averageRMS = 0.;
00682                 
00683                 while( (plane = validPlaneItr()) && planeCtr<leverArm){
00684                         
00685                         planeCharge = plane->GetPlaneCharge();
00686 
00687                         //check out the type of plane you have here
00688                         if(plane->GetPlaneType() == DmxPlaneTypes::kShower){                            
00689                                 matedCharge += dynamic_cast<DmxShowerPlane *>(plane)->GetHypothesis(i)->GetMatedSignalRatio()*planeCharge;
00690                                 averageRMS += dynamic_cast<DmxShowerPlane *>(plane)->GetHypothesis(i)->GetTieBreakerStat();
00691                                 ++rmsCtr;
00692                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "plane = " << plane->GetPlaneNumber() 
00693                                                                                                 << " i = " << i 
00694                                                                                                 << " mated frac = " << dynamic_cast<DmxShowerPlane *>(plane)->GetHypothesis(i)->GetMatedSignalRatio()
00695                                                                                                 << " rms = " << dynamic_cast<DmxShowerPlane *>(plane)->GetHypothesis(i)->GetTieBreakerStat()
00696                                                                                                 << " charge = " << planeCharge << endl;
00697                         }               
00698                                 
00699                         //its a valid muon plane so check to see if the current hypothesis contains the initial strip
00700                         else{
00701                                 if(dynamic_cast<DmxMuonPlane *>(plane)->GetInitialStripCoG()>=i
00702                                    && dynamic_cast<DmxMuonPlane *>(plane)->GetInitialStripCoG()<=i+23)
00703                                         matedCharge += planeCharge;                             
00704                         }
00705                         
00706                         ++planeCtr;
00707                 }//end loop over first leverArm valid planes
00708                 
00709                 //does the current hypothesis represent the most mated signal?
00710                 if(matedCharge>maxMatedCharge){
00711                         maxMatedCharge = matedCharge;
00712                         //minAverageRMS = averageRMS/(1.*rmsCtr);
00713                         maxMatedChargeHyp = i;
00714                 }
00715                 
00716         }//end loop over hypotheses
00717         
00718         MSG("AlgDeMuxBeam", Msg::kDebug) << "best initial hypothesis = " << maxMatedChargeHyp << endl;
00719         
00720         validPlaneItr.ResetFirst();
00721         planeCtr = 0;
00722 
00723         //make an array holding the best hypothesis numbers for these planes
00724         Int_t bestHyps[] = {maxMatedChargeHyp, maxMatedChargeHyp, maxMatedChargeHyp, maxMatedChargeHyp, maxMatedChargeHyp, maxMatedChargeHyp};
00725 
00726         //get the transverse position for the best hypothesis
00727         UgliGeomHandle ugh(fVldContext);
00728         
00729         //check the number of valid planes - if only 2, then just set these suckers to the best hyp and be done with it.
00730         if(leverArm == 2){
00731                 //get the strip end id for the center of gravity for the center of the best hypothesis
00732                 PlexStripEndId seid(DetectorType::kFar,dynamic_cast<DmxPlane *>(validPlaneItr.Ptr())->GetPlaneNumber(),maxMatedChargeHyp+12);
00733                 UgliStripHandle ush = ugh.GetStripHandle(seid);
00734                 
00735                 intercept = ush.GetTPos();
00736                                 
00737                 //set the first n planes - slope is 0 because you are just setting all the planes to one
00738                 //hypothesis
00739                 SetFirstNPlanes(planeItr, 0., intercept);
00740 
00741                 return;
00742         }
00743         
00744         //loop over the valid planes again and see if by adjusting the hypothesis number you can get more 
00745         //mated signal for the plane
00746         while ((plane = validPlaneItr()) && planeCtr<leverArm){
00747                 maxMatedCharge = 0.;
00748                 maxMatedChargeHyp = bestHyps[planeCtr];
00749                 zPos[planeCtr] = plane->GetZPosition();
00750                 //get the strip end id for the center of gravity for the center of the best hypothesis
00751                 PlexStripEndId seid(DetectorType::kFar,plane->GetPlaneNumber(),bestHyps[planeCtr]+12);
00752                 UgliStripHandle ush = ugh.GetStripHandle(seid);
00753                 
00754                 tPos[planeCtr] = ush.GetTPos();
00755                 planeNum[planeCtr] = plane->GetPlaneNumber();
00756                 
00757                 planeCharge = plane->GetPlaneCharge();
00758                 showerPlane = 0;
00759                 muonPlane = 0;
00760                 if( plane->GetPlaneType() == DmxPlaneTypes::kShower) showerPlane = dynamic_cast<DmxShowerPlane *>(plane);
00761                 else muonPlane = dynamic_cast<DmxMuonPlane *>(plane);
00762                 
00763                 if(showerPlane){
00764                         tPos[planeCtr] = showerPlane->GetHypothesisCoG(maxMatedChargeHyp);
00765                         maxMatedCharge = showerPlane->GetHypothesis(bestHyps[planeCtr])->GetMatedSignalRatio()*planeCharge;
00766                 }
00767                 else{
00768                         if(muonPlane->GetInitialStripCoG()>=maxMatedChargeHyp 
00769                            && muonPlane->GetInitialStripCoG()<=maxMatedChargeHyp+23){
00770                                 tPos[planeCtr] = muonPlane->GetCoG();
00771                                 maxMatedCharge = planeCharge;                           
00772                         }
00773                 }
00774 
00775                 //look at hypotheses n strips on either side of the chosen hyp for the plane
00776                 for(Int_t i = 1; i<=fMaxStripAdjustment; ++i){
00777                         
00778                         if(showerPlane){
00779                                 if(bestHyps[planeCtr]-i>=0){
00780                                         matedCharge = showerPlane->GetHypothesis(bestHyps[planeCtr]-i)->GetMatedSignalRatio()*planeCharge;      
00781                                         if(matedCharge>maxMatedCharge){
00782                                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "initial best hyp = " << bestHyps[planeCtr]
00783                                                                                                                 << " new best hyp = " << bestHyps[planeCtr]-i 
00784                                                                                                                 << " new tpos = " << showerPlane->GetHypothesisCoG(maxMatedChargeHyp)
00785                                                                                                                 << endl;
00786                                                 maxMatedCharge = matedCharge;
00787                                                 maxMatedChargeHyp = bestHyps[planeCtr]-i;
00788                                                 tPos[planeCtr] = showerPlane->GetHypothesisCoG(maxMatedChargeHyp);
00789                                         }                                       
00790                                 }//end if the new hypothesis is allowed
00791                                 if(bestHyps[planeCtr]+i<fNumberOfHypotheses){
00792                                         matedCharge = showerPlane->GetHypothesis(bestHyps[planeCtr]+i)->GetMatedSignalRatio()*planeCharge;      
00793                                         if(matedCharge>maxMatedCharge){
00794                                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "initial best hyp = " << bestHyps[planeCtr]
00795                                                                                                                 << " new best hyp = " << bestHyps[planeCtr]+i   
00796                                                                                                                 << " new tpos = " << showerPlane->GetHypothesisCoG(maxMatedChargeHyp)<< endl;
00797                                                 maxMatedCharge = matedCharge;
00798                                                 maxMatedChargeHyp = bestHyps[planeCtr]+i;
00799                                                 tPos[planeCtr] = showerPlane->GetHypothesisCoG(maxMatedChargeHyp);
00800                                         }                                       
00801                                 }//end if the other new hypothesis is allowed
00802                         }//end if it is a shower plane
00803                         if(muonPlane){
00804                                 if(bestHyps[planeCtr]+i<fNumberOfHypotheses){
00805                                         if(muonPlane->GetInitialStripCoG()>=bestHyps[planeCtr]+i && muonPlane->GetInitialStripCoG()<=bestHyps[planeCtr]+i+23){
00806                                                 //this hypothesis contains the original decoding for the valid muon plane
00807                                                 //so the mated charge is all charge on the plane and the transverse position is 
00808                                                 //the original cog
00809                                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "initial best hyp = " << bestHyps[planeCtr]
00810                                                                                                                 << " new best hyp = " << bestHyps[planeCtr]+i  
00811                                                                                                                 << " new tpos = " << muonPlane->GetCoG()<< endl;
00812                                                 maxMatedChargeHyp = bestHyps[planeCtr] + i;
00813                                                 maxMatedCharge = planeCharge;                           
00814                                                 tPos[planeCtr] = muonPlane->GetInitialCoG();
00815                                         }
00816                                 }//end if the new hypothesis is allowed
00817                                 if(bestHyps[planeCtr]-i>=0){
00818                                         if(muonPlane->GetInitialStripCoG()>=bestHyps[planeCtr]-i && muonPlane->GetInitialStripCoG()<=bestHyps[planeCtr]-i+23){
00819                                                 //this hypothesis contains the original decoding for the valid muon plane
00820                                                 //so the mated charge is all charge on the plane and the transverse position is 
00821                                                 //the original cog
00822                                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "initial best hyp = " << bestHyps[planeCtr]
00823                                                                                                                 << " new best hyp = " << bestHyps[planeCtr]-i  
00824                                                                                                                 << " new tpos = " << muonPlane->GetCoG() << endl;
00825                                                 maxMatedChargeHyp = bestHyps[planeCtr] - i;
00826                                                 maxMatedCharge = planeCharge;   
00827                                                 tPos[planeCtr] = muonPlane->GetInitialCoG();
00828                                         }
00829                                 }//end if the other new hypothesis is allowed
00830                         }//end if it is a muon plane
00831                 }//end loop over other hypotheses
00832                 
00833                 bestHyps[planeCtr] = maxMatedChargeHyp;
00834                 
00835                 MSG("AlgDeMuxBeam", Msg::kDebug) << plane->GetPlaneNumber() << " zpos = " << zPos[planeCtr]
00836                                                                                 << " tpos = " << tPos[planeCtr] << " best hyp = "
00837                                                                                 << bestHyps[planeCtr] << endl;
00838                 
00839                 ++planeCtr;
00840         }//end loop over valid planes to adjust the fit
00841                 
00842         FindFitOverNPlanes(zPos,tPos,weight,residual,slope, intercept, leverArm, planeNum);
00843         
00844         MSG("AlgDeMuxBeam", Msg::kDebug) << "set to slope = " << slope << " intercept = " 
00845                                                                         << intercept << endl;
00846         
00847         fFinalShowerRegionSlope = slope;
00848         fFinalShowerRegionIntercept = intercept;
00849         
00850         //set the first n planes
00851         SetFirstNPlanes(planeItr, slope, intercept);
00852         
00853         return;
00854 }

Float_t AlgDeMuxBeam::FindDigitCoG DmxPlaneItr &  validPlaneItr,
CandDeMuxDigitHandleItr &  cdhit
[private]
 

Definition at line 1716 of file AlgDeMuxBeam.cxx.

References fVldContext, UgliGeomHandle::GetStripHandle(), and UgliStripHandle::GetTPos().

01718 {
01719         
01720         //   MSG("AlgDeMuxBeam", Msg::kDebug) << "In FindDigitCoG" << endl;
01721         
01722         Float_t cog = -5.;
01723         Float_t sigTPosSum = 0.;
01724         Float_t sigSum = 0.;
01725         
01726         UgliGeomHandle  ugh(fVldContext);
01727         UgliStripHandle ush;
01728         
01729         validPlaneItr.ResetFirst();
01730         
01731         //loop over the valid planes and get the digits from those planes
01732         while(validPlaneItr.IsValid()){
01733                 cdhit.GetSet()->Slice(validPlaneItr.Ptr()->GetPlaneNumber());
01734                 
01735                 //got to tell the iterator to sort the slice
01736                 cdhit.GetSet()->Update();
01737                 
01738                 //     MSG("AlgDeMuxBeam", Msg::kDebug) << "getting CoG with plane  " 
01739                 //                             <<  validPlaneItr.Ptr()->GetPlaneNumber()
01740                 //                             << " digits" << endl;
01741                 
01742                 while(cdhit.IsValid()){
01743                         if(cdhit.Ptr()->GetDeMuxDigitFlagWord() == 0){
01744                                 ush = ugh.GetStripHandle(cdhit.Ptr()->GetPlexSEIdAltL().GetBestSEId());
01745                                 sigTPosSum += ush.GetTPos()*cdhit.Ptr()->GetCharge();
01746                                 sigSum += cdhit.Ptr()->GetCharge();
01747                         }
01748                         cdhit.Next();
01749                 }//end loop over digits
01750                 
01751                 //clear the digit slice
01752                 cdhit.GetSet()->ClearSlice(false);
01753                 
01754                 //advance the plane iterator
01755                 validPlaneItr.Next();
01756         }//end loop over planes
01757         
01758         validPlaneItr.ResetFirst();
01759         cdhit.ResetFirst();
01760         
01761         //find the cog
01762         if(sigSum > 0.) cog = sigTPosSum/sigSum;
01763         
01764         //   MSG("AlgDeMuxBeam", Msg::kDebug) << "digit cog = " << cog << endl;
01765         return cog;
01766 }

void AlgDeMuxBeam::FindFit DmxPlaneItr &  planeItr,
DmxPlaneItr &  validPlaneItr,
Double_t &  a1,
Double_t &  a2,
Double_t &  a3,
Double_t &  a4,
Double_t &  bestChi2,
Int_t  leverArm,
Int_t *  hypotheses
[private]
 

Definition at line 2148 of file AlgDeMuxBeam.cxx.

References FindFitForHypothesisSet(), FindPlanesToDropFromFit(), and DmxUtilities::IsValidFit().

Referenced by DeMuxFirstNPlanes().

02152 {
02153         
02154         Double_t fitA1 = 0.;
02155         Double_t fitA2 = 0.;
02156         Double_t fitA3 = 0.;
02157         Double_t fitA4 = 0.;
02158         Double_t chi2 = 0.;
02159         DmxUtilities util;
02160         
02161         FindFitForHypothesisSet(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypotheses, 
02162                                                         leverArm);
02163         
02164         if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, 
02165                                                                                   fitA3, fitA4) ){
02166                 bestChi2 = chi2;
02167                 a1 = fitA1;
02168                 a2 = fitA2;
02169                 a3 = fitA3;
02170                 a4 = fitA4;
02171                 
02172                 //see if you can drop some planes and improve the fit
02173                 if( FindPlanesToDropFromFit(validPlaneItr, fitA1, fitA2, fitA3, 
02174                                                                         fitA4, leverArm) ){
02175                         
02176                         FindFitForHypothesisSet(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, 
02177                                                                         hypotheses, leverArm);
02178                         
02179                         if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, 
02180                                                                                                   fitA3, fitA4) ){
02181                                 bestChi2 = chi2;
02182                                 a1 = fitA1;
02183                                 a2 = fitA2;
02184                                 a3 = fitA3;
02185                                 a4 = fitA4;
02186                         }
02187                         validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE);
02188                 }//end if planes should be dropped because they are way off
02189         }//end if its a better straight line fit
02190         
02191         return;
02192 }

void AlgDeMuxBeam::FindFitForHypothesisSet DmxPlaneItr &  planeItr,
Double_t &  prevChiSq,
Double_t &  a1,
Double_t &  a2,
Double_t &  a3,
Double_t &  a4,
Int_t *  hypotheses,
Int_t  leverArm
[private]
 

Definition at line 2196 of file AlgDeMuxBeam.cxx.

References DmxUtilities::FindLinearFit(), DmxPlane::GetCoG(), DmxPlane::GetPlaneCharge(), DmxPlane::GetPlaneNumber(), DmxPlane::GetPlaneType(), DmxPlaneTypes::GetPlaneTypeString(), DmxPlane::GetZPosition(), DmxPlane::IsGolden(), DmxPlane::IsValid(), and MSG.

Referenced by FindFit().

02200 {
02201         
02202         MSG("AlgDeMuxBeam", Msg::kDebug) << "in FindFitForHypothesisSet" << endl;
02203         
02204         planeItr.ResetFirst();
02205         
02206         //cout << "in find fit for first n planes" << endl;
02207         
02208         //declare the variables to do a least squares fit to a straight line.  
02209         //weight is the inverse fraction of the total charge on the plane that 
02210         //is on opposite ends of common strips. multiply the inverse by a 
02211         //sensible number to take account for digits with 1000+ adc's
02212         
02213         //the arrays are the number of planes in the set, ie the lever arm
02214         Double_t x[] = {0.,0.,0.,0.,0.,0.};
02215         Double_t y[] = {0.,0.,0.,0.,0.,0.};
02216         Double_t weight[] = {1.,1.,1.,1.,1.,1.};
02217         Double_t chiSq = 0.;
02218         
02219         DmxUtilities util;
02220         
02221         Int_t planeCtr = 0;
02222         Int_t arrayCtr = 0;
02223         DmxPlane *plane = 0;
02224         
02225         //loop over the plane iterator to fill the variables
02226         
02227         while( (plane = planeItr()) && planeCtr < leverArm){
02228                 
02229                 //get some generic info about the plane
02230                 MSG("AlgDeMuxBeam", Msg::kDebug) << "plane " << plane->GetPlaneNumber() 
02231                 << " is valid " << (Int_t)plane->IsValid()
02232                 << " is golden " << (Int_t)plane->IsGolden() 
02233                 << " masked " << (Int_t)planeItr.GetSet()->GetMasks().GetMask(plane)
02234                 << " " << DmxPlaneTypes::GetPlaneTypeString(plane->GetPlaneType())
02235                 << endl;
02236                 
02237                 if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){
02238                         x[arrayCtr] = plane->GetZPosition();
02239                         
02240                         //get the maximum possible weight first, then for each hypothesis 
02241                         //multiply by the square of the fraction
02242                         weight[arrayCtr] = 1./ TMath::Sqrt(plane->GetPlaneCharge());
02243                         if(plane->IsGolden()) weight[arrayCtr] /= TMath::Sqrt(10.);
02244                         
02245                         y[arrayCtr] = plane->GetCoG();
02246                         
02247                         //only do this if the shower plane is not golden - if it is, 
02248                         //you know where it should be reconstructed to
02249                         if( plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){
02250                                 
02251                                 if(hypotheses[planeCtr] == 1){
02252                                         weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio()); 
02253                                 }
02254                                 //plane->GetCoG() returns the best hypothesis CoG so only change the value 
02255                                 //of y if you are wanting the 2nd or 3rd best hypotheses
02256                                 else if(hypotheses[planeCtr] == 2){ 
02257                                         y[arrayCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG();
02258                                         weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio());
02259                                 }
02260                                 else if(hypotheses[planeCtr] == 3){ 
02261                                         y[arrayCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG();
02262                                         weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio());
02263                                 }
02264                         }
02265                         
02266                         MSG("AlgDeMuxBeam", Msg::kDebug) << "zpos = " << x[arrayCtr] << " tpos = " << y[arrayCtr]
02267                                 << " hypothesis = " << hypotheses[arrayCtr] << endl;
02268                         
02269                         ++arrayCtr;
02270                         
02271                 }//end if the plane isnt marked as sucking && it is in the window bounds
02272                 
02273                 ++planeCtr;
02274         } //end loop over planes to find variables for fit
02275         
02276         //cout << "filled arrays" << endl;
02277         
02278         //use the DmxUtilities function to find a linear fit
02279         util.FindLinearFit(x, y, weight, arrayCtr, a1, a2, chiSq);
02280         
02281         prevChiSq = (double)chiSq;
02282         //a1 = intercept;
02283         //a2 = slope;   
02284         MSG("AlgDeMuxBeam", Msg::kDebug) << "\tinitial fit " << a1 << "\t" << a2 << "\t" 
02285                                                                 << a3 << "\t" << a4 << "\t" << chiSq << endl; 
02286         
02287         planeItr.Reset();
02288         planeCtr = 0;
02289         arrayCtr = 0;
02290         //cout << "reset the iterator" << endl;
02291         
02292         //redo the fit as many times as there are planes, dropping each plane in 
02293         //turn to see if it produces a better chi^2 value - only do it if you have 
02294         //more than 3 planes - ie you can drop one and still do a reasonable fit
02295         //2 planes = great straight line every time.
02296         if(leverArm > 3){
02297                 
02298                 Double_t fitA1 = 0.;
02299                 Double_t fitA2 = 0.;
02300                 Double_t fitA3 = 0.;
02301                 Double_t fitA4 = 0.;
02302                 
02303                 for(Int_t i = 0; i < leverArm; i++){
02304                         arrayCtr = 0;
02305                         
02306                         //cout <<"in loop " << i << endl;
02307                         //loop over the plane iterator to fill the variables
02308                         while( (plane = planeItr()) && planeCtr < leverArm){
02309                                 
02310                                 //use those planes not marked as kTRUE - a mark of kTRUE means to drop the plane
02311                                 //from the set when finding the fit. ie if its true, the plane truely sucks
02312                                 if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){
02313                                         
02314                                         if(i != planeCtr || plane->IsGolden() ){
02315                                                 x[arrayCtr] = plane->GetZPosition();
02316                                                 y[arrayCtr] = plane->GetCoG();
02317                                                 
02318                                                 weight[arrayCtr] = 1. / TMath::Sqrt(plane->GetPlaneCharge());
02319                                                 if(plane->IsGolden()) weight[arrayCtr] /= TMath::Sqrt(10.);
02320                                                 
02321                                                 //only make changes if not a golden plane
02322                                                 if( plane->GetPlaneType() == DmxPlaneTypes::kShower  && !plane->IsGolden()){
02323                                                         //only change y if the hypothesis isnt the best one - the unset plane 
02324                                                         //returns the best cog from the GetCoG() method
02325                                                         
02326                                                         if(hypotheses[planeCtr] == 1){
02327                                                                 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio());
02328                                                         }
02329                                                         else if(hypotheses[planeCtr] == 2){ 
02330                                                                 y[arrayCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG();
02331                                                                 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio());
02332                                                         }
02333                                                         else if(hypotheses[planeCtr] == 3){ 
02334                                                                 y[arrayCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG();
02335                                                                 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio());
02336                                                         }
02337                                                 }
02338                                                 
02339                                                 ++arrayCtr;
02340                                                 //else MSG("AlgDeMuxBeam", Msg::kDebug) << "\tdrop plane " << plane->GetPlaneNumber() 
02341                                                 //<< endl; 
02342                                         } //end if plane is not the dropped one
02343                                 }//end if plane is in window bounds
02344                                 ++planeCtr;
02345                         } //end loop over planes to find variables for fit
02346             
02347                         //use the DmxUtilities function to find a linear fit
02348                         
02349                         util.FindLinearFit(x, y, weight, arrayCtr, fitA1, fitA2, chiSq);
02350                         MSG("AlgDeMuxBeam", Msg::kDebug) << "\tlinear fit drop plane " << chiSq << "\t" << fitA1 
02351                                 << "\t" << fitA2 << endl;
02352                         
02353                         planeItr.Reset();
02354                         
02355                         planeCtr = 0;
02356                         if(chiSq < prevChiSq){
02357                                 prevChiSq = chiSq;
02358                                 a1 = fitA1;
02359                                 a2 = fitA2;
02360                                 a3 = fitA3;
02361                                 a4 = fitA4;
02362                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "\trefined fit, drop plane " << i 
02363                                         << "\t" << prevChiSq << "\t" << a1 << "\t" << a2 << endl;
02364                         }
02365                         
02366                 }//end for loop to improve fit by dropping a plane
02367         }//end if enough planes to improve fit
02368         
02369         planeItr.ResetFirst();
02370         
02371         return;
02372 }

void AlgDeMuxBeam::FindFitOverNPlanes Float_t *  x,
Float_t *  y,
Float_t *  sigma,
Float_t *  residual,
Float_t &  slope,
Float_t &  intercept,
Int_t  numPoints,
Int_t *  planeNum
[private]
 

Definition at line 895 of file AlgDeMuxBeam.cxx.

References fMaxMuonRemovalFraction, fMaxResidual, MSG, and RegionLinearFit().

Referenced by DeMuxFirstNPlanesTest(), UseMuonSlidingWindow(), and UseShowerSlidingWindow().

00899 {
00900         Float_t chiSqr;
00901         Float_t averageResidual = 0.;
00902         Float_t maxResidual = 0.;
00903         Float_t maxChiSqr = 0.;
00904         Float_t prevWeight = 0.;
00905         Int_t maxResidualLoc = 0;
00906         Int_t numBadResidual = 0;
00907         
00908         //now fit a straight line
00909         RegionLinearFit(slope, intercept, chiSqr, x, y, sigma, residual, numPoints);
00910         
00911         //find the fit for the first n planes and look for 
00912         //planes with large residuals.  repeat until planes with 
00913         //large residuals are removed
00914         Int_t nRemoved = 0;
00915         bool pointRemoved = true;
00916         while(nRemoved<=fMaxMuonRemovalFraction*numPoints && pointRemoved){
00917                 
00918                 pointRemoved = false;
00919                 RegionLinearFit(slope, intercept, chiSqr, x, y, sigma, residual, numPoints);
00920                 
00921                 averageResidual = 0.;
00922                 maxResidual = 0.;
00923                 numBadResidual = 0;
00924                 
00925                 for(Int_t i = 0; i<numPoints; ++i){
00926                         MSG("AlgDeMuxBeam", Msg::kDebug) << "zpos = " << x[i] << " tpos = " << y[i]
00927                                                                                         << " plane = " << planeNum[i]
00928                                                                                         << " residual = " << residual[i] << endl;
00929                         if(sigma[i]>0.){
00930                                 averageResidual += TMath::Abs(residual[i]);
00931                                 if(TMath::Abs(residual[i])>fMaxResidual) ++numBadResidual;
00932                         }
00933                         //find the point with the largest residual more than the allowed value
00934                         if(TMath::Abs(residual[i])>maxResidual){
00935                                 maxResidual = TMath::Abs(residual[i]);
00936                                 maxResidualLoc = i;
00937                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "biggest residual for plane " << planeNum[i] << endl;
00938                         }
00939                 }//end loop to find average residual and entry with the largest residual
00940                 
00941                 averageResidual /= (1.*(numPoints-nRemoved));
00942                 
00943                 MSG("AlgDeMuxBeam", Msg::kDebug) << "average residual for first n planes = " 
00944                         << averageResidual << "/" << fMaxResidual << endl;
00945                 
00946                 //is the average residual too big?  then remove the point with the 
00947                 //largest residual and try again.
00948                 if(averageResidual>fMaxResidual || numBadResidual>fMaxBadResidual){
00949                         ++nRemoved;
00950                         pointRemoved = true;
00951                         maxChiSqr = chiSqr;
00952                         //try removing one plane at a time from the fit and see which one causes the bad fit
00953                         for(Int_t j = 0; j<numPoints; ++j){
00954                                 prevWeight = sigma[j];
00955                                 sigma[j] = 0.;
00956                                 RegionLinearFit(slope, intercept, chiSqr, x, y, sigma, residual, numPoints);
00957                                 sigma[j] = prevWeight;
00958                                 if(chiSqr<maxChiSqr){
00959                                         maxChiSqr = chiSqr;
00960                                         maxResidualLoc = j;
00961                                 }
00962                         }//end loop over planes to get rid of the bad one
00963                         MSG("AlgDeMuxBeam", Msg::kDebug) << "!!!! removed plane " << planeNum[maxResidualLoc] 
00964                                 << " from fit !!!!" << endl;
00965                         sigma[maxResidualLoc] = 0.;
00966                 }
00967                 
00968         }//end loop to check fit
00969         
00970         return;
00971 }

Bool_t AlgDeMuxBeam::FindPlanesToDropFromFit DmxPlaneItr &  planeItr,
Double_t  a1,
Double_t  a2,
Double_t  a3,
Double_t  a4,
Int_t  leverArm
[private]
 

Definition at line 1772 of file AlgDeMuxBeam.cxx.

References DmxPlane::GetCoG(), DmxPlane::GetPlaneNumber(), DmxPlane::GetPlaneType(), DmxPlane::GetZPosition(), DmxPlane::IsGolden(), MSG, and DmxPlane::SetGolden().

Referenced by FindFit().

01775 {
01776 
01777         MSG("AlgDeMuxBeam", Msg::kDebug) << "in FindPlanesToDropFromFit" << endl;
01778 
01779         planeItr.ResetFirst();
01780 
01781         Double_t diff1 = 0.;
01782         Double_t diff2 = 0.;
01783         Double_t diff3 = 0.;
01784         Double_t fitCoG = 0.;
01785         bool planesDropped = false;
01786 
01787         Int_t dropPlanes = 0;
01788         Int_t planeCtr = 0;
01789         //MSG("AlgDeMuxBeam", Msg::kDebug)<<"\tin FindPlanesToDropFromFit"; 
01790   
01791         DmxPlane *plane = 0;
01792         //find the plane farthest off from the fit, keep going until you have just 3 planes left
01793         while( (plane = planeItr()) && dropPlanes<(Int_t)(0.1*leverArm) && planeCtr<leverArm){
01794 
01795                 fitCoG = (a1 + (plane->GetZPosition())*a2 
01796                                   + TMath::Power(plane->GetZPosition(),2)*a3
01797                                   + TMath::Power(plane->GetZPosition(),3)*a4);
01798   
01799                 //MSG("AlgDeMuxBeam", Msg::kDebug)<<"\t" << plane->GetPlaneNumber() << endl;
01800       
01801                 if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){
01802                         if( plane->GetPlaneType() == DmxPlaneTypes::kShower ){
01803                                 diff1 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG());
01804                                 diff2 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG());
01805                                 diff3 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG());
01806                         }
01807                         else if( plane->GetPlaneType() == DmxPlaneTypes::kMuon ){
01808                                 diff1 = TMath::Abs(fitCoG - plane->GetCoG());
01809                                 diff2 = TMath::Abs(fitCoG - plane->GetCoG());
01810                                 diff3 = TMath::Abs(fitCoG - plane->GetCoG());
01811                         }
01812         
01813                         //if all the 3 best hypotheses are way off from the fit, that plane is most 
01814                         //likely messing up the fit.  so mark it as kTRUE - ie it, it truely sucks
01815                         if(diff1 > .504 && diff2 > .504 && diff3 > .504 && !plane->IsGolden() ){
01816                                 planeItr.GetSet()->GetMasks().SetMask(kTRUE, planeItr.Ptr());
01817                                 planesDropped = true;
01818                                 MSG("AlgDeMuxBeam", Msg::kDebug)<<"\tmarking plane " << plane->GetPlaneNumber() << endl;
01819                                 //decrement the number of planes now used for a fit.
01820                                 ++dropPlanes;
01821                         }
01822                         else if(diff1 > 0.504 && plane->IsGolden()){
01823           
01824                                 //if this was a golden plane but it just doesnt work, make a non-golden plane
01825                                 planeItr.GetSet()->GetMasks().SetMask(kTRUE, planeItr.Ptr());
01826                                 plane->SetGolden(false);
01827                                 planesDropped = true;
01828                                 MSG("AlgDeMuxBeam", Msg::kDebug)<<"\tmarking plane " << plane->GetPlaneNumber() << endl;
01829                                 //decrement the number of planes now used for a fit.
01830                                 ++dropPlanes;
01831                         }//end if dropping a golden plane
01832                 } //end if the mask hasnt already been set for this plane
01833       
01834                 ++planeCtr;
01835         }
01836         planeItr.ResetFirst();
01837   
01838         //cout << "finished drop planes from fit" << endl;
01839 
01840         return planesDropped;
01841 }

Float_t AlgDeMuxBeam::FindRegionMatedChargeFraction DmxPlaneItr &  validPlaneItr  )  [private]
 

Definition at line 1540 of file AlgDeMuxBeam.cxx.

References DmxPlane::GetCoG(), DmxPlane::GetPlaneCharge(), DmxPlane::GetPlaneNumber(), DmxPlane::GetPlaneType(), DmxPlane::GetStripCoG(), and MSG.

Referenced by RunAlg().

01541 {
01542         MSG("AlgDeMuxBeam", Msg::kDebug) << "In FindRegionMatedChargeFraction" << endl;
01543         
01544         //reset the validPlaneItr
01545         validPlaneItr.ResetFirst();
01546         DmxPlane *plane = 0;
01547         Float_t totalCharge = 0.;
01548         Float_t matedCharge = 0.;
01549         Float_t charge = 0.;
01550         
01551         while( (plane = validPlaneItr()) ){
01552                 
01553                 charge = plane->GetPlaneCharge();
01554                 totalCharge += charge;
01555                 
01556                 MSG("AlgDeMuxBeam", Msg::kDebug) << "plane = " << plane->GetPlaneNumber() 
01557                                                                                 << " charge = " << charge << endl;
01558 
01559                 if(plane->GetPlaneType() == DmxPlaneTypes::kShower)
01560                         matedCharge += dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio()*charge;
01561                 else if(plane->GetPlaneType() == DmxPlaneTypes::kMuon){
01562                         
01563                         MSG("AlgDeMuxBeam", Msg::kDebug) << "muon plane cog = " << plane->GetCoG() 
01564                                                                                         << "/" << dynamic_cast<DmxMuonPlane *>(plane)->GetInitialCoG()
01565                                                                                         << "/" << dynamic_cast<DmxMuonPlane *>(plane)->GetStripCoG()
01566                                                                                         << "/" << dynamic_cast<DmxMuonPlane *>(plane)->GetInitialStripCoG()
01567                                                                                         << endl;
01568                         
01569                         //since this is a valid muon plane, all the charge is mated, assuming that the initial
01570                         //center of gravity is the same as the set center of gravity
01571                         if(plane->GetCoG() == dynamic_cast<DmxMuonPlane *>(plane)->GetInitialCoG())
01572                                 matedCharge += charge;
01573                         
01574                 }//end if muon plane
01575                         
01576                 MSG("AlgDeMuxBeam", Msg::kDebug) << " mated charge = " << matedCharge << endl;
01577                 
01578         }//end loop over valid planes
01579         
01580         
01581         //get the fraction of mated charge in this region.  check it against the 
01582         //passed in parameter
01583         Float_t matedChargeFrac = matedCharge;
01584         if(totalCharge > 0.) matedChargeFrac /= totalCharge;    
01585         else matedChargeFrac = -1.;
01586         
01587         MSG("AlgDeMuxBeam", Msg::kDebug) << "mated charge fraction in region = " 
01588                                                                         << matedChargeFrac << endl;
01589         
01590         return matedChargeFrac;
01591 }

void AlgDeMuxBeam::FindRMSOfPlanes DmxPlaneItr &  planeItr,
Int_t  leverArm,
Int_t *  hypsToUse,
Float_t &  cog,
Float_t &  rms
[private]
 

Definition at line 1846 of file AlgDeMuxBeam.cxx.

References DmxPlane::GetCoG(), DmxPlane::GetPlaneCharge(), DmxPlane::GetPlaneType(), and MSG.

01848 {
01849         //   MSG("AlgDeMuxBeam", Msg::kDebug) << "In FindRMSOfPlanes" << endl;
01850         
01851         //initialize the variables for finding the RMS
01852         Double_t sigTPos2Sum = 0.;
01853         Double_t sigSum = 0.;
01854         Double_t sigTPosSum = 0.;
01855         Double_t signal = 0.;
01856         Double_t planeCoG = 0.;
01857         
01858         Int_t ctr = 0;
01859         
01860         planeItr.ResetFirst();
01861         //loop over the planes in the set and use only those that are 
01862         //between firstPlane and lastPlane
01863         
01864         DmxPlane *plane = 0;
01865         while( planeItr.IsValid() && ctr < leverArm){
01866                 plane = planeItr.Ptr();
01867                 signal = plane->GetPlaneCharge();
01868                 planeCoG = plane->GetCoG();
01869                 
01870                 if( plane->GetPlaneType() == DmxPlaneTypes::kShower ){
01871                         if( hypsToUse[ctr] == 1){
01872                                 signal *= dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio();
01873                                 planeCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG();
01874                         } 
01875                         else if( hypsToUse[ctr] == 2){
01876                                 signal *= dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio();
01877                                 planeCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG();
01878                         } 
01879                         else if( hypsToUse[ctr] == 3){
01880                                 signal *= dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio();
01881                                 planeCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG();
01882                         } 
01883                 }
01884                 
01885                 sigTPos2Sum += signal * planeCoG * planeCoG;
01886                 sigTPosSum += signal * planeCoG;
01887                 sigSum += signal;
01888                 
01889                 //increment the ctr
01890                 ++ctr;
01891                 
01892                 //move to the next plane in the list
01893                 planeItr.Next();
01894         }
01895         
01896         planeItr.Reset();
01897         
01898         //calculate the RMS using the formula from Bevington
01899         //[Sum(S_i * x_i^2) / Sum(S_i) - (av_x)^2] * (N / N -1) where
01900         //S_i is the signal at a distance x_i and av_x is the signal 
01901         //weighted average distance from the line for a digit and N is the
01902         //number of measures in the set
01903         
01904         Double_t weighter = (leverArm * 1.0) / (1.0 * (leverArm - 1));
01905         Double_t avTPos = sigTPosSum / sigSum;
01906         Double_t rmsSq = ((sigTPos2Sum / sigSum) - (avTPos * avTPos)) * weighter;
01907         
01908         cog = avTPos;
01909         
01910         //stupid round off error - make sure it doesnt make the rms^2 negative
01911         if(TMath::Abs(rmsSq)<1.e-3) rmsSq = 0.;
01912         
01913         rms = TMath::Sqrt(rmsSq);
01914         
01915         MSG("AlgDeMuxBeam", Msg::kDebug) << "cog = " << cog << " rms = " << rms << endl;
01916         
01917         
01918         //see what happens if you drop a plane from the set
01919         ctr = 0;
01920         
01921         //redo the fit using only the previously set planes and only if you have 
01922         //more than 3 planes in the set
01923         if(leverArm > 3){
01924                 
01925                 
01926                 Double_t rmsRef = 0.;
01927                 Double_t cogRef = 0.;
01928                 
01929                 for(Int_t i = 0; i < leverArm; i++){
01930                         ctr = 0;
01931                         sigTPosSum = 0;
01932                         sigTPos2Sum = 0;
01933                         sigSum = 0;
01934                         
01935                         //loop over the plane iterator to fill the variables
01936                         while( planeItr.IsValid() && ctr < leverArm){
01937                                 plane = planeItr.Ptr();
01938                                 
01939                                 if(i != ctr){
01940                                         
01941                                         signal = plane->GetPlaneCharge();
01942                                         planeCoG = plane->GetCoG();
01943                                         
01944                                         if( plane->GetPlaneType() == DmxPlaneTypes::kShower ){
01945                                                 if( hypsToUse[ctr] == 1){
01946                                                         signal *= dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio();
01947                                                         planeCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG();
01948                                                 } 
01949                                                 else if( hypsToUse[ctr] == 2){
01950                                                         signal *= dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio();
01951                                                         planeCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG();
01952                                                 } 
01953                                                 else if( hypsToUse[ctr] == 3){
01954                                                         signal *= dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio();
01955                                                         planeCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG();
01956                                                 } 
01957                                         }
01958                                         
01959                                         sigTPos2Sum += signal * planeCoG * planeCoG;
01960                                         sigTPosSum += signal * planeCoG;
01961                                         sigSum += signal;
01962                                         
01963                                         //        MSG("AlgDeMuxBeam", Msg::kDebug) << "inloop " << sigTPos2Sum << " " << sigTPosSum 
01964                                         //                                << " " << sigSum << endl;
01965                                         
01966                                 }//end if not the plane to drop
01967                                 ++ctr;
01968                                 
01969                                 planeItr.Next();
01970                         } //end loop over planes to find variables for fit
01971                         
01972                         planeItr.Reset();
01973                         
01974                         Double_t weighterRef = (leverArm * 1.0) / (1.0 * (leverArm - 1));
01975                         Double_t avTPosRef = sigTPosSum / sigSum;
01976                         Double_t rmsSqRef = ((sigTPos2Sum / sigSum) - (avTPosRef * avTPosRef)) * weighterRef;
01977                         
01978                         //     MSG("AlgDeMuxBeam", Msg::kDebug) << avTPosRef << " "  << sigTPos2Sum/sigSum << " "
01979                         //                          << weighterRef << endl;
01980                         
01981                         //stupid round off error - make sure it doesnt make the rms^2 negative
01982                         if(TMath::Abs(rmsSqRef)<1.e-3) rmsSqRef = 0.;
01983                         
01984                         cogRef = avTPosRef;
01985                         rmsRef = TMath::Sqrt(rmsSqRef);
01986                         
01987                         if(rmsRef < rms){  
01988                                 rms = rmsRef;
01989                                 cog = cogRef;
01990                                 
01991                                 //       MSG("AlgDeMuxBeam", Msg::kDebug) << "new cog = " << cog << " rms = " << rms << endl;
01992                                 
01993                         }
01994                         
01995                         
01996                 }//end loop over planes to drop one at a time
01997         }//end if at least 3 planes in set
01998         
01999         return;
02000 }

void AlgDeMuxBeam::FindShowerWindowSolution DmxPlaneItr &  windowPlaneItr,
Float_t  cog,
Int_t  firstPlane,
Int_t  lastPlane
[private]
 

void AlgDeMuxBeam::ReconcileShowerAndMuonRegions DmxPlaneItr &  planeItr,
CandDeMuxDigitHandleItr &  cdhit
[private]
 

Definition at line 1599 of file AlgDeMuxBeam.cxx.

References PlexSEIdAltL::ClearWeights(), fDigitResetCut, fFinalShowerRegionSlope, fInitialMuonRegionSlope, fMuonStartPlaneNumber, fShowerMuonTransverseDifference, fVldContext, PlexSEIdAltL::GetBestSEId(), DmxPlane::GetCoG(), PlexSEIdAltL::GetCurrentSEId(), CandDeMuxDigitHandle::GetDeMuxDigitFlagWord(), DmxPlane::GetPlaneNumber(), CandDigitHandle::GetPlexSEIdAltL(), CandDigitHandle::GetPlexSEIdAltLWritable(), UgliGeomHandle::GetStripHandle(), UgliStripHandle::GetTPos(), DmxPlane::GetZPosition(), PlexSEIdAltL::IsValid(), MSG, PlexSEIdAltL::Next(), PlexSEIdAltL::SetCurrentWeight(), and PlexSEIdAltL::SetFirst().

Referenced by RunAlg().

01601 {
01602         //get the last slope and intercept for the shower and muon regions and 
01603         //compare the predicted tpos at the muon start plane number.
01604         //also find the extent of the shower at that point.  if the muon track 
01605         //is more than the allowed value away from the shower, then reconcile 
01606         //the shower to the track.
01607         
01608         Float_t showerPredictedTPos = fFinalShowerRegionSlope*fMuonStartPlaneZPos;
01609         showerPredictedTPos += fFinalShowerRegionIntercept;
01610         
01611         Float_t muonPredictedTPos = fInitialMuonRegionSlope*fMuonStartPlaneZPos;
01612         muonPredictedTPos += fInitialMuonRegionIntercept;
01613         
01614         MSG("AlgDeMuxBeam", Msg::kDebug) << "shower prediction = " << showerPredictedTPos
01615                                                                         << " muon prediction = " << muonPredictedTPos 
01616                                                                         << " muon start zpos = " << fMuonStartPlaneZPos 
01617                                                                         << endl;
01618         
01619         CandDeMuxDigitHandle *digit = 0;
01620         DmxPlane *plane = 0;    
01621         
01622         UgliGeomHandle  ugh(fVldContext);
01623         UgliStripHandle ush;
01624 
01625         Float_t maxPlaneTPos = -5.;
01626         Float_t minPlaneTPos = 5.;
01627         Float_t digitTPos = 0.;
01628         Float_t setDigitTPos = 0.;
01629         
01630         if(TMath::Abs(muonPredictedTPos-showerPredictedTPos) > fShowerMuonTransverseDifference){
01631                 
01632                 //it looks like the muon and shower don't match up.  loop over the 
01633                 //CandDeMuxDigitList and see what the extent of the shower region is
01634                 while( (plane = planeItr()) ){
01635                         
01636                         maxPlaneTPos = -5.;
01637                         minPlaneTPos = 5.;
01638                         
01639                         
01640                         cdhit.GetSet()->Slice(plane->GetPlaneNumber());
01641                         
01642                         //got to tell the iterator to sort the slice
01643                         cdhit.GetSet()->Update();
01644                         while( (digit = cdhit()) ){
01645                                 if(digit->GetDeMuxDigitFlagWord() == 0){
01646                                         ush = ugh.GetStripHandle(digit->GetPlexSEIdAltL().GetBestSEId());
01647                                         digitTPos = ush.GetTPos();
01648                                         if(digitTPos > maxPlaneTPos) maxPlaneTPos = digitTPos;
01649                                         else if(digitTPos < minPlaneTPos) minPlaneTPos = digitTPos;
01650                                 }
01651                         }//end loop over digits in the plane
01652 
01653                         //reset the digit iterator
01654                         cdhit.ResetFirst();
01655                         
01656                         //check the demuxed cog of each plane in the shower region against 
01657                         //the predicted position based on the initial muon linear fit. also
01658                         //check that the predicted position is outside the minimum and maximum
01659                         //transverse positions of the reconstructed strips in the the plane.
01660                         //if the difference is more than the allowed value, or the predicted 
01661                         //location is outside the reconstructed strip bounds, then redo the reconstruction
01662                         muonPredictedTPos = fInitialMuonRegionSlope*plane->GetZPosition();
01663                         muonPredictedTPos += fInitialMuonRegionIntercept;
01664 
01665                         if(plane->GetPlaneNumber() < fMuonStartPlaneNumber
01666                            && TMath::Abs(plane->GetCoG()-muonPredictedTPos) > fShowerMuonTransverseDifference
01667                            && (muonPredictedTPos<minPlaneTPos || muonPredictedTPos>maxPlaneTPos)){
01668                                 
01669                                 //plane->SetStrips(muonPredictedTPos);
01670         
01671                                 //loop over the digits again and look at the SEIdAltLists - if there is 
01672                                 //an alternative within the accepted bound of the predicted position,
01673                                 //take it.
01674                                 while( (digit = cdhit()) ){ 
01675                                         
01676                                         ush = ugh.GetStripHandle(digit->GetPlexSEIdAltL().GetBestSEId());
01677                                         setDigitTPos = ush.GetTPos();
01678 
01679                                         //set the alternatives list to the first one
01680                                         digit->GetPlexSEIdAltL().SetFirst();
01681                                         
01682                                         while( digit->GetPlexSEIdAltL().IsValid() ){
01683                                                 ush = ugh.GetStripHandle(digit->GetPlexSEIdAltL().GetCurrentSEId());
01684                                                 digitTPos = ush.GetTPos();
01685                                                         
01686                                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "current tpos = " << digitTPos
01687                                                                                                                 << "/" << muonPredictedTPos << endl;
01688                                                 
01689                                                 if(TMath::Abs(digitTPos-muonPredictedTPos) < fDigitResetCut
01690                                                    || (TMath::Abs(setDigitTPos-muonPredictedTPos) > fShowerMuonTransverseDifference
01691                                                            && TMath::Abs(digitTPos-muonPredictedTPos) < fShowerMuonTransverseDifference) ){
01692                                                         //clear all weights for the digit
01693                                                         digit->GetPlexSEIdAltLWritable().ClearWeights();
01694                                                         MSG("AlgDeMuxBeam", Msg::kDebug) << "setting" << endl;
01695                                                         digit->GetPlexSEIdAltLWritable().SetCurrentWeight(1.0);
01696                                                         break;
01697                                                 }
01698                                                         
01699                                                 digit->GetPlexSEIdAltL().Next();
01700                                         }//end loop over alt list
01701                                 }//end loop over digits to find the ones near the predicted tpos
01702                         }//end if this plane should have some digits reset
01703                         
01704                         //clear the digit slice
01705                         cdhit.GetSet()->ClearSlice(false);
01706                                 
01707                 }//end loop over planeItr
01708                 
01709         }//end if the shower and muon regions have different predicted transverse positions
01710         
01711         return;
01712 }

void AlgDeMuxBeam::RegionLinearFit Float_t &  slope,
Float_t &  intercept,
Float_t &  chiSqr,
Float_t *  x,
Float_t *  y,
Float_t *  sigma,
Float_t *  residual,
Int_t  numPoints
[private]
 

Definition at line 1475 of file AlgDeMuxBeam.cxx.

References MSG.

Referenced by FindFitOverNPlanes().

01479 {
01480 
01481         //define the necessary sums
01482         Double_t sumXSqrDivSigmaSqr = 0.;
01483         Double_t sumYDivSigmaSqr = 0.;
01484         Double_t sumXDivSigmaSqr = 0.;
01485         Double_t sumXYDivSigmaSqr = 0.;
01486         Double_t sum1DivSigmaSqr = 0.;
01487         Double_t sigmaSqr = 0.;
01488         chiSqr = 0.;
01489         
01490         for(Int_t i=0; i<numPoints; ++i){
01491 
01492                 if(TMath::Abs(sigma[i])>0.){
01493                         sigmaSqr = sigma[i]*sigma[i];
01494                         sum1DivSigmaSqr += 1./sigmaSqr;
01495                         sumXDivSigmaSqr += x[i]/sigmaSqr;
01496                         sumYDivSigmaSqr += y[i]/sigmaSqr;
01497                         sumXYDivSigmaSqr += (x[i]*y[i])/sigmaSqr;
01498                         sumXSqrDivSigmaSqr += (x[i]*x[i])/sigmaSqr;
01499                 }
01500                 MSG("AlgDeMuxBeam", Msg::kDebug) << "x = " << x[i] << " y = " << y[i] << " sigma = " 
01501                                                                     << sigma[i] << " sum1DivSigmaSqr = " << sum1DivSigmaSqr
01502                                                                     << " sumXDivSigmaSqr = " << sumXDivSigmaSqr
01503                                                                     << " sumYDivSigmaSqr = " << sumYDivSigmaSqr
01504                                                                     << " sumXYDivSigmaSqr = " << sumXYDivSigmaSqr
01505                                                                     << " sumXSqrDivSigmaSqr = " << sumXSqrDivSigmaSqr << endl;
01506         }
01507         
01508         Float_t delta = sum1DivSigmaSqr*sumXSqrDivSigmaSqr - sumXDivSigmaSqr*sumXDivSigmaSqr;
01509         if(delta==0.){
01510                 MSG("AlgDeMuxBeam", Msg::kWarning) << "delta = 0 in linear fit - kludge an answer and bail" << endl;
01511                 intercept = 0.;
01512                 slope = 0.;
01513                 chiSqr = 10000.;
01514                 return;
01515         }
01516         intercept = (sumXSqrDivSigmaSqr*sumYDivSigmaSqr - sumXDivSigmaSqr*sumXYDivSigmaSqr)/delta;
01517         slope = (sum1DivSigmaSqr*sumXYDivSigmaSqr - sumXDivSigmaSqr*sumYDivSigmaSqr)/delta;
01518         
01519         //now get the chi^2 and residual for the fit - zero chiSqr to be safe
01520         chiSqr = 0.;
01521         Double_t numerator = 0.;
01522         Double_t denominator = 0.;
01523         for(Int_t i=0; i<numPoints; ++i){
01524                 residuals[i] = (y[i]-intercept-slope*x[i]);
01525                 numerator = TMath::Power(y[i]-intercept-slope*x[i],2.);
01526                 denominator = sigma[i]*sigma[i];
01527                 if(denominator>0.) chiSqr += numerator/denominator;
01528         }
01529         
01530         //fit to a straight line has 2 degrees of freedom
01531         if(numPoints>2) chiSqr /= 1.*(numPoints-2);
01532         
01533         return;
01534 }

void AlgDeMuxBeam::RunAlg AlgConfig acd,
CandHandle ch,
CandContext cx
[virtual]
 

Implements AlgBase.

Definition at line 90 of file AlgDeMuxBeam.cxx.

References RawTriggerCodes::AsString(), DmxUtilities::CheckFitWithTiming(), DeMuxFirstNPlanesTest(), fDigitResetCut, DmxUtilities::FillPlaneArray(), DmxUtilities::FindBeamMuonStartPlane(), DmxUtilities::FindEndPlane(), DmxUtilities::FindPlanesOffFit(), FindRegionMatedChargeFraction(), DmxUtilities::FindVertexPlane(), fMaxBadResidual, fMaxMuonRemovalFraction, fMaxResidual, fMaxStripAdjustment, fMinMatedChargeFrac, fMinMuonPlanesRequired, fMuonPlanesInSet, fMuonSlopeLimit, fMuonStartPlaneNumber, fMuonStartPlaneZPos, fNumberOfHypotheses, fPlanesInSet, fShowerMuonTransverseDifference, fStrayCut, fStrayPlanes, fVldContext, DmxStatus::GetAverageTimingOffset(), CandRecord::GetCandHeader(), CandHandle::GetCandRecord(), CandHandle::GetDaughterIterator(), VldContext::GetDetector(), Registry::GetDouble(), DmxStatus::GetEndPlaneNumber(), DmxStatus::GetEventDeMuxed(), DmxStatus::GetEventNumber(), Registry::GetInt(), DmxStatus::GetMuonStartPlaneNumber(), DmxStatus::GetNonPhysicalFailure(), DmxStatus::GetPlaneArray(), DmxPlane::GetPlaneNumber(), DmxPlane::GetPlaneType(), DmxPlaneTypes::GetPlaneTypeString(), DmxPlane::GetPlaneView(), CandHeader::GetSnarl(), DmxStatus::GetVertexPlaneNumber(), CandHandle::GetVldContext(), DmxPlane::GetZPosition(), DmxPlane::IsValid(), KeyFromPlane1(), KeyOnPlane1(), KeyOnUView1(), KeyOnValidU1(), KeyOnValidV1(), KeyOnVView1(), MSG, ReconcileShowerAndMuonRegions(), DmxStatus::ResetStatus(), DmxStatus::SetAverageTimingOffset(), CandDeMuxDigitListHandle::SetAvgTimeOffset(), CandDeMuxDigitListHandle::SetDeMuxDigitListFlagBit(), DmxStatus::SetEndPlaneNumber(), DmxStatus::SetEventNumber(), DmxStatus::SetFigureOfMerit(), DmxStatus::SetMultipleMuon(), DmxStatus::SetMuonStartPlaneNumber(), DmxStatus::SetNoVertexFailure(), DmxStatus::SetNumberOfPlanes(), CandDeMuxDigitListHandle::SetNumStrayPlanesU(), CandDeMuxDigitListHandle::SetNumStrayPlanesV(), CandDeMuxDigitListHandle::SetNumValidPlanesU(), CandDeMuxDigitListHandle::SetNumValidPlanesV(), DmxStatus::SetUMuonMatedFraction(), DmxStatus::SetUShowerMatedFraction(), DmxStatus::SetUStrayPlanes(), DmxStatus::SetUValidPlanes(), DmxStatus::SetValidPlanesFailure(), DmxStatus::SetVertexPlaneNumber(), DmxStatus::SetVertexPlaneZPosition(), DmxStatus::SetVMuonMatedFraction(), DmxStatus::SetVShowerMatedFraction(), DmxStatus::SetVStrayPlanes(), DmxStatus::SetVValidPlanes(), UseMuonSlidingWindow(), and UseShowerSlidingWindow().

00091 {
00092 
00093   assert( ch.InheritsFrom("CandDigitListHandle") );
00094   CandDeMuxDigitListHandle &cdlh = dynamic_cast<CandDeMuxDigitListHandle&>(ch);
00095   CandDeMuxDigitHandleItr cdhit = cdlh.GetDaughterIterator();
00096 
00097   fVldContext = *(ch.GetVldContext());
00098 
00099   if (fVldContext.GetDetector() != Detector::kFar) {
00100     static int msglimit = 20; // no more than 20 warnings about the detector
00101     if (msglimit) {
00102       MSG("AlgDeMuxBeam",Msg::kDebug) 
00103         << "AlgDeMuxBeam::RunAlg() can not DeMux "
00104         << Detector::AsString(fVldContext.GetDetector())
00105         << " detector.  Skip futher DeMux processing."
00106         << endl;
00107       if (--msglimit == 0) 
00108         MSG("AlgDeMuxBeam",Msg::kDebug) 
00109           << " ... last message of this type." << endl;
00110     }
00111     return;
00112   }
00113 
00114   //get the AlgConfigDeMux object
00115   fPlanesInSet = acd.GetInt("PlanesInSet");
00116   fMinMuonPlanesRequired = acd.GetInt("MinMuonPlanesRequired");
00117   fMinMatedChargeFrac = acd.GetDouble("MinMatedChargeFraction");
00118   fMuonPlanesInSet = acd.GetInt("MuonPlanesInSet");
00119   fMuonSlopeLimit = acd.GetDouble("MuonTrackSlopeLimit");
00120   fMaxResidual = acd.GetDouble("MaxResidual");
00121   fMaxBadResidual = acd.GetInt("MaxBadResidual");
00122   fMaxMuonRemovalFraction = acd.GetDouble("MaxMuonRemovalFraction");
00123   fMaxStripAdjustment = acd.GetInt("MaxStripAdjustment");
00124   fStrayCut = acd.GetInt("StrayDeltaStripLimit");
00125   fNumberOfHypotheses = acd.GetInt("NumberOfHypotheses");
00126   fShowerMuonTransverseDifference = acd.GetDouble("ShowerMuonTransverseDifference");
00127   fDigitResetCut = acd.GetDouble("ResetDigitCut");
00128   
00129   //MSG("AlgDeMuxBeam", Msg::kDebug) << "window size = " << fPlanesInSet << endl;
00130 
00131   //get the DmxStatus object
00132   // Find the DmxStatus object or create one for needed scratch space
00133   DmxStatus *status = dynamic_cast<DmxStatus *>(gROOT->GetRootFolder()->FindObject("Loon/DeMux/DmxStatus"));
00134   bool tempStatus = false;
00135   if (status == 0) {
00136     MSG("AlgDeMuxBeam", Msg::kDebug) << "//root/Loon/DeMux/DmxStatus not found."
00137                               << " Create a temporary DmxStatus." << endl;
00138     status = new DmxStatus;      // Make a temporary DmxStatus if needed
00139     tempStatus = true;
00140   }
00141   else status->ResetStatus(); 
00142 
00143   status->SetEventNumber(ch.GetCandRecord()->GetCandHeader()->GetSnarl());
00144  
00145   MSG("AlgDeMuxBeam", Msg::kDebug) << "starting beam demuxing for event " 
00146                                                                   << status->GetEventNumber()
00147                                                                   << endl;
00148 
00149   DmxUtilities util;
00150   
00151   util.FillPlaneArray(status, cdlh, acd);
00152   const TObjArray *planeArray = status->GetPlaneArray();
00153   //DmxPlane *plane = dynamic_cast<DmxPlane *>(planeArray->First());
00154   //MSG("AlgDeMuxBeam", Msg::kDebug) <<"Event = " <<  status->GetEventNumber() << endl;
00155   
00156   //create the DmxPlaneItr over planes and program it to sort the planes
00157   DmxPlaneItr planeItr(planeArray);
00158   //create a KeyFunc to sort planes by number
00159   DmxPlaneKeyFunc *pnKF = planeItr.CreateKeyFunc();
00160   pnKF->SetFun(KeyOnPlane1);
00161   planeItr.GetSet()->AdoptSortKeyFunc(pnKF);
00162   pnKF = 0;
00163   
00164   planeItr.ResetFirst();
00165   status->SetNumberOfPlanes(planeItr.SizeSelect());
00166   status->SetVertexPlaneNumber(util.FindVertexPlane(planeItr));
00167   
00168   //demux the event if there is an identified vertex
00169   if( status->GetVertexPlaneNumber() != -1){
00170     
00171     planeItr.ResetFirst();
00172     planeItr.GetSet()->Slice(status->GetVertexPlaneNumber(), 500);
00173     planeItr.GetSet()->Update();
00174 
00175     //set the end plane number since there was a vertex plane
00176     status->SetEndPlaneNumber(util.FindEndPlane(planeItr));
00177     planeItr.GetSet()->ClearSlice(false);
00178     planeItr.ResetFirst();
00179 
00180     //set the z position of the vertex plane
00181     planeItr.GetSet()->Slice(status->GetVertexPlaneNumber());
00182     planeItr.GetSet()->Update();
00183     planeItr.ResetFirst();
00184     status->SetVertexPlaneZPosition(dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetZPosition());
00185 
00186     planeItr.GetSet()->ClearSlice(false);
00187     planeItr.ResetFirst();
00188 
00189     //set the plane number for the muon start plane
00190         planeItr.GetSet()->Slice(status->GetVertexPlaneNumber(), status->GetEndPlaneNumber());
00191     planeItr.GetSet()->Update();
00192     //set the muon start plane number
00193     status->SetMuonStartPlaneNumber(util.FindBeamMuonStartPlane(planeItr, 
00194                                                                                                                                 acd.GetDouble("AveragePEGainConversion")));
00195         fMuonStartPlaneNumber = status->GetMuonStartPlaneNumber();
00196     planeItr.GetSet()->ClearSlice(false);
00197     planeItr.ResetFirst();
00198     
00199     //create a KeyFunc to sort digits by plane
00200     CandDeMuxDigitHandleKeyFunc *planeKF = cdhit.CreateKeyFunc();
00201     
00202     //program the KeyFunc with the sort function
00203     planeKF->SetFun(KeyFromPlane1);
00204     
00205     //get the NavSet from the iterator and pass the KeyFunc to it
00206     cdhit.GetSet()->AdoptSortKeyFunc(planeKF);
00207     
00208     //clear the KF pointer because we no longer own the KeyFunc
00209     planeKF = 0;
00210 
00211     //make the iterators for the window, valid planes, and vertex
00212     DmxPlaneItr vertexPlaneItr(planeArray);
00213     DmxPlaneItr validPlaneItr(planeArray);
00214        
00215     //create a KeyFunc to sort planes by number
00216     DmxPlaneKeyFunc *vertexPlaneKF = vertexPlaneItr.CreateKeyFunc();
00217     DmxPlaneKeyFunc *validPlaneKF = validPlaneItr.CreateKeyFunc();
00218        
00219     //program the KeyFunc with the sort function
00220     vertexPlaneKF->SetFun(KeyOnPlane1);
00221     validPlaneKF->SetFun(KeyOnPlane1);
00222        
00223     //get the NavSet from the iterator and pass the KeyFunc to it
00224     vertexPlaneItr.GetSet()->AdoptSortKeyFunc(vertexPlaneKF);
00225     validPlaneItr.GetSet()->AdoptSortKeyFunc(validPlaneKF);
00226        
00227     //clear the KF pointer because we no longer own the KeyFunc
00228     vertexPlaneKF = 0;
00229     validPlaneKF = 0;
00230   
00231     planeItr.ResetFirst();
00232     validPlaneItr.ResetFirst();
00233         
00234     //now program a key function to select on plane orientation - U first
00235     DmxPlaneKeyFunc *orientValidUKF = validPlaneItr.CreateKeyFunc();
00236     DmxPlaneKeyFunc *orientUKF = planeItr.CreateKeyFunc();
00237     DmxPlaneKeyFunc *orientValidVKF = validPlaneItr.CreateKeyFunc();
00238     DmxPlaneKeyFunc *orientVKF = planeItr.CreateKeyFunc();
00239         
00240         //initialize the muon and shower region mated fraction variables in the DmxStatus object
00241         status->SetUShowerMatedFraction(-1.);   
00242         status->SetUMuonMatedFraction(-1.);   
00243         status->SetVShowerMatedFraction(-1.);   
00244         status->SetVMuonMatedFraction(-1.);   
00245         
00246         DmxPlane *plane = 0;
00247         bool endPlaneValid = false;
00248 
00249         planeItr.GetSet()->Update();
00250         planeItr.ResetFirst();
00251         //see if it worked
00252         while( (plane = planeItr()) ){
00253                 MSG("AlgDeMuxBeam", Msg::kDebug) << "number = " << plane->GetPlaneNumber()
00254                                                                                 << " orientation = " << (Int_t)plane->GetPlaneView()
00255                                                                                 << " type = " 
00256                                                                                 << DmxPlaneTypes::GetPlaneTypeString(plane->GetPlaneType())
00257                                                                                 << " IsValid() = " << (Int_t)plane->IsValid()  << endl;
00258                 
00259                 if(plane->GetPlaneNumber() == fMuonStartPlaneNumber) 
00260                         fMuonStartPlaneZPos = plane->GetZPosition();
00261                 if(plane->GetPlaneNumber() == status->GetEndPlaneNumber() && plane->IsValid())
00262                         endPlaneValid = true;
00263         }
00264         planeItr.ResetFirst();
00265         
00266     Int_t viewCtr = 0;
00267         Int_t numValidMuonPlanes = 0;
00268         Float_t muonMatedFraction = -1.;
00269         Float_t showerMatedFraction = -1.;
00270     while( viewCtr < 2 ){
00271                 
00272                 //set the muon start plane number at the start of the loop for each 
00273                 //view as one view may have reset it to -1 if there were not enough valid 
00274                 //muon planes in that view after the muon start plane number
00275                 fMuonStartPlaneNumber = status->GetMuonStartPlaneNumber();
00276                 muonMatedFraction = -1.;
00277                 showerMatedFraction = -1.;
00278                 
00279                 MSG("AlgDeMuxBeam", Msg::kDebug) << "vertex plane = " << status->GetVertexPlaneNumber()
00280                                                                                 << " muon start plane = " << fMuonStartPlaneNumber
00281                                                                                 << " end plane = " << status->GetEndPlaneNumber() << endl;
00282                 
00283      
00284                 if( viewCtr == 0){
00285                         //program this function with the select function
00286                         orientUKF->SetFun(KeyOnUView1);
00287                         orientValidUKF->SetFun(KeyOnValidU1);
00288                 
00289                         //adopt it as a selection function
00290                         planeItr.GetSet()->AdoptSelectKeyFunc(orientUKF);
00291                         orientUKF = 0;
00292                         planeItr.Reset();
00293                         validPlaneItr.GetSet()->AdoptSelectKeyFunc(orientValidUKF);
00294                         orientValidUKF = 0;
00295                         validPlaneItr.Reset();
00296                 }
00297                 else if(viewCtr == 1){
00298                         //program this function with the select function
00299                         orientVKF->SetFun(KeyOnVView1);
00300                         orientValidVKF->SetFun(KeyOnValidV1);
00301                 
00302                         //adopt it as a selection function
00303                         planeItr.GetSet()->AdoptSelectKeyFunc(orientVKF);
00304                         orientVKF = 0;
00305                         planeItr.Reset();
00306                         validPlaneItr.GetSet()->AdoptSelectKeyFunc(orientValidVKF);
00307                         orientValidVKF = 0;
00308                         validPlaneItr.Reset();
00309                 }
00310                   
00311                 planeItr.ResetFirst();
00312       
00313                 //there must be at least 2 valid planes for the demuxing to work.
00314                 //slice the validPlaneItr to all planes in the event
00315                 validPlaneItr.GetSet()->Slice(status->GetVertexPlaneNumber(), 
00316                                                                           status->GetEndPlaneNumber());
00317                 validPlaneItr.GetSet()->Update();
00318                 
00319                 if(validPlaneItr.SizeSelect() >= 2){
00320         
00321                         planeItr.GetSet()->Slice(status->GetVertexPlaneNumber(), 
00322                                                                          status->GetEndPlaneNumber()+1);
00323                         planeItr.GetSet()->Update();
00324 
00325                         //demux the first n planes in the detector.  the method adjusts the size of n
00326                         //such that if there are < fPlanesInSet planes hit, n becomes the number of planes
00327                         //hit.  Otherwise, n is fPlanesInSet 
00328                         if((Int_t)validPlaneItr.SizeSelect() < fPlanesInSet)
00329                                 DeMuxFirstNPlanesTest(planeItr, validPlaneItr);
00330         
00331                         else if( (Int_t)validPlaneItr.SizeSelect() >= fPlanesInSet){
00332 
00333                                 //still have to demux the first n planes of the event the same for 
00334                                 //muon or shower like events.  loop over the planes to find the last
00335                                 //plane in the first set of n
00336                                 Int_t ctr = 0;
00337                                 Int_t lastPlane = 0;
00338                                 Int_t firstPlane = 0;
00339                                 
00340                                 while( validPlaneItr.IsValid() && ctr < fPlanesInSet){
00341             
00342                                         plane = validPlaneItr.Ptr();
00343                                         //MSG("AlgDeMuxBeam", Msg::kDebug) << "plane number = " << plane->GetPlaneNumber()
00344                                         //             << endl;
00345 
00346                                         if( ctr == 0 ) firstPlane = plane->GetPlaneNumber();
00347                                         lastPlane = plane->GetPlaneNumber(); 
00348             
00349                                         validPlaneItr.Next();
00350                                         ++ctr;
00351                                 }
00352 
00353                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "\tfirst plane = " << firstPlane 
00354                                                                                                  << "\tlast plane = " << lastPlane << endl;
00355 
00356                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "demuxing first N planes" << endl;
00357 
00358                                 //clear the slice of the validPlaneItr
00359                                 validPlaneItr.GetSet()->ClearSlice(false);
00360                                 planeItr.GetSet()->ClearSlice(false);
00361 
00362                                 //set the initial window 
00363                                 validPlaneItr.GetSet()->Slice(status->GetVertexPlaneNumber(), lastPlane+1);
00364                                 validPlaneItr.GetSet()->Update();
00365                                 
00366                                 //check to see if the number of valid planes == fPlanesInSet.  if so, then 
00367                                 //it means that there wont be any sliding windows, so set all planes in 
00368                                 //the event
00369                                 if(status->GetEndPlaneNumber()-lastPlane <= 2 && !endPlaneValid) 
00370                                         lastPlane = status->GetEndPlaneNumber();
00371                                 
00372                                 //set the plane iterator to be from the vertex to the last plane in the window,
00373                                 //since this is the first window done
00374                                 planeItr.GetSet()->Slice(status->GetVertexPlaneNumber(), lastPlane+1);
00375                                 planeItr.GetSet()->Update();
00376 
00377                                 DeMuxFirstNPlanesTest(planeItr, validPlaneItr);
00378                                 
00379                                 validPlaneItr.GetSet()->ClearSlice(false);
00380                                 planeItr.GetSet()->ClearSlice(false);
00381 
00382                                 //check to make sure that there are valid planes after the 
00383                                 //muon start plane
00384                                 validPlaneItr.GetSet()->Slice(firstPlane, status->GetEndPlaneNumber());
00385                                 validPlaneItr.GetSet()->Update();
00386                                 numValidMuonPlanes = 0;
00387                                 while( (plane = validPlaneItr() ) ){
00388                                         if(plane->GetPlaneNumber()>fMuonStartPlaneNumber 
00389                                            && fMuonStartPlaneNumber > 0 
00390                                            && plane->GetPlaneType()==DmxPlaneTypes::kMuon)
00391                                                 ++numValidMuonPlanes;
00392                                 }
00393                                 validPlaneItr.GetSet()->ClearSlice(false);
00394                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "number valid muon planes in view " << viewCtr
00395                                                                                                  << " = " << numValidMuonPlanes << endl;
00396                                 
00397                                 //if the number of valid muon planes is less than 2, then set the 
00398                                 //fMuonStartPlaneNumber to -1 since you will just demux the muon stuff 
00399                                 //with the shower region
00400                                 if(numValidMuonPlanes<fMinMuonPlanesRequired) fMuonStartPlaneNumber = -1;
00401                                 
00402                                 //demux the shower region if it exists and it extends beyond the 
00403                                 //first set of planes demuxed
00404                                 if(status->GetVertexPlaneNumber() != fMuonStartPlaneNumber
00405                                    && fMuonStartPlaneNumber > 0 && TMath::Abs(fMuonStartPlaneNumber-lastPlane)>2){
00406                                         //slice the valid plane iterator to do the shower region
00407                                         MSG("AlgDeMuxBeam", Msg::kDebug) << "slice shower region with track from " 
00408                                                                                                         << firstPlane+1 << " to " 
00409                                                                                                         << fMuonStartPlaneNumber << endl;
00410                                         validPlaneItr.GetSet()->Slice(firstPlane+1, fMuonStartPlaneNumber);
00411                                         validPlaneItr.GetSet()->Update();
00412                                         UseShowerSlidingWindow(planeItr, validPlaneItr, status);
00413                                         showerMatedFraction = FindRegionMatedChargeFraction(validPlaneItr);
00414                                         if(viewCtr == 0)
00415                                                 status->SetUShowerMatedFraction(showerMatedFraction);   
00416                                         if(viewCtr == 1)
00417                                                 status->SetVShowerMatedFraction(showerMatedFraction);   
00418                                                                                                         
00419                                         validPlaneItr.GetSet()->ClearSlice(false);
00420                                                                                 
00421                                         MSG("AlgDeMuxBeam", Msg::kDebug) <<"Done Setting Shower Region for snarl " 
00422                                                                                                         << status->GetEventNumber() << endl;
00423                                 }
00424                                 else if(fMuonStartPlaneNumber < 0 
00425                                                 && TMath::Abs(status->GetEndPlaneNumber()-lastPlane)>2){
00426                                         //slice the valid plane iterator to do the shower region - there is 
00427                                         //no track to speak of, so just slice the planes out to the end of 
00428                                         //the detector
00429                                         validPlaneItr.GetSet()->Slice(firstPlane+1, 486);
00430                                         validPlaneItr.GetSet()->Update();
00431                                         UseShowerSlidingWindow(planeItr, validPlaneItr, status);
00432                                         showerMatedFraction = FindRegionMatedChargeFraction(validPlaneItr);
00433                                         if(viewCtr == 0)
00434                                                 status->SetUShowerMatedFraction(showerMatedFraction);   
00435                                         if(viewCtr == 1)
00436                                                 status->SetVShowerMatedFraction(showerMatedFraction);   
00437                                         
00438                                         validPlaneItr.GetSet()->ClearSlice(false);
00439             
00440                                         MSG("AlgDeMuxBeam", Msg::kDebug) <<"Done Setting Shower Region for no track or small track " 
00441                                                                                                         << status->GetEventNumber() << endl;
00442                                 }
00443                                 //now do the muon region if it exists           
00444                                 //if( fMuonStartPlaneNumber == status->GetVertexPlaneNumber() 
00445                                 //      && numValidMuonPlanes>1){
00446                                 //      validPlaneItr.GetSet()->Slice(firstPlane+1, 
00447                                 //                                                                status->GetEndPlaneNumber());
00448                                 //      validPlaneItr.GetSet()->Update();
00449                                 //      UseMuonSlidingWindow(planeItr,validPlaneItr, status);
00450                                 //      validPlaneItr.GetSet()->ClearSlice(false);
00451                                         
00452                                 //      MSG("AlgDeMuxBeam", Msg::kDebug) << "done setting the muon for snarl " 
00453                                 //              << status->GetEventNumber()  << endl;
00454                                 //}
00455                                 if(fMuonStartPlaneNumber > 0  && numValidMuonPlanes>1){
00456                                         validPlaneItr.GetSet()->Slice(fMuonStartPlaneNumber, 
00457                                                                                                   status->GetEndPlaneNumber());
00458                                         validPlaneItr.GetSet()->Update();
00459                                         UseMuonSlidingWindow(planeItr,validPlaneItr, status);
00460                                         muonMatedFraction = FindRegionMatedChargeFraction(validPlaneItr);
00461                                         if(viewCtr == 0)
00462                                                 status->SetUMuonMatedFraction(muonMatedFraction);   
00463                                         if(viewCtr == 1)
00464                                                 status->SetVMuonMatedFraction(muonMatedFraction);   
00465                                         
00466                                         validPlaneItr.GetSet()->ClearSlice(false);
00467                                         
00468                                         MSG("AlgDeMuxBeam", Msg::kDebug) << "done setting the muon for snarl " 
00469                                                                                                         << status->GetEventNumber()  << endl;
00470                                 }
00471                                 
00472                                 //check and see that both tracklike and showerlike regions,
00473                                 //that the fraction of the charge in the muon region that is mated
00474                                 //is above the threshold and that there are a reasonable number of 
00475                                 //planes in the muon region for the fit
00476                                 //if so, see that the track and shower solutions are consistent
00477                                 planeItr.GetSet()->Update();
00478                                 planeItr.ResetFirst();
00479                                 if(status->GetVertexPlaneNumber() != fMuonStartPlaneNumber
00480                                    && muonMatedFraction > fMinMatedChargeFrac
00481                                    && numValidMuonPlanes >= fPlanesInSet)
00482                                         ReconcileShowerAndMuonRegions(planeItr, cdhit);
00483                                 
00484                                 //MSG("AlgDeMuxBeam", Msg::kDebug)<<"Done with enough planes to demux"<< endl;
00485                         }//end if at least fPlanesInSet valid planes to reconstruct
00486                 } //end if >=2 valid planes to reconstruct the event
00487                 else{
00488                         MSG("AlgDeMuxBeam", Msg::kDebug)<< "Event " << status->GetEventNumber() 
00489                                                                            << " not demuxed; not enough valid planes" << endl;
00490                         status->SetValidPlanesFailure(true); 
00491                 }
00492 
00493                 //what if there is more to the track?  perhaps the muon went through the
00494                 //coil hole and disappeared for several planes?  treat it in a way similar 
00495                 //to multiple cosmics
00496 
00497                 planeItr.GetSet()->ClearSlice(false);
00498                 validPlaneItr.GetSet()->ClearSlice(false);
00499                 vertexPlaneItr.GetSet()->ClearSlice(false);
00500                 //MSG("AlgDeMuxBeam", Msg::kDebug) << "slice vertex itr" << endl;
00501       
00502                 vertexPlaneItr.GetSet()->Slice(status->GetEndPlaneNumber()+1, 500);
00503                 vertexPlaneItr.GetSet()->Update();
00504                 //MSG("AlgDeMuxBeam", Msg::kDebug)<< "event =  " << status->GetEventNumber() 
00505                 //                   << "\tend plane = " << status->GetEndPlaneNumber() << endl;
00506       
00507 
00508                 //MSG("AlgDeMuxBeam", Msg::kDebug) << "check for new vertex" << endl;
00509 
00510                 Int_t nextVertex = -1;
00511                 if(vertexPlaneItr.SizeSelect() > 3)
00512                         nextVertex = util.FindVertexPlane(vertexPlaneItr);
00513                         vertexPlaneItr.GetSet()->ClearSlice(false);
00514       
00515                         while( nextVertex != -1){
00516         
00517                                 status->SetMultipleMuon(true); 
00518                                 vertexPlaneItr.GetSet()->ClearSlice(false);
00519                                 vertexPlaneItr.GetSet()->Slice(nextVertex, 500);
00520                                 vertexPlaneItr.GetSet()->Update();
00521 
00522                                 //get the next end plane
00523                                 Int_t endPlane = util.FindEndPlane(vertexPlaneItr);
00524                                 
00525                                 status->SetEndPlaneNumber(endPlane);
00526 
00527                                 MSG("AlgDeMuxBeam", Msg::kDebug)<< "\tin gap loop, vertex at plane " << nextVertex 
00528                                                                                    << "\tend plane = " << endPlane << "\tplanes in slice = " 
00529                                                                                    << vertexPlaneItr.SizeSelect() << endl;
00530         
00531                                 //if we are in this loop, then it is most likely because a muon went through
00532                                 //the coil hole.  so the thing to do is just treat all the remaining planes as 
00533                                 //being in the muon track and only demux that way
00534 
00535                                 validPlaneItr.GetSet()->Slice(nextVertex, endPlane);
00536                                 validPlaneItr.GetSet()->Update();
00537                                 validPlaneItr.ResetFirst();
00538                                 
00539                                 //loop over the valid planes and count the number of muon planes
00540                                 numValidMuonPlanes = 0;
00541                                 while( (plane = validPlaneItr()) ){
00542                                         MSG("AlgDeMuxBeam", Msg::kDebug) << "number = " << plane->GetPlaneNumber()
00543                                         << " orientation = " << (Int_t)plane->GetPlaneView()
00544                                         << " type = " 
00545                                         << DmxPlaneTypes::GetPlaneTypeString(plane->GetPlaneType())
00546                                         << " IsValid() = " << (Int_t)plane->IsValid()  << endl;
00547                                         
00548                                         if(plane->GetPlaneType()==DmxPlaneTypes::kMuon) ++numValidMuonPlanes;
00549                                 }
00550                                 
00551                                 validPlaneItr.ResetFirst();
00552                                 
00553                                 if(numValidMuonPlanes<2){
00554                                         nextVertex = -1;
00555                                         continue;
00556                                 }
00557                                 UseMuonSlidingWindow(planeItr,validPlaneItr, status);
00558                                 validPlaneItr.GetSet()->ClearSlice(false);
00559                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "done setting the muon for snarl " 
00560                                                                                     << status->GetEventNumber()  << endl;
00561         
00562                                 //look for another vertex after the end plane
00563                                 planeItr.GetSet()->ClearSlice(false);
00564                                 validPlaneItr.GetSet()->ClearSlice(false);
00565                                 vertexPlaneItr.GetSet()->ClearSlice(false);
00566                                 vertexPlaneItr.GetSet()->Slice(endPlane+1, 500);
00567                                 vertexPlaneItr.GetSet()->Update();
00568                                 //MSG("AlgDeMuxBeam", Msg::kDebug)<< "\tlook for new vertex, slice from " << endPlane+1 
00569                                 //               << "\tto plane 500, planes in slice = " 
00570                                 //               << vertexPlaneItr.SizeSelect() << endl;
00571                                 
00572                                 vertexPlaneItr.Reset();
00573         
00574                                 if(vertexPlaneItr.SizeSelect() > 0) 
00575                                         nextVertex = util.FindVertexPlane(vertexPlaneItr);
00576                                 else nextVertex = -1; 
00577                         }//end loop to find next vertex for spread out multiples
00578 
00579                         fStrayPlanes = util.FindPlanesOffFit(planeItr, fStrayCut);
00580       
00581                         MSG("AlgDeMuxBeam", Msg::kDebug) << status->GetEventNumber() << " " 
00582                                                                                 << fStrayPlanes << endl; 
00583       
00584                         status->SetFigureOfMerit(validPlaneItr.SizeSelect(), fStrayPlanes);
00585                         if(viewCtr == 0 && status->GetEventDeMuxed() ){ 
00586                                 status->SetUStrayPlanes(fStrayPlanes);
00587                                 status->SetUValidPlanes(validPlaneItr.SizeSelect());
00588                                 cdlh.SetNumValidPlanesU(validPlaneItr.SizeSelect());
00589                                 cdlh.SetNumStrayPlanesU(fStrayPlanes);
00590                         }
00591                         if(viewCtr == 1 && status->GetEventDeMuxed() ){ 
00592                                 status->SetVStrayPlanes(fStrayPlanes);
00593                                 status->SetVValidPlanes(validPlaneItr.SizeSelect());
00594                                 cdlh.SetNumValidPlanesV(validPlaneItr.SizeSelect());
00595                                 cdlh.SetNumStrayPlanesV(fStrayPlanes);
00596                         }
00597 
00598                         //done using the first view, so clear the selection function
00599                         //MSG("AlgDeMuxBeam", Msg::kDebug) <<"Done with View " << viewCtr << endl;
00600                         planeItr.GetSet()->ClearSlice(false);
00601                         planeItr.GetSet()->AdoptSelectKeyFunc(0);
00602                         planeItr.ResetFirst();
00603                         validPlaneItr.GetSet()->ClearSlice(false);
00604                         validPlaneItr.GetSet()->AdoptSelectKeyFunc(0);
00605                         validPlaneItr.Reset();
00606                         vertexPlaneItr.GetSet()->ClearSlice(false);
00607                         vertexPlaneItr.Reset();
00608 
00609                         viewCtr++;
00610                 } //end loop over views
00611 
00612                 //if the event was demuxed, check to see how the demuxing and timing jive
00613                 //otherwise see if you need to set the nonphysical solution flag
00614                 if( status->GetEventDeMuxed() ){
00615                         status->SetAverageTimingOffset(util.CheckFitWithTiming(validPlaneItr));
00616                         cdlh.SetAvgTimeOffset(status->GetAverageTimingOffset());
00617                 }
00618                 else if(status->GetNonPhysicalFailure() )  
00619                         cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kNonPhysicalStripSolution);
00620     
00621         }//end if there was a vertex
00622         else{ 
00623                 status->SetNoVertexFailure(true);
00624                 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kNoVertex);
00625                 MSG("AlgDeMuxBeam", Msg::kDebug) << "no vertex found for event " 
00626                                                                         << status->GetEventNumber() << endl;
00627         }
00628   
00629         //get rid of the temporary status object if you made it.
00630         if(tempStatus) delete status;
00631 
00632         return;
00633 }

void AlgDeMuxBeam::SetFirstNPlanes DmxPlaneItr &  planeItr,
Float_t  slope,
Float_t  intercept
[private]
 

Definition at line 860 of file AlgDeMuxBeam.cxx.

References DmxPlane::GetCoG(), DmxPlane::GetPlaneNumber(), DmxPlane::GetZPosition(), MSG, and DmxPlane::SetStrips().

Referenced by DeMuxFirstNPlanes(), and DeMuxFirstNPlanesTest().

00862 {
00863         MSG("AlgDeMuxBeam", Msg::kDebug) << "In SetFirstNPlanes " << slope 
00864                                                                         << " " << intercept <<  endl;
00865         
00866         Float_t cog = 0.;
00867         planeItr.ResetFirst();
00868         DmxPlane *currentPlane = 0;
00869         
00870         while( (currentPlane = planeItr()) ){
00871                 
00872                 MSG("AlgDeMuxBeam", Msg::kDebug) << "on plane " << currentPlane->GetPlaneNumber()
00873                                                                                 << endl;
00874                 
00875                 cog = slope*currentPlane->GetZPosition() + intercept;
00876                 //set those strips if the plane isnt a valid muon plane 
00877                 //if(currentPlane->GetPlaneType() == DmxPlaneTypes::kMuon 
00878                 //   || !currentPlane->IsValid() ){
00879                         currentPlane->SetStrips(cog);
00880                         MSG("AlgDeMuxBeam", Msg::kDebug) << "setting first n planes " 
00881                                                                                         << currentPlane->GetPlaneNumber() << " to "
00882                                                                                         << cog << "/" << currentPlane->GetCoG() << endl;
00883                 //}
00884         
00885         }//end loop over planes
00886 
00887         planeItr.ResetFirst();
00888         return;
00889 }

void AlgDeMuxBeam::SetMuonRegionWindow DmxPlaneItr &  planeItr,
Float_t  slope,
Float_t  intercept,
bool  setAll
[private]
 

Definition at line 1434 of file AlgDeMuxBeam.cxx.

References fMuonStartPlaneNumber, DmxPlane::GetPlaneNumber(), DmxPlane::GetPlaneType(), DmxPlane::GetZPosition(), DmxPlane::IsValid(), MSG, and DmxPlane::SetStrips().

Referenced by UseMuonSlidingWindow().

01436 {
01437         MSG("AlgDeMuxBeam", Msg::kDebug) << "In SetMuonRegionWindow" << endl;
01438         
01439         Float_t cog = 0.;
01440         planeItr.ResetFirst();
01441         DmxPlane *currentPlane = 0;
01442         
01443         while( planeItr.IsValid() ){
01444                 //get the current plane
01445                 currentPlane = planeItr.Ptr();
01446                 
01447                 MSG("AlgDeMuxBeam", Msg::kDebug) << "on plane " 
01448                                                                                 << currentPlane->GetPlaneNumber()
01449                                                                                 << endl;
01450                 
01451                 cog = slope*currentPlane->GetZPosition() + intercept;
01452                 //set those strips if the plane isnt a valid muon plane in the 
01453                 //muon track or it has been determined that the plane shouldnt be a 
01454                 //valid muon plane
01455                 if(currentPlane->GetPlaneNumber() >= fMuonStartPlaneNumber
01456                    && (!currentPlane->IsValid()
01457                            || currentPlane->GetPlaneType() == DmxPlaneTypes::kShower
01458                            || setAll)
01459                    ){
01460                         currentPlane->SetStrips(cog);
01461                         MSG("AlgDeMuxBeam", Msg::kDebug) << "setting muon region plane " 
01462                                                                                         << currentPlane->GetPlaneNumber() 
01463                                                                                         << " to cog = " << cog << endl;
01464                 }//end if this plane to be set
01465                 
01466                 planeItr.Next();
01467         }//end loop over planes
01468         
01469         planeItr.ResetFirst();
01470         return;
01471 }

void AlgDeMuxBeam::SetShowerRegionWindow DmxPlaneItr &  planeItr,
Float_t  slope,
Float_t  intercept
[private]
 

Definition at line 1205 of file AlgDeMuxBeam.cxx.

References fMuonStartPlaneNumber, DmxPlane::GetPlaneNumber(), DmxPlane::GetZPosition(), MSG, and DmxPlane::SetStrips().

Referenced by UseShowerSlidingWindow().

01207 {
01208         MSG("AlgDeMuxBeam", Msg::kDebug) << "In SetShowerRegionWindow" << endl;
01209         
01210         Float_t cog = 0.;
01211         planeItr.ResetFirst();
01212         DmxPlane *currentPlane = 0;
01213         
01214         while( (currentPlane = planeItr()) ){
01215                 //get the current plane
01216                 MSG("AlgDeMuxBeam", Msg::kDebug) << "on plane " << currentPlane->GetPlaneNumber()
01217                                                                                 << endl;
01218                 
01219                 cog = slope*currentPlane->GetZPosition() + intercept;
01220                 if(fMuonStartPlaneNumber>0&&currentPlane->GetPlaneNumber()<fMuonStartPlaneNumber)
01221                         currentPlane->SetStrips(cog); 
01222                 else if(fMuonStartPlaneNumber<0)
01223                         currentPlane->SetStrips(cog); 
01224                 
01225                 MSG("AlgDeMuxBeam", Msg::kDebug) << "setting shower region plane " 
01226                                                                                 << currentPlane->GetPlaneNumber() 
01227                                                                                 << " to " << cog << endl;
01228                 
01229         }//end loop over planes
01230         
01231         planeItr.ResetFirst();
01232         return;
01233 }

void AlgDeMuxBeam::Trace const char *  c  )  const [virtual]
 

Reimplemented from AlgBase.

Definition at line 636 of file AlgDeMuxBeam.cxx.

00637 {
00638 }

void AlgDeMuxBeam::UseMuonSlidingWindow DmxPlaneItr &  planeItr,
DmxPlaneItr &  validPlaneItr,
DmxStatus status
[private]
 

Definition at line 1242 of file AlgDeMuxBeam.cxx.

References fFinalShowerRegionSlope, FindFitOverNPlanes(), fInitialMuonRegionIntercept, fInitialMuonRegionSlope, fMuonSlopeLimit, DmxPlane::GetCoG(), DmxStatus::GetEndPlaneNumber(), DmxStatus::GetMultipleMuon(), DmxStatus::GetMuonStartPlaneNumber(), DmxPlane::GetPlaneCharge(), DmxPlane::GetPlaneNumber(), DmxPlane::GetPlaneType(), DmxPlaneTypes::GetPlaneTypeString(), DmxPlane::GetZPosition(), MSG, and SetMuonRegionWindow().

Referenced by RunAlg().

01245 {
01246         
01247         MSG("AlgDeMuxBeam", Msg::kDebug) << "In UseMuonSlidingWindowTest" << endl;
01248         
01249         DmxPlane *plane = 0;
01250         
01251         validPlaneItr.ResetFirst();
01252 
01253         Int_t loopCtr = 0;
01254         Int_t ctr = 0;
01255         Float_t slope = 0.;
01256         Float_t intercept = 0.;
01257         Float_t prevSlope = 0.;
01258         Float_t prevIntercept = 0.;
01259         
01260         //arrays to hold the information for fitting the straight lines
01261         //weight each plane by 1/charge
01262         Float_t tpos[10];
01263         Float_t zpos[10];
01264         Float_t weight[10];
01265         Float_t residual[10];
01266         Int_t planeNum[10];
01267         Int_t muonPlanesInSet = fMuonPlanesInSet;
01268         
01269         //find the number of valid muon planes
01270         Int_t validPlaneCnt = 0;
01271         while( (plane = validPlaneItr()) ){
01272                 MSG("AlgDeMuxBeam", Msg::kDebug) << " on plane " << plane->GetPlaneNumber() << " type " 
01273                                                                    << DmxPlaneTypes::GetPlaneTypeString(plane->GetPlaneType()) 
01274                                                                    << endl;
01275                 if(plane->GetPlaneType()==DmxPlaneTypes::kMuon) ++validPlaneCnt;
01276         }
01277         
01278         MSG("AlgDeMuxBeam", Msg::kDebug) << "num valid muon planes = " << validPlaneCnt << endl;
01279         
01280         //make sure you dont have fewer valid planes than the default expected
01281         if(validPlaneCnt<muonPlanesInSet) muonPlanesInSet = validPlaneCnt;
01282         
01283         validPlaneItr.ResetFirst();
01284         
01285         //flag to reset valid muon planes if they are determined to be misreconstructions
01286         bool setAll = false;
01287 
01288         //loop over the valid planes and get the first n valid muon planes
01289         while( validPlaneItr.IsValid() && ctr<muonPlanesInSet){
01290                 plane = validPlaneItr.Ptr();
01291                 if(plane->GetPlaneType()==DmxPlaneTypes::kMuon){
01292                         planeNum[ctr] = plane->GetPlaneNumber();
01293                         zpos[ctr] = plane->GetZPosition();
01294                         tpos[ctr] = plane->GetCoG();
01295                         weight[ctr] = 1./plane->GetPlaneCharge();
01296                         ++ctr;
01297                 }
01298                 validPlaneItr.Next();
01299         }//end loop to fill array for first n planes
01300         
01301         //find the fit for the first n planes and look for 
01302         //planes with large residuals.  repeat until planes with 
01303         //large residuals are removed
01304         FindFitOverNPlanes(zpos,tpos,weight,residual,slope,intercept,ctr,planeNum);
01305         
01306         //loop over the weights and if any are 0, then set the setAll flag
01307         for(Int_t i = 0; i<ctr; ++i){
01308                 if(weight[i]==0.) setAll = true;
01309         }
01310         
01311         if(validPlaneCnt == muonPlanesInSet) planeNum[ctr-1] = status->GetEndPlaneNumber();
01312         if(status->GetMuonStartPlaneNumber() < planeNum[0] && !status->GetMultipleMuon() ) 
01313                 planeNum[0] = status->GetMuonStartPlaneNumber();
01314         
01315         //check that the slope seems reasonable - if not use the last good 
01316         //slope and intercept
01317         if(TMath::Abs(slope) > fMuonSlopeLimit){
01318                 MSG("AlgDeMuxBeam", Msg::kDebug) << "slope = " << slope << "/" << fMuonSlopeLimit 
01319                                                                                 << "reset slope to " << fFinalShowerRegionSlope << endl;
01320                 slope = fFinalShowerRegionSlope;
01321                 intercept = fFinalShowerRegionIntercept;
01322         }
01323         
01324         //set the initial muon region slope and intercept variables
01325         fInitialMuonRegionSlope = slope;
01326         fInitialMuonRegionIntercept = intercept;
01327         prevSlope = slope;
01328         prevIntercept = intercept;
01329         
01330         //set the first planes to the slope and intercept found
01331         planeItr.GetSet()->Slice(planeNum[0], planeNum[ctr-1]+1);
01332         planeItr.GetSet()->Update();
01333         SetMuonRegionWindow(planeItr, slope, intercept, setAll);
01334         planeItr.GetSet()->ClearSlice(false);
01335         
01336         //back the iterator up fMuonPlanesInSet-1 places, unless the are only
01337         //fMuonPlanesInSet.  in that case, just return because the work here is 
01338         //done
01339         if(validPlaneCnt > muonPlanesInSet){
01340                 validPlaneItr.Prev();
01341                 MSG("AlgDeMuxBeam", Msg::kDebug) << validPlaneItr.Ptr()->GetPlaneNumber() << "/" << planeNum[1] << endl; 
01342                 while(validPlaneItr.Ptr()->GetPlaneNumber() > planeNum[1]){
01343                         validPlaneItr.Prev();
01344                         MSG("AlgDeMuxBeam", Msg::kDebug) << validPlaneItr.Ptr()->GetPlaneNumber() << "/" << planeNum[1] << endl; 
01345                 }
01346         }
01347         else return;
01348 
01349         //now demux the event 
01350         while(loopCtr < (validPlaneCnt - muonPlanesInSet) ){
01351                 
01352                 setAll = false;
01353                 
01354                 ctr = 0;
01355                         
01356                 MSG("AlgDeMuxBeam", Msg::kDebug) << "find new window" << endl;
01357                 
01358                 while( validPlaneItr.IsValid() && ctr < muonPlanesInSet){
01359                         
01360                         plane = validPlaneItr.Ptr();
01361                         
01362                         MSG("AlgDeMuxBeam", Msg::kDebug) << "plane number = " << plane->GetPlaneNumber()
01363                                                                                          << endl;
01364                         
01365                         if(plane->GetPlaneType() == DmxPlaneTypes::kMuon){ 
01366         
01367                                 planeNum[ctr] = plane->GetPlaneNumber();
01368                                 tpos[ctr] = plane->GetCoG();
01369                                 zpos[ctr] = plane->GetZPosition();
01370                                 weight[ctr] = 1./plane->GetPlaneCharge();
01371                                 ++ctr;
01372                                 MSG("AlgDeMuxBeam", Msg::kDebug) << "plane number = " << plane->GetPlaneNumber()
01373                                                                                                  << " z = "  << zpos[ctr-1] << " cog = " << tpos[ctr-1]
01374                                                                                          << endl;
01375                         }
01376                         
01377                         validPlaneItr.Next();
01378                 }//end loop over valid planes
01379                 
01380                 //find the straight line to valid muon planes
01381                 FindFitOverNPlanes(zpos, tpos, weight, residual, slope, intercept, ctr, planeNum);
01382                 MSG("AlgDeMuxBeam", Msg::kDebug) << "slope = " << slope 
01383                                                                                  << " intercept = " << intercept << endl;
01384                 
01385                 //loop over the weights and if any are 0, then set the setAll flag
01386                 for(Int_t i = 0; i<ctr; ++i){
01387                         if(weight[i]==0.) setAll = true;
01388                 }
01389                                 
01390                 //check that the slope seems reasonable - if not use the last good 
01391                 //slope and intercept
01392                 if(TMath::Abs(slope) > fMuonSlopeLimit){
01393                         MSG("AlgDeMuxBeam", Msg::kDebug) << "slope = " << slope << "/" << fMuonSlopeLimit 
01394                                                                                         << "reset slope to " << prevSlope << endl;
01395                         slope = prevSlope;
01396                         intercept = prevIntercept;
01397                 }
01398                 
01399                 //check to see if this is the last loop.  if it is, make sure to set all unset planes
01400                 //just use the fit found for the last window of valid planes
01401                 if(loopCtr+1 == validPlaneCnt - muonPlanesInSet) 
01402                         planeNum[ctr-1] = status->GetEndPlaneNumber();
01403                 
01404                 MSG("AlgDeMuxBeam", Msg::kDebug) << "loopCtr = " << loopCtr 
01405                                                                                 << " valid planes = " << validPlaneCnt
01406                                                                                 << " last plane in set = " << planeNum[ctr-1] 
01407                                                                                 << " last plane in event " << status->GetEndPlaneNumber() << endl;
01408                                 
01409                 //set the planes from the last set plane to the current one
01410                 planeItr.GetSet()->Slice(planeNum[ctr-2]+1, planeNum[ctr-1]);
01411                 planeItr.GetSet()->Update();
01412                 SetMuonRegionWindow(planeItr, slope, intercept, setAll);
01413                 planeItr.GetSet()->ClearSlice(false);
01414                 
01415                 ++loopCtr;
01416                 
01417                 prevSlope = slope;
01418                 prevIntercept = intercept;
01419                 
01420                 //back the iterator up 
01421                 validPlaneItr.Prev();
01422                 while( validPlaneItr.Ptr()->GetPlaneNumber() > planeNum[1]) validPlaneItr.Prev();
01423                 
01424         }//end loop over windows
01425         
01426         planeItr.GetSet()->ClearSlice(false);
01427         return;
01428 }

void AlgDeMuxBeam::UseReverseMuonSlidingWindow DmxPlaneItr &  planeItr,
DmxPlaneItr &  validPlaneItr,
DmxStatus status
[private]
 

void AlgDeMuxBeam::UseShowerSlidingWindow DmxPlaneItr &  planeItr,
DmxPlaneItr &  validPlaneItr,
DmxStatus status
[private]
 

Definition at line 974 of file AlgDeMuxBeam.cxx.

References fFinalShowerRegionIntercept, fFinalShowerRegionSlope, FindFitOverNPlanes(), fMuonSlopeLimit, fMuonStartPlaneNumber, DmxPlane::GetCoG(), DmxStatus::GetEndPlaneNumber(), DmxStatus::GetMultipleMuon(), DmxPlane::GetPlaneCharge(), DmxPlane::GetPlaneNumber(), DmxPlane::GetPlaneType(), DmxStatus::GetVertexPlaneNumber(), DmxPlane::GetZPosition(), MSG, and SetShowerRegionWindow().

Referenced by RunAlg().

00977 {
00978         MSG("AlgDeMuxBeam", Msg::kDebug) << "In UseShowerSlidingWindow" << endl;
00979 
00980   //figure out how many windows your are going to need for the shower region.  
00981   //you need to find your lever arm
00982   //for the window too - it is either fPlanesInSet or the size of the validPlaneItr set.
00983   //do like in the cosmic algorithm, start from the vertex and go on.
00984   //only use the window until you get to the start of the muon track.
00985   validPlaneItr.ResetFirst();
00986 
00987   DmxPlane *plane = 0;
00988   
00989   validPlaneItr.ResetFirst();
00990   
00991   Int_t loopCtr = 0;
00992   Int_t ctr = 0;
00993   Float_t slope = 0.;
00994   Float_t intercept = 0.;
00995   
00996   //arrays to hold the information for fitting the straight lines
00997   //weight each plane by 1/charge
00998   Float_t tpos[10];
00999   Float_t zpos[10];
01000   Float_t weight[10];
01001   Float_t residual[10];
01002   Int_t planeNum[10];
01003   Int_t planesInSet = fPlanesInSet;
01004   Float_t minResidual = 1.e20;
01005   Float_t minResidualTPos = 0.;
01006   
01007   //find the number of valid planes - in the shower region both muon and shower type planes 
01008   //are ok to use
01009   Int_t validPlaneCnt = validPlaneItr.SizeSelect();
01010   MSG("AlgDeMuxBeam", Msg::kDebug) << "num valid planes = " << validPlaneCnt << endl;
01011   
01012   if(validPlaneCnt==0){
01013           MSG("AlgDeMuxBeam", Msg::kDebug) << "no valid planes in shower window" << endl;
01014           return;
01015   }
01016   
01017   //make sure you dont have fewer valid planes than the default expected
01018   if(validPlaneCnt<planesInSet) planesInSet = validPlaneCnt;
01019   
01020   validPlaneItr.ResetFirst();
01021   
01022   //flag to reset valid muon planes if they are determined to be misreconstructions
01023   bool setAll = false;
01024   
01025   //loop over the valid planes and get the first n valid muon planes
01026   while( validPlaneItr.IsValid() && ctr<planesInSet){
01027           plane = validPlaneItr.Ptr();
01028           planeNum[ctr] = plane->GetPlaneNumber();
01029           zpos[ctr] = plane->GetZPosition();
01030           tpos[ctr] = plane->GetCoG();
01031           weight[ctr] = 1./plane->GetPlaneCharge();
01032           ++ctr;
01033           validPlaneItr.Next();
01034   }//end loop to fill array for first n planes
01035   
01036   //find the fit for the first window of n planes.  check to see if the 
01037   //average residual is too big, if so then remove the last plane in the 
01038   //window and redo the fit.
01039   FindFitOverNPlanes(zpos, tpos, weight, residual, slope, intercept, ctr, planeNum);
01040           
01041   //check that the slope seems reasonable - if not use the last good 
01042   //slope and intercept
01043   if(TMath::Abs(slope) > fMuonSlopeLimit){
01044           MSG("AlgDeMuxBeam", Msg::kDebug) << "slope = " << slope << "/" << fMuonSlopeLimit 
01045                                                                           << "reset slope to " << fFinalShowerRegionSlope << endl;
01046           slope = fFinalShowerRegionSlope;
01047           intercept = fFinalShowerRegionIntercept;
01048   }
01049   
01050   //if there are no more planes to do the sliding window, check and see if there 
01051   //looks to be a track.  if no track, set the last plane to be set at the end of the 
01052   //event
01053   if(validPlaneCnt == planesInSet && fMuonStartPlaneNumber<0) 
01054         planeNum[ctr-1] = status->GetEndPlaneNumber();
01055   else if(validPlaneCnt == planesInSet && fMuonStartPlaneNumber>0)
01056           planeNum[ctr-1] = fMuonStartPlaneNumber-1;
01057   if(status->GetVertexPlaneNumber() < planeNum[0] && !status->GetMultipleMuon() ) 
01058         planeNum[0] = status->GetVertexPlaneNumber();
01059   
01060   //set the first planes to the slope and intercept found
01061   planeItr.GetSet()->Slice(planeNum[ctr-2], planeNum[ctr-1]+1);
01062   planeItr.GetSet()->Update();
01063   SetShowerRegionWindow(planeItr, slope, intercept);
01064   planeItr.GetSet()->ClearSlice(false);
01065   
01066   //back the iterator up fMuonPlanesInSet-1 places, unless the are only
01067   //fMuonPlanesInSet.  in that case, just return because the work here is 
01068   //done
01069   if(validPlaneCnt > planesInSet){
01070           validPlaneItr.Prev();
01071           MSG("AlgDeMuxBeam", Msg::kDebug) << validPlaneItr.Ptr()->GetPlaneNumber() << "/" << planeNum[1] << endl; 
01072           while(validPlaneItr.Ptr()->GetPlaneNumber() > planeNum[1]){
01073                   validPlaneItr.Prev();
01074                   MSG("AlgDeMuxBeam", Msg::kDebug) << validPlaneItr.Ptr()->GetPlaneNumber() << "/" << planeNum[1] << endl; 
01075           }
01076   }
01077   else return;
01078   
01079   //now demux the event 
01080   while(loopCtr < (validPlaneCnt - planesInSet) ){
01081           
01082           setAll = false;
01083           
01084           ctr = 0;
01085           
01086           MSG("AlgDeMuxBeam", Msg::kDebug) << "find new window" << endl;
01087           
01088           //get the tpos for each of the previously set planes
01089           while( validPlaneItr.IsValid() && ctr < planesInSet-1){
01090                   
01091                   plane = validPlaneItr.Ptr();
01092                   
01093                   MSG("AlgDeMuxBeam", Msg::kDebug) << "plane number = " << plane->GetPlaneNumber()
01094                           << endl;
01095                   
01096                   tpos[ctr] = plane->GetCoG();
01097                   zpos[ctr] = plane->GetZPosition();
01098                   weight[ctr] = 1./plane->GetPlaneCharge();
01099                   planeNum[ctr] = plane->GetPlaneNumber();
01100                   ++ctr;
01101                   MSG("AlgDeMuxBeam", Msg::kDebug) << "plane number = " << plane->GetPlaneNumber()
01102                                                                          << " z = "  << zpos[ctr-1] << " cog = " << tpos[ctr-1]
01103                                                                          << endl;
01104                   validPlaneItr.Next();
01105           }//end loop over valid planes
01106 
01107           //fit the previously set planes
01108           FindFitOverNPlanes(zpos, tpos, weight, residual, slope, intercept, ctr, planeNum);
01109 
01110           //now check out the last plane - if it is a shower plane, then loop over the 3 best hypotheses
01111           //to see which is closest to the line fit to the previously set planes
01112           plane = validPlaneItr.Ptr();
01113           
01114           MSG("AlgDeMuxBeam", Msg::kDebug) << "plane number = " << plane->GetPlaneNumber()
01115                   << endl;
01116           
01117           //get the plane info that is independant of plane type
01118           zpos[ctr] = plane->GetZPosition();
01119           weight[ctr] = 1./plane->GetPlaneCharge();
01120           planeNum[ctr] = plane->GetPlaneNumber();
01121           
01122           minResidual = 1.e20;
01123           //loop over the best 3 hyps to see if any of them fit well with the track
01124           for(Int_t i = 0; i<3; ++i){
01125                   
01126                   tpos[ctr] = plane->GetCoG();
01127                   minResidualTPos = tpos[ctr];
01128                   
01129                   if(plane->GetPlaneType() == DmxPlaneTypes::kShower){
01130                           if(i<1) tpos[ctr] = dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG();
01131                           else if(i<2) tpos[ctr] = dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG();
01132                           else if(i<3) tpos[ctr] = dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG();
01133                   }
01134                   //muon planes only have one possible cog
01135                   else break;
01136                   
01137                   residual[ctr] = TMath::Abs(tpos[ctr] - slope*zpos[ctr]+intercept);
01138 
01139                   //check the residual for the last plane
01140                   if(residual[ctr]<minResidual){
01141                           minResidual = residual[ctr];
01142                           minResidualTPos = tpos[ctr];
01143                   }
01144           }//end loop over best 3 hypotheses for this plane
01145 
01146           //use the transverse position with the minimum residual
01147           tpos[ctr] = minResidualTPos;
01148           
01149           //increment the ctr for later
01150           ++ctr;
01151           
01152           //found the best fit of the hypotheses, so now fit the entire set
01153           FindFitOverNPlanes(zpos, tpos, weight, residual, slope, intercept, ctr, planeNum);
01154           MSG("AlgDeMuxBeam", Msg::kDebug) << "fit over all planes in window slope = " << slope 
01155                                                                           << " intercept = " << intercept << endl;
01156         
01157           //check that the slope seems reasonable - if not use the last good 
01158           //slope and intercept
01159           if(TMath::Abs(slope) > fMuonSlopeLimit){
01160                   MSG("AlgDeMuxBeam", Msg::kDebug) << "slope = " << slope << "/" << fMuonSlopeLimit 
01161                                                                                   << "reset slope to " << fFinalShowerRegionSlope << endl;
01162                   slope = fFinalShowerRegionSlope;
01163                   intercept = fFinalShowerRegionIntercept;
01164           }
01165 
01166           //check to see if this is the last loop.  if it is, make sure to set all unset planes
01167           //just use the fit found for the last window of valid planes - if no track region 
01168           //is present, just set all the remaining planes in the detector - what can it hurt?
01169           if(loopCtr+1 == validPlaneCnt - planesInSet && fMuonStartPlaneNumber<0.) 
01170                   planeNum[ctr-1] = 486;
01171           else if(loopCtr+1 == validPlaneCnt - planesInSet && fMuonStartPlaneNumber>0.) 
01172                   planeNum[ctr-1] = fMuonStartPlaneNumber-1;
01173           
01174           MSG("AlgDeMuxBeam", Msg::kDebug) << "loopCtr = " << loopCtr 
01175                                                                           << " valid planes = " << validPlaneCnt
01176                                                                           << " last plane in set = " << planeNum[ctr-1] 
01177                                                                           << " last plane in event " << status->GetEndPlaneNumber() << endl;
01178           
01179           planeItr.GetSet()->Slice(planeNum[ctr-2]+1, planeNum[ctr-1]+1);
01180           planeItr.GetSet()->Update();
01181           SetShowerRegionWindow(planeItr, slope, intercept);
01182           planeItr.GetSet()->ClearSlice(false);
01183           
01184           ++loopCtr;
01185           
01186           //set the final shower region slope and intercept to the current values
01187           fFinalShowerRegionSlope = slope;
01188           fFinalShowerRegionIntercept = intercept;
01189           
01190           //back the iterator up 
01191           validPlaneItr.Prev();
01192           while( validPlaneItr.Ptr()->GetPlaneNumber() > planeNum[1]) validPlaneItr.Prev();
01193           
01194   }//end loop over windows
01195   
01196   planeItr.GetSet()->ClearSlice(false);
01197     
01198   return;
01199 }


Member Data Documentation

Float_t AlgDeMuxBeam::fDigitResetCut [private]
 

Definition at line 44 of file AlgDeMuxBeam.h.

Referenced by ReconcileShowerAndMuonRegions(), and RunAlg().

Float_t AlgDeMuxBeam::fFinalShowerRegionIntercept [private]
 

Definition at line 41 of file AlgDeMuxBeam.h.

Referenced by DeMuxFirstNPlanesTest(), and UseShowerSlidingWindow().

Float_t AlgDeMuxBeam::fFinalShowerRegionSlope [private]
 

Definition at line 40 of file AlgDeMuxBeam.h.

Referenced by DeMuxFirstNPlanesTest(), ReconcileShowerAndMuonRegions(), UseMuonSlidingWindow(), and UseShowerSlidingWindow().

Float_t AlgDeMuxBeam::fInitialMuonRegionIntercept [private]
 

Definition at line 43 of file AlgDeMuxBeam.h.

Referenced by UseMuonSlidingWindow().

Float_t AlgDeMuxBeam::fInitialMuonRegionSlope [private]
 

Definition at line 42 of file AlgDeMuxBeam.h.

Referenced by ReconcileShowerAndMuonRegions(), and UseMuonSlidingWindow().

Int_t AlgDeMuxBeam::fMaxBadResidual [private]
 

Definition at line 45 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Float_t AlgDeMuxBeam::fMaxMuonRemovalFraction [private]
 

Definition at line 47 of file AlgDeMuxBeam.h.

Referenced by FindFitOverNPlanes(), and RunAlg().

Float_t AlgDeMuxBeam::fMaxResidual [private]
 

Definition at line 46 of file AlgDeMuxBeam.h.

Referenced by FindFitOverNPlanes(), and RunAlg().

Int_t AlgDeMuxBeam::fMaxStripAdjustment [private]
 

Definition at line 48 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Float_t AlgDeMuxBeam::fMinMatedChargeFrac [private]
 

Definition at line 50 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Int_t AlgDeMuxBeam::fMinMuonPlanesRequired [private]
 

Definition at line 49 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Int_t AlgDeMuxBeam::fMuonPlanesInSet [private]
 

Definition at line 51 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Float_t AlgDeMuxBeam::fMuonSlopeLimit [private]
 

Definition at line 52 of file AlgDeMuxBeam.h.

Referenced by RunAlg(), UseMuonSlidingWindow(), and UseShowerSlidingWindow().

Int_t AlgDeMuxBeam::fMuonStartPlaneNumber [private]
 

Definition at line 53 of file AlgDeMuxBeam.h.

Referenced by ReconcileShowerAndMuonRegions(), RunAlg(), SetMuonRegionWindow(), SetShowerRegionWindow(), and UseShowerSlidingWindow().

Float_t AlgDeMuxBeam::fMuonStartPlaneZPos [private]
 

Definition at line 54 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Int_t AlgDeMuxBeam::fNumberOfHypotheses [private]
 

Definition at line 58 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Int_t AlgDeMuxBeam::fPlanesInSet [private]
 

Definition at line 55 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Float_t AlgDeMuxBeam::fShowerMuonTransverseDifference [private]
 

Definition at line 59 of file AlgDeMuxBeam.h.

Referenced by ReconcileShowerAndMuonRegions(), and RunAlg().

Int_t AlgDeMuxBeam::fStrayCut [private]
 

Definition at line 56 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

Int_t AlgDeMuxBeam::fStrayPlanes [private]
 

Definition at line 57 of file AlgDeMuxBeam.h.

Referenced by RunAlg().

VldContext AlgDeMuxBeam::fVldContext [private]
 

Definition at line 60 of file AlgDeMuxBeam.h.

Referenced by DeMuxFirstNPlanesTest(), FindDigitCoG(), ReconcileShowerAndMuonRegions(), and RunAlg().


The documentation for this class was generated from the following files:
Generated on Thu Nov 1 15:55:22 2007 for loon by  doxygen 1.3.9.1