File indexing completed on 2025-01-30 09:17:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include "DDDetectors/OtherDetectorHelpers.h"
0012
0013 #include "DD4hep/DetFactoryHelper.h"
0014 #include "DD4hep/Printout.h"
0015 #include "DD4hep/DD4hepUnits.h"
0016 #include "DD4hep/DetType.h"
0017 #include "DDRec/DetectorData.h"
0018 #include "XML/Utilities.h"
0019
0020 #include <cmath>
0021 #include <string>
0022
0023 using dd4hep::Transform3D;
0024 using dd4hep::Position;
0025 using dd4hep::RotationX;
0026 using dd4hep::RotationY;
0027 using dd4hep::RotateY;
0028 using dd4hep::RotateX;
0029 using dd4hep::ConeSegment;
0030 using dd4hep::SubtractionSolid;
0031 using dd4hep::Material;
0032 using dd4hep::Volume;
0033 using dd4hep::Solid;
0034 using dd4hep::Tube;
0035 using dd4hep::PlacedVolume;
0036 using dd4hep::Assembly;
0037 using dd4hep::Detector;
0038 using dd4hep::SensitiveDetector;
0039 using dd4hep::Ref_t;
0040
0041 namespace units = dd4hep;
0042
0043
0044 static Ref_t create_detector(Detector& description,
0045 xml_h xmlHandle,
0046 SensitiveDetector sens) {
0047
0048 printout(dd4hep::DEBUG,"DD4hep_Mask", "Creating Mask" ) ;
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 dd4hep::DetElement tube( name, xmlMask.id() ) ;
0059
0060 bool rotationX= false;
0061
0062
0063 dd4hep::xml::Component xmlParameter = xmlMask.child(_Unicode(parameter));
0064 const double crossingAngle = xmlParameter.attr< double >(_Unicode(crossingangle))*0.5;
0065
0066 if (xmlParameter.hasAttr(_Unicode(rotationX)))
0067 rotationX = xmlParameter.attr< bool >(_Unicode(rotationX));
0068
0069 int counter = 0;
0070 for(xml_coll_t c( xmlMask ,Unicode("section")); c; ++c, counter++) {
0071
0072 xml_comp_t xmlSection( c );
0073 bool isSensitive = false;
0074 ODH::ECrossType crossType = ODH::getCrossType(xmlSection.attr< std::string >(_Unicode(type)));
0075 const double zStart = xmlSection.attr< double > (_Unicode(start));
0076 const double zEnd = xmlSection.attr< double > (_Unicode(end));
0077 const double rInnerStart = xmlSection.attr< double > (_Unicode(rMin1));
0078 const double rInnerEnd = xmlSection.attr< double > (_Unicode(rMin2));
0079 const double rOuterStart = xmlSection.attr< double > (_Unicode(rMax1));
0080 const double rOuterEnd = xmlSection.attr< double > (_Unicode(rMax2));
0081 const double thickness = rOuterStart - rInnerStart;
0082 Material sectionMat = description.material(xmlSection.materialStr());
0083 const std::string volName = "tube_" + xmlSection.nameStr();
0084
0085 double phi1 = 0 ;
0086 double phi2 = 360.0*units::degree;
0087 if (xmlSection.hasAttr(_U(phi1)))
0088 phi1 = xmlSection.attr< double > (_U(phi1));
0089 if (xmlSection.hasAttr(_U(phi2)))
0090 phi2 = xmlSection.attr< double > (_U(phi2));
0091
0092 std::string ssensitive = "none";
0093 if (xmlSection.hasAttr(_U(sensitive))){
0094 isSensitive = true;
0095 ssensitive = xmlSection.attr< std::string > (_U(sensitive));
0096 sens.setType( xmlSection.attr< std::string > (_U(sensitive)) );
0097 printout(dd4hep::DEBUG, "sensitive in sens ", ssensitive);
0098 }
0099
0100
0101 std::stringstream pipeInfo;
0102 pipeInfo << std::setw(8) << zStart /units::mm
0103 << std::setw(8) << zEnd /units::mm
0104 << std::setw(8) << rInnerStart /units::mm
0105 << std::setw(8) << rInnerEnd /units::mm
0106 << std::setw(8) << rOuterStart /units::mm
0107 << std::setw(8) << rOuterEnd /units::mm
0108 << std::setw(8) << thickness /units::mm
0109 << std::setw(8) << crossType
0110 << std::setw(35) << volName
0111 << std::setw(15) << sectionMat.name()
0112 << std::setw(8) << phi1
0113 << std::setw(8) << phi2
0114 << std::setw(8) << ssensitive;
0115
0116 printout(dd4hep::INFO, "DD4hep_Mask", pipeInfo.str() );
0117
0118
0119 const double zHalf = fabs(zEnd - zStart) * 0.5;
0120 const double zPosition = fabs(zEnd + zStart) * 0.5;
0121 Material material = sectionMat;
0122
0123
0124 if (not ODH::checkForSensibleGeometry(crossingAngle, crossType)){
0125 throw std::runtime_error( " Mask_o1_v01_geo.cpp : checkForSensibleGeometry() failed " ) ;
0126 }
0127
0128 const double rotateAngle = getCurrentAngle(crossingAngle, crossType);
0129 const double mirrorAngle = M_PI - rotateAngle;
0130
0131
0132
0133 switch (crossType) {
0134 case ODH::kCenter:
0135 case ODH::kUpstream:
0136 case ODH::kDnstream: {
0137
0138 Transform3D transformer, transmirror;
0139
0140 if( rotationX == true) {
0141
0142 transformer = Transform3D(RotationX(rotateAngle), RotateX( Position(0, 0, zPosition), rotateAngle) );
0143 transmirror = Transform3D(RotationX(mirrorAngle), RotateX( Position(0, 0, zPosition), mirrorAngle) );
0144 } else{
0145
0146 transformer = Transform3D(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition), rotateAngle) );
0147 transmirror = Transform3D(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition), mirrorAngle) );
0148 }
0149
0150
0151 ConeSegment tubeSolid( zHalf, rInnerStart, rOuterStart, rInnerEnd, rOuterEnd , phi1, phi2);
0152
0153
0154 Volume tubeLog0( volName, tubeSolid, material ) ;
0155 Volume tubeLog1( volName, tubeSolid, material ) ;
0156 if (isSensitive) {
0157 tubeLog0.setSensitiveDetector(sens);
0158 tubeLog1.setSensitiveDetector(sens);
0159 }
0160 tubeLog0.setVisAttributes(description, xmlMask.visStr() );
0161 tubeLog1.setVisAttributes(description, xmlMask.visStr() );
0162
0163
0164 PlacedVolume placed0 = envelope.placeVolume( tubeLog0, transformer );
0165 PlacedVolume placed1 = envelope.placeVolume( tubeLog1, transmirror );
0166
0167 placed0.addPhysVolID("side",1);
0168 placed0.addPhysVolID("layer",counter);
0169 placed1.addPhysVolID("side",-1);
0170 placed1.addPhysVolID("layer",counter);
0171
0172 }
0173 break;
0174
0175 case ODH::kPunchedCenter: {
0176
0177
0178 const double rUpstreamPunch = rInnerStart;
0179 const double rDnstreamPunch = rInnerEnd;
0180
0181
0182 Transform3D upstreamTransformer(RotationY(-crossingAngle), Position(zPosition * tan(-crossingAngle), 0, 0));
0183 Transform3D dnstreamTransformer(RotationY(+crossingAngle), Position(zPosition * tan(+crossingAngle), 0, 0));
0184
0185
0186 Transform3D placementTransformer(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition) , rotateAngle) );
0187 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition) , mirrorAngle) );
0188
0189
0190 ConeSegment wholeSolid( zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2 );
0191 Solid tmpSolid0, tmpSolid1, finalSolid0, finalSolid1;
0192
0193
0194
0195
0196
0197 if ( rUpstreamPunch > 1e-6 ) {
0198 Tube upstreamPunch( 0, rUpstreamPunch, 5 * zHalf, phi1, phi2);
0199 tmpSolid0 = SubtractionSolid( wholeSolid, upstreamPunch, upstreamTransformer);
0200 tmpSolid1 = SubtractionSolid( wholeSolid, upstreamPunch, dnstreamTransformer);
0201 } else {
0202 tmpSolid0 = wholeSolid;
0203 tmpSolid1 = wholeSolid;
0204 }
0205
0206 if (rDnstreamPunch > 1e-6 ) {
0207 Tube dnstreamPunch( 0, rDnstreamPunch, 5 * zHalf, phi1, phi2);
0208 finalSolid0 = SubtractionSolid( tmpSolid0, dnstreamPunch, dnstreamTransformer);
0209 finalSolid1 = SubtractionSolid( tmpSolid1, dnstreamPunch, upstreamTransformer);
0210 } else {
0211 finalSolid0 = tmpSolid0;
0212 finalSolid1 = tmpSolid1;
0213 }
0214
0215
0216 Volume tubeLog0( volName + "_0", finalSolid0, material );
0217 Volume tubeLog1( volName + "_1", finalSolid1, material );
0218 if (isSensitive) {
0219 tubeLog0.setSensitiveDetector(sens);
0220 tubeLog1.setSensitiveDetector(sens);
0221 }
0222 tubeLog0.setVisAttributes(description, xmlMask.visStr() );
0223 tubeLog1.setVisAttributes(description, xmlMask.visStr() );
0224
0225
0226 PlacedVolume placed0 = envelope.placeVolume( tubeLog0, placementTransformer );
0227 PlacedVolume placed1 = envelope.placeVolume( tubeLog1, placementTransmirror );
0228
0229 placed0.addPhysVolID("side", 1);
0230 placed1.addPhysVolID("side", -1);
0231 placed0.addPhysVolID("layer", counter);
0232 placed1.addPhysVolID("layer", counter);
0233
0234 break;
0235 }
0236
0237 case ODH::kPunchedUpstream:
0238 case ODH::kPunchedDnstream: {
0239
0240
0241
0242 const double rCenterPunch = (crossType == ODH::kPunchedUpstream) ? (rInnerStart) : (rInnerEnd);
0243 const double rOffsetPunch = (crossType == ODH::kPunchedDnstream) ? (rInnerStart) : (rInnerEnd);
0244
0245
0246 Transform3D punchTransformer(RotationY(-2 * rotateAngle), Position(zPosition * tan(-2 * rotateAngle), 0, 0));
0247 Transform3D punchTransmirror(RotationY(+2 * rotateAngle), Position(zPosition * tan(+2 * rotateAngle), 0, 0));
0248
0249
0250 Transform3D placementTransformer(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition) , rotateAngle) );
0251 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition) , mirrorAngle) );
0252
0253
0254 ConeSegment wholeSolid( zHalf, rCenterPunch , rOuterStart, rCenterPunch, rOuterEnd, phi1, phi2);
0255 Tube punchSolid( 0, rOffsetPunch, 5 * zHalf, phi1, phi2);
0256
0257
0258
0259
0260 SubtractionSolid finalSolid0( wholeSolid, punchSolid, punchTransformer);
0261 SubtractionSolid finalSolid1( wholeSolid, punchSolid, punchTransmirror);
0262
0263
0264 Volume tubeLog0( volName + "_0", finalSolid0, material );
0265 Volume tubeLog1( volName + "_1", finalSolid1, material );
0266 if (isSensitive) {
0267 tubeLog0.setSensitiveDetector(sens);
0268 tubeLog1.setSensitiveDetector(sens);
0269 }
0270 tubeLog0.setVisAttributes(description, xmlMask.visStr() );
0271 tubeLog1.setVisAttributes(description, xmlMask.visStr() );
0272
0273
0274 PlacedVolume placed0 = envelope.placeVolume( tubeLog0, placementTransformer );
0275 PlacedVolume placed1 = envelope.placeVolume( tubeLog1, placementTransmirror );
0276
0277 placed0.addPhysVolID("side", 1);
0278 placed1.addPhysVolID("side", -1);
0279 placed0.addPhysVolID("layer", counter);
0280 placed1.addPhysVolID("layer", counter);
0281
0282 break;
0283 }
0284 default: {
0285 throw std::runtime_error( " Mask_o1_v01_geo.cpp : fatal failure !! ?? " ) ;
0286 }
0287
0288 }
0289
0290 }
0291
0292
0293 Volume mother = description.pickMotherVolume( tube ) ;
0294 PlacedVolume pv(mother.placeVolume(envelope));
0295 pv.addPhysVolID( "system", xmlMask.id() ) ;
0296
0297 tube.setVisAttributes( description, xmlMask.visStr(), envelope );
0298
0299 tube.setPlacement(pv);
0300
0301 return tube;
0302 }
0303 DECLARE_DETELEMENT(DD4hep_Mask_o1_v01,create_detector)