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