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