StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StEEmc2x2ClusterMaker.cxx
1 #include "StEEmc2x2ClusterMaker.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(StEEmc2x2ClusterMaker);
16 
17 // ----------------------------------------------------------------------------
18 StEEmc2x2ClusterMaker::StEEmc2x2ClusterMaker(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 
54  //$$$ buildSmdClusters();
56  Int_t result = StEEmcGenericClusterMaker::Make();
57  return result;
58 }
59 
60 // ----------------------------------------------------------------------------
61 Int_t StEEmc2x2ClusterMaker::buildLayer(Int_t layer )
62 {
63 
64  const Char_t *clayers[]={"T","P","Q","R","U","V"};
65 
66  LOG_INFO << " build clusters for layer=" << clayers[layer] << endm;
67 
68  // get list of hit towers
69  StEEmcTowerVec_t hits=mEEanalysis->towers(layer);
70 
71  // sort towers ascending in energy
72  std::sort( hits.begin(), hits.end());
73  // and reverse so it's descending
74  std::reverse( hits.begin(), hits.end());
75 
76  LOG_DEBUG<<"searching for seeds in layer "<<clayers[layer]<<endm;
77 
78  // loop over all hit towers and find seeds
79  StEEmcTowerVec_t seeds;
80  for ( UInt_t i=0;i<hits.size();i++ )
81  {
82  if ( hits[i].fail() ) continue;
83  if ( hits[i].energy() > mSeedEnergy[layer] )
84  seeds.push_back(hits[i]);
85  else
86  break;
87  LOG_DEBUG<<"+ "<<hits[i].name()<<" "<<hits[i].energy()<<endm;
88  }
89  LOG_DEBUG<<"clustering"<<endm;
90 
91 
92  // Define the four clustering positions relative to each seed tower
93  struct Cluster {
94  int quad;
95  int *etabins;
96  int *phibins;
97  float et;
98  };
99 
100  int etaA[]={0, 0, 1, 1};
101  int etaB[]={0, 0,-1,-1};
102  int phiA[]={0, 1, 0, 1};
103  int phiB[]={0,-1, 0,-1};
104 
105  Cluster Cluster0 = { 0, etaA, phiA, 0. };
106  Cluster Cluster1 = { 1, etaA, phiB, 0. };
107  Cluster Cluster2 = { 2, etaB, phiB, 0. };
108  Cluster Cluster3 = { 3, etaB, phiA, 0. };
109  Cluster Quads[]={Cluster0,Cluster1,Cluster2,Cluster3};
110 
111  // next we form clusters around seeds. clusters are 2x2 in size.
112 
113  Bool_t used[720];
114  for ( Int_t i=0;i<720;i++ ) used[i]=false;
115 
116  for ( UInt_t i=0;i<seeds.size();i++ )
117  {
118 
119  StEEmcTower tow=seeds[i];
120  if ( tow.fail() ) continue; // bad hardware
121  if ( used[tow.index()] ) continue; // used by another cluster
122 
123  Int_t etabin_seed = tow.etabin();
124  Int_t phibin_seed = tow.phibin();
125 
126 
127  // std::cout << Form("----------------------- clustering around %s -----------------------",tow.name()) << std::endl;
128  StEEmcCluster c;
129  Int_t ntowers = 0;
130  // Loop over the 4 possible clustering positions and find the
131  // highest E_T cluster
132 
133  for ( Int_t j=0;j<4;j++ )
134  {
135 
136  StEEmcCluster temp;
137  Int_t ntow=0;
138  for ( Int_t k=0;k<4;k++ ) // loop over the 4 towers
139  {
140 
141  Int_t myeta = etabin_seed + Quads[j].etabins[k];
142  Int_t myphi = phibin_seed + Quads[j].phibins[k];
143  if ( myeta < 0 || myeta > 11 ) continue; // off the doughnut
144  Int_t myindex = myeta + 12 * ( ( myphi + 60 ) % 60 );
145  if ( used[myindex] ) continue; // Skip used towers
146 
147  const StEEmcTower &t = mEEanalysis->tower(myindex,layer);
148  if ( t.energy() > mMinEnergy[layer] ) {
149  temp.add(t);
150  ntow++;
151  }
152 
153  }// loop over the 4 towers
154 
155  if ( ntow > 0 && temp.energy() > c.energy() )
156  {
157  c=temp;
158  ntowers = ntow;
159  }
160 
161  } // loop over the 4 2x2 combinations of towers
162 
163 
164 
165  // double check validity of cluster
166  if ( ntowers ) {
167  add(c); // add to the list of clusters
168  for ( Int_t ii=0;ii<c.numberOfTowers();ii++ )
169  {
170  // std::cout << Form("flagging %s",c.tower(ii).name()) << std::endl;
171  used[ c.tower(ii).index() ] = true; // flag tower as used
172  }
173 
174  LOG_DEBUG<<"+ key="<<c.key()<<" seed="<<c.tower(0).name()<<" energy="<<c.energy()<<endm;
175  }
176 
177  }
178 
179  return kStOk;
180 
181 }
182 
183 // ----------------------------------------------------------------------------
185 {
186  return buildLayer(0);
187 }
188 
189 // ----------------------------------------------------------------------------
191 {
192  buildLayer(1);
193  buildLayer(2);
194  return kStOK;
195 }
196 
197 // ----------------------------------------------------------------------------
199 {
200  return buildLayer(3);
201 }
202 
203 // ----------------------------------------------------------------------------
205 {
206 
207  LOG_INFO << " building SMD clusters" << endm;
208 
209  for ( Int_t sector=0;sector<12;sector++ ) {
210 
211  Float_t etmax = 0.;
212  for ( UInt_t ii=0;ii<mTowerClusters[sector][0].size();ii++ )
213  {
214  const StEEmcCluster &c = mTowerClusters[sector][0][ii];
215  if ( c.momentum().Perp() > etmax ) etmax = c.momentum().Perp();
216  }
217 
218 
219  if ( etmax >= 4.5 ) {
220  mSmdSeedEnergy = ( seed_threshold + seed_slope * (etmax-4.5) ) / 1000.0;
222  }
223  else {
224  mSmdSeedEnergy = seed_threshold / 1000.0;
226  }
227 
228  LOG_INFO<<GetName()<<" sector="<<sector<<" seed energy="<<mSmdSeedEnergy<<endm;
229 
230  for ( Int_t plane=0;plane<2;plane++ )
231  {
232 
233 
234  // get number of smd strips in this plane
235  Int_t nstrips = (Int_t)mESmdGeom -> getEEmcSector( plane, sector ).stripPtrVec.size();
236 
237  // Array denoting which smd strips are in use
238  Bool_t used[288]; for (Int_t i=0;i<288;i++ ) used[i]=false;
239 
240  // Additional energy cut imposed upon seed strips after identifiying an SMD cluster
241  Float_t floor[288]; for ( Int_t i=0;i<288;i++ ) floor[i]=0.;
242 
243  // Get list of hit smd strips
244  StEEmcStripVec_t strips=mEEanalysis->strips(sector,plane);
245  // Sort by energy
246  std::sort(strips.begin(),strips.end());
247  // Order in descending energy
248  std::reverse(strips.begin(),strips.end());
249 
250 
251  LOG_DEBUG << " sector=" << sector
252  << " plane=" << plane
253  << " nhit strips=" << strips.size()
254  << endm;
255 
256  StEEmcStripVec_t seeds;
257 
258  Float_t emax_strip = 0.;
259  for ( UInt_t i=0;i<strips.size();i++ )
260  {
261 
262  // Get the index of the strip
263  Int_t myindex = strips[i].index();
264 
265  // Bail out if the strip is below seed energy
266  if ( strips[i].energy() < mSmdSeedEnergy ) break;
267 
268  // Skip if near edge of the plane
269  if ( myindex < 4 || myindex > nstrips-4 ) continue;
270 
271  // Skip if fail bit is set
272  if ( strips[i].fail() ) continue;
273 
274  // Require signal in adjacent smd strips
275  const StEEmcStrip *stripL = &mEEanalysis->strip(sector,plane,myindex-1);
276  const StEEmcStrip *stripR = &mEEanalysis->strip(sector,plane,myindex+1);
277  if ( stripL->fail() ) stripL=&mEEanalysis->strip(sector,plane,myindex-2);
278  if ( stripR->fail() ) stripR=&mEEanalysis->strip(sector,plane,myindex+2);
279  if ( stripL->energy() < mSmdMinEnergy || stripR->energy() < mSmdMinEnergy ) continue;
280 
281  // Smd strip passes minimum requirements for a seed
282  seeds.push_back( strips[i] );
283 
284  if ( strips[i].energy() > emax_strip )
285  {
286  emax_strip = strips[i].energy();
287  }
288 
289  }
290 
291 
292 
293  LOG_DEBUG << " sector=" << sector
294  << " plane=" << plane
295  << " n seed strips=" << seeds.size()
296  << endm;
297 
298 
299 
300  StEEmcSmdClusterVec_t clusters;
301 
302 
303  for ( UInt_t i=0;i<seeds.size(); i++ )
304  {
305 
306  // Get the current smd seed
307  const StEEmcStrip &seed=seeds[i];
308  Int_t myindex=seed.index();
309 
310  //printf("seed sec=%i plane=%i index=%i energy=%6.3f\n",seed.sector(),seed.plane(),seed.index(),seed.energy());
311 
312  // Skip if seed is in use by another cluster
313  if ( used[myindex] ) continue;
314  used[myindex]=true;
315 
316  // Skip if seed energy too low given floor
317  if ( seed.energy() < mSmdSeedEnergy + floor[myindex] ) continue;
318 
320  cluster.add( seed );
321 
322  Int_t break_inflection = 0;
323 
324  Int_t break_energy = 0;
325 
326  // add smd strips
327  for ( Int_t j=1;j<=mMaxExtent;j++ )
328  {
329 
330  Float_t ecluster = cluster.energy();
331  Int_t fail_count = 0;
332 
333  Int_t istrip;
334  //
335  // add strip on the right hand side of the seed
336  //
337  istrip = myindex+j;
338  if ( istrip < nstrips ) { // strip is in the plane
339 
340  if ( used[istrip] ) break; /* we ran into another cluster */
341 
342  const StEEmcStrip &strip=mEEanalysis->strip(sector,plane,istrip);
343  Float_t energy=strip.energy();
344 
345  // break at inflection points
346  if ( istrip > 1 && istrip < nstrips-1 ) {
347  const StEEmcStrip &strip_left=mEEanalysis->strip(sector,plane,istrip-1);
348  const StEEmcStrip &strip_right=mEEanalysis->strip(sector,plane,istrip+1);
349  if ( strip_right.energy() > strip_left.energy() ) break_inflection++;
350  }
351 
352  if ( energy > mSmdMinEnergy )
353  {
354  if ( !strip.fail() ) {
355  used[istrip] = true;
356  cluster.add(strip);
357  }
358  else
359  fail_count++;
360  }
361  else
362  break_energy++;
363 
364 
365  } // to the right
366 
367 
368  //
369  // add strip on the left hand side of the seed
370  //
371  istrip = myindex-j;
372  if ( istrip >=0 ) { // strip is in the plane
373 
374  if ( used[istrip] ) break; /* we ran into another cluster */
375 
376  const StEEmcStrip &strip=mEEanalysis->strip(sector,plane,istrip);
377  Float_t energy=strip.energy();
378 
379  // break at inflection points
380  if ( istrip > 1 && istrip < nstrips-1 ) {
381  const StEEmcStrip &strip_left=mEEanalysis->strip(sector,plane,istrip-1);
382  const StEEmcStrip &strip_right=mEEanalysis->strip(sector,plane,istrip+1);
383  //if ( strip_right.energy() < strip_left.energy() ) break;
384  if ( strip_right.energy() < strip_left.energy() ) break_inflection++;
385 
386  }
387 
388  if ( energy > mSmdMinEnergy )
389  {
390  if ( !strip.fail() ) {
391  used[istrip] = true;
392  cluster.add(strip);
393  }
394  else
395  fail_count++;
396  }
397  else
398  break_energy++;
399 
400 
401  }
402 
403  if ( break_energy ) break;
404 
405 
406  //
407  // terminate cluster when it doesn't grow enough
408  //
409  Float_t etruncate = ecluster;
410  etruncate *= ( mTruncateRatio - ( mTruncateRatio-1.0 ) * ( fail_count ) );
411  if ( cluster.energy() < etruncate && mBreakTruncation ) break;
412 
413  //
414  // truncate the cluster if it reaches an inflection point
415  //
416  if ( mBreakInflection && break_inflection ) break;
417 
418  }// done adding smd strips
419 
420 
421  // add smd cluster to list of clusters
422  if ( cluster.size() >= mMinStrips ) {
423  add(cluster);
424  LOG_INFO << " adding " << cluster << endm;
425  Int_t index=seed.index();
426  // for narrow clusters, no additional seeds w/in +/- 3 smd strips are allowed
427  for ( Int_t ii=index-3;ii<=index+3; ii++ )
428  if ( ii>=0 && ii<288 ) used[ii]=1;
429 
430 
431  // add a long distance "floor"
432  if ( mUseFloor )
433  for ( Int_t ii=0;ii<288;ii++ )
434  {
435  Float_t f = mFloorParams[0] * cluster.energy() * TMath::Gaus( seed.index()-ii, 0., mFloorParams[1] * cluster.sigma(), true );
436  floor[ii]+=f;
437  }
438 
439 
440  }
441 
442  }
443 
444 
445  }
446  }
447 
448 
449  return kStOK;
450 }
451 
452 // ----------------------------------------------------------------------------
453 
454 
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.
void add(const StEEmcTower &t, Float_t weight=1.0)
StEEmcTowerVec_t & towers(Int_t layer=0)
StEEmcStrip & strip(Int_t sector, Int_t plane, Int_t strip)
StEEmcA2EMaker * mEEanalysis
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
virtual Int_t buildSmdClusters()
builder for smd clusters
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
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.
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
A base class for describing clusters of EEMC towers.
Definition: StEEmcCluster.h:50
StEEmcTower & tower(Int_t index, Int_t layer=0)
virtual Int_t buildPostshowerClusters()
builder for postshower clusters
void energy(Float_t e)
Set the energy (adc-ped+0.5)/gain for this element.
Definition: StEEmcElement.h:21
virtual Int_t buildTowerClusters()
builder for tower clusters
virtual Int_t buildPreshowerClusters()
builder for preshower clusters (both layers)
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