StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMuFmsUtil.cxx
1 /***************************************************************************
2  *
3  * $Id: StMuFmsUtil.cxx,v 1.8 2019/06/18 20:22:53 jdb Exp $
4  *
5  * Author: Jingguo Ma, Jan 2010
6  ***************************************************************************
7  *
8  * Description: FMS Util to convert between StEvent and MuDst
9  *
10  ***************************************************************************
11  *
12  * $Log: StMuFmsUtil.cxx,v $
13  * Revision 1.8 2019/06/18 20:22:53 jdb
14  * Update StMuFmsUtil::recoverMuFmsCollection to solve issue with run16 AuAu data, FmsCollection not cleared
15  *
16  * Revision 1.7 2017/08/14 16:22:36 smirnovd
17  * Recover FMS hits using StTriggerData
18  *
19  * commit 6d7358f4c86a15edd0671326580d291a9843aec9
20  * Date: Tue Aug 8 23:42:41 2017 -0400
21  *
22  * StMuFmsUtil: Recover FMS hits using StTriggerData
23  *
24  * commit 556d07cb8fd87cb62e4ac674226423671c94917d
25  * Date: Tue Aug 8 23:42:34 2017 -0400
26  *
27  * StMuFmsUtil: Added func to fill StMuFmsCollection with FMS hits from StTriggerData in StMuEvent
28  *
29  * commit c355529c1ee401849b2b81d74df8d452886593d1
30  * Date: Tue Aug 8 23:42:19 2017 -0400
31  *
32  * [Cosmetic] Changes in whitespace
33  *
34  * commit 67fdc1b348bebbfbfb137b726ee9c455a7d8be37
35  * Date: Mon Jun 5 12:00:24 2017 -0400
36  *
37  * StMuFmsCollection::addHit() Return pointer to just added default FMS hit object
38  *
39  * Revision 1.6 2016/06/14 17:11:34 jdb
40  * Fixing Coverity Errors:
41  * StMuFmsCluster.cxx : UNINIT_CTOR on member mEnergy
42  * StMuFmsUtile.cxx : DEADCODE on check for null pointer
43  *
44  * Revision 1.5 2015/11/06 17:47:16 jdb
45  * Added StMuFmsInfo.{h,cxx} as a new branch for storing event-by-event FMS paramters
46  *
47  * Revision 1.4 2015/10/23 19:22:49 jdb
48  * akio added mFmsReconstructionFlag and related getters and setters. pushed version number of StMuFmsCollection. Corresponding changes for reconstruction flag in StMuFmsUtil.cxx
49  *
50  * Revision 1.3 2015/09/02 22:09:58 jdb
51  * Added Akios changes to Fms
52  *
53  * Revision 1.2 2015/08/28 18:36:04 jdb
54  * Added Akios FMS codes
55  *
56  * Revision 1.1 2010/01/25 03:57:39 tone421
57  * Added FMS and Roman pot arrays
58  *
59  **************************************************************************/
60 #include "StEvent/StFmsCluster.h"
61 #include "StMuDSTMaker/COMMON/StMuFmsCluster.h"
62 #include "StMuDSTMaker/COMMON/StMuFmsHit.h"
63 #include "StMuDSTMaker/COMMON/StMuFmsPoint.h"
64 #include "StMuDSTMaker/COMMON/StMuFmsUtil.h"
65 #include "StMuDSTMaker/COMMON/StMuFmsCollection.h"
66 #include "StMuDSTMaker/COMMON/StMuDst.h"
67 #include "StMuDSTMaker/COMMON/StMuEvent.h"
68 #include "StEvent/StEvent.h"
69 #include "St_base/StMessMgr.h"
70 #include "StEvent/StEventTypes.h"
71 #include "StEvent/StTriggerData.h"
72 #include "StFmsDbMaker/StFmsDbMaker.h"
73 
74 #include <algorithm> // For std::find
75 #include <iterator> // For std::distance
76 
77 #include "TCollection.h" // For TIter
78 #include "TRefArray.h"
79 #include "TVector3.h"
80 
81 ClassImp(StMuFmsUtil)
82 
83 namespace {
84 /*
85  Return the index of an element in an StPtrVec-like array.
86 
87  The element should be of the pointer type in the StPtrVec.
88  Return -1 if the element cannot be located in the array.
89  See StEvent/StArray.h for the definition of St[S]PtrVec arrays.
90  */
91 template<class StPtrVec, class Element>
92 int findElementIndex(const StPtrVec& array, const Element* element) {
93  // This typedef is equivalent to an iterator to an Element in the StPtrVec,
94  // as defined in StArray.h. The StPtrVec definition does not include a
95  // template iterator typedef itself, but this the same as what
96  // StPtrVec::const_iterator would do.
97  typedef Element* const * ElementConstIter;
98  // Find where the element is in the array
99  ElementConstIter location = std::find(array.begin(), array.end(), element);
100  // Ensure the desired element actually is in the array, as the behaviour
101  // of std::distance is undefined otherwise.
102  // Return -1 if the element isn't in the array, otherwise return its index
103  if (location == array.end()) { // Not in the array
104  return -1;
105  } else {
106  return std::distance(array.begin(), location);
107  } // if
108 }
109 } // namespace
110 
111 StMuFmsUtil::StMuFmsUtil()
112 {
113 }
114 StMuFmsUtil::~StMuFmsUtil()
115 {
116 }
117 
118 StMuFmsCollection* StMuFmsUtil::getMuFms(StFmsCollection *fmscol)
119 {
120  LOG_DEBUG << "StMuFmsUtil::getMuFms" << endm;
121  if(!fmscol) return NULL;
123  fillMuFms(muFms,fmscol);
124  return muFms;
125 }
126 
127 StFmsCollection* StMuFmsUtil::getFms(StMuFmsCollection* muFms)
128 {
129  if(!muFms) return NULL;
130 
131  StFmsCollection *fms=new StFmsCollection();
132  fillFms(fms,muFms);
133  return fms;
134 }
135 
136 void StMuFmsUtil::fillMuFms(StMuFmsCollection *muFms,StFmsCollection *fmscol)
137 {
138  if(!fmscol) return;
139  if(!muFms) return;
140  //fmscol->print();
141  // Do hits and points before clusters, so that the hit and point lists are
142  // populated before we try to set hit- and photon-in-cluster information
143  // during the cluster loop
144 
145  muFms->addInfo();
146  muFms->setFmsReconstructionFlag(fmscol->fmsReconstructionFlag());
147 
148  fillMuFmsHits(muFms, fmscol);
149  fillMuFmsPoints(muFms, fmscol);
150  fillMuFmsClusters(muFms, fmscol);
151  // Now we need to go back and set parent cluster of each point, now that the
152  // cluster list in StMuFmsCollection is populated (as these are the clusters
153  // we reference).
154  setMuFmsPointParentClusters(muFms, fmscol);
155 }
156 
157 void StMuFmsUtil::fillFms(StFmsCollection* fmscol,StMuFmsCollection* muFms)
158 {
159  if(!muFms) return;
160  if(!fmscol) return;
161  fmscol->setFmsReconstructionFlag(muFms->fmsReconstructionFlag());
162  fillFmsHits(fmscol, muFms);
163  fillFmsPoints(fmscol, muFms);
164  fillFmsClusters(fmscol, muFms);
165  // Now we need to go back and set parent cluster of each point, now that the
166  // cluster list in StFmsCollection is populated (as these are the clusters
167  // we reference).
168  setFmsPointParentClusters(fmscol, muFms);
169 }
170 
172  StFmsCollection* fmscol) {
173  StSPtrVecFmsHit vecHit = fmscol->hits();
174  for(unsigned int i=0; i<fmscol->numberOfHits(); i++){
175  unsigned short detId = vecHit[i]->detectorId();
176  unsigned short ch = vecHit[i]->channel();
177  unsigned short crate = vecHit[i]->qtCrate();
178  unsigned short slot = vecHit[i]->qtSlot();
179  unsigned short qtch = vecHit[i]->qtChannel();
180  unsigned short adc = vecHit[i]->adc();
181  unsigned short tdc = vecHit[i]->tdc();
182  float ene = vecHit[i]->energy();
183  muFms->addHit();
184  StMuFmsHit* muFmsHit = muFms->getHit(i);
185  muFmsHit->setDetectorId(detId);
186  muFmsHit->setChannel(ch);
187  muFmsHit->setQtCrate(crate);
188  muFmsHit->setQtSlot(slot);
189  muFmsHit->setQtChannel(qtch);
190  muFmsHit->setAdc(adc);
191  muFmsHit->setTdc(tdc);
192  muFmsHit->setEnergy(ene);
193  }
194 }
195 
196 
197 
206  const StTriggerData& triggerData, const StFmsDbMaker* fmsDbMaker)
207 {
208 
209  // Loop over "electronics" channels and extract raw hit data from StTriggerData
210  for(unsigned short crate=1; crate<=4; crate++)
211  {
212  for(unsigned short slot=1; slot<=16; slot++)
213  {
214  for(unsigned short ch=0; ch<32; ch++)
215  {
216  unsigned short adc = triggerData.fmsADC(crate,slot-1,ch);
217  unsigned short tdc = triggerData.fmsTDC(crate,slot-1,ch);
218 
219  if (adc <= 0 && tdc <= 0) continue;
220 
221  StMuFmsHit* muFmsHit = muFmsCollection.addHit();
222 
223  muFmsHit->setQtCrate(crate);
224  muFmsHit->setQtSlot(slot);
225  muFmsHit->setQtChannel(ch);
226  muFmsHit->setAdc(adc);
227  muFmsHit->setTdc(tdc);
228 
229  // Can proceed with "physical" quantities only if fmsDbMaker is available
230  if ( !fmsDbMaker ) continue;
231 
232  int detectorId, channelId;
233 
234  fmsDbMaker->getReverseMap(crate, slot, ch, &detectorId, &channelId);
235 
236  // Cannot not proceed with invalid detector and channel IDs
237  if ( detectorId <= 0 && channelId <= 0) continue;
238 
239  float g1 = fmsDbMaker->getGain(detectorId, channelId);
240  float g2 = fmsDbMaker->getGainCorrection(detectorId, channelId);
241  float energy = adc*g1*g2;
242 
243  muFmsHit->setDetectorId(detectorId);
244  muFmsHit->setChannel(channelId);
245  muFmsHit->setEnergy(energy);
246  }
247  }
248  }
249 }
250 
251 
261 {
262  StTriggerData* triggerData = (StTriggerData*) muDst.event()->triggerData();
263  TClonesArray* muFmsHits = muDst.muFmsCollection() ? muDst.muFmsCollection()->getHitArray() : nullptr;
264 
265  const Int_t runNumber = muDst.event()->runId();
266 
267  if ( triggerData && muFmsHits && runNumber < 18000000 ){ // recover for run16 AuAu data
268  if ( muFmsHits->GetEntriesFast()>0 ) {
269  muFmsHits->Clear();
270  }
271  fillMuFmsHits(*muDst.muFmsCollection(), *triggerData, fmsDbMaker);
272  }
273 }
274 
275 
276 
277 void StMuFmsUtil::fillMuFmsClusters(StMuFmsCollection* muFms,
278  StFmsCollection* fmscol) {
279  // Fill clusters
280  for (unsigned i(0); i < fmscol->numberOfClusters(); ++i) {
281  const StFmsCluster* cluster = fmscol->clusters()[i];
282  muFms->addCluster(); // Expand StMuFmsCollection cluster array by 1
283  StMuFmsCluster* muCluster = muFms->getCluster(i);
284  muCluster->setDetectorId(cluster->detectorId());
285  muCluster->setCategory(cluster->category());
286  muCluster->setEnergy(cluster->energy());
287  muCluster->setX(cluster->x());
288  muCluster->setY(cluster->y());
289  muCluster->setSigmaMin(cluster->sigmaMin());
290  muCluster->setSigmaMax(cluster->sigmaMax());
291  muCluster->setChi2Ndf1Photon(cluster->chi2Ndf1Photon());
292  muCluster->setChi2Ndf2Photon(cluster->chi2Ndf2Photon());
293  muCluster->setId(cluster->id());
294 
295  // Propagate hits-in-cluster information
296  // Remember, clusters don't *own* hits, they just reference them.
297  // For each StFmsHit in the cluster, find the index of that hit in the main
298  // StFmsCollection hit array. Then add the StMuFmsHit (from the main
299  // StMuFmsCollection hit array) at the same index to the StMuFmsCluster.
300  StPtrVecFmsHitConstIterator hit; // Iterate over StFmsHits
301  for (hit = cluster->hits().begin(); hit != cluster->hits().end(); ++hit) {
302  const int index = findElementIndex(fmscol->hits(), *hit);
303  if (index != -1) {
304  muCluster->hits()->Add(muFms->getHit(index));
305  } // if
306  } // for
307  // Do the same procedure for photon-in-cluster information
308  StPtrVecFmsPointConstIterator p;
309  for (p = cluster->points().begin(); p != cluster->points().end(); ++p) {
310  const int index = findElementIndex(fmscol->points(), *p);
311  if (index != -1) {
312  muCluster->photons()->Add(muFms->getPoint(index));
313  } // if
314  } // for
315  } // for
316 }
317 
318 void StMuFmsUtil::fillMuFmsPoints(StMuFmsCollection* muFms,
319  StFmsCollection* fmscol) {
320  for (unsigned i(0); i < fmscol->numberOfPoints(); ++i) {
321  const StFmsPoint* point = fmscol->points()[i];
322  StMuFmsPoint* muPoint = muFms->addPoint();
323  if (point && muPoint) {
324  muPoint->set(*point);
325  } // if
326  } // for
327 }
328 
329 void StMuFmsUtil::setMuFmsPointParentClusters(StMuFmsCollection* muFms,
330  StFmsCollection* fmscol) {
331  LOG_DEBUG << "setMuFmsPointParentClusters" << endm;
332  for (unsigned i(0); i < muFms->numberOfPoints(); ++i) {
333  // Points and clusters in the StMuFmsCollection and StFmsCollection are in
334  // the same order, so we get the corresponding objects just by index
335  const StFmsPoint* point = fmscol->points().at(i);
336  if (!point) {
337  //LOG_WARN << Form(" No point") << endm;
338  continue;
339  } // if
340  // Find the index of the point's parent cluster in the main cluster list
341  const int index = findElementIndex(fmscol->clusters(), point->cluster());
342  // If we found it, set the StMuFmsPoint's parent cluster to be the
343  // corresponding cluster in the StMuFmsCollection
344  if (index != -1) {
345  StMuFmsPoint* muPoint = muFms->getPoint(i);
346  if (muPoint) {
347  muPoint->setCluster(muFms->getCluster(index));
348  } // if
349  } // if
350  } // for
351 }
352 
353 void StMuFmsUtil::fillFmsHits(StFmsCollection* fmscol,
354  StMuFmsCollection* muFms) {
355  // Using TIter to iterate is safe in the case of hits being NULL
356  TIter next(muFms->getHitArray());
357  StMuFmsHit* muHit(NULL);
358  while ((muHit = static_cast<StMuFmsHit*>(next()))) {
359  fmscol->addHit(new StFmsHit);
360  StFmsHit* hit = fmscol->hits().back();
361  hit->setDetectorId(muHit->detectorId());
362  hit->setChannel(muHit->channel());
363  hit->setQtCrate(muHit->qtCrate());
364  hit->setQtSlot(muHit->qtSlot());
365  hit->setQtChannel(muHit->qtChannel());
366  hit->setAdc(muHit->adc());
367  hit->setTdc(muHit->tdc());
368  hit->setEnergy(muHit->energy());
369  } // while
370 }
371 
372 void StMuFmsUtil::fillFmsClusters(StFmsCollection* fmscol,
373  StMuFmsCollection* muFms) {
374  // Using TIter to iterate is safe in the case of clusters being NULL
375  TIter next(muFms->getClusterArray());
376  StMuFmsCluster* muCluster(NULL);
377  while ((muCluster = static_cast<StMuFmsCluster*>(next()))) {
378  // Create an StFmsCluster from this StMuFmsCluster
379  fmscol->addCluster(new StFmsCluster);
380  StFmsCluster* cluster = fmscol->clusters().back();
381  cluster->setDetectorId(muCluster->detectorId());
382  cluster->setCategory(muCluster->category());
383  cluster->setNTowers(muCluster->hits()->GetEntries());
384  cluster->setEnergy(muCluster->energy());
385  cluster->setX(muCluster->x());
386  cluster->setY(muCluster->y());
387  cluster->setSigmaMin(muCluster->sigmaMin());
388  cluster->setSigmaMax(muCluster->sigmaMax());
389  cluster->setChi2Ndf1Photon(muCluster->chi2Ndf1Photon());
390  cluster->setChi2Ndf2Photon(muCluster->chi2Ndf2Photon());
391  cluster->setId(muCluster->id());
392 
393  //get pointers to fms points
394  TIter next(muCluster->photons());
395  StMuFmsPoint* muPoint(NULL);
396  while ((muPoint = static_cast<StMuFmsPoint*>(next()))) {
397  const int index = muFms->getPointArray()->IndexOf(muPoint);
398  if(index != -1) {
399  StFmsPoint* point = fmscol->points().at(index);
400  cluster->points().push_back(point);
401  }
402  }
405  } // while
406 }
407 
408 void StMuFmsUtil::fillFmsPoints(StFmsCollection* fmscol,
409  StMuFmsCollection* muFms) {
410  // Using TIter to iterate is safe in the case of points being NULL
411  TIter next(muFms->getPointArray());
412  StMuFmsPoint* muPoint(NULL);
413  while ((muPoint = static_cast<StMuFmsPoint*>(next()))) {
414  // Create an StFmsPoint from this StMuFmsPoint
415  fmscol->addPoint(new StFmsPoint);
416  StFmsPoint* point = fmscol->points().back();
417  float energy=muPoint->energy();
418  point->setDetectorId(muPoint->detectorId());
419  point->setEnergy(energy);
420  point->setX(muPoint->x());
421  point->setY(muPoint->y());
422  point->setId(muPoint->id());
423  point->setXYZ(muPoint->xyz());
424  //StThreeVectorF xyz(muPoint->x(),muPoint->y(),muPoint->z());
425  //StThreeVectorF p = xyz.unit() * energy;
426  //point->setFourMomentum(StLorentzVectorF(p, energy));
427  } // while
428 }
429 
430 void StMuFmsUtil::setFmsPointParentClusters(StFmsCollection* fmscol,
431  StMuFmsCollection* muFms) {
432  // Points and clusters in the StMuFmsCollection and StFmsCollection are in
433  // the same order, so we get the corresponding objects just by index
434  for (unsigned i(0); i < muFms->numberOfClusters(); ++i) {
435  const StMuFmsPoint* muPoint = muFms->getPoint(i);
436  if (!muPoint) {
437  continue;
438  } // if
439  const int index = muFms->getClusterArray()->IndexOf(muPoint->cluster());
440  if (index != -1) {
441  StFmsPoint* point = fmscol->points().at(i);
442  if (point) {
443  StFmsCluster* cluster=fmscol->clusters().at(index);
444  point->setCluster(cluster);
445  point->setParentClusterId(cluster->id());
446  point->setNParentClusterPhotons(cluster->nPhotons());
447  } // if
448  } // if
449  } // for
450 }
static StMuFmsCollection * muFmsCollection()
returns pointer to current StMuFmsCollection
Definition: StMuDst.h:391
Float_t getGainCorrection(Int_t detectorId, Int_t ch) const
get the gain for the channel
static void recoverMuFmsCollection(StMuDst &muDst, const StFmsDbMaker *=nullptr)
static void fillMuFmsHits(StMuFmsCollection &, const StTriggerData &, const StFmsDbMaker *=nullptr)
static StMuEvent * event()
returns pointer to current StMuEvent (class holding the event wise information, e.g. event number, run number)
Definition: StMuDst.h:320