StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StEEmcStripClusterFinderTSP.cxx
1 
9 #include <TH1.h>
10 #include <assert.h>
11 #include <algorithm>
12 
13 #include "StRoot/St_base/StMessMgr.h"
14 #include "StRoot/St_base/Stypes.h"
15 
16 #include "StEEmcStripClusterFinderTSP.h"
17 #include "StRoot/StEEmcPool/./EEmcTreeContainers/EEmcEnergy.h"
18 
19 //#define DEBUG_CHILD
20 //#define DEBUG
21 //#define DEBUG2
22 //#define DEBUG_INPUT
23 
24 StEEmcStripClusterFinderTSP_t::StEEmcStripClusterFinderTSP_t() :
25  mNumSmoothIters( 10 ),
26  mMinStripsPerCluster( 5 ),
27  mMaxDist( 5 ),
28  mSearchMargin( 3 ),
29  mSeedAbsThres( 0.0005 ),
30  mSeedRelThres( 0.15 ),
31  mAbsPeakValleyThres( 0.0015 ),
32  mAnomalySupFactor( 0.1 )
33 {
34  // initialize a few parent variables
35  mLayer = U_LAYER;
36  mSector = 0;
37  mIsReady = 1;
38 };
39 
40 StEEmcStripClusterFinderTSP_t::~StEEmcStripClusterFinderTSP_t(){
41  // nothing to do
42 };
43 
44 
46 Int_t StEEmcStripClusterFinderTSP_t::find( const ESmdLayer_t& stripArray, StSimpleClusterVec_t& clusters ){
47  clusters.clear();
48  Int_t ierr = kStOk;
49 
50  // skip if not enough strips hit
51  if( (UInt_t)(stripArray.nStrips) < mMinStripsPerCluster )
52  return ierr;
53 
54  // clear array
55  for( Double_t *p1 = mStripEnergyArray, *p2 = mSmoothedEnergyArrayA, *p3 = mSmoothedEnergyArrayB; p1 != &mStripEnergyArray[kEEmcNumStrips]; ++p1, ++p2, ++p3 )
56  (*p1) = (*p2) = (*p3) = 0;
57 
58  // copy
59  mSmallestIdx = kEEmcNumStrips;
60  mLargestIdx = -1;
61 
62  Int_t stripIdx = 0;
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;
69 
70  mStripEnergyArray[ stripIdx ] = strip->energy;
71  mSmoothedEnergyArrayA[ stripIdx ] = strip->energy;
72  };
73  };
74 
75  if( mSmallestIdx < mLargestIdx ){
76  // i.e. there are some strips that do not fail and have non-zero energy
77 
78  // smooth step A
79  TH1::SmoothArray( kEEmcNumStrips, mSmoothedEnergyArrayA, mNumSmoothIters );
80 
81  // only need to look on the part of array where there is nonzero energy
82  assert( mSearchMargin > 0 );
83  Int_t iStart = mSmallestIdx - mSearchMargin; // just a little margin to be safe
84  Int_t iEnd = mLargestIdx + mSearchMargin;
85  if( iStart < 1 )
86  iStart = 1;
87  if( iEnd > kEEmcNumStrips-1 )
88  iEnd = kEEmcNumStrips-1;
89 
90  // smooth step B: remove anomalies and copy to energy array B
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 ){
93 
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) ) );
98  };
99 
100 #ifdef DEBUG_INPUT
101  for( Int_t idx = mSmallestIdx; idx <= mLargestIdx; ++idx ){
102  cout << "bbb " << mSector << ' ' << (mLayer ? 'v' : 'u' ) << ' ' << idx << ' ' << mStripEnergyArray[idx] << ' ' << mSmoothedEnergyArrayB[idx] << endl;
103  };
104 #endif
105 
106  // find largest strip energy and set peek threshold
107  Double_t maxEnergy = *std::max_element( mSmoothedEnergyArrayB, mSmoothedEnergyArrayB+kEEmcNumStrips );
108  Double_t thres = std::max( mSeedAbsThres, mSeedRelThres*maxEnergy );
109 
110 #ifdef DEBUG2
111  LOG_INFO << "Sector " << mSector << '/' << mLayer << " Max energy strip is " << maxEnergy << ", thres is " << thres << endm;
112 #endif
113 
114  // find all the peeks above threshold and save them as seeds
115 
116 
117  // vector of seeds
118  IntVec_t seedVec;
119 
120  // peak and valley energies
121  std::list< Double_t > peakE, valleyE;
122  valleyE.push_back( 0 );
123  Double_t smallestValley = 0;
124 
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 ){
127  // register the last valley
128  valleyE.push_back( smallestValley );
129 
130  if( !seedVec.empty() ){
131  // see if the peak before should still be a seed or not
132  if( peakE.back() - valleyE.back() < mAbsPeakValleyThres ){
133  peakE.pop_back();
134  valleyE.pop_back();
135  seedVec.pop_back();
136  };
137  };
138 
139  // see if this peak should be a seed
140  if( *p1 - valleyE.back() >= mAbsPeakValleyThres ){
141  peakE.push_back( *p1 );
142  seedVec.push_back( std::distance( mSmoothedEnergyArrayB, p1 ) );
143  };
144 
145  // set smallest valley to a value larger than any possible
146  // valley height
147  smallestValley = *p1;
148  };
149 
150  if( *p1 < smallestValley && ((*p1 < *p0 && *p1 < *p2) || ( *p1 == 0 && *p0 != 0 )) )
151  smallestValley = *p1;
152  };
153 
154 #ifdef DEBUG
155  LOG_INFO << "Sector " << mSector << '/' << mLayer << " Found " << seedVec.size() << " seeds" << endm;
156 #endif
157 #ifdef DEBUG2
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 << ' ';
162  };
163  LOG_INFO << endm;
164  };
165 #endif
166 
167  if( !seedVec.empty() ){
168 
169  // for each seed, find the positions where energy deposition starts to increase
170  IntVec_t leftStrip, rightStrip;
171  IntVec_t::iterator iter;
172 
173  for( iter = seedVec.begin(); iter != seedVec.end(); ++iter ){
174  // left side
175 
176  Double_t *p0, *p1, *p2;
177 
178  // left side
179  for( p1 = &mSmoothedEnergyArrayB[*iter], p0 = p1-1; p1 != &mSmoothedEnergyArrayB[iStart] && (*p1) >= (*p0) && (*p1); --p1, --p0 );
180  leftStrip.push_back( std::distance( mSmoothedEnergyArrayB, p1 ) );
181 
182  // right side
183  for( p1 = &mSmoothedEnergyArrayB[*iter], p2 = p1+1; p1 != &mSmoothedEnergyArrayB[iEnd] && (*p1) >= (*p2) && (*p1); ++p1, ++p2 );
184  rightStrip.push_back( std::distance( mSmoothedEnergyArrayB, p1 ) );
185 
186 #ifdef DEBUG2
187  LOG_INFO << "Cluster with seed " << *iter << " may span " << leftStrip.back() << " to " << rightStrip.back() << endm;
188 #endif
189  };
190 
191  IntVec_t stripsPerClus;
192  stripsPerClus.reserve( 50 );
193 
194  Int_t idx = 0;
195  Int_t lastIdx = seedVec.size() - 1;
196  for( iter = seedVec.begin(); iter != seedVec.end(); ++iter, ++idx ){
197  stripsPerClus.clear();
198 
199  // find left position
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 ) ); // comparison must be done with Ints, not UInts, or will fail
203 
204  // find right position
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 ) );
208  // set right to be the one just past the last to include
209  ++right;
210 
211 #ifdef DEBUG2
212  LOG_INFO << "Cluster with seed " << *iter << " spans " << left << " to " << right << endm;
213 #endif
214 
215  Int_t seedIdx = *iter;
216  Double_t energy = 0;
217  Double_t energySq = 0;
218  Double_t weightedMean = 0;
219  Double_t weightedVar = 0;
220  Int_t idx = left;
221  for( Double_t *p = &mStripEnergyArray[left]; p != &mStripEnergyArray[right]; ++p, ++idx ){
222  if( *p ){
223  //cout << "TSP -- clus " << *iter << " strip " << idx << " E " << *p << ' ' << energy << endl;
224 
225  stripsPerClus.push_back( idx );
226  energy += *p;
227  energySq += (*p)*(*p);
228  weightedMean += idx*(*p);
229  weightedVar += idx*(*p)*(*p);
230  };
231  };
232  if( energy && stripsPerClus.size() >= mMinStripsPerCluster ){
233  weightedMean /= energy;
234  weightedVar /= energy;
235  weightedVar -= weightedMean*weightedMean;
236  weightedVar *= 1/( 1 - energySq/energy/energy);
237 
238  // add cluster
239  clusters.push_back( StSimpleCluster_t( ++mLastClusterID ) );
240  StSimpleCluster_t& clus = clusters.back();
241 
242  Int_t n = stripsPerClus.size();
243 
244  TArrayS& memArr = clus.getMemberArray();
245  TArrayF& wArr = clus.getWeightArray();
246 
247  memArr.Set( n );
248  wArr.Set( n );
249 
250  Int_t internalSeedIdx = 0;
251  for( Int_t i = 0; i < n; ++i ){
252  Int_t idx = stripsPerClus.back();
253  stripsPerClus.pop_back();
254  memArr[i] = idx;
255  wArr[i] = 1;
256 
257  if( idx == seedIdx )
258  internalSeedIdx = i;
259  };
260 
261  clus.setMeanX( weightedMean );
262  clus.setMeanY( weightedVar );
263  clus.setEnergy( mSmoothedEnergyArrayB[ seedIdx ] );
264  clus.setSeedIdx( internalSeedIdx );
265  };
266  }; // iterating over seeds
267  }; // have seeds
268  }; // non-zero number of valid strips
269 #ifdef DEBUG
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;
273  };
274 #endif
275 #ifdef DEBUG_CHILD
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;
279  };
280 #endif
281 
282  return ierr;
283 };
284 
286 
287 /*
288  * $Id: StEEmcStripClusterFinderTSP.cxx,v 1.1 2012/11/26 19:05:55 sgliske Exp $
289  * $Log: StEEmcStripClusterFinderTSP.cxx,v $
290  * Revision 1.1 2012/11/26 19:05:55 sgliske
291  * moved from offline/users/sgliske/StRoot/StEEmcPool/StEEmcHitMaker to StRoot/StEEmcPool/StEEmcHitMaker
292  *
293  *
294  */
virtual Int_t find(const ESmdLayer_t &stripArray, StSimpleClusterVec_t &cluster)
find some clusters
Definition: Stypes.h:41