diff --git a/compact/display_detailed.xml b/compact/display_detailed.xml
index 896000a00..69fde959c 100644
--- a/compact/display_detailed.xml
+++ b/compact/display_detailed.xml
@@ -128,10 +128,11 @@
-
+
+
diff --git a/compact/pid/drich.xml b/compact/pid/drich.xml
index cde823bfa..927e0e836 100644
--- a/compact/pid/drich.xml
+++ b/compact/pid/drich.xml
@@ -43,6 +43,12 @@
+
+
+
+
+
+
- `DRICH_debug_optics`: 1 = all components become vacuum, except for mirrors; test opticalphotons from IP
2 = all components become vacuum, except for mirrors and `gasvol`, test charged particles from IP
@@ -121,6 +127,9 @@
- `rmin` and `rmax`: inner and outer radius (at the front plane; radial bounds are conical)
- `thickness`: radiator thickness, defined separately for aerogel and filter
- `pitch`: controls the angle of the radiator (0=vertical)
+ - `segmentations`:controls tiling method. They can be "trapezoidal", "square" or "unique".
+ A unique segmentation means, no tiling of aerogel.
+
+
+#include
+#include
#include
@@ -80,21 +75,27 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec
auto radiatorRmax = radiatorElem.attr(_Unicode(rmax));
auto radiatorPitch = radiatorElem.attr(_Unicode(pitch));
auto radiatorFrontplane = radiatorElem.attr(_Unicode(frontplane));
-
// - aerogel
auto aerogelElem = radiatorElem.child(_Unicode(aerogel));
auto aerogelMatName = aerogelElem.attr(_Unicode(material));
auto aerogelMat = desc.material(aerogelMatName);
auto aerogelVis = desc.visAttributes(aerogelElem.attr(_Unicode(vis)));
auto aerogelThickness = aerogelElem.attr(_Unicode(thickness));
-
+ // - aerogel structure
+ auto coronasElem = radiatorElem.child(_Unicode(coronas));
+ auto coronasMat = desc.material(coronasElem.attr(_Unicode(material)));
+ auto coronasVis = desc.visAttributes(coronasElem.attr(_Unicode(vis)));
+ auto coronasThickness = coronasElem.attr(_Unicode(thickness));
+ int numCrowns = coronasElem.attr(_Unicode(num));
+ auto segmentationType = coronasElem.attr("segmentation");
+ auto segmentsStr = coronasElem.attr(_Unicode(num_segments));
+ auto radiiStr = coronasElem.attr(_Unicode(radii));
// - filter
auto filterElem = radiatorElem.child(_Unicode(filter));
auto filterMatName = filterElem.attr(_Unicode(material));
auto filterMat = desc.material(filterMatName);
auto filterVis = desc.visAttributes(filterElem.attr(_Unicode(vis)));
auto filterThickness = filterElem.attr(_Unicode(thickness));
-
// - airgap between filter and aerogel
auto airgapElem = radiatorElem.child(_Unicode(airgap));
auto airgapMat = desc.material(airgapElem.attr(_Unicode(material)));
@@ -340,39 +341,161 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec
// BUILD RADIATOR ====================================================================
// solid and volume: create aerogel and filter
- Cone aerogelSolid(aerogelThickness / 2, radiatorRmin, radiatorRmax,
- radiatorRmin + boreDelta * aerogelThickness / vesselLength,
- radiatorRmax + snoutDelta * aerogelThickness / snoutLength);
- Cone airgapSolid(airgapThickness / 2, radiatorRmin + boreDelta * aerogelThickness / vesselLength,
+
+ // ------------------------------------------------------------------------
+ Cone aerogelSolid(aerogelThickness / 2.0, radiatorRmin, radiatorRmax,
+ radiatorRmin + boreDelta * aerogelThickness / vesselLength, radiatorRmax);
+
+ Volume aerogelVol;
+ double halfAerogelThickness = aerogelThickness / 2.0;
+ const int nHalves = 2;
+ std::vector numSegments;
+ std::stringstream ss(segmentsStr);
+ std::string val;
+ while (std::getline(ss, val, ',')) {
+ numSegments.push_back(std::stoi(val));
+ }
+
+ std::vector radii;
+ std::stringstream radiiSS(radiiStr);
+ std::string radius;
+ while (std::getline(radiiSS, radius, ',')) {
+ radii.push_back(std::stod(radius));
+ }
+ auto radiatorPos = Position(0., 0., radiatorFrontplane + 0.5 * aerogelThickness) + originFront;
+ auto aerogelPlacement = Translation3D(radiatorPos) * RotationY(radiatorPitch);
+
+ aerogelVol = Volume(detName + "_aerogel", aerogelSolid, aerogelMat);
+ aerogelVol.setVisAttributes(aerogelVis);
+ auto aerogelPV = gasvolVol.placeVolume(aerogelVol, aerogelPlacement);
+ DetElement aerogelDE(det, "aerogel_de", 0);
+ aerogelDE.setPlacement(aerogelPV);
+
+ if (segmentationType == "trapezoidal") {
+ double crownHeight = halfAerogelThickness;
+ std::vector innerRadiusBottoms_half[nHalves];
+ std::vector innerRadiusTops_half[nHalves];
+ std::vector outerRadiusBottoms_half[nHalves];
+ std::vector outerRadiusTops_half[nHalves];
+ std::vector crownSolids[nHalves];
+ std::vector segmentSolids[nHalves];
+ Solid crownSolidUnion_half[nHalves], segmentSolidUnion_half[nHalves],
+ crownAndSegmentSolid_half[nHalves];
+ // ------------------------------------------------------------------------
+ // HALF 1
+ // ------------------------------------------------------------------------
+ for (int h = 0; h < nHalves; h++) {
+ //double zPos_half = (pow(-1,(h+1)))*crownHeight / 2.0;
+ for (int i = 0; i < numCrowns; i++) {
+ double centralRadius = radii[i];
+ double rMinBottom, rMinTop, rMaxBottom, rMaxTop;
+
+ if (i == 0) {
+ rMinBottom = centralRadius - boreDelta * (coronasThickness / 2.0) / vesselLength;
+ rMinTop = rMinBottom + snoutDelta * halfAerogelThickness / snoutLength;
+ rMaxBottom = rMinBottom + boreDelta * coronasThickness / vesselLength;
+ rMaxTop = rMinTop + boreDelta * coronasThickness / vesselLength;
+ } else {
+ double innerRadius = centralRadius - coronasThickness / 2.0;
+ double outerRadius = centralRadius + coronasThickness / 2.0;
+
+ // FIX PROTRUSION
+ if (i == numCrowns - 1) {
+ double safetyMargin = 0.05 * dd4hep::cm;
+ outerRadius -= safetyMargin;
+ }
+
+ rMinBottom = innerRadius;
+ rMinTop = innerRadius;
+ rMaxBottom = outerRadius;
+ rMaxTop = outerRadius;
+ }
+
+ innerRadiusBottoms_half[h].push_back(rMinBottom);
+ innerRadiusTops_half[h].push_back(rMinTop);
+ outerRadiusBottoms_half[h].push_back(rMaxBottom);
+ outerRadiusTops_half[h].push_back(rMaxTop);
+
+ Cone crownSolid(crownHeight / 2.0, rMinBottom, rMaxBottom, rMinTop, rMaxTop);
+ crownSolids[h].push_back(crownSolid);
+ std::string crownName = "CarbonCrown_Half1_" + std::to_string(i);
+ Volume crownVol(crownName, crownSolid, coronasMat);
+ crownVol.setVisAttributes(coronasVis);
+ //aerogelVol.placeVolume(crownVol, Position(0., 0., zPos_half1));
+ }
+ crownSolidUnion_half[h] = std::accumulate(
+ crownSolids[h].begin() + 1, crownSolids[h].end(), crownSolids[h][0],
+ [](const Solid& a, const Solid& b) { return UnionSolid(a, b, Position(0., 0., 0.)); });
+
+ // ---- Segments Half 1 -----
+ for (int i = 0; i < numCrowns - 1; i++) {
+ int N = numSegments[i];
+
+ double rMin_Zminus = outerRadiusBottoms_half[h][i];
+ double rMax_Zminus = innerRadiusBottoms_half[h][i + 1];
+ double rMin_Zplus = outerRadiusTops_half[h][i];
+ double rMax_Zplus = innerRadiusTops_half[h][i + 1];
+
+ double segmentSpacing = 2 * M_PI / N;
+ double segmentAngularWidth = coronasThickness / rMin_Zminus;
+
+ for (int p = 0; p < N; p++) {
+ double phiStart = p * segmentSpacing;
+ double phiEnd = phiStart + segmentAngularWidth;
+
+ ConeSegment segmentSolid(crownHeight / 2.0, rMin_Zminus, rMax_Zminus, rMin_Zplus,
+ rMax_Zplus, phiStart, phiEnd);
+ segmentSolids[h].push_back(segmentSolid);
+ std::string segName =
+ "CarbonSegment_Half1_" + std::to_string(i) + "_" + std::to_string(p);
+ Volume segVol(segName, segmentSolid, coronasMat);
+ segVol.setVisAttributes(coronasVis);
+ //aerogelVol.placeVolume(segVol, Position(0., 0., zPos_half));
+ }
+ } //crown
+
+ segmentSolidUnion_half[h] = std::accumulate(
+ segmentSolids[h].begin() + 1, segmentSolids[h].end(), segmentSolids[h][0],
+ [](const Solid& a, const Solid& b) { return UnionSolid(a, b, Position(0., 0., 0.)); });
+
+ crownAndSegmentSolid_half[h] = UnionSolid(crownSolidUnion_half[h], segmentSolidUnion_half[h]);
+ } //halves
+ std::string crName[2] = {"_crown_and_segment_1", "_crown_and_segment_2"};
+
+ for (int h = 0; h < nHalves; h++) {
+ // aerogel structure positioning
+ double localZ = pow(-1, h + 1) * 0.5 * crownHeight;
+ Transform3D placement = Transform3D(RotationY(radiatorPitch), Position(0., 0., localZ));
+ Volume crownAndSegmentVolume(detName + crName[h], crownAndSegmentSolid_half[h], coronasMat);
+ crownAndSegmentVolume.setVisAttributes(coronasVis);
+ auto crownPV = aerogelVol.placeVolume(crownAndSegmentVolume, placement);
+ DetElement crownDE(det, crName[h], 0);
+ crownDE.setPlacement(crownPV);
+ }
+ } //trapezoidal
+
+ else if (segmentationType == "square") {
+ printout(WARNING, "DRICH_geo", "Square segmentation requested but not implemented yet.");
+ } //Square
+
+ Cone airgapSolid(airgapThickness / 2.0,
+ radiatorRmin + boreDelta * aerogelThickness / vesselLength,
radiatorRmax + snoutDelta * aerogelThickness / snoutLength,
radiatorRmin + boreDelta * (aerogelThickness + airgapThickness) / vesselLength,
radiatorRmax + snoutDelta * (aerogelThickness + airgapThickness) / snoutLength);
Cone filterSolid(
- filterThickness / 2,
+ filterThickness / 2.0,
radiatorRmin + boreDelta * (aerogelThickness + airgapThickness) / vesselLength,
radiatorRmax + snoutDelta * (aerogelThickness + airgapThickness) / snoutLength,
radiatorRmin +
boreDelta * (aerogelThickness + airgapThickness + filterThickness) / vesselLength,
radiatorRmax +
snoutDelta * (aerogelThickness + airgapThickness + filterThickness) / snoutLength);
-
- Volume aerogelVol(detName + "_aerogel", aerogelSolid, aerogelMat);
Volume airgapVol(detName + "_airgap", airgapSolid, airgapMat);
Volume filterVol(detName + "_filter", filterSolid, filterMat);
- aerogelVol.setVisAttributes(aerogelVis);
airgapVol.setVisAttributes(airgapVis);
filterVol.setVisAttributes(filterVis);
- // aerogel placement and surface properties
- // TODO [low-priority]: define skin properties for aerogel and filter
- // FIXME: radiatorPitch might not be working correctly (not yet used)
- auto radiatorPos = Position(0., 0., radiatorFrontplane + 0.5 * aerogelThickness) + originFront;
- auto aerogelPlacement = Translation3D(radiatorPos) * // re-center to originFront
- RotationY(radiatorPitch); // change polar angle to specified pitch
- auto aerogelPV = gasvolVol.placeVolume(aerogelVol, aerogelPlacement);
- DetElement aerogelDE(det, "aerogel_de", 0);
- aerogelDE.setPlacement(aerogelPV);
-
// airgap and filter placement and surface properties
if (!debugOptics) {
@@ -868,9 +991,9 @@ static Ref_t createDetector(Detector& desc, xml::Handle_t handle, SensitiveDetec
addVecToMap("pos", sensorPos);
addVecToMap("normX", sensorNormX);
addVecToMap("normY", sensorNormY);
- printout(VERBOSE, "DRICH_geo", "sensor %s:", sensorIDname.c_str());
+ printout(DEBUG, "DRICH_geo", "sensor %s:", sensorIDname.c_str());
for (auto kv : pssVarMap->variantParameters)
- printout(VERBOSE, "DRICH_geo", " %s: %f", kv.first.c_str(),
+ printout(DEBUG, "DRICH_geo", " %s: %f", kv.first.c_str(),
pssVarMap->get(kv.first));
#endif
printout(DEBUG, "DRICH_geo", "sensor %s:", sensorIDname.c_str());