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

AlgShowerSSList Class Reference

#include <AlgShowerSSList.h>

Inheritance diagram for AlgShowerSSList:

AlgShowerSRList AlgBase List of all members.

Public Member Functions

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

Constructor & Destructor Documentation

AlgShowerSSList::AlgShowerSSList  ) 
 

Definition at line 49 of file AlgShowerSSList.cxx.

00050 {
00051 }

AlgShowerSSList::~AlgShowerSSList  )  [virtual]
 

Definition at line 54 of file AlgShowerSSList.cxx.

00055 {
00056 }


Member Function Documentation

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

We begin with a nested loop over all CandSlices, and over all CandClusters within each CandSlice, generating list of all clusters in the U and V planes. Next, we execute a nested loop over U-view and V-view CandClusters, checking for matching 2D clusters. The following criteria are used: Beginning planes for the two 2D 'long' CandClusters (defined by PlaneScale) must be within DiffViewPlaneMatch., or DiffViewPlaneMatchShort if one or more clusters is short. Beginning times for the two 2D CandClusters must be within DiffViewTimeMatch. The fractional overlap of U and V clusters must exceed DiffViewPlaneCoverage, if both clusters are long. The total pulse heights of the U and V clusters must agree to within DiffViewPulseHeightCut if at least one of the clusters is long. (Note: This should probably be changed to a charge ratio) If a U/V cluster set is found which satisfies these requirements, a second loop over U clusters is performed, searching for alternative U/V pairs involving the original V cluster satisfying the requirements above, but higher in total energy. If no better alternative is found a CandShower is constructed. In this way, a given CandCluster will only be used once, in the shower with the highest total energy.

Reimplemented from AlgShowerSRList.

Definition at line 60 of file AlgShowerSSList.cxx.

References CandHandle::AddDaughterLink(), Registry::Get(), AlgFactory::GetAlgHandle(), CandSubShowerSRHandle::GetAvgDev(), CandRecoHandle::GetBegPlane(), CandContext::GetCandRecord(), CandRecoHandle::GetCandSlice(), CandStripHandle::GetCharge(), CandSubShowerSRHandle::GetClusterID(), CandContext::GetDataIn(), CandHandle::GetDaughterIterator(), CandRecoHandle::GetEndPlane(), CandShowerHandle::GetEnergy(), CandSubShowerSRHandle::GetEnergy(), AlgFactory::GetInstance(), CandSubShowerSRHandle::GetMaxU(), CandSubShowerSRHandle::GetMaxV(), CandSubShowerSRHandle::GetMinU(), CandSubShowerSRHandle::GetMinV(), CandContext::GetMom(), CandSubShowerSRHandle::GetPlaneView(), CandSubShowerSRHandle::GetSlope(), CandStripHandle::GetTPos(), RecMinos::GetVldContext(), CandRecoHandle::GetVtxU(), CandRecoHandle::GetVtxV(), CandShowerSR::MakeCandidate(), MSG, PITCHINMETRES, CandHandle::Print(), and CandRecoHandle::SetCandSlice().

00061 {
00062 
00063   assert(cx.GetDataIn());
00064   if (!(cx.GetDataIn()->InheritsFrom("TObjArray"))) {
00065     return;
00066   }
00067 
00068   const CandSliceListHandle *slicelist = 0;
00069   const CandClusterListHandle *clusterlist = 0;
00070   const CandSubShowerSRListHandle *subshowerlist = 0;
00071   const TObjArray *cxin = dynamic_cast<const TObjArray *>(cx.GetDataIn());
00072   for (Int_t i=0; i<=cxin->GetLast(); i++) {
00073     TObject *tobj = cxin->At(i);
00074     if (tobj->InheritsFrom("CandSliceListHandle")) {
00075       slicelist = dynamic_cast<CandSliceListHandle*>(tobj);
00076     }
00077     if (tobj->InheritsFrom("CandClusterListHandle")) {
00078       clusterlist = dynamic_cast<CandClusterListHandle*>(tobj);
00079     }
00080     if (tobj->InheritsFrom("CandSubShowerSRListHandle")) {
00081       subshowerlist = dynamic_cast<CandSubShowerSRListHandle*>(tobj);
00082     }
00083   }
00084   if (!slicelist || !clusterlist || !subshowerlist) {
00085     MSG("AlgShowerSS",Msg::kError) <<
00086       "CandSliceListHandle, CandClusterListHandle or CandSubShowerSRListHandle missing\n";
00087     return;
00088   }
00089 
00090   CandContext cxx(this,cx.GetMom());
00091 
00092   Double_t MinNonPhysicsEnergy = 0.2; //in GeV
00093   Int_t MaxPlaneGap = 2;
00094   Int_t NPeakFindingBins = 32;
00095   //get config for AlgSubShowerSS
00096   const char *charShowerSSAlgConfig = 0;
00097   ac.Get("ShowerSSAlgConfig",charShowerSSAlgConfig);
00098   ac.Get("MaxPlaneGap",MaxPlaneGap);
00099   ac.Get("NPeakFindingBins",NPeakFindingBins);
00100   ac.Get("MinNonPhysicsEnergy",MinNonPhysicsEnergy);
00101   
00102   //Get singleton instance of AlgFactory
00103   AlgFactory &af = AlgFactory::GetInstance();
00104   AlgHandle ah = af.GetAlgHandle("AlgShowerSS",charShowerSSAlgConfig);
00105 
00106   const CandRecord *candrec = cx.GetCandRecord();
00107   assert(candrec);
00108   const VldContext *vldcptr = candrec->GetVldContext();
00109   assert(vldcptr);
00110   VldContext vldc = *vldcptr;
00111 
00112   UgliGeomHandle ugh(vldc);
00113   
00114   CandSliceHandleItr sliceItr(slicelist->GetDaughterIterator());
00115   Int_t nslice = 0;
00116   Int_t nsubshower = 0;
00117 
00118   while (CandSliceHandle *slice = sliceItr()) { //slice loop
00119 
00120     MSG("AlgShowerSS",Msg::kDebug) << "Slice: " << nslice << endl;
00121 
00122     // Select SubShowers  within this slice
00123     CandSubShowerSRHandleItr subshowerItr(subshowerlist->GetDaughterIterator());
00124 
00125     // iterate over subshowers, and make a shower out of 
00126     // all subshowers in each slice, in contiguous planes
00127     int plane[500] = {0};
00128     int firstPlane = 500;
00129     int lastPlane = 0;
00130     nsubshower = 0;
00131     while (CandSubShowerSRHandle *subshower = subshowerItr()) {
00132       if (*subshower->GetCandSlice()==*slice) { 
00133         MSG("AlgShowerSS",Msg::kDebug) << "SubShower: " << nsubshower 
00134                                        << " in slice " << nslice << endl;
00135         for(int i=subshower->GetBegPlane();i<=subshower->GetEndPlane();i++){
00136           MSG("AlgShowerSS",Msg::kDebug) << "Plane: " << i << endl;
00137           plane[i] = 1;
00138           if(i<firstPlane) firstPlane = i;
00139           if(i>lastPlane) lastPlane = i;
00140         }
00141       }
00142       nsubshower++;
00143     }
00144   
00145     MSG("AlgShowerSS",Msg::kDebug) << "First Plane = " << firstPlane << endl;
00146     MSG("AlgShowerSS",Msg::kDebug) << "Last Plane = " << lastPlane << endl;
00147 
00148     //separate up into plane chunks according to MaxPlaneGap
00149     Int_t nshower = 0;
00150     while(firstPlane<=lastPlane){ //while loop over planes
00151 
00152       Int_t begPlane = 500;
00153       Int_t endPlane = 0;
00154       Int_t nGaps = 0;
00155       
00156       for(int i=firstPlane;i<=lastPlane;i++){
00157         if(plane[i]==0) {
00158           if(begPlane!=500) nGaps+=1;
00159         }
00160         else {
00161           if(begPlane==500) begPlane = i;
00162           endPlane = i;
00163         }
00164         plane[i] = 0;
00165         if(nGaps>MaxPlaneGap) {
00166           MSG("AlgShowerSS",Msg::kDebug) << "begPlane = " << begPlane << endl;
00167           MSG("AlgShowerSS",Msg::kDebug) << "endPlane = " << endPlane << endl;
00168           break;
00169         }
00170       }
00171       firstPlane = endPlane+1;
00172     
00173       //could have multiple showers per plane chunk
00174       //pull out all subshowers in plane chunk and look for TPos peaks:
00175 
00176       //loop through subshower list again and histogram tposvtx
00177       //in order to look for peaks
00178       // (add an extra bin at each end outside of expected range, 
00179       //  in order to be able to detect peaks at (far) detector edges)
00180       TH1F *vtxUHistAll = new TH1F("vtxUHistAll","vtxUHistAll",NPeakFindingBins+2,
00181                                    -4. - 8./Float_t(NPeakFindingBins),
00182                                    +4. + 8./Float_t(NPeakFindingBins)); 
00183       TH1F *vtxVHistAll = new TH1F("vtxVHistAll","vtxVHistAll",NPeakFindingBins+2,
00184                                    -4. - 8./Float_t(NPeakFindingBins),
00185                                    +4. + 8./Float_t(NPeakFindingBins));
00186       TH1F *vtxUHist = new TH1F("vtxUHist","vtxUHist",NPeakFindingBins+2,
00187                                 -4. - 8./Float_t(NPeakFindingBins),
00188                                 +4. + 8./Float_t(NPeakFindingBins));
00189       TH1F *vtxVHist = new TH1F("vtxVHist","vtxVHist",NPeakFindingBins+2,
00190                                 -4. - 8./Float_t(NPeakFindingBins),
00191                                 +4. + 8./Float_t(NPeakFindingBins));
00192       subshowerItr.ResetFirst();
00193       nsubshower = 0;
00194       while (CandSubShowerSRHandle *subshower = subshowerItr()) {
00195         if (*subshower->GetCandSlice()==*slice) {
00196           if(subshower->GetBegPlane()>=begPlane && 
00197              subshower->GetBegPlane()<=endPlane){
00198             if(subshower->GetPlaneView()==PlaneView::kU || 
00199                subshower->GetPlaneView()==PlaneView::kX) {        
00200               Float_t weightedCentre = subshower->GetVtxU() +
00201                 subshower->GetSlope() * PITCHINMETRES * 
00202                 Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00203               if(weightedCentre<-4. || weightedCentre>4.) weightedCentre = subshower->GetVtxU();
00204               MSG("AlgShowerSS",Msg::kDebug) 
00205                 << "Filling vtxUHist with Subshower " << nsubshower 
00206                 << " with vtvU = " << subshower->GetVtxU() 
00207                 << " and energy = " << subshower->GetEnergy()
00208                 << " and slope = " << subshower->GetSlope()
00209                 << " and AvgDev = " << subshower->GetAvgDev()
00210                 << " and weightedCentre = " << weightedCentre 
00211                 << endl;
00212               CandStripHandleItr stripssItr(subshower->GetDaughterIterator());
00213               while (CandStripHandle *stp = stripssItr()) {
00214                 Float_t val = stp->GetCharge(CalDigitType::kSigCorr) - 
00215                   vtxUHistAll->GetBinContent(vtxUHistAll->FindBin(stp->GetTPos()));
00216                 if(val>0) vtxUHistAll->Fill(stp->GetTPos(),val);
00217                 //vtxUHistAll->Fill(weightedCentre);
00218                 if( subshower->GetClusterID()==ClusterType::kEMLike  ||
00219                     subshower->GetClusterID()==ClusterType::kHadLike ||
00220                     subshower->GetClusterID()==ClusterType::kTrkLike){
00221                   val = stp->GetCharge(CalDigitType::kSigCorr) - 
00222                     vtxUHist->GetBinContent(vtxUHist->FindBin(stp->GetTPos()));
00223                   if(val>0) vtxUHist->Fill(stp->GetTPos(),val);
00224                   //vtxUHist->Fill(weightedCentre);
00225                 }
00226               }
00227             }
00228             else if(subshower->GetPlaneView()==PlaneView::kV || 
00229                     subshower->GetPlaneView()==PlaneView::kY){
00230               Float_t weightedCentre = subshower->GetVtxV() +
00231                 subshower->GetSlope() * PITCHINMETRES * 
00232                 Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2;
00233               if(weightedCentre<-4. || weightedCentre>4.) weightedCentre = subshower->GetVtxV();
00234               MSG("AlgShowerSS",Msg::kDebug) 
00235                 << "Filling vtxVHist with Subshower " << nsubshower 
00236                 << " with vtvV = " << subshower->GetVtxV() 
00237                 << " and energy = " << subshower->GetEnergy() 
00238                 << " and slope = " << subshower->GetSlope()
00239                 << " and AvgDev = " << subshower->GetAvgDev()
00240                 << " and weightedCentre = " << weightedCentre 
00241                 << endl;
00242               CandStripHandleItr stripssItr(subshower->GetDaughterIterator());
00243               while (CandStripHandle *stp = stripssItr()) {
00244                 //fill with max charge for this tpos
00245                 Float_t val = stp->GetCharge(CalDigitType::kSigCorr) - 
00246                   vtxVHistAll->GetBinContent(vtxVHistAll->FindBin(stp->GetTPos()));
00247                 if(val>0) vtxVHistAll->Fill(stp->GetTPos(),val);
00248                 //vtxVHistAll->Fill(weightedCentre);
00249                 if( subshower->GetClusterID()==ClusterType::kEMLike  ||
00250                     subshower->GetClusterID()==ClusterType::kHadLike ||
00251                     subshower->GetClusterID()==ClusterType::kTrkLike){
00252                   val = stp->GetCharge(CalDigitType::kSigCorr) - 
00253                     vtxVHist->GetBinContent(vtxVHist->FindBin(stp->GetTPos()));
00254                   if(val>0) vtxVHist->Fill(stp->GetTPos(),val);
00255                   //vtxVHist->Fill(weightedCentre);
00256                 }
00257               }
00258             }
00259           }
00260         }
00261         nsubshower++;
00262       }
00263 
00264       if(false){
00265         TCanvas *can = new TCanvas();
00266         can->Divide(2,2);
00267         can->cd(1);
00268         vtxUHistAll->Draw();
00269         can->cd(2);
00270         vtxVHistAll->Draw();
00271         can->cd(3);
00272         vtxUHist->Draw();
00273         can->cd(4);
00274         vtxVHist->Draw();
00275         char nomus[256];
00276         sprintf(nomus,"peakPlot_slice%i.eps",nslice);
00277         can->Print(nomus);
00278         delete can;
00279       }
00280 
00281       TSpectrum *specUAll = new TSpectrum(10);
00282       specUAll->Search(vtxUHistAll,1);
00283       TSpectrum *specU = new TSpectrum(10);
00284       specU->Search(vtxUHist,1);
00285       TSpectrum *specVAll = new TSpectrum(10);
00286       specVAll->Search(vtxVHistAll,1);
00287       TSpectrum *specV = new TSpectrum(10);
00288       specV->Search(vtxVHist,1);
00289     
00290       Int_t nUPeaksAll = specUAll->GetNPeaks();
00291       Int_t nUPeaks = specU->GetNPeaks();
00292       Float_t *peakUPos = specU->GetPositionX();
00293       Float_t *peakUVal = specU->GetPositionY();
00294       
00295       Int_t nVPeaksAll = specVAll->GetNPeaks();
00296       Int_t nVPeaks = specV->GetNPeaks();
00297       Float_t *peakVPos = specV->GetPositionX();
00298       Float_t *peakVVal = specV->GetPositionY();
00299 
00300       //if no peaks in either view
00301       if(nUPeaksAll==0 || nVPeaksAll==0) {
00302         //can't form a 3D shower in these conditions!
00303         MSG("AlgShowerSS",Msg::kDebug)
00304           << "nUPeaks = " << nUPeaks 
00305           << " nVPeaks = " << nVPeaks 
00306           << " Can't form a 3D shower" << endl;
00307         delete vtxUHist;
00308         delete vtxVHist;
00309         delete specU;
00310         delete specV; 
00311         delete vtxUHistAll;
00312         delete vtxVHistAll;
00313         delete specUAll;
00314         delete specVAll; 
00315         continue;
00316       }
00317 
00318       //one or both views have no good "physics" subshower:
00319       if(nUPeaks==0 || nVPeaks==0){
00320         MSG("AlgShowerSS",Msg::kDebug) << "Have something in both views but "
00321                                        << "nUPeaks = " << nUPeaks 
00322                                        << "and nVPeaks = " << nVPeaks 
00323                                        << endl;
00324         //try to form anyway with whatever's there
00325         if(nUPeaks==0) nUPeaks = 1;
00326         if(nVPeaks==0) nVPeaks = 1;
00327       }
00328       
00329       //Try to form some 3D showers, yeah!
00330       
00331       //have one or more peak => maybe one or 
00332       //more shower in this plane range
00333       //get boundaries that define each shower in each view:
00334       Float_t *peakUPosLow = new Float_t[nUPeaks];
00335       Float_t *peakUPosUpp = new Float_t[nUPeaks];
00336       MSG("AlgShowerSS",Msg::kDebug) << "Number of U Peaks found = "
00337                                      << nUPeaks << " with positions, heights "
00338                                      << "and bounds: "  << endl;
00339       for (int i=0;i<nUPeaks;i++){
00340         if(i==0) peakUPosLow[i] = -4;
00341         else peakUPosLow[i] = peakUPosUpp[i-1];
00342         if(i==nUPeaks-1) peakUPosUpp[i] = 4;
00343         else {
00344           Int_t bin = vtxUHist->GetXaxis()->FindBin(peakUPos[i]);
00345           Int_t bestBin = vtxUHist->GetNbinsX();
00346           Float_t threeBinAve = 1000000; //sigcor!
00347           while(bin<vtxUHist->GetNbinsX() && 
00348                 vtxUHist->GetBinCenter(bin)<peakUPos[i+1]) {
00349             Float_t ave = (vtxUHist->GetBinContent(bin-1) + 
00350                            vtxUHist->GetBinContent(bin) +
00351                            vtxUHist->GetBinContent(bin+1));
00352             if(ave<threeBinAve) {
00353               threeBinAve = ave;
00354               bestBin = bin;
00355             }
00356             bin++;
00357           }
00358           peakUPosUpp[i] = vtxUHist->GetBinCenter(bestBin);
00359         }
00360         MSG("AlgShowerSS",Msg::kDebug) << peakUPos[i] << " " 
00361                                        << peakUVal[i] << " ["
00362                                        << peakUPosLow[i] << "," 
00363                                        << peakUPosUpp[i] << "]" 
00364                                        << endl;
00365       }
00366       
00367       Float_t *peakVPosLow = new Float_t[nVPeaks];
00368       Float_t *peakVPosUpp = new Float_t[nVPeaks];
00369       MSG("AlgShowerSS",Msg::kDebug) << "Number of V Peaks found = "
00370                                      << nVPeaks 
00371                                      << " with positions, heights "
00372                                      << "and bounds: "  << endl;
00373       for (int i=0;i<nVPeaks;i++){
00374         if(i==0) peakVPosLow[i] = -4;
00375         else peakVPosLow[i] = peakVPosUpp[i-1];
00376         if(i==nVPeaks-1) peakVPosUpp[i] = 4;
00377         else {    
00378           Int_t bin = vtxVHist->GetXaxis()->FindBin(peakVPos[i]);
00379           Int_t bestBin = vtxVHist->GetNbinsX();
00380           Float_t threeBinAve = 1000000; //gev!
00381           while(bin<vtxVHist->GetNbinsX() && 
00382                 vtxVHist->GetBinCenter(bin)<peakVPos[i+1]) {
00383             Float_t ave = (vtxVHist->GetBinContent(bin-1) + 
00384                            vtxVHist->GetBinContent(bin) +
00385                            vtxVHist->GetBinContent(bin+1));
00386             if(ave<threeBinAve) {
00387               threeBinAve = ave;
00388               bestBin = bin;
00389             }
00390             bin++;
00391           }
00392           peakVPosUpp[i] = vtxVHist->GetBinCenter(bestBin);
00393         }
00394         MSG("AlgShowerSS",Msg::kDebug) << peakVPos[i] << " " 
00395                                        << peakVVal[i] << " ["
00396                                        << peakVPosLow[i] << "," 
00397                                        << peakVPosUpp[i] << "]" 
00398                                        << endl;
00399       }
00400 
00401       //for matching up U/V views of showers:
00402       Float_t *totUEnergy = new Float_t[nUPeaks];
00403       Float_t *approxVfromTime = new Float_t[nUPeaks];
00404       Float_t *maxPhysU = new Float_t[nUPeaks];
00405       Float_t *minPhysU = new Float_t[nUPeaks];
00406       Int_t *maxPlaneU = new Int_t[nUPeaks];
00407       Int_t *minPlaneU = new Int_t[nUPeaks];
00408       Int_t *nSubShowersU = new Int_t[nUPeaks];
00409       for(int i=0;i<nUPeaks;i++) {
00410         totUEnergy[i] = 0;
00411         approxVfromTime[i] = 0;
00412         maxPhysU[i] = -1;  maxPlaneU[i] = -1;
00413         minPhysU[i] = 999; minPlaneU[i] = -1;
00414         nSubShowersU[i] = 0;
00415       }
00416       Float_t *totVEnergy = new Float_t[nVPeaks];
00417       Float_t *approxUfromTime = new Float_t[nVPeaks];
00418       Float_t *maxPhysV = new Float_t[nVPeaks];
00419       Float_t *minPhysV = new Float_t[nVPeaks];
00420       Int_t *maxPlaneV = new Int_t[nVPeaks];
00421       Int_t *minPlaneV = new Int_t[nVPeaks];
00422       Int_t *nSubShowersV = new Int_t[nVPeaks];
00423       for(int i=0;i<nVPeaks;i++) {
00424         totVEnergy[i] = 0;
00425         approxUfromTime[i] = 0; 
00426         maxPhysV[i] = -1;  maxPlaneV[i] = -1;
00427         minPhysV[i] = 999; minPlaneV[i] = -1;
00428         nSubShowersV[i] = 0;
00429       }
00430 
00431       //loop through subshowerlist and add up energy of showers      
00432       subshowerItr.ResetFirst();
00433       while (CandSubShowerSRHandle *subshower = subshowerItr()) {
00434         if (*subshower->GetCandSlice()==*slice) {
00435           if(subshower->GetBegPlane()>=begPlane && 
00436              subshower->GetEndPlane()<=endPlane) {
00437             if(subshower->GetPlaneView()==PlaneView::kU){
00438               for(int i=0;i<nUPeaks;i++){
00439                 Float_t weightedCentre = subshower->GetVtxU() +
00440                   subshower->GetSlope() * PITCHINMETRES * 
00441                   Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00442                 if(weightedCentre>peakUPosLow[i] &&
00443                    weightedCentre<=peakUPosUpp[i]) {
00444                   totUEnergy[i]+=subshower->GetEnergy();
00445                   if(nUPeaks>1 &&
00446                      subshower->GetClusterID()==ClusterType::kEMLike ||
00447                      subshower->GetClusterID()==ClusterType::kHadLike ||
00448                      subshower->GetClusterID()==ClusterType::kTrkLike){
00449                     approxVfromTime[i]+=subshower->GetVtxV();
00450                     nSubShowersU[i] += 1;
00451                     for(int j=subshower->GetBegPlane();j<=subshower->GetEndPlane();j++){
00452                       Float_t testMinU = subshower->GetMinU(j);
00453                       Float_t testMaxU = subshower->GetMaxU(j);
00454                       if(testMaxU>maxPhysU[i]) {
00455                         maxPhysU[i] = testMaxU;
00456                         maxPlaneU[i] = j;
00457                       }
00458                       if(testMinU<minPhysU[i]) {
00459                         minPhysU[i] = testMinU;
00460                         minPlaneU[i] = j;
00461                       }
00462                     }
00463                   }
00464                 }
00465               }
00466             }
00467             else if(subshower->GetPlaneView()==PlaneView::kV){
00468               for(int i=0;i<nVPeaks;i++){
00469                 Float_t weightedCentre = subshower->GetVtxV() +
00470                   subshower->GetSlope() * PITCHINMETRES * 
00471                   Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00472                 if(weightedCentre>peakVPosLow[i] &&
00473                    weightedCentre<=peakVPosUpp[i]) {
00474                   totVEnergy[i]+=subshower->GetEnergy();
00475                   if(nVPeaks>1 &&
00476                      subshower->GetClusterID()==ClusterType::kEMLike ||
00477                      subshower->GetClusterID()==ClusterType::kHadLike ||
00478                      subshower->GetClusterID()==ClusterType::kTrkLike){
00479                     approxUfromTime[i]+=subshower->GetVtxU();
00480                     nSubShowersV[i] += 1;
00481                     for(int j=subshower->GetBegPlane();j<=subshower->GetEndPlane();j++){
00482                       Float_t testMinV = subshower->GetMinV(j);
00483                       Float_t testMaxV = subshower->GetMaxV(j);
00484                       if(testMaxV>maxPhysV[i]) {
00485                         maxPhysV[i] = testMaxV;
00486                         maxPlaneV[i] = j;
00487                       }
00488                       if(testMinV<minPhysV[i]) {
00489                         minPhysV[i] = testMinV;
00490                         minPlaneV[i] = j;
00491                       }
00492                     }
00493                   }
00494                 }
00495               }
00496             }
00497           }
00498         }
00499       }
00500       
00501       //Test to see if any peaks should be combined:
00502       //Look for adjacent peaks for which min - max "physics" strip difference is ~1
00503       for(int i=0;i<nUPeaks-1;i++){
00504         if(minPlaneU[i+1]==-1 || maxPlaneU[i]==-1 ||
00505            TMath::Abs(minPlaneU[i+1] - maxPlaneU[i]) > 3 ) //within +/- 1 plane in view
00506           continue; 
00507         if(minPhysU[i+1] - maxPhysU[i] < 1.5*STRIPWIDTHINMETRES ) {//combine peaks
00508           //add energy to second peak and
00509           //remove energy from first peak
00510           totUEnergy[i+1] += totUEnergy[i];
00511           totUEnergy[i] = 0;
00512           //add other-view vertex estimate sum
00513           approxVfromTime[i+1] += approxVfromTime[i];
00514           approxVfromTime[i] = 0;
00515           nSubShowersU[i+1] += nSubShowersU[i];
00516           nSubShowersU[i] = 0;
00517           //shift min U of second peak down and
00518           //set min U plane of second peak
00519           minPhysU[i+1] = minPhysU[i];
00520           minPlaneU[i+1] = minPlaneU[i];
00521           //set min/max limits of first peak to be the same
00522           maxPhysU[i] = minPhysU[i];
00523           maxPlaneU[i] = minPlaneU[i];  
00524           //set peak lower limit of second peak to that of first
00525           peakUPosLow[i+1] = peakUPosLow[i];
00526           //set peak lower and upper limit of first peak to be the same
00527           peakUPosUpp[i] = peakUPosLow[i];
00528         }
00529       }
00530       for(int i=0;i<nVPeaks-1;i++){
00531         if(minPlaneV[i+1]==-1 || maxPlaneV[i]==-1 ||
00532            TMath::Abs(minPlaneV[i+1] - maxPlaneV[i]) > 3 ) //within +/- 1 plane in view
00533           continue; 
00534         if(minPhysV[i+1] - maxPhysV[i] < 1.5*STRIPWIDTHINMETRES ) {//combine peaks
00535           //add energy to second peak and
00536           //remove energy from first peak
00537           totVEnergy[i+1] += totVEnergy[i];
00538           totVEnergy[i] = 0;
00539           //add other-view vertex estimate sum
00540           approxUfromTime[i+1] += approxUfromTime[i];
00541           approxUfromTime[i] = 0;
00542           nSubShowersV[i+1] += nSubShowersV[i];
00543           nSubShowersV[i] = 0;
00544           //shift min V of second peak down and
00545           //set min V plane of second peak
00546           minPhysV[i+1] = minPhysV[i];
00547           minPlaneV[i+1] = minPlaneV[i];
00548           //set min/max limits of first peak to be the same
00549           maxPhysV[i] = minPhysV[i];
00550           maxPlaneV[i] = minPlaneV[i];  
00551           //set peak lower limit of second peak to that of first
00552           peakVPosLow[i+1] = peakVPosLow[i];
00553           //set peak lower and upper limit of first peak to be the same
00554           peakVPosUpp[i] = peakVPosLow[i];
00555         }
00556       }
00557 
00558       //get best order for matching subshower groups in U/V
00559       Int_t *bestOrderU = new Int_t[nUPeaks];
00560       Int_t *bestOrderV = new Int_t[nVPeaks];
00561       for(int i=0;i<nUPeaks;i++){
00562         if(totUEnergy[i]>0){
00563           Int_t nbigger = 0;
00564           for(int j=0;j<nUPeaks;j++){
00565             if(totUEnergy[i]<totUEnergy[j]) nbigger+=1;
00566           }
00567           bestOrderU[nbigger] = i;
00568         }
00569         else {                                 // if there is no energy in this "peak"
00570           Int_t nsmaller = 0;                  // put zero peaks in reverse order
00571           for(int j=0;j<i;j++){                // purely to ensure that all indices
00572             if(totUEnergy[j]==0) nsmaller+=1;  // of bestOrderX are filled
00573           }                                    // with legitimate values (prevents
00574           bestOrderU[nUPeaks-1-nsmaller] = i;  // against a rare case seg fault)
00575         }
00576       }
00577       for(int i=0;i<nVPeaks;i++){
00578         if(totVEnergy[i]>0){
00579           Int_t nbigger = 0;
00580           for(int j=0;j<nVPeaks;j++){
00581             if(totVEnergy[i]<totVEnergy[j]) nbigger+=1;
00582           }
00583           bestOrderV[nbigger] = i;
00584         }
00585         else {
00586           Int_t nsmaller = 0;
00587           for(int j=0;j<i;j++){
00588             if(totVEnergy[j]==0) nsmaller+=1;
00589           }
00590           bestOrderV[nVPeaks-1-nsmaller] = i;
00591         }
00592       }
00593 
00594       Int_t nShowers = nUPeaks;
00595       if(nShowers>nVPeaks) nShowers = nVPeaks;
00596 
00597       if(false){ 
00598         //check energy ordering is ok:
00599         for(int i=0;i<nShowers-1;i++){ //loop over showers
00600           Float_t EUi = totUEnergy[bestOrderU[i]];
00601           Float_t EVi = totVEnergy[bestOrderV[i]];
00602           Float_t EUii = totUEnergy[bestOrderU[i+1]];
00603           Float_t EVii = totVEnergy[bestOrderV[i+1]];
00604           if(EUi==0 || EUii==0 || EVi==0 || EVii==0) continue;
00605           //can we swap the order and still get two good energy matches?        
00606           Float_t asym = TMath::Abs(EUi - EVi)/(EUi + EVi) +
00607             TMath::Abs(EUii - EVii)/(EUii + EVii);
00608           Float_t asymSwap = TMath::Abs(EUi - EVii)/(EUi + EVii) + 
00609             TMath::Abs(EUii - EVi)/(EUii + EVi);
00610           //if difference between two asymmetry estimates is <10%
00611           //see if vertex estimate from timing helps
00612           if( TMath::Abs(asym - asymSwap)/asym < 0.1) {
00613             if(nSubShowersU[bestOrderU[i]]==0 || 
00614                nSubShowersV[bestOrderV[i]]==0 ||
00615                nSubShowersU[bestOrderU[i+1]]==0 || 
00616                nSubShowersV[bestOrderV[i+1]]==0) continue;
00617             
00618             approxVfromTime[bestOrderU[i]]   /= nSubShowersU[bestOrderU[i]];
00619             approxUfromTime[bestOrderV[i]]   /= nSubShowersV[bestOrderV[i]];
00620             approxVfromTime[bestOrderU[i+1]] /= nSubShowersU[bestOrderU[i+1]];
00621             approxUfromTime[bestOrderV[i+1]] /= nSubShowersV[bestOrderV[i+1]];
00622             
00623             //sum distance from both showers
00624             Float_t vertexDistance = 
00625               TMath::Sqrt(TMath::Power(approxUfromTime[bestOrderV[i]] - 
00626                                        peakUPos[bestOrderU[i]],2.) +
00627                           TMath::Power(approxVfromTime[bestOrderU[i]] - 
00628                                        peakVPos[bestOrderV[i]],2)) + 
00629               TMath::Sqrt(TMath::Power(approxUfromTime[bestOrderV[i+1]] - 
00630                                        peakUPos[bestOrderU[i+1]],2.) +
00631                           TMath::Power(approxVfromTime[bestOrderU[i+1]] - 
00632                                        peakVPos[bestOrderV[i+1]],2));
00633             Float_t vertexDistanceSwap = 
00634               TMath::Sqrt(TMath::Power(approxUfromTime[bestOrderV[i+1]] - 
00635                                        peakUPos[bestOrderU[i]],2.) +
00636                           TMath::Power(approxVfromTime[bestOrderU[i]] - 
00637                                        peakVPos[bestOrderV[i+1]],2)) +
00638               TMath::Sqrt(TMath::Power(approxUfromTime[bestOrderV[i]] - 
00639                                        peakUPos[bestOrderU[i+1]],2.) +
00640                           TMath::Power(approxVfromTime[bestOrderU[i+1]] - 
00641                                        peakVPos[bestOrderV[i]],2));
00642             
00643             if(vertexDistanceSwap<vertexDistance && 
00644                vertexDistanceSwap<0.5) { //check that best vertex is reasonable
00645               //swap!
00646               //arbitrary choice which view to switch:
00647               Int_t tempIndex = bestOrderU[i];
00648               bestOrderU[i] = bestOrderU[i+1];
00649               bestOrderU[i+1] = tempIndex;
00650               //start checks again so that clusters 
00651               //can propagate if better matches are found
00652               i=0;
00653             }
00654           }
00655         }
00656       }
00657 
00658       //get true number of physics peaks again
00659       //for final test
00660       nUPeaks = specU->GetNPeaks();
00661       nVPeaks = specV->GetNPeaks();
00662 
00663       //loop over number of expected showers:
00664       for(int i=0;i<nShowers;i++){
00665         TObjArray newshower;
00666         Int_t nsubshower = 0;
00667         subshowerItr.ResetFirst();
00668         while (CandSubShowerSRHandle *subshower = subshowerItr()) {
00669           if (*subshower->GetCandSlice()==*slice) {
00670             if(subshower->GetBegPlane()>=begPlane && 
00671                subshower->GetEndPlane()<=endPlane) {
00672               if(subshower->GetPlaneView()==PlaneView::kU){
00673                 Float_t weightedCentre = subshower->GetVtxU() +
00674                   subshower->GetSlope() * PITCHINMETRES * 
00675                   Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00676                 if(weightedCentre>peakUPosLow[bestOrderU[i]] &&
00677                    weightedCentre<=peakUPosUpp[bestOrderU[i]]) {
00678                   newshower.Add(subshower);
00679                   MSG("AlgShowerSS",Msg::kDebug) 
00680                     << "Adding SubShower: " 
00681                     << nsubshower << " in slice " << nslice 
00682                     << " to newshower " << i << endl;
00683                 }
00684               }
00685               if(subshower->GetPlaneView()==PlaneView::kV){
00686                 Float_t weightedCentre = subshower->GetVtxV() +
00687                   subshower->GetSlope() * PITCHINMETRES * 
00688                   Float_t(subshower->GetEndPlane() - subshower->GetBegPlane() + 1)/2.;
00689                 if(weightedCentre>peakVPosLow[bestOrderV[i]] &&
00690                    weightedCentre<=peakVPosUpp[bestOrderV[i]]) {
00691                   newshower.Add(subshower);
00692                   MSG("AlgShowerSS",Msg::kDebug) 
00693                     << "Adding SubShower: " 
00694                     << nsubshower << " in slice " << nslice 
00695                     << " to newshower " << i << endl;
00696                 }
00697               }
00698             }
00699           }
00700           nsubshower+=1;
00701         }
00702 
00703         cxx.SetDataIn(&newshower);
00704         CandShowerSRHandle showerhandle = CandShowerSR::MakeCandidate(ah,cxx);  
00705         if((showerhandle.GetEnergy()>0 && nUPeaks>0 && nVPeaks>0) || 
00706            showerhandle.GetEnergy()>MinNonPhysicsEnergy) {
00707           showerhandle.SetCandSlice(slice);
00708           ch.AddDaughterLink(showerhandle);
00709         }
00710         else {
00711           MSG("AlgShowerSS",Msg::kDebug) << "Shower " << nshower 
00712                                          << " has zero energy."
00713                                          << " - Not adding shower to list."
00714                                          << endl;
00715         }
00716       }
00717 
00718       delete [] peakUPosUpp;
00719       delete [] peakUPosLow;
00720       delete [] peakVPosUpp;
00721       delete [] peakVPosLow;
00722       delete [] totUEnergy;
00723       delete [] totVEnergy;
00724       delete [] approxVfromTime;
00725       delete [] approxUfromTime;
00726       delete [] nSubShowersU;
00727       delete [] nSubShowersV;
00728       delete [] maxPhysU;
00729       delete [] maxPhysV;
00730       delete [] minPhysU;
00731       delete [] minPhysV;
00732       delete [] maxPlaneU;
00733       delete [] maxPlaneV;
00734       delete [] minPlaneU;
00735       delete [] minPlaneV;
00736       delete [] bestOrderU;
00737       delete [] bestOrderV;
00738       delete vtxUHist;
00739       delete vtxVHist;
00740       delete vtxUHistAll;
00741       delete vtxVHistAll;
00742       delete specU;
00743       delete specV; 
00744       delete specUAll;
00745       delete specVAll; 
00746   
00747     }
00748     nslice++;
00749   }
00750 }

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

Reimplemented from AlgShowerSRList.

Definition at line 755 of file AlgShowerSSList.cxx.

00756 {
00757 }


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