File indexing completed on 2025-07-01 07:54:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/DetFactoryHelper.h>
0016 #include <DD4hep/Printout.h>
0017 #include <XML/Utilities.h>
0018 #include <DD4hep/ShapeTags.h>
0019 #include <TGeoScaledShape.h>
0020 #include <TGeoShapeAssembly.h>
0021 #include <TSystem.h>
0022 #include <TClass.h>
0023
0024
0025 #include <fstream>
0026
0027 using namespace dd4hep;
0028 using namespace dd4hep::detail;
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 static Handle<TObject> create_Scaled(Detector&, xml_h e) {
0045 xml_dim_t scale(e);
0046 Solid shape(xml_comp_t(scale.child(_U(shape))).createShape());
0047 Solid solid = Scale(shape.ptr(), scale.x(1.0), scale.y(1.0), scale.z(1.0));
0048 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0049 return solid;
0050 }
0051 DECLARE_XML_SHAPE(Scale__shape_constructor,create_Scaled)
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 static Handle<TObject> create_Assembly(Detector&, xml_h e) {
0066 xml_dim_t dim(e);
0067 Solid solid = Handle<TNamed>(new TGeoShapeAssembly());
0068 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0069 return solid;
0070 }
0071 DECLARE_XML_SHAPE(Assembly__shape_constructor,create_Assembly)
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 static Handle<TObject> create_Box(Detector&, xml_h e) {
0086 xml_dim_t dim(e);
0087 Solid solid = Box(dim.dx(),dim.dy(),dim.dz());
0088 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0089 return solid;
0090 }
0091 DECLARE_XML_SHAPE(Box__shape_constructor,create_Box)
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107 static Handle<TObject> create_HalfSpace(Detector&, xml_h e) {
0108 xml_dim_t dim(e);
0109 xml_dim_t point = e.child(_U(point));
0110 xml_dim_t normal = e.child(_U(normal));
0111 double p[3] = { point.x(), point.y(), point.z()};
0112 double n[3] = { normal.x(), normal.y(), normal.z()};
0113 Solid solid = HalfSpace(p, n);
0114 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0115 return solid;
0116 }
0117 DECLARE_XML_SHAPE(HalfSpace__shape_constructor,create_HalfSpace)
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 static Handle<TObject> create_Cone(Detector&, xml_h element) {
0132 xml_dim_t e(element);
0133 double rmi1 = e.rmin1(0.0), rma1 = e.rmax1();
0134 Solid solid = Cone(e.z(0.0), rmi1, rma1, e.rmin2(rmi1), e.rmax2(rma1));
0135 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0136 return solid;
0137 }
0138 DECLARE_XML_SHAPE(Cone__shape_constructor,create_Cone)
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157 static Handle<TObject> create_Polycone(Detector&, xml_h element) {
0158 xml_dim_t e(element);
0159 int num = 0;
0160 std::vector<double> rmin,rmax,z;
0161 double start = e.startphi(0e0), deltaphi = e.deltaphi(2*M_PI);
0162 for(xml_coll_t c(e,_U(zplane)); c; ++c, ++num) {
0163 xml_comp_t plane(c);
0164 rmin.emplace_back(plane.rmin(0.0));
0165 rmax.emplace_back(plane.rmax());
0166 z.emplace_back(plane.z());
0167 }
0168 if ( num < 2 ) {
0169 throw std::runtime_error("PolyCone Shape> Not enough Z planes. minimum is 2!");
0170 }
0171 Solid solid = Polycone(start,deltaphi,rmin,rmax,z);
0172 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0173 return solid;
0174 }
0175 DECLARE_XML_SHAPE(Polycone__shape_constructor,create_Polycone)
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198 static Handle<TObject> create_ConeSegment(Detector&, xml_h element) {
0199 Solid solid;
0200 xml_dim_t e(element);
0201 xml_attr_t aphi = element.attr_nothrow(_U(phi1));
0202 xml_attr_t bphi = element.attr_nothrow(_U(phi2));
0203 if ( aphi || bphi ) {
0204 double phi1 = e.phi1(0.0);
0205 double phi2 = e.phi2(2*M_PI);
0206
0207 solid = ConeSegment(e.dz(),e.rmin1(0.0),e.rmax1(),e.rmin2(0.0),e.rmax2(),phi1,phi2);
0208 }
0209 else {
0210 double start_phi = e.startphi(0.0);
0211 double delta_phi = e.deltaphi(2*M_PI);
0212 while ( start_phi > 2.0*M_PI ) start_phi -= 2.0*M_PI;
0213
0214 solid = ConeSegment(e.dz(),e.rmin1(0.0),e.rmax1(),e.rmin2(0.0),e.rmax2(),start_phi,start_phi+delta_phi);
0215 }
0216 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0217 return solid;
0218 }
0219 DECLARE_XML_SHAPE(ConeSegment__shape_constructor,create_ConeSegment)
0220
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242 static Handle<TObject> create_Tube(Detector&, xml_h element) {
0243 Solid solid;
0244 xml_dim_t e(element);
0245 xml_attr_t aphi = element.attr_nothrow(_U(phi1));
0246 xml_attr_t bphi = element.attr_nothrow(_U(phi2));
0247 if ( aphi || bphi ) {
0248 double phi1 = e.phi1(0.0);
0249 double phi2 = e.phi2(2*M_PI);
0250 solid = Tube(e.rmin(0.0),e.rmax(),e.dz(0.0),phi1, phi2);
0251 }
0252 else {
0253 double phi1 = e.startphi(0.0);
0254 double phi2 = phi1 + e.deltaphi(2*M_PI);
0255 solid = Tube(e.rmin(0.0),e.rmax(),e.dz(0.0),phi1,phi2);
0256 }
0257 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0258 return solid;
0259 }
0260 DECLARE_XML_SHAPE(Tube__shape_constructor,create_Tube)
0261
0262
0263
0264
0265
0266
0267
0268 static Handle<TObject> create_TwistedTube(Detector&, xml_h element) {
0269 xml_dim_t e(element);
0270 Solid solid;
0271 int nseg = 1;
0272 double zpos = 0.0, zneg = 0.0;
0273 if ( element.attr_nothrow(_U(nsegments)) ) {
0274 nseg = e.nsegments();
0275 }
0276 if ( element.attr_nothrow(_U(dz)) ) {
0277 zneg = -1.0*(zpos = e.dz());
0278 }
0279 else {
0280 zpos = e.zpos();
0281 zneg = e.zneg();
0282 }
0283 solid = TwistedTube(e.twist(0.0), e.rmin(0.0),e.rmax(),zneg, zpos, nseg, e.deltaphi(2*M_PI));
0284
0285 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0286 return solid;
0287 }
0288 DECLARE_XML_SHAPE(TwistedTube__shape_constructor,create_TwistedTube)
0289
0290
0291
0292
0293
0294
0295
0296 static Handle<TObject> create_CutTube(Detector&, xml_h element) {
0297 xml_dim_t e(element);
0298 Solid solid = CutTube(e.rmin(0.0),e.rmax(),e.dz(),
0299 e.attr<double>(_U(phi1)),
0300 e.attr<double>(_U(phi2)),
0301 e.attr<double>(_U(lx)),
0302 e.attr<double>(_U(ly)),
0303 e.attr<double>(_U(lz)),
0304 e.attr<double>(_U(tx)),
0305 e.attr<double>(_U(ty)),
0306 e.attr<double>(_U(tz)));
0307 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0308 return solid;
0309 }
0310 DECLARE_XML_SHAPE(CutTube__shape_constructor,create_CutTube)
0311
0312
0313
0314
0315
0316
0317
0318 static Handle<TObject> create_EllipticalTube(Detector&, xml_h element) {
0319 xml_dim_t e(element);
0320 Solid solid = EllipticalTube(e.a(),e.b(),e.dz());
0321 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0322 return solid;
0323 }
0324 DECLARE_XML_SHAPE(EllipticalTube__shape_constructor,create_EllipticalTube)
0325
0326
0327
0328
0329
0330
0331
0332 static Handle<TObject> create_TruncatedTube(Detector&, xml_h element) {
0333 xml_dim_t e(element);
0334 double sp = e.startphi(0.0), dp = e.deltaphi(2*M_PI);
0335 Solid solid = TruncatedTube(e.dz(), e.rmin(0.0), e.rmax(), sp, dp,
0336 e.attr<double>(xml_tag_t("cutAtStart")),
0337 e.attr<double>(xml_tag_t("cutAtDelta")),
0338 e.attr<bool>(xml_tag_t("cutInside")));
0339 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0340 return solid;
0341 }
0342 DECLARE_XML_SHAPE(TruncatedTube__shape_constructor,create_TruncatedTube)
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 static Handle<TObject> create_Trap(Detector&, xml_h element) {
0365 xml_dim_t e(element);
0366 Solid solid;
0367 if ( e.hasAttr(_U(dz)) ) {
0368 solid = Trap(e.dz(),e.dy(),e.dx(),_toDouble(_Unicode(pLTX)));
0369 }
0370 else {
0371 xml_attr_t attr = 0;
0372 double x1 = e.x1();
0373 double x2 = e.x2();
0374 double x3 = (attr=element.attr_nothrow(_U(x3))) ? element.attr<double>(attr) : x1;
0375 double x4 = (attr=element.attr_nothrow(_U(x4))) ? element.attr<double>(attr) : x2;
0376 double y1 = e.y1();
0377 double y2 = (attr=element.attr_nothrow(_U(y2))) ? element.attr<double>(attr) : y1;
0378 solid = Trap(e.z(0.0),e.theta(0),e.phi(0),y1,x1,x2,e.alpha1(0),y2,x3,x4,e.alpha2(0));
0379 }
0380 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0381 return solid;
0382 }
0383 DECLARE_XML_SHAPE(Trap__shape_constructor,create_Trap)
0384
0385
0386
0387
0388
0389
0390
0391 static Handle<TObject> create_PseudoTrap(Detector&, xml_h element) {
0392 xml_dim_t e(element);
0393 Solid solid = PseudoTrap(e.x1(),e.x2(),e.y1(),e.y2(),e.z(),e.radius(),e.attr<bool>(xml_tag_t("minusZ")));
0394 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0395 return solid;
0396 }
0397 DECLARE_XML_SHAPE(PseudoTrap__shape_constructor,create_PseudoTrap)
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410 static Handle<TObject> create_Trd1(Detector&, xml_h element) {
0411 xml_dim_t e(element);
0412 Solid solid = Trd1(e.x1(),e.x2(),e.y(),e.z(0.0));
0413 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0414 return solid;
0415 }
0416 DECLARE_XML_SHAPE(Trd1__shape_constructor,create_Trd1)
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429 static Handle<TObject> create_Trd2(Detector&, xml_h element) {
0430 xml_dim_t e(element);
0431 Solid solid = Trd2(e.x1(),e.x2(),e.y1(),e.y2(),e.z(0.0));
0432 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0433 return solid;
0434 }
0435 DECLARE_XML_SHAPE(Trapezoid__shape_constructor,create_Trd2)
0436 DECLARE_XML_SHAPE(Trd2__shape_constructor,create_Trd2)
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456 static Handle<TObject> create_Torus(Detector&, xml_h element) {
0457 Solid solid;
0458 xml_dim_t e(element);
0459 xml_attr_t aphi = element.attr_nothrow(_U(phi1));
0460 xml_attr_t bphi = element.attr_nothrow(_U(phi2));
0461 if ( aphi || bphi ) {
0462 double phi1 = e.phi1(0.0);
0463 double phi2 = e.phi2(2*M_PI);
0464
0465 solid = Torus(e.r(), e.rmin(0.0), e.rmax(), phi1, phi2-phi1);
0466 }
0467 else {
0468 double start_phi = e.startphi(0.0);
0469 double delta_phi = e.deltaphi(2*M_PI);
0470 while ( start_phi > 2.0*M_PI ) start_phi -= 2.0*M_PI;
0471
0472 solid = Torus(e.r(), e.rmin(0.0), e.rmax(), start_phi, delta_phi);
0473 }
0474 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0475 return solid;
0476 }
0477 DECLARE_XML_SHAPE(Torus__shape_constructor,create_Torus)
0478
0479
0480
0481
0482
0483
0484
0485
0486
0487
0488
0489
0490
0491
0492
0493
0494 static Handle<TObject> create_Sphere(Detector&, xml_h element) {
0495 xml_dim_t e(element);
0496 double startphi = e.phi(0e0);
0497 double endphi = startphi + 2.*M_PI;
0498 double starttheta = e.theta(0e0);
0499 double endtheta = starttheta + M_PI;
0500
0501 if ( e.hasAttr(_U(startphi)) ) {
0502 startphi = e.startphi();
0503 endphi = startphi + 2.*M_PI;
0504 }
0505 if ( e.hasAttr(_U(endphi)) )
0506 endphi = e.endphi();
0507 else if ( e.hasAttr(_U(deltaphi)) )
0508 endphi = startphi + e.deltaphi();
0509
0510 if ( e.hasAttr(_U(starttheta)) ) {
0511 starttheta = e.starttheta();
0512 endtheta = starttheta + M_PI;
0513 }
0514 if ( e.hasAttr(_U(endtheta)) )
0515 endtheta = e.endtheta();
0516 else if ( e.hasAttr(_U(deltatheta)) )
0517 endtheta = starttheta + e.deltatheta();
0518
0519 Solid solid = Sphere(e.rmin(0e0), e.rmax(), starttheta, endtheta, startphi, endphi);
0520 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0521 return solid;
0522 }
0523 DECLARE_XML_SHAPE(Sphere__shape_constructor,create_Sphere)
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536 static Handle<TObject> create_Paraboloid(Detector&, xml_h element) {
0537 xml_dim_t e(element);
0538 Solid solid = Paraboloid(e.rmin(0.0),e.rmax(),e.dz());
0539 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0540 return solid;
0541 }
0542 DECLARE_XML_SHAPE(Paraboloid__shape_constructor,create_Paraboloid)
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557 static Handle<TObject> create_Hyperboloid(Detector&, xml_h element) {
0558 xml_dim_t e(element);
0559 Solid solid = Hyperboloid(e.rmin(), e.inner_stereo(), e.rmax(), e.outer_stereo(), e.dz());
0560 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0561 return solid;
0562 }
0563 DECLARE_XML_SHAPE(Hyperboloid__shape_constructor,create_Hyperboloid)
0564
0565
0566
0567
0568
0569
0570
0571
0572
0573
0574
0575
0576
0577 static Handle<TObject> create_PolyhedraRegular(Detector&, xml_h element) {
0578 xml_dim_t e(element);
0579 Solid solid = PolyhedraRegular(e.numsides(),e.rmin(),e.rmax(),e.dz());
0580 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0581 return solid;
0582 }
0583 DECLARE_XML_SHAPE(PolyhedraRegular__shape_constructor,create_PolyhedraRegular)
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599 static Handle<TObject> create_Polyhedra(Detector&, xml_h element) {
0600 xml_dim_t e(element);
0601 std::vector<double> z, rmin, rmax;
0602 for ( xml_coll_t c(e,_U(plane)); c; ++c ) {
0603 xml_comp_t plane(c);
0604 rmin.emplace_back(plane.rmin());
0605 rmax.emplace_back(plane.rmax());
0606 z.emplace_back(plane.z());
0607 }
0608 Solid solid = Polyhedra(e.numsides(),e.startphi(),e.deltaphi(),z,rmin,rmax);
0609 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0610 return solid;
0611 }
0612 DECLARE_XML_SHAPE(Polyhedra__shape_constructor,create_Polyhedra)
0613
0614
0615
0616
0617
0618
0619
0620 static Handle<TObject> create_ExtrudedPolygon(Detector&, xml_h element) {
0621 xml_dim_t e(element);
0622 std::vector<double> pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale;
0623 for ( xml_coll_t sec(element, _U(section)); sec; ++sec ) {
0624 xml_dim_t section(sec);
0625 sec_z.emplace_back(section.attr<double>(_U(z)));
0626 sec_x.emplace_back(section.attr<double>(_U(x)));
0627 sec_y.emplace_back(section.attr<double>(_U(y)));
0628 sec_scale.emplace_back(section.attr<double>(_U(scale),1.0));
0629 }
0630 for ( xml_coll_t pt(element, _U(point)); pt; ++pt ) {
0631 xml_dim_t point(pt);
0632 pt_x.emplace_back(point.attr<double>(_U(x)));
0633 pt_y.emplace_back(point.attr<double>(_U(y)));
0634 }
0635 Solid solid = ExtrudedPolygon(pt_x, pt_y, sec_z, sec_x, sec_y, sec_scale);
0636 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0637 return solid;
0638 }
0639 DECLARE_XML_SHAPE(ExtrudedPolygon__shape_constructor,create_ExtrudedPolygon)
0640
0641
0642
0643
0644
0645
0646
0647 static Handle<TObject> create_EightPointSolid(Detector&, xml_h element) {
0648 xml_dim_t e(element);
0649 double v[8][2];
0650 int num = 0;
0651 memset(&v[0][0],0,sizeof(v));
0652 for(xml_coll_t c(e,_Unicode(vertex)); c && num<8; ++c, ++num) {
0653 xml_comp_t vtx(c);
0654 v[num][0] = vtx.x();
0655 v[num][1] = vtx.y();
0656 }
0657 Solid solid = EightPointSolid(e.dz(),&v[0][0]);
0658 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0659 return solid;
0660 }
0661 DECLARE_XML_SHAPE(EightPointSolid__shape_constructor,create_EightPointSolid)
0662
0663
0664
0665
0666
0667
0668
0669 static Handle<TObject> create_TessellatedSolid(Detector&, xml_h element) {
0670 xml_dim_t e(element);
0671 std::vector<TessellatedSolid::Vertex> vertices;
0672 for ( xml_coll_t vtx(element, _U(vertex)); vtx; ++vtx ) {
0673 xml_dim_t v(vtx);
0674 vertices.emplace_back(v.x(), v.y(), v.z());
0675 }
0676 int num_facets = 0;
0677 for ( xml_coll_t facet(element, _U(facet)); facet; ++facet ) ++num_facets;
0678 TessellatedSolid solid = TessellatedSolid(num_facets);
0679 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0680 for ( xml_coll_t facet(element, _U(facet)); facet; ++facet ) {
0681 xml_dim_t f(facet);
0682 size_t i0 = f.attr<size_t>(_U(v0));
0683 size_t i1 = f.attr<size_t>(_U(v1));
0684 size_t i2 = f.attr<size_t>(_U(v2));
0685 if ( f.hasAttr(_U(v3)) ) {
0686 size_t i3 = f.attr<size_t>(_U(v3));
0687 solid.addFacet(vertices[i0], vertices[i1], vertices[i2], vertices[i3]);
0688 }
0689 else {
0690 solid.addFacet(vertices[i0], vertices[i1], vertices[i2]);
0691 }
0692 }
0693 return solid;
0694 }
0695 DECLARE_XML_SHAPE(TessellatedSolid__shape_constructor,create_TessellatedSolid)
0696
0697
0698
0699
0700
0701
0702
0703
0704
0705 static Handle<TObject> create_BooleanShape(Detector&, xml_h element) {
0706
0707 xml_det_t e(element);
0708
0709
0710 xml_coll_t c( e ,_U(shape)) ;
0711 xml_comp_t x_shape1( c ) ;
0712 ++c ;
0713 xml_comp_t x_shape2( c ) ;
0714
0715
0716 Solid solid1( xml_comp_t( std::move(x_shape1) ).createShape()) ;
0717 Solid solid2( xml_comp_t( std::move(x_shape2) ).createShape()) ;
0718
0719
0720 std::string op = e.attr<std::string>(_U(operation)) ;
0721 std::transform( op.begin(), op.end(), op.begin(), ::tolower);
0722
0723 Solid resultSolid ;
0724
0725 bool useRot(false), usePos(false), useTrans(false);
0726 Position pos ;
0727 RotationZYX rot ;
0728
0729 if( e.hasChild( _U(transformation) ) ) {
0730 useTrans = true ;
0731 }
0732 if( e.hasChild( _U(position) ) ) {
0733 usePos = true ;
0734 xml_comp_t x_pos = e.position();
0735 pos = Position( x_pos.x(0.0),x_pos.y(0.0),x_pos.z(0.0) );
0736 }
0737 if( e.hasChild( _U(rotation) ) ) {
0738 useRot = true ;
0739 xml_comp_t x_rot = e.rotation();
0740 rot = RotationZYX( x_rot.z(0.0),x_rot.y(0.0),x_rot.x(0.0) ) ;
0741 }
0742
0743 if( op == "subtraction" ) {
0744 if ( useTrans ) {
0745 Transform3D tr = xml::createTransformation(e.child(_U(transformation)));
0746 resultSolid = SubtractionSolid(solid1, solid2, tr);
0747 }
0748 else if( useRot && usePos ) {
0749 resultSolid = SubtractionSolid(solid1, solid2, Transform3D(rot, pos));
0750 }
0751 else if( useRot )
0752 resultSolid = SubtractionSolid(solid1, solid2, rot);
0753 else if( usePos)
0754 resultSolid = SubtractionSolid(solid1, solid2, pos);
0755 else
0756 resultSolid = SubtractionSolid(solid1, solid2);
0757 }
0758 else if( op == "union" ) {
0759 if ( useTrans ) {
0760 Transform3D tr = xml::createTransformation(e.child(_U(transformation)));
0761 resultSolid = UnionSolid(solid1, solid2, tr);
0762 }
0763 else if( useRot && usePos )
0764 resultSolid = UnionSolid(solid1, solid2, Transform3D(rot, pos));
0765 else if( useRot)
0766 resultSolid = UnionSolid(solid1, solid2, rot);
0767 else if( usePos)
0768 resultSolid = UnionSolid(solid1, solid2, pos);
0769 else
0770 resultSolid = UnionSolid(solid1, solid2);
0771 }
0772 else if( op == "intersection" ) {
0773 if ( useTrans ) {
0774 Transform3D tr = xml::createTransformation(e.child(_U(transformation)));
0775 resultSolid = IntersectionSolid(solid1, solid2, tr);
0776 }
0777 else if( useRot && usePos )
0778 resultSolid = IntersectionSolid(solid1, solid2, Transform3D(rot, pos));
0779 else if( useRot)
0780 resultSolid = IntersectionSolid(solid1, solid2, rot);
0781 else if( usePos)
0782 resultSolid = IntersectionSolid(solid1, solid2, pos);
0783 else
0784 resultSolid = IntersectionSolid(solid1, solid2) ;
0785
0786 } else {
0787
0788 throw std::runtime_error(std::string(" create_BooleanShape - unknown operation given: ") + op +
0789 std::string(" - needs to be one of 'subtraction','union' or 'intersection' ") ) ;
0790 }
0791 Solid solid = resultSolid ;
0792 if ( e.hasAttr(_U(name)) ) solid->SetName(e.attr<std::string>(_U(name)).c_str());
0793 return solid;
0794 }
0795 DECLARE_XML_SHAPE(BooleanShapeOld__shape_constructor,create_BooleanShape)
0796
0797
0798 static Handle<TObject> create_BooleanMulti(Detector& description, xml_h element) {
0799 xml_det_t e(element);
0800
0801 Solid tmp, solid, result;
0802 int flag = 0;
0803 Transform3D position, rotation, trafo;
0804
0805 xml_attr_t attr = 0;
0806 std::string op = e.attr<std::string>(_U(operation)) ;
0807 std::transform( op.begin(), op.end(), op.begin(), ::tolower);
0808
0809 for (xml_coll_t i(e ,_U(star)); i; ++i ) {
0810 xml_comp_t x_elt = i;
0811 std::string tag = x_elt.tag();
0812 if ( tag == "shape" && !result.isValid() ) {
0813 result = xml::createShape(description, x_elt.typeStr(), x_elt);
0814 if ( (attr=i.attr_nothrow(_U(name))) ) result->SetName(i.attr<std::string>(attr).c_str());
0815 flag = 1;
0816 }
0817 else if ( tag == "shape" && !solid.isValid() ) {
0818 solid = xml::createShape(description, x_elt.typeStr(), x_elt);
0819 if ( (attr=i.attr_nothrow(_U(name))) ) result->SetName(i.attr<std::string>(attr).c_str());
0820 flag = 3;
0821 }
0822 else if ( result.isValid() && solid.isValid() ) {
0823 if ( tag == "position" ) {
0824 if ( flag == 4 ) trafo = position * trafo;
0825 else if ( flag == 5 ) trafo = (position * rotation) * trafo;
0826 Position pos(x_elt.x(0), x_elt.y(0), x_elt.z(0));
0827 position = Transform3D(pos);
0828 rotation = Transform3D();
0829 flag = 4;
0830 }
0831 else if ( tag == "positionRZPhi" ) {
0832 if ( flag == 4 ) trafo = position * trafo;
0833 else if ( flag == 5 ) trafo = (position * rotation) * trafo;
0834 ROOT::Math::RhoZPhiVector pos(x_elt.r(0), x_elt.z(0), x_elt.phi(0));
0835 position = Transform3D(pos);
0836 rotation = Transform3D();
0837 flag = 4;
0838 }
0839 else if ( tag == "transformation" ) {
0840 if ( flag == 4 ) trafo = position * trafo;
0841 else if ( flag == 5 ) trafo = (position * rotation) * trafo;
0842 Transform3D tr = xml::createTransformation(x_elt);
0843 trafo = tr * trafo;
0844 position = rotation = Transform3D();
0845 flag = 3;
0846 }
0847 else if ( tag == "rotation" ) {
0848 rotation = Transform3D(RotationZYX(x_elt.z(0), x_elt.y(0), x_elt.x(0)));
0849 flag = 5;
0850 }
0851 else if ( tag == "shape" ) {
0852
0853 if ( flag == 4 ) trafo = position * trafo;
0854 else if ( flag == 5 ) trafo = (position * rotation) * trafo;
0855 tmp = Solid();
0856 if( op == "subtraction" )
0857 tmp = SubtractionSolid(result, solid, trafo);
0858 else if( op == "union" )
0859 tmp = UnionSolid(result, solid, trafo);
0860 else if( op == "intersection" )
0861 tmp = IntersectionSolid(result, solid, trafo);
0862 else {
0863 throw std::runtime_error(" create_BooleanShape - unknown operation given: " + op +
0864 " - needs to be one of 'subtraction','union' or 'intersection' ");
0865 }
0866 result = tmp;
0867 trafo = position = rotation = Transform3D();
0868 solid = xml::createShape(description, x_elt.typeStr(), x_elt);
0869 if ( (attr=i.attr_nothrow(_U(name))) ) result->SetName(i.attr<std::string>(attr).c_str());
0870 flag = 3;
0871 }
0872 }
0873 }
0874 if ( flag >= 3 ) {
0875
0876 if ( flag == 4 ) trafo = position * trafo;
0877 else if ( flag == 5 ) trafo = (position * rotation) * trafo;
0878 if( op == "subtraction" )
0879 tmp = SubtractionSolid(result, solid, trafo);
0880 else if( op == "union" )
0881 tmp = UnionSolid(result, solid, trafo);
0882 else if( op == "intersection" )
0883 tmp = IntersectionSolid(result, solid, trafo);
0884 else {
0885 throw std::runtime_error(" create_BooleanShape - unknown operation given: " + op +
0886 " - needs to be one of 'subtraction','union' or 'intersection' ");
0887 }
0888 result = tmp;
0889 }
0890 attr = element.attr_nothrow(_U(name));
0891 if ( attr ) {
0892 std::string nam = element.attr<std::string>(attr);
0893 result->SetName(nam.c_str());
0894 }
0895 return result;
0896 }
0897 DECLARE_XML_SHAPE(BooleanShape__shape_constructor,create_BooleanMulti)
0898
0899
0900
0901
0902
0903
0904
0905
0906 static Handle<TObject> create_std_volume(Detector& description, xml_h element) {
0907 return xml::createStdVolume(description, element);
0908 }
0909 DECLARE_XML_VOLUME(DD4hep_StdVolume,create_std_volume)
0910
0911
0912
0913
0914
0915
0916
0917
0918 static Handle<TObject> create_gen_volume(Detector& description, xml_h element) {
0919 xml_dim_t elt = element;
0920 std::string typ = elt.attr<std::string>(_U(type));
0921 return xml::createVolume(description, typ, element);
0922 }
0923 DECLARE_XML_VOLUME(DD4hep_GenericVolume,create_gen_volume)
0924
0925 TGeoCombiTrans* createPlacement(const Rotation3D& iRot, const Position& iTrans) {
0926 double elements[9];
0927 iRot.GetComponents(elements);
0928 TGeoRotation r;
0929 r.SetMatrix(elements);
0930 TGeoTranslation t(iTrans.x(), iTrans.y(), iTrans.z());
0931 return new TGeoCombiTrans(t, r);
0932 }
0933
0934
0935
0936
0937
0938
0939
0940 static Ref_t create_shape(Detector& description, xml_h e, SensitiveDetector sens) {
0941 xml_det_t x_det = e;
0942 std::string name = x_det.nameStr();
0943 xml_dim_t x_reflect = x_det.child(_U(reflect), false);
0944 DetElement det (name,x_det.id());
0945 Material mat = description.air();
0946 Assembly assembly (name);
0947 PlacedVolume pv;
0948 int count = 0;
0949
0950 printout(DEBUG,"TestShape","+++ Create shape: %s build type is: %s",
0951 name.c_str(), buildTypeName(description.buildType()).c_str());
0952 if ( x_det.hasChild(_U(material)) ) {
0953 mat = description.material(x_det.child(_U(material)).attr<std::string>(_U(name)));
0954 printout(INFO,"TestShape","+++ Volume material is %s", mat.name());
0955 }
0956 for ( xml_coll_t itm(e, _U(check)); itm; ++itm, ++count ) {
0957 xml_dim_t x_check = itm;
0958 xml_comp_t shape (x_check.child(_U(shape)));
0959 xml_dim_t pos (x_check.child(_U(position), false));
0960 xml_dim_t rot (x_check.child(_U(rotation), false));
0961 bool reflect = x_check.hasChild(_U(reflect));
0962 bool reflectZ = x_check.hasChild(_U(reflect_z));
0963 bool reflectY = x_check.hasChild(_U(reflect_y));
0964 bool reflectX = x_check.hasChild(_U(reflect_x));
0965 std::string shape_type = shape.typeStr();
0966 Volume volume;
0967 Solid solid;
0968
0969 if ( shape_type == "CAD_Assembly" || shape_type == "CAD_MultiVolume" ) {
0970 volume = xml::createVolume(description, shape_type, shape);
0971 solid = volume->GetShape();
0972 }
0973 else if ( shape_type == "StdVolume" ) {
0974 volume = xml::createStdVolume(description, shape.child(_U(volume)));
0975 solid = volume->GetShape();
0976 }
0977 else if ( shape_type == "GenVolume" ) {
0978 volume = xml::createVolume(description, shape_type, shape.child(_U(volume)));
0979 solid = volume->GetShape();
0980 }
0981 else {
0982 solid = xml::createShape(description, shape_type, shape);
0983 volume = Volume(name+_toString(count,"_vol_%d"),solid, mat);
0984 }
0985 if ( x_det.hasChild(_U(sensitive)) ) {
0986 std::string sens_type = x_det.child(_U(sensitive)).attr<std::string>(_U(type));
0987 volume.setSensitiveDetector(sens);
0988 sens.setType(sens_type);
0989 printout(INFO,"TestShape","+++ Sensitive type is %s", sens_type.c_str());
0990 }
0991 volume.setVisAttributes(description, x_check.visStr());
0992 solid->SetName(shape_type.c_str());
0993
0994 Transform3D tr;
0995 if ( pos.ptr() && rot.ptr() ) {
0996 Rotation3D rot3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)));
0997 Position pos3D(pos.x(0),pos.y(0),pos.z(0));
0998 tr = Transform3D(rot3D, pos3D);
0999 }
1000 else if ( pos.ptr() ) {
1001 tr = Transform3D(Rotation3D(),Position(pos.x(0),pos.y(0),pos.z(0)));
1002 }
1003 else if ( rot.ptr() ) {
1004 Rotation3D rot3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)));
1005 tr = Transform3D(rot3D,Position());
1006 }
1007
1008 if ( reflect ) {
1009 tr = tr * Rotation3D(1., 0., 0., 0., 1., 0., 0., 0., -1.);
1010 }
1011 if ( reflectX ) {
1012 tr = tr * Rotation3D(-1.,0.,0.,0.,1.,0.,0.,0.,1.);
1013 }
1014 if ( reflectY ) {
1015 tr = tr * Rotation3D(1.,0.,0.,0.,-1.,0.,0.,0.,1.);
1016 }
1017 if ( reflectZ ) {
1018 tr = tr * Rotation3D(1.,0.,0.,0.,1.,0.,0.,0.,-1.);
1019 }
1020 pv = assembly.placeVolume(volume,tr);
1021
1022 if ( x_check.hasAttr(_U(id)) ) {
1023 pv.addPhysVolID("check",x_check.id());
1024 printout(INFO,"TestShape","+++ Volume id is %d", x_check.id());
1025 }
1026 const char* nam = solid->GetName();
1027 printout(INFO,"TestShape","Created successfull shape of type: %s %c%s%c",
1028 shape_type.c_str(), nam ? '[' : ' ', nam ? nam : "" ,nam ? ']' : ' ');
1029
1030 bool instance_test = false;
1031 if ( shape_type == "CAD_Assembly" || shape_type == "CAD_MultiVolume" ) {
1032 solid->SetTitle(shape_type.c_str());
1033 instance_test = true;
1034 }
1035 else if ( 0 == strcasecmp(solid->GetTitle(),BOX_TAG) )
1036 instance_test = isInstance<Box>(solid);
1037 else if ( 0 == strcasecmp(solid->GetTitle(),TUBE_TAG) )
1038 instance_test = isInstance<Tube>(solid);
1039 else if ( 0 == strcasecmp(solid->GetTitle(),CUTTUBE_TAG) )
1040 instance_test = isInstance<CutTube>(solid);
1041 else if ( 0 == strcasecmp(solid->GetTitle(),CONE_TAG) )
1042 instance_test = isInstance<Cone>(solid);
1043 else if ( 0 == strcasecmp(solid->GetTitle(),TRD1_TAG) )
1044 instance_test = isInstance<Trd1>(solid);
1045 else if ( 0 == strcasecmp(solid->GetTitle(),TRD2_TAG) )
1046 instance_test = isInstance<Trd2>(solid);
1047 else if ( 0 == strcasecmp(solid->GetTitle(),TORUS_TAG) )
1048 instance_test = isInstance<Torus>(solid);
1049 else if ( 0 == strcasecmp(solid->GetTitle(),SPHERE_TAG) )
1050 instance_test = isInstance<Sphere>(solid);
1051 else if ( 0 == strcasecmp(solid->GetTitle(),HALFSPACE_TAG) )
1052 instance_test = isInstance<HalfSpace>(solid);
1053 else if ( 0 == strcasecmp(solid->GetTitle(),CONESEGMENT_TAG) )
1054 instance_test = isInstance<ConeSegment>(solid);
1055 else if ( 0 == strcasecmp(solid->GetTitle(),PARABOLOID_TAG) )
1056 instance_test = isInstance<Paraboloid>(solid);
1057 else if ( 0 == strcasecmp(solid->GetTitle(),HYPERBOLOID_TAG) )
1058 instance_test = isInstance<Hyperboloid>(solid);
1059 else if ( 0 == strcasecmp(solid->GetTitle(),"PolyhedraRegular") )
1060 instance_test = isInstance<PolyhedraRegular>(solid);
1061 else if ( 0 == strcasecmp(solid->GetTitle(),POLYHEDRA_TAG) )
1062 instance_test = isInstance<Polyhedra>(solid);
1063 else if ( 0 == strcasecmp(solid->GetTitle(),ELLIPTICALTUBE_TAG) )
1064 instance_test = isInstance<EllipticalTube>(solid);
1065 else if ( 0 == strcasecmp(solid->GetTitle(),EXTRUDEDPOLYGON_TAG) )
1066 instance_test = isInstance<ExtrudedPolygon>(solid);
1067 else if ( 0 == strcasecmp(solid->GetTitle(),SCALE_TAG) )
1068 instance_test = isInstance<Scale>(solid);
1069 else if ( 0 == strcasecmp(solid->GetTitle(),TESSELLATEDSOLID_TAG) ) {
1070 instance_test = isInstance<TessellatedSolid>(solid);
1071 shape_type = TESSELLATEDSOLID_TAG;
1072 }
1073 else if ( 0 == strcasecmp(solid->GetTitle(),POLYCONE_TAG) )
1074 instance_test = isInstance<Polycone>(solid);
1075 else if ( 0 == strcasecmp(solid->GetTitle(),TWISTEDTUBE_TAG) ) {
1076 instance_test = isInstance<TwistedTube>(solid);
1077 instance_test &= isInstance<Tube>(solid);
1078 instance_test &= isA<TwistedTube>(solid);
1079 instance_test &= !isA<Tube>(solid);
1080 }
1081 else if ( 0 == strcasecmp(solid->GetTitle(),EIGHTPOINTSOLID_TAG) ) {
1082 instance_test = isInstance<EightPointSolid>(solid);
1083 instance_test &= !isInstance<Trap>(solid);
1084 instance_test &= isA<EightPointSolid>(solid);
1085 instance_test &= !isA<Trap>(solid);
1086 }
1087 else if ( 0 == strcasecmp(solid->GetTitle(),TRAP_TAG) ) {
1088 instance_test = isInstance<EightPointSolid>(solid);
1089 instance_test &= isInstance<Trap>(solid);
1090 instance_test &= isA<Trap>(solid);
1091 instance_test &= !isA<EightPointSolid>(solid);
1092 }
1093 else if ( 0 == strcasecmp(solid->GetTitle(),SUBTRACTION_TAG) ) {
1094 instance_test = isInstance<BooleanSolid>(solid);
1095 instance_test &= isInstance<SubtractionSolid>(solid);
1096 instance_test &= !isA<IntersectionSolid>(solid);
1097 instance_test &= !isA<UnionSolid>(solid);
1098 instance_test &= isA<SubtractionSolid>(solid);
1099 instance_test &= !isA<PseudoTrap>(solid);
1100 }
1101 else if ( 0 == strcasecmp(solid->GetTitle(),UNION_TAG) ) {
1102 instance_test = isInstance<BooleanSolid>(solid);
1103 instance_test &= isInstance<UnionSolid>(solid);
1104 instance_test &= !isA<IntersectionSolid>(solid);
1105 instance_test &= isA<UnionSolid>(solid);
1106 instance_test &= !isA<SubtractionSolid>(solid);
1107 instance_test &= !isA<PseudoTrap>(solid);
1108 }
1109 else if ( 0 == strcasecmp(solid->GetTitle(),INTERSECTION_TAG) ) {
1110 instance_test = isInstance<BooleanSolid>(solid);
1111 instance_test &= isInstance<IntersectionSolid>(solid);
1112 instance_test &= isA<IntersectionSolid>(solid);
1113 instance_test &= !isA<UnionSolid>(solid);
1114 instance_test &= !isA<SubtractionSolid>(solid);
1115 instance_test &= !isA<PseudoTrap>(solid);
1116 }
1117 else if ( 0 == strcasecmp(solid->GetTitle(),TRUNCATEDTUBE_TAG) ) {
1118 instance_test = isInstance<BooleanSolid>(solid);
1119 instance_test &= isInstance<TruncatedTube>(solid);
1120 instance_test &= isA<TruncatedTube>(solid);
1121 instance_test &= !isA<PseudoTrap>(solid);
1122 instance_test &= !isA<IntersectionSolid>(solid);
1123 instance_test &= !isA<UnionSolid>(solid);
1124 instance_test &= !isA<SubtractionSolid>(solid);
1125 }
1126 else if ( 0 == strcasecmp(solid->GetTitle(),PSEUDOTRAP_TAG) ) {
1127 instance_test = isInstance<BooleanSolid>(solid);
1128 instance_test &= isInstance<PseudoTrap>(solid);
1129 instance_test &= isA<PseudoTrap>(solid);
1130 instance_test &= !isA<TruncatedTube>(solid);
1131 instance_test &= !isA<IntersectionSolid>(solid);
1132 instance_test &= !isA<UnionSolid>(solid);
1133 instance_test &= !isA<SubtractionSolid>(solid);
1134 }
1135
1136 if ( !instance_test || ::strcasecmp(shape_type.c_str(),solid->GetTitle()) != 0 ) {
1137 printout(ERROR,"TestShape","BAD shape type: %s <-> %s Instance test: %s",
1138 shape_type.c_str(), solid->GetTitle(),
1139 instance_test ? "OK" : "FAILED");
1140 }
1141 else {
1142 printout(INFO,"TestShape","Correct shape type: %s %s <-> %s Instance test: %s",
1143 solid->GetName(), shape_type.c_str(), solid->GetTitle(), "OK");
1144 }
1145 }
1146 if ( x_reflect ) {
1147 xml_dim_t x_pos(x_reflect.child(_U(position), false));
1148 xml_dim_t x_rot(x_reflect.child(_U(rotation), false));
1149 DetElement full_detector(name+"_full",100+x_det.id());
1150 Assembly full_assembly(name+"_full");
1151 RotationZYX refl_rot;
1152 Position refl_pos;
1153
1154 if ( x_rot ) refl_rot = RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0));
1155 if ( x_pos ) refl_pos = Position(x_pos.x(0),x_pos.y(0),x_pos.z(0));
1156 Transform3D refl_trafo(Rotation3D(refl_rot),refl_pos);
1157
1158
1159 pv = full_assembly.placeVolume(assembly);
1160 full_detector.add(det);
1161 det.setPlacement(pv);
1162
1163
1164 auto reflected = det.reflect(name+"_reflected",100+x_det.id());
1165 pv = full_assembly.placeVolume(reflected.second, refl_trafo);
1166 full_detector.add(reflected.first);
1167 reflected.first.setPlacement(pv);
1168
1169
1170 pv = description.worldVolume().placeVolume(full_assembly);
1171 full_detector.setPlacement(pv);
1172
1173 det = full_detector;
1174 }
1175 else {
1176 pv = description.worldVolume().placeVolume(assembly);
1177 pv.addPhysVolID("system", x_det.id());
1178 det.setPlacement(pv);
1179 }
1180
1181 for ( xml_coll_t itm(e, xml_tag_t("test")); itm; ++itm, ++count ) {
1182 xml_comp_t x_test = itm;
1183 std::string typ = x_test.typeStr();
1184 const void* argv[] = { &e, &pv, 0};
1185 Ref_t result = (NamedObject*)PluginService::Create<void*>(typ, &description, 2, (char**)argv);
1186 if ( !result.isValid() ) {
1187 printout(INFO,"TestShape","+++ Shape verification FAILED. [Plugin not found]");
1188 except("TestShape","+++ Shape verification FAILED.");
1189 }
1190 else if ( ::strcmp(result->GetName(),"SUCCESS") == 0 ) {
1191 printout(INFO,"TestShape","+++ Shape verification SUCCESSFUL. [type=%s]",name.c_str());
1192 delete result.ptr();
1193 }
1194 else {
1195 printout(INFO,"TestShape","+++ Shape verification FAILED [result=%s]",result->GetName());
1196 printout(INFO,"TestShape","+++ Diagnosis: \n%s",result->GetTitle());
1197 delete result.ptr();
1198 except("TestShape","+++ Shape verification FAILED.");
1199 }
1200 }
1201 return det;
1202 }
1203
1204
1205 DECLARE_DETELEMENT(DD4hep_TestShape_Creator,create_shape)
1206
1207
1208
1209
1210
1211
1212
1213 void* shape_mesh_verifier(Detector& description, int argc, char** argv) {
1214 if ( argc != 2 ) { }
1215 xml_det_t x_det = *(xml_h*)argv[0];
1216 PlacedVolume pv = *(PlacedVolume*)argv[1];
1217 xml_comp_t x_test = x_det.child(xml_tag_t("test"));
1218 int ref_cr = x_test.hasAttr(_U(create)) ? x_test.attr<int>(_U(create)) : 0;
1219 int nseg = x_test.hasAttr(_U(segmentation)) ? x_test.attr<int>(_U(segmentation)) : -1;
1220 TString ref = x_test.refStr().c_str();
1221 std::string ref_str;
1222 std::stringstream os;
1223
1224 if ( nseg > 0 ) {
1225 description.manager().SetNsegments(nseg);
1226 }
1227 Volume v = pv.volume();
1228 for (Int_t ipv=0, npv=v->GetNdaughters(); ipv < npv; ipv++) {
1229 PlacedVolume place = v->GetNode(ipv);
1230 auto vol = place.volume();
1231 auto solid = vol.solid();
1232 os << "ShapeCheck[" << ipv << "] ";
1233 os << toStringMesh(place, 2);
1234 printout(INFO,"Mesh_Verifier","+++ Checking mesh of %s %s [%s] vol:%s.",
1235 solid->IsA()->GetName(),
1236 solid->GetName(), solid->GetTitle(),
1237 vol->GetName());
1238 }
1239 gSystem->ExpandPathName(ref);
1240 if ( ref_cr ) {
1241 std::ofstream out(ref, std::fstream::out);
1242 if ( !out.is_open() ) {
1243 except("Mesh_Verifier","+++ FAILED to open(WRITE) reference file: "+x_test.refStr());
1244 }
1245 out << os.str();
1246 out.close();
1247 printout(INFO,"Mesh_Verifier","+++ Successfully wrote reference file: "+x_test.refStr());
1248 }
1249 else if ( ref.Length() > 0 ) {
1250 char c;
1251 std::ifstream in(ref.Data(), std::fstream::in);
1252 if ( !in.is_open() ) {
1253 except("Mesh_Verifier","+++ FAILED to access reference file: "+x_test.refStr());
1254 }
1255 while (in.get(c))
1256 ref_str += c;
1257 in.close();
1258 printout(INFO,"Mesh_Verifier","+++ Successfully read reference file: "+x_test.refStr());
1259 if ( ref_str != os.str() ) {
1260 printout(ERROR,"Mesh_Verifier","+++ Output and reference differ! Please check.");
1261 return Constant("FAILURE",os.str().c_str()).ptr();
1262 }
1263 printout(INFO,"Mesh_Verifier","+++ Successfully checked CREATED shapes.");
1264 os.str("");
1265 for (Int_t ipv=0, npv=v->GetNdaughters(); ipv < npv; ipv++) {
1266 PlacedVolume place = v->GetNode(ipv);
1267 Solid solid = place.volume().solid();
1268 if ( isInstance<TruncatedTube>(solid) ) {
1269 auto params = solid.dimensions();
1270 solid.setDimensions(params);
1271 }
1272 else if ( isInstance<PseudoTrap>(solid) ) {
1273 auto params = solid.dimensions();
1274 solid.setDimensions(params);
1275 }
1276 else if ( solid->IsA() != TGeoCompositeShape::Class() ) {
1277 auto params = solid.dimensions();
1278 solid.setDimensions(params);
1279 }
1280 else {
1281 printout(INFO,"Mesh_Verifier","+++ Skip re-dimensioning of %s [%s].",
1282 solid->IsA()->GetName(), solid->GetTitle());
1283 }
1284 }
1285 for (Int_t ipv=0, npv=v->GetNdaughters(); ipv < npv; ipv++) {
1286 PlacedVolume place = v->GetNode(ipv);
1287 os << "ShapeCheck[" << ipv << "] ";
1288 os << toStringMesh(place, 2);
1289 }
1290 if ( ref_str != os.str() ) {
1291 printout(DEBUG,"Mesh_Verifier","+++ REFERENCE shape mesh:\n%s",ref_str.c_str());
1292 printout(DEBUG,"Mesh_Verifier","+++ REDIMENSIONED shape mesh:\n%s",os.str().c_str());
1293 printout(ERROR,"Mesh_Verifier","+++ Output and reference differ after re-dimension! Please check.");
1294 return Constant("FAILURE",os.str().c_str()).ptr();
1295 }
1296 printout(INFO,"Mesh_Verifier","+++ Successfully checked REDIMENSIONED shapes.");
1297 }
1298 return Constant("SUCCESS",os.str().c_str()).ptr();
1299 }
1300 DECLARE_DD4HEP_CONSTRUCTOR(DD4hep_Mesh_Verifier,shape_mesh_verifier)