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

AlgSubShowerSRList Class Reference

#include <AlgSubShowerSRList.h>

Inheritance diagram for AlgSubShowerSRList:

AlgBase List of all members.

Public Member Functions

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

Static Public Member Functions

NavKey StripKeyFromPlane (const CandStripHandle *)

Private Member Functions

Bool_t FindCluster (TObjArray *, TObjArray *, Int_t)
Bool_t TestOverLap (TObjArray *, CandHandle &, const CandSliceHandle *)
std::vector< windowTransCluster (std::vector< window >, Int_t)
std::vector< windowHoughTransCluster (std::vector< window >, Int_t)
Bool_t MergeCluster (TObjArray *, CandHandle &, Int_t, Bool_t test=false)
Bool_t CleanUp (TObjArray *, CandHandle &, Int_t, const CandSliceHandle *cslice=NULL)
Bool_t FormHalo (TObjArray *, CandHandle &, CandContext &, AlgHandle &, const CandSliceListHandle *, Int_t)
Bool_t BestHough (std::vector< window >, Double_t *, Bool_t)

Private Attributes

Double_t fMergeFracEnergyLimit
Double_t fMergeBestFracBoundary
Double_t fMergeBestFracWithin
Double_t fMergeBestFracCross
Double_t fLongWindowMipCut
Int_t fMaxPlaneGap

Constructor & Destructor Documentation

AlgSubShowerSRList::AlgSubShowerSRList  ) 
 

Definition at line 57 of file AlgSubShowerSRList.cxx.

00057                                        :
00058   fMergeFracEnergyLimit(0.1),fMergeBestFracBoundary(0.8),
00059   fMergeBestFracWithin(0.6),fMergeBestFracCross(0.9),
00060   fLongWindowMipCut(0.0),fMaxPlaneGap(2)
00061 {
00062 }

AlgSubShowerSRList::~AlgSubShowerSRList  )  [virtual]
 

Definition at line 65 of file AlgSubShowerSRList.cxx.

00066 {
00067 }


Member Function Documentation

Bool_t AlgSubShowerSRList::BestHough std::vector< window ,
Double_t *  ,
Bool_t 
[private]
 

Definition at line 3109 of file AlgSubShowerSRList.cxx.

References MSG, name, CandHandle::Print(), and STRIPWIDTHINMETRES.

Referenced by HoughTransCluster(), and TransCluster().

03111 {
03112 
03113   std::vector<window>::iterator winIterBeg = winVec.begin();
03114   std::vector<window>::iterator winIterEnd = winVec.end();
03115   
03116   //get extrema of windows:
03117   Int_t MaxPlane = 0;
03118   Int_t MinPlane = 500;
03119   Double_t MaxStrip = -5.;
03120   Double_t MinStrip = 5.;
03121   //total PH:
03122   Double_t totPH = 0;
03123   //PH of window with max PH:
03124   Double_t maxWinPH = 0;
03125   //plane with maximum PH, and value of max PH:
03126   Int_t maxPlanePos = -1;
03127   Double_t maxPlanePosPH = 0;
03128   //plane by plane sum PH:
03129   Double_t PlanePH[500] = {0};
03130   while(winIterBeg!=winIterEnd){
03131     if(MaxPlane<winIterBeg->plane) MaxPlane = winIterBeg->plane;
03132     if(MinPlane>winIterBeg->plane) MinPlane = winIterBeg->plane;
03133     if(MaxStrip<winIterBeg->upper_tpos) MaxStrip = winIterBeg->upper_tpos;
03134     if(MinStrip>winIterBeg->lower_tpos) MinStrip = winIterBeg->lower_tpos;
03135     if(maxWinPH<winIterBeg->ph) maxWinPH = winIterBeg->ph;
03136     totPH+=winIterBeg->ph;
03137     PlanePH[winIterBeg->plane] += winIterBeg->ph;
03138     if(PlanePH[winIterBeg->plane]>maxPlanePosPH) {
03139       maxPlanePos = winIterBeg->plane;
03140       maxPlanePosPH = PlanePH[maxPlanePos];
03141     }
03142     winIterBeg++;
03143   }
03144   
03145   //window tpos position with max PH, and value of max PH
03146   Double_t maxWindowPos = 0.;
03147   Double_t maxWindowPH = 0.;
03148   winIterBeg = winVec.begin();
03149   while(winIterBeg!=winIterEnd){
03150     if(winIterBeg->plane==maxPlanePos){
03151       if(winIterBeg->ph>maxWindowPH){
03152         maxWindowPos = winIterBeg->phpos;
03153         maxWindowPH = winIterBeg->ph;
03154       }
03155     }
03156     winIterBeg++;
03157   }
03158 
03159   if(winVec.size()<=1 || MinPlane==MaxPlane){
03160     MCV[0] = 0;
03161     MCV[1] = maxWindowPos;
03162     MCV[2] = maxPlanePos;
03163     MCV[3] = 0;
03164     MCV[4] = 0;
03165     MCV[5] = 0;
03166     MCV[6] = maxWindowPos;
03167     MCV[7] = maxPlanePos;
03168     MCV[8] = 0;
03169     MCV[9] = 0;
03170     MCV[10] = 0;
03171     MCV[11] = maxWindowPos;
03172     MCV[12] = 0;
03173     MCV[13] = maxWindowPos;
03174     return true;
03175   }
03176 
03177   Double_t TPosWin = MaxStrip-MinStrip+0.041;
03178 
03179   MSG("SubShowerSR",Msg::kDebug) << "Hough extrema: plane " << MinPlane 
03180                                  << " to " << MaxPlane
03181                                  << " strip tpos " << MinStrip 
03182                                  << " to " << MaxStrip << endl;
03183   
03184   //define "x=0" to be at MinPlane-2, 
03185   //so y-intercept is strip value at MinPlane-2
03186   //gradient is in units of Delta(tpos) per plane
03187 
03188   TH2F *houghHist = new TH2F("houghHist","Hough Histogram",
03189                              Int_t(TPosWin/STRIPWIDTHINMETRES) + 
03190                              MaxPlane-MinPlane+2,
03191                              -2.*TPosWin/Float_t(MaxPlane-MinPlane+2),
03192                              2.*TPosWin/Float_t(MaxPlane-MinPlane+2),
03193                              Int_t(2.*TPosWin/STRIPWIDTHINMETRES),
03194                              MinStrip-TPosWin,
03195                              MaxStrip+TPosWin);
03196 
03197   TH2F *phHoughHist = new TH2F("phHoughHist","PH Weighted Hough Histogram",
03198                                Int_t(TPosWin/STRIPWIDTHINMETRES) + 
03199                                MaxPlane-MinPlane+2,
03200                                -2.*TPosWin/Float_t(MaxPlane-MinPlane+2),
03201                                2.*TPosWin/Float_t(MaxPlane-MinPlane+2),
03202                                Int_t(2.*TPosWin/STRIPWIDTHINMETRES),
03203                                MinStrip-TPosWin,
03204                                MaxStrip+TPosWin);
03205   
03206   winIterBeg = winVec.begin();
03207   while(winIterBeg!=winIterEnd){
03208     Int_t plane = winIterBeg->plane;
03209     Double_t strip = winIterBeg->phpos;
03210     Double_t ph = winIterBeg->ph;
03211     Int_t lastBin = -1;
03212     for(Double_t c=MinStrip-TPosWin; c<=MaxStrip+TPosWin;
03213         c+=STRIPWIDTHINMETRES){
03214       Double_t m = (strip - c)/Float_t(plane-MinPlane+2);
03215       MSG("SubShowerSR",Msg::kVerbose) << "Hough entries: " << m << " " 
03216                                        << c << " " << ph << endl;      
03217       if(houghHist->FindBin(m,c)!=lastBin){
03218         houghHist->Fill(m,c,1);
03219         phHoughHist->Fill(m,c,TMath::Sqrt(ph));
03220         lastBin = houghHist->FindBin(m,c);
03221       }
03222     }
03223     winIterBeg++;
03224   }
03225 
03226   Int_t maxBin = houghHist->GetMaximumBin();
03227   Float_t maxVal = houghHist->GetMaximum();
03228   Int_t xbin = maxBin%(houghHist->GetNbinsX()+2);
03229   Int_t ybin = maxBin/(houghHist->GetNbinsX()+2);
03230   Int_t phMaxBin = phHoughHist->GetMaximumBin();
03231   Float_t phMaxVal = phHoughHist->GetMaximum();
03232   Int_t phXbin = phMaxBin%(phHoughHist->GetNbinsX()+2);
03233   Int_t phYbin = phMaxBin/(phHoughHist->GetNbinsX()+2);
03234 
03235   Double_t totx = 0;
03236   Double_t sumx=0,sumx2=0;
03237   Double_t ptotx = 0;
03238   Double_t psumx=0,psumx2=0;
03239 
03240   Double_t toty=0;
03241   Double_t sumy=0,sumy2=0;
03242   Double_t ptoty = 0;
03243   Double_t psumy=0,psumy2=0;
03244 
03245   for(int xx = 1;xx<=houghHist->GetNbinsX();xx++){
03246     for(int yy = 1;yy<=houghHist->GetNbinsY();yy++){
03247 
03248       if(houghHist->GetBinContent(xx,yy)>maxVal*0.75) {
03249         
03250         totx += houghHist->GetBinContent(xx,yy);
03251         sumx += ( houghHist->GetBinContent(xx,yy) * 
03252                   houghHist->GetXaxis()->GetBinCenter(xx)  );
03253         sumx2 += ( houghHist->GetBinContent(xx,yy) * 
03254                    houghHist->GetXaxis()->GetBinCenter(xx)  *
03255                    houghHist->GetXaxis()->GetBinCenter(xx)  );
03256         
03257         toty += houghHist->GetBinContent(xx,yy);
03258         sumy += ( houghHist->GetBinContent(xx,yy) * 
03259                   houghHist->GetYaxis()->GetBinCenter(yy)  );
03260         sumy2 += ( houghHist->GetBinContent(xx,yy) * 
03261                    houghHist->GetYaxis()->GetBinCenter(yy)  *
03262                    houghHist->GetYaxis()->GetBinCenter(yy)  );
03263       }
03264 
03265       if(phHoughHist->GetBinContent(xx,yy)>phMaxVal*0.75) {
03266 
03267         ptotx += phHoughHist->GetBinContent(xx,yy);
03268         psumx += ( phHoughHist->GetBinContent(xx,yy) * 
03269                    phHoughHist->GetXaxis()->GetBinCenter(xx)  );
03270         psumx2 += ( phHoughHist->GetBinContent(xx,yy) * 
03271                     phHoughHist->GetXaxis()->GetBinCenter(xx)  *
03272                     phHoughHist->GetXaxis()->GetBinCenter(xx)  );
03273         
03274         ptoty += phHoughHist->GetBinContent(xx,yy);
03275         psumy += ( phHoughHist->GetBinContent(xx,yy) * 
03276                    phHoughHist->GetYaxis()->GetBinCenter(yy)  );
03277         psumy2 += ( phHoughHist->GetBinContent(xx,yy) * 
03278                     phHoughHist->GetYaxis()->GetBinCenter(yy)  *
03279                     phHoughHist->GetYaxis()->GetBinCenter(yy)  );
03280       }
03281 
03282     }
03283   }
03284 
03285   MCV[2] = MinPlane - 2;
03286   if(totx>0) {
03287     MCV[0] = sumx/totx;
03288     MCV[3] = (sumx2/totx - TMath::Power(MCV[0],2))/totx;
03289     if(MCV[3]>0) MCV[3] = TMath::Sqrt(MCV[3]);
03290     else MCV[3] = 0;
03291   }
03292   if(toty>0) {
03293     MCV[1] = sumy/toty;
03294     MCV[4] = (sumy2/toty - TMath::Power(MCV[1],2))/toty;
03295     if(MCV[4]>0) MCV[4] = TMath::Sqrt(MCV[4]);
03296     else MCV[4] = 0;
03297   }
03298   if(MCV[3]<houghHist->GetXaxis()->GetBinWidth(1))
03299     MCV[3] = houghHist->GetXaxis()->GetBinWidth(1);
03300   if(MCV[4]<houghHist->GetYaxis()->GetBinWidth(1))
03301     MCV[4] = houghHist->GetYaxis()->GetBinWidth(1);
03302 
03303   MCV[7] = MinPlane - 2;
03304   if(ptotx>0) {
03305     MCV[5] = psumx/ptotx;
03306     MCV[8] = (psumx2/ptotx - TMath::Power(MCV[5],2))/ptotx;
03307     if(MCV[8]>0) MCV[8] = TMath::Sqrt(MCV[8]);
03308     else MCV[8] = 0;
03309   }
03310   if(ptoty>0) {
03311     MCV[6] = psumy/ptoty;
03312     MCV[9] = (psumy2/ptoty - TMath::Power(MCV[6],2))/ptoty;
03313     if(MCV[9]>0) MCV[9] = TMath::Sqrt(MCV[9]);
03314     else MCV[9] = 0;  
03315   }
03316   if(MCV[8]<phHoughHist->GetXaxis()->GetBinWidth(1))
03317     MCV[8] = phHoughHist->GetXaxis()->GetBinWidth(1);  
03318   if(MCV[9]<phHoughHist->GetYaxis()->GetBinWidth(1))
03319     MCV[9] = phHoughHist->GetYaxis()->GetBinWidth(1);
03320 
03321   MCV[10] = houghHist->GetXaxis()->GetBinCenter(xbin);
03322   MCV[11] = houghHist->GetYaxis()->GetBinCenter(ybin);
03323   MCV[12] = phHoughHist->GetXaxis()->GetBinCenter(phXbin);
03324   MCV[13] = phHoughHist->GetYaxis()->GetBinCenter(phYbin);
03325 
03326   if(makeEPS) {
03327     gStyle->SetOptStat(0);
03328     TCanvas *can = new TCanvas();
03329     can->Divide(2,2);
03330     can->cd(1);
03331     houghHist->Draw("COLZ");
03332     can->cd(2);
03333     phHoughHist->Draw("COLZ");
03334     can->cd(3);
03335     houghHist->Draw("LEGO2");
03336     can->cd(4);
03337     phHoughHist->Draw("LEGO2");
03338     Int_t countr = 0;
03339     Bool_t noPlot = true;
03340     while(noPlot){
03341       char name[256];
03342       sprintf(name,"best_%i.root",countr);
03343       std::ifstream Test(name);
03344       if(!Test) { //if files does not exist:
03345         can->Print(name);
03346         noPlot = false;
03347       }
03348       countr+=1;
03349     }
03350     delete can;
03351   }
03352   delete houghHist;
03353   delete phHoughHist;
03354 
03355   MSG("SubShowerSR",Msg::kDebug) 
03356     << "Before Cuts in BestHough:"
03357     << "\nHough gradient, intercept, plane vertex: " 
03358     << MCV[0] << "+/-" << MCV[3] << " " 
03359     << MCV[1] << "+/-" << MCV[4] << " " << MCV[2]
03360     << "\nPH Hough gradient, intercept, plane vertex: " 
03361     << MCV[5] << "+/-" << MCV[8] << " " 
03362     << MCV[6] << "+/-" << MCV[9] << " " << MCV[7] 
03363     << "\n Hough Max Bin Gradient and Intercept Values: "
03364     << MCV[10] << " " << MCV[11] << " "
03365     << MCV[12] << " " << MCV[13] << endl;
03366 
03367   //check that there is a coincidence of 3 or more windows
03368   //and gradient is bigger than error
03369   if(maxVal < 3 || 
03370      (TMath::Abs(MCV[0])-MCV[3]<0 && 
03371       TMath::Abs(MCV[10])-MCV[3]<0)) {
03372     MCV[0] = 0;
03373     MCV[1] = maxWindowPos;
03374     MCV[2] = maxPlanePos;
03375     MCV[3] = 0;
03376     MCV[4] = 0; 
03377     MCV[10] = 0;
03378     MCV[11] = maxWindowPos;
03379   }
03380   
03381   if((phMaxVal - maxWindowPH)/(totPH - maxWindowPH) < 0.1 || 
03382      (TMath::Abs(MCV[5])-MCV[8]<0 ) &&
03383      (TMath::Abs(MCV[12])-MCV[8]<0 )) {
03384     MCV[5] = 0;
03385     MCV[6] = maxWindowPos;
03386     MCV[7] = maxPlanePos;
03387     MCV[8] = 0;
03388     MCV[9] = 0;
03389     MCV[12] = 0;
03390     MCV[13] = maxWindowPos;
03391   }
03392   return true;
03393   
03394 }

Bool_t AlgSubShowerSRList::CleanUp TObjArray *  ,
CandHandle ,
Int_t  ,
const CandSliceHandle cslice = NULL
[private]
 

Definition at line 2568 of file AlgSubShowerSRList.cxx.

References CandHandle::AddDaughterLink(), CandSubShowerSRHandle::GetAveTime(), CandSubShowerSRHandle::GetAvgDev(), CandRecoHandle::GetBegPlane(), CandRecoHandle::GetCandSlice(), CandRecoHandle::GetCharge(), CandStripHandle::GetCharge(), CandHandle::GetDaughterIterator(), CandRecoHandle::GetEndPlane(), CandSubShowerSRHandle::GetEnergy(), Calibrator::GetMIP(), CandHandle::GetNDaughters(), CandRecoHandle::GetNStrip(), CandStripHandle::GetPlane(), CandSubShowerSRHandle::GetPlaneView(), CandStripHandle::GetPlaneView(), CandSubShowerSRHandle::GetSlope(), CandStripHandle::GetStrip(), CandStripHandle::GetTime(), CandStripHandle::GetTPos(), CandRecoHandle::GetVtxU(), CandRecoHandle::GetVtxV(), CandRecoHandle::GetVtxZ(), CandStripHandle::GetZPos(), Calibrator::Instance(), MSG, and CandSubShowerSRHandle::SetEnergy().

Referenced by FormHalo(), and RunAlg().

02570 {
02571   MSG("SubShowerSR", Msg::kDebug) << "Running CleanUp()" << endl;
02572 
02573   Int_t totUnassigned = allStrips->GetLast()+1;
02574   if(totUnassigned==0) return false;
02575 
02576   Calibrator& calibrator=Calibrator::Instance();
02577 
02578   assert(ch.InheritsFrom("CandSubShowerSRListHandle"));
02579   CandSubShowerSRListHandle &csslh = 
02580     dynamic_cast<CandSubShowerSRListHandle &>(ch);
02581 
02582   //Get planeview for this cleanup
02583   TObject *firstObj = allStrips->At(0);
02584   assert(firstObj->InheritsFrom("CandStripHandle"));
02585   CandStripHandle *firstStp = dynamic_cast<CandStripHandle*>(firstObj);
02586   PlaneView::PlaneView_t pv = firstStp->GetPlaneView();
02587   MSG("SubShowerSR", Msg::kDebug) << "PlaneView = " << pv << endl;
02588 
02589   //Any changes made?
02590   Bool_t anyChanges = false;
02591   //once strips have been assigned do not try to assign again:
02592   Bool_t *useStrip = new Bool_t[totUnassigned];
02593   Bool_t *assignedStrip = new Bool_t[totUnassigned];
02594   
02595   for(int i=0;i<totUnassigned;i++) {
02596     assignedStrip[i] = false;
02597     //if cslice defined, check that strip is part of slice:
02598     if(cslice){
02599       useStrip[i] = false;
02600       TObject *tobj = allStrips->At(i);
02601       CandStripHandle *unassigned = dynamic_cast<CandStripHandle*>(tobj);
02602       CandStripHandleItr stpSliceItr(cslice->GetDaughterIterator());
02603       while(CandStripHandle *stp = stpSliceItr()) {
02604         if(*stp==*unassigned) {
02605           useStrip[i] = true;
02606           break;
02607         }
02608       }
02609     }
02610     else useStrip[i] = true;
02611   }
02612   MSG("SubShowerSR", Msg::kDebug) << "Checking " << totUnassigned 
02613                                   << " strips" << endl;
02614 
02615   //going to check if any isolated strips are nearby within +/- 2 strip
02616   for (Int_t i=0; i<totUnassigned; i++) {
02617     
02618     MSG("SubShowerSR", Msg::kVerbose) << "Checking unassigned strip " 
02619                                       << i << endl;
02620 
02621     TObject *tobj = allStrips->At(i);
02622     if(!useStrip[i]) continue;
02623     MSG("SubShowerSR", Msg::kVerbose) << "Can still use unassigned strip " 
02624                                       << i << endl;
02625 
02626     CandStripHandle *unassigned = dynamic_cast<CandStripHandle*>(tobj);
02627     Float_t *StripDistance = new Float_t[csslh.GetNDaughters()];
02628     Float_t theCharge = 
02629       calibrator.GetMIP(unassigned->GetCharge(CalDigitType::kSigCorr));
02630 
02631     //loop through existing subshowers
02632     Int_t ssCount = 0;
02633     CandSubShowerSRHandleItr subshowerItr(csslh.GetDaughterIterator());
02634     while (CandSubShowerSRHandle *subshower = subshowerItr()) {       
02635 
02636       StripDistance[ssCount] = 99999; //set to 999999 as a flag
02637 
02638       //increment early because of continue statements, later use ssCount-1
02639       ssCount++; 
02640 
02641       //if a slice is given in argument list
02642       //demand that slices are the same
02643       if(cslice){
02644         if(*subshower->GetCandSlice()!=*cslice) continue;
02645       }
02646       else if(TMath::Abs(subshower->GetAveTime() - 
02647                          unassigned->GetTime())*1.0e9 > 100.0) continue;
02648       
02649       //only look at the right planeview subshowers
02650       if(subshower->GetPlaneView()!=pv) continue; 
02651       
02652       MSG("SubShowerSR", Msg::kVerbose) << "SubShower " << ssCount-1 
02653                                         << " in the same planeview" << endl;
02654 
02655       // if plane of strip is more than 1 plane (of same type away)
02656       // don't try to add it to this subshower 
02657       // (also beware of SM boundary in FarDet)
02658       Int_t thePlane = unassigned->GetPlane();
02659       if(thePlane<subshower->GetBegPlane()-2 || 
02660          thePlane>subshower->GetEndPlane()+2 || 
02661          (det==1 && 
02662           ( (subshower->GetBegPlane()>249 && thePlane<249) || 
02663             (subshower->GetEndPlane()<249 && thePlane>249) ))) continue;
02664 
02665       MSG("SubShowerSR", Msg::kVerbose) << "SubShower " << ssCount-1 
02666                                         << " in the same plane range" << endl;
02667  
02668       //loop through strips in subshower
02669       //check for proximity to other strips in subshower
02670       //(on a plane-by-plane basis)
02671       Bool_t checkProximity = false;
02672       Float_t theStrip_tpos = unassigned->GetTPos();
02673       CandStripHandleItr stripItr(subshower->GetDaughterIterator());
02674       while(CandStripHandle *stp = stripItr()){
02675         //check we're on the same plane 
02676         //or on the begin plane if the unassigned plane < begin plane
02677         //or on the end plane if the unassigned plane > end plane
02678         if((stp->GetPlane() == thePlane) ||
02679            (thePlane < subshower->GetBegPlane() && 
02680             stp->GetPlane() == subshower->GetBegPlane()) ||
02681             (thePlane > subshower->GetEndPlane() && 
02682             stp->GetPlane() == subshower->GetEndPlane())) {
02683           //allow +/- 2.5 strips:
02684           if(TMath::Abs(theStrip_tpos-stp->GetTPos())<=2.5*STRIPWIDTHINMETRES) { 
02685             MSG("SubShowerSR",Msg::kVerbose) 
02686               << "TMath::Abs(theStrip_tpos-stp->GetTPos())=" 
02687               << TMath::Abs(theStrip_tpos-stp->GetTPos()) 
02688               << " stp->Plane()=" << stp->GetPlane()
02689               << " stp->Strip()=" << stp->GetStrip()
02690               << endl;
02691             checkProximity = true;
02692           }
02693         }
02694       }
02695       if(!checkProximity) continue;  //not close enough to this subshower
02696 
02697       MSG("SubShowerSR", Msg::kVerbose) 
02698         << "SubShower " << ssCount-1 
02699         << " has strips in the same tpos range" 
02700         << endl;
02701 
02702       //calculate pH weighted distance from cluster centre
02703       //get subshower vertex and angle:
02704       Double_t tposVtx = 0;
02705       if(pv==PlaneView::kU || 
02706          pv==PlaneView::kX) tposVtx = subshower->GetVtxU();
02707       else if(pv==PlaneView::kV || 
02708               pv==PlaneView::kY) tposVtx = subshower->GetVtxV();      
02709       Double_t zposVtx = subshower->GetVtxZ();
02710       Float_t slope = subshower->GetSlope(); 
02711       Float_t avgdev = subshower->GetAvgDev();
02712       //get strip position and charge:
02713       Float_t tpos = unassigned->GetTPos();
02714       Float_t zpos = unassigned->GetZPos();
02715       if(avgdev!=0.) { 
02716         StripDistance[ssCount-1] = 
02717           (TMath::Abs(tpos - (tposVtx + slope*(zpos - zposVtx))) * 
02718            TMath::Cos(TMath::ATan(slope)))*theCharge/avgdev; 
02719       }
02720       else {
02721         MSG("SubShowerSR",Msg::kVerbose) << "SubShower " << ssCount-1 
02722                                          << " has AvgDev = 0!" << endl;
02723         StripDistance[ssCount-1] = 99998;
02724       }
02725 
02726       MSG("SubShowerSR", Msg::kVerbose) 
02727         << "Unassigned strip " << i 
02728         << " and SubShower " << ssCount-1 
02729         << " are a good match with dev(strip)/avgdev(subshower) = " 
02730         << StripDistance[ssCount-1] << endl;
02731     }
02732 
02733     //make decision here about closest subshower
02734     Float_t minSD = 99999;
02735     Int_t bestSS = -1;
02736     for(int j=0;j<csslh.GetNDaughters();j++){
02737       if(StripDistance[j]<minSD) {
02738         minSD = StripDistance[j];
02739         bestSS = j;
02740       }
02741     }
02742     if(bestSS!=-1){
02743       MSG("SubShowerSR", Msg::kVerbose) << "Best match for strip " << i 
02744                                         << ": SubShower " 
02745                                         << bestSS << " Adding plane: " 
02746                                         << unassigned->GetPlane() 
02747                                         << " strip: " 
02748                                         << unassigned->GetStrip() << endl; 
02749       
02750       CandSubShowerSRHandleItr subshowerItr(csslh.GetDaughterIterator());
02751       ssCount = 0;
02752       while(CandSubShowerSRHandle *cssh = subshowerItr()){
02753         if(ssCount==bestSS){
02754           MSG("SubShowerSR",Msg::kVerbose) << "Before: cssh->GetNStrip() = " 
02755                                            <<  cssh->GetNStrip() 
02756                                            << " cssh->GetEnergy() = " 
02757                                            << cssh->GetEnergy() << endl; 
02758                                          
02759           cssh->AddDaughterLink(*unassigned);
02760           Double_t mip2gev = cssh->GetEnergy() / 
02761             calibrator.GetMIP(cssh->GetCharge(CalStripType::kSigCorr));
02762           cssh->SetEnergy(cssh->GetEnergy()+mip2gev*theCharge);
02763 
02764           MSG("SubShowerSR",Msg::kVerbose) << "After: cssh->GetNStrip() = " 
02765                                            << cssh->GetNStrip() 
02766                                            << " cssh->GetEnergy() = " 
02767                                            << cssh->GetEnergy() << endl;
02768 
02769           assignedStrip[i] = true;
02770           anyChanges = true;
02771           break;
02772         }
02773         ssCount+=1;
02774       }
02775     }
02776     else {
02777       MSG("SubShowerSR", Msg::kVerbose) 
02778         << "No matching subshower for unassigned strip " 
02779         << i << endl;
02780     }
02781     delete [] StripDistance;
02782   }
02783   
02784   //remove assigned strips
02785   Int_t assigned = 0;
02786   for(int i=0;i<totUnassigned;i++) {
02787     if(assignedStrip[i]) {
02788       allStrips->RemoveAt(i);
02789       assigned+=1;
02790     }  
02791   }
02792   allStrips->Compress();
02793   
02794   if(anyChanges) {
02795     MSG("SubShowerSR", Msg::kDebug) 
02796       << assigned << "/" << totUnassigned
02797       << " strips assigned to SubShowers" << endl;
02798   }
02799   else {
02800     MSG("SubShowerSR", Msg::kDebug) 
02801       << "No Changes made to SubShowers" << endl;
02802   }
02803   return anyChanges;
02804   
02805 }

Bool_t AlgSubShowerSRList::FindCluster TObjArray *  allStrips,
TObjArray *  newSubShower,
Int_t  det
[private]
 

Read in info:

find maximum PH plane within selected longitudinal window:

Definition at line 510 of file AlgSubShowerSRList.cxx.

References window::centroid, CandStripHandle::GetCharge(), Calibrator::GetMIP(), CandStripHandle::GetPlane(), CandStripHandle::GetStrip(), CandStripHandle::GetTPos(), CandHandle::GetVldContext(), CandStripHandle::GetZPos(), Calibrator::Instance(), window::lower, window::lower_tpos, MSG, window::ph, window::phpos, window::phwidth, window::plane, s(), TransCluster(), window::type, window::upper, window::upper_tpos, and win.

Referenced by RunAlg().

00512 {
00513 
00514   Int_t nstp = allStrips->GetLast()+1;
00515   if(nstp==0){
00516     MSG("SubShower", Msg::kError) << "No strips present!" << endl;
00517     return true;
00518   }
00519 
00521   //Get useful info from candidates for clustering
00522  
00524   Int_t *plane = new Int_t[nstp];
00525   Int_t *strip = new Int_t[nstp];
00526   Double_t *ph = new Double_t[nstp];
00527   Double_t *pherr = new Double_t[nstp];
00528   Double_t *z = new Double_t[nstp];
00529   Double_t *tpos = new Double_t[nstp];
00530 
00531   //neighbouring strip info
00532   Double_t *TransGradientPlus = new Double_t[nstp];
00533   Double_t *TransGradientMinus = new Double_t[nstp];
00534   Double_t *TransGradientErrorPlus = new Double_t[nstp];
00535   Double_t *TransGradientErrorMinus = new Double_t[nstp];
00536 
00537   CandStripHandle *usefulStrip;
00538   int begPlane = 500;
00539   int endPlane = 0;
00540   
00541   Int_t doubleCounter = 0;
00542   Int_t alreadyGot[500][192] = {{0}};
00543   Calibrator& calibrator=Calibrator::Instance();
00544   for (Int_t i=0; i<=allStrips->GetLast(); i++) {
00545     TObject *tobj = allStrips->At(i);
00546     assert(tobj->InheritsFrom("CandStripHandle"));
00547     CandStripHandle *stp = dynamic_cast<CandStripHandle*>(tobj);
00548     if(alreadyGot[stp->GetPlane()][stp->GetStrip()]==1) {
00549       for(int j=0;j<i-doubleCounter;j++){
00550         if(plane[j]==stp->GetPlane() && strip[j]==stp->GetStrip()){
00551           ph[j] += calibrator.GetMIP(stp->GetCharge(CalDigitType::kSigCorr));
00552           TransGradientPlus[j] = ph[j];
00553           TransGradientMinus[j] = ph[j];
00554           break;
00555         }
00556       }
00557       doubleCounter+=1;
00558       nstp -= 1;
00559     }
00560     else {
00561       alreadyGot[stp->GetPlane()][stp->GetStrip()] = 1;
00562       plane[i-doubleCounter] = stp->GetPlane();
00563       if (plane[i-doubleCounter]<begPlane) begPlane = plane[i-doubleCounter];
00564       if (plane[i-doubleCounter]>endPlane) endPlane = plane[i-doubleCounter];
00565       strip[i-doubleCounter] = stp->GetStrip();
00566       
00567       ph[i-doubleCounter] = 
00568         calibrator.GetMIP(stp->GetCharge(CalDigitType::kSigCorr));
00569       pherr[i-doubleCounter] = ph[i-doubleCounter] /
00570         TMath::Sqrt(stp->GetCharge(CalDigitType::kPE)); //pe stats err
00571       
00572       z[i-doubleCounter] = stp->GetZPos();
00573       tpos[i-doubleCounter] = stp->GetTPos();
00574       
00575       TransGradientPlus[i-doubleCounter] = ph[i-doubleCounter];
00576       TransGradientErrorPlus[i-doubleCounter] = 
00577         TMath::Power(pherr[i-doubleCounter],2);
00578       
00579       TransGradientMinus[i-doubleCounter] = ph[i-doubleCounter];
00580       TransGradientErrorMinus[i-doubleCounter] = 
00581         TMath::Power(pherr[i-doubleCounter],2);
00582       
00583       usefulStrip = stp;
00584     }
00585   }
00586 
00588   //find transverse neighbour strip index and PH gradient for each strip
00589   for(Int_t i=0;i<nstp;i++){
00590     for(Int_t j=0;j<nstp;j++){
00591       if (plane[j]==plane[i]){
00592         if(strip[j]==strip[i]-1) {
00593           TransGradientMinus[i] = TransGradientMinus[i] - ph[j];
00594           TransGradientErrorMinus[i] = TMath::Sqrt(TransGradientErrorMinus[i]+ 
00595                                                    TMath::Power(pherr[j],2));
00596         }
00597         if(strip[j]==strip[i]+1) {
00598           TransGradientPlus[i] = TransGradientPlus[i] - ph[j];
00599           TransGradientErrorPlus[i] = TMath::Sqrt(TransGradientErrorPlus[i]+ 
00600                                                   TMath::Power(pherr[j],2));
00601           TransGradientErrorMinus[i] = 0;
00602           TransGradientErrorPlus[i] = 0;
00603         }
00604       }
00605     }
00606   }
00607 
00609   //find per plane PH
00610   int npls = (endPlane-begPlane)/2+1;
00611   if(det==1&&(begPlane-249)*(endPlane-249)<0) npls = (endPlane-begPlane-1)/2+1;
00612   Int_t *allpl = new Int_t[npls];
00613   Double_t *allplph = new Double_t[npls];
00614   Int_t *allstp = new Int_t[npls];
00615   for(Int_t i=0;i<npls;i++){
00616     allpl[i] = 2*i+begPlane;
00617     if(det==1&&(begPlane-249)*(endPlane-249)<0&&(2*i+begPlane)>249)
00618       allpl[i] = 2*i+begPlane+1;
00619     allplph[i] = 0.;
00620     allstp[i] = 0;
00621     for(Int_t j=0;j<nstp;j++){
00622       if (plane[j]==allpl[i]){
00623         allplph[i] += ph[j];
00624         allstp[i] += 1;
00625       }
00626     }
00627   }
00628   UgliGeomHandle ugh(*usefulStrip->GetVldContext());
00629 
00631   //Start Clustering: 
00633   //Find contiguous longitudinal windows
00634   MSG("SubShowerSR",Msg::kDebug) <<"start longitudinal clustering"<<endl;
00635 
00636   std::vector<int> zeroPlanes;  //vector of planes with PH = 0
00637   int start = begPlane-2;
00638   if(det==1&&(begPlane-2-249)*(begPlane-249)<0) start = begPlane-3;
00639   zeroPlanes.push_back(start-2);
00640   zeroPlanes.push_back(start);
00641   for(Int_t i=0;i<npls;i++){
00642     if (allplph[i]<=fLongWindowMipCut) zeroPlanes.push_back(allpl[i]);
00643   }
00644   int over = endPlane+2;
00645   if(det==1&&(endPlane+2-249)*(endPlane-249)<0) over = endPlane+3;
00646   zeroPlanes.push_back(over);
00647   zeroPlanes.push_back(over+2);
00648   
00649   MSG("SubShowerSR",Msg::kVerbose) << "Number of Zero Planes = " 
00650                                    << zeroPlanes.size()
00651                                    << " First Zero Plane = " << start 
00652                                    << " Last Zero Plane =  "<< over << endl;
00653   //----------------------------------------------
00654   //Find "Zero PH" windows
00655   //position of first plane in a longitudinal gap window:
00656   std::vector<int> firstGapPlane;
00657   //position of last plane in a longitudinal gap window:
00658   std::vector<int> lastGapPlane;
00659   int begGap = 0;
00660   int endGap = -5;
00661   //filling gap window vectors:
00662   for (UInt_t i = 0; i<zeroPlanes.size(); i++){
00663     bool foundgap = false;
00664     if(zeroPlanes.at(i)>endGap) {
00665       begGap = zeroPlanes.at(i);
00666       endGap = zeroPlanes.at(i);
00667       int j = 0;
00668       while ((i+j+1)<zeroPlanes.size() && 
00669              zeroPlanes.at(i+j+1)-zeroPlanes.at(i+j)<4) {
00670         foundgap = true;
00671         endGap = zeroPlanes.at(i+j+1);
00672         j++;
00673       }
00674       if (foundgap){
00675         firstGapPlane.push_back(begGap);
00676         lastGapPlane.push_back(endGap);
00677       }
00678     }
00679   }
00680 
00681   //Find highest strip density longitudinal window
00682   Int_t maxWinBegPlane = 0;  //first boundary plane of max window
00683   Int_t maxWinEndPlane = 0;
00684   Float_t maxDensity = 0;
00685   for (UInt_t i = 0; i<firstGapPlane.size(); i++){
00686     if((i+1)<firstGapPlane.size()){
00687       Float_t density = 0;
00688       Int_t bpln = lastGapPlane.at(i);
00689       Int_t epln = firstGapPlane.at(i+1);
00690       for(int j=0;j<npls;j++){
00691         if(allpl[j]>=bpln && allpl[j]<=epln){
00692           density += Float_t(allstp[j]);
00693         }
00694       }
00695       density/=Float_t(epln-bpln+2);
00696       MSG("SubShowerSR",Msg::kDebug) << "Proto-long window [" << bpln
00697                                      << "," << epln << "] density = " 
00698                                      << density << endl;
00699       if(density > maxDensity) {
00700         maxWinBegPlane = bpln;
00701         maxWinEndPlane = epln;
00702         maxDensity = density;
00703       }
00704     }
00705   }
00706 
00707   MSG("SubShowerSR",Msg::kDebug) << "Using Longitudinal Window: "
00708                                  << maxWinBegPlane << "-"
00709                                  << maxWinEndPlane << endl;
00710   
00711 
00714   Int_t maxPlane = -1;
00715   Double_t maxPlanePH = 0;
00716   for(int i=0;i<npls;i++){
00717     if(allpl[i]<maxWinEndPlane && allpl[i]>maxWinBegPlane) {
00718       if(allplph[i]>maxPlanePH) {
00719         maxPlane = allpl[i];
00720         maxPlanePH = allplph[i];
00721       }
00722     }
00723   }
00724   MSG("SubShowerSR",Msg::kVerbose) 
00725     << "Maximum PH plane within Long. window = " 
00726     << maxPlane << endl;
00727 
00728   Int_t numPreMaxPlanes = maxPlane - maxWinBegPlane;
00729   Int_t numPostMaxPlanes = maxWinEndPlane - maxPlane;
00730   Int_t numLongPlanes = numPostMaxPlanes + numPreMaxPlanes - 1;
00731 
00732    if(numLongPlanes/2<2){
00733      for (Int_t i=0; i<=allStrips->GetLast(); i++) {
00734        TObject *tobj = allStrips->At(i);
00735        assert(tobj->InheritsFrom("CandStripHandle"));
00736        CandStripHandle *stp = dynamic_cast<CandStripHandle*>(tobj);
00737        if(stp->GetPlane()>=maxWinBegPlane && stp->GetPlane()<=maxWinEndPlane){
00738          newSubShower->Add(stp);
00739        }
00740      }
00741      return true;
00742    }
00743 
00745   //Start Transverse Clustering
00746   
00747   //window info:
00748   std::vector<window> winvec;  //vector containing all transverse windows
00749 
00751   //Loop over all planes in long. window
00752   //Find transverse windows per plane
00753 
00754   for (int i=0;i<numLongPlanes;i++){
00755  
00756     //find next appropriate plane to look at starting from max plane:
00757     int pl = -1;
00758     if(numPreMaxPlanes>numPostMaxPlanes){
00759       if (i<numPreMaxPlanes) pl = maxPlane-i;
00760       else pl = maxPlane + i - numPreMaxPlanes + 1; 
00761       //add 1 to prevent re-doing max plane
00762     }
00763     else{
00764       if (i<numPostMaxPlanes) pl = maxPlane+i;
00765       else pl = maxPlane - i + numPostMaxPlanes - 1;
00766       //subtract 1 to prevent re-doing max plane
00767     }
00768 
00769     std::vector<Int_t> winu;  // vector of upper dip
00770     std::vector<Int_t> wind;  // vector of lower dip
00771     std::vector<Double_t> winu_tpos;  // vector of tpos of upper dip
00772     std::vector<Double_t> wind_tpos;  // vector of tpos of lower dip
00773     std::vector<Int_t> wintu; // vector of upper dip type
00774     std::vector<Int_t> wintd; // vector of lower dip type
00775 
00776     //
00777     //find dips and categorize them
00778     
00779     MSG("SubShowerSR",Msg::kVerbose) << "Find Upper/Lower boundaries in plane = "
00780                                      << pl << endl;
00781     for(Int_t i=0;i<nstp;i++){
00782       if(plane[i]==pl){
00783         //using neighbouring strip info from above:
00784         //(only called dips if delta PH is significant given pe stats)
00785         if(TransGradientPlus[i]<0 /*-(TransGradientErrorPlus[i])*/ &&
00786            TransGradientMinus[i]<0 /*-(TransGradientErrorMinus[i])*/){
00787           winu.push_back(strip[i]);
00788           winu_tpos.push_back(tpos[i]);
00789           wintu.push_back(0);      // type-0 (this is a dip) 
00790           MSG("SubShowerSR",Msg::kVerbose) << "up dip strip = " << strip[i]
00791                                            << " ph = " << ph[i] 
00792                                            << " tgp = " 
00793                                            << TransGradientPlus[i]
00794                                            << " tgm = " 
00795                                            << TransGradientMinus[i]
00796                                            << endl;
00797         }
00798         else if(TransGradientPlus[i]==ph[i] && 
00799                 TransGradientMinus[i]<=ph[i]){
00800           winu.push_back(strip[i]);
00801           winu_tpos.push_back(tpos[i]);
00802           MSG("SubShowerSR",Msg::kVerbose) << "up edge/iso strip = " 
00803                                            << strip[i]
00804                                            << " ph = " << ph[i] 
00805                                            << " tgp = " 
00806                                            << TransGradientPlus[i]
00807                                            << " tgm = " 
00808                                            << TransGradientMinus[i]
00809                                            << endl;
00810 
00811           if (TransGradientMinus[i]<ph[i]) 
00812             wintu.push_back(1);     // type-1 (this is an edge strip) 
00813           else wintu.push_back(2);  // type-2 (this is an isolated strip)
00814         }
00815         if(TransGradientPlus[i]<0 /*-(TransGradientErrorPlus[i])*/ &&
00816            TransGradientMinus[i]<0 /*-(TransGradientErrorMinus[i])*/ ){
00817           wind.push_back(strip[i]);
00818           wind_tpos.push_back(tpos[i]);
00819           wintd.push_back(0);      // type-0
00820           MSG("SubShowerSR",Msg::kVerbose) << "down dip strip = " << strip[i]
00821                                            << " ph = " << ph[i]
00822                                            << " tgp = " 
00823                                            << TransGradientPlus[i]
00824                                            << " tgm = " 
00825                                            << TransGradientMinus[i]
00826                                            << endl;
00827         
00828         }
00829         else if(TransGradientMinus[i]==ph[i] && 
00830                 TransGradientPlus[i]<=ph[i]){
00831           wind.push_back(strip[i]);
00832           wind_tpos.push_back(tpos[i]);
00833           MSG("SubShowerSR",Msg::kVerbose) << "down edge/iso strip = " 
00834                                            << strip[i]
00835                                            << " ph = " << ph[i]
00836                                            << " tgp = " 
00837                                            << TransGradientPlus[i]
00838                                            << " tgm = " 
00839                                            << TransGradientMinus[i]
00840                                            << endl;
00841           if (TransGradientPlus[i]<ph[i]) 
00842             wintd.push_back(1);     //type-1
00843           else wintd.push_back(2);  //type-2
00844         }
00845       }
00846     }
00847 
00849     //use dips to form windows                                   
00850     UInt_t wins = winu.size();
00851     if(wins!=wind.size()) {
00852       MSG("SubShowerSR",Msg::kError) 
00853         << "Number of Upper Transverse Window Boundaries does not equal " 
00854         << "number of Lower Transverse Window Boundaries... "
00855         << "Leaving FindCluster()" << endl;
00856       MSG("SubShowerSR",Msg::kError) << "winu.size() = " << winu.size()
00857                                      << endl;
00858       MSG("SubShowerSR",Msg::kError) << "wind.size() = " << wind.size()
00859                                      << endl;
00860       MSG("SubShowerSR",Msg::kError) << "wins = " << wins << endl;
00861       
00862       return false;
00863     }
00864 
00866     //temporarily hold window info
00867     Int_t        *win0  = new Int_t[wins];     // strip of upper dip
00868     Int_t        *win1  = new Int_t[wins];     // strip of lower dip
00869     Float_t *win0_tpos  = new Float_t[wins];   // tpos of strip of upper dip
00870     Float_t *win1_tpos  = new Float_t[wins];   // tpos of strip of lower dip
00871     Float_t      *win2  = new Float_t[wins];   // PH of window
00872     Int_t        *win3  = new Int_t[wins];     // ID of window: 
00873                                                //   0-both dips; 
00874                                                //   1 or 10-one dip,one gap; 
00875                                                //   11-both gaps; 
00876                                                //   22-isolated strip
00877     Float_t      *win4  = new Float_t[wins];   // Centroid of window in tpos
00878     Float_t      *win5  = new Float_t[wins];   // PH weighted tpos of window
00879     Float_t      *win6  = new Float_t[wins];   // PH weighted width of window
00880 
00882     //match up dips to form windows
00883     for (UInt_t w = 0; w<wins; w++){
00884       win0[w] = -1;
00885       win1[w] = -1;
00886       win0_tpos[w] = 0;
00887       win1_tpos[w] = 0;
00888       win2[w] = 0;
00889       win3[w] = -1;
00890       win4[w] = 0;
00891       win5[w] = 0;
00892       win6[w] = 0;
00893       int winw = 200;
00894       for (UInt_t s = 0; s<wind.size(); s++){
00895         int diff = winu.at(w)-wind.at(s);
00896         if ( ( (diff>0  && wintu.at(w)<2  && wintd.at(s)<2) ||
00897                (diff==0 && wintu.at(w)==2 && wintd.at(s)==2) ) &&
00898              diff<winw) {
00899           winw = diff;
00900           win0[w] = winu.at(w);
00901           win1[w] = wind.at(s);
00902           win0_tpos[w] = winu_tpos.at(w);
00903           win1_tpos[w] = wind_tpos.at(s);
00904           win3[w] = wintu.at(w)*10+wintd.at(s);
00905         }
00906       }
00907     }
00908 
00910     //now get PH of windows
00911     //and push_back windows into vectors
00912     for (UInt_t w = 0; w<wins; w++){            
00913       Double_t biggestStripPH = 0;
00914       Int_t n = 0;
00915       for(Int_t i=0;i<nstp;i++){
00916         if (plane[i]==pl && strip[i]<=win0[w] && strip[i]>=win1[w]) {
00917           win2[w] += ph[i];
00918           if(ph[i]>biggestStripPH) {
00919             win4[w] = tpos[i];
00920             biggestStripPH = ph[i];
00921           }
00922           win5[w] += ph[i]*tpos[i];
00923           win6[w] += ph[i]*tpos[i]*tpos[i];
00924           n++;
00925         }
00926       }
00927       win5[w] /= win2[w];
00928       if(n!=1){
00929         win6[w] /= win2[w];
00930         win6[w] -= win5[w]*win5[w];
00931         if(win6[w]>0) win6[w] = TMath::Sqrt(win6[w]);
00932         else win6[w] = 0.041/TMath::Sqrt(12.);
00933       }
00934       else win6[w] = 0.041/TMath::Sqrt(12.);
00935       
00936       window win;
00937       win.plane = pl;
00938       win.upper = win0[w];
00939       win.lower = win1[w];
00940       win.upper_tpos = win0_tpos[w];
00941       win.lower_tpos = win1_tpos[w];
00942       win.ph = win2[w];
00943       win.type = win3[w];
00944       win.centroid = win4[w];
00945       win.phpos = win5[w];
00946       win.phwidth = win6[w];
00947       winvec.push_back(win);
00948 
00949     }
00950 
00951     delete [] win0;
00952     delete [] win1;
00953     delete [] win0_tpos;
00954     delete [] win1_tpos;
00955     delete [] win2;
00956     delete [] win3;
00957     delete [] win4;
00958     delete [] win5;
00959     delete [] win6;
00960 
00961   }
00962 
00964   //Perform clustering on windows:
00965   std::vector<window> clusterWinVec = TransCluster(winvec,det);
00966   
00967   //no windows added to cluster:
00968   if(clusterWinVec.size()==0) return false;
00969 
00970   //Check for longitudinal gaps within the proto-cluster
00971   //Remove windows after first gap on both sides of shower max plane
00972   
00973   maxPlane = -1;  //recalculate maxPlane
00974   maxPlanePH = 0.;
00975   Double_t PlanePH[500] = {0.};
00976   Int_t non0Win = 0;
00977   std::vector<window>::iterator winIter = clusterWinVec.begin();
00978   std::vector<window>::iterator winEnd = clusterWinVec.end();
00979   while(winIter!=winEnd){
00980     if(winIter->plane>0){
00981       PlanePH[winIter->plane] += winIter->ph;
00982       if(PlanePH[winIter->plane]>0) non0Win++;
00983       if(PlanePH[winIter->plane]>maxPlanePH) {
00984         maxPlane = winIter->plane;
00985         maxPlanePH = PlanePH[maxPlane];
00986       }
00987     }
00988     winIter++;
00989   }
00990   
00991   if(non0Win==0){
00992     MSG("SubShowerSR",Msg::kDebug) <<"No window solutions found"<<endl;
00993     return false;
00994   }
00995 
00996   Int_t maxLongPlane = -1;
00997   Int_t minLongPlane = -1;
00998   Int_t counter = 0;
00999   Int_t delta = 2;
01000   while(PlanePH[maxPlane+counter]>0||(maxPlane+counter)==249) {
01001     maxLongPlane = maxPlane+counter;
01002     delta = 2;
01003     if(det==1&&(maxLongPlane-249)*(maxLongPlane+delta-249)<0)
01004       delta = 3;
01005     counter+=delta;
01006   }
01007   counter = 0;
01008   while(PlanePH[maxPlane+counter]>0||(maxPlane+counter)==249) {
01009     minLongPlane = maxPlane+counter;
01010     delta = 2;
01011     if(det==1&&(minLongPlane-249)*(minLongPlane-delta-249)<0)
01012       delta = 3;
01013     counter-=delta;
01014   }
01015   MSG("SubShowerSR",Msg::kDebug) <<"New Longitudinal Window: "<< minLongPlane
01016                                  << "-" << maxLongPlane << endl;
01017 
01018   for (Int_t i=0; i<=allStrips->GetLast(); i++) {
01019     TObject *tobj = allStrips->At(i);
01020     assert(tobj->InheritsFrom("CandStripHandle"));
01021     CandStripHandle *stp = dynamic_cast<CandStripHandle*>(tobj);
01022     if(stp->GetPlane()>=minLongPlane && stp->GetPlane()<=maxLongPlane){
01023       winIter = clusterWinVec.begin();
01024       while(winIter!=winEnd){
01025         if(winIter->plane==stp->GetPlane()){
01026           Int_t strp = stp->GetStrip();
01027           if(strp<=winIter->upper && strp>=winIter->lower) {
01028             newSubShower->Add(stp);
01029             break;
01030           }
01031         }
01032         winIter++;
01033       }
01034     }
01035   }
01036   delete [] plane;
01037   delete [] strip;
01038   delete [] ph;
01039   delete [] z;
01040   delete [] tpos;
01041   delete [] TransGradientPlus;
01042   delete [] TransGradientMinus;
01043   delete [] TransGradientErrorPlus;
01044   delete [] TransGradientErrorMinus;
01045   delete [] allplph;
01046   delete [] allpl;
01047   delete [] allstp;
01048 
01049   return true;
01050 }

Bool_t AlgSubShowerSRList::FormHalo TObjArray *  ,
CandHandle ,
CandContext ,
AlgHandle ,
const CandSliceListHandle ,
Int_t 
[private]
 

Definition at line 2808 of file AlgSubShowerSRList.cxx.

References CandHandle::AddDaughterLink(), CleanUp(), CandSubShowerSRHandle::GetAvgDev(), CandRecoHandle::GetBegPlane(), CandRecoHandle::GetCandSlice(), CandSubShowerSRHandle::GetClusterID(), CandHandle::GetDaughterIterator(), CandRecoHandle::GetEndPlane(), CandSubShowerSRHandle::GetEnergy(), CandHandle::GetNDaughters(), CandRecoHandle::GetNStrip(), CandStripHandle::GetPlane(), CandStripHandle::GetPlaneView(), CandSubShowerSRHandle::GetPlaneView(), CandSubShowerSRHandle::GetSlope(), CandStripHandle::GetTPos(), CandRecoHandle::GetVtxU(), CandRecoHandle::GetVtxV(), CandSubShowerSR::MakeCandidate(), MSG, PITCHINMETRES, CandHandle::Print(), CandRecoHandle::SetCandSlice(), CandSubShowerSRHandle::SetClusterID(), and CandContext::SetDataIn().

Referenced by RunAlg().

02812 {
02813 
02814   MSG("SubShowerSR", Msg::kDebug) << "Running FormHalo()" << endl;
02815   
02816   assert(ch.InheritsFrom("CandSubShowerSRListHandle"));
02817 
02818   Int_t totUnassigned = allStrips->GetLast()+1;
02819   if(totUnassigned==0) return false;
02820   
02821   MSG("SubShowerSR", Msg::kDebug) << "Forming slice-wise, " 
02822                                   << "plane-wise Halo clusters from " 
02823                                   << totUnassigned 
02824                                   << " unassigned strips" << endl;
02825   
02826   //loop over slices
02827   Int_t nslice = 0;
02828   CandSliceHandleItr sliceItr(slicelist->GetDaughterIterator());
02829   while (CandSliceHandle *slice = sliceItr()) {
02830     MSG("SubShowerSR",Msg::kDebug) << "Slice " << nslice << endl;
02831     
02832     //get valid plane ranges for this slice:
02833     CandSubShowerSRListHandle &subshowerlist = 
02834       dynamic_cast<CandSubShowerSRListHandle&>(ch);
02835     CandSubShowerSRHandleItr subshowerItr(subshowerlist.GetDaughterIterator());
02836     Int_t plane[500] = {0};
02837     Int_t firstPlane = 500;
02838     Int_t lastPlane = 0;
02839     while (CandSubShowerSRHandle *subshower = subshowerItr()) {
02840       if (*subshower->GetCandSlice()==*slice) { 
02841         for(int i=subshower->GetBegPlane();i<=subshower->GetEndPlane();i++){
02842           plane[i] = 1;
02843           if(i<firstPlane) firstPlane = i;
02844           if(i>lastPlane) lastPlane = i;
02845         }
02846       }
02847     }
02848 
02849     //loop over valid plane ranges and look for gaps > fMaxPlaneGap
02850     while(firstPlane<=lastPlane){
02851       Int_t begPlane = 500;
02852       Int_t endPlane = 0;
02853       Int_t nGaps = 0;
02854       for(int i=firstPlane;i<=lastPlane;i++){
02855         if(plane[i]==0) {
02856           if(begPlane!=500) nGaps+=1;
02857         }
02858         else {
02859           if(begPlane==500) begPlane = i;
02860           endPlane = i;
02861         }
02862         plane[i] = 0;
02863         if(nGaps>fMaxPlaneGap) {
02864           break;
02865         }
02866       }
02867       firstPlane = endPlane+1;
02868 
02869       //use plane range between begPlane and endPlane to form subshowers
02870       //loop over views:
02871       for(Int_t pv=0;pv<2;pv++){
02872 
02873         MSG("SubShowerSR",Msg::kDebug) << "View : " << pv << endl;
02874 
02875         //first loop through subshower list again and histogram tposvtx
02876         //in order to look for peaks
02877         TH1F *vtxHist = new TH1F("vtxHist","vtxHist",66,-4.125,4.125);
02878         subshowerItr.ResetFirst();
02879         while (CandSubShowerSRHandle *subshower = subshowerItr()) {
02880           if (*subshower->GetCandSlice()==*slice && 
02881               subshower->GetClusterID()!=ClusterType::kXTalk) {
02882             if(pv==0 && 
02883                (subshower->GetPlaneView()==PlaneView::kV || 
02884                 subshower->GetPlaneView()==PlaneView::kY)) continue;
02885             else if(pv==1 && 
02886                     (subshower->GetPlaneView()==PlaneView::kU || 
02887                      subshower->GetPlaneView()==PlaneView::kX)) continue;
02888             if(subshower->GetBegPlane()>=begPlane && 
02889                subshower->GetBegPlane()<=endPlane){
02890               if(pv==0) {
02891                 Float_t weightedCentre = subshower->GetVtxU() +
02892                   subshower->GetSlope() * PITCHINMETRES * 
02893                   Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
02894                 if(weightedCentre<-4. || weightedCentre>4.) weightedCentre = subshower->GetVtxU();
02895                 vtxHist->Fill(weightedCentre);
02896                 MSG("SubShowerSR",Msg::kDebug) 
02897                   << "Filling vtxHist with Subshower "
02898                   << " with tposvtv = " << subshower->GetVtxU() 
02899                   << " and energy = " << subshower->GetEnergy() 
02900                   << " and slope = " << subshower->GetSlope()
02901                   << " and AvgDev = " << subshower->GetAvgDev()
02902                   << " and weightedCentre = " << weightedCentre
02903                   << endl;
02904               }
02905               else if(pv==1) {
02906                 Float_t weightedCentre = subshower->GetVtxV() +
02907                   subshower->GetSlope() * PITCHINMETRES * 
02908                   Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
02909                 if(weightedCentre<-4. || weightedCentre>4.) weightedCentre = subshower->GetVtxV();
02910                 vtxHist->Fill(weightedCentre);
02911                 MSG("SubShowerSR",Msg::kDebug) 
02912                   << "Filling vtxHist with Subshower "
02913                   << " with tposvtv = " << subshower->GetVtxV() 
02914                   << " and energy = " << subshower->GetEnergy() 
02915                   << " and slope = " << subshower->GetSlope()
02916                   << " and AvgDev = " << subshower->GetAvgDev()
02917                   << " and weightedCentre = " << weightedCentre
02918                   << endl;
02919               }
02920             }
02921           }
02922         }
02923 
02924         if(false){
02925           TCanvas *can = new TCanvas();
02926           can->cd(1);
02927           vtxHist->Draw();
02928           char nomus[256];
02929           sprintf(nomus,"peakPlot_FH_view%i_slice%i.eps",pv,nslice);
02930           can->Print(nomus);
02931           delete can;
02932         }
02933 
02934         TSpectrum *spec = new TSpectrum(10);
02935         spec->Search(vtxHist,1);
02936 
02937         Int_t nPeaks = spec->GetNPeaks();
02938         Float_t *peakPos = spec->GetPositionX();
02939         Float_t *peakVal = spec->GetPositionY();
02940 
02941         //if no peaks are found
02942         //then there's no reconstructed subshower 
02943         //in this slice + plane range + view
02944         if(nPeaks==0) {
02945           MSG("SubShowerSR",Msg::kDebug) << "No peaks found" << endl;
02946           //so take everything and put it in a subshower
02947           CandStripHandleItr stripslcItr(slice->GetDaughterIterator());
02948           TObjArray newSubShower;
02949           while (CandStripHandle *stp = stripslcItr()) {
02950             if(pv==0 && (stp->GetPlaneView()==PlaneView::kV || 
02951                          stp->GetPlaneView()==PlaneView::kY)) continue;
02952             else if(pv==1 && (stp->GetPlaneView()==PlaneView::kU || 
02953                               stp->GetPlaneView()==PlaneView::kX)) continue;
02954             //is this strip in the subshower plane range?
02955             //allow +/- 2 planes in this window
02956             if(stp->GetPlane()>endPlane+2 || 
02957                stp->GetPlane()<begPlane-2) continue;
02958             //loop over unassigned strips, and see if it's there
02959             for (Int_t i=0; i<allStrips->GetLast()+1; i++) {
02960               TObject *tobj = allStrips->At(i);
02961               CandStripHandle *unassigned = 
02962                 dynamic_cast<CandStripHandle*>(tobj);
02963               if(*unassigned == *stp) {
02964                 newSubShower.Add(unassigned);
02965                 allStrips->RemoveAt(i);
02966               }
02967             }
02968             allStrips->Compress();
02969           }
02970           //make a new subshower with the unassigned strips in this slice
02971           if(newSubShower.GetLast()+1>0){
02972             cxx.SetDataIn(&newSubShower);
02973             MSG("SubShowerSR",Msg::kDebug) << "forming SubShowerSR\n";
02974             CandSubShowerSRHandle subshowersrhandle = 
02975               CandSubShowerSR::MakeCandidate(ah,cxx);
02976             if(subshowersrhandle.GetNStrip()!=0) {
02977               MSG("SubShowerSR",Msg::kDebug) << "Formed SubShowerSR " 
02978                                              << ch.GetNDaughters()
02979                                              << " with " 
02980                                              << subshowersrhandle.GetNStrip()
02981                                              << " strips" << endl;
02982               subshowersrhandle.SetClusterID(ClusterType::kHalo);
02983               subshowersrhandle.SetCandSlice(slice);
02984               ch.AddDaughterLink(subshowersrhandle);          
02985             }
02986           }
02987           delete spec;
02988           delete vtxHist;
02989           continue;
02990         }
02991       
02992         //have one or more peak => maybe one or 
02993         //more shower in this plane range
02994         //first find acceptable limits in tpos for a halo
02995         //subshower to be formed:
02996         Float_t *peakPosLow = new Float_t[nPeaks];
02997         Float_t *peakPosUpp = new Float_t[nPeaks];
02998         MSG("SubShowerSR",Msg::kDebug) << "Number of Peaks found = "
02999                                        << nPeaks 
03000                                        << " with positions, heights "
03001                                        << "and bounds: "  << endl;
03002         for (int i=0;i<nPeaks;i++){
03003           if(i==0) peakPosLow[i] = -4;
03004           else peakPosLow[i] = peakPosUpp[i-1];
03005           if(i==nPeaks-1) peakPosUpp[i] = 4;
03006           else {
03007             if(peakVal[i]+peakVal[i+1] == 0) {
03008               MSG("SubShowerSR",Msg::kError) << "peakVal[" << i << "]=" << peakVal[i] 
03009                                              << " peakVal[" << i+1 << "]=" << peakVal[i+1]
03010                                              << " - Setting nPeaks=1!" << endl;
03011               nPeaks=1;
03012               peakPosUpp[0] = 4;
03013               break;
03014             }
03015             peakPosUpp[i] = peakPos[i] + 
03016               (peakVal[i])*(peakPos[i+1] - peakPos[i]) / 
03017               ((peakVal[i]) + (peakVal[i+1]));
03018           }
03019           MSG("SubShowerSR",Msg::kDebug) << peakPos[i] << " " 
03020                                          << peakVal[i] << " ["
03021                                          << peakPosLow[i] << "," 
03022                                          << peakPosUpp[i] << "]" 
03023                                          << endl;
03024         }
03025 
03026         //loop through peaks and assign strips to form halo subshowers
03027         //according to acceptable tpos and plane ranges
03028         for(int i=0;i<nPeaks;i++){
03029           //loop through slice strips
03030           CandStripHandleItr stripslcItr(slice->GetDaughterIterator());
03031           TObjArray newSubShower;
03032         
03033           //loop over strips in slices in this view:
03034           // (have to loop through slice strips and not just
03035           // unassigned strips because you cannot get slice number
03036           // from strip handle)
03037           while (CandStripHandle *stp = stripslcItr()) {
03038           
03039             //only look at one view at a time:
03040             if(pv==0 && (stp->GetPlaneView()==PlaneView::kV || 
03041                          stp->GetPlaneView()==PlaneView::kY)) continue;
03042             else if(pv==1 && (stp->GetPlaneView()==PlaneView::kU || 
03043                               stp->GetPlaneView()==PlaneView::kX)) continue;
03044           
03045             //is this strip in the subshower plane range?
03046             //allow +/- 2 planes in this window
03047             if(stp->GetPlane()>endPlane+2 || 
03048                stp->GetPlane()<begPlane-2) continue;
03049             
03050             //is this strip in the tpos range
03051             if(stp->GetTPos()>peakPosUpp[i] ||
03052                stp->GetTPos()<=peakPosLow[i]) continue;
03053 
03054             //loop over unassigned strips, and see if it's there
03055             for (Int_t i=0; i<allStrips->GetLast()+1; i++) {
03056               TObject *tobj = allStrips->At(i);
03057               CandStripHandle *unassigned = 
03058                 dynamic_cast<CandStripHandle*>(tobj);
03059               if(*unassigned == *stp) {
03060                 newSubShower.Add(unassigned);
03061                 allStrips->RemoveAt(i);
03062               }
03063             }
03064             allStrips->Compress();
03065           }
03066           
03067           //make a new subshower with the unassigned strips in this slice
03068           if(newSubShower.GetLast()+1>0){  
03069             cxx.SetDataIn(&newSubShower);
03070             MSG("SubShowerSR",Msg::kDebug) << "forming SubShowerSR\n";
03071             CandSubShowerSRHandle subshowersrhandle = 
03072               CandSubShowerSR::MakeCandidate(ah,cxx);
03073             if(subshowersrhandle.GetNStrip()!=0) {
03074               MSG("SubShowerSR",Msg::kDebug) << "Formed SubShowerSR with " 
03075                                              << subshowersrhandle.GetNStrip()
03076                                              << " strips" << endl;
03077               subshowersrhandle.SetClusterID(ClusterType::kHalo);
03078               subshowersrhandle.SetCandSlice(slice);
03079               ch.AddDaughterLink(subshowersrhandle); 
03080             }
03081           }
03082         }
03083         delete spec;
03084         delete vtxHist;
03085         delete [] peakPosLow;
03086         delete [] peakPosUpp;
03087       }
03088     }
03089     //slice-wise clean up
03090     Int_t numberOfCleanUps = 0;
03091     while(CleanUp(allStrips,ch,det,slice)) {
03092       numberOfCleanUps+=1;
03093       //prevent against infinite loop! (which should NEVER happen)
03094       if(numberOfCleanUps>1000) break;
03095     }
03096     nslice++;
03097   }
03098   //slice-wise clean up
03099   Int_t numberOfCleanUps = 0;
03100   while(CleanUp(allStrips,ch,det)) {
03101     numberOfCleanUps+=1;
03102     //prevent against infinite loop! (which should NEVER happen)
03103     if(numberOfCleanUps>1000) break;
03104   }
03105   return true;
03106 }

std::vector< window > AlgSubShowerSRList::HoughTransCluster std::vector< window ,
Int_t 
[private]
 

Definition at line 1742 of file AlgSubShowerSRList.cxx.

References BestHough(), MSG, and win.

Referenced by TransCluster().

01744 {
01745 
01746   MSG("SubShowerSR",Msg::kDebug) << "In HoughTransCluster()" << endl;
01747   
01748   std::vector<window> cluster;
01749   std::vector<window> nonCluster;
01750   std::vector<window> emptyCluster;
01751   
01752   //copy all windows into nonCluster:
01753   //also get best vertex estimate in first plane
01754   Int_t vertexPlane = 500;
01755   Double_t vertexPlanePH = 0;
01756   Double_t vertexTPos = 0;
01757   Double_t vertexTPosWidth = 0;
01758 
01759   //use these to calculate the density of hits in the long. window
01760   //this can be used to decide which Hough method to use
01761   Double_t hitDensity = 0;
01762   Double_t totStrips = 0; 
01763   Double_t maxTpos = -5.0;
01764   Double_t minTpos = 5.0;
01765   Int_t lastPlane = 0;
01766 
01767   std::vector<window>::iterator wIt = win.begin();
01768   std::vector<window>::iterator wEn = win.end();
01769   while(wIt!=wEn){
01770     nonCluster.push_back(*wIt);
01771     if(wIt->plane<vertexPlane) {
01772       if(wIt->ph>1.0) {
01773         vertexPlane = wIt->plane;
01774         vertexPlanePH = wIt->ph;
01775         vertexTPos = wIt->phpos;
01776         vertexTPosWidth = wIt->phwidth;
01777         if(vertexTPosWidth<0.041) vertexTPosWidth=0.041;
01778       }
01779       else if(vertexPlanePH<1.0){
01780         vertexPlane = wIt->plane;
01781         vertexPlanePH = wIt->ph;
01782         vertexTPos = wIt->phpos;
01783         vertexTPosWidth = wIt->phwidth;
01784         if(vertexTPosWidth<0.041) vertexTPosWidth=0.041;
01785       }
01786     }
01787     else if(wIt->plane==vertexPlane){
01788       if(wIt->ph>vertexPlanePH){
01789         vertexPlanePH = wIt->ph;
01790         vertexTPos = wIt->phpos;
01791         vertexTPosWidth = wIt->phwidth;
01792         if(vertexTPosWidth<0.041) vertexTPosWidth=0.041;
01793       }
01794     }
01795     if(wIt->ph>1.0) {
01796       if(wIt->plane>lastPlane) lastPlane = wIt->plane;
01797       if(wIt->upper_tpos>maxTpos) maxTpos = wIt->upper_tpos;
01798       if(wIt->lower_tpos<minTpos) minTpos = wIt->lower_tpos;      
01799       totStrips += Double_t(wIt->upper - wIt->lower + 1);
01800     }
01801     wIt++;
01802   }
01803 
01804   //calculate hitDensity:
01805   if(lastPlane-vertexPlane+1 != 0) { //multiple planes
01806     hitDensity = totStrips/(((maxTpos-minTpos+0.041)/0.041) * 
01807                             Double_t(lastPlane-vertexPlane+1));
01808   }
01809   else hitDensity = 0;  //single plane
01810 
01811   MSG("SubShowerSR",Msg::kDebug) << "hitDensity = " << hitDensity << endl;
01812   
01813   //keep track of some quantities for quality checking at the end:
01814   Int_t   lowPlane  = 500;
01815   Int_t   uppPlane  = 0;
01816   Double_t nStrips  = 0;
01817   Double_t   avePH  = 0;
01818   Double_t aveWidth = 0;
01819   
01820   //keep looping until we have all windows
01821   Bool_t keepGoing = true;
01822   Int_t nLoops = 0;
01823   while(keepGoing && nLoops<5) {
01824     
01825     MSG("SubShowerSR",Msg::kDebug) << "Running BestHough(): Loop number " 
01826                                    << nLoops << endl;
01827 
01828     //remember number of strips in cluster after last loop
01829     //once this value does not change, then stop looping
01830     Double_t oldNStrips = nStrips;
01831 
01832     //Get Hough m,c:
01833     Double_t *MCV = new Double_t[14];
01834     MCV[0] = 0; MCV[1] = 0; MCV[2] = 0; MCV[3] = 0; MCV[4] = 0;
01835     MCV[5] = 0; MCV[6] = 0; MCV[7] = 0; MCV[8] = 0; MCV[9] = 0;
01836     MCV[10] = 0; MCV[11] = 0; MCV[12] = 0; MCV[13] = 0;
01837     Int_t badGradient[4] = {0};
01838 
01839     //To decide which Hough to use first
01840     Int_t offset = 5;               //by default PH first
01841     if(hitDensity<0.05) offset = 0; //unless hit density <0.05 of max possible
01842 
01843     //If we are on the first loop, use all windows to get angle
01844     //If we are not on first loop, just use previously 
01845     //selected windows to get better determination of angle
01846     if(cluster.size()==0){
01847       MSG("SubShowerSR",Msg::kDebug) << "cluster.size()=0" << endl;
01848       if(BestHough(win,MCV,false)) {
01849         if(true){
01850           //verify that best hough passes reasonably close to vertex:
01851 
01852           MSG("SubShowerSR",Msg::kDebug) << "vertexPlane = " 
01853                                          << vertexPlane << endl;
01854           MSG("SubShowerSR",Msg::kDebug) << "vertexTPos = " 
01855                                          << vertexTPos << endl;
01856           MSG("SubShowerSR",Msg::kDebug) << "vertexTPosWidth = " 
01857                                          << vertexTPosWidth << endl;
01858 
01859           double vertexY_simple = (vertexPlane - MCV[2])*MCV[0] + MCV[1];
01860           double vertexY_simple_peak = (vertexPlane - MCV[2])*MCV[10] + MCV[11];
01861 
01862           MSG("SubShowerSR",Msg::kDebug) << "vertexY_simple = " 
01863                                          << vertexY_simple << endl;
01864 
01865           if( vertexY_simple < vertexTPos - vertexTPosWidth ||
01866               vertexY_simple > vertexTPos + vertexTPosWidth || 
01867               MCV[0]==0 ){
01868             offset = 5;
01869             badGradient[0] = 1;
01870           }
01871         
01872           if( (vertexY_simple_peak < vertexTPos - vertexTPosWidth) || 
01873                (vertexY_simple_peak > vertexTPos + vertexTPosWidth) ||
01874               MCV[10]==0 ){
01875             badGradient[1] = 1;
01876           }
01877 
01878           double vertexY_ph      = (vertexPlane - MCV[7])*MCV[5] + MCV[6];
01879           double vertexY_ph_peak = (vertexPlane - MCV[7])*MCV[12] + MCV[13];
01880           MSG("SubShowerSR",Msg::kDebug) << "vertexY_ph = " << vertexY_ph 
01881                                          << endl;
01882           if( vertexY_ph < vertexTPos - vertexTPosWidth || 
01883               vertexY_ph > vertexTPos + vertexTPosWidth ||
01884               MCV[5]==0 ) {
01885             offset = 0;  //use simple Hough if this is no good
01886             badGradient[2] = 1;
01887           }
01888           if( vertexY_ph_peak < vertexTPos - vertexTPosWidth || 
01889               vertexY_ph_peak > vertexTPos + vertexTPosWidth ||
01890               MCV[12]==0 ) {
01891             badGradient[3] = 1;
01892           }
01893         }
01894       }
01895     }
01896     else {
01897       MSG("SubShowerSR",Msg::kDebug) << "cluster.size()=" 
01898                                      << cluster.size() << endl;
01899       BestHough(cluster,MCV,false);
01900     }
01901 
01902     MSG("SubShowerSR",Msg::kDebug) 
01903       << "\nHough gradient, intercept, plane vertex: " 
01904       << MCV[0] << "+/-" << MCV[3] << " " 
01905       << MCV[1] << "+/-" << MCV[4] << " " << MCV[2]
01906       << "\nPH Hough gradient, intercept, plane vertex: " 
01907       << MCV[5] << "+/-" << MCV[8] << " " 
01908       << MCV[6] << "+/-" << MCV[9] << " " << MCV[7]
01909       << "\n Hough Max Bin Gradient and Intercept Values: "
01910       << MCV[10] << " " << MCV[11] << " "
01911       << MCV[12] << " " << MCV[13] << endl;
01912 
01913     //if we've learnt nothing from first run of BestHough
01914     //stop now and try other clustering algorithm
01915     if(badGradient[0]==1 && badGradient[1]==1 && 
01916        badGradient[2]==1 && badGradient[3]==1 && 
01917        cluster.size()==0) {
01918       delete [] MCV;
01919       return emptyCluster;
01920     }
01921 
01922     if(true){
01923       cluster.clear();
01924       avePH = 0;
01925       aveWidth = 0;
01926       nStrips = 0;
01927       lowPlane = 500;
01928       uppPlane = 0;
01929       std::vector<int> tempcluster[4];
01930       std::vector<window>::iterator winIter = nonCluster.begin();
01931       std::vector<window>::iterator winEnd  = nonCluster.end();
01932       Int_t counter = 0;
01933       while(winIter!=winEnd){
01934         double y[4] = {};
01935         double y_upp[4] = {};
01936         double y_low[4] = {};
01937         y[0] = (winIter->plane - MCV[2])*MCV[0]  + MCV[1];
01938         y[1] = (winIter->plane - MCV[2])*MCV[10] + MCV[11];
01939         y[2] = (winIter->plane - MCV[7])*MCV[5]  + MCV[6];
01940         y[3] = (winIter->plane - MCV[7])*MCV[12] + MCV[13];
01941         
01942         if(cluster.size()==0) {
01943           for(int ii=0;ii<4;ii++) {
01944             y_upp[ii] = y[ii] + STRIPWIDTHINMETRES; 
01945             y_low[ii] = y[ii] - STRIPWIDTHINMETRES;
01946           }
01947         }
01948         else {
01949           for(int ii=0;ii<4;ii++) {
01950             y_upp[ii] = y[ii] + MCV[4+int(ii/2)*5];
01951             y_low[ii] = y[ii] - MCV[4+int(ii/2)*5];
01952           }
01953         }
01954 
01955 
01956         for(int ii=0;ii<4;ii++){
01957           if( ( winIter->upper_tpos>=y[ii] && winIter->lower_tpos<=y[ii] ) ||
01958               ( winIter->phpos<=y_upp[ii]  && winIter->phpos>=y_low[ii]  ) ) {
01959             if(badGradient[ii]==0) {
01960               tempcluster[ii].push_back(counter);
01961             }
01962           }
01963         }
01964         winIter++;
01965         counter++;
01966       }
01967 
01968       Int_t best_cluster = -1;
01969       UInt_t max_size = 0;
01970       for(int ii=0;ii<4;ii++){
01971         if(tempcluster[ii].size()>max_size) {
01972           max_size = tempcluster[ii].size();
01973           best_cluster = ii;
01974         }
01975       }
01976       if(best_cluster>=0 && best_cluster<=3) {
01977         std::vector<window>::iterator winIter = nonCluster.begin();
01978         std::vector<window>::iterator winEnd  = nonCluster.end();
01979         std::vector<int>::iterator tempIter = tempcluster[best_cluster].begin();
01980         std::vector<int>::iterator tempEnd  = tempcluster[best_cluster].end();
01981         counter = 0;
01982         while(winIter!=winEnd){
01983           if(tempIter!=tempEnd && (*tempIter) == counter) {
01984             cluster.push_back(*winIter);
01985             avePH += winIter->ph;
01986             aveWidth += winIter->upper_tpos - winIter->lower_tpos;
01987             nStrips += Double_t(winIter->upper - winIter->lower + 1);
01988             if(winIter->plane<lowPlane) lowPlane = winIter->plane;
01989             if(winIter->plane>uppPlane) uppPlane = winIter->plane;
01990             tempIter++;
01991           }
01992           winIter++;
01993           counter++;
01994         }
01995       }
01996     }
01997     else {
01998       cluster.clear();
01999       avePH = 0;
02000       aveWidth = 0;
02001       nStrips = 0;
02002       lowPlane = 500;
02003       uppPlane = 0;
02004       Bool_t stop = false;
02005       while(!stop && offset>=0){
02006         std::vector<window>::iterator winIter = nonCluster.begin();
02007         std::vector<window>::iterator winEnd  = nonCluster.end();
02008         MSG("SubShowerSR",Msg::kVerbose) << "Adding to Proto SubShower: " 
02009                                          << endl;
02010         while(winIter!=winEnd){
02011           double y = (winIter->plane - 
02012                       MCV[2+offset])*MCV[offset] + MCV[1+offset];
02013           double y_upp = (winIter->plane - 
02014                           MCV[2+offset])*MCV[offset] + MCV[1+offset];
02015           double y_low = (winIter->plane - 
02016                           MCV[2+offset])*MCV[offset] + MCV[1+offset];
02017           if(cluster.size()==0) {
02018             y_upp += 0.041;
02019             y_low -= 0.041;
02020           }
02021           else {
02022             y_upp += MCV[4+offset];
02023             y_low -= MCV[4+offset];
02024           }
02025           
02026           MSG("SubShowerSR",Msg::kVerbose) << "Plane: " 
02027                                            << winIter->plane << endl; 
02028           MSG("SubShowerSR",Msg::kVerbose) << "y, upp_tpos, low_tpos: " 
02029                                            << y << " " 
02030                                            << winIter->upper_tpos << " " 
02031                                            << winIter->lower_tpos << endl;
02032           MSG("SubShowerSR",Msg::kVerbose) << "phpos, y_upp, y_low: " 
02033                                            << winIter->phpos << " " 
02034                                            << y_upp << " " << y_low << endl;
02035           
02036           if( ( winIter->upper_tpos>=y && winIter->lower_tpos<=y ) ||
02037               ( winIter->phpos<=y_upp  && winIter->phpos>=y_low  ) ) {
02038             MSG("SubShowerSR",Msg::kVerbose) << "Passed!" << endl;
02039             cluster.push_back(*winIter);
02040             avePH += winIter->ph;
02041             aveWidth += winIter->upper_tpos - winIter->lower_tpos;
02042             nStrips += Double_t(winIter->upper - winIter->lower + 1);
02043             if(winIter->plane<lowPlane) lowPlane = winIter->plane;
02044             if(winIter->plane>uppPlane) uppPlane = winIter->plane;
02045           }
02046           winIter++;
02047         }
02048         offset-=5;
02049         if(cluster.size()!=0) stop = true;
02050       }
02051     }
02052     
02053     delete [] MCV;
02054 
02055     MSG("SubShowerSR",Msg::kDebug) << "Proto-SubShower currently has " 
02056                                    << (uppPlane-lowPlane+2)/2
02057                                    << " planes and " << nStrips 
02058                                    << " strips" << endl;
02059 
02060     if(nStrips == oldNStrips) keepGoing = false;
02061     nLoops+=1;
02062   }
02063 
02064   if(nStrips<=0) return emptyCluster;
02065     
02066   MSG("SubShowerSR",Msg::kDebug) 
02067     << "Returning Proto-SubShower from HoughTransCluster()" << endl;
02068   
02069   if( det==1 && uppPlane>249 && lowPlane<249 ) return cluster;
02070   avePH/=nStrips;
02071   if( ((uppPlane - lowPlane + 2)/2)<3 && avePH<1. ) return emptyCluster;
02072   
02073   return cluster;
02074 
02075 }

Bool_t AlgSubShowerSRList::MergeCluster TObjArray *  ,
CandHandle ,
Int_t  ,
Bool_t  test = false
[private]
 

Definition at line 2252 of file AlgSubShowerSRList.cxx.

References CandStripHandle::DupHandle(), CandSubShowerSRHandle::GetAvgDev(), CandRecoHandle::GetBegPlane(), CandRecoHandle::GetCharge(), CandStripHandle::GetCharge(), CandSubShowerSRHandle::GetClusterID(), CandHandle::GetDaughterIterator(), CandRecoHandle::GetEndPlane(), CandSubShowerSRHandle::GetEnergy(), Calibrator::GetMIP(), CandHandle::GetNDaughters(), CandStripHandle::GetPlane(), CandSubShowerSRHandle::GetPlaneView(), CandStripHandle::GetPlaneView(), CandSubShowerSRHandle::GetSlope(), CandStripHandle::GetTPos(), CandRecoHandle::GetVtxU(), CandRecoHandle::GetVtxV(), CandRecoHandle::GetVtxZ(), CandStripHandle::GetZPos(), Calibrator::Instance(), MSG, PITCHINMETRES, CandHandle::RemoveDaughter(), and STRIPWIDTHINMETRES.

Referenced by RunAlg().

02254 {
02255 
02256   MSG("SubShowerSR", Msg::kDebug) << "Running MergeCluster()" << endl;
02257 
02258   Int_t totStp = newSubShower->GetLast()+1;  
02259   if(totStp==0) return false;
02260 
02261   Calibrator& calibrator=Calibrator::Instance();
02262 
02263   assert(ch.InheritsFrom("CandSubShowerSRListHandle"));
02264   CandSubShowerSRListHandle &csslh = dynamic_cast<CandSubShowerSRListHandle &>(ch);
02265   if(csslh.GetNDaughters()==0) return false;
02266   
02267   //Get planeview for this merge test
02268   TObject *firstObj = newSubShower->At(0);
02269   assert(firstObj->InheritsFrom("CandStripHandle"));
02270   CandStripHandle *firstStp = dynamic_cast<CandStripHandle*>(firstObj);
02271   PlaneView::PlaneView_t pv = firstStp->GetPlaneView();
02272   MSG("SubShowerSR", Msg::kDebug) << "PlaneView = " << pv << endl;
02273 
02274   //check that PH of new subshower is less than some 
02275   //fraction of the primary subshower in the view  
02276   Float_t PrimarySubShowerEnergy = 0;
02277   Float_t NewSubShowerEnergy = 0;
02278   Int_t firstPlaneInNewSubShower = 500;
02279   Int_t lastPlaneInNewSubShower = 0;
02280 
02281   for (Int_t i=0; i<totStp; i++) {
02282     TObject *tobj = newSubShower->At(i);
02283     CandStripHandle *nssStrip = dynamic_cast<CandStripHandle*>(tobj);
02284     NewSubShowerEnergy += calibrator.GetMIP(nssStrip->GetCharge(CalDigitType::kSigCorr));
02285     Int_t thePlane = nssStrip->GetPlane();
02286     if(thePlane<firstPlaneInNewSubShower) firstPlaneInNewSubShower = thePlane;
02287     if(thePlane>lastPlaneInNewSubShower) lastPlaneInNewSubShower = thePlane;
02288   }
02289   
02290   //calculate the number of planes in this newsubshower:
02291   Float_t nPlanesInNewSubShower = Float_t(lastPlaneInNewSubShower-firstPlaneInNewSubShower+2)/2.;
02292   MSG("SubShowerSR", Msg::kDebug) << "First Plane in NewSubShower = " << firstPlaneInNewSubShower 
02293                                   << " Last Plane in NewSubShower = " << lastPlaneInNewSubShower
02294                                   << " Number of Planes in New SubShower " << nPlanesInNewSubShower
02295                                   << endl;
02296 
02297   Double_t mip2gev;
02298   CandSubShowerSRHandleItr PHsubshowerItr(csslh.GetDaughterIterator());
02299   while (CandSubShowerSRHandle *subshower = PHsubshowerItr()) {
02300     if(subshower->GetPlaneView()!=pv) continue;
02301     mip2gev = subshower->GetEnergy() / 
02302       calibrator.GetMIP(subshower->GetCharge(CalStripType::kSigCorr));
02303     if(subshower->GetEnergy()>PrimarySubShowerEnergy) 
02304       PrimarySubShowerEnergy=subshower->GetEnergy();
02305   }
02306   NewSubShowerEnergy*=mip2gev;
02307   
02308   if(PrimarySubShowerEnergy<=0) return false;
02309   if(NewSubShowerEnergy/PrimarySubShowerEnergy>fMergeFracEnergyLimit) return false;
02310   
02311   //keep track of the following to decide whether or not to merge:
02312   //1) number of shared boundary planes:  
02313   //2) number of planes which have strips nearby to another subshower core:
02314   //3) charge asymmetry of newsubshower around axis of other subshowers:
02315   //   (if this is not high => newsubshower is being formed 
02316   //    from outliers of another subshower)
02317   //4) summed distance of each hit in newsubshower to the closest hit in another subshower:
02318   //   (only used when newsubshower has <=2 planes)
02319   Float_t *FracBoundaryPlanes = new Float_t[csslh.GetNDaughters()];
02320   Float_t *FracWithinPlanes = new Float_t[csslh.GetNDaughters()];
02321   Float_t *FracDiffCross = new Float_t[csslh.GetNDaughters()];
02322   Float_t *SumDistanceFromNewSubShower = new Float_t[csslh.GetNDaughters()];
02323   for(int i=0;i<csslh.GetNDaughters();i++) {
02324     FracBoundaryPlanes[i] = 0;
02325     FracWithinPlanes[i] = 0;
02326     FracDiffCross[i] = 1.;
02327     SumDistanceFromNewSubShower[i] = 0.;
02328   }
02329 
02330   //loop through existing subshowers
02331   Int_t ssCount = 0;
02332   CandSubShowerSRHandleItr subshowerItr(csslh.GetDaughterIterator());
02333   while (CandSubShowerSRHandle *subshower = subshowerItr()) {
02334 
02335     ssCount++; //increment early because of continue statements, later use ssCount-1
02336     
02337     //only look at the right planeview subshowers
02338     if(subshower->GetPlaneView()!=pv) {
02339       SumDistanceFromNewSubShower[ssCount-1] = 99999.;
02340       continue; 
02341     }
02342 
02343     MSG("SubShowerSR", Msg::kVerbose) << "SubShower " << ssCount-1 
02344                                       << " in the same planeview" << endl;
02345 
02346     //get subshower vertex and angle:
02347     Double_t tposVtx = 0;
02348     if(pv==PlaneView::kU || pv==PlaneView::kX) tposVtx = subshower->GetVtxU();
02349     else if(pv==PlaneView::kV || pv==PlaneView::kY) tposVtx = subshower->GetVtxV();      
02350     Double_t zposVtx = subshower->GetVtxZ();
02351     Float_t slope = subshower->GetSlope(); 
02352     Float_t avgdev = subshower->GetAvgDev();
02353     ClusterType::ClusterType_t id = subshower->GetClusterID();
02354 
02355     Bool_t stripVeto = false;
02356     Int_t PlaneChecker[500] = {0};
02357     Double_t PlaneTot[500] = {0};
02358     Double_t PlaneWithin[500] = {0};
02359     Double_t PlaneUp = 0;
02360     Double_t PlaneDown = 0;    
02361 
02362     //shortest distance between any strip in newsubshower and any strip in existing subshower:
02363     Float_t minimumDistanceFromNewSubShower = 999.; 
02364 
02365     //perform checks to see if new potential cluster can be merged with an existing cluster
02366     for (Int_t i=0; i<totStp; i++) {
02367       
02368       TObject *tobj = newSubShower->At(i);
02369       CandStripHandle *nssStrip = dynamic_cast<CandStripHandle*>(tobj);
02370 
02371       // if plane of any strip is more than 1 plane (of same type) away
02372       // don't try to merge with this subshower unless new subshower contains <=2 planes
02373       // (also beware of SM boundary in FarDet)
02374       Int_t thePlane = nssStrip->GetPlane();
02375       Float_t theCharge = calibrator.GetMIP(nssStrip->GetCharge(CalDigitType::kSigCorr));
02376 
02377       if(thePlane<subshower->GetBegPlane()-2 || thePlane>subshower->GetEndPlane()+2 || 
02378          (det==1 && ( (subshower->GetBegPlane()>249 && thePlane<249) || 
02379                       (subshower->GetEndPlane()<249 && thePlane>249)   ) ) ) {
02380         stripVeto = true;       
02381       }
02382       else MSG("SubShowerSR", Msg::kVerbose) << "New Strip " << i 
02383                                              << " in the same plane range" << endl;
02384 
02385       //if we got a stripVeto above, 
02386       //and this NewSubShower is longer than 2 planes
02387       //or the existing SubShower is not of type XTalk
02388       //don't merge, break here:
02389       if(stripVeto) {
02390         if(nPlanesInNewSubShower>2) break;      
02391         if(id!=ClusterType::kXTalk) {
02392           SumDistanceFromNewSubShower[ssCount-1] = 99999.;
02393           break;
02394         }
02395       }
02396 
02397       //loop through strips in subshower
02398       //check for proximity to other strips in subshower (on a plane-by-plane basis)
02399       Float_t theStrip_tpos = nssStrip->GetTPos();
02400       //remember closest distance from nssStrip to any strip in subshower:
02401       Float_t closestDistance = 999.;
02402       CandStripHandleItr stripItr(subshower->GetDaughterIterator());
02403       while(CandStripHandle *stp = stripItr()){
02404         //check we're on the same plane 
02405         //or on the begin plane if the nssStrip plane < begin plane
02406         //or on the end plane if the nssStrip plane > end plane
02407         if((stp->GetPlane() == thePlane) ||
02408            (thePlane < subshower->GetBegPlane() && stp->GetPlane() == subshower->GetBegPlane()) ||
02409            (thePlane > subshower->GetEndPlane() && stp->GetPlane() == subshower->GetEndPlane())) {
02410           if(TMath::Abs(theStrip_tpos-stp->GetTPos())<=2.5*STRIPWIDTHINMETRES) { //allow +/- 2.5 strips
02411             PlaneChecker[thePlane] = 1;  //this plane has a shared boundary
02412           }
02413           if(TMath::Abs(theStrip_tpos-stp->GetTPos())<closestDistance) {
02414             closestDistance = TMath::Abs(theStrip_tpos-stp->GetTPos());
02415           }
02416         }
02417         if(stripVeto) { //newsubshower must be short (<2 planes)
02418           //this strip is not adjacent to any existing subshower
02419           //calculate the closestDistance anyway, but factor in delta(plane):
02420           Float_t testDistance = TMath::Abs(theStrip_tpos-stp->GetTPos()) + 
02421             PITCHINMETRES*TMath::Abs(Float_t(thePlane-stp->GetPlane()));
02422           if(testDistance < closestDistance) closestDistance = testDistance;
02423         }
02424       }
02425 
02426       if(closestDistance<minimumDistanceFromNewSubShower)
02427         minimumDistanceFromNewSubShower = closestDistance;
02428       
02429       SumDistanceFromNewSubShower[ssCount-1] += closestDistance;
02430       
02431       //calculate pH weighted distance from cluster centre      
02432       //get strip position and charge:
02433       Float_t tpos = nssStrip->GetTPos();
02434       Float_t zpos = nssStrip->GetZPos();
02435       Double_t StripDistance = 99999;
02436       if(avgdev!=0.) {
02437         StripDistance = (tpos-(tposVtx+slope*(zpos-zposVtx))* 
02438                          TMath::Cos(TMath::ATan(slope)))*theCharge/avgdev;
02439       }
02440       else MSG("SubShowerSR",Msg::kWarning) << "SubShower " << ssCount-1 
02441                                             << " has AvgDev = 0!" << endl;
02442       
02443       if(TMath::Abs(StripDistance)<=1.) PlaneWithin[thePlane]+=theCharge;
02444       if(StripDistance>0) PlaneUp+=theCharge;
02445       if(StripDistance<0) PlaneDown+=theCharge;
02446       PlaneTot[thePlane]+=theCharge;
02447 
02448     }
02449 
02450     if(stripVeto) continue;
02451 
02452     //If this is true, Must be comparing a subshower with itself
02453     if(SumDistanceFromNewSubShower[ssCount-1] == 0.000000) {
02454       SumDistanceFromNewSubShower[ssCount-1] = 99999;
02455       continue;
02456     }
02457 
02458     MSG("SubShowerSR",Msg::kVerbose) << "SumDistanceFromNewSubShower for SubShower " 
02459                                      << ssCount-1     
02460                                      << " = " << SumDistanceFromNewSubShower[ssCount-1] << endl;
02461 
02462     //fill the arrays for this subshower:
02463     Float_t n0planes = 0.;
02464     for(int i = firstPlaneInNewSubShower;i<=lastPlaneInNewSubShower;i+=2){
02465       FracBoundaryPlanes[ssCount-1] += PlaneChecker[i];
02466       if (PlaneTot[i]>0){ 
02467         FracWithinPlanes[ssCount-1] += PlaneWithin[i]/PlaneTot[i];
02468       }
02469       else n0planes++;
02470     }
02471 
02472     FracBoundaryPlanes[ssCount-1] /= nPlanesInNewSubShower-n0planes;
02473     FracWithinPlanes[ssCount-1] /= nPlanesInNewSubShower-n0planes;
02474     if (PlaneUp*PlaneDown>0) {
02475       FracDiffCross[ssCount-1] = TMath::Abs(PlaneUp-PlaneDown)/(PlaneUp+PlaneDown);
02476     }
02477     
02478     //lastly we need to worry about a special case:
02479     //if newSubShower is in the same plane range, and the number of planes is <=2
02480     //but the closest strip to the current subshower is >2.5 strips away and the
02481     //cluster id is not kXTalk, then don't merge with this subshower
02482     if(!stripVeto && nPlanesInNewSubShower<=2 && 
02483        minimumDistanceFromNewSubShower>2.5*STRIPWIDTHINMETRES &&
02484        id!=ClusterType::kXTalk) SumDistanceFromNewSubShower[ssCount-1] = 99999.; 
02485     
02486   }
02487   
02488   Float_t BestSumDistance = 9999.;
02489   Int_t closestSubShowerSumDistance = -1;
02490 
02491   Float_t BestFracBoundary = fMergeBestFracBoundary;
02492   Int_t closestSubShowerBoundary = -1;
02493 
02494   Float_t BestFracWithin = fMergeBestFracWithin;
02495   Int_t closestSubShowerWithin = -1;
02496 
02497   Float_t BestFracCross = fMergeBestFracCross;
02498   Int_t closestSubShowerCross = -1;
02499 
02500   //Float_t BestFracBoundaryHalf = BestFracBoundary/2.;
02501   //Float_t BestFracWithinHalf = BestFracWithin/2.;
02502   //Int_t closestSubShowerBoundWithin = -1;
02503 
02504   Int_t closestSubShower = -1;
02505 
02506   for(int i=0;i<csslh.GetNDaughters();i++){
02507     if(false&&nPlanesInNewSubShower<=2){
02508       if(SumDistanceFromNewSubShower[i]<BestSumDistance) {
02509         BestSumDistance = SumDistanceFromNewSubShower[i];
02510         closestSubShowerSumDistance = i;
02511       }
02512     }
02513     else {
02514       if(FracBoundaryPlanes[i]>BestFracBoundary){
02515         BestFracBoundary = FracBoundaryPlanes[i];
02516         closestSubShowerBoundary = i;
02517       }
02518       if(FracWithinPlanes[i]>BestFracWithin) {
02519         BestFracWithin = FracWithinPlanes[i];
02520         closestSubShowerWithin = i;
02521       }
02522       //if(FracBoundaryPlanes[i]>BestFracBoundaryHalf &&
02523       // FracWithinPlanes[i]>BestFracWithinHalf) {
02524       //BestFracBoundaryHalf = FracBoundaryPlanes[i];
02525       //BestFracWithinHalf = FracWithinPlanes[i];
02526       //closestSubShowerBoundWithin = i;
02527       //}
02528       if(FracDiffCross[i]<BestFracCross) {
02529         BestFracCross = FracDiffCross[i];
02530         closestSubShowerCross = i;
02531       }
02532     }
02533   }
02534 
02535   delete [] FracBoundaryPlanes;
02536   delete [] FracWithinPlanes;
02537   delete [] FracDiffCross;
02538   delete [] SumDistanceFromNewSubShower;
02539 
02540   if(closestSubShowerCross>=0)            closestSubShower = closestSubShowerCross;     
02541   else if(closestSubShowerSumDistance>=0) closestSubShower = closestSubShowerSumDistance;
02542   else if(closestSubShowerBoundary>=0)    closestSubShower = closestSubShowerBoundary;
02543   else if(closestSubShowerWithin>=0)      closestSubShower = closestSubShowerWithin;
02544   //else if(closestSubShowerBoundWithin>=0) closestSubShower = closestSubShowerBoundWithin;
02545   
02546   if(closestSubShower!=-1){    
02547     CandSubShowerSRHandleItr subshowerItr(csslh.GetDaughterIterator());
02548     ssCount = 0;
02549     while(CandSubShowerSRHandle *cssh = subshowerItr()){
02550       if(ssCount==closestSubShower){
02551         MSG("SubShowerSR", Msg::kDebug) << "Found Sub Shower to merge "<<closestSubShower<<endl;
02552         if(test) return true;
02553         CandStripHandleItr stripItr(cssh->GetDaughterIterator());
02554         while(CandStripHandle *stp = stripItr()) newSubShower->Add(stp->DupHandle());
02555         csslh.RemoveDaughter(cssh);
02556         MSG("SubShowerSR", Msg::kDebug) << "Old Sub Shower removed"<<endl;
02557         return true;
02558       }
02559       ssCount+=1;   
02560     }
02561   }
02562 
02563   return false;  //couldn't merge
02564   
02565 }

void AlgSubShowerSRList::RunAlg AlgConfig ac,
CandHandle ch,
CandContext cx
[virtual]
 

Implements AlgBase.

Definition at line 70 of file AlgSubShowerSRList.cxx.

References CandHandle::AddDaughterLink(), CleanUp(), CandStripHandle::DupHandle(), FindCluster(), fLongWindowMipCut, fMaxPlaneGap, fMergeBestFracBoundary, fMergeBestFracCross, fMergeBestFracWithin, fMergeFracEnergyLimit, FormHalo(), Registry::Get(), AlgFactory::GetAlgHandle(), CandClusterHandle::GetBegPlane(), CandRecoHandle::GetBegPlane(), CandContext::GetCandRecord(), CandClusterHandle::GetCandSlice(), CandRecoHandle::GetCandSlice(), CandStripHandle::GetCharge(), CandContext::GetDataIn(), CandHandle::GetDaughterIterator(), VldContext::GetDetector(), Registry::GetDouble(), CandClusterHandle::GetEndPlane(), CandRecoHandle::GetEndPlane(), AlgFactory::GetInstance(), Registry::GetInt(), Calibrator::GetMIP(), CandContext::GetMom(), CandHandle::GetNDaughters(), CandRecoHandle::GetNStrip(), CandStripHandle::GetPlane(), CandStripHandle::GetPlaneView(), RecMinos::GetVldContext(), Calibrator::Instance(), CandSubShowerSR::MakeCandidate(), MergeCluster(), MSG, CandHandle::RemoveDaughter(), CandRecoHandle::SetCandSlice(), and TestOverLap().

00071 {
00072 
00073   MSG("SubShowerSR", Msg::kDebug) << "Starting AlgSubShowerSRList::RunAlg()" 
00074                                   << endl;
00075   assert(cx.GetDataIn());
00076   if (!(cx.GetDataIn()->InheritsFrom("TObjArray"))) {
00077     return;
00078   }
00079   
00080   const CandSliceListHandle *slicelist = 0;
00081   const CandClusterListHandle *clusterlist = 0;
00082   const CandTrackListHandle *tracklist = 0;
00083   const TObjArray *cxin = dynamic_cast<const TObjArray *>(cx.GetDataIn());
00084   for (Int_t i=0; i<=cxin->GetLast(); i++) {
00085     TObject *tobj = cxin->At(i);
00086     MSG("SubShowerSR", Msg::kDebug) << "cxin->At(" << i << ")"<< endl;
00087     if (tobj->InheritsFrom("CandSliceListHandle")) {
00088       slicelist = dynamic_cast<CandSliceListHandle*>(tobj);
00089       MSG("SubShowerSR", Msg::kDebug) << "Got SliceList" << endl;
00090     }
00091     if (tobj->InheritsFrom("CandClusterListHandle")) {
00092       clusterlist = dynamic_cast<CandClusterListHandle*>(tobj);
00093       MSG("SubShowerSR", Msg::kDebug) << "Got ClusterList" << endl;
00094     }
00095     if (tobj->InheritsFrom("CandTrackListHandle")) {
00096       tracklist = dynamic_cast<CandTrackListHandle*>(tobj);
00097       MSG("SubShowerSR", Msg::kDebug) << "Got TrackList" << endl;
00098     }
00099   }
00100   if (!slicelist || !clusterlist || !tracklist) {
00101     MSG("SubShowerSR",Msg::kInfo) << "CandSliceListHandle or " 
00102                                   << "CandClusterListHandle or " 
00103                                   << "CandTrackListHandle missing\n";
00104     return;
00105   }
00106 
00107   MSG("SubShowerSR", Msg::kDebug) << "Creating CandContext" << endl;
00108   // Create Candcontext
00109   CandContext cxx(this,cx.GetMom());
00110 
00111   //get config for AlgSubShowerSRList
00112   const char *charSubShowerSRAlgConfig = 0;
00113   ac.Get("SubShowerSRAlgConfig",charSubShowerSRAlgConfig);
00114   fMergeFracEnergyLimit  = ac.GetDouble("MergeFracEnergyLimit");
00115   fMergeBestFracBoundary = ac.GetDouble("MergeBestFracBoundary");
00116   fMergeBestFracWithin   = ac.GetDouble("MergeBestFracWithin");
00117   fMergeBestFracCross    = ac.GetDouble("MergeBestFracCross");
00118   fLongWindowMipCut      = ac.GetDouble("LongWindowMipCut");
00119   fMaxPlaneGap           = ac.GetInt("MaxPlaneGap");
00120   
00121   Int_t minNTrkOnlyPlanesToUseTrackStrips = 
00122     ac.GetInt("MinNTrkOnlyPlanesToUseTrackStrips");
00123   Int_t maxPlanesFromVtxToUseTrackStrips  = 
00124     ac.GetInt("MaxPlanesFromVertexToUseTrackStrips");
00125   Double_t minMIPsToUseTrackStrips =
00126     ac.GetDouble("MinMIPsToUseTrackStrips");
00127 
00128   //Get singleton instance of AlgFactory
00129   AlgFactory &af = AlgFactory::GetInstance();
00130   AlgHandle ah = af.GetAlgHandle("AlgSubShowerSR",charSubShowerSRAlgConfig);
00131                                                                    
00132   const CandRecord *candrec = cx.GetCandRecord();
00133   assert(candrec);
00134   const VldContext *vldcptr = candrec->GetVldContext();
00135   assert(vldcptr);
00136   VldContext vldc = *vldcptr;                                         
00137   UgliGeomHandle ugh(vldc);
00138   Int_t detector = 0;
00139   if(vldc.GetDetector()==DetectorType::kFar) detector = 1;
00140 
00141   Calibrator& calibrator = Calibrator::Instance();
00142 
00143   //keep track of all unassigned strips in all slices and try to add them later
00144   TObjArray unassignedStrips;
00145 
00146   //loop over all slices
00147   Int_t sliceCounter = 0;
00148   CandSliceHandleItr sliceItr(slicelist->GetDaughterIterator());
00149   while (CandSliceHandle *slice = sliceItr()) {
00150 
00151     MSG("SubShowerSR",Msg::kVerbose) << "Slice " <<  sliceCounter << endl;
00152 
00153     //also keep track of cluster planes and track planes
00154     Int_t cluPln[500] = {0};
00155     Int_t trkPln[500] = {0};
00156     Int_t nTrkOnlyPlanes = 0;
00157     if(tracklist!=0) {
00158       //loop through all tracks in track list
00159       CandTrackHandleItr trackItr(tracklist->GetDaughterIterator());
00160       while (CandTrackHandle *track = trackItr()){
00161         //if this track is in the current slice then...
00162         if (*track->GetCandSlice()==*slice) {
00163           for(Int_t i=track->GetBegPlane();i<=track->GetEndPlane();i++){
00164             trkPln[i] += 1;   //if trkPln > 1 => multiple tracks in plane
00165             nTrkOnlyPlanes += 1;
00166           }
00167         }
00168       }
00169     }
00170     if(clusterlist!=0) {
00171       //loop through all clusters in cluster list
00172       CandClusterHandleItr clusterItr(clusterlist->GetDaughterIterator());
00173       while (CandClusterHandle *cluster = clusterItr()){
00174         //if this cluster is in the current slice then...
00175         if (*cluster->GetCandSlice()==*slice) {
00176           for(Int_t i=cluster->GetBegPlane();i<=cluster->GetEndPlane();i+=2){
00177             cluPln[i] += 1;   //if cluPln > 1 => multiple clusters in plane
00178             if(trkPln[i]>0) nTrkOnlyPlanes-=1;
00179             if(detector==1){//account for SM gap
00180               if(i==247) i = 250; 
00181               if(i==248) i = 251;
00182             }
00183           }
00184         }
00185       }
00186     }
00187 
00188     //for each slice, make an Object Array to hold all the 
00189     //non track strips in the slice
00190     TObjArray allUStrips;
00191     TObjArray allVStrips;
00192     
00193     //loop through the strips in the slice
00194     CandStripHandleItr stripslcItr(slice->GetDaughterIterator());    
00195     MSG("SubShowerSR",Msg::kVerbose) << "About to loop through slice strips" 
00196                                      << endl;
00197     
00198     while (CandStripHandle *stp =stripslcItr()) { //while over slice stp
00199       bool gotStrip = false;
00200       MSG("SubShowerSR",Msg::kVerbose) << "PlaneView " 
00201                                        << stp->GetPlaneView() << endl;
00202       
00203       CandClusterHandleItr clusterItr(clusterlist->GetDaughterIterator());
00204       Int_t clusterCounter = 0;
00205       while(CandClusterHandle *cluster = clusterItr()){ 
00206         MSG("SubShowerSR",Msg::kVerbose) 
00207           << "Looking for stp match in cluster " << clusterCounter << endl;
00208         if(*cluster->GetCandSlice()==*slice){
00209           CandStripHandleItr stripcluItr(cluster->GetDaughterIterator());
00210           while (CandStripHandle *stpclu =stripcluItr()){
00211             if(*stp==*stpclu){
00212               gotStrip = true;
00213               //add strip to object array then break out of loop
00214               if(stp->GetPlaneView()==PlaneView::kU ||
00215                  stp->GetPlaneView()==PlaneView::kX) {
00216                 allUStrips.Add(stp);
00217                 MSG("SubShowerSR",Msg::kVerbose) << "Found match! U strip" 
00218                                                  << endl;             
00219               }
00220               else if(stp->GetPlaneView()==PlaneView::kV ||
00221                       stp->GetPlaneView()==PlaneView::kY) {
00222                 allVStrips.Add(stp);
00223                 MSG("SubShowerSR",Msg::kVerbose) << "Found match! V strip" 
00224                                                  << endl;
00225               }
00226               else MSG("SubShowerSR",Msg::kError) 
00227                 << "Unknown PlaneView! Not adding strip to initial ObjArray" 
00228                 << endl;
00229               break;
00230             }
00231           }
00232         }
00233         if(gotStrip) break;
00234         clusterCounter++;
00235       }
00236       
00237       //if this is an ND strip in spectrometer, don't add to array
00238       if(!gotStrip && detector==0 && stp->GetPlane()>=121) gotStrip=true;
00239 
00240       if(!gotStrip){  //if !gotStrip
00241         bool inTrack = false;
00242         Int_t nPlanesFromBegPlane = 0;
00243         if(tracklist!=0) {
00244           MSG("SubShowerSR",Msg::kVerbose) 
00245             << "No matched strip found in clusters, looking in tracks"
00246             << endl;
00247           
00248           //loop through all tracks in track list
00249           CandTrackHandleItr trackItr(tracklist->GetDaughterIterator());
00250           Int_t trackCounter = 0;
00251           while (CandTrackHandle *track = trackItr()){
00252             MSG("SubShowerSR",Msg::kVerbose) 
00253               << "Looking for match of slc stp with trk stp in track "
00254               << trackCounter << endl;
00255             //if this track is in the current slice then...
00256             if (*track->GetCandSlice()==*slice) {
00257               //...loop over all strips in this track
00258               CandStripHandleItr striptrkItr(track->GetDaughterIterator());
00259               while (CandStripHandle *stptrk =striptrkItr()){
00260                 //if this strip is in this track then...
00261                 if (*stp == *stptrk) {
00262                   MSG("SubShowerSR",Msg::kVerbose) 
00263                     << "Found match! This strip is in a track!" << endl;
00264                   //...break and move on to the next strip in the slice
00265                   inTrack = true;
00266                   nPlanesFromBegPlane = TMath::Abs(stp->GetPlane()-track->GetBegPlane());
00267                   break;
00268                 }
00269               }
00270             }
00271             if(inTrack) break;
00272             trackCounter++;
00273           }
00274         }
00275         
00276         MSG("SubShowerSR",Msg::kVerbose) << "nTrkOnlyPlanes = " 
00277                                          << nTrkOnlyPlanes << endl;
00278         if(inTrack && nTrkOnlyPlanes<minNTrkOnlyPlanesToUseTrackStrips) {
00279           MSG("SubShowerSR",Msg::kDebug) 
00280             << "nTrkOnlyPlanes<" << minNTrkOnlyPlanesToUseTrackStrips 
00281             << " - going to include this strip " 
00282             << "even though it's in a track." << endl;
00283           inTrack = false; //ignore tracks that are buried in showers
00284         }
00285         else if(inTrack && nPlanesFromBegPlane <
00286                 maxPlanesFromVtxToUseTrackStrips) { //near vertex
00287           if(calibrator.GetMIP(stp->GetCharge(CalDigitType::kSigCorr)) >
00288              minMIPsToUseTrackStrips) {
00289             MSG("SubShowerSR",Msg::kDebug) 
00290               << "nPlanesFromBegPlane < "
00291               << maxPlanesFromVtxToUseTrackStrips 
00292               << " for this strip and ph = "
00293               << calibrator.GetMIP(stp->GetCharge(CalDigitType::kSigCorr))
00294               << " mips. "
00295               << "Going to include it even though it's in a track." 
00296               << endl;
00297             inTrack = false;
00298           }
00299         }
00300 
00301         //then: add it to our array
00302         if(!inTrack){
00303           MSG("SubShowerSR",Msg::kVerbose) << "Strip not found in track! ";
00304           if(stp->GetPlaneView()==PlaneView::kU ||
00305              stp->GetPlaneView()==PlaneView::kX) {
00306             allUStrips.Add(stp);
00307             MSG("SubShowerSR",Msg::kVerbose) << "Adding U strip" << endl;
00308           }
00309           else if(stp->GetPlaneView()==PlaneView::kV ||
00310                   stp->GetPlaneView()==PlaneView::kY) {
00311             allVStrips.Add(stp);
00312             MSG("SubShowerSR",Msg::kVerbose) << "Adding V strip" << endl;
00313           }
00314           else MSG("SubShowerSR",Msg::kError) 
00315             << "Unknown PlaneView! Not adding strip to initial ObjArray" 
00316             << endl;
00317         }
00318       }
00319     }
00320 
00321     MSG("SubShowerSR",Msg::kDebug) << "Found total of " 
00322                                    << allUStrips.GetLast()+1 << " U strips" 
00323                                    << " and " << allVStrips.GetLast()+1 
00324                                    << " V strips" << endl;
00325     
00326     //In here put code to pull out the strips belonging to the SubShowers:
00327     bool keepGoingU = true;
00328     bool keepGoingV = true;
00329     while(keepGoingU || keepGoingV){
00330       if(keepGoingU) 
00331         MSG("SubShowerSR",Msg::kDebug) << "Still have " 
00332                                        << allUStrips.GetLast()+1
00333                                        << " U strips to process" << endl;
00334       
00335       else if(keepGoingV) 
00336         MSG("SubShowerSR",Msg::kDebug) << "Still have " 
00337                                        << allVStrips.GetLast()+1
00338                                        << " V strips to process" << endl;
00339 
00340       if(allUStrips.GetLast()+1<=0) keepGoingU = false;
00341       if(allVStrips.GetLast()+1<=0) keepGoingV = false;
00342 
00343       TObjArray newSubShower;
00344       if(keepGoingU){ //do U first
00345         this->FindCluster(&allUStrips,&newSubShower,detector);
00346         while(this->TestOverLap(&newSubShower,ch,slice));
00347         MSG("SubShowerSR",Msg::kDebug) << "Added " << newSubShower.GetLast()+1 
00348                                        << " U strips to newSubShower" << endl;
00349       }
00350       else if(keepGoingV) { //then V strips
00351         TObjArray protoSubShower;
00352         this->FindCluster(&allVStrips,&newSubShower,detector);
00353         while(this->TestOverLap(&newSubShower,ch,slice));
00354         MSG("SubShowerSR",Msg::kDebug) << "Added " << newSubShower.GetLast()+1 
00355                                        << " V strips to newSubShower" << endl;
00356      }
00357 
00358       //Everytime you have a newSubShower with all the strips 
00359       //you want to add do this
00360       cxx.SetDataIn(&newSubShower);
00361       MSG("SubShowerSR",Msg::kDebug) << "forming SubShowerSR\n";
00362       CandSubShowerSRHandle subshowersrhandle = 
00363         CandSubShowerSR::MakeCandidate(ah,cxx);
00364       
00365       if(subshowersrhandle.GetNStrip()!=0) {
00366         
00367         MSG("SubShowerSR",Msg::kDebug) << "Formed SubShowerSR with " 
00368                                        << subshowersrhandle.GetNStrip() 
00369                                        << " strips" << endl;
00370         
00371         subshowersrhandle.SetCandSlice(slice);
00372         ch.AddDaughterLink(subshowersrhandle);
00373         
00374         CandStripHandleItr stripItr(subshowersrhandle.GetDaughterIterator());
00375         
00376         int *tmpUArray = new int[allUStrips.GetLast()+1];
00377         for(int i=0;i<allUStrips.GetLast()+1;i++) tmpUArray[i] = 0;
00378         int *tmpVArray = new int[allVStrips.GetLast()+1];
00379         for(int i=0;i<allVStrips.GetLast()+1;i++) tmpVArray[i] = 0;     
00380         
00381         while(CandStripHandle *stp = stripItr()){
00382           if(stp->GetPlaneView()==PlaneView::kU ||
00383              stp->GetPlaneView()==PlaneView::kX){
00384             for (int i=0; i<=allUStrips.GetLast(); i++) {
00385               TObject *tobj = allUStrips.At(i);
00386               assert(tobj->InheritsFrom("CandStripHandle"));
00387               CandStripHandle *striphandle = 
00388                 dynamic_cast<CandStripHandle*>(tobj);
00389               if(*stp==*striphandle) {
00390                 tmpUArray[i] = 1;
00391                 break;
00392               }
00393             }
00394           }
00395           else if(stp->GetPlaneView()==PlaneView::kV ||
00396                   stp->GetPlaneView()==PlaneView::kY){
00397             for (int i=0; i<=allVStrips.GetLast(); i++) {
00398               TObject *tobj = allVStrips.At(i);
00399               assert(tobj->InheritsFrom("CandStripHandle"));
00400               CandStripHandle *striphandle = 
00401                 dynamic_cast<CandStripHandle*>(tobj);
00402               if(*stp==*striphandle) {
00403                 tmpVArray[i] = 1;
00404                 break;
00405               }
00406             }
00407           }
00408         }
00409         
00410         //remove used strips from arrays
00411         for(int i=0;i<allUStrips.GetLast()+1;i++) {
00412           if(tmpUArray[i]==1) allUStrips.RemoveAt(i);
00413         }
00414         allUStrips.Compress();
00415         if(allUStrips.GetLast()==-1) keepGoingU = false;
00416         delete [] tmpUArray;
00417         
00418         for(int i=0;i<allVStrips.GetLast()+1;i++) {
00419           if(tmpVArray[i]==1) allVStrips.RemoveAt(i);
00420         }
00421         allVStrips.Compress();
00422         if(allVStrips.GetLast()==-1) keepGoingV = false;
00423         delete [] tmpVArray;
00424       
00425       }
00426       else {
00427         MSG("SubShowerSR",Msg::kDebug) 
00428           << "SubShowerSR formed with 0 strips - not adding to list" 
00429           << endl;
00430         if(keepGoingU) {
00431           MSG("SubShowerSR",Msg::kDebug) << "Running CleanUp() on U Strips" 
00432                                          << endl;       
00433           keepGoingU = CleanUp(&allUStrips,ch,detector,slice);
00434           if(!keepGoingU) {
00435             for(int i=0;i<allUStrips.GetLast()+1;i++) {
00436               unassignedStrips.Add(allUStrips.At(i));
00437             }
00438           }
00439         }
00440         else {
00441           MSG("SubShowerSR",Msg::kDebug) << "Running CleanUp() on V Strips" 
00442                                          << endl;
00443           keepGoingV = CleanUp(&allVStrips,ch,detector,slice);
00444           if(!keepGoingV) {
00445             for(int i=0;i<allVStrips.GetLast()+1;i++) {
00446               unassignedStrips.Add(allVStrips.At(i));
00447             }
00448           }
00449         }
00450       }
00451     }
00452 
00453     sliceCounter++;
00454 
00455     continue;
00456     //Try to merge some clusters:
00457     Bool_t stillMergeChanges = true;
00458     while(stillMergeChanges){
00459       stillMergeChanges = false;
00460       CandSubShowerSRListHandle &csslh = 
00461         dynamic_cast<CandSubShowerSRListHandle &>(ch);
00462       MSG("SubShowerSR",Msg::kDebug) << "In Merge Loop: NDaughters = " 
00463                                      << csslh.GetNDaughters() << endl;
00464       CandSubShowerSRHandleItr subshowerItr(csslh.GetDaughterIterator());    
00465       CandSubShowerSRHandleKeyFunc *engKF = subshowerItr.CreateKeyFunc();
00466       engKF->SetFun(CandSubShowerSRHandle::KeyFromReverseViewEnergy);
00467       subshowerItr.GetSet()->AdoptSortKeyFunc(engKF);
00468       while(CandSubShowerSRHandle *cssh = subshowerItr()){
00469         if(*cssh->GetCandSlice()==*slice){
00470           CandStripHandleItr stripItr(cssh->GetDaughterIterator());
00471           TObjArray mergeSubShower;
00472           while(CandStripHandle *stp = stripItr()) 
00473             mergeSubShower.Add(stp->DupHandle());
00474           
00475           if(this->MergeCluster(&mergeSubShower,csslh,detector,true)){
00476             MSG("SubShowerSR",Msg::kDebug) << "Going to Merge: NDaughters = " 
00477                                            << csslh.GetNDaughters() << endl;
00478             csslh.RemoveDaughter(cssh);
00479             MSG("SubShowerSR",Msg::kDebug) 
00480               << "Removed Initial Daughter: NDaughters = " 
00481               << csslh.GetNDaughters() << endl;             
00482             this->MergeCluster(&mergeSubShower,csslh,detector);
00483             MSG("SubShowerSR",Msg::kDebug) << "Merged: NDaughters = " 
00484                                            << csslh.GetNDaughters() << endl;
00485             cxx.SetDataIn(&mergeSubShower);
00486             CandSubShowerSRHandle subshowersrhandle = 
00487               CandSubShowerSR::MakeCandidate(ah,cxx);
00488             subshowersrhandle.SetCandSlice(slice);
00489             csslh.AddDaughterLink(subshowersrhandle);       
00490             MSG("SubShowerSR",Msg::kDebug) 
00491               << "Made New Daughter: NDaughters = " 
00492               << csslh.GetNDaughters() << endl;
00493             stillMergeChanges = true;
00494             break;
00495           }
00496           if(stillMergeChanges) break;
00497         }
00498         if(stillMergeChanges) break;
00499       }
00500     }
00501   }
00502 
00503   //slice-wise cleanup
00504   if(FormHalo(&unassignedStrips,ch,cxx,ah,slicelist,detector)) 
00505     MSG("SubShowerSR",Msg::kDebug) << "Halo SubShowers formed" << endl;
00506 
00507 }

NavKey AlgSubShowerSRList::StripKeyFromPlane const CandStripHandle  )  [static]
 

Definition at line 3397 of file AlgSubShowerSRList.cxx.

03398 {
03399   return const_cast<CandStripHandle *>(strip)->GetPlane();
03400 }

Bool_t AlgSubShowerSRList::TestOverLap TObjArray *  ,
CandHandle ,
const CandSliceHandle
[private]
 

Definition at line 2078 of file AlgSubShowerSRList.cxx.

References CandRecoHandle::GetBegPlane(), CandRecoHandle::GetCandSlice(), CandStripHandle::GetCharge(), CandSubShowerSRHandle::GetClusterID(), CandHandle::GetDaughterIterator(), CandRecoHandle::GetEndPlane(), CandHandle::GetNDaughters(), CandStripHandle::GetPlane(), CandSubShowerSRHandle::GetPlaneView(), CandStripHandle::GetPlaneView(), CandSubShowerSRHandle::GetSlope(), CandStripHandle::GetTPos(), CandRecoHandle::GetVtxU(), CandRecoHandle::GetVtxV(), CandRecoHandle::GetVtxZ(), CandStripHandle::GetZPos(), and MSG.

Referenced by RunAlg().

02080 {
02081   //Going to check that proto-subshower does not go through an existing subshower  
02082   //if it does, take largest, plane-wise contiguous set of strips
02083 
02084   MSG("SubShowerSR", Msg::kDebug) << "Running TestOverLap()" << endl;
02085 
02086   //if no strips return false. Empty subshower will be caught later.
02087   Int_t totStp = newSubShower->GetLast()+1;  
02088   if(totStp<=1) return false;
02089 
02090   assert(ch.InheritsFrom("CandSubShowerSRListHandle"));
02091   CandSubShowerSRListHandle &csslh = dynamic_cast<CandSubShowerSRListHandle &>(ch);
02092   //if this is the first subshower, just return false:
02093   if(csslh.GetNDaughters()==0) return false;
02094 
02095   //Get plane view:
02096   TObject *firstObj = newSubShower->At(0);
02097   assert(firstObj->InheritsFrom("CandStripHandle"));
02098   CandStripHandle *firstStp = dynamic_cast<CandStripHandle*>(firstObj);
02099   PlaneView::PlaneView_t pv = firstStp->GetPlaneView();
02100   MSG("SubShowerSR", Msg::kDebug) << "PlaneView = " << pv << endl;
02101 
02102   //loop through subshowers in view + energy order
02103   //so that newSubShower is tested against largest subshower first
02104   CandSubShowerSRHandleItr subshowerItr(csslh.GetDaughterIterator());
02105   CandSubShowerSRHandleKeyFunc *engKF = subshowerItr.CreateKeyFunc();
02106   engKF->SetFun(CandSubShowerSRHandle::KeyFromViewEnergy);
02107   subshowerItr.GetSet()->AdoptSortKeyFunc(engKF);
02108   while (CandSubShowerSRHandle *subshower = subshowerItr()) {
02109     if((*subshower->GetCandSlice())!=(*slice)) continue;
02110     if(subshower->GetPlaneView()!=pv) continue;
02111     if(subshower->GetClusterID()==ClusterType::kXTalk ||
02112        subshower->GetClusterID()==ClusterType::kHalo) continue;
02113     //Get vertex and angle of subshower:
02114     Double_t tpos_vtx = 0;
02115     Double_t z_vtx = subshower->GetVtxZ();
02116     if((subshower->GetPlaneView()==PlaneView::kU || 
02117         subshower->GetPlaneView()==PlaneView::kX)) 
02118       tpos_vtx = subshower->GetVtxU();
02119     if((subshower->GetPlaneView()==PlaneView::kV || 
02120         subshower->GetPlaneView()==PlaneView::kY)) {
02121       tpos_vtx = subshower->GetVtxV();
02122     }
02123     Double_t slope = subshower->GetSlope();
02124     Int_t beg_plane = subshower->GetBegPlane();
02125     Int_t end_plane = subshower->GetEndPlane();
02126 
02127     //for calculating asymmetry:
02128     Double_t n_upp = 0;
02129     Double_t n_low = 0;
02130     Double_t ph_upp = 0;
02131     Double_t ph_low = 0;
02132     Double_t n_plane_upp[500] = {0};
02133     Double_t n_plane_low[500] = {0};
02134     Double_t ph_plane_upp[500] = {0};
02135     Double_t ph_plane_low[500] = {0};
02136 
02137     Int_t firstPlane = 500;
02138     Int_t lastPlane = 0;
02139 
02140     //calculate number of strips above and below axis of subshower
02141     for(int i=0;i<totStp;i++){
02142       CandStripHandle *stp = dynamic_cast<CandStripHandle*>(newSubShower->At(i));
02143       if(firstPlane>stp->GetPlane()) firstPlane = stp->GetPlane();
02144       if(lastPlane<stp->GetPlane()) lastPlane = stp->GetPlane();
02145       if(stp->GetTPos() > (slope*(stp->GetZPos()-z_vtx) + tpos_vtx)) {
02146         n_plane_upp[stp->GetPlane()] += 1;
02147         ph_plane_upp[stp->GetPlane()] += stp->GetCharge(CalDigitType::kSigCorr);
02148         if(stp->GetPlane()>=beg_plane && stp->GetPlane()<=end_plane) {
02149           n_upp += 1;
02150           ph_upp += stp->GetCharge(CalDigitType::kSigCorr);
02151         }
02152       }
02153       else {
02154         n_plane_low[stp->GetPlane()] += 1;
02155         ph_plane_low[stp->GetPlane()] += stp->GetCharge(CalDigitType::kSigCorr);
02156         if(stp->GetPlane()>=beg_plane && stp->GetPlane()<=end_plane) {  
02157           n_low += 1;
02158           ph_low += stp->GetCharge(CalDigitType::kSigCorr);
02159         }
02160       }
02161     }
02162 
02163     //if asymmetry < 95% (should be 100%!) in the plane 
02164     //range of the current subshower then only keep the 
02165     //larger part of the new subshower:
02166     Double_t asymmetry = 1;
02167     Double_t asymmetryPH = 1;
02168     if( n_upp + n_low > 1 ) asymmetry = TMath::Abs(n_upp-n_low)/(n_upp+n_low);
02169     if( ph_upp + ph_low > 1 ) asymmetryPH = TMath::Abs(ph_upp-ph_low)/(ph_upp+ph_low);
02170     MSG("SubShowerSR", Msg::kDebug) << "Asymmetry = " << asymmetry
02171                                     << " AsymmetryPH = " << asymmetryPH
02172                                     << " TotStp = " << totStp
02173                                     << " n_upp = " << n_upp
02174                                     << " n_low = " << n_low
02175                                     << " ph_upp = " << ph_upp
02176                                     << " ph_low = " << ph_low
02177                                     << endl;
02178     if(asymmetry < 0.95) {
02179       //we know now that this proto-subshower is cutting through another subshower
02180       //find the greatest number of contiguous planes above or below slope
02181       //and take those strips only
02182 
02183       Int_t bestAsymFirstPlane = firstPlane;
02184       Int_t bestAsymLastPlane = firstPlane;
02185       Int_t AsymFirstPlane = firstPlane;
02186       Int_t currentSense = 0;
02187       Int_t bestSense = 0;
02188 
02189       //loop through all planes and find longest segments
02190       for(int i=firstPlane;i<=lastPlane;i+=2){
02191         //find longest set of contiguous planes with same asym sign:
02192         if(n_plane_upp[i]>n_plane_low[i] || 
02193            ( n_plane_upp[i]==n_plane_low[i] && 
02194              ph_plane_upp[i]>ph_plane_low[i]) ) {
02195           if(currentSense==0) {
02196             AsymFirstPlane = i;
02197             currentSense = 1;
02198           }
02199           else if(currentSense>0) currentSense += 1;
02200           else if(currentSense<0) { //sense has changed:
02201             if(TMath::Abs(currentSense)>TMath::Abs(bestSense)){
02202               bestSense = currentSense;
02203               bestAsymFirstPlane = AsymFirstPlane;
02204               bestAsymLastPlane = i-1;
02205             }
02206             currentSense = 1;
02207             AsymFirstPlane = i;
02208           }
02209         }
02210         else if(n_plane_low[i]>n_plane_upp[i] || 
02211                 ( n_plane_upp[i]==n_plane_low[i] && 
02212                   ph_plane_low[i]>ph_plane_upp[i]) ){
02213           if(currentSense==0) {
02214             AsymFirstPlane = i;
02215             currentSense = -1;
02216           }
02217           else if(currentSense<0) currentSense -= 1;
02218           else if(currentSense>0) {
02219             if(TMath::Abs(currentSense)>TMath::Abs(bestSense)){
02220               bestSense = currentSense;
02221               bestAsymFirstPlane = AsymFirstPlane;
02222               bestAsymLastPlane = i-1;
02223             }
02224             currentSense = -1;
02225             AsymFirstPlane = i;
02226           }
02227         }
02228       }
02229 
02230       if(TMath::Abs(currentSense)>TMath::Abs(bestSense)){
02231         bestSense = currentSense;
02232         bestAsymFirstPlane = AsymFirstPlane;
02233         bestAsymLastPlane = lastPlane;
02234       }
02235 
02236       for(int i=0;i<totStp;i++){
02237         CandStripHandle *stp = dynamic_cast<CandStripHandle*>(newSubShower->At(i));
02238         if(stp->GetPlane()<bestAsymFirstPlane || stp->GetPlane()>bestAsymLastPlane){
02239           newSubShower->RemoveAt(i);
02240         }
02241       }
02242       newSubShower->Compress();
02243       if(newSubShower->GetLast()+1<totStp) {
02244         return true;
02245       }
02246     }
02247   }
02248   return false;
02249 }

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

Reimplemented from AlgBase.

Definition at line 3403 of file AlgSubShowerSRList.cxx.

03404 {
03405 }

std::vector< window > AlgSubShowerSRList::TransCluster std::vector< window ,
Int_t 
[private]
 

Definition at line 1053 of file AlgSubShowerSRList.cxx.

References BestHough(), window::centroid, HoughTransCluster(), window::lower, window::lower_tpos, MSG, window::ph, window::phpos, window::phwidth, window::plane, window::type, window::upper, window::upper_tpos, and win.

Referenced by FindCluster().

01055 {
01056   std::vector<window> cluster;
01057 
01058   Int_t maxPlane = -1;  //calculate maxPlane
01059   Double_t maxPlanePH = 0;
01060   Double_t PlanePH[500] = {0};
01061   std::vector<window>::iterator winIter = win.begin();
01062   std::vector<window>::iterator winEnd = win.end();
01063   while(winIter!=winEnd){
01064     PlanePH[winIter->plane] += winIter->ph;
01065     if(PlanePH[winIter->plane]>maxPlanePH) {
01066       maxPlane = winIter->plane;
01067       maxPlanePH = PlanePH[maxPlane];
01068     }
01069     winIter++;
01070   }
01071 
01072   Int_t maxLongPlane = -1;
01073   Int_t minLongPlane = -1;
01074   Int_t counter = 0;
01075   Int_t delta = 2;
01076   while(PlanePH[maxPlane+counter]>0||(maxPlane+counter)==249) {
01077     maxLongPlane = maxPlane+counter;
01078     delta = 2;
01079     if(det==1&&(maxLongPlane-249)*(maxLongPlane+delta-249)<0)
01080       delta = 3;
01081     counter+=delta;
01082   }
01083   counter = 0;
01084   while(PlanePH[maxPlane+counter]<=0||(maxPlane+counter)==249) {
01085     minLongPlane = maxPlane+counter;
01086     delta = 2;
01087     if(det==1&&(minLongPlane-249)*(minLongPlane-delta-249)<0)
01088       delta = 3;
01089     counter-=delta;
01090   }
01091   Int_t numPreMaxPlanes = maxPlane-minLongPlane+1;
01092   Int_t numPostMaxPlanes = maxLongPlane-maxPlane+1;
01093   Int_t numLongPlanes = numPostMaxPlanes + numPreMaxPlanes - 1;
01094 
01095   //match up windows plane by plane
01096   Double_t shwmid = 0;    // centroid of cluster transversely
01097   Double_t shwwid = 0;    // trans width of widest window in proto-cluster
01098   Double_t maxwid = 0;
01099   Double_t clusterph = 0; // total PH of cluster
01100   Double_t refp = 0;      // reference plane  }  essentially pivot point for 
01101   Double_t refs = 0;      // reference strip  }  cluster
01102   
01103   //long. window info:
01104   Int_t *winpl = new Int_t[numLongPlanes];           // plane number
01105   Int_t *winpl0 = new Int_t[numLongPlanes];          // upper bound
01106   Int_t *winpl1 = new Int_t[numLongPlanes];          // lower bound
01107   Float_t *winpl0_tpos = new Float_t[numLongPlanes]; // upper bound in tpos
01108   Float_t *winpl1_tpos = new Float_t[numLongPlanes]; // lower bound in tpos
01109   Double_t *winpl2 = new Double_t[numLongPlanes];    // PH
01110   Int_t *winpl3 = new Int_t[numLongPlanes];          // window type
01111   Double_t *winpl4 = new Double_t[numLongPlanes];    // width
01112   Double_t *winpl5 = new Double_t[numLongPlanes];    // centroid
01113   
01114   Double_t slopen = 0;
01115   Double_t eslopen = 0;
01116   Bool_t trustslopen = false;
01117 
01118   std::vector<window> houghcluster = HoughTransCluster(win,det);
01119 
01120   if(houghcluster.size()==0) { //houghcluster.size()=0 try usual tracking
01121     
01122     for (int d = 0;d<numLongPlanes;d++){
01123       int pl = -1;
01124       if(numPreMaxPlanes>numPostMaxPlanes){
01125         if (d<numPreMaxPlanes) pl = maxPlane-d;
01126         else pl = maxPlane+d-numPreMaxPlanes+1;
01127       }
01128       else{
01129         if (d<numPostMaxPlanes) pl = maxPlane+d;
01130         else pl = maxPlane-d+numPostMaxPlanes-1;
01131       }
01132       winpl[d] = 0;
01133       winpl0[d] = -1;
01134       winpl1[d] = -1;
01135       winpl0_tpos[d] = -10;
01136       winpl1_tpos[d] = -10;
01137       winpl2[d] = 0;
01138       winpl3[d] = 0;
01139       winpl4[d] = -1;
01140       winpl5[d] = -1;
01141       // PH for current best matched window:
01142       double weight = 0.;
01143       //deviation of best matched window from prediction of 
01144       //centroid for this plane:
01145       double weight1 = 10000.;
01146       //loop keeps track of # windows already checked on this plane:
01147       int loop = 0;
01148       // counts number of windows with a good match:
01149       int within = 0;
01150       //prediction of centroid for this plane (not using slope in info):
01151       double mid0 = 0;
01152       //prediction of centroid for this plane using slope info where available:
01153       double mid = 0;
01154       
01155       //loop over all in windows
01156       winIter = win.begin();
01157       while (winIter!=winEnd){
01158         if (winIter->plane==pl){  //if it's in current plane:
01159           loop++;
01160           double dev = shwwid;
01161           if (dev<(winIter->upper_tpos-winIter->lower_tpos+STRIPWIDTHINMETRES))
01162             dev = winIter->upper_tpos-winIter->lower_tpos+STRIPWIDTHINMETRES;
01163           if (dev<2.*STRIPWIDTHINMETRES) dev = 2.*STRIPWIDTHINMETRES;
01164           if (shwmid!=0) {
01165             mid0 = shwmid;
01166             mid = shwmid;
01167           }
01168           else {
01169             mid = (winIter->upper+winIter->lower)/2.;
01170             mid0 = mid;
01171           }
01172           
01173           // check if this window is consistent with previously selected 
01174           // windows and has a higher PH than current best match for this
01175           // plane or else if it's shower max plane
01176           if((shwmid==0 ||
01177               (TMath::Abs(winIter->upper_tpos-mid)<dev &&
01178                TMath::Abs(winIter->lower_tpos-mid)<dev))
01179              && winIter->ph>weight){
01180             
01182             //loop through planes in long. window again to do a local 
01183             //scan to ensure best match is found.
01184             //step forward and backward once each if possible
01185           
01186             int loopp = 0;
01187             int loopm = 0;
01188             int withinp = 0;
01189             int withinm = 0;
01190             //double midp0 = 0;
01191             //double midm0 = 0;
01192             double midp = 0;
01193             double midm = 0;
01194             
01195             // step forward:
01196             std::vector<window>::iterator winIter1 = win.begin();
01197             while(winIter1!=winEnd){
01198               if ((((det==1&&(pl-249)*(pl+2-249)>0)||det==0)
01199                    &&winIter1->plane==pl+2)
01200                   ||(det==1&&(pl-249)*(pl+2-249)<0
01201                      &&winIter1->plane==pl+3)){   //go to next same view plane
01202                 loopp++;
01203                 if(shwmid!=0){  //not shower max plane
01204                   midp = shwmid;
01205                   if(TMath::Abs(winIter1->upper_tpos-midp)<dev/2.
01206                      ||TMath::Abs(winIter1->lower_tpos-midp)<dev/2.){  //good match
01207                     withinp++;
01208                   }
01209                 }
01210                 else if(shwmid==0){  //in shower max plane
01211                   midp = (winIter->upper_tpos+winIter->lower_tpos)/2.;
01212                   if(TMath::Abs(winIter1->upper_tpos-midp)<dev/2.
01213                      ||TMath::Abs(winIter1->lower_tpos-midp)<dev/2.){  //good match
01214                     withinp++;  
01215                   }
01216                 }
01217               }
01218               
01219               //step backwards:
01220               if ((((det==1&&(pl-249)*(pl-2-249)>0)||det==0)
01221                    &&winIter1->plane==pl-2)
01222                   ||(det==1&&(pl-249)*(pl-2-249)<0
01223                      &&winIter1->plane==pl-3)){   
01224                 //go to previous same view plane                
01225                 loopm++;
01226                 if(shwmid!=0){   // not shower max plane
01227                   midm = shwmid;
01228                   if(TMath::Abs(winIter1->upper_tpos-midm)<dev
01229                      ||TMath::Abs(winIter1->lower_tpos-midm)<dev){  //good match
01230                     withinm++;
01231                   }
01232                 }
01233                 else if(shwmid==0){  //shower max plane
01234                   midm = (winIter->upper_tpos+winIter->lower_tpos)/2.;
01235                   if(TMath::Abs(winIter1->upper_tpos-midm)<dev
01236                      ||TMath::Abs(winIter1->lower_tpos-midm)<dev){  //good match
01237                     withinm++;
01238                   }
01239                 }
01240               }
01241               winIter1++;
01242             }
01243             if((withinp>0 && withinm>0) || (loopp==0 && withinm>0) ||
01244                (loopm==0 && withinp>0)){  
01245               //success! current window is a good solution
01246               within++;
01247               // write out solution: 
01248               winpl[d] = winIter->plane;
01249               winpl0[d] = winIter->upper;
01250               winpl1[d] = winIter->lower;
01251               winpl0_tpos[d] = winIter->upper_tpos;
01252               winpl1_tpos[d] = winIter->lower_tpos;
01253               winpl2[d] = winIter->ph;
01254               winpl3[d] = winIter->type;
01255               weight = winIter->ph;
01256               weight1 = (winIter->upper_tpos+winIter->lower_tpos)/2.-mid0;
01257               //these will be overwritten if there is another window 
01258               //which is also a good match, but has more PH, 
01259               //ensuring we get best possible match
01260             }
01261           }
01262         }
01263         winIter++;
01264       }
01265       
01266       if(loop*within>0){   //got a matched window
01267         if (shwmid==0) {   // shower max plane
01268           refp = winpl[d];  // set reference point
01269           refs = (winpl0_tpos[d]+winpl1_tpos[d])/2.;
01270         }
01271         //determine widest window:
01272         if(shwwid<(winpl0_tpos[d]-winpl1_tpos[d]+STRIPWIDTHINMETRES)) 
01273           shwwid = winpl0_tpos[d]-winpl1_tpos[d]+STRIPWIDTHINMETRES; 
01274         // average centroid of event so far:
01275         shwmid = (shwmid*clusterph+(winpl0_tpos[d]+winpl1_tpos[d]) * 
01276                   winpl2[d]/2.)/(clusterph+winpl2[d]); 
01277         clusterph+=winpl2[d];
01278         winpl4[d] = shwwid;
01279         winpl5[d] = shwmid;
01280       }
01281     }
01282   
01283     //Fitting the boundaries of windows matched
01284     Double_t slopetn = 0;
01285     Double_t slopebn = 0;
01286     Double_t eslopetn = 0;
01287     Double_t eslopebn = 0;
01288     Double_t chi2tn = 0;
01289     Double_t chi2bn = 0;
01290     int nt = 0;
01291     int nb = 0;
01292 
01293     for (int d = 0;d<numLongPlanes;d++){
01294       int pl = -1;
01295       if(numPreMaxPlanes>numPostMaxPlanes){
01296         if (d<numPreMaxPlanes) pl = maxPlane-d;
01297         else pl = maxPlane+d-numPreMaxPlanes+1;
01298       }
01299       else{
01300         if (d<numPostMaxPlanes) pl = maxPlane+d;
01301         else pl = maxPlane-d+numPostMaxPlanes-1;
01302       }
01303       if(winpl2[d]>0) {nt++; nb++;}
01304       if (maxwid<winpl4[d]) maxwid = winpl4[d];
01305       if (maxwid<2.*STRIPWIDTHINMETRES) maxwid = 2.*STRIPWIDTHINMETRES;
01306     }
01307     if (nt>2&&nb>2) {
01308       TGraphErrors *grat = new TGraphErrors(nt);
01309       TGraphErrors *grab = new TGraphErrors(nb);
01310       int t = 0;
01311       int b = 0;
01312       for (int d = 0;d<numLongPlanes;d++){
01313         int pl = -1;
01314         if(numPreMaxPlanes>numPostMaxPlanes){
01315           if (d<numPreMaxPlanes) pl = maxPlane-d;
01316           else pl = maxPlane+d-numPreMaxPlanes+1;
01317         }
01318         else{
01319           if (d<numPostMaxPlanes) pl = maxPlane+d;
01320           else pl = maxPlane-d+numPostMaxPlanes-1;
01321         }
01322         if(winpl2[d]>0) {
01323           grat->SetPoint(t,winpl[d],winpl0_tpos[d]);
01324           grat->SetPointError(t,0,1./TMath::Sqrt(winpl2[d]));
01325           t++;
01326           grab->SetPoint(b,winpl[d],winpl1_tpos[d]);
01327           grab->SetPointError(b,0,1./TMath::Sqrt(winpl2[d]));
01328           b++;
01329         }
01330       }
01331       
01332       TF1 *p1 = new TF1("p1","pol1",0,500);
01333       grat->Fit("p1","NNLQ");
01334       slopetn = p1->GetParameter(1);
01335       eslopetn = p1->GetParError(1);
01336       chi2tn = p1->GetChisquare();
01337       grab->Fit("p1","NNLQ");
01338       slopebn = p1->GetParameter(1);
01339       eslopebn = p1->GetParError(1);
01340       chi2bn = p1->GetChisquare();
01341       delete grat;
01342       delete grab;
01343       delete p1;
01344       
01345       if ((slopetn+slopebn)!=0. && slopetn*slopebn!=0.){
01346         if(chi2tn/nt<100. && chi2bn/nb<100. &&
01347            ((((eslopetn/TMath::Abs(slopetn)<0.1 && eslopebn/TMath::Abs(slopebn)<0.1
01348                &&chi2tn/nt>0.1 && chi2bn/nb>0.1)) &&
01349              (TMath::Abs(slopetn-slopebn)/TMath::Abs(slopetn+slopebn)<0.25)) ||
01350             TMath::Abs(slopetn-slopebn)==0)) {
01351           slopen = (slopetn+slopebn)/2.;
01352           eslopen = TMath::Sqrt(TMath::Power(eslopetn,2)+TMath::Power(eslopebn,2))/2.;
01353           if(TMath::Abs(slopetn-slopebn)>eslopen) eslopen = TMath::Abs(slopetn-slopebn);
01354           trustslopen = true;
01355         }
01356       }
01357       MSG("SubShowerSR",Msg::kDebug) <<"fit window "<<slopetn<<" "<<slopebn
01358                                      <<" "<<slopen<<" "<<eslopetn<<" "
01359                                      <<eslopebn<<" "<<eslopen<<" "
01360                                      <<chi2tn/nt<<" "<<chi2bn/nb<<" "
01361                                      <<nt<<" "<<nb<<endl;
01362     }
01363     
01364     //check if solution is good:
01365     double usewid = maxwid;
01366     for (Int_t d = 0;d<numLongPlanes;d++){
01367       int pl = -1;
01368       if(numPreMaxPlanes>numPostMaxPlanes){
01369         if (d<numPreMaxPlanes) pl = maxPlane-d;
01370         else pl = maxPlane+d-numPreMaxPlanes+1;
01371       }
01372       else{
01373         if (d<numPostMaxPlanes) pl = maxPlane+d;
01374         else pl = maxPlane-d+numPostMaxPlanes-1;
01375       }
01376     
01377       if(d>0 && (winpl0[d]>=0||winpl1[d]>=0) ){ //if there is a solution
01378         if(!trustslopen && //don't trust new slope
01379            //window is too far away from centroid
01380            (winpl0_tpos[d]-shwmid)*(winpl1_tpos[d]-shwmid) > 
01381            (maxwid/2.)*(maxwid/2.) ){ 
01382           MSG("SubShowerSR",Msg::kDebug) << "removed plane " << winpl[d] 
01383                                          << " " << winpl0[d] << " " 
01384                                          << winpl1[d] << " " 
01385                                          << winpl0_tpos[d] << " " 
01386                                          << winpl1_tpos[d] << endl;
01387           shwmid = (shwmid*clusterph-(winpl0_tpos[d]+winpl1_tpos[d]) * 
01388                     winpl2[d]/2.)/(clusterph-winpl2[d]);
01389           winpl0[d] = -1;
01390           winpl1[d] = -1;
01391           winpl0_tpos[d] = -10;
01392           winpl1_tpos[d] = -10;
01393           winpl2[d] = 0;
01394           winpl3[d] = 0;
01395           winpl4[d] = -1;
01396           winpl5[d] = -1;
01397         }
01398         else if(trustslopen){ 
01399           //this time account for slope on window boundaries:
01400           //try to find another window as a reference point       
01401           //to compare the window in this plane with
01402           int i = 0;  
01403           while(winpl2[i]==0&&i<=d) i++;
01404           if(i==d){
01405             while(winpl2[i]==0&&i<numLongPlanes) i++;
01406           }
01407           if(usewid<TMath::Abs(winpl[d]-winpl[i])*eslopen)  
01408             //find appropriate cut value on window width
01409             usewid = TMath::Abs(winpl[d]-winpl[i])*eslopen; 
01410           //expected centroid for plane:
01411           double expmid = (winpl0_tpos[i] + 
01412                            winpl1_tpos[i])/2.+(winpl[d]-winpl[i])*slopen; 
01413           if((winpl0_tpos[d]-expmid)*(winpl1_tpos[d]-expmid) >
01414              (usewid/2.)*(usewid/2.)){ 
01415             MSG("SubShowerSR",Msg::kDebug) <<"removed plane using slope "
01416                                            <<winpl[d]<<" "<<winpl0[d]<<" "
01417                                            <<winpl1[d]<<" with pl "
01418                                            <<maxPlane<<" "<<winpl[i]
01419                                            <<" "<<expmid<<" "<<usewid<<endl;
01420             shwmid = (shwmid*clusterph-(winpl0_tpos[d]+winpl1_tpos[d]) * 
01421                       winpl2[d]/2.)/(clusterph-winpl2[d]);
01422             clusterph-=winpl2[d];
01423             winpl0[d] = -1;
01424             winpl1[d] = -1;
01425             winpl0_tpos[d] = -10;
01426             winpl1_tpos[d] = -10;
01427             winpl2[d] = 0;
01428             winpl3[d] = 0;
01429             winpl4[d] = -1;
01430             winpl5[d] = -1;
01431           }
01432         }
01433       }
01434     }
01435   }
01436   else { //use hough solution as a starting point:
01437     for (int d = 0;d<numLongPlanes;d++){  
01438       int pl = -1;
01439       if(numPreMaxPlanes>numPostMaxPlanes){
01440         if (d<numPreMaxPlanes) pl = maxPlane-d;
01441         else pl = maxPlane+d-numPreMaxPlanes+1;
01442       }
01443       else{
01444         if (d<numPostMaxPlanes) pl = maxPlane+d;
01445         else pl = maxPlane-d+numPostMaxPlanes-1;
01446       }
01447       winpl[d] = 0;
01448       winpl0[d] = -1;
01449       winpl1[d] = -1;
01450       winpl0_tpos[d] = -10;
01451       winpl1_tpos[d] = -10;
01452       winpl2[d] = 0;
01453       winpl3[d] = 0;
01454       winpl4[d] = -1;
01455       winpl5[d] = -1;
01456 
01457       //loop over all in windows
01458       std::vector<window>::iterator hcIter = houghcluster.begin();
01459       std::vector<window>::iterator hcEnd = houghcluster.end();      
01460       while (hcIter!=hcEnd){
01461         if (hcIter->plane==pl){  //if it's in current plane:
01462           winpl[d] = hcIter->plane;
01463           winpl0[d] = hcIter->upper;
01464           winpl1[d] = hcIter->lower;
01465           winpl0_tpos[d] = hcIter->upper_tpos;
01466           winpl1_tpos[d] = hcIter->lower_tpos;
01467           winpl2[d] = hcIter->ph;
01468           winpl3[d] = hcIter->type;
01469                 
01470           if (shwmid==0) {   // shower max plane
01471             refp = winpl[d];  // set reference point
01472             refs = (winpl0_tpos[d]+winpl1_tpos[d])/2.;
01473           }
01474           //determine widest window:
01475           if(shwwid<(winpl0_tpos[d]-winpl1_tpos[d]+STRIPWIDTHINMETRES)) 
01476             shwwid = winpl0_tpos[d]-winpl1_tpos[d]+STRIPWIDTHINMETRES; 
01477           // average centroid of event so far:
01478           shwmid = (shwmid*clusterph+(winpl0_tpos[d]+winpl1_tpos[d]) * 
01479                     winpl2[d]/2.)/(clusterph+winpl2[d]); 
01480           // calculate average distance to centroid:
01481           clusterph += winpl2[d];
01482           winpl4[d] = shwwid;
01483           winpl5[d] = shwmid;
01484           if (maxwid<winpl4[d]) maxwid = winpl4[d];
01485           if (maxwid<2.*STRIPWIDTHINMETRES) maxwid = 2.*STRIPWIDTHINMETRES;
01486         }
01487         hcIter++;
01488       }
01489     }
01490     Double_t *MCV = new Double_t[14];
01491     MCV[0] = 0; MCV[1] = 0; MCV[2] = 0; MCV[3] = 0; MCV[4] = 0;
01492     MCV[5] = 0; MCV[6] = 0; MCV[7] = 0; MCV[8] = 0; MCV[9] = 0;
01493     MCV[10] = 0; MCV[11] = 0; MCV[12] = 0; MCV[13] = 0;
01494     BestHough(houghcluster,MCV,false);
01495     if(MCV[5]!=0){
01496       slopen = MCV[5];
01497       eslopen = MCV[8];
01498       trustslopen = true;
01499     }
01500     else if(MCV[0]!=0){
01501       slopen = MCV[0];
01502       eslopen = MCV[3];
01503       trustslopen = true;
01504     }
01505     else {
01506       slopen = 0;
01507       eslopen = 0;
01508       trustslopen = false;
01509     }
01510     delete [] MCV;
01511   }
01512   
01514   //Try to fill planes with no windows
01515   
01516   //First find centroid and width for +/- 1 planes
01517   
01518   for (Int_t d = 0;d<numLongPlanes;d++){
01519     int pl = -1;
01520     if(numPreMaxPlanes>numPostMaxPlanes){
01521       if (d<numPreMaxPlanes) pl = maxPlane-d;
01522       else pl = maxPlane+d-numPreMaxPlanes+1;
01523     }
01524     else{
01525       if (d<numPostMaxPlanes) pl = maxPlane+d;
01526       else pl = maxPlane-d+numPostMaxPlanes-1;
01527     }
01528     
01529     double minwei = 200.;   //minimum distance to centroid (weight)
01530     double minwei_tpos = 10.;   //minimum distance to centroid (weight)
01531     int newwinpl0 = -1;     //new window upper and lower strip bounds
01532     int newwinpl1 = -1;
01533     Float_t newwinpl0_tpos = -10; //new window upp and low strip tpos bounds
01534     Float_t newwinpl1_tpos = -10;
01535     double newwinpl2 = 0.;
01536     int newwinpl3 = 0;
01537 
01538     if(winpl0[d]==-1&&winpl1[d]==-1){  //does this plane have a solution?
01539       
01540       int p = 0;
01541       int m = 0;
01542       if (det==0||(det==1&&(pl-249)*(pl+2-249)>0)) p = 2;
01543       else p = 3;
01544       if (det==0||(det==1&&(pl-249)*(pl-2-249)>0)) m = 2;
01545       else m = 3;
01546       
01547       double pmid = -1;   //centroid for next plane (plus)
01548       double mmid = -1;   //centroid for prev plane (minus)
01549       double pwid = -1;   //width
01550       double mwid = -1;   
01551       int pwt = -1;      // window type  plus
01552       int mwt = -1;     //               minus
01553       bool useslopep = false; 
01554       bool useslopem = false;
01555       
01556       for (Int_t c = 0;c<numLongPlanes;c++){
01557         if (winpl[c]==pl+p) {
01558           pmid = winpl5[c];
01559           if (trustslopen) useslopep = true;
01560           pwid = winpl4[c];
01561           pwt = winpl3[c];
01562         }
01563         if (winpl[c]==pl-m) {
01564           mmid = winpl5[c];      
01565           if (trustslopen) useslopem = true;
01566           mwid = winpl4[c];
01567           mwt = winpl3[c];
01568         }
01569       }
01570       
01571       //Find compatible windows
01572       
01573       double usewid = maxwid;
01574       if(maxwid>0){
01575         if((mmid==-1&&pmid==-1)||
01576            (!useslopem&&mmid>=0&&TMath::Abs(shwmid-mmid)>maxwid)||
01577            (!useslopep&&pmid>=0&&TMath::Abs(shwmid-pmid)>maxwid)||
01578            (useslopem&&mmid>=0&&
01579               (TMath::Abs(shwmid-mmid-(maxPlane-pl+m)*slopen)>maxwid)||
01580             (TMath::Abs(shwmid-mmid-(maxPlane-pl+m)*slopen) > 
01581              TMath::Abs(maxPlane-pl+m)*eslopen))||
01582            (useslopep&&pmid>=0&&
01583               (TMath::Abs(shwmid-pmid-(maxPlane-pl-p)*slopen)>maxwid)||
01584             (TMath::Abs(shwmid-pmid-(maxPlane-pl-p)*slopen) > 
01585              TMath::Abs(maxPlane-pl-p)*eslopen))){
01586           minwei = 200.;
01587           minwei_tpos = 10.;
01588           newwinpl0 = -1;
01589           newwinpl1 = -1;
01590           newwinpl0_tpos = -10;
01591           newwinpl1_tpos = -10;
01592           newwinpl2 = 0.;
01593           winIter = win.begin();
01594           while(winIter!=winEnd){
01595             if(winIter->plane==pl){
01596               if (//shwmid>=0&&
01597                   ((winIter->upper_tpos-shwmid) * 
01598                    (winIter->lower_tpos-shwmid)<=
01599                    (maxwid/2.)*(maxwid/2.)) && 
01600                   TMath::Abs((winIter->upper_tpos + 
01601                               winIter->lower_tpos)/2.-shwmid)<minwei_tpos){
01602                 minwei = TMath::Abs((winIter->upper_tpos + 
01603                                      winIter->lower_tpos)/2.-shwmid);
01604                 newwinpl0 = winIter->upper;
01605                 newwinpl1 = winIter->lower;
01606                 newwinpl0_tpos = winIter->upper_tpos;
01607                 newwinpl1_tpos = winIter->lower_tpos;
01608                 newwinpl2 = winIter->ph;
01609                 newwinpl3 = winIter->type;
01610               }
01611             }
01612             winIter++;
01613           }
01614         }
01615         else{
01616           minwei = 200.;
01617           minwei_tpos = 10.;
01618           newwinpl0 = -1;
01619           newwinpl1 = -1;
01620           newwinpl0_tpos = -10.;
01621           newwinpl1_tpos = -10.;
01622           newwinpl2 = 0.;
01623           winIter = win.begin();
01624           while(winIter!=winEnd){
01625             if(winIter->plane==pl){
01626               if (!useslopem&&mmid>=0
01627                   &&((winIter->upper_tpos-mmid) * 
01628                      (winIter->lower_tpos-mmid) <=
01629                      (maxwid/2.)*(maxwid/2.)) &&
01630                   TMath::Abs((winIter->upper_tpos + 
01631                               winIter->lower_tpos)/2.-mmid)<minwei_tpos){
01632                 minwei = TMath::Abs((winIter->upper_tpos + 
01633                                      winIter->lower_tpos)/2.-mmid);
01634                 newwinpl0 = winIter->upper;
01635                 newwinpl1 = winIter->lower;
01636                 newwinpl0_tpos = winIter->upper_tpos;
01637                 newwinpl1_tpos = winIter->lower_tpos;
01638                 newwinpl2 = winIter->ph;
01639                 newwinpl3 = winIter->type;
01640               }
01641               else if (!useslopep&&pmid>=0
01642                        &&((winIter->upper_tpos-pmid) * 
01643                           (winIter->lower_tpos-pmid) <= 
01644                           (maxwid/2.)*(maxwid/2.))
01645                        && TMath::Abs((winIter->upper_tpos + 
01646                                       winIter->lower_tpos)/2.-pmid)<minwei){
01647                 minwei = TMath::Abs((winIter->upper_tpos + 
01648                                      winIter->lower_tpos)/2.-pmid);
01649                 newwinpl0 = winIter->upper;
01650                 newwinpl1 = winIter->lower;
01651                 newwinpl0_tpos = winIter->upper_tpos;
01652                 newwinpl1_tpos = winIter->lower_tpos;
01653                 newwinpl2 = winIter->ph;
01654                 newwinpl3 = winIter->type;
01655               }
01656               else if (useslopem&&mmid>=0){
01657                 if(usewid<m*eslopen) usewid = m*eslopen;
01658                 else usewid = maxwid;
01659                 if((winIter->upper_tpos-mmid-m*slopen) * 
01660                    (winIter->lower_tpos-mmid-m*slopen) <= 
01661                    (usewid/2.)*(usewid/2.)
01662                    &&TMath::Abs((winIter->upper_tpos + 
01663                                  winIter->lower_tpos)/2.-mmid-m*slopen)<minwei){
01664                   minwei = TMath::Abs((winIter->upper_tpos + 
01665                                        winIter->lower_tpos)/2.-mmid-m*slopen);
01666                   newwinpl0 = winIter->upper;
01667                   newwinpl1 = winIter->lower;
01668                   newwinpl0_tpos = winIter->upper_tpos;
01669                   newwinpl1_tpos = winIter->lower_tpos;
01670                   newwinpl2 = winIter->ph;
01671                   newwinpl3 = winIter->type;
01672                 }
01673               }
01674               else if (useslopep&&pmid>=0){
01675                 if(usewid<p*eslopen) usewid = p*eslopen;
01676                 else usewid = maxwid; 
01677                 if((winIter->upper_tpos-pmid+p*slopen) * 
01678                    (winIter->lower_tpos-pmid+p*slopen) <= 
01679                    (usewid/2.)*(usewid/2.)
01680                    &&TMath::Abs((winIter->upper_tpos + 
01681                                  winIter->lower_tpos)/2.-pmid+p*slopen)<minwei){
01682                   minwei = TMath::Abs((winIter->upper_tpos + 
01683                                        winIter->lower_tpos)/2.-pmid+p*slopen);
01684                   newwinpl0 = winIter->upper;
01685                   newwinpl1 = winIter->lower;
01686                   newwinpl0_tpos = winIter->upper_tpos;
01687                   newwinpl1_tpos = winIter->lower_tpos;
01688                   newwinpl2 = winIter->ph;
01689                   newwinpl3 = winIter->type;
01690                 }
01691               }
01692             }
01693             winIter++;
01694           }
01695         }
01696       }
01697       if(newwinpl0>=0) {
01698         winpl0[d] = newwinpl0;
01699         winpl1[d] = newwinpl1;
01700         winpl0_tpos[d] = newwinpl0_tpos;
01701         winpl1_tpos[d] = newwinpl1_tpos;
01702         winpl2[d] = newwinpl2;
01703         winpl3[d] = newwinpl3;
01704         shwmid = (shwmid*clusterph + 
01705                   (winpl0_tpos[d]+winpl1_tpos[d]) * 
01706                   winpl2[d]/2.)/(clusterph+winpl2[d]);
01707         clusterph+=winpl2[d];
01708         MSG("SubShowerSR",Msg::kDebug) <<"find missed windows "<<pl
01709                                        <<" "<<newwinpl0<<" "
01710                                        <<newwinpl1<<" "<<minwei<<endl;
01711       }
01712     }
01713     
01714     window winSolution;
01715     winSolution.plane = pl;
01716     winSolution.upper = winpl0[d];
01717     winSolution.lower = winpl1[d];
01718     winSolution.upper_tpos = winpl0_tpos[d];
01719     winSolution.lower_tpos = winpl1_tpos[d];
01720     winSolution.ph = winpl2[d];
01721     winSolution.type = winpl3[d];
01722     winSolution.centroid = 0.;
01723     winSolution.phpos = 0.;
01724     winSolution.phwidth = 0.;
01725     cluster.push_back(winSolution);
01726   }
01727 
01728   delete [] winpl;
01729   delete [] winpl0;
01730   delete [] winpl1;
01731   delete [] winpl0_tpos;
01732   delete [] winpl1_tpos;
01733   delete [] winpl2;
01734   delete [] winpl3;
01735   delete [] winpl4;
01736   delete [] winpl5;
01737   return cluster;
01738 }


Member Data Documentation

Double_t AlgSubShowerSRList::fLongWindowMipCut [private]
 

Definition at line 59 of file AlgSubShowerSRList.h.

Referenced by RunAlg().

Int_t AlgSubShowerSRList::fMaxPlaneGap [private]
 

Definition at line 61 of file AlgSubShowerSRList.h.

Referenced by RunAlg().

Double_t AlgSubShowerSRList::fMergeBestFracBoundary [private]
 

Definition at line 56 of file AlgSubShowerSRList.h.

Referenced by RunAlg().

Double_t AlgSubShowerSRList::fMergeBestFracCross [private]
 

Definition at line 58 of file AlgSubShowerSRList.h.

Referenced by RunAlg().

Double_t AlgSubShowerSRList::fMergeBestFracWithin [private]
 

Definition at line 57 of file AlgSubShowerSRList.h.

Referenced by RunAlg().

Double_t AlgSubShowerSRList::fMergeFracEnergyLimit [private]
 

Definition at line 55 of file AlgSubShowerSRList.h.

Referenced by RunAlg().


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