00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "MagneticField/GeomBuilder/src/volumeHandle.h"
00012 #include "DetectorDescription/Core/interface/DDExpandedView.h"
00013 #include "DetectorDescription/Base/interface/DDTranslation.h"
00014 #include "DetectorDescription/Core/interface/DDSolid.h"
00015 #include "DetectorDescription/Core/interface/DDValue.h"
00016 #include "DetectorDescription/Core/interface/DDMaterial.h"
00017
00018 #include "DataFormats/GeometrySurface/interface/Plane.h"
00019 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00020 #include "DataFormats/GeometrySurface/interface/Cone.h"
00021 #include "DataFormats/GeometryVector/interface/CoordinateSets.h"
00022
00023 #include "CLHEP/Units/SystemOfUnits.h"
00024
00025
00026
00027
00028 #include "MagneticField/Layers/interface/MagVerbosity.h"
00029
00030 #include <string>
00031 #include <iterator>
00032 #include <iomanip>
00033 #include <iostream>
00034
00035 using namespace SurfaceOrientation;
00036 using namespace std;
00037
00038
00039 MagGeoBuilderFromDDD::volumeHandle::~volumeHandle(){
00040 delete refPlane;
00041 }
00042
00043 MagGeoBuilderFromDDD::volumeHandle::volumeHandle(const DDExpandedView &fv, bool expand2Pi)
00044 : name(fv.logicalPart().name().name()),
00045 copyno(fv.copyno()),
00046 magVolume(0),
00047 masterSector(1),
00048 theRN(0.),
00049 theRMin(0.),
00050 theRMax(0.),
00051 refPlane(0),
00052 solid(fv.logicalPart().solid()),
00053 center_(GlobalPoint(fv.translation().x()/cm,
00054 fv.translation().y()/cm,
00055 fv.translation().z()/cm)),
00056 expand(expand2Pi),
00057 isIronFlag(false)
00058 {
00059 for (int i=0; i<6; ++i) {
00060 isAssigned[i] = false;
00061 }
00062
00063
00064 if (MagGeoBuilderFromDDD::debug) {
00065 cout.precision(7);
00066 }
00067
00068
00069 referencePlane(fv);
00070
00071 if (solid.shape() == ddbox) {
00072 buildBox(fv);
00073 } else if (solid.shape() == ddtrap) {
00074 buildTrap(fv);
00075 } else if (solid.shape() == ddcons) {
00076 buildCons(fv);
00077 } else if (solid.shape() == ddtubs) {
00078 buildTubs(fv);
00079 } else if (solid.shape() == ddpseudotrap) {
00080 buildPseudoTrap(fv);
00081 } else if (solid.shape() == ddtrunctubs) {
00082 buildTruncTubs(fv);
00083 } else {
00084 cout << "volumeHandle ctor: Unexpected solid: " << (int) solid.shape() << endl;
00085 }
00086
00087
00088 DDsvalues_type sv(fv.mergedSpecifics());
00089
00090 {
00091 std::vector<std::string> temp;
00092 std::string pname = "table";
00093 DDValue val(pname);
00094 DDsvalues_type sv(fv.mergedSpecifics());
00095 if (DDfetch(&sv,val)) {
00096 temp = val.strings();
00097 if (temp.size() != 1) {
00098 cout << "*** WARNING: volume has > 1 SpecPar " << pname << endl;
00099 }
00100 magFile = temp[0];
00101 } else {
00102 cout << "*** WARNING: volume does not have a SpecPar " << pname << endl;
00103 cout << " DDsvalues_type: " << fv.mergedSpecifics() << endl;
00104 }
00105 }
00106
00107 {
00108 std::vector<double> temp;
00109 const std::string pname = "masterSector";
00110 DDValue val(pname);
00111 if (DDfetch(&sv,val)) {
00112 temp = val.doubles();
00113 if (temp.size() != 1) {
00114 cout << "*** WARNING: volume has > 1 SpecPar " << pname << endl;
00115 }
00116 masterSector = int(temp[0]+.5);
00117 } else {
00118 cout << "*** WARNING: volume does not have a SpecPar " << pname << endl;
00119 cout << " DDsvalues_type: " << fv.mergedSpecifics() << endl;
00120 }
00121 }
00122
00123
00124 if (fv.logicalPart().material().name().name() == "Iron") isIronFlag=true;
00125
00126
00127 if (MagGeoBuilderFromDDD::debug) {
00128 cout << " RMin = " << theRMin <<endl;
00129 cout << " RMax = " << theRMax <<endl;
00130
00131 if (theRMin < 0 || theRN < theRMin || theRMax < theRN)
00132 cout << "*** WARNING: wrong RMin/RN/RMax , shape: " << (int) shape() << endl;
00133
00134 cout << "Summary: " << name << " " << copyno
00135 << " Shape= " << (int) shape()
00136 << " trasl " << center()
00137 << " R " << center().perp()
00138 << " phi " << center().phi()
00139 << " magFile " << magFile
00140 << " Material= " << fv.logicalPart().material().name()
00141 << " isIron= " << isIronFlag
00142 << " masterSector= " << masterSector << std::endl;
00143
00144 cout << " Orientation of surfaces:";
00145 std::string sideName[3] = {"positiveSide", "negativeSide", "onSurface"};
00146 for (int i=0; i<6; ++i) {
00147 cout << " " << i << ":" << sideName[surfaces[i]->side(center_,0.3)];
00148 }
00149 cout << endl;
00150 }
00151 }
00152
00153
00154 const Surface::GlobalPoint & MagGeoBuilderFromDDD::volumeHandle::center() const {
00155 return center_;
00156 }
00157
00158 void MagGeoBuilderFromDDD::volumeHandle::referencePlane(const DDExpandedView &fv){
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188 Surface::PositionType & posResult = center_;
00189
00190
00191 DD3Vector x, y, z;
00192 fv.rotation().GetComponents(x,y,z);
00193 if (MagGeoBuilderFromDDD::debug) {
00194 if (x.Cross(y).Dot(z) < 0.5) {
00195 cout << "*** WARNING: Rotation is not RH "<< endl;
00196 }
00197 }
00198
00199
00200 Surface::RotationType
00201 rotResult(float(x.X()),float(x.Y()),float(x.Z()),
00202 float(y.X()),float(y.Y()),float(y.Z()),
00203 float(z.X()),float(z.Y()),float(z.Z()));
00204
00205 refPlane = new GloballyPositioned<float>(posResult, rotResult);
00206
00207
00208 if (MagGeoBuilderFromDDD::debug) {
00209
00210 cout << "Refplane pos " << refPlane->position() << endl;
00211
00212
00213 LocalVector globalZdir(0.,0.,1.);
00214 if (solid.shape() == ddpseudotrap) {
00215 globalZdir = LocalVector(0.,1.,0.);
00216 }
00217 if (refPlane->toGlobal(globalZdir).z()<0.) {
00218 globalZdir=-globalZdir;
00219 }
00220
00221 float chk = refPlane->toGlobal(globalZdir).dot(GlobalVector(0,0,1));
00222 if (chk < .999) cout << "*** WARNING RefPlane check failed!***"
00223 << chk << endl;
00224 }
00225 }
00226
00227
00228
00229 void MagGeoBuilderFromDDD::volumeHandle::buildPhiZSurf(double startPhi,
00230 double deltaPhi,
00231 double zhalf,
00232 double rCentr) {
00233
00234
00235 GlobalVector planeXAxis = refPlane->toGlobal(LocalVector( 1, 0, 0));
00236 GlobalVector planeYAxis = refPlane->toGlobal(LocalVector( 0, 1, 0));
00237 GlobalVector planeZAxis = refPlane->toGlobal(LocalVector( 0, 0, 1));
00238
00239
00240 GlobalVector y_phiplus = refPlane->toGlobal(LocalVector(cos(startPhi+deltaPhi),
00241 sin(startPhi+deltaPhi),0.));
00242 GlobalVector y_phiminus = refPlane->toGlobal(LocalVector(cos(startPhi),
00243 sin(startPhi),0.));
00244
00245 Surface::RotationType rot_Z(planeXAxis,planeYAxis);
00246 Surface::RotationType rot_phiplus(planeZAxis, y_phiplus);
00247 Surface::RotationType rot_phiminus(planeZAxis, y_phiminus);
00248
00249 GlobalPoint pos_zplus(center_.x(),center_.y(),center_.z()+zhalf);
00250 GlobalPoint pos_zminus(center_.x(),center_.y(),center_.z()-zhalf);
00251
00252
00253 GlobalPoint pos_phiplus(refPlane->toGlobal(LocalPoint(rCentr*cos(startPhi+deltaPhi),rCentr*sin(startPhi+deltaPhi),0.)));
00254 GlobalPoint pos_phiminus(refPlane->toGlobal(LocalPoint(rCentr*cos(startPhi),
00255 rCentr*sin(startPhi),
00256 0.)));
00257 surfaces[zplus] = new Plane(pos_zplus, rot_Z);
00258 surfaces[zminus] = new Plane(pos_zminus, rot_Z);
00259 surfaces[phiplus] = new Plane(pos_phiplus, rot_phiplus);
00260 surfaces[phiminus] = new Plane(pos_phiminus, rot_phiminus);
00261
00262 if (MagGeoBuilderFromDDD::debug) {
00263 cout << "Actual Center at: " << center_ << " R " << center_.perp()
00264 << " phi " << center_.phi() << endl;
00265 cout << "RN " << theRN << endl;
00266
00267 cout << "pos_zplus " << pos_zplus << " "
00268 << pos_zplus.perp() << " " << pos_zplus.phi() << endl
00269 << "pos_zminus " << pos_zminus << " "
00270 << pos_zminus.perp() << " " << pos_zminus.phi() << endl
00271 << "pos_phiplus " << pos_phiplus << " "
00272 << pos_phiplus.perp() << " " << pos_phiplus.phi() <<endl
00273 << "pos_phiminus " << pos_phiminus << " "
00274 << pos_phiminus.perp() << " " << pos_phiminus.phi() <<endl;
00275
00276 cout << "y_phiplus " << y_phiplus << endl;
00277 cout << "y_phiminus " << y_phiminus << endl;
00278
00279 cout << "rot_Z " << surfaces[zplus]->toGlobal(LocalVector(0.,0.,1.)) << endl
00280 << "rot_phi+ " << surfaces[phiplus]->toGlobal(LocalVector(0.,0.,1.))
00281 << " phi " << surfaces[phiplus]->toGlobal(LocalVector(0.,0.,1.)).phi()
00282 << endl
00283 << "rot_phi- " << surfaces[phiminus]->toGlobal(LocalVector(0.,0.,1.))
00284 << " phi " << surfaces[phiminus]->toGlobal(LocalVector(0.,0.,1.)).phi()
00285 << endl;
00286 }
00287
00288
00289 if (MagGeoBuilderFromDDD::debug) {
00290 if (pos_zplus.z() < pos_zminus.z()) {
00291 cout << "*** WARNING: pos_zplus < pos_zminus " << endl;
00292 }
00293 if (Geom::Phi<float>(pos_phiplus.phi()-pos_phiminus.phi()) < 0. ) {
00294 cout << "*** WARNING: pos_phiplus < pos_phiminus " << endl;
00295 }
00296 }
00297 }
00298
00299
00300
00301 bool MagGeoBuilderFromDDD::volumeHandle::sameSurface(const Surface & s1, Sides which_side, float tolerance)
00302 {
00303
00304 if (&s1==(surfaces[which_side]).get()){
00305 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: OK (same ptr)" << endl;
00306 return true;
00307 }
00308
00309
00310
00311
00312 const float maxtilt = 0.999;
00313
00314 const Surface & s2 = *(surfaces[which_side]);
00315
00316 const Plane * p1 = dynamic_cast<const Plane*>(&s1);
00317 if (p1!=0) {
00318 const Plane * p2 = dynamic_cast<const Plane*>(&s2);
00319 if (p2==0) {
00320 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
00321 return false;
00322 }
00323
00324 if ( (fabs(p1->normalVector().dot(p2->normalVector())) > maxtilt)
00325 && (fabs((p1->toLocal(p2->position())).z()) < tolerance) ) {
00326 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: OK "
00327 << fabs(p1->normalVector().dot(p2->normalVector()))
00328 << " " << fabs((p1->toLocal(p2->position())).z()) << endl;
00329 return true;
00330 } else{
00331 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: not the same: "
00332 << p1->normalVector() << p1->position() << endl
00333 << " "
00334 << p2->normalVector() << p2->position() << endl
00335 << fabs(p1->normalVector().dot(p2->normalVector()))
00336 << " " << (p1->toLocal(p2->position())).z()<< endl;
00337 return false;
00338 }
00339 }
00340
00341
00342 const Cylinder * cy1 = dynamic_cast<const Cylinder*>(&s1);
00343 if (cy1!=0) {
00344 const Cylinder * cy2 = dynamic_cast<const Cylinder*>(&s2);
00345 if (cy2==0) {
00346 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
00347 return false;
00348 }
00349
00350 if (fabs(cy1->radius() - cy2->radius()) < tolerance) {
00351 return true;
00352 } else {
00353 return false;
00354 }
00355 }
00356
00357
00358 const Cone * co1 = dynamic_cast<const Cone*>(&s1);
00359 if (co1!=0) {
00360 const Cone * co2 = dynamic_cast<const Cone*>(&s2);
00361 if (co2==0) {
00362 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
00363 return false;
00364 }
00365
00366 if (fabs(co1->openingAngle()-co2->openingAngle()) < maxtilt
00367 && (co1->vertex()-co2->vertex()).mag() < tolerance) {
00368 return true;
00369 } else {
00370 return false;
00371 }
00372 }
00373
00374 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: unknown surfaces..." << endl;
00375 return false;
00376 }
00377
00378
00379
00380 bool MagGeoBuilderFromDDD::volumeHandle::setSurface(const Surface & s1, Sides which_side)
00381 {
00382
00383 if (&s1==(surfaces[which_side]).get()){
00384 isAssigned[which_side] = true;
00385 return true;
00386 }
00387
00388 if (!sameSurface(s1,which_side)){
00389 cout << "***ERROR: setSurface: trying to assign a surface that does not match destination surface. Skipping." << endl;
00390 const Surface & s2 = *(surfaces[which_side]);
00391
00392 const Plane * p1 = dynamic_cast<const Plane*>(&s1);
00393 const Plane * p2 = dynamic_cast<const Plane*>(&s2);
00394 if (p1!=0 && p2 !=0)
00395 cout << p1->normalVector() << p1->position() << endl
00396 << p2->normalVector() << p2->position() << endl;
00397 return false;
00398 }
00399
00400
00401 if (isAssigned[which_side]) {
00402 if (&s1!=(surfaces[which_side]).get()){
00403 cout << "*** WARNING volumeHandle::setSurface: trying to reassign a surface to a different surface instance" << endl;
00404 return false;
00405 }
00406 } else {
00407 surfaces[which_side] = &s1;
00408 isAssigned[which_side] = true;
00409 if (MagGeoBuilderFromDDD::debug) cout << " Volume " << name << " # " << copyno << " Assigned: " << (int) which_side << endl;
00410 return true;
00411 }
00412
00413 return false;
00414 }
00415
00416
00417
00418 const Surface &
00419 MagGeoBuilderFromDDD::volumeHandle::surface(Sides which_side) const {
00420 return *(surfaces[which_side]);
00421 }
00422
00423
00424
00425 const Surface &
00426 MagGeoBuilderFromDDD::volumeHandle::surface(int which_side) const {
00427 assert(which_side >=0 && which_side <6);
00428 return *(surfaces[which_side]);
00429 }
00430
00431
00432 std::vector<VolumeSide>
00433 MagGeoBuilderFromDDD::volumeHandle::sides() const{
00434 std::vector<VolumeSide> result;
00435 for (int i=0; i<6; ++i){
00436
00437
00438 if (expand && (i==phiplus || i==phiminus)) continue;
00439
00440
00441 if (solid.shape() == ddtubs && i == SurfaceOrientation::inner && theRMin < 0.001) continue;
00442
00443 ReferenceCountingPointer<Surface> s = const_cast<Surface*> (surfaces[i].get());
00444 result.push_back(VolumeSide(s, GlobalFace(i),
00445 surfaces[i]->side(center_,0.3)));
00446 }
00447 return result;
00448 }
00449
00450 void MagGeoBuilderFromDDD::volumeHandle::printUniqueNames(handles::const_iterator begin, handles::const_iterator end ) {
00451 std::vector<std::string> names;
00452 for (handles::const_iterator i = begin;
00453 i != end; ++i){
00454 names.push_back((*i)->name);
00455 }
00456
00457 sort(names.begin(),names.end());
00458 std::vector<std::string>::iterator i = unique(names.begin(),names.end());
00459 int nvols = int(i - names.begin());
00460 cout << nvols << " ";
00461 copy(names.begin(), i, ostream_iterator<std::string>(cout, " "));
00462
00463 cout << endl;
00464 }
00465
00466
00467 #include "MagneticField/GeomBuilder/src/buildBox.icc"
00468 #include "MagneticField/GeomBuilder/src/buildTrap.icc"
00469 #include "MagneticField/GeomBuilder/src/buildTubs.icc"
00470 #include "MagneticField/GeomBuilder/src/buildCons.icc"
00471 #include "MagneticField/GeomBuilder/src/buildPseudoTrap.icc"
00472 #include "MagneticField/GeomBuilder/src/buildTruncTubs.icc"