File indexing completed on 2025-01-18 09:14:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "DDDetectors/OtherDetectorHelpers.h"
0013
0014 #include "DD4hep/DetFactoryHelper.h"
0015 #include "DD4hep/DD4hepUnits.h"
0016 #include "DD4hep/DetType.h"
0017 #include "DD4hep/Printout.h"
0018
0019 #include "DDRec/DetectorData.h"
0020 #include "DDRec/Surface.h"
0021
0022 #include "XML/Utilities.h"
0023
0024 #include <cmath>
0025 #include <map>
0026 #include <string>
0027
0028 using dd4hep::Transform3D;
0029 using dd4hep::Position;
0030 using dd4hep::RotationY;
0031 using dd4hep::RotateY;
0032 using dd4hep::ConeSegment;
0033 using dd4hep::SubtractionSolid;
0034 using dd4hep::Material;
0035 using dd4hep::Volume;
0036 using dd4hep::Solid;
0037 using dd4hep::Tube;
0038 namespace units = dd4hep;
0039 using dd4hep::rec::Vector3D;
0040 using dd4hep::rec::VolCylinder;
0041 using dd4hep::rec::VolCone;
0042 using dd4hep::rec::SurfaceType;
0043
0044
0045 class SimpleCylinderImpl : public dd4hep::rec::VolCylinderImpl{
0046 double _half_length ;
0047 public:
0048
0049 SimpleCylinderImpl( dd4hep::Volume vol, SurfaceType type,
0050 double thickness_inner ,double thickness_outer, Vector3D origin ) :
0051 dd4hep::rec::VolCylinderImpl( vol, type, thickness_inner, thickness_outer, origin ),
0052 _half_length(0){
0053 }
0054 void setHalfLength( double half_length){
0055 _half_length = half_length ;
0056 }
0057 void setID( dd4hep::FieldID id ) { _id = id ;
0058 }
0059
0060 bool insideBounds(const Vector3D& point, double epsilon) const {
0061 return ( std::abs( point.rho() - origin().rho() ) < epsilon && std::abs( point.z() ) < _half_length ) ;
0062 }
0063
0064 virtual std::vector< std::pair<Vector3D, Vector3D> > getLines(unsigned nMax=100){
0065
0066 std::vector< std::pair<Vector3D, Vector3D> > lines ;
0067
0068 lines.reserve( nMax ) ;
0069
0070 Vector3D zv( 0. , 0. , _half_length ) ;
0071 double r = _o.rho() ;
0072
0073 unsigned n = nMax / 4 ;
0074 double dPhi = 2.* ROOT::Math::Pi() / double( n ) ;
0075
0076 for( unsigned i = 0 ; i < n ; ++i ) {
0077
0078 Vector3D rv0( r*sin( i *dPhi ) , r*cos( i *dPhi ) , 0. ) ;
0079 Vector3D rv1( r*sin( (i+1)*dPhi ) , r*cos( (i+1)*dPhi ) , 0. ) ;
0080
0081 Vector3D pl0 = zv + rv0 ;
0082 Vector3D pl1 = zv + rv1 ;
0083 Vector3D pl2 = -zv + rv1 ;
0084 Vector3D pl3 = -zv + rv0 ;
0085
0086 lines.push_back( std::make_pair( pl0, pl1 ) ) ;
0087 lines.push_back( std::make_pair( pl1, pl2 ) ) ;
0088 lines.push_back( std::make_pair( pl2, pl3 ) ) ;
0089 lines.push_back( std::make_pair( pl3, pl0 ) ) ;
0090 }
0091 return lines;
0092 }
0093 };
0094
0095 class SimpleCylinder : public dd4hep::rec::VolSurface{
0096 public:
0097 SimpleCylinder( dd4hep::Volume vol, dd4hep::rec::SurfaceType type, double thickness_inner ,
0098 double thickness_outer, Vector3D origin ) :
0099 dd4hep::rec::VolSurface( new SimpleCylinderImpl( vol, type, thickness_inner , thickness_outer, origin ) ) {
0100 }
0101 SimpleCylinderImpl* operator->() { return static_cast<SimpleCylinderImpl*>( _surf ) ; }
0102 } ;
0103
0104
0105 static dd4hep::Ref_t create_element(dd4hep::Detector& description,
0106 xml_h element,
0107 dd4hep::SensitiveDetector ) {
0108
0109 printout(dd4hep::DEBUG,"DD4hep_Beampipe", "Creating Beampipe" ) ;
0110
0111
0112 xml_det_t xmlBeampipe = element;
0113 const std::string name = xmlBeampipe.nameStr();
0114 bool nocore = xmlBeampipe.nocore(false);
0115
0116 dd4hep::DetElement tube( name, xmlBeampipe.id() ) ;
0117
0118
0119
0120 Volume envelope = dd4hep::xml::createPlacedEnvelope( description, element , tube ) ;
0121
0122 dd4hep::xml::setDetectorTypeFlag( element, tube ) ;
0123
0124 if( description.buildType() == dd4hep::BUILD_ENVELOPE ) return tube ;
0125
0126
0127
0128
0129 dd4hep::rec::ConicalSupportData* beampipeData = new dd4hep::rec::ConicalSupportData ;
0130
0131
0132 const double phi1 = 0 ;
0133 const double phi2 = 360.0*units::degree;
0134
0135
0136 dd4hep::xml::Component xmlParameter = xmlBeampipe.child(_Unicode(parameter));
0137 const double crossingAngle = xmlParameter.attr< double >(_Unicode(crossingangle))*0.5;
0138
0139
0140 double min_radius = 1.e99 ;
0141
0142 for(xml_coll_t c( xmlBeampipe ,Unicode("section")); c; ++c) {
0143
0144 xml_comp_t xmlSection( c );
0145
0146 ODH::ECrossType crossType = ODH::getCrossType(xmlSection.attr< std::string >(_Unicode(type)));
0147 const double zStart = xmlSection.attr< double > (_Unicode(start));
0148 const double zEnd = xmlSection.attr< double > (_Unicode(end));
0149 const double rInnerStart = xmlSection.attr< double > (_Unicode(rMin1));
0150 const double rInnerEnd = xmlSection.attr< double > (_Unicode(rMin2));
0151 const double rOuterStart = xmlSection.attr< double > (_Unicode(rMax1));
0152 const double rOuterEnd = xmlSection.attr< double > (_Unicode(rMax2));
0153 const double thickness = rOuterStart - rInnerStart;
0154 Material sectionMat = description.material(xmlSection.materialStr());
0155 const std::string volName = "tube_" + xmlSection.nameStr();
0156
0157 std::stringstream pipeInfo;
0158 pipeInfo << std::setw(8) << zStart /units::mm
0159 << std::setw(8) << zEnd /units::mm
0160 << std::setw(8) << rInnerStart /units::mm
0161 << std::setw(8) << rInnerEnd /units::mm
0162 << std::setw(8) << rOuterStart /units::mm
0163 << std::setw(8) << rOuterEnd /units::mm
0164 << std::setw(8) << thickness /units::mm
0165 << std::setw(8) << crossType
0166 << std::setw(35) << volName
0167 << std::setw(15) << sectionMat.name();
0168
0169 printout(dd4hep::INFO, "DD4hep_Beampipe", pipeInfo.str() );
0170
0171 if( crossType == ODH::kCenter ) {
0172 dd4hep::rec::ConicalSupportData::Section section ;
0173 section.rInner = rInnerStart ;
0174 section.rOuter = rOuterStart ;
0175 section.zPos = zStart ;
0176 beampipeData->sections.push_back( section ) ;
0177 }
0178
0179
0180 const double zHalf = fabs(zEnd - zStart) * 0.5;
0181 const double zPosition = fabs(zEnd + zStart) * 0.5;
0182 Material coreMaterial = description.material("beam");
0183 Material wallMaterial = sectionMat;
0184
0185
0186 if (not checkForSensibleGeometry(crossingAngle, crossType)){
0187
0188 throw std::runtime_error( " Beampipe_o1_v01_geo.cpp : checkForSensibleGeometry() failed " ) ;
0189
0190 }
0191 const double rotateAngle = getCurrentAngle(crossingAngle, crossType);
0192 const double mirrorAngle = M_PI - rotateAngle;
0193
0194
0195 switch (crossType) {
0196 case ODH::kCenter:
0197 case ODH::kUpstream:
0198 case ODH::kDnstream: {
0199
0200
0201
0202 Transform3D transformer(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition), rotateAngle) );
0203 Transform3D transmirror(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition), mirrorAngle) );
0204
0205
0206 ConeSegment tubeSolid( zHalf, 0, rOuterStart, 0, rOuterEnd , phi1, phi2);
0207
0208
0209
0210 Volume tubeLog( volName, tubeSolid, coreMaterial ) ;
0211 Volume tubeLog2( volName, tubeSolid, coreMaterial ) ;
0212
0213
0214 if (rInnerStart != rOuterStart || rInnerEnd != rOuterEnd) {
0215
0216
0217 ConeSegment wallSolid( zHalf, rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, phi1, phi2);
0218
0219
0220 Volume wallLog ( volName + "_wall", wallSolid, wallMaterial);
0221 Volume wallLog2( volName + "_wall2", wallSolid, wallMaterial);
0222
0223 if( crossType == ODH::kCenter ) {
0224
0225
0226 const bool isCylinder = ( rInnerStart == rInnerEnd );
0227
0228
0229 if (isCylinder) {
0230
0231 Vector3D ocyl( rInnerStart + thickness/2. , 0. , 0. ) ;
0232
0233 VolCylinder cylSurf1( wallLog , SurfaceType( SurfaceType::Helper ) , 0.5*thickness , 0.5*thickness , ocyl );
0234 VolCylinder cylSurf2( wallLog2, SurfaceType( SurfaceType::Helper ) , 0.5*thickness , 0.5*thickness , ocyl );
0235
0236 dd4hep::rec::volSurfaceList( tube )->push_back( cylSurf1 );
0237 dd4hep::rec::volSurfaceList( tube )->push_back( cylSurf2 );
0238
0239 }else{
0240
0241 const double dr = rInnerEnd - rInnerStart ;
0242 const double theta = atan2( dr , 2.* zHalf ) ;
0243
0244 Vector3D ocon( rInnerStart + 0.5 * ( dr + thickness ), 0. , 0. );
0245
0246 Vector3D v( 1. , 0. , theta, Vector3D::spherical ) ;
0247
0248 VolCone conSurf1( wallLog , SurfaceType( SurfaceType::Helper ) , 0.5*thickness , 0.5*thickness , v, ocon );
0249 VolCone conSurf2( wallLog2, SurfaceType( SurfaceType::Helper ) , 0.5*thickness , 0.5*thickness , v, ocon );
0250
0251 dd4hep::rec::volSurfaceList( tube )->push_back( conSurf1 );
0252 dd4hep::rec::volSurfaceList( tube )->push_back( conSurf2 );
0253
0254 }
0255
0256 if( rInnerStart < min_radius ) min_radius = rInnerStart ;
0257 if( rOuterStart < min_radius ) min_radius = rOuterStart ;
0258 }
0259
0260 wallLog.setVisAttributes(description, "TubeVis");
0261 wallLog2.setVisAttributes(description, "TubeVis");
0262 tubeLog.setVisAttributes(description, "VacVis");
0263 tubeLog2.setVisAttributes(description, "VacVis");
0264
0265 if (nocore){
0266
0267
0268 envelope.placeVolume( wallLog, transformer );
0269 envelope.placeVolume( wallLog2, transmirror );
0270
0271 }else{
0272
0273
0274 envelope.placeVolume( tubeLog, transformer );
0275 envelope.placeVolume( tubeLog2, transmirror );
0276
0277
0278 tubeLog.placeVolume( wallLog, Transform3D() );
0279 tubeLog2.placeVolume( wallLog2, Transform3D() );
0280 }
0281
0282 }
0283 }
0284 break;
0285
0286 case ODH::kPunchedCenter: {
0287
0288
0289
0290 const double rUpstreamPunch = rInnerStart;
0291 const double rDnstreamPunch = rInnerEnd;
0292
0293
0294 Transform3D upstreamTransformer(RotationY(-crossingAngle), Position(zPosition * tan(-crossingAngle), 0, 0));
0295 Transform3D dnstreamTransformer(RotationY(+crossingAngle), Position(zPosition * tan(+crossingAngle), 0, 0));
0296
0297
0298 Transform3D placementTransformer(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition) , rotateAngle) );
0299 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition) , mirrorAngle) );
0300
0301
0302 ConeSegment tubeSolid( zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2);
0303
0304
0305 Volume tubeLog0( volName + "_0", tubeSolid, coreMaterial );
0306 Volume tubeLog1( volName + "_1", tubeSolid, coreMaterial );
0307
0308
0309 ConeSegment wholeSolid( zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2);
0310
0311 Solid tmpSolid0, tmpSolid1, wallSolid0, wallSolid1;
0312
0313
0314
0315
0316
0317 if ( rUpstreamPunch > 1e-6 ) {
0318 Tube upstreamPunch( 0, rUpstreamPunch, 5 * zHalf, phi1, phi2);
0319 tmpSolid0 = SubtractionSolid( wholeSolid, upstreamPunch, upstreamTransformer);
0320 tmpSolid1 = SubtractionSolid( wholeSolid, upstreamPunch, dnstreamTransformer);
0321 } else {
0322 tmpSolid0 = wholeSolid;
0323 tmpSolid1 = wholeSolid;
0324 }
0325
0326 if (rDnstreamPunch > 1e-6 ) {
0327 Tube dnstreamPunch( 0, rDnstreamPunch, 5 * zHalf, phi1, phi2);
0328 wallSolid0 = SubtractionSolid( tmpSolid0, dnstreamPunch, dnstreamTransformer);
0329 wallSolid1 = SubtractionSolid( tmpSolid1, dnstreamPunch, upstreamTransformer);
0330 } else {
0331 wallSolid0 = tmpSolid0;
0332 wallSolid1 = tmpSolid1;
0333 }
0334
0335
0336 Volume wallLog0( volName + "_wall_0", wallSolid0, wallMaterial );
0337 Volume wallLog1( volName + "_wall_1", wallSolid1, wallMaterial );
0338
0339 wallLog0.setVisAttributes(description, "TubeVis");
0340 wallLog1.setVisAttributes(description, "TubeVis");
0341 tubeLog0.setVisAttributes(description, "VacVis");
0342 tubeLog1.setVisAttributes(description, "VacVis");
0343
0344 if (nocore){
0345
0346
0347 envelope.placeVolume( wallLog0, placementTransformer );
0348 envelope.placeVolume( wallLog1, placementTransmirror );
0349
0350 }else{
0351
0352
0353 envelope.placeVolume( tubeLog0, placementTransformer );
0354 envelope.placeVolume( tubeLog1, placementTransmirror );
0355
0356
0357 tubeLog0.placeVolume( wallLog0, Position() );
0358 tubeLog1.placeVolume( wallLog1, Position() );
0359 }
0360
0361 break;
0362 }
0363
0364 case ODH::kPunchedUpstream:
0365 case ODH::kPunchedDnstream: {
0366
0367
0368
0369 const double rCenterPunch = (crossType == ODH::kPunchedUpstream) ? (rInnerStart) : (rInnerEnd);
0370 const double rOffsetPunch = (crossType == ODH::kPunchedDnstream) ? (rInnerStart) : (rInnerEnd);
0371
0372
0373 Transform3D punchTransformer(RotationY(-2 * rotateAngle), Position(zPosition * tan(-2 * rotateAngle), 0, 0));
0374 Transform3D punchTransmirror(RotationY(+2 * rotateAngle), Position(zPosition * tan(+2 * rotateAngle), 0, 0));
0375
0376
0377 Transform3D placementTransformer(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition) , rotateAngle) );
0378 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition) , mirrorAngle) );
0379
0380
0381 ConeSegment tubeSolid( zHalf, 0, rOuterStart, 0, rOuterEnd, phi1, phi2);
0382
0383
0384 Volume tubeLog0( volName + "_0", tubeSolid, coreMaterial );
0385 Volume tubeLog1( volName + "_1", tubeSolid, coreMaterial );
0386
0387
0388 ConeSegment wholeSolid( zHalf, rCenterPunch , rOuterStart, rCenterPunch, rOuterEnd, phi1, phi2);
0389
0390 Tube punchSolid( 0, rOffsetPunch, 5 * zHalf, phi1, phi2);
0391
0392
0393
0394
0395 SubtractionSolid wallSolid0( wholeSolid, punchSolid, punchTransformer);
0396 SubtractionSolid wallSolid1( wholeSolid, punchSolid, punchTransmirror);
0397
0398
0399 Volume wallLog0( volName + "_wall_0", wallSolid0, wallMaterial );
0400 Volume wallLog1( volName + "_wall_1", wallSolid1, wallMaterial );
0401
0402 wallLog0.setVisAttributes(description, "TubeVis");
0403 wallLog1.setVisAttributes(description, "TubeVis");
0404
0405 tubeLog0.setVisAttributes(description, "VacVis");
0406 tubeLog1.setVisAttributes(description, "VacVis");
0407
0408
0409 if (nocore){
0410
0411
0412 envelope.placeVolume( wallLog0, placementTransformer );
0413 envelope.placeVolume( wallLog1, placementTransmirror );
0414
0415 }else{
0416
0417
0418 envelope.placeVolume( tubeLog0, placementTransformer );
0419 envelope.placeVolume( tubeLog1, placementTransmirror );
0420
0421
0422 tubeLog0.placeVolume( wallLog0 , Position() );
0423 tubeLog1.placeVolume( wallLog1 , Position() );
0424 }
0425
0426 break;
0427 }
0428
0429 case ODH::kUpstreamClippedFront:
0430 case ODH::kDnstreamClippedFront:
0431 case ODH::kUpstreamSlicedFront:
0432 case ODH::kDnstreamSlicedFront: {
0433
0434
0435
0436
0437
0438 const double clipSize = rOuterStart;
0439 Tube clipSolid( 0, 2 * clipSize, clipSize, phi1, phi2);
0440
0441
0442 const double clipAngle = (crossType == ODH::kUpstreamClippedFront || crossType == ODH::kDnstreamClippedFront) ? (rotateAngle) : (2 * rotateAngle);
0443 const double clipShift = (zStart - clipSize) / cos(clipAngle) - (zPosition - clipSize / 2);
0444 Transform3D clipTransformer(RotationY(-clipAngle), Position(0, 0, clipShift));
0445 Transform3D clipTransmirror(RotationY(+clipAngle), Position(0, 0, clipShift));
0446
0447
0448 Transform3D placementTransformer(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition - clipSize / 2) , rotateAngle) );
0449 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition - clipSize / 2) , mirrorAngle) );
0450
0451
0452
0453 ConeSegment wholeSolid( zHalf + clipSize / 2, 0, rOuterStart, 0, rOuterEnd, phi1, phi2);
0454
0455
0456 SubtractionSolid tubeSolid0( wholeSolid, clipSolid, clipTransformer);
0457 SubtractionSolid tubeSolid1( wholeSolid, clipSolid, clipTransmirror);
0458
0459
0460 Volume tubeLog0( volName + "_0", tubeSolid0, coreMaterial );
0461 Volume tubeLog1( volName + "_1", tubeSolid1, coreMaterial );
0462
0463 if (nocore==false){
0464
0465 envelope.placeVolume( tubeLog0, placementTransformer );
0466 envelope.placeVolume( tubeLog1, placementTransmirror );
0467 }
0468
0469 if (rInnerStart != rOuterStart || rInnerEnd != rOuterEnd) {
0470
0471 ConeSegment wallWholeSolid( zHalf + clipSize / 2, rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, phi1, phi2);
0472
0473
0474 SubtractionSolid wallSolid0( wallWholeSolid, clipSolid, clipTransformer);
0475 SubtractionSolid wallSolid1( wallWholeSolid, clipSolid, clipTransmirror);
0476
0477
0478 Volume wallLog0( volName + "_wall_0", wallSolid0, wallMaterial );
0479 Volume wallLog1( volName + "_wall_1", wallSolid1, wallMaterial );
0480
0481 wallLog0.setVisAttributes(description, "TubeVis");
0482 wallLog1.setVisAttributes(description, "TubeVis");
0483
0484 tubeLog0.setVisAttributes(description, "VacVis");
0485 tubeLog1.setVisAttributes(description, "VacVis");
0486 if (nocore==false){
0487
0488 tubeLog0.placeVolume( wallLog0, Position() );
0489 tubeLog1.placeVolume( wallLog1, Position() );
0490 }else{
0491 envelope.placeVolume( wallLog0, placementTransformer );
0492 envelope.placeVolume( wallLog1, placementTransmirror );
0493 }
0494 }
0495 }
0496 break;
0497
0498 case ODH::kUpstreamClippedRear:
0499 case ODH::kDnstreamClippedRear:
0500 case ODH::kUpstreamSlicedRear:
0501 case ODH::kDnstreamSlicedRear: {
0502
0503
0504
0505
0506
0507 const double clipSize = rOuterEnd;
0508 Tube clipSolid( 0, 2 * clipSize, clipSize, phi1, phi2);
0509
0510
0511 const double clipAngle = (crossType == ODH::kUpstreamClippedRear || crossType == ODH::kDnstreamClippedRear) ? (rotateAngle) : (2 * rotateAngle);
0512 const double clipShift = (zEnd + clipSize) / cos(clipAngle) - (zPosition + clipSize / 2);
0513 Transform3D clipTransformer(RotationY(-clipAngle), Position(0, 0, clipShift));
0514 Transform3D clipTransmirror(RotationY(+clipAngle), Position(0, 0, clipShift));
0515
0516
0517 Transform3D placementTransformer(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition + clipSize / 2) , rotateAngle) );
0518 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition + clipSize / 2) , mirrorAngle) );
0519
0520
0521 ConeSegment wholeSolid( 0, rOuterStart, 0, rOuterEnd, zHalf + clipSize / 2, phi1, phi2);
0522
0523
0524 SubtractionSolid tubeSolid0( wholeSolid, clipSolid, clipTransformer);
0525 SubtractionSolid tubeSolid1( wholeSolid, clipSolid, clipTransmirror);
0526
0527
0528 Volume tubeLog0( volName + "_0", tubeSolid0, coreMaterial );
0529 Volume tubeLog1( volName + "_1", tubeSolid1, coreMaterial );
0530
0531 if (nocore==false){
0532
0533 envelope.placeVolume( tubeLog0, placementTransformer );
0534 envelope.placeVolume( tubeLog1, placementTransmirror );
0535 }
0536
0537 if (rInnerStart != rOuterStart || rInnerEnd != rOuterEnd) {
0538
0539 ConeSegment wallWholeSolid( rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, zHalf + clipSize / 2, phi1, phi2);
0540
0541
0542 SubtractionSolid wallSolid0( wallWholeSolid, clipSolid, clipTransformer);
0543 SubtractionSolid wallSolid1( wallWholeSolid, clipSolid, clipTransmirror);
0544
0545
0546 Volume wallLog0( volName + "_wall_0", wallSolid0, wallMaterial );
0547 Volume wallLog1( volName + "_wall_1", wallSolid1, wallMaterial );
0548
0549 wallLog0.setVisAttributes(description, "TubeVis");
0550 wallLog1.setVisAttributes(description, "TubeVis");
0551
0552 tubeLog0.setVisAttributes(description, "VacVis");
0553 tubeLog1.setVisAttributes(description, "VacVis");
0554
0555 if (nocore==false){
0556
0557 tubeLog0.placeVolume( wallLog0, Transform3D() );
0558 tubeLog1.placeVolume( wallLog1, Transform3D() );
0559 }else{
0560 envelope.placeVolume( wallLog0, placementTransformer );
0561 envelope.placeVolume( wallLog1, placementTransmirror );
0562 }
0563 }
0564 break;
0565 }
0566
0567 case ODH::kUpstreamClippedBoth:
0568 case ODH::kDnstreamClippedBoth:
0569 case ODH::kUpstreamSlicedBoth:
0570 case ODH::kDnstreamSlicedBoth: {
0571
0572
0573
0574
0575
0576 const double clipSize = rOuterEnd;
0577 Tube clipSolid( 0, 2 * clipSize, clipSize, phi1, phi2);
0578
0579
0580 const double clipAngle = (crossType == ODH::kUpstreamClippedBoth || crossType == ODH::kDnstreamClippedBoth) ? (rotateAngle) : (2 * rotateAngle);
0581 const double clipShiftFrnt = (zStart - clipSize) / cos(clipAngle) - zPosition;
0582 const double clipShiftRear = (zEnd + clipSize) / cos(clipAngle) - zPosition;
0583 Transform3D clipTransformerFrnt(RotationY(-clipAngle), Position(0, 0, clipShiftFrnt));
0584 Transform3D clipTransformerRear(RotationY(-clipAngle), Position(0, 0, clipShiftRear));
0585 Transform3D clipTransmirrorFrnt(RotationY(+clipAngle), Position(0, 0, clipShiftFrnt));
0586 Transform3D clipTransmirrorRear(RotationY(+clipAngle), Position(0, 0, clipShiftRear));
0587
0588
0589 Transform3D placementTransformer(RotationY(rotateAngle), RotateY( Position(0, 0, zPosition) , rotateAngle) );
0590 Transform3D placementTransmirror(RotationY(mirrorAngle), RotateY( Position(0, 0, zPosition) , mirrorAngle) );
0591
0592
0593 ConeSegment wholeSolid( 0, rOuterStart, 0, rOuterEnd, zHalf + clipSize, phi1, phi2);
0594
0595
0596 SubtractionSolid tmpSolid0 ( wholeSolid, clipSolid, clipTransformerFrnt);
0597 SubtractionSolid tmpSolid1 ( wholeSolid, clipSolid, clipTransmirrorFrnt);
0598 SubtractionSolid tubeSolid0( tmpSolid0, clipSolid, clipTransformerRear);
0599 SubtractionSolid tubeSolid1( tmpSolid1, clipSolid, clipTransmirrorRear);
0600
0601
0602 Volume tubeLog0( volName + "_0", tubeSolid0, coreMaterial );
0603 Volume tubeLog1( volName + "_1", tubeSolid1, coreMaterial );
0604
0605 if (nocore==false){
0606
0607 envelope.placeVolume( tubeLog0, placementTransformer );
0608 envelope.placeVolume( tubeLog1, placementTransmirror );
0609 }
0610
0611 if (rInnerStart != rOuterStart || rInnerEnd != rOuterEnd) {
0612
0613 ConeSegment wallWholeSolid( rInnerStart, rOuterStart, rInnerEnd, rOuterEnd, zHalf + clipSize, phi1, phi2);
0614
0615
0616 SubtractionSolid wallTmpSolid0( wallWholeSolid, clipSolid, clipTransformerFrnt);
0617 SubtractionSolid wallTmpSolid1( wallWholeSolid, clipSolid, clipTransmirrorFrnt);
0618 SubtractionSolid wallSolid0 ( wallTmpSolid0, clipSolid, clipTransformerRear);
0619 SubtractionSolid wallSolid1 ( wallTmpSolid1, clipSolid, clipTransmirrorRear);
0620
0621
0622 Volume wallLog0(volName + "_wall_0", wallSolid0, wallMaterial );
0623 Volume wallLog1(volName + "_wall_1", wallSolid1, wallMaterial );
0624
0625 wallLog0.setVisAttributes(description, "TubeVis");
0626 wallLog1.setVisAttributes(description, "TubeVis");
0627
0628 tubeLog0.setVisAttributes(description, "VacVis");
0629 tubeLog1.setVisAttributes(description, "VacVis");
0630
0631 if (nocore==false){
0632
0633 tubeLog0.placeVolume( wallLog0, Transform3D() );
0634 tubeLog1.placeVolume( wallLog1, Transform3D() );
0635 }else{
0636 envelope.placeVolume( wallLog0, placementTransformer );
0637 envelope.placeVolume( wallLog1, placementTransmirror );
0638 }
0639 }
0640 break;
0641 }
0642 default: {
0643 throw std::runtime_error( " Beampipe_o1_v01_geo.cpp : fatal failure !! ?? " ) ;
0644
0645
0646 }
0647
0648 }
0649 }
0650
0651
0652
0653
0654
0655 if (nocore==false){
0656 Vector3D oIPCyl( (min_radius-1.e-3) , 0. , 0. ) ;
0657 SimpleCylinder ipCylSurf( envelope , SurfaceType( SurfaceType::Helper ) , 1.e-5 , 1e-5 , oIPCyl ) ;
0658
0659 ipCylSurf->setHalfLength( 100*units::cm ) ;
0660 dd4hep::rec::volSurfaceList( tube )->push_back( ipCylSurf ) ;
0661 }
0662
0663 tube.addExtension< dd4hep::rec::ConicalSupportData >( beampipeData ) ;
0664
0665
0666
0667 tube.setVisAttributes( description, xmlBeampipe.visStr(), envelope );
0668
0669
0670
0671 return tube;
0672 }
0673 DECLARE_DETELEMENT(DD4hep_Beampipe_o1_v01,create_element)