File indexing completed on 2025-07-15 08:15:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include "FCC_OtherDetectorHelpers.h"
0011
0012
0013
0014 #define endmsg std::endl
0015 #define lLog std::cout
0016 namespace MSG {
0017 const std::string DEBUG = " Debug: ";
0018 }
0019
0020 #include "DD4hep/DD4hepUnits.h"
0021 #include "DD4hep/DetFactoryHelper.h"
0022 #include <cmath>
0023 #include <string>
0024
0025 using dd4hep::Assembly;
0026 using dd4hep::ConeSegment;
0027 using dd4hep::DetElement;
0028 using dd4hep::Detector;
0029 using dd4hep::Material;
0030 using dd4hep::PlacedVolume;
0031 using dd4hep::Position;
0032 using dd4hep::Ref_t;
0033 using dd4hep::RotateY;
0034 using dd4hep::RotationY;
0035 using dd4hep::SensitiveDetector;
0036 using dd4hep::Solid;
0037 using dd4hep::SubtractionSolid;
0038 using dd4hep::Transform3D;
0039 using dd4hep::Tube;
0040 using dd4hep::Volume;
0041
0042 static Ref_t create_element(Detector& theDetector, xml_h xmlHandle, SensitiveDetector ) {
0043
0044
0045
0046
0047
0048
0049 xml_det_t xmlMask = xmlHandle;
0050 const std::string name = xmlMask.nameStr();
0051
0052
0053 Assembly envelope(name + "_assembly");
0054
0055
0056 DetElement tube(name, xmlMask.id());
0057
0058 const double phi1 = 0;
0059 const double phi2 = 360.0 * dd4hep::degree;
0060
0061
0062 dd4hep::xml::Component xmlParameter = xmlMask.child(_Unicode(parameter));
0063 const double crossingAngle = xmlParameter.attr<double>(_Unicode(crossingangle)) * 0.5;
0064
0065 for (xml_coll_t c(xmlMask, Unicode("section")); c; ++c) {
0066
0067 xml_comp_t xmlSection(c);
0068
0069 ODH::ECrossType crossType = ODH::getCrossType(xmlSection.attr<std::string>(_Unicode(type)));
0070 const double zStart = xmlSection.attr<double>(_Unicode(start));
0071 const double zEnd = xmlSection.attr<double>(_Unicode(end));
0072 const double rInnerStart = xmlSection.attr<double>(_Unicode(rMin1));
0073 const double rInnerEnd = xmlSection.attr<double>(_Unicode(rMin2));
0074 const double rOuterStart = xmlSection.attr<double>(_Unicode(rMax1));
0075 const double rOuterEnd = xmlSection.attr<double>(_Unicode(rMax2));
0076 const double thickness = rOuterStart - rInnerStart;
0077 Material sectionMat = theDetector.material(xmlSection.materialStr());
0078 const std::string volName = "tube_" + xmlSection.nameStr();
0079
0080 lLog << MSG::DEBUG << std::setw(8) << zStart << std::setw(8) << zEnd << std::setw(8) << rInnerStart << std::setw(8)
0081 << rInnerEnd << std::setw(8) << rOuterStart << std::setw(8) << rOuterEnd << std::setw(8) << thickness
0082 << std::setw(8) << crossType << std::setw(15) << volName << std::setw(15) << sectionMat.name()
0083 << endmsg;
0084
0085
0086 const double zHalf = fabs(zEnd - zStart) * 0.5;
0087 const double zPosition = fabs(zEnd + zStart) * 0.5;
0088 Material material = sectionMat;
0089
0090
0091 if (not ODH::checkForSensibleGeometry(crossingAngle, crossType)) {
0092 throw std::runtime_error(" Mask_o1_v01_geo.cpp : checkForSensibleGeometry() failed ");
0093 }
0094
0095 const double rotateAngle =
0096 getCurrentAngle(crossingAngle, crossType);
0097 const double mirrorAngle = M_PI - rotateAngle;
0098
0099
0100 switch (crossType) {
0101 case ODH::kCenter:
0102 case ODH::kUpstream:
0103 case ODH::kDnstream: {
0104
0105
0106
0107 Transform3D transformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle));
0108 Transform3D transmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle));
0109
0110
0111 ConeSegment tubeSolid(zHalf, rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, phi1, phi2);
0112
0113
0114 Volume tubeLog(volName, tubeSolid, material);
0115 tubeLog.setVisAttributes(theDetector, xmlMask.visStr());
0116
0117
0118 envelope.placeVolume(tubeLog, transformer);
0119 envelope.placeVolume(tubeLog, transmirror);
0120
0121 } break;
0122
0123 case ODH::kPunchedCenter: {
0124
0125
0126 const double rUpstreamPunch = rInnerStart;
0127 const double rDnstreamPunch = rInnerEnd;
0128
0129
0130 Transform3D upstreamTransformer(RotationY(-crossingAngle), Position(zPosition * tan(-crossingAngle), 0, 0));
0131 Transform3D dnstreamTransformer(RotationY(+crossingAngle), Position(zPosition * tan(+crossingAngle), 0, 0));
0132
0133
0134 Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle));
0135 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle));
0136
0137
0138 ConeSegment wholeSolid(zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2);
0139 Solid tmpSolid0, tmpSolid1, finalSolid0, finalSolid1;
0140
0141
0142
0143
0144
0145 if (rUpstreamPunch > 1e-6) {
0146 Tube upstreamPunch(0, rUpstreamPunch, 5 * zHalf, phi1, phi2);
0147 tmpSolid0 = SubtractionSolid(wholeSolid, upstreamPunch, upstreamTransformer);
0148 tmpSolid1 = SubtractionSolid(wholeSolid, upstreamPunch, dnstreamTransformer);
0149 } else {
0150 tmpSolid0 = wholeSolid;
0151 tmpSolid1 = wholeSolid;
0152 }
0153
0154 if (rDnstreamPunch > 1e-6) {
0155 Tube dnstreamPunch(0, rDnstreamPunch, 5 * zHalf, phi1, phi2);
0156 finalSolid0 = SubtractionSolid(tmpSolid0, dnstreamPunch, dnstreamTransformer);
0157 finalSolid1 = SubtractionSolid(tmpSolid1, dnstreamPunch, upstreamTransformer);
0158 } else {
0159 finalSolid0 = tmpSolid0;
0160 finalSolid1 = tmpSolid1;
0161 }
0162
0163
0164 Volume tubeLog0(volName + "_0", finalSolid0, material);
0165 Volume tubeLog1(volName + "_1", finalSolid1, material);
0166 tubeLog0.setVisAttributes(theDetector, xmlMask.visStr());
0167 tubeLog1.setVisAttributes(theDetector, xmlMask.visStr());
0168
0169
0170 envelope.placeVolume(tubeLog0, placementTransformer);
0171 envelope.placeVolume(tubeLog1, placementTransmirror);
0172
0173 break;
0174 }
0175
0176 case ODH::kPunchedUpstream:
0177 case ODH::kPunchedDnstream: {
0178
0179
0180
0181 const double rCenterPunch = (crossType == ODH::kPunchedUpstream)
0182 ? (rInnerStart)
0183 : (rInnerEnd);
0184 const double rOffsetPunch = (crossType == ODH::kPunchedDnstream)
0185 ? (rInnerStart)
0186 : (rInnerEnd);
0187
0188
0189 Transform3D punchTransformer(RotationY(-2 * rotateAngle), Position(zPosition * tan(-2 * rotateAngle), 0, 0));
0190 Transform3D punchTransmirror(RotationY(+2 * rotateAngle), Position(zPosition * tan(+2 * rotateAngle), 0, 0));
0191
0192
0193 Transform3D placementTransformer(RotationY(rotateAngle), RotateY(Position(0, 0, zPosition), rotateAngle));
0194 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY(Position(0, 0, zPosition), mirrorAngle));
0195
0196
0197 ConeSegment wholeSolid(zHalf, rCenterPunch, rOuterStart, rCenterPunch, rOuterEnd, phi1, phi2);
0198 Tube punchSolid(0, rOffsetPunch, 5 * zHalf, phi1, phi2);
0199
0200
0201
0202
0203 SubtractionSolid finalSolid0(wholeSolid, punchSolid, punchTransformer);
0204 SubtractionSolid finalSolid1(wholeSolid, punchSolid, punchTransmirror);
0205
0206
0207 Volume tubeLog0(volName + "_0", finalSolid0, material);
0208 Volume tubeLog1(volName + "_1", finalSolid1, material);
0209 tubeLog0.setVisAttributes(theDetector, xmlMask.visStr());
0210 tubeLog1.setVisAttributes(theDetector, xmlMask.visStr());
0211
0212
0213 envelope.placeVolume(tubeLog0, placementTransformer);
0214 envelope.placeVolume(tubeLog1, placementTransmirror);
0215
0216 break;
0217 }
0218 default: { throw std::runtime_error(" Mask_o1_v01_geo.cpp : fatal failure !! ?? "); }
0219
0220 }
0221 }
0222
0223
0224 Volume mother = theDetector.pickMotherVolume(tube);
0225 PlacedVolume pv(mother.placeVolume(envelope));
0226 pv.addPhysVolID("system", xmlMask.id());
0227
0228 tube.setVisAttributes(theDetector, xmlMask.visStr(), envelope);
0229
0230 tube.setPlacement(pv);
0231
0232 return tube;
0233 }
0234 DECLARE_DETELEMENT(DD4hep_FCC_Mask_o1_v01, create_element)