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