From f1b25902d866ec04625b34d6af68a6f1b379815d Mon Sep 17 00:00:00 2001 From: Vardan Tadevosyan <tadevosn@jlab.org> Date: Mon, 19 Jan 2015 11:30:01 +0400 Subject: [PATCH] Improve THcShower class structure and cleanup Clean up THcShower.h and THcShower.cxx. typedef vector<THcShowerHit*> THcShowerHitList by typedef set<THcShowerHit*> THcShowerHitList. Remove inheritance of class THcShowerCluster from THcShowerHitList. Define THcShowerCluster as THcShowerHitList, aka set<THcShowerHit*>. Remove inheritance of class THcShowerClusterList from THcShClusterList, a.k.a. vector<THcShowerCluster*> container. Define THcShowerClusterList as vector<THcShowerCluster*>. Rename THcShowerHitSet by THcShowerHitList. Rename HitList (related to the HMS calorimeter) to HitSet. Add operator< in THcShowerHit class, in order to have THcShowerHitSet objects to be properly sorted. --- examples/PARAM/52949/hcal.param.vt.52949 | 2 +- src/THcShower.cxx | 212 +++++++++++++++--- src/THcShower.h | 272 +++-------------------- 3 files changed, 219 insertions(+), 267 deletions(-) diff --git a/examples/PARAM/52949/hcal.param.vt.52949 b/examples/PARAM/52949/hcal.param.vt.52949 index 8e5f719..3970fb3 100644 --- a/examples/PARAM/52949/hcal.param.vt.52949 +++ b/examples/PARAM/52949/hcal.param.vt.52949 @@ -4,7 +4,7 @@ hcal_slop = 7.5 ;Turn on HMS cal. fiducial volume cut. 0="no cut" ;Default hcal_fv_test=0 -hcal_fv_test = 0 +hcal_fv_test = 1 hcal_pos_cal_const =0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001 0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001,0.001 diff --git a/src/THcShower.cxx b/src/THcShower.cxx index bb89477..3ed60a6 100644 --- a/src/THcShower.cxx +++ b/src/THcShower.cxx @@ -29,6 +29,7 @@ #include <cstdio> #include <cstdlib> #include <iostream> +#include <numeric> using namespace std; @@ -521,7 +522,14 @@ void THcShower::Clear(Option_t* opt) fEtot = 0.; fEtotNorm = 0.; - fClusterList->purge(); + // Purge cluster list + + for (THcShowerClusterListIt i=fClusterList->begin(); i!=fClusterList->end(); + ++i) { + delete *i; + *i = 0; + } + fClusterList->clear(); } @@ -572,12 +580,12 @@ Int_t THcShower::CoarseProcess( TClonesArray& tracks) // // Apply corrections and reconstruct the complete hits. - // Clustering of hits. - // + // Clustering of hits. + // - // Fill list of unclustered hits. + // Fill set of unclustered hits. - THcShowerHitList HitList; + THcShowerHitSet HitSet; for(UInt_t j=0; j < fNLayers; j++) { @@ -606,13 +614,13 @@ Int_t THcShower::CoarseProcess( TClonesArray& tracks) THcShowerHit* hit = new THcShowerHit(i,j,x,z,Edep,Epos,Eneg); - HitList.push_back(hit); + HitSet.insert(hit); //<set> version } } } - fNhits = HitList.size(); + fNhits = HitSet.size(); //Debug output, print out hits before clustering. @@ -620,17 +628,18 @@ Int_t THcShower::CoarseProcess( TClonesArray& tracks) cout << "---------------------------------------------------------------\n"; cout << "Debug output from THcShower::CoarseProcess\n"; cout << " List of unclustered hits. Total hits: " << fNhits << endl; + THcShowerHitIt it = HitSet.begin(); //<set> version for (Int_t i=0; i!=fNhits; i++) { cout << " hit " << i << ": "; - (*(HitList.begin()+i))->show(); + (*(it++))->show(); } } // Create list of clusters and fill it. - fClusterList->ClusterHits(HitList); + ClusterHits(HitSet); - fNclust = (*fClusterList).NbClusters(); //number of clusters + fNclust = (*fClusterList).size(); //number of clusters //Debug output, print out the cluster list. @@ -638,20 +647,23 @@ Int_t THcShower::CoarseProcess( TClonesArray& tracks) cout << " Clustered hits. Number of clusters: " << fNclust << endl; - for (Int_t i=0; i!=fNclust; i++) { + UInt_t i = 0; + for (THcShowerClusterListIt ppcl = (*fClusterList).begin(); + ppcl != (*fClusterList).end(); ppcl++) { - THcShowerCluster* cluster = (*fClusterList).ListedCluster(i); - cout << " Cluster #" << i - <<": E=" << (*cluster).clE() - << " Epr=" << (*cluster).clEpr() - << " X=" << (*cluster).clX() - << " Z=" << (*cluster).clZ() - << " size=" << (*cluster).clSize() + cout << " Cluster #" << i++ + <<": E=" << clE(*ppcl) + << " Epr=" << clEpr(*ppcl) + << " X=" << clX(*ppcl) + << " Z=" << clZ(*ppcl) + << " size=" << (**ppcl).size() << endl; - for (UInt_t j=0; j!=(*cluster).clSize(); j++) { - THcShowerHit* hit = (*cluster).ClusteredHit(j); - cout << " hit #" << j << ": "; (*hit).show(); + Int_t j=0; + for (THcShowerClusterIt pph=(**ppcl).begin(); pph!=(**ppcl).end(); + pph++) { + cout << " hit " << j++ << ": "; + (**pph).show(); } } @@ -664,6 +676,149 @@ Int_t THcShower::CoarseProcess( TClonesArray& tracks) //----------------------------------------------------------------------------- +void THcShower::ClusterHits(THcShowerHitSet& HitSet) { + + // Collect hits from the HitSet into the clusters. The resultant clusters + // of hits are saved in the ClusterList. + + while (HitSet.size() != 0) { + + THcShowerCluster* cluster = new THcShowerCluster; + + THcShowerHitIt it = HitSet.end(); + (*cluster).insert(*(--it)); //Move the last hit from the hit list + HitSet.erase(it); //into the 1st cluster + + bool clustered = true; + + while (clustered) { //Proceed while a hit is clustered + + clustered = false; + + for (THcShowerHitIt i=HitSet.begin(); i!=HitSet.end(); ++i) { + + for (THcShowerClusterIt k=(*cluster).begin(); k!=(*cluster).end(); + k++) { + + if ((**i).isNeighbour(*k)) { + + (*cluster).insert(*i); //If the hit #i is neighbouring a hit + HitSet.erase(i); //in the cluster, then move it + //into the cluster. + clustered = true; + } + + if (clustered) break; + } //k + + if (clustered) break; + } //i + + } //while clustered + + fClusterList->push_back(cluster); //Put the cluster in the cluster list + + } //While hit_list not exhausted + +}; + +//----------------------------------------------------------------------------- + +Double_t addE(Double_t x, THcShowerHit* h) { + return x + h->hitE(); +} + +Double_t addX(Double_t x, THcShowerHit* h) { + return x + h->hitE() * h->hitX(); +} + +Double_t addZ(Double_t x, THcShowerHit* h) { + return x + h->hitE() * h->hitZ(); +} + +Double_t addEpr(Double_t x, THcShowerHit* h) { + return h->hitColumn() == 0 ? x + h->hitE() : x; +} + +Double_t addEpos(Double_t x, THcShowerHit* h) { + return x + h->hitEpos(); +} + +Double_t addEneg(Double_t x, THcShowerHit* h) { + return x + h->hitEneg(); +} + +// X coordinate of center of gravity of cluster, calculated as hit energy +// weighted average. Put X out of the calorimeter (-75 cm), if there is no +// energy deposition in the cluster. +// +Double_t clX(THcShowerCluster* cluster) { + Double_t Etot = accumulate((*cluster).begin(),(*cluster).end(),0.,addE); + return (Etot != 0. ? + accumulate((*cluster).begin(),(*cluster).end(),0.,addX)/Etot : -75.); +} + +// Z coordinate of center of gravity of cluster, calculated as a hit energy +// weighted average. Put Z out of the calorimeter (0 cm), if there is no energy +// deposition in the cluster. +// +Double_t clZ(THcShowerCluster* cluster) { + Double_t Etot = accumulate((*cluster).begin(),(*cluster).end(),0.,addE); + return (Etot != 0. ? + accumulate((*cluster).begin(),(*cluster).end(),0.,addZ)/Etot : 0.); +} + +//Energy depostion in a cluster +// +Double_t clE(THcShowerCluster* cluster) { + return accumulate((*cluster).begin(),(*cluster).end(),0.,addE); +} + +//Energy deposition in the Preshower (1st plane) for a cluster +// +Double_t clEpr(THcShowerCluster* cluster) { + return accumulate((*cluster).begin(),(*cluster).end(),0.,addEpr); +} + + +//Cluster energy deposition in plane iplane=0,..,3: +// side=0 -- from positive PMTs only; +// side=1 -- from negative PMTs only; +// side=2 -- from postive and negative PMTs. +// + +Double_t clEplane(THcShowerCluster* cluster, Int_t iplane, Int_t side) { + + if (side!=0&&side!=1&&side!=2) { + cout << "*** Wrong Side in clEplane:" << side << " ***" << endl; + return -1; + } + + THcShowerHitSet pcluster; + for (THcShowerHitIt it=(*cluster).begin(); it!=(*cluster).end(); ++it) { + if ((*it)->hitColumn() == iplane) pcluster.insert(*it); + } + + Double_t Eplane; + switch (side) { + case 0 : + Eplane = accumulate(pcluster.begin(),pcluster.end(),0.,addEpos); + break; + case 1 : + Eplane = accumulate(pcluster.begin(),pcluster.end(),0.,addEneg); + break; + case 2 : + Eplane = accumulate(pcluster.begin(),pcluster.end(),0.,addE); + break; + default : + Eplane = 0. ; + } + + return Eplane; +} + +//----------------------------------------------------------------------------- + Int_t THcShower::MatchCluster(THaTrack* Track, Double_t& XTrFront, Double_t& YTrFront) { @@ -719,16 +874,14 @@ Int_t THcShower::MatchCluster(THaTrack* Track, if (inFidVol) { - // for (Int_t i=0; i<fNclust; i++) { - // Since hits and clusters are in reverse order (with respect to Engine), // search backwards to be consistent with Engine. // for (Int_t i=fNclust-1; i>-1; i--) { - THcShowerCluster* cluster = (*fClusterList).ListedCluster(i); + THcShowerCluster* cluster = *(fClusterList->begin()+i); - Double_t dx = TMath::Abs( (*cluster).clX() - XTrFront ); + Double_t dx = TMath::Abs( clX(cluster) - XTrFront ); if (dx <= (0.5*BlockThick[0] + fSlop)) { fNtracks++; // number of shower tracks (Consistent with engine) @@ -761,7 +914,7 @@ Int_t THcShower::MatchCluster(THaTrack* Track, cout << " Fiducial volume test: inFidVol = " << inFidVol << endl; cout << " Matched cluster #" << mclust << ", delatX= " << deltaX - << endl; + << endl; cout << "---------------------------------------------------------------\n"; } @@ -789,7 +942,8 @@ Float_t THcShower::GetShEnergy(THaTrack* Track) { if (mclust >= 0) { // if there is a matched cluster // Get matched cluster. - THcShowerCluster* cluster = (*fClusterList).ListedCluster(mclust); + + THcShowerCluster* cluster = *(fClusterList->begin()+mclust); // Correct track energy depositions for the impact coordinate. @@ -809,8 +963,8 @@ Float_t THcShower::GetShEnergy(THaTrack* Track) { corneg = 0.; } - Etrk += (*cluster).clEplane(ip,0) * corpos; - Etrk += (*cluster).clEplane(ip,1) * corneg; + Etrk += clEplane(cluster,ip,0) * corpos; + Etrk += clEplane(cluster,ip,1) * corneg; } //over planes diff --git a/src/THcShower.h b/src/THcShower.h index 0e1880e..e52b424 100644 --- a/src/THcShower.h +++ b/src/THcShower.h @@ -16,7 +16,7 @@ // HMS calorimeter hits, version 2 -#include <vector> +#include <set> #include <iterator> #include <iostream> #include <memory> @@ -86,12 +86,12 @@ public: } // Decide if a hit is neighbouring the current hit. - // Two hits are neighbours if share a side or a corner. + // Two hits are neighbours if share a side or a corner, + // or in the same row but separated by no more than a block. // bool isNeighbour(THcShowerHit* hit1) { //Is hit1 neighbouring this hit? Int_t dRow = fRow-(*hit1).fRow; Int_t dCol = fCol-(*hit1).fCol; - // return TMath::Abs(dRow)<2 && TMath::Abs(dCol)<2; return (TMath::Abs(dRow)<2 && TMath::Abs(dCol)<2) || (dRow==0 && TMath::Abs(dCol)<3); } @@ -104,252 +104,36 @@ public: << " E=" << fE << " Epos=" << fEpos << " Eneg=" << fEneg << endl; } -}; - - -// Container (collection) of hits and its iterator. -// -typedef vector<THcShowerHit*> THcShowerHitList; -typedef THcShowerHitList::iterator THcShowerHitIt; - - - -//HMS calorimeter hit cluster -// -class THcShowerCluster : THcShowerHitList { - - public: - - THcShowerCluster() { - // cout << "Dummy THcShowerCluster object created" << endl; - } - - ~THcShowerCluster() { - for (THcShowerHitIt i = THcShowerHitList::begin(); - i != THcShowerHitList::end(); ++i) { - delete *i; - *i = 0; - } - } - - // Add a hit to the cluster hit list - // - void grow(THcShowerHit* hit) { - THcShowerHitList::push_back(hit); - } - - //Pointer to the hit #i in the cluster hit list - // - THcShowerHit* ClusteredHit(UInt_t i) { - return * (THcShowerHitList::begin()+i); - } - - //Print out a hit in the cluster - // - void showHit(UInt_t num) { - (*(THcShowerHitList::begin()+num))->show(); - } - - // X coordinate of center of gravity of cluster, - // calculated as hit energy weighted average. - // Put X out of the calorimeter (-75 cm), if there is no energy deposition - // in the cluster. + // Define < operator in order to fill in hit sets in a sorted manner. // - Double_t clX() { - Double_t x_sum=0.; - Double_t Etot=0.; - for (THcShowerHitIt it=THcShowerHitList::begin(); - it!=THcShowerHitList::end(); ++it) { - x_sum += (*it)->hitX() * (*it)->hitE(); - Etot += (*it)->hitE(); - } - // cout << "x_sum=" << x_sum << " Etot=" << Etot << endl; - return (Etot != 0. ? x_sum/Etot : -75.); - } - - // Z coordinate of center of gravity of cluster, - // calculated as a hit energy weighted average. - // Put Z out of the calorimeter (0 cm), if there is no energy deposition - // in the cluster. - // - Double_t clZ() { - Double_t z_sum=0.; - Double_t Etot=0.; - for (THcShowerHitIt it=THcShowerHitList::begin(); - it!=THcShowerHitList::end(); ++it) { - z_sum += (*it)->hitZ() * (*it)->hitE(); - Etot += (*it)->hitE(); - } - // cout << "z_sum=" << z_sum << " Etot=" << Etot << endl; - return (Etot != 0. ? z_sum/Etot : 0.); - } - - //Energy depostion in a cluster - // - Double_t clE() { - // cout << "In ECl:" << endl; - Double_t Etot=0.; - for (THcShowerHitIt it=THcShowerHitList::begin(); - it!=THcShowerHitList::end(); ++it) { - Etot += (*it)->hitE(); - } - return Etot; - } - - //Energy deposition in the Preshower (1st plane) for a cluster - // - Double_t clEpr() { - Double_t Epr=0.; - for (THcShowerHitIt it=THcShowerHitList::begin(); - it!=THcShowerHitList::end(); ++it) { - if ((*it)->hitColumn() == 0) { - Epr += (*it)->hitE(); - } - } - return Epr; - } - - //Cluster energy deposition in plane iplane=0,..,3: - // side=0 -- from positive PMTs only; - // side=1 -- from negative PMTs only; - // side=2 -- from postive and negative PMTs. - // - - Double_t clEplane(Int_t iplane, Int_t side) { - - if (side!=0&&side!=1&&side!=2) { - cout << "*** Wrong Side in clEplane:" << side << " ***" << endl; - return -1; - } - - Double_t Eplane=0.; - for (THcShowerHitIt it=THcShowerHitList::begin(); - it!=THcShowerHitList::end(); ++it) { - - if ((*it)->hitColumn() == iplane) - - switch (side) { - case 0 : Eplane += (*it)->hitEpos(); - break; - case 1 : Eplane += (*it)->hitEneg(); - break; - case 2 : Eplane += (*it)->hitE(); - break; - default : ; - } - - } - - return Eplane; - } - - - //Cluster size (number of hits in the cluster). - // - UInt_t clSize() { - return THcShowerHitList::size(); + bool operator<(THcShowerHit rhs) const { + if (fCol != rhs.fCol) + return fCol < rhs.fCol; + else + return fRow < rhs.fRow; } }; -//----------------------------------------------------------------------------- -//Alias for container of clusters and for its iterator -// -typedef vector<THcShowerCluster*> THcShClusterList; -typedef THcShClusterList::iterator THcShClusterIt; +//____________________________________________________________________________ -//List of clusters +// Container (collection) of hits and its iterator. // -class THcShowerClusterList : private THcShClusterList { - - public: - - THcShowerClusterList() { - // cout << "Dummy THcShowerClusterList object created" << endl; - } - - ~THcShowerClusterList() { - purge(); - } +typedef set<THcShowerHit*> THcShowerHitSet; +typedef THcShowerHitSet::iterator THcShowerHitIt; - // Purge cluster list - // - void purge() { - for (THcShClusterIt i = THcShClusterList::begin(); - i != THcShClusterList::end(); ++i) { - delete *i; - *i = 0; - } - THcShClusterList::clear(); - } - - //Put a cluster in the cluster list - // - void grow(THcShowerCluster* cluster) { - THcShClusterList::push_back(cluster); - } - - //Pointer to the cluster #i in the cluster list - // - THcShowerCluster* ListedCluster(UInt_t i) { - return *(THcShClusterList::begin()+i); - } - - //Cluster list size. - // - UInt_t NbClusters() { - return THcShClusterList::size(); - } +typedef THcShowerHitSet THcShowerCluster; +typedef THcShowerCluster::iterator THcShowerClusterIt; - //____________________________________________________________________________ - - void ClusterHits(THcShowerHitList HitList) { - - // Collect hits from the HitList into the clusters. The resultant clusters - // of hits are saved in the ClusterList. - - while (HitList.size() != 0) { - - THcShowerCluster* cluster = new THcShowerCluster; - - (*cluster).grow(*(HitList.end()-1)); //Move the last hit from the hit list - HitList.erase(HitList.end()-1); //into the 1st cluster - bool clustered = true; - - while (clustered) { //Proceed while a hit is clustered - - clustered = false; - - for (THcShowerHitIt i=HitList.begin(); i!=HitList.end(); ++i) { - - for (UInt_t k=0; k!=(*cluster).clSize(); k++) { - - if ((**i).isNeighbour((*cluster).ClusteredHit(k))) { - - (*cluster).grow(*i); //If the hit #i is neighbouring a hit - HitList.erase(i); //in the cluster, then move it - //into the cluster. - clustered = true; - } - - if (clustered) break; - } //k - - if (clustered) break; - } //i - - } //while clustered - - grow(cluster); //Put the cluster in the cluster list - - } //While hit_list not exhausted - - } - -}; +//______________________________________________________________________________ +//Alias for container of clusters and for its iterator +// +typedef vector<THcShowerCluster*> THcShowerClusterList; +typedef THcShowerClusterList::iterator THcShowerClusterListIt; +//______________________________________________________________________________ class THcShower : public THaNonTrackingDetector, public THcHitList { @@ -513,6 +297,8 @@ protected: // Cluster to track association method. Int_t MatchCluster(THaTrack*, Double_t&, Double_t&); + void ClusterHits(THcShowerHitSet& HitSet); + friend class THcShowerPlane; //to access debug flags. ClassDef(THcShower,0) // Shower counter detector @@ -520,4 +306,16 @@ protected: /////////////////////////////////////////////////////////////////////////////// +// Auxiliary methods to be used with the hit and cluster containers. + +Double_t addE(Double_t x, THcShowerHit* h); +Double_t addX(Double_t x, THcShowerHit* h); +Double_t addZ(Double_t x, THcShowerHit* h); +Double_t addEpr(Double_t x, THcShowerHit* h); +Double_t clX(THcShowerCluster* cluster); +Double_t clZ(THcShowerCluster* cluster); +Double_t clE(THcShowerCluster* cluster); +Double_t clEpr(THcShowerCluster* cluster); +Double_t clEplane(THcShowerCluster* cluster, Int_t iplane, Int_t side); + #endif -- GitLab