Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CylinderGeom_Mvtx.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CylinderGeom_Mvtx.cc
1 #include "CylinderGeom_Mvtx.h"
2 
3 #include "SegmentationAlpide.h"
4 
6 
7 #include <TRotation.h>
8 #include <TVector3.h>
9 
10 #include <cmath>
11 #include <ostream> // for operator<<, basic_ostream::operator<<, basic_...
12 
13 using namespace std;
15 
17  int in_layer,
18  int in_N_staves,
19  double in_layer_nominal_radius,
20  double in_phistep,
21  double in_phitilt,
22  double in_phi0)
23  : layer(in_layer)
24  , N_staves(in_N_staves)
25  , N_half_staves(0)
26  , layer_radius(in_layer_nominal_radius)
27  , stave_phi_step(in_phistep)
28  , stave_phi_tilt(in_phitilt)
29  , stave_phi_0(in_phi0)
30  , pixel_x(Segmentation::PitchRow)
31  , pixel_z(Segmentation::PitchCol)
32  , pixel_thickness(Segmentation::SensorLayerThickness)
33 {
34  // Note that stave is centered at origin with normal to face of sensor pointing in +y direction
35  // Units here are cm, same as in the gdml file
36 
37  // for all layers
38  double loc_sensor_in_chip_data[3] = {0.058128, -0.0005, 0.0}; // mvtx_stave_v1.gdml
39 
40  for (int i = 0; i < 3; i++)
41  loc_sensor_in_chip[i] = loc_sensor_in_chip_data[i];
42 
43  // inner barrel layers stave construction
44  //==========================
45  // from mvtx_stave_v1.gdml
46  // chip 0 is the closet to connectors (-Z)
47  double inner_loc_chip_in_module_data[9][3] = {
48  {0.0275, -0.02075, -12.060},
49  {0.0275, -0.02075, -9.0450},
50  {0.0275, -0.02075, -6.0300},
51  {0.0275, -0.02075, -3.0150},
52  {0.0275, -0.02075, 0.0},
53  {0.0275, -0.02075, 3.0150},
54  {0.0275, -0.02075, 6.0300},
55  {0.0275, -0.02075, 9.0450},
56  {0.0275, -0.02075, 12.060}};
57 
58  double inner_loc_module_in_halfstave_data[3] = {0.0, 0.0, 0.0}; // only one module
59 
60  double inner_loc_halfstave_in_stave_data[3] = {-0.0275, 0.01825, 0.0};
61 
62  for (int i = 0; i < 3; i++)
63  {
64  inner_loc_module_in_halfstave[i] = inner_loc_module_in_halfstave_data[i];
65  inner_loc_halfstave_in_stave[i] = inner_loc_halfstave_in_stave_data[i];
66  for (int j = 0; j < 9; j++)
67  {
68  inner_loc_chip_in_module[j][i] = inner_loc_chip_in_module_data[j][i];
69  }
70  }
71 
72  return;
73 }
74 
75 TVector3
78  TVector3 world)
79 {
80  Acts::Vector3 global;
81  global(0) = world[0];
82  global(1) = world[1];
83  global(2) = world[2];
84 
85  global *= Acts::UnitConstants::cm;
86 
87  Acts::Vector3 local = surface->transform(tGeometry->geometry().getGeoContext()).inverse() * global;
88  local /= Acts::UnitConstants::cm;
89 
91  return TVector3(local(0), local(2) * -1, local(1));
92 }
93 
94 void
95 CylinderGeom_Mvtx::get_sensor_indices_from_world_coords(std::vector<double> &world, unsigned int &stave_index, unsigned int &chip_index)
96 {
97  // stave number is fom phi
98  double phi = atan2(world[1], world[0]);
99  if(phi < 0) phi += 2.0*M_PI;
100  //int stave_tmp = (int) ( (phi - stave_phi_0) / stave_phi_step );
101  int stave_tmp = round( (phi - stave_phi_0) / stave_phi_step );
102  //std::cout << " phi " << phi << " stave_phi_0 " << stave_phi_0 << " stave_phi_step " << stave_phi_step << " stave_tmp " << stave_tmp << std::endl;
103 
104  // sensor is from z
105  double chip_delta_z = (inner_loc_chip_in_module[8][2] - inner_loc_chip_in_module[0][2]) / 8.0;
106  //int chip_tmp = (int) (world[2]/chip_delta_z) + 4; // 0-9
107  int chip_tmp = round(world[2]/chip_delta_z) + 4; // 0-9
108  //std::cout << " z " << world[2] << " chip_delta_z " << chip_delta_z << " chip_tmp " << chip_tmp << endl;
109 
110  stave_index = stave_tmp;
111  chip_index = chip_tmp;
112 }
113 
114 TVector3
116 {
117  Acts::Vector2 actslocal;
118  actslocal(0) = local.X();
119  actslocal(1) = local.Y();
120  actslocal *= Acts::UnitConstants::cm;
121 
122  Acts::Vector3 global;
124  global = surface->localToGlobal(tGeometry->geometry().getGeoContext(),
125  actslocal, Acts::Vector3(1,1,1));
126  global /= Acts::UnitConstants::cm;
127 
128  TVector3 res;
129  res[0] = global(0);
130  res[1] = global(1);
131  res[2] = global(2);
132 
133  return res;
134 }
135 
136 TVector3
138 {
139  Acts::Vector3 loc(local.x(), local.y(), local.z());
141 
142  Acts::Vector3 glob = surface->transform(tGeometry->geometry().getGeoContext())*loc;
143  glob /= Acts::UnitConstants::cm;
144 
145  return TVector3(glob(0), glob(1), glob(2));
146 
147 }
148 bool CylinderGeom_Mvtx::get_pixel_from_local_coords(TVector3 sensor_local, int& iRow, int& iCol)
149 {
150  //YCM (2020-01-02): It seems that due some round issues, local coords of hits at the edge of the sensor volume
151  // are out by some fraction of microns from the ActiveMatrix. Making a safety check inside 0.1 um
152  double EPS = 5e-6;
153  if ( fabs(fabs(sensor_local.X()) - SegmentationAlpide::ActiveMatrixSizeRows/2.f) < EPS ){
154  //cout << " Adjusting X, before X= " << sensor_local.X() << endl;
155  sensor_local.SetX( ((sensor_local.X() < 0 ) ? -1 : 1) * (SegmentationAlpide::ActiveMatrixSizeRows/2.f - EPS) );
156  //cout << " Adjusting X, after X= " << sensor_local.X() << endl;
157  }
158  if ( fabs(fabs(sensor_local.Z()) - SegmentationAlpide::ActiveMatrixSizeCols/2.f) < EPS ){
159  //cout << " Adjusting Z, before Z= " << sensor_local.Z() << endl;
160  sensor_local.SetZ( ((sensor_local.Z() < 0 ) ? -1 : 1) * (SegmentationAlpide::ActiveMatrixSizeCols/2.f - EPS) );
161  //cout << " Adjusting Z, after Z= " << sensor_local.Z() << endl;
162  }
163  // YCM (2020-01-02): go from sensor to chip local coords
164  TVector3 in_chip = sensor_local;
166  in_chip += tr;
167 
168  return SegmentationAlpide::localToDetector(in_chip.X(), in_chip.Z(), iRow, iCol);
169 }
170 
172 {
173  int Ngridx, Ngridz;
174  bool px_in = get_pixel_from_local_coords(sensor_local, Ngridx, Ngridz);
175  if (!px_in)
176  cout << PHWHERE
177  << " Pixel is out sensor. ("
178  << sensor_local.X() << ", "
179  << sensor_local.Y() << ", "
180  << sensor_local.Z() << ")."
181  << endl;
182 
183  if (Ngridx < 0 || Ngridx >= get_NX() || Ngridz < 0 || Ngridz >= get_NZ())
184  cout << PHWHERE << "Wrong pixel value X= " << Ngridx << " and Z= " << Ngridz << endl;
185 
186  // numbering starts at zero
187  return Ngridx + Ngridz * get_NX();
188 }
189 
191 {
192  int Ngridz = NXZ / get_NX();
193  int Ngridx = NXZ % get_NX();
194 
195  return get_local_coords_from_pixel(Ngridx, Ngridz);
196 }
197 
199 {
200  TVector3 local;
201  bool check = SegmentationAlpide::detectorToLocal((float)iRow, (float)iCol, local);
202  if ( ! check)
203  cout << PHWHERE << "Pixel coord ( " << iRow << ", " << iCol <<" )" << "out of range" << endl;
204  // Transform location in chip to location in sensors
205  TVector3 trChipToSens(loc_sensor_in_chip[0],
207  loc_sensor_in_chip[2]);
208  local -= trChipToSens;
209  return local;
210 }
211 
212 void CylinderGeom_Mvtx::identify(std::ostream& os) const
213 {
214  os << "CylinderGeom_Mvtx: layer: " << layer
215  << ", layer_radius: " << layer_radius
216  << ", N_staves in layer: " << N_staves
217  << ", N_half_staves in layer: " << N_half_staves
218  << ", pixel_x: " << pixel_x
219  << ", pixel_z: " << pixel_z
220  << ", pixel_thickness: " << pixel_thickness
221  << endl;
222  return;
223 }
224 
226 {
227  TVector2 sensor_local(0.0, 0.0);
228 
229  TVector3 sensor_world = get_world_from_local_coords(surface, tGeometry, sensor_local);
230 
231  location[0] = sensor_world.X();
232  location[1] = sensor_world.Y();
233  location[2] = sensor_world.Z();
234 
235  return;
236 }
237 
238 // hide SegmentationAlpide include from root5 rootcint (rootcling is fine)
240 {
242 }
243 
245 {
247 }
248 
250 {
251  return NXZ % get_NX();
252 }
253 
255 {
256  return NXZ / get_NX();
257 }
258 
259 int CylinderGeom_Mvtx::get_pixel_number_from_xbin_zbin(int xbin, int zbin) // obsolete
260 {
261  return xbin + zbin * get_NX();
262 }