StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StFmsFpsMaker.cxx
1 // \class StFmsFpsMaker
2 // \author Akio Ogawa
3 //
4 // $Id: StFmsFpsMaker.cxx,v 1.8 2016/06/07 18:00:52 akio Exp $
5 // $Log: StFmsFpsMaker.cxx,v $
6 // Revision 1.8 2016/06/07 18:00:52 akio
7 // Removing data member initialization from constructor (moved to c++11 style initialization in .h file)
8 // Moving project() and distance() as private member function (from global scope)
9 // Adding "const" for many of local variables
10 // Adding "unsigned" for loop variables for consistency
11 // Removing hardcoded zvertex=0.0 and replaced with mMeanVertexZ which is defaulted to 0 and settable via setMeanVertexZ(float v)
12 // Removed obsoluted lines
13 // Added some local const variable for loop condition
14 // Remove commented out cout for debugging, or replaced with LOG_DEBUG
15 //
16 // Revision 1.7 2016/01/26 19:53:14 akio
17 // Drop QA/alignment histograms and just do the analysis/filling StEvent structure
18 // Offline QA and Alignment histograms will be moved to StRoot/StSpinPool/StFmsOfflineQaMaker
19 //
20 // Revision 1.6 2015/12/08 17:00:03 akio
21 // updates
22 //
23 // Revision 1.5 2015/10/29 21:22:01 akio
24 // more cuts for QA
25 //
26 // Revision 1.4 2015/10/21 15:51:01 akio
27 // Add more QA for debugging FMS reconstruciton code
28 //
29 // Revision 1.3 2015/09/18 18:50:06 akio
30 // cleaning up and adding QA histos
31 //
32 // Revision 1.2 2015/09/02 16:12:29 akio
33 // fix typo
34 //
35 // Revision 1.1 2015/09/02 14:56:12 akio
36 // Initial version of FMS-FPS correation analysis
37 //
38 
39 #include "StFmsFpsMaker.h"
40 
41 #include "StMessMgr.h"
42 #include "Stypes.h"
43 
44 #include "StFmsDbMaker/StFmsDbMaker.h"
45 #include "StEnumerations.h"
46 #include "StEventTypes.h"
47 #include "StEvent/StEvent.h"
48 #include "StEvent/StFmsCollection.h"
49 #include "StEvent/StFmsHit.h"
50 #include "StEvent/StFmsPoint.h"
51 #include "StEvent/StFmsPointPair.h"
52 #include "StMuDSTMaker/COMMON/StMuTypes.hh"
53 
54 ClassImp(StFmsFpsMaker);
55 
56 StFmsFpsMaker::StFmsFpsMaker(const Char_t* name): StMaker(name) {}
57 
58 StFmsFpsMaker::~StFmsFpsMaker(){}
59 
60 Int_t StFmsFpsMaker::Init(){
61  mFmsDbMaker=static_cast<StFmsDbMaker*>(GetMaker("fmsDb"));
62  if(!mFmsDbMaker){
63  LOG_ERROR << "StFmsFpsMaker::InitRun Failed to get StFmsDbMaker" << endm;
64  return kStFatal;
65  }
66  return kStOK;
67 }
68 
70  StEvent* event = (StEvent*)GetInputDS("StEvent");
71  if(!event) {LOG_ERROR << "StFmsFpsMaker::Make did not find StEvent"<<endm; return kStErr;}
72  mFmsColl = event->fmsCollection();
73  if(!mFmsColl) {LOG_ERROR << "StFmsFpsMaker::Make did not find StEvent->FmsCollection"<<endm; return kStErr;}
74  if(mReadMuDST) readMuDST();
75  mFmsColl->fillFpsSlat(); //fill StFpsSlat in StFmsCollection
76  corrFmsFps(); //find FMS-FPS correlation, add fps slats info to StFmsPoint
77  mFmsColl->fillFpsAssociation(); //fill StFpsSlat with association info to FmsPoint
78  pid(mPidMethod); //find PID, add to FMS point
79  mFmsColl->fillFmsPointPair(); //find pairs of points
80  isolationCone(); //calc sum energy within cones
81  return kStOk;
82 }
83 
84 //Correlation between FMS and FPS
85 void StFmsFpsMaker::corrFmsFps(){
86  const unsigned int npoint=mFmsColl->numberOfPoints();
87  StSPtrVecFmsPoint& points = mFmsColl->points();
88 
89  //loop over FMS points
90  for(unsigned int i=0; i<npoint; i++) {
91  const float x=points[i]->XYZ().x();
92  const float y=points[i]->XYZ().y();
93  const float z=points[i]->XYZ().z();
94  StLorentzVectorF v1=points[i]->fourMomentum();
95  points[i]->resetFps();
96  //loop over FPS layers to and project
97  for(unsigned int l=1; l<=kFpsNLayer; l++){
98  int nFpsFound=0;
99  //loop pver FPS quad and slats
100  for(unsigned int q=1; q<=kFpsNQuad; q++){
101  for(unsigned int s=1; s<=kFpsNSlat; s++) {
102  const int slatid = mFmsDbMaker->fpsSlatId(q,l,s);
103  if(slatid<0) continue;
104  float xyz[3],width[3];
105  mFmsDbMaker->fpsPosition(slatid,xyz,width);
106  const float projx=project(x,z,xyz[2],mMeanVertexZ);
107  const float projy=project(y,z,xyz[2],mMeanVertexZ);
108  const float d = distance(projx,projy,xyz[0],xyz[1],width[0],width[1]);
109  if(d<mMaxDistanceToAssociate){
110  float mip=mFmsColl->fps(slatid)->mip();
111  const unsigned short status=mFmsDbMaker->fpsStatus(slatid);
112  if(status != 0) mip=-9.0; //check FPS status from DB
113  LOG_DEBUG << Form("%3d proj=%5.1f %5.1f slatid=%4d Q%1dL%1dS%02d d=%4.1f n=%d\n",
114  i,projx,projy,slatid,q,l,s,d,nFpsFound) << endm;
115  points[i]->setFps(l,mip,slatid,d);
116  nFpsFound++;
117  } // if this hit a fps slat
118  } //loop over fps slat
119  } //loop over fps quad
120  if(nFpsFound==0){
121  LOG_DEBUG << Form("%3d proj=%5.1f %5.1f E=%5.1f L%1d not found!!!\n",i,x,y,points[i]->energy(),l) << endm;
122  }else if(nFpsFound>kFpsNCandidate){
123  LOG_WARN << Form("found %d FPS slats assosicated with FmsPoint, which is more than %d!!!",nFpsFound,kFpsNCandidate) <<endm;
124  }
125  } //loop over fps layer
126  }
127 }
128 
129 //opt: 0=take closest only, 1=sum of all associated, 2=closest, if mip=0 at closest, take 2nd if available
130 void StFmsFpsMaker::pid(int opt){
131  const unsigned int npoint=mFmsColl->numberOfPoints();
132  StSPtrVecFmsPoint& points = mFmsColl->points();
133 
134  for(unsigned int i=0; i<npoint; i++) {
135  int pid=StFmsPoint::kFpsPidNoFps;
136  int i1=0,i2=0,i3=0;
137  if(opt==0 || opt==2){
138  i1=int(points[i]->fpsMip(1,0) + 0.5);
139  i2=int(points[i]->fpsMip(2,0) + 0.5);
140  i3=int(points[i]->fpsMip(3,0) + 0.5);
141  }else if(opt==1){
142  i1=int(points[i]->fpsMip(1,kFpsNCandidate+2)+0.5);
143  i2=int(points[i]->fpsMip(2,kFpsNCandidate+2)+0.5);
144  i3=int(points[i]->fpsMip(3,kFpsNCandidate+2)+0.5);
145  }
146  if(opt==2){
147  if(i1<=0) i1=int(points[i]->fpsMip(1,1) + 0.5);
148  if(i2<=0) i2=int(points[i]->fpsMip(2,1) + 0.5);
149  if(i3<=0) i3=int(points[i]->fpsMip(3,1) + 0.5);
150  }
151  if(i1<-5 || i2<-5 || i3<-5) {
152  pid=StFmsPoint::kFpsPidBad; //bad FPS status
153  }else if(i1<0 || i2<0 || i3<0) {
154  pid=StFmsPoint::kFpsPidNoFps; //no FPS coverage
155  }else{
156  //total 0
157  if (i1==0 && i2==0 && i3==0) pid=StFmsPoint::kFpsPidGamma1; // golden gamma which didn't convert in PbC
158  //total 1 hits
159  else if(i1>=1 && i2==0 && i3==0) pid=StFmsPoint::kFpsPidGamma3; // gamma + accidental?
160  else if(i1==0 && i2>=1 && i3==0) pid=StFmsPoint::kFpsPidGamma4; // gamma + accidental?
161  else if(i1==0 && i2==0 && i3>=1) pid=StFmsPoint::kFpsPidGamma2; // golden gamma
162  //total 2 hits
163  else if(i1>=1 && i2>=1 && i3==0) pid=StFmsPoint::kFpsPidUnknown; // ???
164  else if(i1>=1 && i2==0 && i3>=1) pid=StFmsPoint::kFpsPidGamma5; // gamma + accidental?
165  else if(i1==0 && i2>=1 && i3>=1) pid=StFmsPoint::kFpsPidGamma6; // gamma + accidental?
166  //total 3 hits
167  else if(i1>=1 && i2>=1 && i3<=4) pid=StFmsPoint::kFpsPidMip; // MIP
168  else if(i1==1 && i2==1 && i3>=5) pid=StFmsPoint::kFpsPidElectron1;// golden e+e-
169  else if(i1==1 && i2>=2 && i3>=5) pid=StFmsPoint::kFpsPidElectron2;// e+e-
170  else if(i1>=2 && i2==1 && i3>=5) pid=StFmsPoint::kFpsPidElectron3;// e+e-
171  else if(i1>=2 && i2>=2 && i3>=5) pid=StFmsPoint::kFpsPidGamma7; // gamma converted to e+e- pair?
172  else LOG_WARN << Form("Leaking selection : %1d %1d %1d\n",i1,i2,i3)<<endm;
173  }
174  points[i]->setFpsPid(pid);
175  } // loop over FMS points
176 }
177 
178 void StFmsFpsMaker::isolationCone(){
179  const unsigned int nPointPairs = mFmsColl->numberOfPointPairs();
180  const unsigned int nHits = mFmsColl->numberOfHits();
181  for(unsigned int i=0; i<nPointPairs; i++){
182  StFmsPointPair* pair=mFmsColl->pointPairs()[i];
183  StThreeVectorF v1=pair->fourMomentum().vect();
184  float sum[StFmsPointPair::kFmsPointMaxCone];
185  memset(sum,0,sizeof(sum));
186  for(unsigned int h=0; h<nHits; h++){
187  StFmsHit* hit=mFmsColl->hits()[h];
188  if(hit->detectorId()>=kFmsNorthLargeDetId && hit->detectorId()<=kFmsSouthSmallDetId){
189  StThreeVectorF v2=mFmsDbMaker->getStarXYZ(hit);
190  float angle=v1.angle(v2);
191  for(unsigned int c=0; c<StFmsPointPair::kFmsPointMaxCone; c++){
192  if(angle < pair->coneRadius(c)){
193  sum[c]+=hit->energy();
194  }//if within cone radius
195  }//loop over difference cone sizes
196  }//if fms hits
197  }//loop over hits
198  for(unsigned int c=0; c<StFmsPointPair::kFmsPointMaxCone; c++) pair->setConeEnergy(c,sum[c]);
199  }//loop over point pairs
200 }
201 
202 //Read MuDST if available, and update FPS hits in StEvent using current DB values
203 void StFmsFpsMaker::readMuDST(){
204  const unsigned int nh=mFmsColl->numberOfHits();
205  StSPtrVecFmsHit& hits = mFmsColl->hits();
206  int nfpshit=0;
207  for(unsigned int j=0; j<nh; j++){ //count fps hits in StEvent->StFmsCollection->Hit
208  if(hits[j]->detectorId()==kFpsDetId) nfpshit++;
209  }
210  StMuDst* mudst = (StMuDst*)GetInputDS("MuDst");
211  if(!mudst){ LOG_INFO<<"StFmsFpsMaker::readMuDST found no Mudst"<<endm; return;}
212 
214  if(!muFmsColl){ LOG_INFO<<"StFmsFpsMaker::readMuDST found no StMuFmsCollection in MuDST"<<endm; return;}
215  int nfps=0;
216  const unsigned int nhits = muFmsColl->numberOfHits();
217  for(unsigned int i=0; i<nhits; i++){
218  StMuFmsHit* h = muFmsColl->getHit(i);
219  if(h->detectorId()==15) h->setDetectorId(kFpsDetId); //hack to deal with wrong DetId
220  if(h->detectorId()==kFpsDetId) { //only updating FPS hits... StFmsHitMaker deal with the rest
221  int flag=0;
222  const int ch=h->channel();
223  const float gain=mFmsDbMaker->fpsGain(ch);
224  const float nmip=h->adc()/gain;
225  LOG_DEBUG << Form("ch=%3d adc=%4d gain=%6.2f nmip=%6.2f\n",ch,h->adc(),gain,nmip)<<endm;
226  if(nfpshit>0){ //only if there were FPS hits in StEnvent...
227  for(unsigned int j=0; j<nh; j++){ //loop over fmsHits in StEvent and updating energy with new calibration
228  if(hits[j]->detectorId()==kFpsDetId && hits[j]->channel()==ch){
229  if(h->adc()!= hits[j]->adc()) {
230  LOG_ERROR << "StFmsFpsMaker::readMuDst Found inconsistent FPS hit" <<endm;
231  h->print();
232  hits[j]->print();
233  break;
234  }
235  LOG_DEBUG<<"StFmsFpsMaker::readMuDST found matching hits in StEvent->StFmsCollection, updating energy with new DB value "<<endm;
236  hits[j]->setEnergy(nmip);
237  flag=1;
238  break;
239  }
240  }
241  }
242  if(flag==0){ //found no correspinding hit in StEvent->FmsCollection, so adding it
243  StFmsHit* hit = new StFmsHit(h->detectorId(),h->channel(),
244  h->qtCrate(),h->qtSlot(),h->qtChannel(),
245  h->adc(), h->tdc(), nmip);
246  mFmsColl->addHit(hit);
247  LOG_DEBUG<<"StFmsFpsMaker::readMuDST did not find matching hits in StEvent->StFmsCollection. Creating and adding"<<endm;
248  }
249  nfps++;
250  }
251  }
252  LOG_INFO<<"StFmsFpsMaker::readMuDST Found "<<nhits<<" FMS hits in MuDst, updated "<<nfps<<" FPS hits"<<endm;
253 }
254 
255 Float_t StFmsFpsMaker::project(float x, float z, float zp, float vz){
256  if(z==vz) return 0.0;
257  return x/(z-vz)*(zp-vz);
258 }
259 
260 //find minimal distance between a point (x,y) and edge of a rectange with center (x0,y0) and width (xw,yw)
261 //return negative distance if its inside, positive outside
262 Float_t StFmsFpsMaker::distance(float x, float y, float x0, float y0, float xw, float yw){
263  const float xx=x-x0;
264  float yy=y-y0;
265  float dx1=xx-xw/2.0, adx1=fabs(dx1);
266  float dx2=xx+xw/2.0, adx2=fabs(dx2);
267  float dy1=yy-yw/2.0, ady1=fabs(dy1);
268  float dy2=yy+yw/2.0, ady2=fabs(dy2);
269  float adx=(adx1<adx2) ? adx1 : adx2;
270  float ady=(ady1<ady2) ? ady1 : ady2;
271  float ad =(adx <ady ) ? adx : ady ;
272  float oix=dx1*dx2;
273  float oiy=dy1*dy2;
274  if(oix<0.0 && oiy<0.0) return -ad; //inside
275  if(oix<0.0 && oiy>0.0) return ady; //outside in y direction
276  if(oix>0.0 && oiy<0.0) return adx; //outside in x direction
277  return sqrt( pow(fabs(xx)-xw/2.0,2.0) + pow(fabs(yy)-yw/2.0,2.0) ); //outside both ways, return dist from corner
278 }
static StMuFmsCollection * muFmsCollection()
returns pointer to current StMuFmsCollection
Definition: StMuDst.h:391
StThreeVectorF getStarXYZ(Int_t detectorId, Float_t FmsX, Float_t FmsY)
get the Y width of the cell
Definition: Stypes.h:40
Definition: Stypes.h:44
Definition: Stypes.h:41