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