StFms  0.0.0
FMS software in the STAR framework
StFmsPointMaker.cxx
Go to the documentation of this file.
1 // $Id$
2 //
3 // $Log$
13 
14 #include <TLorentzVector.h>
15 #include <TProcessID.h>
16 
17 #include "StRoot/St_base/StMessMgr.h"
18 #include "StRoot/StEvent/StEvent.h"
21 #include "StRoot/StEvent/StFmsHit.h"
23 #include "StRoot/StEvent/StRunInfo.h"
25 
30 
31 namespace {
32 // Calculate a 4 momentum from a direction/momentum vector and energy
33 // assuming zero mass i.e. E = p
34 TLorentzVector compute4Momentum(const TVector3& xyz, Double_t energy) {
35  TVector3 mom3 = xyz.Unit() * energy; // Momentum vector with m = 0
36  return TLorentzVector(mom3, energy);
37 }
38 } // unnamed namespace
39 
41  : StMaker(name), mFmsDbMaker(NULL), mObjectCount(0) { }
42 
44 
45 Int_t StFmsPointMaker::InitRun(Int_t runNumber) {
46  // Ensure we can access database information
47  mFmsDbMaker = static_cast<StFmsDbMaker*>(GetMaker("fmsDb"));
48  if (!mFmsDbMaker) {
49  return kStErr;
50  } // if
51  // Set up geometry, which stays constant for each run
53  // Return an error if geometry initialization fails
54  return kStErr;
55  } // if
56  return StMaker::InitRun(runNumber);
57 }
58 
60  // Cache the current count of referenced objects, as discussed here
61  // http://root.cern.ch/root/htmldoc/TRef.html
66  mObjectCount = TProcessID::GetObjectCount();
67  if (!populateTowerLists()) {
68  LOG_ERROR << "StFmsPointMaker::Make() - failed to initialise tower " <<
69  "lists for the event" << endm;
70  } // if
71  if (clusterEvent() == kStOk) {
72  return StMaker::Make();
73  } // if
74  return kStErr;
75 }
76 
77 void StFmsPointMaker::Clear(Option_t* option) {
78  mTowers.clear();
79  // Reset the count of referenced objects to the value before the previous
80  // call to Make(), in order prevent ever-growing table of objects
81  TProcessID::SetObjectCount(mObjectCount);
82  StMaker::Clear(option);
83 }
84 
86  StEvent* event = static_cast<StEvent*>(GetInputDS("StEvent"));
87  StFmsCollection* fms(NULL);
88  if (event) {
89  fms = event->fmsCollection();
90  } // if
91  if (!fms) {
92  LOG_ERROR << "StFmsPointMaker did not find "
93  << "an StFmsCollection in StEvent" << endm;
94  } // if
95  return fms;
96 }
97 
99  StFmsCollection* fmsCollection = getFmsCollection();
100  if (!fmsCollection) {
101  return kStErr;
102  } // if
103  for (auto i = mTowers.begin(); i != mTowers.end(); ++i) {
104  if (!validateTowerEnergySum(i->second)) {
105  continue; // To remove LED trails
106  } // if
107  clusterDetector(&i->second, i->first, fmsCollection);
108  } // for
109  return kStOk;
110 }
111 
112 /* Perform photon reconstruction on a single sub-detector */
113 int StFmsPointMaker::clusterDetector(TowerList* towers, const int detectorId,
114  StFmsCollection* fmsCollection) {
115  FMSCluster::StFmsEventClusterer clustering(&mGeometry, detectorId);
116  // Perform tower clustering, skip this subdetector if an error occurs
117  if (!clustering.cluster(towers)) { // Cluster tower list
118  return kStWarn;
119  } // if
120  // Saved cluster info into StFmsCluster
121  FMSCluster::ClusterList& clusters = clustering.clusters();
122  for (auto cluster = clusters.begin(); cluster != clusters.end(); ++cluster) {
123  processTowerCluster(cluster->get(), detectorId, fmsCollection);
124  } // for
125  return kStOk;
126 }
127 
129  // Attempt to get center-of-mass energy from StRunInfo.
130  // If it can't be accessed assume 500 GeV running.
131  float centerOfMassEnergy(500.);
132  const StEvent* event = static_cast<const StEvent*>(GetInputDS("StEvent"));
133  if (event) {
134  if (event->runInfo()) {
135  centerOfMassEnergy = event->runInfo()->centerOfMassEnergy();
136  } // if
137  } // if
138  // Sum tower energies and test validity of the sum
139  float Esum = 0.f;
140  typedef TowerList::const_iterator TowerIter;
141  for (TowerIter i = towers.begin(); i != towers.end(); ++i) {
142  Esum += i->hit()->energy();
143  } // for
144  return Esum >= 0.f && Esum <= centerOfMassEnergy;
145 }
146 
148  FMSCluster::StFmsTowerCluster* towerCluster,
149  const int detectorId,
150  StFmsCollection* fmsCollection) {
151  // Update the StFmsCluster object we want to store in StEvent with information
152  // not automatically propagated via StFmsTowerCluster
153  StFmsCluster* cluster = towerCluster->cluster();
154  // Skip clusters that don't have physically sensible coordinates
155  if (!(cluster->x() > 0. && cluster->y() > 0.)) {
156  return false;
157  } // if
158  cluster->setDetectorId(detectorId);
159  // Cluster id is id of the 1st photon, not necessarily the highest-E photon
160  cluster->setId(305 + 20 * detectorId + fmsCollection->numberOfPoints());
161  // Cluster locations are in column-row coordinates so convert to cm
163  cluster->x(), cluster->y(), detectorId);
164  cluster->setFourMomentum(compute4Momentum(xyz, cluster->energy()));
165  // Save photons reconstructed from this cluster
166  for (Int_t np = 0; np < cluster->nPhotons(); np++) {
167  StFmsPoint* point = makeFmsPoint(towerCluster->photons()[np], detectorId);
168  point->setDetectorId(detectorId);
169  point->setId(305 + 20 * detectorId + fmsCollection->numberOfPoints());
170  point->setParentClusterId(cluster->id());
171  point->setNParentClusterPhotons(cluster->nPhotons());
172  point->setCluster(cluster);
173  // Add it to both the StFmsCollection and StFmsCluster
174  // StFmsCollection owns the pointer, the cluster merely references it
175  fmsCollection->points().push_back(point);
176  cluster->points().push_back(point);
177  } // for
178  // Save the tower hit info.
179  typedef std::list<FMSCluster::StFmsTower*>::const_iterator TowerIter;
180  std::list<FMSCluster::StFmsTower*>& towers = towerCluster->towers();
181  for (TowerIter i = towers.begin(); i != towers.end(); ++i) {
182  if ((*i)->hit()->adc() >= 1) { // Min ADC = 1
183  cluster->hits().push_back((*i)->hit());
184  } // if
185  } // for
186  // Release StFmsCluster held by towerCluster to pass ownership to
187  // StFmsCollection (and hence StEvent).
188  fmsCollection->addCluster(towerCluster->release());
189  return true;
190 }
191 
193  const FMSCluster::StFmsFittedPhoton& photon, const int detectorId) {
194  StFmsPoint* point = new StFmsPoint;
195  point->setEnergy(photon.energy);
196  // Calculate photon 4 momentum
197  // StFmsFittedPhoton position is in detector-local (x, y) cm coordinates
198  // Convert to global STAR coordinates for StFmsPoint
199  TVector3 xyz = mGeometry.localToGlobalCoordinates(
200  photon.xPos, photon.yPos, detectorId);
201  point->setX(xyz.x());
202  point->setY(xyz.y());
203  point->setFourMomentum(compute4Momentum(xyz, point->energy()));
204  return point;
205 }
206 
208  StFmsCollection* fmsCollection = getFmsCollection();
209  if (!fmsCollection) {
210  return false;
211  } // if
212  StSPtrVecFmsHit& hits = fmsCollection->hits();
213  for (StSPtrVecFmsHitIterator i = hits.begin(); i != hits.end(); ++i) {
214  StFmsHit* hit = *i;
215  const int detector = hit->detectorId();
216  const int row = mFmsDbMaker->getRowNumber(detector, hit->channel());
217  const int column = mFmsDbMaker->getColumnNumber(detector, hit->channel());
218  if (!isValidChannel(detector, row, column)) {
219  continue;
220  } // if
221  if (hit->adc() > 0) {
222  // Insert a tower list for this detector ID if there isn't one already
223  // This method is faster than using find() followed by insert()
224  // http://stackoverflow.com/questions/97050/stdmap-insert-or-stdmap-find
225  TowerMap::iterator low = mTowers.lower_bound(detector);
226  if (low == mTowers.end() || mTowers.key_comp()(detector, low->first)) {
227  mTowers.insert(TowerMap::value_type(detector, TowerList()));
228  } // if
229  FMSCluster::StFmsTower tower(hit);
230  // Ensure tower information is valid before adding
231  if (tower.initialize(mFmsDbMaker)) {
232  mTowers[detector].push_back(tower);
233  } // if
234  } // if
235  } // for
236  return true;
237 }
238 
239 /* Test channel validity by detector and row, column in the range [1, N] */
240 bool StFmsPointMaker::isValidChannel(int detector, int row, int column) {
241  // Simplest check first, test lower bounds are valid
242  if (row < 1 || column < 1) {
243  return false;
244  } // if
245  // Omit gaps in the detector
246  switch (detector) {
247  case FMSCluster::kFmsNorthLarge: // Deliberate fall-through
248  case FMSCluster::kFmsSouthLarge: // Large-cell FMS sub-detector
249  if (fabs(row - 17.5) < 8 && column < 9) { // Central hole
250  return false;
251  } // if
252  // This cuts off a 7x7 triangle from the corners
253  if (fabs(17.5 - row) + column > 27.) {
254  return false;
255  } // if
256  break;
257  case FMSCluster::kFmsNorthSmall: // Deliberate fall-through
258  case FMSCluster::kFmsSouthSmall: // Small-cell FMS sub-detector
259  if (fabs(row - 12.5) < 5 && column < 6) { // Central hole
260  return false;
261  } // if
262  break;
263  default: // Don't currently support non-FMS sub-detectors
264  return false;
265  } // switch (detector)
266  // Test row and column number against the numbers stored in the database for
267  // this detector. Leave this to last to avoid database calls when possible.
268  // Also serves as a double-check on detector, as the database will
269  // return -1 for both numbers in case of an invalid detector number.
270  if (mFmsDbMaker) {
271  const int nRows = mFmsDbMaker->nRow(detector);
272  if (nRows < 0 || row > nRows) {
273  return false;
274  } // if
275  const int nColumns = mFmsDbMaker->nColumn(detector);
276  if (nColumns < 0 || column > nColumns) {
277  return false;
278  } // if
279  } // if
280  return true;
281 }
bool isValidChannel(int detector, int row, int col)
bool validateTowerEnergySum(const TowerList &towers) const
Bool_t initialize(StFmsDbMaker *fmsDbMaker)
bool processTowerCluster(FMSCluster::StFmsTowerCluster *towerCluster, int detectorId, StFmsCollection *fmsCollection)
void setY(Float_t ypos)
Definition: StFmsPoint.h:60
Float_t x() const
Definition: StFmsCluster.h:59
StFmsPoint * makeFmsPoint(const FMSCluster::StFmsFittedPhoton &photon, int detectorId)
Int_t nColumn(Int_t detectorId)
number of rows
void setNParentClusterPhotons(Int_t nclph)
Definition: StFmsPoint.h:68
Int_t InitRun(Int_t runNumber)
void setCluster(StFmsCluster *cluster)
Definition: StFmsPoint.h:64
void Clear(Option_t *option="")
void setX(Float_t xpos)
Definition: StFmsPoint.h:58
Declaration of StFmsCluster, a group of adjacent FMS hits.
void setFourMomentum(const TLorentzVector &p4)
Definition: StFmsPoint.h:70
Float_t xPos
Fitted (relative) x-position.
void setParentClusterId(Int_t cluid)
Definition: StFmsPoint.h:66
int mObjectCount
Object count in event for use with TRef.
Declaration of StFmsTower, a simple FMS tower wrapper.
Int_t getColumnNumber(Int_t detectorId, Int_t ch)
get the row number for the channel
void setId(Int_t phid)
Definition: StFmsPoint.h:62
Float_t energy
Fitted energy.
Declaration of StFmsEventClusterer, manager class for clustering.
Bool_t initialize(StFmsDbMaker *database)
Definition: StFmsTower.cxx:27
TowerMap mTowers
One for each sub-detector, keyed by detector ID.
void setDetectorId(UShort_t detector)
Definition: StFmsPoint.h:54
StFmsDbMaker * mFmsDbMaker
Access to FMS database information.
Declaration of StFmsTowerCluster, a cluster of FMS towers.
Declaration of StFmsPointMaker, the FMS cluster/photon maker.
Int_t getRowNumber(Int_t detectorId, Int_t ch)
maximum number of channels
StSPtrVecFmsPoint & points()
Int_t nRow(Int_t detectorId)
type of the detector
void addCluster(StFmsCluster *)
StFmsFittedPhoton * photons()
Declaration of StFmsPoint, the StEvent FMS photon structure.
Int_t nPhotons() const
Definition: StFmsCluster.h:55
StPtrVecFmsPoint & points()
Definition: StFmsCluster.h:105
void setEnergy(Float_t energy)
Definition: StFmsPoint.h:56
Declaration of StFmsFittedPhoton, a photon fitted to an FMS cluster.
void setDetectorId(UShort_t detector)
Definition: StFmsCluster.h:75
std::list< std::unique_ptr< StFmsTowerCluster > > ClusterList
void setId(Float_t cluid)
Definition: StFmsCluster.h:97
StSPtrVecFmsHit & hits()
TVector3 localToGlobalCoordinates(Double_t x, Double_t y, Int_t detectorId) const
StPtrVecFmsHit & hits()
Definition: StFmsCluster.h:101
std::vector< FMSCluster::StFmsTower > TowerList
int clusterDetector(TowerList *towers, int detectorId, StFmsCollection *fmsCollection)
StFmsPointMaker(const char *name="StFmsPointMaker")
Float_t y() const
Definition: StFmsCluster.h:61
Float_t yPos
Fitted (relative) y-position.
unsigned int numberOfPoints() const
Bool_t cluster(std::vector< FMSCluster::StFmsTower > *towers)
TVector3 columnRowToGlobalCoordinates(Double_t column, Double_t row, Int_t detectorId) const
Float_t energy() const
Definition: StFmsPoint.h:36
StFmsCollection * getFmsCollection()
void setFourMomentum(TLorentzVector p4)
Definition: StFmsCluster.h:99
FMSCluster::StFmsGeometry mGeometry
Access to current FMS geometry.
Float_t energy() const
Definition: StFmsCluster.h:57
Int_t id() const
Definition: StFmsCluster.h:71