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 } else {
00099 cout << "*** WARNING: volume does not have a SpecPar " << pname << endl;
00100 cout << " DDsvalues_type: " << fv.mergedSpecifics() << endl;
00101 }
00102 }
00103
00104 {
00105 std::vector<double> temp;
00106 const std::string pname = "masterSector";
00107 DDValue val(pname);
00108 if (DDfetch(&sv,val)) {
00109 temp = val.doubles();
00110 if (temp.size() != 1) {
00111 cout << "*** WARNING: volume has > 1 SpecPar " << pname << endl;
00112 }
00113 masterSector = int(temp[0]+.5);
00114 } else {
00115 cout << "*** WARNING: volume does not have a SpecPar " << pname << endl;
00116 cout << " DDsvalues_type: " << fv.mergedSpecifics() << endl;
00117 }
00118 }
00119
00120
00121 if (fv.logicalPart().material().name().name() == "Iron") isIronFlag=true;
00122
00123
00124 if (MagGeoBuilderFromDDD::debug) {
00125 cout << " RMin = " << theRMin <<endl;
00126 cout << " RMax = " << theRMax <<endl;
00127
00128 if (theRMin < 0 || theRN < theRMin || theRMax < theRN)
00129 cout << "*** WARNING: wrong RMin/RN/RMax , shape: " << (int) shape() << endl;
00130
00131 cout << "Summary: " << name << " " << copyno
00132 << " Shape= " << (int) shape()
00133 << " trasl " << center()
00134 << " R " << center().perp()
00135 << " phi " << center().phi()
00136 << " magFile " << magFile
00137 << " Material= " << fv.logicalPart().material().name()
00138 << " isIron= " << isIronFlag
00139 << " masterSector= " << masterSector << std::endl;
00140
00141 cout << " Orientation of surfaces:";
00142 std::string sideName[3] = {"positiveSide", "negativeSide", "onSurface"};
00143 for (int i=0; i<6; ++i) {
00144 cout << " " << i << ":" << sideName[surfaces[i]->side(center_,0.3)];
00145 }
00146 cout << endl;
00147 }
00148 }
00149
00150
00151 const Surface::GlobalPoint & MagGeoBuilderFromDDD::volumeHandle::center() const {
00152 return center_;
00153 }
00154
00155 void MagGeoBuilderFromDDD::volumeHandle::referencePlane(const DDExpandedView &fv){
00156
00157
00158
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 Surface::PositionType & posResult = center_;
00186
00187
00188 DD3Vector x, y, z;
00189 fv.rotation().GetComponents(x,y,z);
00190 if (MagGeoBuilderFromDDD::debug) {
00191 if (x.Cross(y).Dot(z) < 0.5) {
00192 cout << "*** WARNING: Rotation is not RH "<< endl;
00193 }
00194 }
00195
00196
00197 Surface::RotationType
00198 rotResult(float(x.X()),float(x.Y()),float(x.Z()),
00199 float(y.X()),float(y.Y()),float(y.Z()),
00200 float(z.X()),float(z.Y()),float(z.Z()));
00201
00202 refPlane = new GloballyPositioned<float>(posResult, rotResult);
00203
00204
00205 if (MagGeoBuilderFromDDD::debug) {
00206
00207 cout << "Refplane pos " << refPlane->position() << endl;
00208
00209
00210 LocalVector globalZdir(0.,0.,1.);
00211 if (solid.shape() == ddpseudotrap) {
00212 globalZdir = LocalVector(0.,1.,0.);
00213 }
00214 if (refPlane->toGlobal(globalZdir).z()<0.) {
00215 globalZdir=-globalZdir;
00216 }
00217
00218 float chk = refPlane->toGlobal(globalZdir).dot(GlobalVector(0,0,1));
00219 if (chk < .999) cout << "*** WARNING RefPlane check failed!***"
00220 << chk << endl;
00221 }
00222 }
00223
00224
00225
00226 void MagGeoBuilderFromDDD::volumeHandle::buildPhiZSurf(double startPhi,
00227 double deltaPhi,
00228 double zhalf,
00229 double rCentr) {
00230
00231
00232 GlobalVector planeXAxis = refPlane->toGlobal(LocalVector( 1, 0, 0));
00233 GlobalVector planeYAxis = refPlane->toGlobal(LocalVector( 0, 1, 0));
00234 GlobalVector planeZAxis = refPlane->toGlobal(LocalVector( 0, 0, 1));
00235
00236
00237 GlobalVector y_phiplus = refPlane->toGlobal(LocalVector(cos(startPhi+deltaPhi),
00238 sin(startPhi+deltaPhi),0.));
00239 GlobalVector y_phiminus = refPlane->toGlobal(LocalVector(cos(startPhi),
00240 sin(startPhi),0.));
00241
00242 Surface::RotationType rot_Z(planeXAxis,planeYAxis);
00243 Surface::RotationType rot_phiplus(planeZAxis, y_phiplus);
00244 Surface::RotationType rot_phiminus(planeZAxis, y_phiminus);
00245
00246 GlobalPoint pos_zplus(center_.x(),center_.y(),center_.z()+zhalf);
00247 GlobalPoint pos_zminus(center_.x(),center_.y(),center_.z()-zhalf);
00248
00249
00250 GlobalPoint pos_phiplus(refPlane->toGlobal(LocalPoint(rCentr*cos(startPhi+deltaPhi),rCentr*sin(startPhi+deltaPhi),0.)));
00251 GlobalPoint pos_phiminus(refPlane->toGlobal(LocalPoint(rCentr*cos(startPhi),
00252 rCentr*sin(startPhi),
00253 0.)));
00254 surfaces[zplus] = new Plane(pos_zplus, rot_Z);
00255 surfaces[zminus] = new Plane(pos_zminus, rot_Z);
00256 surfaces[phiplus] = new Plane(pos_phiplus, rot_phiplus);
00257 surfaces[phiminus] = new Plane(pos_phiminus, rot_phiminus);
00258
00259 if (MagGeoBuilderFromDDD::debug) {
00260 cout << "Actual Center at: " << center_ << " R " << center_.perp()
00261 << " phi " << center_.phi() << endl;
00262 cout << "RN " << theRN << endl;
00263
00264 cout << "pos_zplus " << pos_zplus << " "
00265 << pos_zplus.perp() << " " << pos_zplus.phi() << endl
00266 << "pos_zminus " << pos_zminus << " "
00267 << pos_zminus.perp() << " " << pos_zminus.phi() << endl
00268 << "pos_phiplus " << pos_phiplus << " "
00269 << pos_phiplus.perp() << " " << pos_phiplus.phi() <<endl
00270 << "pos_phiminus " << pos_phiminus << " "
00271 << pos_phiminus.perp() << " " << pos_phiminus.phi() <<endl;
00272
00273 cout << "y_phiplus " << y_phiplus << endl;
00274 cout << "y_phiminus " << y_phiminus << endl;
00275
00276 cout << "rot_Z " << surfaces[zplus]->toGlobal(LocalVector(0.,0.,1.)) << endl
00277 << "rot_phi+ " << surfaces[phiplus]->toGlobal(LocalVector(0.,0.,1.))
00278 << " phi " << surfaces[phiplus]->toGlobal(LocalVector(0.,0.,1.)).phi()
00279 << endl
00280 << "rot_phi- " << surfaces[phiminus]->toGlobal(LocalVector(0.,0.,1.))
00281 << " phi " << surfaces[phiminus]->toGlobal(LocalVector(0.,0.,1.)).phi()
00282 << endl;
00283 }
00284
00285
00286 if (MagGeoBuilderFromDDD::debug) {
00287 if (pos_zplus.z() < pos_zminus.z()) {
00288 cout << "*** WARNING: pos_zplus < pos_zminus " << endl;
00289 }
00290 if (Geom::Phi<float>(pos_phiplus.phi()-pos_phiminus.phi()) < 0. ) {
00291 cout << "*** WARNING: pos_phiplus < pos_phiminus " << endl;
00292 }
00293 }
00294 }
00295
00296
00297
00298 bool MagGeoBuilderFromDDD::volumeHandle::sameSurface(const Surface & s1, Sides which_side, float tolerance)
00299 {
00300
00301 if (&s1==(surfaces[which_side]).get()){
00302 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: OK (same ptr)" << endl;
00303 return true;
00304 }
00305
00306 const float maxtilt = 0.999;
00307
00308 const Surface & s2 = *(surfaces[which_side]);
00309
00310 const Plane * p1 = dynamic_cast<const Plane*>(&s1);
00311 if (p1!=0) {
00312 const Plane * p2 = dynamic_cast<const Plane*>(&s2);
00313 if (p2==0) {
00314 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
00315 return false;
00316 }
00317
00318 if ( (fabs(p1->normalVector().dot(p2->normalVector())) > maxtilt)
00319 && (fabs((p1->toLocal(p2->position())).z()) < tolerance) ) {
00320 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: OK "
00321 << fabs(p1->normalVector().dot(p2->normalVector()))
00322 << " " << fabs((p1->toLocal(p2->position())).z()) << endl;
00323 return true;
00324 } else{
00325 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: not the same: "
00326 << p1->normalVector() << p1->position() << endl
00327 << " "
00328 << p2->normalVector() << p2->position() << endl
00329 << fabs(p1->normalVector().dot(p2->normalVector()))
00330 << " " << (p1->toLocal(p2->position())).z()<< endl;
00331 return false;
00332 }
00333 }
00334
00335
00336 const Cylinder * cy1 = dynamic_cast<const Cylinder*>(&s1);
00337 if (cy1!=0) {
00338 const Cylinder * cy2 = dynamic_cast<const Cylinder*>(&s2);
00339 if (cy2==0) {
00340 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
00341 return false;
00342 }
00343
00344 if (fabs(cy1->radius() - cy2->radius()) < tolerance) {
00345 return true;
00346 } else {
00347 return false;
00348 }
00349 }
00350
00351
00352 const Cone * co1 = dynamic_cast<const Cone*>(&s1);
00353 if (co1!=0) {
00354 const Cone * co2 = dynamic_cast<const Cone*>(&s2);
00355 if (co2==0) {
00356 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: different types" << endl;
00357 return false;
00358 }
00359
00360 if (fabs(co1->openingAngle()-co2->openingAngle()) < maxtilt
00361 && (co1->vertex()-co2->vertex()).mag() < tolerance) {
00362 return true;
00363 } else {
00364 return false;
00365 }
00366 }
00367
00368 if (MagGeoBuilderFromDDD::debug) cout << " sameSurface: unknown surfaces..." << endl;
00369 return false;
00370 }
00371
00372
00373
00374 bool MagGeoBuilderFromDDD::volumeHandle::setSurface(const Surface & s1, Sides which_side)
00375 {
00376
00377 if (&s1==(surfaces[which_side]).get()){
00378 isAssigned[which_side] = true;
00379 return true;
00380 }
00381
00382 if (!sameSurface(s1,which_side)){
00383 cout << "***ERROR: setSurface: trying to assign a surface that does not match destination surface. Skipping." << endl;
00384 const Surface & s2 = *(surfaces[which_side]);
00385
00386 const Plane * p1 = dynamic_cast<const Plane*>(&s1);
00387 const Plane * p2 = dynamic_cast<const Plane*>(&s2);
00388 if (p1!=0 && p2 !=0)
00389 cout << p1->normalVector() << p1->position() << endl
00390 << p2->normalVector() << p2->position() << endl;
00391 return false;
00392 }
00393
00394
00395 if (isAssigned[which_side]) {
00396 if (&s1!=(surfaces[which_side]).get()){
00397 cout << "*** WARNING volumeHandle::setSurface: trying to reassign a surface to a different surface instance" << endl;
00398 return false;
00399 }
00400 } else {
00401 surfaces[which_side] = &s1;
00402 isAssigned[which_side] = true;
00403 if (MagGeoBuilderFromDDD::debug) cout << " Volume " << name << " # " << copyno << " Assigned: " << (int) which_side << endl;
00404 return true;
00405 }
00406
00407 return false;
00408 }
00409
00410
00411
00412 const Surface &
00413 MagGeoBuilderFromDDD::volumeHandle::surface(Sides which_side) const {
00414 return *(surfaces[which_side]);
00415 }
00416
00417
00418
00419 const Surface &
00420 MagGeoBuilderFromDDD::volumeHandle::surface(int which_side) const {
00421 assert(which_side >=0 && which_side <6);
00422 return *(surfaces[which_side]);
00423 }
00424
00425
00426 std::vector<VolumeSide>
00427 MagGeoBuilderFromDDD::volumeHandle::sides() const{
00428 std::vector<VolumeSide> result;
00429 for (int i=0; i<6; ++i){
00430
00431
00432 if (expand && (i==phiplus || i==phiminus)) continue;
00433
00434
00435 if (solid.shape() == ddtubs && i == SurfaceOrientation::inner && theRMin < 0.001) continue;
00436
00437 ReferenceCountingPointer<Surface> s = const_cast<Surface*> (surfaces[i].get());
00438 result.push_back(VolumeSide(s, GlobalFace(i),
00439 surfaces[i]->side(center_,0.3)));
00440 }
00441 return result;
00442 }
00443
00444 void MagGeoBuilderFromDDD::volumeHandle::printUniqueNames(handles::const_iterator begin, handles::const_iterator end ) {
00445 std::vector<std::string> names;
00446 for (handles::const_iterator i = begin;
00447 i != end; ++i){
00448 names.push_back((*i)->name);
00449 }
00450
00451 sort(names.begin(),names.end());
00452 std::vector<std::string>::iterator i = unique(names.begin(),names.end());
00453 int nvols = int(i - names.begin());
00454 cout << nvols << " ";
00455 copy(names.begin(), i, ostream_iterator<std::string>(cout, " "));
00456
00457 cout << endl;
00458 }
00459
00460
00461 #include "MagneticField/GeomBuilder/src/buildBox.icc"
00462 #include "MagneticField/GeomBuilder/src/buildTrap.icc"
00463 #include "MagneticField/GeomBuilder/src/buildTubs.icc"
00464 #include "MagneticField/GeomBuilder/src/buildCons.icc"
00465 #include "MagneticField/GeomBuilder/src/buildPseudoTrap.icc"
00466 #include "MagneticField/GeomBuilder/src/buildTruncTubs.icc"