From 9da2b6d1c3ae33eca0364757bd6140410c28ec4f Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Wed, 14 Aug 2019 11:50:37 +0200 Subject: [PATCH] Fix errors in Solid::setDimensions/Solid::dimensions --- DDCore/src/Shapes.cpp | 388 ++++++++++++++++++++---- DDCore/src/plugins/ShapePlugins.cpp | 10 +- DDG4/include/DDG4/Geant4SensDetAction.h | 2 +- DDG4/plugins/Geant4EventReaderHepMC.cpp | 10 +- DDG4/plugins/Geant4GDMLWriteAction.cpp | 11 +- 5 files changed, 346 insertions(+), 75 deletions(-) diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 8944c7898..465609baa 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -125,7 +125,7 @@ namespace dd4hep { } /// Access Shape dimension parameters (As in TGeo, but angles in radians rather than degrees) - std::vector<double> get_shape_dimensions(TGeoShape* shape) { + vector<double> get_shape_dimensions(TGeoShape* shape) { if (shape) { TClass* cl = shape->IsA(); if (cl == TGeoShapeAssembly::Class()) { @@ -248,25 +248,123 @@ namespace dd4hep { pars.emplace_back(vtx->xy[i][0]); pars.emplace_back(vtx->xy[i][1]); } -#if 0 - const Double_t* vertices = sh->GetVertices(); - vector<double> pars { sh->GetDz() }; - pars.reserve(17); - for ( size_t i=0; i<8; ++i ) - pars.emplace_back(vertices[i*2]); - for ( size_t i=0; i<8; ++i ) - pars.emplace_back(vertices[i*2]+1); -#endif return pars; } else if (cl == TGeoCompositeShape::Class()) { + Solid solid(shape); const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape; const TGeoBoolNode* boolean = sh->GetBoolNode(); - TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator(); - TGeoMatrix* left_matrix = boolean->GetRightMatrix(); TGeoMatrix* right_matrix = boolean->GetRightMatrix(); TGeoShape* left_solid = boolean->GetLeftShape(); - TGeoShape* right_solid = boolean->GetLeftShape(); + TGeoShape* right_solid = boolean->GetRightShape(); + if ( instanceOf<TruncatedTube>(solid) ) { + stringstream params(right_matrix->GetTitle()); + vector<double> pars; + pars.reserve(8); + for(size_t i=0; i<8; ++i) { + double val; + params >> val; + pars.emplace_back(val); + if ( !params.good() ) { + except("Solid::dimensions","+++ Invalid parameter stream."); + } + } + return pars; +#if 0 + TGeoTubeSeg* tubs = (TGeoTubeSeg*)left_solid; + TGeoBBox* box = (TGeoBBox*)right_solid; + double rmin = tubs->GetRmin(); + double rmax = tubs->GetRmax(); + double zhalf = tubs->GetDz(); + double startPhi = tubs->GetPhi1()*units::degree; + double deltaPhi = tubs->GetPhi2()*units::degree - startPhi; + double boxY = box->GetDY(); + double xBox = right_matrix->GetTranslation()[0]; + XYZAngles angles = detail::matrix::_xyzAngles(right_matrix); + double alpha = -angles.Z(); + double sin_alpha = std::sin(std::fabs(alpha)); + double sin2alpha = sin_alpha*sin_alpha; + double cos_phi = std::cos(deltaPhi); + double cos2phi = cos_phi*cos_phi; + double sin2phi = 1.0 - cos2phi; + double ss1 = 1.0 - (sin2phi/sin2alpha); + double R = 0, r = 0; + bool cutInside = true; + + /// Need to select physical solutions: THIS DOES NOT WORK. CANNOT RESOLVE THE AMBIGUITY. + double r1 = xBox + boxY/sin_alpha; + double r2 = xBox - boxY/sin_alpha; + if ( r1 > 0 ) + r = r1, cutInside = true; + else if ( r2 > 0 ) + r = r2, cutInside = false; + else + except("","+++ Bad parameters"); + + double R1 = -r*cos_phi/ss1*(1.0 + std::sqrt(1.0 + (1.0 - ss1/cos2phi))); + double R2 = -r*cos_phi/ss1*(1.0 - std::sqrt(1.0 + (1.0 - ss1/cos2phi))); + /// Need to select physical solutions: THIS DOES NOT WORK. CANNOT RESOLVE THE AMBIGUITY. + if ( R1 > 0 ) + R = R1; + else if ( R2 > 0 ) + R = R2; + else + except("","+++ Bad parameters"); + double cutAtStart = r; + double cutAtDelta = R; + + cout << "dimensions: " << endl; + cout << right_matrix->GetTitle() << endl; + cout << TRUNCATEDTUBE_TAG << ":" << endl + << "\t zhalf: " << zhalf << " " << endl + << "\t rmin: " << rmin << " " << endl + << "\t rmax: " << rmax << " " << endl + << "\t startPhi: " << startPhi/units::degree << " " << endl + << "\t deltaPhi: " << deltaPhi/units::degree << " " << endl + << "\t cutAtStart:" << cutAtStart << " " << endl + << "\t cutAtDelta:" << cutAtDelta << " " << endl + << "\t cutInside: " << char(cutInside ? '1' : '0') << endl + << "\t\t boxY: " << boxY << endl + << "\t\t alpha: " << angles.Z() << " [rad] " << angles.Z()/units::degree << " [degree]" << endl + << "\t\t sin_alpha: " << sin_alpha << endl + << "\t\t xBox: " << xBox << endl + << "\t\t r1: " << r1 << endl + << "\t\t r2: " << r2 << endl + << "\t\t R1: " << R1 << endl + << "\t\t R2: " << R2 << endl + ; + + return { + zhalf, rmin, rmax, + startPhi*units::deg, deltaPhi*units::deg, + cutAtStart, cutAtDelta, cutInside ? 1.0 : 0.0 }; +#endif + } + else if ( instanceOf<PseudoTrap>(solid) ) { + stringstream params(right_matrix->GetTitle()); + vector<double> pars; + pars.reserve(7); + cout << "dimensions: [" << PSEUDOTRAP_TAG << "]" << endl + << right_matrix->GetTitle() << endl; + for(size_t i=0; i<7; ++i) { + double val; + params >> val; + pars.emplace_back(val); + if ( !params.good() ) { + except("Solid::dimensions","+++ Invalid parameter stream."); + } + } + return pars; + } + else if ( instanceOf<SubtractionSolid>(solid) ) { + } + else if ( instanceOf<UnionSolid>(solid) ) { + } + else if ( instanceOf<IntersectionSolid>(solid) ) { + } + + TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator(); + TGeoMatrix* left_matrix = boolean->GetRightMatrix(); const Double_t* left_tr = left_matrix->GetTranslation(); const Double_t* left_rot = left_matrix->GetRotationMatrix(); const Double_t* right_tr = right_matrix->GetTranslation(); @@ -296,12 +394,12 @@ namespace dd4hep { } /// Access Shape dimension parameters (As in TGeo, but angles in radians rather than degrees) - std::vector<double> get_shape_dimensions(Solid solid) { + vector<double> get_shape_dimensions(Solid solid) { return get_shape_dimensions(solid.ptr()); } /// Set the shape dimensions. As for the TGeo shape, but angles in rad rather than degrees. - void set_shape_dimensions(TGeoShape* shape, const std::vector<double>& params) { + void set_shape_dimensions(TGeoShape* shape, const vector<double>& params) { if (shape) { TClass* cl = shape->IsA(); Solid solid(shape); @@ -485,10 +583,142 @@ namespace dd4hep { solid._setDimensions(&pars[0]); } else if (cl == TGeoCompositeShape::Class()) { - //TGeoCompositeShape* sh = (TGeoCompositeShape*) shape; + TGeoCompositeShape* sh = (TGeoCompositeShape*) shape; + TGeoBoolNode* boolean = sh->GetBoolNode(); + TGeoMatrix* right_matrix = boolean->GetRightMatrix(); + TGeoShape* left_solid = boolean->GetLeftShape(); + TGeoShape* right_solid = boolean->GetRightShape(); if ( instanceOf<TruncatedTube>(solid) ) { + TGeoTubeSeg* tubs = (TGeoTubeSeg*)left_solid; + TGeoBBox* box = (TGeoBBox*)right_solid; + double zhalf = params[0]; + double rmin = params[1]; + double rmax = params[2]; + double startPhi = params[3]/units::deg; + double deltaPhi = params[4]/units::deg; + double cutAtStart = params[5]; + double cutAtDelta = params[6]; + bool cutInside = params[7] > 0.5; + + cout << "setDimensions: [" << TRUNCATEDTUBE_TAG << "]" << endl + << right_matrix->GetTitle() << endl; + // check the parameters + if( rmin <= 0 || rmax <= 0 || cutAtStart <= 0 || cutAtDelta <= 0 ) + except(TRUNCATEDTUBE_TAG,"++ 0 <= rIn,cutAtStart,rOut,cutAtDelta,rOut violated!"); + else if( rmin >= rmax ) + except(TRUNCATEDTUBE_TAG,"++ rIn<rOut violated!"); + else if( startPhi != 0. ) + except(TRUNCATEDTUBE_TAG,"++ startPhi != 0 not supported!"); + + double r = cutAtStart; + double R = cutAtDelta; + // angle of the box w.r.t. tubs + double cath = r - R * std::cos( deltaPhi*units::deg ); + double hypo = std::sqrt( r*r + R*R - 2.*r*R * std::cos( deltaPhi*units::deg )); + double cos_alpha = cath / hypo; + double alpha = std::acos( cos_alpha ); + double sin_alpha = std::sin( std::fabs(alpha) ); + + // exaggerate dimensions - does not matter, it's subtracted! + // If we don't, the **edge** of the box would cut into the tube segment + // for larger delta-phi values + double boxX = 1.1*rmax + rmax/sin_alpha; // Need to adjust for move! + double boxY = rmax; + // width of the box > width of the tubs + double boxZ = 1.1 * zhalf; + double xBox; // center point of the box + if( cutInside ) + xBox = r - boxY / sin_alpha; + else + xBox = r + boxY / sin_alpha; + + // rotationmatrix of box w.r.t. tubs + TGeoRotation rot; + rot.RotateZ( -alpha/dd4hep::deg ); + double box_dim[] = {boxX, boxY, boxZ}; + double tub_dim[] = {rmin, rmax, zhalf, startPhi, deltaPhi}; + box->SetDimensions(box_dim); + tubs->SetDimensions(tub_dim); + TGeoCombiTrans* combi = (TGeoCombiTrans*)right_matrix; + combi->SetRotation(rot); + combi->SetTranslation(xBox, 0, 0); + return; } else if ( instanceOf<PseudoTrap>(solid) ) { + double x1 = params[0]; + double x2 = params[1]; + double y1 = params[2]; + double y2 = params[3]; + double z = params[4]; + double r = params[5]; + bool atMinusZ = params[6] > 0.5; + double x = atMinusZ ? x1 : x2; + double h = 0; + bool intersec = false; // union or intersection solid + double displacement = 0; + double startPhi = 0; + double halfZ = z; + double halfOpeningAngle = std::asin( x / std::abs( r ))/units::deg; + /// calculate the displacement of the tubs w.r.t. to the trap, determine the opening angle of the tubs + double delta = std::sqrt( r * r - x * x ); + + cout << "setDimensions: [" << PSEUDOTRAP_TAG << "]" << endl + << right_matrix->GetTitle() << endl; + + // Implementation from : + // https://cmssdt.cern.ch/lxr/source/Fireworks/Geometry/src/TGeoMgrFromDdd.cc#0538 + if( r < 0 && std::abs(r) >= x ) { + intersec = true; // intersection solid + h = y1 < y2 ? y2 : y1; // tubs half height + h += h/20.; // enlarge a bit - for subtraction solid + if( atMinusZ ) { + displacement = - halfZ - delta; + startPhi = 90.0 - halfOpeningAngle; + } + else { + displacement = halfZ + delta; + startPhi = -90.0 - halfOpeningAngle; + } + } + else if( r > 0 && std::abs(r) >= x ) { + if( atMinusZ ) { + displacement = - halfZ + delta; + startPhi = 270.0 - halfOpeningAngle; + h = y1; + } + else + { + displacement = halfZ - delta; + startPhi = 90.0 - halfOpeningAngle; + h = y2; + } + } + else { + except(PSEUDOTRAP_TAG,"Check parameters of the PseudoTrap!"); + } + double trd2_dim[] = { x1, x2, y1, y2, halfZ }; + double tube_dim[] = { 0.0, std::abs(r), h, startPhi, startPhi + halfOpeningAngle*2. }; + if( intersec && left_solid->IsA() == TGeoTrd2::Class() ) { + left_solid->SetDimensions(trd2_dim); + right_solid->SetDimensions(tube_dim); + } + else if ( right_solid->IsA() == TGeoCompositeShape::Class() ) { + double box_dim[] = { 1.1*x, 1.1*h, std::sqrt(r*r-x*x) }; + TGeoCompositeShape* comp = (TGeoCompositeShape*)right_solid; + TGeoBoolNode* b_s = comp->GetBoolNode(); + b_s->GetLeftShape()->SetDimensions(tube_dim); + b_s->GetRightShape()->SetDimensions(box_dim); + left_solid->SetDimensions(trd2_dim); + } + else { + except("PseudoTrap","+++ Incompatible change of parameters."); + } + ((TGeoTranslation*)right_matrix)->SetTranslation(0,0,displacement); + stringstream params; + params << x1 << " " << x2 << " " << y1 << " " << y2 << " " << z << " " + << r << " " << char(atMinusZ ? '1' : '0') << " "; + right_matrix->SetTitle(params.str().c_str()); + return; } else if ( instanceOf<SubtractionSolid>(solid) ) { } @@ -507,7 +737,7 @@ namespace dd4hep { except("Solid","set_shape_dimensions: Failed to set dimensions [Invalid handle]."); } /// Set the shape dimensions. As for the TGeo shape, but angles in rad rather than degrees. - void set_shape_dimensions(Solid solid, const std::vector<double>& params) { + void set_shape_dimensions(Solid solid, const vector<double>& params) { set_shape_dimensions(solid.ptr(), params); } } @@ -645,7 +875,7 @@ string dd4hep::toStringSolid(const TGeoShape* shape, int precision) { else if (shape->IsA() == TGeoCompositeShape::Class()) { const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape; const TGeoBoolNode* boolean = sh->GetBoolNode(); - const TGeoShape* left = boolean->GetLeftShape(); + const TGeoShape* left = boolean->GetLeftShape(); const TGeoShape* right = boolean->GetRightShape(); TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator(); if (oper == TGeoBoolNode::kGeoSubtraction) @@ -661,7 +891,7 @@ string dd4hep::toStringSolid(const TGeoShape* shape, int precision) { } /// Output mesh vertices to string -std::string dd4hep::toStringMesh(const TGeoShape* shape, int prec) { +string dd4hep::toStringMesh(const TGeoShape* shape, int prec) { Solid sol(shape); stringstream os; @@ -747,14 +977,14 @@ template <typename T> vector<double> Solid_type<T>::dimensions() { } /// Set the shape dimensions. As for the TGeo shape, but angles in rad rather than degrees. -template <typename T> Solid_type<T>& Solid_type<T>::setDimensions(const std::vector<double>& params) { +template <typename T> Solid_type<T>& Solid_type<T>::setDimensions(const vector<double>& params) { set_shape_dimensions(this->access(), params); return *this; } /// Divide volume into subsections (See the ROOT manuloa for details) template <typename T> TGeoVolume* -Solid_type<T>::divide(const Volume& voldiv, const std::string& divname, +Solid_type<T>::divide(const Volume& voldiv, const string& divname, int iaxis, int ndiv, double start, double step) const { T* p = this->ptr(); if ( p ) { @@ -770,7 +1000,7 @@ ShapelessSolid::ShapelessSolid(const string& nam) { _assign(new TGeoShapeAssembly(), nam, "Assembly", true); } -void Box::make(const std::string& nam, double x_val, double y_val, double z_val) { +void Box::make(const string& nam, double x_val, double y_val, double z_val) { _assign(new TGeoBBox(nam.c_str(), x_val, y_val, z_val), "", "Box", true); } @@ -797,7 +1027,7 @@ double Box::z() const { } /// Internal helper method to support object construction -void HalfSpace::make(const std::string& nam, const double* const point, const double* const normal) { +void HalfSpace::make(const string& nam, const double* const point, const double* const normal) { _assign(new TGeoHalfSpace(nam.c_str(),(Double_t*)point, (Double_t*)normal), "", "HalfSpace",true); } @@ -848,12 +1078,12 @@ Polycone::Polycone(double startPhi, double deltaPhi, const vector<double>& r, co } /// Constructor to be used when creating a new object -Polycone::Polycone(const std::string& nam, double startPhi, double deltaPhi) { +Polycone::Polycone(const string& nam, double startPhi, double deltaPhi) { _assign(new TGeoPcon(nam.c_str(), startPhi/units::deg, deltaPhi/units::deg, 0), "", "Polycone", false); } /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes -Polycone::Polycone(const std::string& nam, double startPhi, double deltaPhi, +Polycone::Polycone(const string& nam, double startPhi, double deltaPhi, const vector<double>& rmin, const vector<double>& rmax, const vector<double>& z) { vector<double> params; if (rmin.size() < 2) { @@ -874,7 +1104,7 @@ Polycone::Polycone(const std::string& nam, double startPhi, double deltaPhi, } /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes -Polycone::Polycone(const std::string& nam, double startPhi, double deltaPhi, const vector<double>& r, const vector<double>& z) { +Polycone::Polycone(const string& nam, double startPhi, double deltaPhi, const vector<double>& r, const vector<double>& z) { vector<double> params; if (r.size() < 2) { throw runtime_error("dd4hep: PolyCone Not enough Z planes. minimum is 2!"); @@ -928,7 +1158,7 @@ ConeSegment::ConeSegment(double dz, } /// Constructor to be used when creating a new cone segment object -ConeSegment::ConeSegment(const std::string& nam, +ConeSegment::ConeSegment(const string& nam, double dz, double rmin1, double rmax1, double rmin2, double rmax2, @@ -949,7 +1179,7 @@ ConeSegment& ConeSegment::setDimensions(double dz, } /// Constructor to be used when creating a new object with attribute initialization -void Cone::make(const std::string& nam, double z, double rmin1, double rmax1, double rmin2, double rmax2) { +void Cone::make(const string& nam, double z, double rmin1, double rmax1, double rmin2, double rmax2) { _assign(new TGeoCone(nam.c_str(), z, rmin1, rmax1, rmin2, rmax2 ), "", "Cone", true); } @@ -979,14 +1209,14 @@ CutTube::CutTube(double rmin, double rmax, double dz, double startPhi, double en } /// Constructor to be used when creating a new object with attribute initialization -CutTube::CutTube(const std::string& nam, +CutTube::CutTube(const string& nam, double rmin, double rmax, double dz, double startPhi, double endPhi, double lx, double ly, double lz, double tx, double ty, double tz) { make(nam, rmin,rmax,dz,startPhi/units::deg,endPhi/units::deg,lx,ly,lz,tx,ty,tz); } /// Constructor to be used when creating a new object with attribute initialization -void CutTube::make(const std::string& nam, double rmin, double rmax, double dz, double startPhi, double endPhi, +void CutTube::make(const string& nam, double rmin, double rmax, double dz, double startPhi, double endPhi, double lx, double ly, double lz, double tx, double ty, double tz) { _assign(new TGeoCtub(nam.c_str(), rmin,rmax,dz,startPhi,endPhi,lx,ly,lz,tx,ty,tz),"","CutTube",true); } @@ -997,13 +1227,13 @@ TruncatedTube::TruncatedTube(double zhalf, double rmin, double rmax, double star { make("", zhalf, rmin, rmax, startPhi/units::deg, deltaPhi/units::deg, cutAtStart, cutAtDelta, cutInside); } /// Constructor to create a truncated tube object with attribute initialization -TruncatedTube::TruncatedTube(const std::string& nam, +TruncatedTube::TruncatedTube(const string& nam, double zhalf, double rmin, double rmax, double startPhi, double deltaPhi, double cutAtStart, double cutAtDelta, bool cutInside) { make(nam, zhalf, rmin, rmax, startPhi/units::deg, deltaPhi/units::deg, cutAtStart, cutAtDelta, cutInside); } /// Internal helper method to support object construction -void TruncatedTube::make(const std::string& nam, +void TruncatedTube::make(const string& nam, double zhalf, double rmin, double rmax, double startPhi, double deltaPhi, double cutAtStart, double cutAtDelta, bool cutInside) { // check the parameters @@ -1038,15 +1268,39 @@ void TruncatedTube::make(const std::string& nam, // rotationmatrix of box w.r.t. tubs TGeoRotation rot; - //rot.RotateX( 90.0 ); rot.RotateZ( -alpha/dd4hep::deg ); TGeoTranslation trans(xBox, 0., 0.); TGeoBBox* box = new TGeoBBox((nam+"Box").c_str(), boxX, boxY, boxZ); TGeoTubeSeg* tubs = new TGeoTubeSeg((nam+"Tubs").c_str(), rmin, rmax, zhalf, startPhi, deltaPhi); - TGeoSubtraction* sub = new TGeoSubtraction(tubs, box, nullptr, new TGeoCombiTrans(trans, rot)); - // For debugging: - // TGeoUnion* sub = new TGeoUnion(tubs, box, nullptr, new TGeoCombiTrans(trans, rot)); + TGeoCombiTrans* combi = new TGeoCombiTrans(trans, rot); + TGeoSubtraction* sub = new TGeoSubtraction(tubs, box, nullptr, combi); _assign(new TGeoCompositeShape(nam.c_str(), sub),"",TRUNCATEDTUBE_TAG,true); + stringstream params; + params << zhalf << " " << endl + << rmin << " " << endl + << rmax << " " << endl + << startPhi*units::deg << " " << endl + << deltaPhi*units::deg << " " << endl + << cutAtStart << " " << endl + << cutAtDelta << " " << endl + << char(cutInside ? '1' : '0') << endl; + combi->SetTitle(params.str().c_str()); + //cout << "Params: " << params.str() << endl; +#if 0 + params << TRUNCATEDTUBE_TAG << ":" << endl + << "\t zhalf: " << zhalf << " " << endl + << "\t rmin: " << rmin << " " << endl + << "\t rmax: " << rmax << " " << endl + << "\t startPhi: " << startPhi << " " << endl + << "\t deltaPhi: " << deltaPhi << " " << endl + << "\t r/cutAtStart:" << cutAtStart << " " << endl + << "\t R/cutAtDelta:" << cutAtDelta << " " << endl + << "\t cutInside: " << char(cutInside ? '1' : '0') << endl + << "\t\t alpha: " << alpha << endl + << "\t\t sin_alpha: " << sin_alpha << endl + << "\t\t boxY: " << boxY << endl + << "\t\t xBox: " << xBox << endl; +#endif #if 0 cout << "Trans:"; trans.Print(); cout << endl; cout << "Rot: "; rot.Print(); cout << endl; @@ -1074,12 +1328,12 @@ void TruncatedTube::make(const std::string& nam, } /// Constructor to be used when creating a new object with attribute initialization -void EllipticalTube::make(const std::string& nam, double a, double b, double dz) { +void EllipticalTube::make(const string& nam, double a, double b, double dz) { _assign(new TGeoEltu(nam.c_str(), a, b, dz), "", "EllipticalTube", true); } /// Constructor to be used when creating a new object with attribute initialization -void Trd1::make(const std::string& nam, double x1, double x2, double y, double z) { +void Trd1::make(const string& nam, double x1, double x2, double y, double z) { _assign(new TGeoTrd1(nam.c_str(), x1, x2, y, z ), "", "Trd1", true); } @@ -1091,7 +1345,7 @@ Trd1& Trd1::setDimensions(double x1, double x2, double y, double z) { } /// Constructor to be used when creating a new object with attribute initialization -void Trd2::make(const std::string& nam, double x1, double x2, double y1, double y2, double z) { +void Trd2::make(const string& nam, double x1, double x2, double y1, double y2, double z) { _assign(new TGeoTrd2(nam.c_str(), x1, x2, y1, y2, z ), "", "Trd2", true); } @@ -1103,7 +1357,7 @@ Trd2& Trd2::setDimensions(double x1, double x2, double y1, double y2, double z) } /// Constructor to be used when creating a new object with attribute initialization -void Paraboloid::make(const std::string& nam, double r_low, double r_high, double delta_z) { +void Paraboloid::make(const string& nam, double r_low, double r_high, double delta_z) { _assign(new TGeoParaboloid(nam.c_str(), r_low, r_high, delta_z ), "", "Paraboloid", true); } @@ -1115,7 +1369,7 @@ Paraboloid& Paraboloid::setDimensions(double r_low, double r_high, double delta_ } /// Constructor to create a new anonymous object with attribute initialization -void Hyperboloid::make(const std::string& nam, double rin, double stin, double rout, double stout, double dz) { +void Hyperboloid::make(const string& nam, double rin, double stin, double rout, double stout, double dz) { _assign(new TGeoHype(nam.c_str(), rin, stin/units::deg, rout, stout/units::deg, dz), "", "Hyperboloid", true); } @@ -1127,7 +1381,7 @@ Hyperboloid& Hyperboloid::setDimensions(double rin, double stin, double rout, do } /// Constructor function to be used when creating a new object with attribute initialization -void Sphere::make(const std::string& nam, double rmin, double rmax, double startTheta, double endTheta, double startPhi, double endPhi) { +void Sphere::make(const string& nam, double rmin, double rmax, double startTheta, double endTheta, double startPhi, double endPhi) { _assign(new TGeoSphere(nam.c_str(), rmin, rmax, startTheta/units::deg, endTheta/units::deg, startPhi/units::deg, endPhi/units::deg), "", "Sphere", true); @@ -1141,7 +1395,7 @@ Sphere& Sphere::setDimensions(double rmin, double rmax, double startTheta, doubl } /// Constructor to be used when creating a new object with attribute initialization -void Torus::make(const std::string& nam, double r, double rmin, double rmax, double startPhi, double deltaPhi) { +void Torus::make(const string& nam, double r, double rmin, double rmax, double startPhi, double deltaPhi) { _assign(new TGeoTorus(nam.c_str(), r, rmin, rmax, startPhi/units::deg, deltaPhi/units::deg), "", "Torus", true); } @@ -1162,7 +1416,7 @@ Trap::Trap(double z, double theta, double phi, } /// Constructor to be used when creating a new anonymous object with attribute initialization -Trap::Trap(const std::string& nam, +Trap::Trap(const string& nam, double z, double theta, double phi, double h1, double bl1, double tl1, double alpha1, double h2, double bl2, double tl2, double alpha2) { @@ -1172,7 +1426,7 @@ Trap::Trap(const std::string& nam, } /// Constructor to be used when creating a new anonymous object with attribute initialization -void Trap::make(const std::string& nam, double pz, double py, double px, double pLTX) { +void Trap::make(const string& nam, double pz, double py, double px, double pLTX) { double z = pz / 2e0; double theta = 0e0; double phi = 0e0; @@ -1197,7 +1451,7 @@ Trap& Trap::setDimensions(double z, double theta, double phi, } /// Internal helper method to support object construction -void PseudoTrap::make(const std::string& nam, double x1, double x2, double y1, double y2, double z, double r, bool atMinusZ) { +void PseudoTrap::make(const string& nam, double x1, double x2, double y1, double y2, double z, double r, bool atMinusZ) { double x = atMinusZ ? x1 : x2; double h = 0; bool intersec = false; // union or intersection solid @@ -1285,11 +1539,15 @@ void PseudoTrap::make(const std::string& nam, double x1, double x2, double y1, d SubtractionSolid sub((nam+"Subs").c_str(), tubs, Box(1.1*x, 1.1*h, std::sqrt(r*r-x*x)), Transform3D(RotationX(M_PI/2.))); solid = UnionSolid(nam, trap, sub, Transform3D(RotationX(M_PI/2.), Position(0,0,displacement))).ptr(); } + stringstream params; + params << x1 << " " << x2 << " " << y1 << " " << y2 << " " << z << " " + << r << " " << char(atMinusZ ? '1' : '0') << " "; + solid->GetBoolNode()->GetRightMatrix()->SetTitle(params.str().c_str()); _assign(solid,"",PSEUDOTRAP_TAG, true); } /// Helper function to create poly hedron -void PolyhedraRegular::make(const std::string& nam, int nsides, double rmin, double rmax, +void PolyhedraRegular::make(const string& nam, int nsides, double rmin, double rmax, double zpos, double zneg, double start, double delta) { if (rmin < 0e0 || rmin > rmax) throw runtime_error("dd4hep: PolyhedraRegular: Illegal argument rmin:<" + _toString(rmin) + "> is invalid!"); @@ -1301,7 +1559,7 @@ void PolyhedraRegular::make(const std::string& nam, int nsides, double rmin, dou } /// Helper function to create poly hedron -void Polyhedra::make(const std::string& nam, int nsides, double start, double delta, +void Polyhedra::make(const string& nam, int nsides, double start, double delta, const vector<double>& z, const vector<double>& rmin, const vector<double>& rmax) { vector<double> temp; if ( rmin.size() != z.size() || rmax.size() != z.size() ) { @@ -1324,7 +1582,7 @@ void Polyhedra::make(const std::string& nam, int nsides, double start, double de } /// Helper function to create the polyhedron -void ExtrudedPolygon::make(const std::string& nam, +void ExtrudedPolygon::make(const string& nam, const vector<double>& pt_x, const vector<double>& pt_y, const vector<double>& sec_z, @@ -1341,7 +1599,7 @@ void ExtrudedPolygon::make(const std::string& nam, } /// Creator method -void EightPointSolid::make(const std::string& nam, double dz, const double* vtx) { +void EightPointSolid::make(const string& nam, double dz, const double* vtx) { _assign(new TGeoArb8(nam.c_str(), dz, (double*)vtx), "", "EightPointSolid", true); } @@ -1376,31 +1634,31 @@ SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, con } /// Constructor to be used when creating a new object. Position is identity, Rotation is the identity rotation -SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2) { +SubtractionSolid::SubtractionSolid(const string& nam, const Solid& shape1, const Solid& shape2) { TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity()); _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true); } /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother -SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) { +SubtractionSolid::SubtractionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) { TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans)); _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true); } /// Constructor to be used when creating a new object. Rotation is the identity rotation -SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) { +SubtractionSolid::SubtractionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) { TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos)); _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true); } /// Constructor to be used when creating a new object -SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) { +SubtractionSolid::SubtractionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) { TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot)); _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true); } /// Constructor to be used when creating a new object -SubtractionSolid::SubtractionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) { +SubtractionSolid::SubtractionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) { TGeoSubtraction* sub = new TGeoSubtraction(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot)); _assign(new TGeoCompositeShape(nam.c_str(), sub), "", SUBTRACTION_TAG, true); } @@ -1436,31 +1694,31 @@ UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Rotation3 } /// Constructor to be used when creating a new object. Position is identity, Rotation is identity rotation -UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2) { +UnionSolid::UnionSolid(const string& nam, const Solid& shape1, const Solid& shape2) { TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity()); _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true); } /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother -UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) { +UnionSolid::UnionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) { TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans)); _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true); } /// Constructor to be used when creating a new object. Rotation is identity rotation -UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) { +UnionSolid::UnionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) { TGeoUnion* uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos)); _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true); } /// Constructor to be used when creating a new object -UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) { +UnionSolid::UnionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) { TGeoUnion *uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot)); _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true); } /// Constructor to be used when creating a new object -UnionSolid::UnionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) { +UnionSolid::UnionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) { TGeoUnion *uni = new TGeoUnion(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot)); _assign(new TGeoCompositeShape(nam.c_str(), uni), "", UNION_TAG, true); } @@ -1496,31 +1754,31 @@ IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, c } /// Constructor to be used when creating a new object. Position is identity, Rotation is identity rotation -IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2) { +IntersectionSolid::IntersectionSolid(const string& nam, const Solid& shape1, const Solid& shape2) { TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_identity()); _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true); } /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother -IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) { +IntersectionSolid::IntersectionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Transform3D& trans) { TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_transform(trans)); _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true); } /// Constructor to be used when creating a new object. Position is identity. -IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) { +IntersectionSolid::IntersectionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Position& pos) { TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_translation(pos)); _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true); } /// Constructor to be used when creating a new object -IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) { +IntersectionSolid::IntersectionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const RotationZYX& rot) { TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotationZYX(rot)); _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true); } /// Constructor to be used when creating a new object -IntersectionSolid::IntersectionSolid(const std::string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) { +IntersectionSolid::IntersectionSolid(const string& nam, const Solid& shape1, const Solid& shape2, const Rotation3D& rot) { TGeoIntersection* inter = new TGeoIntersection(shape1, shape2, detail::matrix::_identity(), detail::matrix::_rotation3D(rot)); _assign(new TGeoCompositeShape(nam.c_str(), inter), "", INTERSECTION_TAG, true); } diff --git a/DDCore/src/plugins/ShapePlugins.cpp b/DDCore/src/plugins/ShapePlugins.cpp index 5290b8fe7..d464456e3 100644 --- a/DDCore/src/plugins/ShapePlugins.cpp +++ b/DDCore/src/plugins/ShapePlugins.cpp @@ -660,7 +660,15 @@ void* shape_mesh_verifier(Detector& description, int argc, char** argv) { for (Int_t ipv=0, npv=v->GetNdaughters(); ipv < npv; ipv++) { PlacedVolume place = v->GetNode(ipv); Solid solid = place.volume().solid(); - if ( solid->IsA() != TGeoCompositeShape::Class() ) { + if ( instanceOf<TruncatedTube>(solid) ) { + auto params = solid.dimensions(); + solid.setDimensions(params); + } + else if ( instanceOf<PseudoTrap>(solid) ) { + auto params = solid.dimensions(); + solid.setDimensions(params); + } + else if ( solid->IsA() != TGeoCompositeShape::Class() ) { auto params = solid.dimensions(); solid.setDimensions(params); } diff --git a/DDG4/include/DDG4/Geant4SensDetAction.h b/DDG4/include/DDG4/Geant4SensDetAction.h index 2febc51bd..86c5b5e03 100644 --- a/DDG4/include/DDG4/Geant4SensDetAction.h +++ b/DDG4/include/DDG4/Geant4SensDetAction.h @@ -126,7 +126,7 @@ namespace dd4hep { int m_hitCreationMode = 0; #if defined(G__ROOT) || defined(__CLING__) || defined(__ROOTCLING__) /// Reference to the detector description object - Detector* m_detDesc; + Detector* m_detDesc {0}; #else /// Reference to the detector description object Detector& m_detDesc; diff --git a/DDG4/plugins/Geant4EventReaderHepMC.cpp b/DDG4/plugins/Geant4EventReaderHepMC.cpp index f3842e9a3..ad0afc49d 100644 --- a/DDG4/plugins/Geant4EventReaderHepMC.cpp +++ b/DDG4/plugins/Geant4EventReaderHepMC.cpp @@ -309,11 +309,11 @@ void HepMC::fix_particles(EventStream& info) { for(id=v->out.begin(); id!=v->out.end();++id) { EventStream::Particles::iterator ipp = parts.find(*id); Geant4Particle* dau = ipp != parts.end() ? (*ipp).second : 0; - if ( !dau ) { + if ( !dau ) cout << "ERROR: Invalid daughter particle: " << *id << endl; - } + else + dau->parents.insert(p->id); p->daughters.insert(*id); - dau->parents.insert(p->id); } } } @@ -486,6 +486,10 @@ int HepMC::read_vertex(EventStream &info, istream& is, istringstream & input) } input >> id >> dummy >> v->x >> v->y >> v->z >> v->time >> num_orphans_in >> num_particles_out >> weights_size; + if( !input ) { + delete v; + return 0; + } #if defined(DD4HEP_DEBUG_HEP_MC_VERTEX) if ( id == DD4HEP_DEBUG_HEP_MC_VERTEX ) { printout(ALWAYS,"HepMC","++ Created Vertex ID=%d",id); diff --git a/DDG4/plugins/Geant4GDMLWriteAction.cpp b/DDG4/plugins/Geant4GDMLWriteAction.cpp index 2c79155d4..24e66ce20 100644 --- a/DDG4/plugins/Geant4GDMLWriteAction.cpp +++ b/DDG4/plugins/Geant4GDMLWriteAction.cpp @@ -134,11 +134,12 @@ void Geant4GDMLWriteAction::writeGDML() { error("+++ No GDML file name given. Please set the output file (property Output)"); return; } - if ( 0 == ::stat(fname.c_str(), &buff) && !m_overWrite ) { - error("+++ GDML file elready exists. Please set another output file (property Output)"); - return; - } - if ( 0 == ::stat(fname.c_str(), &buff) && m_overWrite ) { + if ( 0 == ::stat(fname.c_str(), &buff) ) { + if ( !m_overWrite ) { + error("+++ GDML file %s elready exists. Please set another output file (property Output)", + fname.c_str()); + return; + } warning("+++ GDML file %s already exists. Overwriting existing file.", fname.c_str()); ::unlink(fname.c_str()); } -- GitLab