StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMyClusterMaker.cxx
1 #include "StMyClusterMaker.h"
2 
3 #include "StEEmcPool/StEEmcA2EMaker/StEEmcA2EMaker.h"
4 
5 #include <algorithm>
6 
7 #include "StMuDSTMaker/COMMON/StMuTrack.h"
8 
9 #include "StMcEvent/StMcEvent.hh"
10 #include "StMcEvent/StMcTrack.hh"
11 #include "StMcEvent/StMcVertex.hh"
12 
13 #include "StMessMgr.h"
14 
15 ClassImp(StMyClusterMaker);
16 
17 // ----------------------------------------------------------------------------
18 StMyClusterMaker::StMyClusterMaker(const Char_t *name, const StEEmcA2EMaker *a2e, StMuDstMaker * /*mumk*/ )
20 {
21  mSmdSeedEnergy = 4.0 / 1000.0;
22  mSmdMinEnergy = 0.5 / 1000.0;
23 
24  mMaxExtent = 40;
25  mTruncateRatio = 1.2;
26  mMinStrips = 3;
27 
28  mSeedEnergy[0]=0.8; mMinEnergy[0]=0.1;
29  mSeedEnergy[1]=1.0/1000.0; mMinEnergy[1]=0.1/1000.0;
30  mSeedEnergy[2]=1.0/1000.0; mMinEnergy[2]=0.1/1000.0;
31  mSeedEnergy[3]=1.0/1000.0; mMinEnergy[3]=0.1/1000.0;
32 
33  mEtaCut = 999;
34  mPhiCut = 999;
35 
36  //mMuDst=mumk;
37  // assert(mumk);
38 
39  setDoBreakInflection(0);
40  setDoBreakTruncation(0);
41  setDoBreakSize(0);
42 
43  mUseFloor=false;
44  mFloorParams[0]=0.;mFloorParams[1]=0.;
45 
46 }
47 
48 // ----------------------------------------------------------------------------
50 {
51 
56  Int_t result = StEEmcGenericClusterMaker::Make();
57  return result;
58 
59 }
60 
61 // ----------------------------------------------------------------------------
62 Int_t StMyClusterMaker::buildLayer(Int_t layer )
63 {
64 
65  const Char_t *clayers[]={"T","P","Q","R","U","V"};
66 
67  LOG_DEBUG << " build clusters for layer=" << clayers[layer] << endm;
68 
69  // get list of hit towers
70  StEEmcTowerVec_t hits=mEEanalysis->towers(layer);
71 
72  // sort towers ascending in energy
73  std::sort( hits.begin(), hits.end());
74  // and reverse so it's descending
75  std::reverse( hits.begin(), hits.end());
76 
77  LOG_DEBUG<<"searching for seeds in layer "<<clayers[layer]<<endm;
78 
79  // loop over all hit towers and find seeds
80  StEEmcTowerVec_t seeds;
81  for ( UInt_t i=0;i<hits.size();i++ )
82  {
83 
84  if ( hits[i].fail() ) continue;
85 
86  if ( hits[i].energy() > mSeedEnergy[layer] )
87  seeds.push_back(hits[i]);
88  else
89  break;
90 
91  LOG_DEBUG<<"+ "<<hits[i].name()<<" "<<hits[i].energy()<<endm;
92 
93  }
94 
95  LOG_DEBUG<<"clustering"<<endm;
96 
97  // next we form clusters around seeds. clusters grow to
98  // absorb all continuous energized towers.
99  Bool_t used[720];
100  for ( Int_t i=0;i<720;i++ ) used[i]=false;
101  for ( UInt_t i=0;i<seeds.size();i++ )
102  {
103 
104  const StEEmcTower &tow=seeds[i];
105  if ( tow.fail() ) continue; // bad hardware
106  if ( used[tow.index()] ) continue; // used by another cluster
107 
108  Int_t etabin_seed = tow.etabin();
109  Int_t phibin_seed = tow.phibin();
110 
111  StEEmcCluster c;
112  c.add(tow);
113  used[tow.index()]=true;
114 
115  // loop over all hits. if a given is adjacent to
116  // the cluster and hasn't been used, grab it and
117  // mark it as used.
118 
119  CLUSTERING:
120  Int_t size_old = c.numberOfTowers();
121  for ( UInt_t j=0;j<hits.size();j++ )
122  {
123  const StEEmcTower &tow=hits[j];
124 
125  if ( used[ tow.index() ] ) continue; // next hit
126  if ( tow.fail() ) continue; // bad channel
127 
128  if ( tow.energy() < mMinEnergy[layer] ) break; // rest are not considered hit
129 
130  Int_t deta=TMath::Abs(etabin_seed - tow.etabin());
131  if ( deta > mEtaCut ) continue;
132 
133  Int_t phi1=TMath::Max(phibin_seed,tow.phibin());
134  Int_t phi2=TMath::Min(phibin_seed,tow.phibin());
135  Int_t diff1 = phi1-phi2;
136  Int_t diff2 = phi2-phi1+60;
137  Int_t dphi=TMath::Min(diff1,diff2);
138  if ( dphi > mPhiCut ) continue;
139 
140  if ( c.isNeighbor( tow ) ) {
141  c.add(tow);
142  used[tow.index()]=true;
143  }
144 
145  }
146  if ( c.numberOfTowers() > size_old ) goto CLUSTERING;
147 
148  add(c); // add to the list of clusters
149  LOG_DEBUG<<"+ key="<<c.key()<<" seed="<<c.tower(0).name()<<" energy="<<c.energy()<<endm;
150 
151  }
152 
153  return kStOk;
154 
155 }
156 
157 // ----------------------------------------------------------------------------
159 {
160  buildLayer(0);
161  return kStOK;
162 }
163 
164 // ----------------------------------------------------------------------------
166 {
167  buildLayer(1);
168  buildLayer(2);
169  return kStOK;
170 }
171 
172 // ----------------------------------------------------------------------------
174 {
175  buildLayer(3);
176  return kStOK;
177 }
178 
179 // ----------------------------------------------------------------------------
181 {
182 
183  LOG_DEBUG << " building SMD clusters" << endm;
184 
185  for ( Int_t sector=0;sector<12;sector++ ) {
186 
187  Float_t etmax = 0.;
188  for ( UInt_t ii=0;ii<mTowerClusters[sector][0].size();ii++ )
189  {
190  const StEEmcCluster &c = mTowerClusters[sector][0][ii];
191  if ( c.momentum().Perp() > etmax ) etmax = c.momentum().Perp();
192  }
193 
194 
195  if ( etmax >= 4.5 ) {
196  mSmdSeedEnergy = ( seed_threshold + seed_slope * (etmax-4.5) ) / 1000.0;
198  }
199  else {
200  mSmdSeedEnergy = seed_threshold / 1000.0;
202  }
203 
204  LOG_DEBUG<<GetName()<<" sector="<<sector<<" seed energy="<<mSmdSeedEnergy<<endm;
205 
206  for ( Int_t plane=0;plane<2;plane++ )
207  {
208 
209 
210  // get number of smd strips in this plane
211  Int_t nstrips = (Int_t)mESmdGeom -> getEEmcSector( plane, sector ).stripPtrVec.size();
212 
213  // Array denoting which smd strips are in use
214  Bool_t used[288]; for (Int_t i=0;i<288;i++ ) used[i]=false;
215 
216  // Additional energy cut imposed upon seed strips after identifiying an SMD cluster
217  Float_t floor[288]; for ( Int_t i=0;i<288;i++ ) floor[i]=0.;
218 
219  // Get list of hit smd strips
220  StEEmcStripVec_t strips=mEEanalysis->strips(sector,plane);
221  // Sort by energy
222  std::sort(strips.begin(),strips.end());
223  // Order in descending energy
224  std::reverse(strips.begin(),strips.end());
225 
226 
227  LOG_DEBUG << " sector=" << sector
228  << " plane=" << plane
229  << " nhit strips=" << strips.size()
230  << endm;
231 
232  StEEmcStripVec_t seeds;
233 
234  Float_t emax_strip = 0.;
235  for ( UInt_t i=0;i<strips.size();i++ )
236  {
237 
238  // Get the index of the strip
239  Int_t myindex = strips[i].index();
240 
241  // Bail out if the strip is below seed energy
242  if ( strips[i].energy() < mSmdSeedEnergy ) break;
243 
244  // Skip if near edge of the plane
245  if ( myindex < 4 || myindex > nstrips-4 ) continue;
246 
247  // Skip if fail bit is set
248  if ( strips[i].fail() ) continue;
249 
250  // Require signal in adjacent smd strips
251  const StEEmcStrip *stripL = &mEEanalysis->strip(sector,plane,myindex-1);
252  const StEEmcStrip *stripR = &mEEanalysis->strip(sector,plane,myindex+1);
253  if ( stripL->fail() ) stripL = &mEEanalysis->strip(sector,plane,myindex-2);
254  if ( stripR->fail() ) stripR = &mEEanalysis->strip(sector,plane,myindex+2);
255  if ( stripL->energy() < mSmdMinEnergy ||
256  stripR->energy() < mSmdMinEnergy ) continue;
257 
258  // Smd strip passes minimum requirements for a seed
259  seeds.push_back( strips[i] );
260 
261  if ( strips[i].energy() > emax_strip )
262  {
263  emax_strip = strips[i].energy();
264  }
265 
266  }
267 
268 
269 
270  LOG_DEBUG << " sector=" << sector
271  << " plane=" << plane
272  << " n seed strips=" << seeds.size()
273  << endm;
274 
275 
276 
277  StEEmcSmdClusterVec_t clusters;
278 
279 
280  for ( UInt_t i=0;i<seeds.size(); i++ )
281  {
282 
283  // Get the current smd seed
284  const StEEmcStrip &seed=seeds[i];
285  Int_t myindex=seed.index();
286 
287  //printf("seed sec=%i plane=%i index=%i energy=%6.3f\n",seed.sector(),seed.plane(),seed.index(),seed.energy());
288 
289  // Skip if seed is in use by another cluster
290  if ( used[myindex] ) continue;
291  used[myindex]=true;
292 
293  // Skip if seed energy too low given floor
294  if ( seed.energy() < mSmdSeedEnergy + floor[myindex] ) continue;
295 
297  cluster.add( seed );
298 
299  Int_t break_inflection = 0;
300 
301  Int_t break_energy = 0;
302 
303  // add smd strips
304  for ( Int_t j=1;j<=mMaxExtent;j++ )
305  {
306 
307  Float_t ecluster = cluster.energy();
308  Int_t fail_count = 0;
309 
310  Int_t istrip;
311  //
312  // add strip on the right hand side of the seed
313  //
314  istrip = myindex+j;
315  if ( istrip < nstrips ) { // strip is in the plane
316 
317  if ( used[istrip] ) break; /* we ran into another cluster */
318 
319  const StEEmcStrip &strip=mEEanalysis->strip(sector,plane,istrip);
320  Float_t energy=strip.energy();
321 
322  // break at inflection points
323  if ( istrip > 1 && istrip < nstrips-1 ) {
324  const StEEmcStrip &strip_left=mEEanalysis->strip(sector,plane,istrip-1);
325  const StEEmcStrip &strip_right=mEEanalysis->strip(sector,plane,istrip+1);
326  if ( strip_right.energy() > strip_left.energy() ) break_inflection++;
327  }
328 
329  if ( energy > mSmdMinEnergy )
330  {
331  if ( !strip.fail() ) {
332  used[istrip] = true;
333  cluster.add(strip);
334  }
335  else
336  fail_count++;
337  }
338  else
339  break_energy++;
340 
341 
342  } // to the right
343 
344 
345  //
346  // add strip on the left hand side of the seed
347  //
348  istrip = myindex-j;
349  if ( istrip >=0 ) { // strip is in the plane
350 
351  if ( used[istrip] ) break; /* we ran into another cluster */
352 
353  const StEEmcStrip &strip=mEEanalysis->strip(sector,plane,istrip);
354  Float_t energy=strip.energy();
355 
356  // break at inflection points
357  if ( istrip > 1 && istrip < nstrips-1 ) {
358  const StEEmcStrip &strip_left=mEEanalysis->strip(sector,plane,istrip-1);
359  const StEEmcStrip &strip_right=mEEanalysis->strip(sector,plane,istrip+1);
360  //if ( strip_right.energy() < strip_left.energy() ) break;
361  if ( strip_right.energy() < strip_left.energy() ) break_inflection++;
362 
363  }
364 
365  if ( energy > mSmdMinEnergy )
366  {
367  if ( !strip.fail() ) {
368  used[istrip] = true;
369  cluster.add(strip);
370  }
371  else
372  fail_count++;
373  }
374  else
375  break_energy++;
376 
377 
378  }
379 
380  if ( break_energy ) break;
381 
382 
383  //
384  // terminate cluster when it doesn't grow enough
385  //
386  Float_t etruncate = ecluster;
387  etruncate *= ( mTruncateRatio - ( mTruncateRatio-1.0 ) * ( fail_count ) );
388  if ( cluster.energy() < etruncate && mBreakTruncation ) break;
389 
390  //
391  // truncate the cluster if it reaches an inflection point
392  //
393  if ( mBreakInflection && break_inflection ) break;
394 
395  }// done adding smd strips
396 
397 
398  // add smd cluster to list of clusters
399  if ( cluster.size() >= mMinStrips ) {
400  add(cluster);
401  LOG_DEBUG << " adding " << cluster << endm;
402  Int_t index=seed.index();
403  // for narrow clusters, no additional seeds w/in +/- 3 smd strips are allowed
404  for ( Int_t ii=index-3;ii<=index+3; ii++ )
405  if ( ii>=0 && ii<288 ) used[ii]=1;
406 
407 
408  // add a long distance "floor"
409  if ( mUseFloor )
410  for ( Int_t ii=0;ii<288;ii++ )
411  {
412  Float_t f = mFloorParams[0] * cluster.energy() * TMath::Gaus( seed.index()-ii, 0., mFloorParams[1] * cluster.sigma(), true );
413  floor[ii]+=f;
414  }
415 
416 
417  }
418 
419  }
420 
421 
422  }
423  }
424 
425 
426  return kStOK;
427 }
428 
429 // ----------------------------------------------------------------------------
430 
431 
TVector3 momentum() const
Definition: StEEmcCluster.h:69
StEEmcTower & tower(Int_t t)
Get the specified tower within the cluster.
Definition: StEEmcCluster.h:79
EEmc ADC –&gt; energy maker.
virtual Int_t buildPreshowerClusters()
builder for preshower clusters (both layers)
virtual Int_t buildSmdClusters()
builder for smd clusters
void add(const StEEmcTower &t, Float_t weight=1.0)
virtual Int_t buildTowerClusters()
builder for tower clusters
StEEmcTowerVec_t & towers(Int_t layer=0)
StEEmcStrip & strip(Int_t sector, Int_t plane, Int_t strip)
void add(const StEEmcCluster &cluster)
Add a tower (pre/postshower) cluster to the list of clusters.
void name(const Char_t *n)
Set the name for this element.
Definition: StEEmcElement.h:27
StEEmcClusterVec_t & clusters(Int_t sec, Int_t layer)
Return a vector of tower clusters.
Int_t etabin() const
Returns the etabin of this tower, pre- or postshower element.
Definition: StEEmcTower.h:45
void fail(unsigned f)
Set a fail bit for this element.
Definition: StEEmcElement.h:25
StEEmcStripVec_t & strips(Int_t sec, Int_t pln)
Returns a vector of hit strips, given the sector and plane.
void index(Int_t i)
Sets the index for this SMD strip, 0..287.
Definition: StEEmcStrip.cxx:32
void index(Int_t i)
Definition: StEEmcTower.cxx:76
Base class for representing tower, preshower and postshower elements.
Definition: StEEmcTower.h:11
Bool_t isNeighbor(const StEEmcTower &tower) const
Returns true if tower is adjacent to any tower in the cluster.
Float_t mSeedEnergy[6]
virtual const char * GetName() const
special overload
Definition: StMaker.cxx:237
Int_t numberOfTowers() const
Get the number of towers in cluster.
Definition: StEEmcCluster.h:76
Definition: Stypes.h:40
A base class for representing clusters of EEMC smd strips.
virtual Int_t buildPostshowerClusters()
builder for postshower clusters
Float_t energy() const
Get energy of this cluster.
Definition: StEEmcCluster.h:62
Int_t phibin() const
Returns the phibin of this tower.
Definition: StEEmcTower.h:47
virtual Int_t Make()
A base class for describing clusters of EEMC towers.
Definition: StEEmcCluster.h:50
void energy(Float_t e)
Set the energy (adc-ped+0.5)/gain for this element.
Definition: StEEmcElement.h:21
StEEmcCluster & cluster(Int_t sector, Int_t layer, Int_t index)
Base class for describing an endcap SMD strip.
Definition: StEEmcStrip.h:8
Definition: Stypes.h:41