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

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< window > | TransCluster (std::vector< window >, Int_t) |
| std::vector< window > | HoughTransCluster (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 |
|
|
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 }
|
|
|
Definition at line 65 of file AlgSubShowerSRList.cxx. 00066 {
00067 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
||||||||||||||||||||||||||||
|
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 }
|
|
||||||||||||
|
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 }
|
|
||||||||||||||||||||
|
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 }
|
|
||||||||||||||||
|
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 }
|
|
|
Definition at line 3397 of file AlgSubShowerSRList.cxx. 03398 {
03399 return const_cast<CandStripHandle *>(strip)->GetPlane();
03400 }
|
|
||||||||||||||||
|
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 }
|
|
|
Reimplemented from AlgBase. Definition at line 3403 of file AlgSubShowerSRList.cxx. 03404 {
03405 }
|
|
||||||||||||
|
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 }
|
|
|
Definition at line 59 of file AlgSubShowerSRList.h. Referenced by RunAlg(). |
|
|
Definition at line 61 of file AlgSubShowerSRList.h. Referenced by RunAlg(). |
|
|
Definition at line 56 of file AlgSubShowerSRList.h. Referenced by RunAlg(). |
|
|
Definition at line 58 of file AlgSubShowerSRList.h. Referenced by RunAlg(). |
|
|
Definition at line 57 of file AlgSubShowerSRList.h. Referenced by RunAlg(). |
|
|
Definition at line 55 of file AlgSubShowerSRList.h. Referenced by RunAlg(). |
1.3.9.1