From d630b01ebee28d76fa17aa23cefa8e5a09c01c38 Mon Sep 17 00:00:00 2001
From: Whitney Armstrong <warmstrong@anl.gov>
Date: Fri, 21 May 2021 03:09:33 -0500
Subject: [PATCH] 	modified:   part2/adding_detectors.md

---
 src/docs/part2/adding_detectors.md | 167 ++++++++++++++++++++++++++---
 1 file changed, 153 insertions(+), 14 deletions(-)

diff --git a/src/docs/part2/adding_detectors.md b/src/docs/part2/adding_detectors.md
index 1529eba..2fa7f4f 100644
--- a/src/docs/part2/adding_detectors.md
+++ b/src/docs/part2/adding_detectors.md
@@ -2,20 +2,6 @@
 title: 'Tutorial Part 2: Modifying and Adding Detectors '
 ---
 
-  * [Introduction](#introduction)
-  * [How to build a detector from scratch](#how-to-build-a-detector-from-scratch)
-    + [Compiling a new detector](#compiling-a-new-detector)
-    + [Building the geometry](#building-the-geometry)
-      - [Compact detector description entry element](#compact-detector-description-entry-element)
-      - [Geometry Construction](#geometry-construction)
-        * [XML Parsing Tip : Provide good default values](#xml-parsing-tip--provide-good-default-values)
-      - [Critical parts of build_detector](#critical-parts-of-build_detector)
-  * [The Readout and Bit Fields](#the-readout-and-bit-fields)
-  * [Simple Reconstruction Overview of scripts](#simple-reconstruction-overview-of-scripts)
-    + [Dependencies](#dependencies)
-    + [Running the scripts](#running-the-scripts)
-    + [To Do](#to-do)
-
 ## Setup 
 
 Note all these commands assume you are in an `eic-shell` singularity session.
@@ -315,4 +301,157 @@ And have a look at the detector part of the compact file.
 
 Here you see a different strategy: build a module, then build layers constructed from the module. 
 
+Here is the detector constructor function
+```cpp
+static Ref_t create_detector(Detector& description, xml_h e, SensitiveDetector sens) {
+  typedef vector<PlacedVolume> Placements;
+  xml_det_t                    x_det    = e;
+  Material                     vacuum   = description.vacuum();
+  int                          det_id   = x_det.id();
+  string                       det_name = x_det.nameStr();
+  bool                         reflect  = x_det.reflect(false);
+  DetElement                   sdet(det_name, det_id);
+  Assembly                     assembly(det_name);
+  Volume                       motherVol = description.pickMotherVolume(sdet);
+  int                          m_id = 0, c_id = 0, n_sensor = 0;
+  map<string, Volume>          modules;
+  map<string, Placements>      sensitives;
+  PlacedVolume                 pv;
+
+  assembly.setVisAttributes(description.invisible());
+  sens.setType("tracker");
+
+  // Loop over and build modules
+  for (xml_coll_t mi(x_det, _U(module)); mi; ++mi, ++m_id) {
+    xml_comp_t x_mod = mi;
+    string     m_nam = x_mod.nameStr();
+    xml_comp_t trd   = x_mod.trd();
+    double     posY;
+    double     x1 = trd.x1();
+    double     x2 = trd.x2();
+    double     z  = trd.z();
+    double     y1, y2, total_thickness = 0.;
+    xml_coll_t ci(x_mod, _U(module_component));
+    for (ci.reset(), total_thickness = 0.0; ci; ++ci)
+      total_thickness += xml_comp_t(ci).thickness();
+
+    y1 = y2 = total_thickness / 2;
+    Volume m_volume(m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum);
+    m_volume.setVisAttributes(description.visAttributes(x_mod.visStr()));
+
+    for (ci.reset(), n_sensor = 1, c_id = 0, posY = -y1; ci; ++ci, ++c_id) {
+      xml_comp_t c           = ci;
+      double     c_thick     = c.thickness();
+      auto       comp_x1     = getAttrOrDefault(c, _Unicode(x1), x1);
+      auto       comp_x2     = getAttrOrDefault(c, _Unicode(x2), x2);
+      auto       comp_height = getAttrOrDefault(c, _Unicode(height), z);
+
+      Material c_mat  = description.material(c.materialStr());
+      string   c_name = _toString(c_id, "component%d");
+      Volume   c_vol(c_name, Trapezoid(comp_x1, comp_x2, c_thick / 2e0, c_thick / 2e0, comp_height), c_mat);
+
+      // use the module vis attributes if not set for component.
+      auto comp_vis = x_mod.visStr();
+      if(( c.visStr().size() >0 ) ) {
+        comp_vis = c.visStr();
+      }
+
+      c_vol.setVisAttributes(description.visAttributes(comp_vis));
+      pv = m_volume.placeVolume(c_vol, Position(0, posY + c_thick / 2, 0));
+      if (c.isSensitive()) {
+        sdet.check(n_sensor > 2, "SiTrackerEndcap2::fromCompact: " + c_name + " Max of 2 modules allowed!");
+        pv.addPhysVolID("sensor", n_sensor);
+        c_vol.setSensitiveDetector(sens);
+        sensitives[m_nam].push_back(pv);
+        ++n_sensor;
+      }
+      posY += c_thick;
+    }
+    // Modules are stored here
+    modules[m_nam] = m_volume;
+  }
+
+  // Construct each layer
+  for (xml_coll_t li(x_det, _U(layer)); li; ++li) {
+    xml_comp_t x_layer(li);
+    int        l_id    = x_layer.id();
+    int        mod_num = 1;
+    for (xml_coll_t ri(x_layer, _U(ring)); ri; ++ri) {
+      xml_comp_t  x_ring   = ri;
+      double      r        = x_ring.r();
+      double      phi0     = x_ring.phi0(0);
+      double      zstart   = x_ring.zstart();
+      double      dz       = x_ring.dz(0);
+      int         nmodules = x_ring.nmodules();
+      string      m_nam    = x_ring.moduleStr();
+      Volume      m_vol    = modules[m_nam];
+      double      iphi     = 2 * M_PI / nmodules;
+      double      phi      = phi0;
+      Placements& sensVols = sensitives[m_nam];
+
+      for (int k = 0; k < nmodules; ++k) {
+        string     m_base = _toString(l_id, "layer%d") + _toString(mod_num, "_module%d");
+        double     x      = -r * std::cos(phi);
+        double     y      = -r * std::sin(phi);
+        DetElement module(sdet, m_base + "_pos", det_id);
+        pv = assembly.placeVolume(m_vol,
+                                  Transform3D(RotationZYX(0, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, zstart + dz)));
+        pv.addPhysVolID("barrel", 1).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
+        module.setPlacement(pv);
+        for (size_t ic = 0; ic < sensVols.size(); ++ic) {
+          PlacedVolume sens_pv = sensVols[ic];
+          DetElement   comp_elt(module, sens_pv.volume().name(), mod_num);
+          comp_elt.setPlacement(sens_pv);
+        }
+
+        if (reflect) {
+          pv = assembly.placeVolume(
+              m_vol, Transform3D(RotationZYX(M_PI, -M_PI / 2 - phi, -M_PI / 2), Position(x, y, -zstart - dz)));
+          pv.addPhysVolID("barrel", 2).addPhysVolID("layer", l_id).addPhysVolID("module", mod_num);
+          DetElement r_module(sdet, m_base + "_neg", det_id);
+          r_module.setPlacement(pv);
+          for (size_t ic = 0; ic < sensVols.size(); ++ic) {
+            PlacedVolume sens_pv = sensVols[ic];
+            DetElement   comp_elt(r_module, sens_pv.volume().name(), mod_num);
+            comp_elt.setPlacement(sens_pv);
+          }
+        }
+        dz = -dz;
+        phi += iphi;
+        ++mod_num;
+      }
+    }
+  }
+  pv = motherVol.placeVolume(assembly);
+  pv.addPhysVolID("system", det_id);
+  sdet.setPlacement(pv);
+  return sdet;
+}
+
+// clang-format off
+DECLARE_DETELEMENT(TrapEndcapTracker, create_detector)
+DECLARE_DETELEMENT(MyGEMTrackerEndcap, create_detector)
+```
+
+![gem tracker](../gem_tracker_part2.png)
+
+
+## Hands on challenges
+
+### Update gem tracker 
+
+Swap out the gem tracker from part 1 with the detailed construction. 
+
+### Add top and bottom support for the GEM foil frame.
+
+There is a side currently there
+
+### Make the modules overlap
+
+Currently the modules do not overlap much. Can you come up with a way to modify to get a nice overlap?
+
+### What bug exists with the negative endcap?
+
+If you uncomment the negative endcap, can you find out what is wrong with the construction?
+
 
-- 
GitLab