StFms  0.0.0
FMS software in the STAR framework
StFmsGeometry.cxx
Go to the documentation of this file.
1 // $Id$
2 //
3 // $Log$
14 
15 #include "St_base/StMessMgr.h"
16 #include "StChain/StMaker.h"
18 #include "tables/St_fmsDetectorPosition_Table.h"
19 
20 namespace FMSCluster {
22 
24 
26  // If no FMS database was provided, attempt to locate on in the current chain,
27  // if one exists
28  if (!fmsDbMaker) {
29  StMaker* chain = StMaker::GetChain();
30  if (chain) {
31  fmsDbMaker = static_cast<StFmsDbMaker*>(chain->GetMaker("fmsDb"));
32  } // if
33  } // if
34  // Bail out if no FMS database can be located
35  if (!fmsDbMaker) {
36  LOG_ERROR << "StFmsGeometry unable to locate an StFmsDbMaker - "
37  << "geometry will not be initialised!" << endm;
38  return false;
39  } // if
40  const fmsDetectorPosition_st* dbgeom = fmsDbMaker->DetectorPosition();
41  if (dbgeom) {
42  // Detector IDs count [0, N), so number of detectors is one greater than max
43  const int nDetectors = fmsDbMaker->maxDetectorId() + 1;
44  for (int i(0); i < nDetectors; ++i) {
45  // The first detector has ID = 0. Subsequent detectors with no data will
46  // also have detector ID = 0. This won't overwrite the first entry, as
47  // map::insert won't insert if there is already an entry with that key.
48  mPositions.insert(std::make_pair(dbgeom[i].detectorId, &dbgeom[i]));
49  } // for
50  return true;
51  } // if
52  return false;
53 }
54 
55 Float_t StFmsGeometry::xOffset(Int_t detectorId) const {
56  const fmsDetectorPosition_st* geometry = find(detectorId);
57  if (geometry) {
58  return geometry->xoffset;
59  } // if
60  return 0.;
61 }
62 
63 Float_t StFmsGeometry::yOffset(Int_t detectorId) const {
64  const fmsDetectorPosition_st* geometry = find(detectorId);
65  if (geometry) {
66  return geometry->yoffset;
67  } // if
68  return 0.;
69 }
70 
71 Float_t StFmsGeometry::z(Int_t detectorId) const {
72  const fmsDetectorPosition_st* geometry = find(detectorId);
73  if (geometry) {
74  return geometry->zoffset;
75  } // if
76  return 0.;
77 }
78 
79 std::vector<Float_t> StFmsGeometry::towerWidths(Int_t detectorId) const {
80  // I don't like this implementation, returning a pointer to access two floats
81  // It relies on the data being aligned OK and seems dangerous. We should add
82  // a more robust solution e.g. return a pair or 2-element vector.
83  const fmsDetectorPosition_st* geometry = find(detectorId);
84  std::vector<Float_t> widths(2, 0.);
85  if (geometry) {
86  widths.at(0) = geometry->xwidth;
87  widths.at(1) = geometry->ywidth;
88  } // if
89  return widths;
90 }
91 
92 const fmsDetectorPosition_st* StFmsGeometry::find(Int_t detectorId) const {
93  const fmsDetectorPosition_st* positions(NULL);
94  Table::const_iterator entry = mPositions.find(detectorId);
95  if (entry != mPositions.end()) {
96  positions = entry->second;
97  } // if
98  return positions;
99 }
100 
101 TVector3 StFmsGeometry::localToGlobalCoordinates(Double_t x, Double_t y,
102  Int_t detectorId) const {
103  TVector3 global(0., 0., 0.);
104  const fmsDetectorPosition_st* detector = find(detectorId);
105  if (!detector) {
106  return global; // Uninitialized StFmsGeometry object or invalid detector ID
107  } // if
108  if (isNorth(detectorId)) {
109  // Local coordinates are always positive numbers, but north
110  // detectors have negative global STAR coordinates hence "minus column".
111  // The offset is already stored in the database as a negative value.
112  global.SetX(detector->xoffset - x);
113  } else {
114  global.SetX(detector->xoffset + x);
115  } // if
116  // y offset gives the *top* of the detector in the global system
117  // y offset is half the vertical height, as the detectors are centered about
118  // y = 0 i.e. y offset = nrows / 2 * row height
119  // Note the y coordinate has 0 at the *bottom*, which corresponds to
120  // maximally negative in the global system.
121  global.SetY(y - detector->yoffset);
122  global.SetZ(detector->zoffset); // Detector face
123  return global;
124 }
125 
127  Double_t row,
128  Int_t detectorId) const {
129  const fmsDetectorPosition_st* detector = find(detectorId);
130  if (detector) {
131  // Multiply column and row by tower widths to convert to cm then just call
132  // the normal local-to-global conversion
133  return localToGlobalCoordinates(column * detector->xwidth,
134  row * detector->ywidth, detectorId);
135  } // if
136  return TVector3(0., 0., 0.); // In case of no detector information
137 }
138 
139 Bool_t StFmsGeometry::isNorth(Int_t detectorId) {
140  switch (detectorId) {
141  case kFpdNorth: // Deliberate fall-through
142  case kFpdNorthPreshower: // Deliberate fall-through
143  case kFpdNorthShowerMaxVertical: // Deliberate fall-through
144  case kFpdNorthShowerMaxHorizontal: // Deliberate fall-through
145  case kFmsNorthLarge: // Deliberate fall-through
146  case kFmsNorthSmall: // Deliberate fall-through
147  case kFhcNorth:
148  return true;
149  default:
150  return false;
151  } // switch
152 }
153 } // namespace FMSCluster
Bool_t initialize(StFmsDbMaker *fmsDbMaker)
fmsDetectorPosition_st * DetectorPosition()
getting the whole table
Declaration of StFmsGeometry, an FMS database geometry interface.
Table mPositions
Detector ID: position information pairs.
static Bool_t isNorth(Int_t detectorId)
Float_t yOffset(Int_t detectorId) const
const fmsDetectorPosition_st * find(Int_t detectorId) const
Float_t z(Int_t detectorId) const
TVector3 localToGlobalCoordinates(Double_t x, Double_t y, Int_t detectorId) const
std::vector< Float_t > towerWidths(Int_t detectorId) const
TVector3 columnRowToGlobalCoordinates(Double_t column, Double_t row, Int_t detectorId) const
Int_t maxDetectorId()
Utility functions related to FMS ChannelGeometry.
Float_t xOffset(Int_t detectorId) const