From 329a552ec6ee065d88dcf948e034173e5205e384 Mon Sep 17 00:00:00 2001 From: Whitney Armstrong <warmstrong@anl.gov> Date: Fri, 21 May 2021 00:52:46 -0500 Subject: [PATCH] modified: part1/simple_detector.md --- src/docs/part1/simple_detector.md | 163 +++++++++++++++++++++++++----- 1 file changed, 139 insertions(+), 24 deletions(-) diff --git a/src/docs/part1/simple_detector.md b/src/docs/part1/simple_detector.md index 31f9d07..921f869 100644 --- a/src/docs/part1/simple_detector.md +++ b/src/docs/part1/simple_detector.md @@ -1,7 +1,18 @@ --- -title: "Simple Detector" +title: "Simple Detector Demo" --- + * [Setup](#setup) + + [Inspect files](#inspect-files) + + [Compile the detector library](#compile-the-detector-library) + * [Visualize and Check Geometry](#visualize-and-check-geometry) + + [Look at disk tracker](#look-at-disk-tracker) + + [Check for overlaps](#check-for-overlaps) + + [Look at all the constants](#look-at-all-the-constants) + * [Running Geant4 simulation](#running-geant4-simulation) + * [Using detector description in analysis](#using-detector-description-in-analysis) + * [References](#references) + ## Setup Note all these commands assume you are in an `eic-shell` singularity session. @@ -128,21 +139,26 @@ Refer to the [GPS Documentation](http://www.fe.infn.it/u/paterno/Geant4_tutorial ## Using detector description in analysis -### Preface: data model +### Simulation output data model -First, the geant4 output data model used by `npsim` is [described in a single yaml file](https://eicweb.phy.anl.gov/EIC/NPDet/-/blob/master/src/dd4pod/dd4hep.yaml). +The geant4 output data model used by `npsim` is [described in a single yaml file](https://eicweb.phy.anl.gov/EIC/NPDet/-/blob/master/src/dd4pod/dd4hep.yaml). Note that this is purposefully factorized from the larger EIC data model, `eicd`, which is used at every step post geant4. https://eic.phy.anl.gov/eicd/ -Look at the generated file in results: - -This is the local position in the segmentation (i.e. pixel, strip, readout pad, etc.). +### Cell ID to position + +```bash +root -b -q scripts/tutorial1_hit_position.cxx+ +``` +Look at the generated plot in `results`: + -### Cell ID (channel) to Position +This is the local position in the segmentation cell (i.e. pixel, strip, readout pad, etc.). +#### Detector handle At the top of the script you can see these lines: ```cpp @@ -150,43 +166,151 @@ At the top of the script you can see these lines: detector.fromCompact("gem_tracker.xml"); dd4hep::rec::CellIDPositionConverter cellid_converter(detector); ``` + This - gets the main [DD4hep Detector](https://dd4hep.web.cern.ch/dd4hep/reference/classdd4hep_1_1Detector.html) instance - loads the compact detector file - initializes the [position converter tool](https://dd4hep.web.cern.ch/dd4hep/reference/classdd4hep_1_1rec_1_1CellIDPositionConverter.html) (which provides thread safe access) +Later on you can see its use while looping over hits: -Later on you can see its use: ```cpp - auto pos1 = cellid_converter.position(h.cellID); +auto pos0 = h.position; +auto pos1 = cellid_converter.position(h.cellID); ``` +Here `pos0` is a [dd4pod tracker hit](https://eic.phy.anl.gov/npdet/ref_doc/classdd4pod_1_1_tracker_hit.html) +which has `position`, a +[dd4pod four vector](https://eic.phy.anl.gov/npdet/ref_doc/classdd4pod_1_1_four_vector.html). +This is the position (and time) of the Geant4 step through the sensitive tracking volume<sup>1</sup>. + +`pos1` is a three vector of the smallest sensitive detector segment. +The converter tool is used along with the hit's `cellID` (i.e. unique channel number) to look up this position<sup>2</sup>. -### Cell size +- <sup>1</sup> Technically it is the average between the pre and post step points. +- <sup>2</sup> This is the first example showing how to use a single source of geometry information (i.e. the compact description file). + +### Accessing segmentation cell size ```bash root -b -q scripts/tutorial2_cell_size.cxx+ ``` -You will see this: +The output should contain a lot of statements like this: ```bash ... Segmentation-Cell Position : 39,102,-100 dim 1, 3, +... +``` + +The following snippet shows how to get cell size information from within the hit loop. +```cpp + auto context = cellid_converter.findContext( h.cellID ) ; + dd4hep::Readout r = cellid_converter.findReadout( context->element ) ; + dd4hep::Segmentation seg = r.segmentation() ; + auto cell_dim = seg.cellDimensions(h.cellID); +``` +Here `cell_dim` is a `std::vector<double>` passed by the specific segmentation implementation. + +#### Where is the segmentation defined? + +Look at the `readouts` tag of `gem_tracker.xml` and you will see this: +```xml + <readout name="GEMTrackerHits"> + <segmentation type="CartesianGridXY" grid_size_x="1*cm" grid_size_y="3*cm" /> + <id>system:8,barrel:2,layer:4,module:12,sensor:2,x:32:-16,y:-16</id> + <!-- + <segmentation type="PolarGridRPhi" grid_size_phi="3.0*degree" grid_size_r="5.0*cm"/> + <id>system:5,barrel:3,layer:4,module:5,r:32:-16,phi:-16</id> + --> + </readout> +``` + +Note the `grid_size_x` and `grid_size_y` attributes with values corresponding to the sizes above. +In the `CartesianGridXY` case, the cell sizes are always the same. + +#### Change the segmentation + +1. Swap in the comment on segmentation and id to create the `PolarGridRPhi` segmentation. Should look like this: +```xml + <readout name="GEMTrackerHits"> + <segmentation type="PolarGridRPhi" grid_size_phi="3.0*degree" grid_size_r="5.0*cm"/> + <id>system:5,barrel:3,layer:4,module:5,r:32:-16,phi:-16</id> + </readout> +``` +2. Re-run npsim command above. +3. Re-run the root script: +```bash +root -b -q scripts/tutorial2_cell_size.cxx+ +``` + +The output should look similar +```bash +... +Segmentation-Cell Position : -96.44711531372378,-62.6334890267281,-100 + dim 5, 6.02139, + Hit Position : 34.53880143830617,-11.266496282927323,-60 +Segmentation-Cell Position : 33.28697807033037,-10.815594803123158,-60 + dim 5, 1.8326, + Hit Position : 46.356572126864805,-13.944556949561113,-80 +Segmentation-Cell Position : 47.552825814757675,-15.450849718747369,-80 + dim 5, 2.61799, +... ``` +Note that the dimensions of the cell in one direction is changing the rho coordinate! +This is expected because the cell has dimensions rho =x and r*dphi = y. + +Here we point out that access to this information is very useful. +For example, a tracking covariance matrix could be computed using this method, again coming (dynamically) from a single source geometry description. + ### Id Specification +The cell ID is a 64bit integer with field names assigned to a few bits. +Looking at the id specification we see the following: +```xml + <segmentation type="PolarGridRPhi" grid_size_phi="3.0*degree" grid_size_r="5.0*cm"/> + <id>system:5,barrel:3,layer:4,module:5,r:32:-16,phi:-16</id> +``` +This means there are 5 bits associated with system (this is the `<detector>`'s `id`) this field is mandatory but can differ from 5 bits. +The subsequent fields are arbitrary but should result in a unique 64 bit integer. +Here 3 bits for the "barrel", 4 bits for a "layer", 5 bits for the "module". +More bit fields could be allocated if desired (in part 2 it will become clear why we might want to do this). +The last two bit fields start at the 32nd bit, leaving 15 unused bits. These "r" and "phi" fields are not associated with physical volumes but rather the 2D segmentation above. The segmentation is a virtual geometry applied the smallest geometry volumes (nodes). So the last 32 bits are split between these two fields and are signed. + +Note the concept of a `VolumeID` is essentially equal to `CellID` but where the bits in `CellID` associated with a segmentation are set to zero. `VolumeID`s are associated with actual constructed and placed volumes. + +Run the example: + ```bash root -b -q scripts/tutorial3_id_spec.cxx+ ``` +You should see this (with the R-phi segmentation) +```bash +ID specification: +system:0:5,barrel:5:3,layer:8:4,module:12:5,r:32:-16,phi:48:-16 + "layer" index is 2. +``` + +or this with the XY grid segmentation: + +```bash +ID specification: +system:0:8,barrel:8:2,layer:10:4,module:14:12,sensor:26:2,x:32:-16,y:48:-16 + "layer" index is 2. +``` + +This comes from the snippet at the initialization stage: + ```cpp - fmt::print("--------------------------\n"); fmt::print("ID specification:\n"); auto decoder = detector.readout("GEMTrackerHits").idSpec().decoder(); fmt::print("{}\n", decoder->fieldDescription()); auto layer_index = decoder->index("layer"); fmt::print(" \"layer\" index is {}.\n", layer_index); ``` + +This gets an index for the named field "layer" and initializes a decoder. See [BitFieldCoder documentation](https://dd4hep.web.cern.ch/dd4hep/reference/classdd4hep_1_1DDSegmentation_1_1BitFieldCoder.html) documentation for more details. Later in the loop over event hits. @@ -199,18 +323,9 @@ Later in the loop over event hits. Note the `layer_index` is computed once in the beginning when the decoder is also initialized. This means it will be fast because it only parses the ID specification string once. -```bash -ID specification: -system:0:5,barrel:5:3,layer:8:4,module:12:5,r:32:-16,phi:48:-16 - "layer" index is 2. -``` -or -```bash -ID specification: -system:0:8,barrel:8:2,layer:10:4,module:14:12,sensor:26:2,x:32:-16,y:48:-16 - "layer" index is 2. -``` - +The statement above selects for the interior layers number 4 and 5: +Look at the generated plot in `results`: + ## References -- GitLab