StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StFmsTowerCluster.cxx
Go to the documentation of this file.
1 // $Id: StFmsTowerCluster.cxx,v 1.7 2016/06/07 15:51:44 akio Exp $
2 //
3 // $Log: StFmsTowerCluster.cxx,v $
4 // Revision 1.7 2016/06/07 15:51:44 akio
5 // Making code better based on Coverity reports
6 //
7 // Revision 1.6 2016/01/26 14:42:48 akio
8 // better chi2 handling
9 //
10 // Revision 1.5 2015/11/02 22:44:49 akio
11 // Fix photonEnergyInTower()
12 //
13 // Revision 1.4 2015/10/21 15:58:05 akio
14 // Code speed up (~x2) by optimizing minimization fuctions and showershape function
15 // Add option to merge small cells to large, so that it finds cluster at border
16 // Add option to perform 1photon fit when 2photon fit faield
17 // Add option to turn on/off global refit
18 // Moment analysis done without ECUTOFF when no tower in cluster exceed ECUTOFF=0.5GeV
19 //
20 // Revision 1.3 2015/10/01 19:55:48 akio
21 // *** empty log message ***
22 //
23 // Revision 1.2 2015/09/02 15:01:32 akio
24 // Removing StFmsGeometry class, and now it uses StFmsDbMaker to get appropriate parameters.
25 //
26 // Revision 1.1 2015/03/10 14:38:54 jeromel
27 // First version of FmsUtil from Yuxi Pan - reviewd 2015/02
28 //
39 
40 #include <cmath>
41 
42 #include "TMath.h"
43 #include "TVector2.h"
44 
45 #include "StEvent/StFmsCluster.h"
46 #include "StEvent/StFmsHit.h"
47 
48 #include "StFmsUtil/StFmsTower.h"
49 
50 namespace FMSCluster {
52  : mIndex(0), mDetectorId(detectorId), mEtot(0.0), mEnergyCutoff(0.5), mCluster(cluster) {
53  Clear();
54 }
55 
57 
58 void StFmsTowerCluster::Clear(const char* /* option */) {
60  mThetaAxis = -10;
61  mTowers.clear();
62 }
63 
65  mEnergyCutoff = Ecoff;
66  Double_t w0, w1, mtmp, mx, my, sigx, sigy, sigXY;
67  w0 = w1 = mtmp = mx = my = sigx = sigy = sigXY = 0;
68  for (Towers::const_iterator i = mTowers.begin(); i != mTowers.end(); ++i) {
69  const StFmsTower* tower = *i;
70  Double_t xxx, yyy;
71  if(tower->hit()->detectorId() != mDetectorId){ //this is small cell merged to large cell
72  xxx = (tower->column() - 0.5)/1.5;
73  yyy = (tower->row() - 0.5)/1.5 + 9.0;
74  }else{
75  xxx = tower->column() - 0.5;
76  yyy = tower->row() - 0.5;
77  }
78  mtmp = log(tower->hit()->energy() + 1. - Ecoff) > 0 ?
79  log(tower->hit()->energy() + 1. - Ecoff) : 0;
80  w1 += mtmp;
81  w0 += tower->hit()->energy();
82  mx += mtmp * xxx;
83  my += mtmp * yyy;
84  sigx += mtmp * xxx * xxx;
85  sigy += mtmp * yyy * yyy;
86  sigXY += mtmp * xxx * yyy;
87  } // for
88  mEtot=w0;
89  mCluster->setEnergy(w0);
90  if (w1 > 0) {
91  mCluster->setX(mx / w1);
92  mCluster->setY(my / w1);
93  mSigmaX = sqrt(fabs(sigx / w1 - std::pow(mCluster->x(), 2.)));
94  mSigmaY = sqrt(fabs(sigy / w1 - std::pow(mCluster->y(), 2.)));
95  mSigmaXY = sigXY / w1 - mCluster->x() * mCluster->y();
96  }else if(w0 > 0){
97  //if cluster has no tower above ecoff, do it without cutoff
98  Double_t keepEcoff = mEnergyCutoff;
100  mEnergyCutoff = keepEcoff;
101  }else{
102  mCluster->setX(0.);
103  mCluster->setY(0.);
104  mSigmaX = 0;
105  mSigmaY = 0;
106  mSigmaXY = 0;
107  } // if
108 }
109 
110 void StFmsTowerCluster::findClusterAxis(Double_t xwidth, Double_t ywidth) {
111  Double_t dSigma2, aA, bB;
112  dSigma2 = mSigmaX * mSigmaX - mSigmaY * mSigmaY;
113  aA = sqrt(dSigma2 * dSigma2 + 4.0 * mSigmaXY * mSigmaXY) + dSigma2;
114  bB = 2 * mSigmaXY;
115  if (mSigmaXY < 1e-10) {
116  if (aA < 1e-10) {
117  bB = sqrt(dSigma2 * dSigma2 + 4.0 * mSigmaXY * mSigmaXY) - dSigma2;
118  aA = 2 * mSigmaXY;
119  } // if
120  } // if
121  mThetaAxis = atan2(bB, aA);
122  Double_t myPi = TMath::Pi();
123  while (mThetaAxis > (myPi / 2.0)) {
124  mThetaAxis -= myPi;
125  } // while
126  while (mThetaAxis < -(myPi / 2.0)) {
127  mThetaAxis += myPi;
128  } // while
129  mCluster->setSigmaMin(getSigma(mThetaAxis,xwidth,ywidth));
130  mCluster->setSigmaMax(getSigma(mThetaAxis - TMath::Pi() / 2.0,xwidth,ywidth));
131 }
132 
133 Double_t StFmsTowerCluster::getSigma(Double_t theta,Double_t xwidth, Double_t ywidth) {
134  Double_t sigma = 0;
135  // 2-d vector vaxis define the axis
136  TVector2 vaxis(cos(theta), sin(theta));
137  // loop over all towers pointer in cluster
138  double wnew =0;
139  int isSmall=0;
140  float emax=0.0;
141  for (Towers::const_iterator i = mTowers.begin(); i != mTowers.end(); ++i) {
142  StFmsTower* tower = *i;
143  // the 2-d vector from the "center" of cluster to tower
144  // "center" are at 0.5, 1.5, etc! Need shift of 0.5
145  Double_t xxx, yyy;
146  int flag=0;
147  if(emax<tower->hit()->energy()) {emax=tower->hit()->energy(); flag=1;}
148  if(tower->hit()->detectorId() != mDetectorId){ //small cell merged to large cell list
149  xxx = (tower->column() - 0.5)/1.5;
150  yyy = (tower->row() - 0.5)/1.5 + 9.0;
151  if(flag==1) isSmall=1;
152  }else{
153  xxx = tower->column() - 0.5;
154  yyy = tower->row() - 0.5;
155  if(flag==1) isSmall=0;
156  }
157  tower->setXY(xxx*xwidth,yyy*ywidth);
158  TVector2 v1(xxx - mCluster->x(),
159  yyy - mCluster->y());
160  // perpendicular distance to the axis = length of the component of vector
161  // "v1" that is norm to "vaxis"
162  Double_t dis = (v1.Norm(vaxis)).Mod();
163  // contribution to sigma
164  double wtmp = log(tower->hit()->energy() + 1. - mEnergyCutoff) > 0 ?
165  log(tower->hit()->energy() + 1. - mEnergyCutoff) : 0;
166  wnew += wtmp;
167  sigma += wtmp * dis * dis;
168  } // for
169  if(isSmall==0){
170  return wnew > 0 ? sqrt(sigma / wnew) : 0;
171  }else{
172  return wnew > 0 ? 1.5*sqrt(sigma / wnew) : 0; //if highest tower is small cell merged to large cell list, put back correct sigma
173  }
174 }
175 
177  mCluster->setChi2Ndf1Photon(mChiSquare1);
178  mCluster->setChi2Ndf2Photon(mChiSquare2);
179  return mCluster.release();
180 }
181 
182 } // namespace FMSCluster
Double_t mSigmaY
2nd moment in y
Double_t mThetaAxis
of least-2nd-sigma axis
Towers mTowers
Towers that make the cluster.
Double_t mSigmaX
2nd moment in x
Double_t getSigma(Double_t theta, Double_t xwidth, Double_t ywidth)
Double_t mChiSquare2
Chi-square of the fitting 2 photon.
const StFmsHit * hit() const
Definition: StFmsTower.h:90
Int_t column() const
Definition: StFmsTower.h:92
Declaration of StFmsTower, a simple FMS tower wrapper.
void findClusterAxis(Double_t Ecoff, Double_t xwidth, Double_t ywidth)
Declaration of StFmsTowerCluster, a cluster of FMS towers.
void setXY(double x, double y)
Definition: StFmsTower.h:100
void calculateClusterMoments(Double_t energyCutoff)
std::unique_ptr< StFmsCluster > mCluster
Pointer to StEvent cluster.
StFmsTowerCluster(StFmsCluster *cluster, Int_t detectorId)
Int_t row() const
Definition: StFmsTower.h:94
Double_t mChiSquare1
Chi-square of the fitting 1 photon.
Double_t mChiSquare
Chi-square of the fitting.
Double_t mEnergyCutoff
Cutoff on towers to use in moment calculations.
Double_t mSigmaXY
2nd moment in x-y