StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMyPointMaker.cxx
1 #include "StMyPointMaker.h"
2 
3 #include "StMessMgr.h"
4 #include <algorithm>
5 
6 #include "StEEmcPool/StEEmcClusterMaker/StEEmcCluster.h"
7 #include "StEEmcPool/StEEmcClusterMaker/StEEmcSmdCluster.h"
8 
9 ClassImp(StMyPointMaker);
10 
11 // ---------------------------------------------------------------------
12 StMyPointMaker::StMyPointMaker(const Char_t *name, const StEEmcA2EMaker *a2e, const StEEmcGenericClusterMaker *cl):
13  StEEmcGenericPointMaker(name,a2e,cl)
14 {
15  mAllowSplitting=false;
16  mSplitMinimumET=0.0;
17  setSmdMinFraction(0.0);
18  mMaxClusterId = 0;
19 }
20 
21 // ---------------------------------------------------------------------
22 Int_t StMyPointMaker::Init()
23 {
24 
25  return StEEmcGenericPointMaker::Init();
26 }
27 
28 // ---------------------------------------------------------------------
30 {
31 
32  gMessMgr->Info() << GetName() << " -I- building points " << endm;
33 
34  typedef StEEmcGenericClusterMaker::EEmatch EEmatch_t;
35 
36  if (mEEclusters) mMaxClusterId = mEEclusters->maxClusterId();
37 
39  //
40  // loop over all sectors and determine the best set of points
41  // beneath clusters
42  //
44  for ( Int_t sector=0;sector<12;sector++ )
45  {
46 
47  // get the vector of tower clusters, sorted descending in energy
48  StEEmcClusterVec_t clusters = mEEclusters->clusters(sector, 0);
49  std::sort( clusters.begin(), clusters.end() );
50  std::reverse( clusters.begin(), clusters.end() );
51 
52  LOG_INFO << GetName() << " sector "<<sector+1
53  <<" nclusters="<<clusters.size()
54  <<" nu="<<mEEclusters->numberOfClusters(sector,4)
55  <<" nv=" <<mEEclusters->numberOfClusters(sector,5)
56  << endm;
57 
58 
59  // loop over tower clusters and associate the matching SMD clusters
60  // into points, based on which pairings minimize a chi^2-like energy
61  // difference
62  for ( UInt_t ic=0;ic<clusters.size();ic++ )
63  {
64 
65  StEEmcCluster cluster=clusters[ic];
66  LOG_DEBUG<<GetName()<<" tower cluster at "<<cluster.tower(0).name()<<endm;
67 
68  EEmatch_t matches = mEEclusters->clusterMatch( cluster );
69 
70  // clusters1 is the smaller of the two lists of smd clusters
71  // matched to this tower cluster
72  StEEmcSmdClusterVec_t clusters1 =
73  (matches.smdu.size()<matches.smdv.size()) ? matches.smdu : matches.smdv;
74 
75  // clusters2 is the larger of the two lists of smd clusters
76  // matched to this tower cluster
77  StEEmcSmdClusterVec_t clusters2 =
78  (matches.smdu.size()<matches.smdv.size()) ? matches.smdv : matches.smdu;
79 
80  if ( clusters1.size() == 0 ) continue;
81  if ( clusters2.size() == 0 ) continue;
82 
83  /*
84  * Test all permutations of the larger list of SMD clusters against
85  * the smaller list of clusters to find the best matches (minimize
86  * a chi^2-like function).
87  */
88  AssociateClusters( clusters1, clusters2 );
89 
90  /*
91  * Attempt to split clusters and, if successful, rerun assocation
92  */
93  if ( mAllowSplitting && cluster.momentum().Perp() > mSplitMinimumET )
94  {
95  if ( SplitClusters( clusters1, clusters2 ) )
96  {
97  AssociateClusters( clusters1, clusters2 );
98  }
99  }
100 
101 
102 
103 
104  StEEmcSmdClusterVec_t uclusters = ( clusters1[0].plane()==0 ) ? clusters1 : clusters2 ;
105  StEEmcSmdClusterVec_t vclusters = ( clusters1[0].plane()==0 ) ? clusters2 : clusters1 ;
106 
107  // we will form this many points associated with this tower cluster
108  UInt_t npoints = clusters1.size();
109  for ( UInt_t ipoint = 0; ipoint < npoints; ipoint++ )
110  {
111 
112  StEEmcPoint p;
113  p.cluster(cluster, 0 ); /* set tower cluster */
114 
115  StEEmcSmdCluster u=uclusters[ipoint];
116  StEEmcSmdCluster v=vclusters[ipoint];
117  p.cluster( u, 0 );
118  p.cluster( v, 1 );
119 
120  Float_t energy = ( u.energy() + v.energy() ) / 0.014; /* initial estimate assumes 1.4% s.f. */
121  p.energy( energy );
122 
123  Float_t sigma = ( u.sigma() + v.sigma() ) / 2.0;
124  p.sigma( sigma );
125 
126  TVector3 position = mEEsmd->getIntersection( u.sector(), u.mean(), v.mean() );
127  if ( position.Z() < 0. )
128  {
129  LOG_WARN<<GetName()<<" attempt to add point with invalid intersection: "<<Form(" X=%5.1f Y=%5.1f sec=%i %i u=%5.1f v=%5.1f",
130  position.X(),position.Y(),u.sector(),v.sector(),u.mean(),v.mean())<<endm;
131  continue;
132  }
133  p.position(position);
134 
135  /*
136  * Obtain a pointer to the tower which this point sits under, and copy
137  * the tower data structure into the point. In the unlikely event that
138  * the tower is out of the acceptance of the endcap, then there is some-
139  * thing wrong with the smd geometry class or the point maker.
140  */
141  const StEEmcTower *tower = mEEanalysis->tower( position, 0 );
142  if ( !tower )
143  {
144  LOG_WARN<<GetName()<<" attempt to add point which misses the EEMC towers: "<<Form(" X=%5.1f Y=%5.1f sec=%i %i u=%5.1f v=%5.1f",
145  position.X(),position.Y(),u.sector(),v.sector(),u.mean(),v.mean())<<endm;
146  continue;
147  }
148  p.tower(*tower);
149 
150  /*
151  * If we've reached this point then, to get to the point of the matter
152  * (sorry...)
153  *
154  * Add the point to the list of SMD points
155  *
156  */
157  addSmdPoint( p );
158 
159  /*
160  * Something is screwy here, and we lose the tower cluster when addSmdPoint
161  * is called. Maybe a problem in the point's copy constructor? Kludge it
162  * for now.
163  */
164  //mSmdPoints.back().cluster( cluster, 0 );
165 
166  }
167 
168 
169 
170  }// loop over tower clusters
171 
172 
173 
174  }// loop over sectors
175 
176 
177 
178 
179  //
180  // Now divide tower energy between all smd points. Start by incrementing a weight
181  // for each endcap tower by the smd energy of the point, and increment weights in
182  // all neighboring towers as well.
183  //
184  Float_t sumw[720]; for ( Int_t ii=0;ii<720;ii++ ) sumw[ii]=0.;
185  for ( Int_t ipoint=0;ipoint<numberOfSmdPoints();ipoint++ )
186  {
187 
188  StEEmcPoint point = smdPoint(ipoint);
189  StEEmcTower tower = point.tower(0);
190  sumw[ tower.index() ] += point.energy();
191 
192  for ( Int_t jj=0;jj<tower.numberOfNeighbors();jj++ )
193  {
194  sumw[tower.neighbor(jj).index()] += point.energy();
195  }
196 
197  }
198 
199 
200  for ( Int_t ipoint=0;ipoint<numberOfSmdPoints();ipoint++ )
201  {
202 
203  StEEmcPoint point = smdPoint(ipoint);
204  StEEmcTower tower = point.tower(0);
205  Float_t epoint = 0.;
206  Float_t w = sumw[tower.index()];
207  if ( !tower.fail() && w>0. ) epoint+=tower.energy() * point.energy()/w;
208  for ( Int_t jj=0;jj<tower.numberOfNeighbors();jj++ )
209  {
210  StEEmcTower neighbor=tower.neighbor(jj);
211  w = sumw[ neighbor.index() ];
212  if ( !neighbor.fail() && w>0. ) epoint+=neighbor.energy() * point.energy()/w;
213 
214  }
215 
216  point.energy(epoint);
217 
218 
219  // for now, associate energy of preshower element including point w/ the
220  // point.
221  Int_t index = tower.index();
222  Float_t epre1 = mEEanalysis->tower(index,1).energy(); /* energy of pre1 */
223  Float_t epre2 = mEEanalysis->tower(index,2).energy(); /* energy of pre2 */
224  Float_t epost = mEEanalysis->tower(index,3).energy(); /* energy of post */
225 
226  point.energy(epre1,1);
227  point.energy(epre2,2);
228  point.energy(epost,3);
229 
230  addPoint( point );
231 
232  }
233 
235 }
236 
237 // ----------------------------------------------------------------------------
238 Bool_t StMyPointMaker::AssociateClusters( const StEEmcSmdClusterVec_t &list1, StEEmcSmdClusterVec_t &list2 )
239 {
240 
241  /*
242  * Sanity checks
243  */
244  if ( list1.size() == 1 && list2.size()==1 )
245  return true;
246 
247  if ( list1.size() > list2.size() )
248  assert(2+2==5); // list1 should be smaller than list2
249 
250  if ( list2.size() == 0 )
251  return false;
252 
253  LOG_DEBUG<<GetName()<<" associating smd clusters"<<endm;
254 
255 
256  /*
257  * Index1 and index2 specify the order we take clusters from the list
258  */
259  std::vector<UInt_t> index1;
260  std::vector<UInt_t> index2;
261  for ( UInt_t i=0;i<list1.size();i++ ){ index1.push_back(i); }
262  for ( UInt_t i=0;i<list2.size();i++ ){ index2.push_back(i); }
263 
264  std::vector<UInt_t> best1;
265  std::vector<UInt_t> best2;
266 
267  /*
268  * Loop while Index2 has a permutation
269  */
270  Bool_t go = true;
271  Float_t ediff_min = 9.0E9;
272 
273  Int_t count=0;
274  while ( go )
275  {
276 
277  LOG_DEBUG<<GetName()<<" permutation = " << count++ << " ediff_min="<< ediff_min<< endm;
278 
279  // calculate energy chi^2 sum for the current order of
280  // list 2 relative to list 1
281  Float_t ediff_sum = 0.0;
282  for ( UInt_t i=0;i<list1.size();i++ )
283  {
284 
285  // consider this pairing of clusters
286  UInt_t i1 = index1[i];
287  UInt_t i2 = index2[i];
288  StEEmcSmdCluster cluster1 = list1[i1];
289  StEEmcSmdCluster cluster2 = list2[i2];
290 
291 
292  if ( cluster1.sector() != cluster2.sector() ) goto INVALID_PERM;
293  if ( cluster1.plane () == cluster2.plane () ) goto INVALID_PERM;
294 
295  Float_t mean1 = cluster1.mean();
296  Float_t mean2 = cluster2.mean();
297 
298  TVector3 hit = mEEsmd->getIntersection( cluster1.sector(), mean1, mean2 );
299  if ( hit.Z() < -1.0 ) goto INVALID_PERM;
300 
301  Float_t echi2 = energyChi2( cluster1, cluster2 );
302  if ( echi2 < 0. ) goto INVALID_PERM;
303 
304  ediff_sum += echi2;
305 
306  }
307 
308 
309  if ( ediff_sum < ediff_min )
310  {
311  best1 = index1;
312  best2 = index2;
313  ediff_min = ediff_sum;
314  }
315 
316 
317  INVALID_PERM:
318  go = std::next_permutation( index2.begin(), index2.end() );
319 
320  }
321 
322 
323  // if we find a valid permuation, overwrite list2 with new
324  // ordering and return true
325  if ( best1.size() == index1.size() )
326  {
327 
328  StEEmcSmdClusterVec_t temp2;
329 
330  for ( UInt_t i=0;i<best2.size();i++ )
331  {
332 
333  temp2.push_back( list2[ best2[i] ] );
334 
335  }
336 
337  LOG_DEBUG<<GetName()<<Form(" ukey\tvkey\t\tvkey")<<endm;
338  LOG_DEBUG<<GetName()<<Form(" \t(initial)\t(final)")<<endm;
339  for ( UInt_t i=0;i<best1.size();i++ )
340  {
341  LOG_DEBUG<<GetName()<<Form(" %i\t%i\t\t%i", list1[i].key(), list2[i].key(), temp2[i].key() )<<endm;
342  }
343 
344  list2.clear();
345  list2=temp2;
346  return true;
347 
348  }
349 
350  /*
351  * If we reached this point, no valid points were found
352  */
353 
354  return false;
355 
356 }
357 
358 // -----------------------------------------------------------------------------
359 Bool_t StMyPointMaker::SplitClusters( StEEmcSmdClusterVec_t &list1,
360  const StEEmcSmdClusterVec_t &list2 )
361 {
362 
363 
364  //
365  // Only split clusters if we have two clusters in list2
366  //
367  if ( list2.size() != 2 ) return false;
368 
369  //
370  // Likewise, only split if we have one cluster in list 1
371  //
372  if ( list1.size() != 1 ) return false;
373 
374 
375  //
376  // energy difference for 1 + 2 case
377  //
378  Float_t ediff12 = energyChi2( list1[0], list2[0] );
379 
380  //
381  // energy difference for 2 + 2 case
382  //
383  Float_t ediff22 = energyChi2( list1[0], list2[0], list2[1] );
384 
385  //
386  // if "chi2" is better for the 2 + 2 case, then split list1[0]
387  //
388  if ( ediff12 <= ediff22 ) return false;
389 
390  StEEmcSmdCluster tempa, tempb;
391  Float_t chi2_a=9.0E9, chi2_b = 9.0E9;
392 
393  StEEmcSmdCluster mergeda=list1[0];
394  StEEmcSmdCluster mergedb=list1[0];
395 
396  Bool_t a = split( list2[0], list2[1], mergeda, tempa, chi2_a );
397  Bool_t b = split( list2[1], list2[0], mergedb, tempb, chi2_b );
398 
399  // case where either order is found
400  if ( a && b )
401  {
402  if ( chi2_a <= chi2_b ) {
403  tempa.key( mMaxClusterId++ );
404  mergeda.key( mMaxClusterId++ );
405  list1[0]=mergeda;
406  list1.push_back( tempa );
407  return true;
408  }
409  else {
410  tempb.key( mMaxClusterId++ );
411  mergedb.key( mMaxClusterId++ );
412  list1[0]=mergedb;
413  list1.push_back( tempb );
414  return true;
415  }
416 
417  }
418  // only first orientation valid
419  else if ( a )
420  {
421  tempa.key( mMaxClusterId++ );
422  mergeda.key( mMaxClusterId++ );
423  list1[0]=mergeda;
424  list1.push_back( tempa );
425  return true;
426  }
427  // only second orientation valid
428  else if ( b )
429  {
430  tempb.key( mMaxClusterId++ );
431  mergedb.key( mMaxClusterId++ );
432  list1[0]=mergedb;
433  list1.push_back( tempb );
434  return true;
435  }
436 
437 
438 
439  return true;
440 }
441 
442 
443 // ---------------------------------------------------------------------
444 Float_t StMyPointMaker::energyChi2( const StEEmcSmdCluster &c1, const StEEmcSmdCluster &c2 ) const
445 {
446  Float_t e1 = c1.energy() * 1000.0;
447  Float_t e2 = c2.energy() * 1000.0;
448  Float_t esum = e1+e2;
449  Float_t edif = e1-e2;
450  Float_t nmip = esum/1.3;
451  if ( esum <= 0. ) return -1.;
452  return edif*edif/nmip;
453 }
454 Float_t StMyPointMaker::energyChi2( const StEEmcSmdCluster &c1, const StEEmcSmdCluster &c2, const StEEmcSmdCluster &c3 ) const
455 {
456  Float_t e1 = c1.energy() * 1000.0;
457  Float_t e2 = c2.energy() * 1000.0;
458  Float_t e3 = c3.energy() * 1000.0;
459  Float_t esum = e1+e2+e3;
460  Float_t edif = e1-e2-e3;
461  Float_t nmip = esum/1.3;
462  if ( esum <= 0. ) return -1.;
463  return edif*edif/nmip;
464 }
465 
466 
467 // ---------------------------------------------------------------------
468 void StMyPointMaker::Clear(Option_t *opts)
469 {
470  return StEEmcGenericPointMaker::Clear(opts);
471 }
472 
473 // ---------------------------------------------------------------------
474 Bool_t StMyPointMaker::split( const StEEmcSmdCluster &in1, // first resolved cluster in view 1
475  const StEEmcSmdCluster &in2, // second resolved cluster in view 1
476  StEEmcSmdCluster &out1, // merged cluster in view 2, will output first split cluster
477  StEEmcSmdCluster &out2, // for output of second split cluster
478  Float_t &chi2out
479  )
480 {
481 
483  if ( in1.sector() != in2.sector() ) return false;
484  if ( in1.plane() != in2.plane() ) return false;
485  if ( in1.sector() != out1.sector() ) return false;
486  if ( in1.plane() == out1.plane() ) return false;
487 
489  //EEmcSmdGeom *geom = EEmcSmdGeom::instance();
490 
491  //Int_t nstrips_in = (Int_t)geom -> getEEmcSector( in1.plane(), in1.sector() ).stripPtrVec.size();
492  //Int_t nstrips_out = (Int_t)geom -> getEEmcSector( out1.plane(), out1.sector() ).stripPtrVec.size();
493 
495  Int_t size = out1.size();
496 
498  StEEmcStrip seed = out1.seed();
499  Int_t id_min = seed.index() - size/2;
500  Int_t id_max = seed.index() + size/2;
501 
502 
514 
516  Int_t id_first = seed.index();
517 
519  Int_t id_second = -1;
520  Float_t min_chi2 = 9.0E9;
521 
523  for ( Int_t id_scan=id_min; id_scan<=id_max; id_scan++ )
524  {
525 
527  Float_t energy[288]; for ( Int_t ii=0;ii<288;ii++ ) energy[ii]=0.;
528 
530  Int_t shift = seed.index() - in1.seed().index();
531  for ( Int_t ii=0;ii<in1.size();ii++ )
532  {
533  StEEmcStrip strip = in1.strip(ii);
534  Int_t index = strip.index() + shift;
535  if ( index < 0 || index > 287 ) continue;
536  energy[index] = strip.energy();
537  }
538 
540  shift = id_scan - in2.seed().index();
541  for ( Int_t ii=0;ii<in2.size();ii++ )
542  {
543  StEEmcStrip strip = in2.strip(ii);
544  Int_t index = strip.index() + shift;
545  if ( index < 0 || index > 287 ) continue;
546  energy[index] += strip.energy();
547  }
548 
549 
551  Float_t chi2 = 0.0;
552  for ( Int_t ii=0;ii<size;ii++ )
553  {
554 
555  StEEmcStrip strip = out1.strip(ii);
556  Int_t jj=strip.index();
557  Float_t ediff = 1000.0 * ( strip.energy() - energy[jj] );
558  Float_t esum = 1000.0 * ( strip.energy() + energy[jj] );
559  Float_t nmip = esum / 1.3;
560 
561  if ( nmip > 0. ) chi2+=ediff*ediff/nmip;
562 
563  }
564 
565  if ( chi2 < min_chi2 )
566  {
567 
568  min_chi2 = chi2;
569  chi2out = chi2;
570  id_second = id_scan;
571 
572  }
573 
574 
575  }// scan 2nd resolved cluster across the merged cluster
576 
577 
578  if ( id_second < 0 ) return false; /* failed to find minimum */
579 
580 
582  StEEmcSmdCluster my1, my2;
583 
586  my1.key( out1.key() );
587  //my2.key( out1.key() );
588  my2.key( mMaxClusterId++ );
589 
590 
592  StEEmcStrip seed1 = mEEanalysis->strip( out1.sector(), out1.plane(), id_first );
593  StEEmcStrip seed2 = mEEanalysis->strip( out1.sector(), out1.plane(), id_second );
594 
595 
598  Float_t energy1[288], energy2[288];
599  for ( Int_t ii=0;ii<288;ii++ ) { energy1[ii]=0.; energy2[ii]=0.; }
600 
601  Int_t shift = id_first - in1.seed().index();
602  for ( Int_t ii=0;ii<in1.size();ii++ )
603  {
604  StEEmcStrip strip=in1.strip(ii);
605  Int_t index = strip.index() + shift;
606  if ( !strip.fail() )
607  energy1[index] = strip.energy();
608  }
609 
610  shift = id_second - in2.seed().index();
611  for ( Int_t ii=0;ii<in2.size();ii++ )
612  {
613  StEEmcStrip strip=in2.strip(ii);
614  Int_t index = strip.index()+shift;
615  if ( !strip.fail() )
616  energy2[index] = strip.energy();
617  }
618 
619 
621  {
622  Float_t e1 = energy1[ seed1.index() ];
623  Float_t e2 = energy2[ seed1.index() ];
624  if ( e1==0. ) e1=0.5*( energy1[seed1.index()-1] + energy1[seed1.index()+1] );
625  if ( e2==0. ) e2=0.5*( energy2[seed1.index()-1] + energy2[seed1.index()+1] );
626  Float_t sumw = e1+e2;
627  my1.add( seed1, e1/sumw );
628  }
629  {
630  Float_t e1 = energy1[ seed2.index() ];
631  Float_t e2 = energy2[ seed2.index() ];
632  if ( e1==0. ) e1=0.5*( energy1[seed2.index()-1] + energy1[seed2.index()+1] );
633  if ( e2==0. ) e2=0.5*( energy2[seed2.index()-1] + energy2[seed2.index()+1] );
634  Float_t sumw = e1+e2;
635  my2.add( seed2, e2/sumw );
636  }
637 
638  for ( Int_t ii=0;ii<out1.size();ii++ )
639  {
640 
641  StEEmcStrip strip = out1.strip(ii);
642 
643  Float_t e1 = energy1[ strip.index() ];
644  Float_t e2 = energy2[ strip.index() ];
645  if ( e1==0. ) e1=0.5*( energy1[strip.index()-1] + energy1[strip.index()+1] );
646  if ( e2==0. ) e2=0.5*( energy2[strip.index()-1] + energy2[strip.index()+1] );
647 
648  Float_t sumw = e1+e2;
649  if ( sumw==0. ) continue;
650 
651  if ( strip.index() != seed1.index() ) my1.add( strip, e1/sumw );
652  if ( strip.index() != seed2.index() ) my2.add( strip, e2/sumw );
653 
654  }
655 
656 
657  out1=my1;
658  out2=my2;
659 
660  return true;
661 
662 }
TVector3 momentum() const
Definition: StEEmcCluster.h:69
const StEEmcA2EMaker * mEEanalysis
void cluster(const StEEmcSmdCluster &c, Int_t plane)
Add an smd cluster to this point.
Definition: StEEmcPoint.h:40
StEEmcTower & tower(Int_t t)
Get the specified tower within the cluster.
Definition: StEEmcCluster.h:79
Int_t numberOfNeighbors() const
get the number of neighboring towers
Definition: StEEmcTower.h:54
Int_t numberOfSmdPoints() const
Number of smd-only points.
EEmc ADC –&gt; energy maker.
Bool_t split(const StEEmcSmdCluster &in1, const StEEmcSmdCluster &in2, StEEmcSmdCluster &out1, StEEmcSmdCluster &out2, Float_t &chi2)
Base class for representing EEMC points.
Definition: StEEmcPoint.h:24
void energy(Float_t e, Int_t layer=0)
Set the energy of this point.
Definition: StEEmcPoint.h:34
void neighbor(StEEmcTower *n)
add a tower to list of neighbors
Definition: StEEmcTower.h:52
StEEmcStrip & strip(Int_t sector, Int_t plane, Int_t strip)
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.
void fail(unsigned f)
Set a fail bit for this element.
Definition: StEEmcElement.h:25
Int_t numberOfClusters(Int_t sector, Int_t layer) const
EEmatch & clusterMatch(const StEEmcCluster &c)
Float_t sigma() const
Returns the width.
Definition: StEEmcPoint.h:90
void index(Int_t i)
Sets the index for this SMD strip, 0..287.
Definition: StEEmcStrip.cxx:32
Bool_t AssociateClusters(const StEEmcSmdClusterVec_t &c1, StEEmcSmdClusterVec_t &c2)
void index(Int_t i)
Definition: StEEmcTower.cxx:76
Base class for representing tower, preshower and postshower elements.
Definition: StEEmcTower.h:11
const StEEmcGenericClusterMaker * mEEclusters
StEEmcPoint & smdPoint(Int_t ipoint)
StEEmcStrip & seed()
Returns the seed strip (by convention, the first strip added to the cluster).
virtual const char * GetName() const
special overload
Definition: StMaker.cxx:237
Int_t key()
Return a unique key assigned by the cluster maker.
virtual void Clear(Option_t *opts="")
User defined functions.
virtual Int_t Make()
A base class for representing clusters of EEMC smd strips.
void tower(const StEEmcTower &t, Float_t w=1.)
Add a tower with specified weight to the point.
Definition: StEEmcPoint.h:38
TVector3 getIntersection(Int_t iSec, Int_t iUStrip, Int_t iVStrip, const TVector3 &vertex) const
virtual void Clear(Option_t *opts="")
User defined functions.
void position(const TVector3 &p)
Set the position of this point at the SMD plane.
Definition: StEEmcPoint.h:32
A base class for describing clusters of EEMC towers.
Definition: StEEmcCluster.h:50
StEEmcTower & tower(Int_t index, Int_t layer=0)
Float_t energyChi2(const StEEmcSmdCluster &c1, const StEEmcSmdCluster &c2) const
Given two clusters, return (e1-e2)^2/nmips.
void energy(Float_t e)
Set the energy (adc-ped+0.5)/gain for this element.
Definition: StEEmcElement.h:21
StEEmcPoint & point(Int_t ipoint)
StEEmcStrip & strip(Int_t s)
Returns the specified smd strip w/in the cluster.
Base class for describing an endcap SMD strip.
Definition: StEEmcStrip.h:8