13 #include "StRoot/St_base/StMessMgr.h"
16 #include "StEEmcStripClusterFinderTSP.h"
17 #include "StRoot/StEEmcPool/./EEmcTreeContainers/EEmcEnergy.h"
24 StEEmcStripClusterFinderTSP_t::StEEmcStripClusterFinderTSP_t() :
25 mNumSmoothIters( 10 ),
26 mMinStripsPerCluster( 5 ),
29 mSeedAbsThres( 0.0005 ),
30 mSeedRelThres( 0.15 ),
31 mAbsPeakValleyThres( 0.0015 ),
32 mAnomalySupFactor( 0.1 )
40 StEEmcStripClusterFinderTSP_t::~StEEmcStripClusterFinderTSP_t(){
51 if( (UInt_t)(stripArray.nStrips) < mMinStripsPerCluster )
55 for( Double_t *p1 = mStripEnergyArray, *p2 = mSmoothedEnergyArrayA, *p3 = mSmoothedEnergyArrayB; p1 != &mStripEnergyArray[kEEmcNumStrips]; ++p1, ++p2, ++p3 )
56 (*p1) = (*p2) = (*p3) = 0;
59 mSmallestIdx = kEEmcNumStrips;
63 for(
const EEmcElement_t *strip = stripArray.strip; strip != &stripArray.strip[288]; ++strip, ++stripIdx ){
64 if( !strip->fail && strip->energy ){
65 if( mSmallestIdx > stripIdx )
66 mSmallestIdx = stripIdx;
67 if( mLargestIdx < stripIdx )
68 mLargestIdx = stripIdx;
70 mStripEnergyArray[ stripIdx ] = strip->energy;
71 mSmoothedEnergyArrayA[ stripIdx ] = strip->energy;
75 if( mSmallestIdx < mLargestIdx ){
79 TH1::SmoothArray( kEEmcNumStrips, mSmoothedEnergyArrayA, mNumSmoothIters );
82 assert( mSearchMargin > 0 );
83 Int_t iStart = mSmallestIdx - mSearchMargin;
84 Int_t iEnd = mLargestIdx + mSearchMargin;
87 if( iEnd > kEEmcNumStrips-1 )
88 iEnd = kEEmcNumStrips-1;
91 for( Double_t *p0 = &mSmoothedEnergyArrayA[ iStart-1 ], *p1 = &mSmoothedEnergyArrayA[ iStart ], *p2 = &mSmoothedEnergyArrayA[ iStart+1 ], *pB = &mSmoothedEnergyArrayB[ iStart ];
92 p1 != &mSmoothedEnergyArrayA[iEnd]; ++p0, ++p1, ++p2, ++pB ){
94 Double_t sum = ((*p0) + (*p2))*0.5;
95 Double_t upper = sum*(1 + mAnomalySupFactor );
96 Double_t lower = sum*(1 - mAnomalySupFactor );
97 (*pB) = ( (*p1) > upper ? upper : ( (*p1) < lower ? lower : (*p1) ) );
101 for( Int_t idx = mSmallestIdx; idx <= mLargestIdx; ++idx ){
102 cout <<
"bbb " << mSector <<
' ' << (mLayer ?
'v' :
'u' ) <<
' ' << idx <<
' ' << mStripEnergyArray[idx] <<
' ' << mSmoothedEnergyArrayB[idx] << endl;
107 Double_t maxEnergy = *std::max_element( mSmoothedEnergyArrayB, mSmoothedEnergyArrayB+kEEmcNumStrips );
108 Double_t thres = std::max( mSeedAbsThres, mSeedRelThres*maxEnergy );
111 LOG_INFO <<
"Sector " << mSector <<
'/' << mLayer <<
" Max energy strip is " << maxEnergy <<
", thres is " << thres << endm;
121 std::list< Double_t > peakE, valleyE;
122 valleyE.push_back( 0 );
123 Double_t smallestValley = 0;
125 for( Double_t *p1 = &mSmoothedEnergyArrayB[iStart], *p0 = p1-1, *p2 = p1+1; p1 != &mSmoothedEnergyArrayB[iEnd]; ++p0, ++p1, ++p2 ){
126 if( *p1 > thres && *p1 > *p0 && *p1 > *p2 ){
128 valleyE.push_back( smallestValley );
130 if( !seedVec.empty() ){
132 if( peakE.back() - valleyE.back() < mAbsPeakValleyThres ){
140 if( *p1 - valleyE.back() >= mAbsPeakValleyThres ){
141 peakE.push_back( *p1 );
142 seedVec.push_back( std::distance( mSmoothedEnergyArrayB, p1 ) );
147 smallestValley = *p1;
150 if( *p1 < smallestValley && ((*p1 < *p0 && *p1 < *p2) || ( *p1 == 0 && *p0 != 0 )) )
151 smallestValley = *p1;
155 LOG_INFO <<
"Sector " << mSector <<
'/' << mLayer <<
" Found " << seedVec.size() <<
" seeds" << endm;
158 if( !seedVec.empty() ){
159 LOG_INFO <<
"\t\tSeeds are ";
160 for( IntVec_t::iterator iter = seedVec.begin(); iter != seedVec.end(); ++iter ){
161 LOG_INFO << *iter <<
' ';
167 if( !seedVec.empty() ){
170 IntVec_t leftStrip, rightStrip;
171 IntVec_t::iterator iter;
173 for( iter = seedVec.begin(); iter != seedVec.end(); ++iter ){
176 Double_t *p0, *p1, *p2;
179 for( p1 = &mSmoothedEnergyArrayB[*iter], p0 = p1-1; p1 != &mSmoothedEnergyArrayB[iStart] && (*p1) >= (*p0) && (*p1); --p1, --p0 );
180 leftStrip.push_back( std::distance( mSmoothedEnergyArrayB, p1 ) );
183 for( p1 = &mSmoothedEnergyArrayB[*iter], p2 = p1+1; p1 != &mSmoothedEnergyArrayB[iEnd] && (*p1) >= (*p2) && (*p1); ++p1, ++p2 );
184 rightStrip.push_back( std::distance( mSmoothedEnergyArrayB, p1 ) );
187 LOG_INFO <<
"Cluster with seed " << *iter <<
" may span " << leftStrip.back() <<
" to " << rightStrip.back() << endm;
191 IntVec_t stripsPerClus;
192 stripsPerClus.reserve( 50 );
195 Int_t lastIdx = seedVec.size() - 1;
196 for( iter = seedVec.begin(); iter != seedVec.end(); ++iter, ++idx ){
197 stripsPerClus.clear();
200 UInt_t left = leftStrip[idx];
201 if( *iter - left < mMaxDist )
202 left = std::max( (Int_t)(*iter - mMaxDist), (Int_t)( idx > 0 ? rightStrip[ idx-1 ] : 0 ) );
205 UInt_t right = rightStrip[idx];
206 if( right - *iter < mMaxDist )
207 right = std::min( *iter + mMaxDist, (UInt_t)( idx < lastIdx ? leftStrip[ idx+1 ] : kEEmcNumStrips-1 ) );
212 LOG_INFO <<
"Cluster with seed " << *iter <<
" spans " << left <<
" to " << right << endm;
215 Int_t seedIdx = *iter;
217 Double_t energySq = 0;
218 Double_t weightedMean = 0;
219 Double_t weightedVar = 0;
221 for( Double_t *p = &mStripEnergyArray[left]; p != &mStripEnergyArray[right]; ++p, ++idx ){
225 stripsPerClus.push_back( idx );
227 energySq += (*p)*(*p);
228 weightedMean += idx*(*p);
229 weightedVar += idx*(*p)*(*p);
232 if( energy && stripsPerClus.size() >= mMinStripsPerCluster ){
233 weightedMean /= energy;
234 weightedVar /= energy;
235 weightedVar -= weightedMean*weightedMean;
236 weightedVar *= 1/( 1 - energySq/energy/energy);
242 Int_t n = stripsPerClus.size();
244 TArrayS& memArr = clus.getMemberArray();
245 TArrayF& wArr = clus.getWeightArray();
250 Int_t internalSeedIdx = 0;
251 for( Int_t i = 0; i < n; ++i ){
252 Int_t idx = stripsPerClus.back();
253 stripsPerClus.pop_back();
261 clus.setMeanX( weightedMean );
262 clus.setMeanY( weightedVar );
263 clus.setEnergy( mSmoothedEnergyArrayB[ seedIdx ] );
264 clus.setSeedIdx( internalSeedIdx );
270 for( UInt_t i=0; i<clusters.size(); ++i ){
271 LOG_INFO <<
"Final results: event " << getEventNum() <<
" sector/layer " << mSector <<
'/'
272 << (mLayer ?
'v' :
'u') <<
' ' << clusters[i] << endm;
276 for( UInt_t i=0; i<clusters.size(); ++i ){
277 LOG_INFO <<
"TSP final results: event " << getEventNum() <<
" sector/layer " << mSector <<
'/'
278 << (mLayer ?
'v' :
'u') <<
' ' << clusters[i] <<
" sigma " << clusters[i].getMeanY() << endm;
virtual Int_t find(const ESmdLayer_t &stripArray, StSimpleClusterVec_t &cluster)
find some clusters