LDMX Software
ldmx::EcalGeometry Class Reference

Translation between real-space positions and cell IDs within the ECal. More...

#include <EcalGeometry.h>

Public Member Functions

virtual ~EcalGeometry ()=default
 Class destructor.
 
EcalID getID (double x, double y, double z, bool fallible=false) const
 Get a cell's ID number from its position.
 
EcalID getID (double x, double y, int layer_id, bool fallible=false) const
 Get a cell's ID from its x,y global position and layer number.
 
EcalID getID (double x, double y, int layer_id, int module_id, bool fallible=false) const
 Get a cell's ID from its x,y global position and layer/module numbers as deduced from GDML copy numbers.
 
std::tuple< double, double, double > getPosition (EcalID id) const
 Get a cell's position from its ID number.
 
std::pair< double, double > getPositionInModule (int cell_id) const
 Get a cell's position within a module.
 
double getZPosition (int layer) const
 Get the z-coordinate given the layer id.
 
double getEcalFrontZ () const
 Get the z-coordinate of the Ecal face.
 
int getNumLayers () const
 Get the number of layers in the Ecal Geometry.
 
int getNumModulesPerLayer () const
 Get the number of modules in the Ecal flower.
 
int getNumCellsPerModule () const
 Get the number of cells in each module of the Ecal Geometry.
 
std::vector< EcalID > getNN (EcalID id) const
 Get the Nearest Neighbors of the input ID.
 
bool isNN (EcalID centroid, EcalID probe) const
 Check if the probe id is one of the nearest neightbors of the centroid id.
 
std::vector< EcalID > getNNN (EcalID id) const
 Get the Next-to-Nearest Neighbors of the input ID.
 
bool isNNN (EcalID centroid, EcalID probe) const
 Check if the probe id is one of the next-to-nearest neightbors of the centroid id.
 
double getModuleMinR () const
 Get the center-to-flat radius of the module hexagons.
 
double getModuleMaxR () const
 Get the center-to-corner radius of the module hexagons.
 
double getCellMinR () const
 Get the center-to-flat radius of the cell hexagons.
 
double getCellMaxR () const
 Get the center-to-corner radius of the cell hexagons.
 
TH2Poly * getCellPolyMap () const
 Get a reference to the TH2Poly used for Cell IDs.
 
- Public Member Functions inherited from framework::ConditionsObject
 ConditionsObject (const std::string &name)
 Class constructor.
 
virtual ~ConditionsObject ()
 Destructor.
 
std::string getName () const
 Get the name of this object.
 

Static Public Member Functions

static EcalGeometry * debugMake (const framework::config::Parameters &p)
 

Static Public Attributes

static constexpr const char * CONDITIONS_OBJECT_NAME {"EcalGeometry"}
 

Private Member Functions

 EcalGeometry (const framework::config::Parameters &ps)
 Class constructor, for use only by the provider.
 
void buildLayerMap ()
 Constructs the positions of the layers in world coordinates.
 
void buildModuleMap ()
 Constructs the positions of the seven modules (moduleID) relative to the ecal center.
 
void buildCellMap ()
 Constructs the flat-bottomed hexagonal grid (cellID) of corner-down hexagonal cells.
 
void buildCellModuleMap ()
 Constructs the positions of all the cells in a layer relative to the ecal center.
 
void buildNeighborMaps ()
 Construts NNMap and NNNMap.
 
double distanceToEdge (EcalID id) const
 Distance to module edge, and whether cell is on edge of module.
 
bool isEdgeCell (EcalID cellModuleID) const
 Check if input cell is on the edge of a module.
 
bool isInside (double normX, double normY) const
 Determines if point (x,y), already normed to max hexagon radius, lies within a hexagon.
 

Private Attributes

double gap_
 Gap between module flat sides [mm].
 
double cell_r_min_ {0}
 Center-to-Flat Radius of cell hexagon [mm].
 
double module_r_min_ {0}
 Center-to-Flat Radius of module hexagon [mm].
 
double cell_r_max_ {0}
 Center-to-Corner Radius of cell hexagon [mm].
 
double module_r_max_ {0}
 Center-to-Corner Radius of module hexagon [mm].
 
bool corners_side_up_
 indicator of geometry orientation if true, flower shape's corners side (ie: side with two modules) is at the top
 
double layer_shift_x_
 shift of layers in the x-direction [mm]
 
double layer_shift_y_
 shift of layers in the y-direction [mm]
 
bool layer_shift_odd_
 shift odd layers
 
bool layer_shift_odd_bilayer_
 shift odd bi layers
 
double ecal_center_x_
 World x of the layer centers [mm].
 
double ecal_center_y_
 World y of the layer centers [mm].
 
bool flip_y_
 ECal y axis points along world -y, e.g. rotated about x by 180 deg.
 
double si_thickness_
 Thickness of the Si sensitive layer [mm].
 
double n_cell_r_height_ {0}
 Number of cell center-to-corner radii (one side of the cell) from the bottom to the top of the module.
 
double ecal_front_z_ {0}
 Front of ECal relative to world geometry [mm].
 
std::vector< double > layer_z_positions_
 The layer Z postions are with respect to the front of the ECal [mm].
 
std::map< int, std::tuple< double, double, double > > layer_pos_xy_
 Position of layer centers in world coordinates (uses layer ID as key)
 
std::map< int, std::pair< double, double > > module_pos_xy_
 Postion of module centers relative to the center of the layer in world coordinates.
 
std::map< int, std::pair< double, double > > cell_pos_in_module_
 Position of cell centers relative to center of module in p,q space.
 
std::map< EcalID, std::pair< double, double > > cell_pos_in_layer_
 Position of cell centers relative to center of layer in world coordinates.
 
std::map< EcalID, std::tuple< double, double, double > > cell_global_pos_
 Position of cell centers relative to world geometry.
 
std::map< EcalID, std::vector< EcalID > > nn_map_
 Map of cell ID to neighboring cells.
 
std::map< EcalID, std::vector< EcalID > > nnn_map_
 Map of cell ID to neighbors of neighbor cells.
 
TH2Poly cell_id_in_module_
 Honeycomb Binning from ROOT.
 

Friends

class ecal::EcalGeometryProvider
 

Detailed Description

Translation between real-space positions and cell IDs within the ECal.

This is the object that does the extra geometry not implemented in the gdml. In order to save time during the simulation, the individual cells in the readout hexagons are not constructed individually in Geant4. This means we have to have a translation between position and cell ID which is accomplished by this class.

Moreover, downstream processors sometimes need access to the cell position when they only know the cell ID. This class can also do this conversion.

ORIENTATION ASSUMPTIONS:

  • modules and cells have opposite orientation. i.e. if modules are corner-side down, then cells are flat-side down.

SOME GEOMETRY:

  • hexagons have two radii:
    • r (half of flat-to-flat width) and R (half of corner-to-corner width).
    • r = (sqrt(3)/2)R and s = R, where s is the length of an edge.
  • for seven ecal modules oriented flat-side-down, maximum x and y extents are:
    • deltaY = 6r' + 2g = 3sqrt(3)R' + 2g
    • deltaX = 4R' + s' + 2g/cos(30 deg) = 5R' + 4g/sqrt(3)
    • where g is uniform gap width between modules, and primed variables correspond to modules.

Since the whole hexagon flower has changed orientation since previous versions of the detector (which we wish to still support), I am defining an extra set of axes with respect to the flower itself. Below I have drawn the ECal hexagon i flower and defined two axes: p (through the "pointy sides") and q (through the "flat sides"). In some versions of the ECal flower, p == x and q == y while in others p == -y and q == x.

     ^
     | q axis
    __
 __/1 \__
/6 \__/2 \
\__/0 \__/ __ p axis __>
/5 \__/3 \
\__/4 \__/
   \__/

Now we can define a process for determining the cellular IDs.

  • Define a mapping of cell IDs within a module (center of module is the origin)
    • Use TH2Poly to do the Hexagon tiling in p,q space
  • Define center of modules with respect to center of layer in p,q space
    • currently this is assumed to be the same within all layers BUT will depend on geometry parameters like the gap between modules
  • Define center of layers (INCLUDING x,y position)
    • some versions of the geometry shift layers off the z axis to cover the gaps between modules
    • Will need to handle the conversion between x,y and p,q axes

THIS GRID:

  • column-to-column distance in a grid such as ours is 2r = sqrt(3)R.
  • row-to-row distance is 1.5R (easy to observe that twice that distance = 3R)

The cell radius is calculated from the total number of center-to-corner cell radii that span the module height. This count can have fractional counts to account for the fractions of cell radii at the module edges.

Definition at line 101 of file EcalGeometry.h.

Constructor & Destructor Documentation

◆ ~EcalGeometry()

virtual ldmx::EcalGeometry::~EcalGeometry ( )
virtualdefault

Class destructor.

Does nothing because the member variables clean up themselves.

◆ EcalGeometry()

ldmx::EcalGeometry::EcalGeometry ( const framework::config::Parameters & ps)
private

Class constructor, for use only by the provider.

Parameters
psParameters to configure the EcalGeometry

Definition at line 49 of file EcalGeometry.cxx.

50 : framework::ConditionsObject(EcalGeometry::CONDITIONS_OBJECT_NAME) {
51 layer_z_positions_ = ps.get<std::vector<double>>("layer_z_positions");
52 ecal_front_z_ = ps.get<double>("ecal_front_z");
53 module_r_min_ = ps.get<double>("module_min_r");
54 gap_ = ps.get<double>("gap");
55 n_cell_r_height_ = ps.get<double>("n_cell_r_height");
56 corners_side_up_ = ps.get<bool>("corners_side_up");
57 layer_shift_x_ = ps.get<double>("layer_shift_x");
58 layer_shift_y_ = ps.get<double>("layer_shift_y");
59 layer_shift_odd_ = ps.get<bool>("layer_shift_odd");
60 layer_shift_odd_bilayer_ = ps.get<bool>("layer_shift_odd_bilayer");
61 ecal_center_x_ = ps.get<double>("ecal_center_x", 0.);
62 ecal_center_y_ = ps.get<double>("ecal_center_y", 0.);
63 flip_y_ = ps.get<bool>("flip_y", false);
64 si_thickness_ = ps.get<double>("si_thickness");
65
67 EXCEPTION_RAISE("BadConf",
68 "Cannot shift both odd sensitive layers and odd bilayers");
69 }
70
71 module_r_max_ = module_r_min_ * (2 / sqrt(3));
73 cell_r_min_ = (sqrt(3.) / 2.) * cell_r_max_;
74
75 ldmx_log(debug) << "Building module map with gap " << std::setprecision(2)
76 << gap_ << ", nCellRHeight " << n_cell_r_height_
77 << ", min/max radii of cell " << cell_r_min_ << " / "
78 << cell_r_max_ << ", and module " << module_r_min_ << " / "
80
86
87 ldmx_log(trace) << "Geometry fully constructed";
88}
Base class for all conditions objects, very simple.
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
void buildCellModuleMap()
Constructs the positions of all the cells in a layer relative to the ecal center.
double layer_shift_y_
shift of layers in the y-direction [mm]
double ecal_center_x_
World x of the layer centers [mm].
void buildCellMap()
Constructs the flat-bottomed hexagonal grid (cellID) of corner-down hexagonal cells.
bool layer_shift_odd_
shift odd layers
double module_r_max_
Center-to-Corner Radius of module hexagon [mm].
double cell_r_min_
Center-to-Flat Radius of cell hexagon [mm].
double n_cell_r_height_
Number of cell center-to-corner radii (one side of the cell) from the bottom to the top of the module...
double layer_shift_x_
shift of layers in the x-direction [mm]
void buildModuleMap()
Constructs the positions of the seven modules (moduleID) relative to the ecal center.
std::vector< double > layer_z_positions_
The layer Z postions are with respect to the front of the ECal [mm].
double si_thickness_
Thickness of the Si sensitive layer [mm].
bool layer_shift_odd_bilayer_
shift odd bi layers
double ecal_center_y_
World y of the layer centers [mm].
void buildLayerMap()
Constructs the positions of the layers in world coordinates.
double cell_r_max_
Center-to-Corner Radius of cell hexagon [mm].
bool flip_y_
ECal y axis points along world -y, e.g. rotated about x by 180 deg.
double ecal_front_z_
Front of ECal relative to world geometry [mm].
double gap_
Gap between module flat sides [mm].
double module_r_min_
Center-to-Flat Radius of module hexagon [mm].
void buildNeighborMaps()
Construts NNMap and NNNMap.
bool corners_side_up_
indicator of geometry orientation if true, flower shape's corners side (ie: side with two modules) is...

References buildCellMap(), buildCellModuleMap(), buildLayerMap(), buildModuleMap(), buildNeighborMaps(), cell_r_max_, cell_r_min_, corners_side_up_, ecal_center_x_, ecal_center_y_, ecal_front_z_, flip_y_, gap_, framework::config::Parameters::get(), layer_shift_odd_, layer_shift_odd_bilayer_, layer_shift_x_, layer_shift_y_, layer_z_positions_, module_r_max_, module_r_min_, n_cell_r_height_, and si_thickness_.

Member Function Documentation

◆ buildCellMap()

void ldmx::EcalGeometry::buildCellMap ( )
private

Constructs the flat-bottomed hexagonal grid (cellID) of corner-down hexagonal cells.

Sets ecalMap_ with the defined bins being the ecal cells in coordinates with respect to the module center. Also sets cellPostionMap_ with the keys being the cell ID and the values being the position of the cell with respect to the module center.

Strategy

Use ROOT's TH2Poly::HoneyComb method to build a large hexagonal grid, then copy the polygons from it which overlap with the module with more than one vertex.

A vertex between three cells is placed at the origin, then the bottom left corner of the honeycomb and the number of x and y cells across the honeycomb is calculated by continuing to decrement the grid x/y point until the module center-to-flat distance is reached.

The hexagons that only have one vertex outside the module hexagon leave a small space un-covered by the tiling, so the vertices adjacent to the external vertex are projected onto the module edge.

Parameters
[in]cell_r_max_the center-to-flat cell radius
[in]cell_r_min_the center-to-corner cell radius
[in]module_r_min_the center-to-flat module radius
[in]module_r_max_the center-to-flat module radius
[out]ecalMap_TH2Poly with local cell ID to local cell position mapping
[out]cellPostionMap_map of local cell ID to cell center position relative to module

STRATEGY use ROOT HoneyComb method (build large hex grid, copy polygons that cover module)

the sneaky bit is that the center of TH2Poly::HoneyComb is the center of a cell while the center of one of our modules is the corner between three cells. This means some of the hexagons along the edges of the module will not be regular and need to stretched/squashed a bit.

REMEMBER: We are in p,q space for the cells_in_module_ map. i.e.

^ | q axis __ / \ – > p axis __/

TODO is this needed?

Definition at line 257 of file EcalGeometry.cxx.

257 {
277 TH2Poly grid_map;
278
279 // make hexagonal grid [boundary is rectangle] larger than the module
280 double grid_min_p = 0., grid_min_q = 0.; // start at the origin
281 int num_p_cells = 0, num_q_cells = 0;
282
283 // first x-cell is only a half
284 grid_min_p -= cell_r_min_;
285 num_p_cells++;
286 while (grid_min_p > -1 * module_r_max_) {
287 // decrement x by cell center-to-flat diameter
288 grid_min_p -= 2 * cell_r_min_;
289 num_p_cells++;
290 }
291 while (grid_min_q > -1 * module_r_min_) {
292 // decrement y by cell center-to-corner radius
293 // alternate between a full corner-to-corner diameter
294 // and a side of a cell (center-to-corner radius)
295 if (num_q_cells % 2 == 0)
296 grid_min_q -= 1 * cell_r_max_;
297 else
298 grid_min_q -= 2 * cell_r_max_;
299 num_q_cells++;
300 }
301 // only counted one half of the cells
302 num_p_cells *= 2;
303 num_q_cells *= 2;
304
305 grid_map.Honeycomb(grid_min_p, grid_min_q, cell_r_max_, num_p_cells,
306 num_q_cells);
307
308 ldmx_log(trace) << std::setprecision(2)
309 << "Building buildCellMap with cell rmin: " << cell_r_min_
310 << " cell rmax: " << cell_r_max_ << " (gridMinP,gridMinQ) = ("
311 << grid_min_p << "," << grid_min_q << ")"
312 << " (numPCells,numQCells) = (" << num_p_cells << ","
313 << num_q_cells << ")";
314
315 // copy cells lying within module boundaries to a module grid
316 TListIter next(grid_map.GetBins()); // a TH2Poly is a TList of TH2PolyBin
317 TH2PolyBin* poly_bin = 0;
318 TGraph* poly = 0; // a polygon returned by TH2Poly is a TGraph
319 // cells_in_module_ IDs go from 0 to N-1, not equal to original grid cell ID
320 int cell_id = 0;
321 while ((poly_bin = (TH2PolyBin*)next())) {
322 // these bins are coming from the honeycomb
323 // grid so we assume that they are regular
324 // hexagons i.e. has 6 vertices
325 poly = (TGraph*)poly_bin->GetPolygon();
326
327 // decide whether to copy polygon to new map.
328 // use all vertices in case of cut-off edge polygons.
329 int num_vertices_inside = 0;
330 double vertex_p[6], vertex_q[6]; // vertices of the cell
331 bool isinside[6]; // which vertices are inside
332 ldmx_log(trace) << " Cell vertices";
333 for (unsigned i = 0; i < 6; i++) {
334 poly->GetPoint(i, vertex_p[i], vertex_q[i]);
335 ldmx_log(trace) << " vtx # " << i;
336 ldmx_log(trace) << " vtx p,q " << vertex_p[i] << " " << vertex_q[i];
337
338 isinside[i] =
339 isInside(vertex_p[i] / module_r_max_, vertex_q[i] / module_r_max_);
340 if (isinside[i]) num_vertices_inside++;
341 }
342
343 if (num_vertices_inside > 1) {
344 // Include this cell if more than one of its vertices is inside the module
345 // hexagon
346 double actual_p[8], actual_q[8];
347 int num_vertices{0};
348 if (num_vertices_inside < 6) {
349 // This cell is stradling the edge of the module
350 // and is NOT cleanly cut by module edge
351
352 ldmx_log(trace) << " Polygon " << cell_id
353 << " has vertices poking out of module hexagon.";
354
355 // loop through vertices
356 for (int i = 0; i < 6; i++) {
357 int up = i == 5 ? 0 : i + 1;
358 int dn = i == 0 ? 5 : i - 1;
359 if (isinside[i] and (not isinside[up] or not isinside[dn])) {
360 // this vertex is inside the module hexagon and is adjacent to a
361 // vertex outside
362 // ==> project this vertex onto the nearest edge of the module
363 // hexagon
364
365 // determine which side of hexagon we should project onto
366 double edge_origin_p, edge_origin_q;
367 double edge_dest_p, edge_dest_q;
368 if (vertex_p[i] < -module_r_max_ / 2.) {
369 // sloped edge on negative-x side
370 edge_origin_p = -1. * module_r_max_;
371 edge_origin_q = 0.;
372 edge_dest_p = -0.5 * module_r_max_;
373 edge_dest_q = module_r_min_;
374 } else if (vertex_p[i] > module_r_max_ / 2.) {
375 // sloped edge on positive-x side
376 edge_origin_p = 0.5 * module_r_max_;
377 edge_origin_q = module_r_min_;
378 edge_dest_p = module_r_max_;
379 edge_dest_q = 0.;
380 } else {
381 // flat edge at top
382 edge_origin_p = 0.5 * module_r_max_;
383 edge_origin_q = module_r_min_;
384 edge_dest_p = -0.5 * module_r_max_;
385 edge_dest_q = module_r_min_;
386 }
387 // flip to bottom half if below x-axis
388 if (vertex_q[i] < 0) {
389 edge_dest_q *= -1;
390 edge_origin_q *= -1;
391 }
392
393 // get edge slope vector
394 double edge_slope_p = edge_dest_p - edge_origin_p;
395 double edge_slope_q = edge_dest_q - edge_origin_q;
396
397 ldmx_log(trace)
398 << "Vertex " << i
399 << " is inside and adjacent to a vertex outside the module.";
400 ldmx_log(trace) << "Working on edge with slope (" << edge_slope_p
401 << "," << edge_slope_q << ")" << " and origin ("
402 << edge_origin_p << "," << edge_origin_q << ")";
403
404 // project vertices adjacent to the vertex outside the module onto
405 // the module edge
406 double projection_factor =
407 ((vertex_p[i] - edge_origin_p) * edge_slope_p +
408 (vertex_q[i] - edge_origin_q) * edge_slope_q) /
409 (edge_slope_p * edge_slope_p + edge_slope_q * edge_slope_q);
410
411 double proj_p = edge_origin_p + projection_factor * edge_slope_p;
412 double proj_q = edge_origin_q + projection_factor * edge_slope_q;
413
414 if (not isinside[up]) {
415 // the next point is outside
416 actual_p[num_vertices] = vertex_p[i];
417 actual_q[num_vertices] = vertex_q[i];
418 actual_p[num_vertices + 1] = proj_p;
419 actual_q[num_vertices + 1] = proj_q;
420 } else {
421 // the previous point was outside
422 actual_p[num_vertices] = proj_p;
423 actual_q[num_vertices] = proj_q;
424 actual_p[num_vertices + 1] = vertex_p[i];
425 actual_q[num_vertices + 1] = vertex_q[i];
426 }
427 num_vertices += 2;
428
429 ldmx_log(trace) << "New Vertex " << i << " : (" << vertex_p[i]
430 << "," << vertex_q[i] << ")";
431
432 } else {
433 actual_p[num_vertices] = vertex_p[i];
434 actual_q[num_vertices] = vertex_q[i];
435 num_vertices++;
436 } // should we project or not
437 } // loop through vertices
438 } else {
439 // all 6 inside, just copy the vertices over
440 num_vertices = 6;
441 for (int i = 0; i < 6; i++) {
442 actual_p[i] = vertex_p[i];
443 actual_q[i] = vertex_q[i];
444 }
445 } // if numVerticesInside is less than 5
446
447 // TH2Poly needs to have its own copy of the polygon TGraph
448 // otherwise, we get a seg fault when EcalGeometry is destructed
449 // because the polygon that was copied over from gridMap is deleted at
450 // the end of this function
451 cell_id_in_module_.AddBin(num_vertices, actual_p, actual_q);
452
456 double p = (poly_bin->GetXMax() + poly_bin->GetXMin()) / 2.;
457 double q = (poly_bin->GetYMax() + poly_bin->GetYMin()) / 2.;
458
459 ldmx_log(trace) << " Copying poly with ID " << poly_bin->GetBinNumber()
460 << " and (p,q) (" << std::setprecision(2) << p << "," << q
461 << ")";
462 // save cell location as center of ENTIRE hexagon
463 cell_pos_in_module_[cell_id] = std::pair<double, double>(p, q);
464 ++cell_id; // incrememnt cell ID
465 } // if num vertices inside is > 1
466 } // loop over larger grid spanning module hexagon
467 return;
468}
std::map< int, std::pair< double, double > > cell_pos_in_module_
Position of cell centers relative to center of module in p,q space.
bool isInside(double normX, double normY) const
Determines if point (x,y), already normed to max hexagon radius, lies within a hexagon.
TH2Poly cell_id_in_module_
Honeycomb Binning from ROOT.

References cell_id_in_module_, cell_pos_in_module_, cell_r_max_, cell_r_min_, isInside(), module_r_max_, and module_r_min_.

Referenced by EcalGeometry().

◆ buildCellModuleMap()

void ldmx::EcalGeometry::buildCellModuleMap ( )
private

Constructs the positions of all the cells in a layer relative to the ecal center.

This uses the modulePostionMap_ and cellPositionMap_ to calculate the center of all cells relative to the ecal center.

Parameters
[in]modulePositionMap_map of module IDs to module centers relative to ecal
[in]cellPositionMap_map of cell IDs to cell centers relative to module
[out]

construct map of cell centers relative to layer center

construct map of global cell centers relative to target center

Definition at line 470 of file EcalGeometry.cxx.

470 {
471 ldmx_log(trace) << "Building cellModule position map";
473 for (auto const& [module_id, module_xy] : module_pos_xy_) {
474 for (auto const& [cell_id, cell_pq] : cell_pos_in_module_) {
475 double cell_x{cell_pq.first}, cell_y{cell_pq.second};
476 // convert from (p,q) to (x,y) space
477 // when the corners are not up, x = p and y = q
478 // so no transformation needs to be done
479 if (corners_side_up_) unrotate(cell_x, cell_y);
480
481 // calculate cell's pq relative to entire layer center
482 auto cell_rel_to_layer =
483 std::make_pair(module_xy.first + cell_x, module_xy.second + cell_y);
484
485 // now add the layer-center values to get the global position
486 // of the cell
487 cell_pos_in_layer_[EcalID(0, module_id, cell_id)] = cell_rel_to_layer;
488 }
489 }
490
492 for (auto const& [layer_id, layer_xyz] : layer_pos_xy_) {
493 for (auto const& [flat_id, rel_to_layer] : cell_pos_in_layer_) {
494 // now add the layer-center values to get the global position
495 // of the cell
496 cell_global_pos_[EcalID(layer_id, flat_id.module(), flat_id.cell())] =
497 std::make_tuple(rel_to_layer.first + std::get<0>(layer_xyz),
498 (flip_y_ ? -1. : 1.) * rel_to_layer.second +
499 std::get<1>(layer_xyz),
500 std::get<2>(layer_xyz));
501 }
502 }
503
504 ldmx_log(trace) << "Cell module map contains " << cell_global_pos_.size()
505 << " entries. ";
506 return;
507}
std::map< EcalID, std::tuple< double, double, double > > cell_global_pos_
Position of cell centers relative to world geometry.
std::map< int, std::pair< double, double > > module_pos_xy_
Postion of module centers relative to the center of the layer in world coordinates.
std::map< int, std::tuple< double, double, double > > layer_pos_xy_
Position of layer centers in world coordinates (uses layer ID as key)
std::map< EcalID, std::pair< double, double > > cell_pos_in_layer_
Position of cell centers relative to center of layer in world coordinates.

References cell_global_pos_, cell_pos_in_layer_, cell_pos_in_module_, corners_side_up_, flip_y_, layer_pos_xy_, and module_pos_xy_.

Referenced by EcalGeometry().

◆ buildLayerMap()

void ldmx::EcalGeometry::buildLayerMap ( )
private

Constructs the positions of the layers in world coordinates.

Definition at line 198 of file EcalGeometry.cxx.

198 {
199 ldmx_log(debug) << "Building layer map with " << layer_z_positions_.size()
200 << " layers";
202 if (layer_shift_odd_) {
203 ldmx_log(debug) << "Shifting odd layers by (x,y) = (" << layer_shift_x_
204 << ", " << layer_shift_y_ << ") mm";
205 } else {
206 ldmx_log(debug) << "Shifting odd bilayers by (x,y) = (" << layer_shift_x_
207 << ", " << layer_shift_y_ << ") mm";
208 }
209 }
210
211 for (std::size_t i_layer{0}; i_layer < layer_z_positions_.size(); ++i_layer) {
212 // default is centered on z-axis
213 double x{ecal_center_x_}, y{ecal_center_y_},
214 z{ecal_front_z_ + layer_z_positions_.at(i_layer)};
215 const double shift_y{flip_y_ ? -layer_shift_y_ : layer_shift_y_};
216 if (layer_shift_odd_ and (i_layer % 2 == 1)) {
217 x += layer_shift_x_;
218 y += shift_y;
219 } else if (layer_shift_odd_bilayer_ and ((i_layer / 2) % 2 == 1)) {
220 x += layer_shift_x_;
221 y += shift_y;
222 }
223 ldmx_log(trace) << " Layer " << i_layer << " has center at (" << x
224 << ", " << y << ", " << z << ") mm";
225
226 layer_pos_xy_[i_layer] = std::make_tuple(x, y, z);
227 }
228}

References ecal_center_x_, ecal_center_y_, ecal_front_z_, flip_y_, layer_pos_xy_, layer_shift_odd_, layer_shift_odd_bilayer_, layer_shift_x_, layer_shift_y_, and layer_z_positions_.

Referenced by EcalGeometry().

◆ buildModuleMap()

void ldmx::EcalGeometry::buildModuleMap ( )
private

Constructs the positions of the seven modules (moduleID) relative to the ecal center.

Sets modulePositionMap_ using the module IDs for keys and the centers of the module hexagons for values.

The module IDs are set in the ecal.gdml file and are replicated here.

  • 0 for center module
  • 1 on top (12 o'clock)
  • clockwise till 6 at 11 o'clock
Parameters
[in]gap_separation between module flat-sides
[in]moduler_center-to-flat module radius
[out]modulePositionMap_map of module IDs to module centers relative to ecal

Definition at line 230 of file EcalGeometry.cxx.

230 {
231 static const double c_pi = 3.14159265358979323846;
232
233 // the center module (module_id == 0) has always been (and will always be?)
234 // centered with respect to the layer position
235 module_pos_xy_[0] = std::pair<double, double>(0., 0.);
236
237 // for flat-side-up designs (v12 and earlier), the modules are numbered 1 on
238 // positive y-axis and then counter-clockwise until 6
239 //
240 // for corner-side-up designes (v13 and later), the modules are numbered 1 on
241 // positive x-axis and then counter-clockwise until 6.
242 for (unsigned id = 1; id < 7; id++) {
243 // flat-side-up
244 double x = (2. * module_r_min_ + gap_) * sin((id - 1) * (c_pi / 3.));
245 double y = (2. * module_r_min_ + gap_) * cos((id - 1) * (c_pi / 3.));
246 if (corners_side_up_) {
247 // re-calculating to make sure centers match GDML
248 x = (2. * module_r_min_ + gap_) * cos((id - 1) * (c_pi / 3.));
249 y = -(2. * module_r_min_ + gap_) * sin((id - 1) * (c_pi / 3.));
250 }
251 module_pos_xy_[id] = std::pair<double, double>(x, y);
252 ldmx_log(trace) << " Module " << id << " is centered at (x,y) = " << "("
253 << x << ", " << y << ") mm";
254 }
255}

References corners_side_up_, gap_, module_pos_xy_, and module_r_min_.

Referenced by EcalGeometry().

◆ buildNeighborMaps()

void ldmx::EcalGeometry::buildNeighborMaps ( )
private

Construts NNMap and NNNMap.

Since this only occurs once during processing, we can be wasteful. We do a nested loop over the entire cellular position map and calculate neighbors by seeing which cells are within multiples of the cellular radius of each other.

Note
We require two cells to be in the same layer in order to be nearest neighbors or next-nearest neighbors.
Parameters
[in]cellModulePostionMap_map of cells to cell centers relative to ecal
[out]NNMap_map of cell IDs to list of cell IDs that are its nearest neighbors
[out]NNNMap_map of cell IDs to list of cell IDs that are its next-to-nearest neighbors

STRATEGY

Neighbors may include from other modules. All this is precomputed. So we can be wasteful here. Gaps may be nonzero, so we simply apply an anulus requirement (r < point <= r+dr) using total x,y positions relative to the ecal center (cell+module positions). This makes the routine portable to future cell layouts. Note that the module centers already take into account a nonzero gap. The number of neighbors is not simple because: edges, and that module edges have cutoff cells. (NN) Center within [1*cell_r_min_, 3*cell_r_min_] (NNN) Center within [3*cell_r_min_, 4.5*cell_r_min_] Chosen b/c in ideal case, centers are at 2*cell_ (NN), and at 3*cell_r_max_=3.46*cell_r_min_ and 4*cell_r_min_ (NNN).

do distance calculation

Definition at line 509 of file EcalGeometry.cxx.

509 {
523 ldmx_log(trace) << "Building Nearest and Next-Nearest Neighbor maps";
524
525 nn_map_.clear();
526 nnn_map_.clear();
527 for (auto const& [center_id, center_xyz] : cell_pos_in_layer_) {
528 for (auto const& [probe_id, probe_xyz] : cell_pos_in_layer_) {
530 double dist = distance(probe_xyz, center_xyz);
531 if (dist > 1 * cell_r_min_ && dist <= 3. * cell_r_min_) {
532 nn_map_[center_id].push_back(probe_id);
533 } else if (dist > 3. * cell_r_min_ && dist <= 4.5 * cell_r_min_) {
534 nnn_map_[center_id].push_back(probe_id);
535 }
536 }
537 // Keeping this commented out until the SimIDs string method is implemented
538 // ldmx_log(debug) << " Found " << nn_map_[center_id].size() << " NN and "
539 // << nnn_map_[center_id].size() << " NNN for cell " << center_id;
540 }
541 return;
542}
std::map< EcalID, std::vector< EcalID > > nnn_map_
Map of cell ID to neighbors of neighbor cells.
std::map< EcalID, std::vector< EcalID > > nn_map_
Map of cell ID to neighboring cells.

References cell_pos_in_layer_, cell_r_min_, nn_map_, and nnn_map_.

Referenced by EcalGeometry().

◆ debugMake()

static EcalGeometry * ldmx::EcalGeometry::debugMake ( const framework::config::Parameters & p)
inlinestatic

Definition at line 340 of file EcalGeometry.h.

340 {
341 return new EcalGeometry(p);
342 }
EcalGeometry(const framework::config::Parameters &ps)
Class constructor, for use only by the provider.

◆ distanceToEdge()

double ldmx::EcalGeometry::distanceToEdge ( EcalID id) const
private

Distance to module edge, and whether cell is on edge of module.

@TODO Use getNN()/getNNN() + isEdgeCell() to expand functionality.

Parameters
[in]cellModuleIDEcalId where all we care about is module and cell
Returns
distance to edge of the module

Definition at line 544 of file EcalGeometry.cxx.

544 {
545 // https://math.stackexchange.com/questions/1210572/find-the-distance-to-the-edge-of-a-hexagon
546 std::pair<double, double> cell_location = cell_pos_in_module_.at(id.cell());
547 double x = fabs(cell_location.first); // bring to first quadrant
548 double y = fabs(cell_location.second);
549 double r = sqrt(x * x + y * y);
550 double theta = (r > 1E-3) ? fabs(std::atan(y / x)) : 0;
551 if (x < module_r_max_ / 2.)
552 return (module_r_min_ -
553 y); // closest line is straight vertical to top edge
554 double dist =
555 sqrt(3.) * module_r_max_ / (std::sin(theta) + sqrt(3.) * std::cos(theta));
556 return dist;
557}

References cell_pos_in_module_, module_r_max_, and module_r_min_.

Referenced by isEdgeCell().

◆ getCellMaxR()

double ldmx::EcalGeometry::getCellMaxR ( ) const
inline

Get the center-to-corner radius of the cell hexagons.

Returns
cell max radius [mm]

Definition at line 322 of file EcalGeometry.h.

322{ return cell_r_max_; }

References cell_r_max_.

Referenced by ecal::EcalMipTrackingProcessor::produce().

◆ getCellMinR()

double ldmx::EcalGeometry::getCellMinR ( ) const
inline

Get the center-to-flat radius of the cell hexagons.

Returns
cell min radius [mm]

Definition at line 315 of file EcalGeometry.h.

315{ return cell_r_min_; }

References cell_r_min_.

◆ getCellPolyMap()

TH2Poly * ldmx::EcalGeometry::getCellPolyMap ( ) const
inline

Get a reference to the TH2Poly used for Cell IDs.

Note
This is only helpful in the use case where you want to print the cell ID <-> cell position map. DO NOT USE THIS OTHERWISE.
Returns
pointer to member variable cell_id_in_module_

Definition at line 333 of file EcalGeometry.h.

333 {
334 for (auto const& [cell_id, cell_center] : cell_pos_in_module_) {
335 cell_id_in_module_.Fill(cell_center.first, cell_center.second, cell_id);
336 }
337 return &cell_id_in_module_;
338 }

References cell_id_in_module_, and cell_pos_in_module_.

◆ getEcalFrontZ()

double ldmx::EcalGeometry::getEcalFrontZ ( ) const
inline

Get the z-coordinate of the Ecal face.

Returns
z-coordinate of the Ecal face

Definition at line 208 of file EcalGeometry.h.

208{ return ecal_front_z_; }

References ecal_front_z_.

Referenced by ecal::EcalTrackFinderProcessor::createEcalSurfaces(), ecal::EcalTrackFinderProcessor::onNewRun(), and ecal::EcalVetoProcessor::produce().

◆ getID() [1/3]

EcalID ldmx::EcalGeometry::getID ( double x,
double y,
double z,
bool fallible = false ) const

Get a cell's ID number from its position.

Parameters
[in]xglobal x position [mm]
[in]yglobal y position [mm]
[in]zglobal z position [mm]
[in]falliblebool to decide if the function should fail
Returns
EcalID of the cell (null-id if fallible) Example for fallible use case
auto id = geometry.getID(x, y, z, true);
if (id.null()) {
// position (x,y) is not contained within a cell in layer at z
}

Definition at line 90 of file EcalGeometry.cxx.

90 {
91 int layer_id{-1};
92 for (const auto& [lid, layer_xyz] : layer_pos_xy_) {
93 // check if the z coordinate is within the layer thickness
94 if (std::abs(std::get<2>(layer_xyz) - z) < si_thickness_) {
95 layer_id = lid;
96 break;
97 }
98 }
99 if (layer_id < 0) {
100 if (fallible) {
101 return ldmx::EcalID(0);
102 } else {
103 EXCEPTION_RAISE("BadConf", "z = " + std::to_string(z) +
104 " mm is not within any"
105 " of the configured layers.");
106 }
107 }
108 return getID(x, y, layer_id, fallible);
109}
EcalID getID(double x, double y, double z, bool fallible=false) const
Get a cell's ID number from its position.
Extension of DetectorID providing access to ECal layers and cell numbers in a hex grid.
Definition EcalID.h:20

References getID(), layer_pos_xy_, and si_thickness_.

Referenced by getID(), getID(), and ecal::EcalVetoProcessor::produce().

◆ getID() [2/3]

EcalID ldmx::EcalGeometry::getID ( double x,
double y,
int layer_id,
bool fallible = false ) const

Get a cell's ID from its x,y global position and layer number.

This is faster as long as we trust that the layer positions between GDML and the configured parameters of this class match.

Parameters
[in]xglobal x position [mm]
[in]yglobal y position [mm]
[in]layer_idinteger ID of the layer the hit is in
[in]falliblebool to decide if the function should fail
Returns
EcalID of the cell (null-id if fallible) Example for fallible use case
auto id = geometry.getID(x, y, ilayer, true);
if (id.null()) {
// position (x,y) is not contained within a cell in layer ilayer
}

Definition at line 111 of file EcalGeometry.cxx.

112 {
113 // now assume we know the layer
114 // shift to center of layer
115 // and convert to flower coordinates
116 double p{x - std::get<0>(layer_pos_xy_.at(layer_id))},
117 q{y - std::get<1>(layer_pos_xy_.at(layer_id))};
118 if (flip_y_) q = -q;
119
120 // deduce module ID
121 // there are only 7 modules so we just loop through them
122 // all and pick out the module ID that we are inside of
123
124 int module_id{-1};
125 for (auto const& [mid, module_xy] : module_pos_xy_) {
126 double probe_x{p - module_xy.first}, probe_y{q - module_xy.second};
127 if (corners_side_up_) rotate(probe_x, probe_y);
128 if (isInside(probe_x / module_r_max_, probe_y / module_r_max_)) {
129 module_id = mid;
130 break;
131 }
132 }
133
134 if (module_id < 0) {
135 if (fallible) {
136 return ldmx::EcalID(0);
137 } else {
138 EXCEPTION_RAISE(
139 "BadConf",
140 TString::Format(
141 "Coordinates relative to layer (p,q) = (%.2f, %.2f) mm "
142 "derived from world coordinates (%.2f, %.2f) mm with layer = %d "
143 "are not inside any module.",
144 p, q, x, y, layer_id)
145 .Data());
146 }
147 }
148
149 return getID(x, y, layer_id, module_id);
150}

References corners_side_up_, flip_y_, getID(), isInside(), layer_pos_xy_, module_pos_xy_, and module_r_max_.

◆ getID() [3/3]

EcalID ldmx::EcalGeometry::getID ( double x,
double y,
int layer_id,
int module_id,
bool fallible = false ) const

Get a cell's ID from its x,y global position and layer/module numbers as deduced from GDML copy numbers.

This is the fastest option but we need to carefully validated that the layer and module positions between the GDML and the configured parameters of this class match.

Parameters
[in]xglobal x position [mm]
[in]yglobal y position [mm]
[in]layer_idinteger ID of the layer the hit is in
[in]module_idinteger ID of the module the hit is in
[in]falliblebool to decide if the function should fail
Returns
EcalID of the cell (null-id if fallible) Example for fallible use case
auto id = geometry.getID(x, y, ilayer, imodule, true);
if (id.null()) {
// position (x,y) is not contained within a cell in layer ilayer in
module imodule
}

Definition at line 152 of file EcalGeometry.cxx.

153 {
154 // now assume we know the layer and module
155 // shift to center of layer and then center of module
156 double p{x - std::get<0>(layer_pos_xy_.at(layer_id)) -
157 module_pos_xy_.at(module_id).first},
158 q{(flip_y_ ? -1. : 1.) * (y - std::get<1>(layer_pos_xy_.at(layer_id))) -
159 module_pos_xy_.at(module_id).second};
160
161 // need to rotate
162 if (corners_side_up_) rotate(p, q);
163
164 // deduce cell ID
165 int cell_id = cell_id_in_module_.FindBin(p, q) - 1;
166
167 if (cell_id < 0) {
168 if (fallible) {
169 return ldmx::EcalID(0);
170 } else {
171 EXCEPTION_RAISE(
172 "BadConf",
173 TString::Format(
174 "Relative cell coordinates (%.2f, %.2f) mm "
175 "derived from world coordinates (%.2f, %.2f) mm with layer = %d "
176 "and module = %d are outside module hexagon",
177 p, q, x, y, layer_id, module_id)
178 .Data());
179 }
180 }
181
182 return EcalID(layer_id, module_id, cell_id);
183}

References cell_id_in_module_, corners_side_up_, flip_y_, layer_pos_xy_, and module_pos_xy_.

◆ getModuleMaxR()

double ldmx::EcalGeometry::getModuleMaxR ( ) const
inline

Get the center-to-corner radius of the module hexagons.

Returns
module max radius [mm]

Definition at line 308 of file EcalGeometry.h.

308{ return module_r_max_; }

References module_r_max_.

◆ getModuleMinR()

double ldmx::EcalGeometry::getModuleMinR ( ) const
inline

Get the center-to-flat radius of the module hexagons.

Returns
module min radius [mm]

Definition at line 301 of file EcalGeometry.h.

301{ return module_r_min_; }

References module_r_min_.

◆ getNN()

std::vector< EcalID > ldmx::EcalGeometry::getNN ( EcalID id) const
inline

Get the Nearest Neighbors of the input ID.

Parameters
idid to get
Returns
list of EcalID that are the inputs nearest neighbors

Definition at line 247 of file EcalGeometry.h.

247 {
248 auto list = nn_map_.at(EcalID(0, id.module(), id.cell()));
249 for (auto& flat : list)
250 flat = EcalID(id.layer(), flat.module(), flat.cell());
251 return list;
252 }

References nn_map_.

Referenced by isNN().

◆ getNNN()

std::vector< EcalID > ldmx::EcalGeometry::getNNN ( EcalID id) const
inline

Get the Next-to-Nearest Neighbors of the input ID.

Parameters
idid to get
Returns
list of EcalID that are the inputs next-to-nearest neighbors

Definition at line 274 of file EcalGeometry.h.

274 {
275 auto list = nnn_map_.at(EcalID(0, id.module(), id.cell()));
276 for (auto& flat : list)
277 flat = EcalID(id.layer(), flat.module(), flat.cell());
278 return list;
279 }

References nnn_map_.

Referenced by isNNN().

◆ getNumCellsPerModule()

int ldmx::EcalGeometry::getNumCellsPerModule ( ) const
inline

Get the number of cells in each module of the Ecal Geometry.

Note
This assumes that all modules are the full high-density hexagons from CMS (no triangles!)

Definition at line 237 of file EcalGeometry.h.

237 {
238 return cell_id_in_module_.GetNumberOfBins();
239 }

References cell_id_in_module_.

◆ getNumLayers()

int ldmx::EcalGeometry::getNumLayers ( ) const
inline

Get the number of layers in the Ecal Geometry.

Returns
number fo layers in geometry

Definition at line 215 of file EcalGeometry.h.

215{ return layer_pos_xy_.size(); }

References layer_pos_xy_.

Referenced by ecal::EcalTrackFinderProcessor::createEcalSurfaces(), and ecal::EcalTrackFinderProcessor::onNewRun().

◆ getNumModulesPerLayer()

int ldmx::EcalGeometry::getNumModulesPerLayer ( ) const
inline

Get the number of modules in the Ecal flower.

Note
This number is hard-coded to reflect the fact that it is also hard-coded in the buildModuleMap function. If a future geometry adds more modules (perhaps "triangles" to fill in rectangular block in the HCal that the ECal is in), then buildModuleMap and this function will need to be modified.
Returns
number of modules

Definition at line 229 of file EcalGeometry.h.

229{ return 7; }

◆ getPosition()

std::tuple< double, double, double > ldmx::EcalGeometry::getPosition ( EcalID id) const

Get a cell's position from its ID number.

std::tuple is useful here because you can use C++17's pattern matching to use code like the following

auto [x,y,z] = geometry.getPosition(id);

Definition at line 185 of file EcalGeometry.cxx.

185 {
186 return cell_global_pos_.at(id);
187}

References cell_global_pos_.

Referenced by ecal::EcalTrackFinderProcessor::createMeasurements(), ecal::EcalTriggerGeometry::globalPosition(), ecal::EcalPnetVetoProcessor::makeInputs(), ecal::EcalRecoilRemovalProcessor::produce(), ecal::EcalTrackFinderProcessor::produce(), ecal::EcalVetoProcessor::produce(), and ecal::EcalWABRecProcessor::produce().

◆ getPositionInModule()

std::pair< double, double > ldmx::EcalGeometry::getPositionInModule ( int cell_id) const

Get a cell's position within a module.

Definition at line 189 of file EcalGeometry.cxx.

189 {
190 auto pq = cell_pos_in_module_.at(cell_id);
191
192 // going from (p,q) to (x,y) is a unrotate
193 if (corners_side_up_) unrotate(pq.first, pq.second);
194
195 return pq;
196}

References cell_pos_in_module_, and corners_side_up_.

Referenced by ecal::EcalTriggerGeometry::localPosition().

◆ getZPosition()

double ldmx::EcalGeometry::getZPosition ( int layer) const
inline

Get the z-coordinate given the layer id.

Parameters
[in]layerint layer id
Returns
z-coordinate of the input sensitive layer

Definition at line 200 of file EcalGeometry.h.

200 {
201 return std::get<2>(layer_pos_xy_.at(layer));
202 }

References layer_pos_xy_.

Referenced by ecal::EcalTrackFinderProcessor::createEcalSurfaces(), ecal::EcalTrackFinderProcessor::onNewRun(), ecal::EcalMipTrackingProcessor::produce(), and ecal::EcalVetoProcessor::produce().

◆ isEdgeCell()

bool ldmx::EcalGeometry::isEdgeCell ( EcalID cellModuleID) const
inlineprivate

Check if input cell is on the edge of a module.

See also
distanceToEdge
Parameters
[in]cellModuleIDEcalId where all we care about is module and cell return true if distance to edge is less than max cell radius

Definition at line 464 of file EcalGeometry.h.

464 {
465 return (distanceToEdge(cellModuleID) < cell_r_max_);
466 }
double distanceToEdge(EcalID id) const
Distance to module edge, and whether cell is on edge of module.

References cell_r_max_, and distanceToEdge().

◆ isInside()

bool ldmx::EcalGeometry::isInside ( double normX,
double normY ) const
private

Determines if point (x,y), already normed to max hexagon radius, lies within a hexagon.

Corners are (1,0) and (0.5,sqrt(3)/2). Uses "<", not "<=".

Note
This function is in p,q space so any rotations need to be performed before calling this function.
Parameters
[in]normXX-coordinate relative to module hexagon divided by maximum hexagon radius
[in]normYY-coordinate relative to module hexagon divided by maximum hexagon radius
Returns
true if (normX,normY) is within the hexagon centered at the origin with maximum radius 1.

Definition at line 559 of file EcalGeometry.cxx.

559 {
560 ldmx_log(trace) << std::fixed << std::setprecision(2)
561 << "Checking if normXY=(" << normX << "," << normY
562 << ") is inside.";
563 normX = fabs(normX), normY = fabs(normY);
564 double xvec = -1, yvec = -1. / sqrt(3);
565 double xref = 0.5, yref = sqrt(3) / 2.;
566 if ((normX > 1.) || (normY > yref)) {
567 ldmx_log(trace) << "They are outside quadrant.";
568 return false;
569 }
570 double dot_prod = (xvec * (normX - xref) + yvec * (normY - yref));
571 ldmx_log(trace) << std::fixed << std::setprecision(2)
572 << "They are inside quadrant. Dot product (>0 is inside): "
573 << dot_prod;
574 return (dot_prod > 0.);
575}

Referenced by buildCellMap(), and getID().

◆ isNN()

bool ldmx::EcalGeometry::isNN ( EcalID centroid,
EcalID probe ) const
inline

Check if the probe id is one of the nearest neightbors of the centroid id.

Parameters
probeid to check if it is nearest neighbor
centroidid that is center of neighbors
Returns
true if probe ID is a nearest neighbor of the centroid

Definition at line 261 of file EcalGeometry.h.

261 {
262 for (auto& id : getNN(centroid)) {
263 if (id == probe) return true;
264 }
265 return false;
266 }
std::vector< EcalID > getNN(EcalID id) const
Get the Nearest Neighbors of the input ID.

References getNN().

◆ isNNN()

bool ldmx::EcalGeometry::isNNN ( EcalID centroid,
EcalID probe ) const
inline

Check if the probe id is one of the next-to-nearest neightbors of the centroid id.

Parameters
probeid to check if it is a next-to-nearest neighbor
centroidid that is center of neighbors
Returns
true if probe ID is a next-to-nearest neighbor of the centroid

Definition at line 289 of file EcalGeometry.h.

289 {
290 for (auto& id : getNNN(centroid)) {
291 if (id == probe) return true;
292 }
293 return false;
294 }
std::vector< EcalID > getNNN(EcalID id) const
Get the Next-to-Nearest Neighbors of the input ID.

References getNNN().

Friends And Related Symbol Documentation

◆ ecal::EcalGeometryProvider

friend class ecal::EcalGeometryProvider
friend

Definition at line 351 of file EcalGeometry.h.

Member Data Documentation

◆ cell_global_pos_

std::map<EcalID, std::tuple<double, double, double> > ldmx::EcalGeometry::cell_global_pos_
private

Position of cell centers relative to world geometry.

This is where we convert p,q (flower) space into x,y (world) space by calculating the z-location as well as including rotations and shifts when converting from p,q to x,y.

The key is the full EcalID and the value is the x,y,z tuple.

Definition at line 616 of file EcalGeometry.h.

Referenced by buildCellModuleMap(), and getPosition().

◆ cell_id_in_module_

TH2Poly ldmx::EcalGeometry::cell_id_in_module_
mutableprivate

Honeycomb Binning from ROOT.

Needs to be mutable because ROOT doesn't have good const handling

Lookup a cell ID using its position relative to the center of the module in p,q space.

Definition at line 640 of file EcalGeometry.h.

Referenced by buildCellMap(), getCellPolyMap(), getID(), and getNumCellsPerModule().

◆ cell_pos_in_layer_

std::map<EcalID, std::pair<double, double> > ldmx::EcalGeometry::cell_pos_in_layer_
private

Position of cell centers relative to center of layer in world coordinates.

Note
Layer shifts are NOT included in this map since they depend on the layer number!!

Uses EcalID with layer set to zero as key.

Definition at line 605 of file EcalGeometry.h.

Referenced by buildCellModuleMap(), and buildNeighborMaps().

◆ cell_pos_in_module_

std::map<int, std::pair<double, double> > ldmx::EcalGeometry::cell_pos_in_module_
private

Position of cell centers relative to center of module in p,q space.

use cell ID as key

Definition at line 594 of file EcalGeometry.h.

Referenced by buildCellMap(), buildCellModuleMap(), distanceToEdge(), getCellPolyMap(), and getPositionInModule().

◆ cell_r_max_

double ldmx::EcalGeometry::cell_r_max_ {0}
private

Center-to-Corner Radius of cell hexagon [mm].

Definition at line 496 of file EcalGeometry.h.

496{0};

Referenced by buildCellMap(), EcalGeometry(), getCellMaxR(), and isEdgeCell().

◆ cell_r_min_

double ldmx::EcalGeometry::cell_r_min_ {0}
private

Center-to-Flat Radius of cell hexagon [mm].

Definition at line 490 of file EcalGeometry.h.

490{0};

Referenced by buildCellMap(), buildNeighborMaps(), EcalGeometry(), and getCellMinR().

◆ CONDITIONS_OBJECT_NAME

const char* ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME {"EcalGeometry"}
staticconstexpr

Definition at line 103 of file EcalGeometry.h.

103{"EcalGeometry"};

◆ corners_side_up_

bool ldmx::EcalGeometry::corners_side_up_
private

indicator of geometry orientation if true, flower shape's corners side (ie: side with two modules) is at the top

Definition at line 506 of file EcalGeometry.h.

Referenced by buildCellModuleMap(), buildModuleMap(), EcalGeometry(), getID(), getID(), and getPositionInModule().

◆ ecal_center_x_

double ldmx::EcalGeometry::ecal_center_x_
private

World x of the layer centers [mm].

Definition at line 542 of file EcalGeometry.h.

Referenced by buildLayerMap(), and EcalGeometry().

◆ ecal_center_y_

double ldmx::EcalGeometry::ecal_center_y_
private

World y of the layer centers [mm].

Definition at line 545 of file EcalGeometry.h.

Referenced by buildLayerMap(), and EcalGeometry().

◆ ecal_front_z_

double ldmx::EcalGeometry::ecal_front_z_ {0}
private

Front of ECal relative to world geometry [mm].

Definition at line 568 of file EcalGeometry.h.

568{0};

Referenced by buildLayerMap(), EcalGeometry(), and getEcalFrontZ().

◆ flip_y_

bool ldmx::EcalGeometry::flip_y_
private

ECal y axis points along world -y, e.g. rotated about x by 180 deg.

Definition at line 548 of file EcalGeometry.h.

Referenced by buildCellModuleMap(), buildLayerMap(), EcalGeometry(), getID(), and getID().

◆ gap_

double ldmx::EcalGeometry::gap_
private

Gap between module flat sides [mm].

Definition at line 487 of file EcalGeometry.h.

Referenced by buildModuleMap(), and EcalGeometry().

◆ layer_pos_xy_

std::map<int, std::tuple<double, double, double> > ldmx::EcalGeometry::layer_pos_xy_
private

Position of layer centers in world coordinates (uses layer ID as key)

Definition at line 578 of file EcalGeometry.h.

Referenced by buildCellModuleMap(), buildLayerMap(), getID(), getID(), getID(), getNumLayers(), and getZPosition().

◆ layer_shift_odd_

bool ldmx::EcalGeometry::layer_shift_odd_
private

shift odd layers

odd layers are the high-z layer in each bi-layer

i.e. We will shift if layer_id_ % 2 == 1

Definition at line 525 of file EcalGeometry.h.

Referenced by buildLayerMap(), and EcalGeometry().

◆ layer_shift_odd_bilayer_

bool ldmx::EcalGeometry::layer_shift_odd_bilayer_
private

shift odd bi layers

NOT IMPLEMENTED IN GDML

This shifts the bi-layer grouping of two sensitive layers together.

i.e. We will shift if (layer_id_ / 2) % 2 == 1

where it is integer division.

Definition at line 539 of file EcalGeometry.h.

Referenced by buildLayerMap(), and EcalGeometry().

◆ layer_shift_x_

double ldmx::EcalGeometry::layer_shift_x_
private

shift of layers in the x-direction [mm]

Definition at line 511 of file EcalGeometry.h.

Referenced by buildLayerMap(), and EcalGeometry().

◆ layer_shift_y_

double ldmx::EcalGeometry::layer_shift_y_
private

shift of layers in the y-direction [mm]

Definition at line 516 of file EcalGeometry.h.

Referenced by buildLayerMap(), and EcalGeometry().

◆ layer_z_positions_

std::vector<double> ldmx::EcalGeometry::layer_z_positions_
private

The layer Z postions are with respect to the front of the ECal [mm].

Definition at line 571 of file EcalGeometry.h.

Referenced by buildLayerMap(), and EcalGeometry().

◆ module_pos_xy_

std::map<int, std::pair<double, double> > ldmx::EcalGeometry::module_pos_xy_
private

Postion of module centers relative to the center of the layer in world coordinates.

(uses module ID as key)

Definition at line 586 of file EcalGeometry.h.

Referenced by buildCellModuleMap(), buildModuleMap(), getID(), and getID().

◆ module_r_max_

double ldmx::EcalGeometry::module_r_max_ {0}
private

Center-to-Corner Radius of module hexagon [mm].

Definition at line 499 of file EcalGeometry.h.

499{0};

Referenced by buildCellMap(), distanceToEdge(), EcalGeometry(), getID(), and getModuleMaxR().

◆ module_r_min_

double ldmx::EcalGeometry::module_r_min_ {0}
private

Center-to-Flat Radius of module hexagon [mm].

Definition at line 493 of file EcalGeometry.h.

493{0};

Referenced by buildCellMap(), buildModuleMap(), distanceToEdge(), EcalGeometry(), and getModuleMinR().

◆ n_cell_r_height_

double ldmx::EcalGeometry::n_cell_r_height_ {0}
private

Number of cell center-to-corner radii (one side of the cell) from the bottom to the top of the module.

Could be fractional depending on how many fractions of a radii are spanning between the center of the top/bottom cell row and the edge of the module

Definition at line 565 of file EcalGeometry.h.

565{0};

Referenced by EcalGeometry().

◆ nn_map_

std::map<EcalID, std::vector<EcalID> > ldmx::EcalGeometry::nn_map_
private

Map of cell ID to neighboring cells.

The EcalID's in this map all have layer ID set to zero.

Definition at line 623 of file EcalGeometry.h.

Referenced by buildNeighborMaps(), and getNN().

◆ nnn_map_

std::map<EcalID, std::vector<EcalID> > ldmx::EcalGeometry::nnn_map_
private

Map of cell ID to neighbors of neighbor cells.

The EcalID's in this map all have layer ID set to zero.

Definition at line 630 of file EcalGeometry.h.

Referenced by buildNeighborMaps(), and getNNN().

◆ si_thickness_

double ldmx::EcalGeometry::si_thickness_
private

Thickness of the Si sensitive layer [mm].

This is used to determine if a hit is within a layer when the z-coordinate is given.

Definition at line 556 of file EcalGeometry.h.

Referenced by EcalGeometry(), and getID().


The documentation for this class was generated from the following files: