00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012 #include <iostream>
00013 #include <cassert>
00014 #include <math.h>
00015 #include <set>
00016 using namespace std;
00017
00018 #include <TGeoManager.h>
00019 #include <TGeoMatrix.h>
00020 #include <TGeoNode.h>
00021 #include <TGeoBBox.h>
00022 #include <TGeoArb8.h>
00023 #include <TList.h>
00024 #include <TGeoEltu.h>
00025 #include <TGeoCompositeShape.h>
00026
00027 #include "Conventions/Munits.h"
00028 #include "Conventions/MinosMaterial.h"
00029 #include "Util/UtilString.h"
00030 #include "GeoGeometry/Geo.h"
00031 #include "GeoGeometry/GeoGeometry.h"
00032 #include "GeoGeometry/GeoMediumMap.h"
00033 #include "GeoGeometry/GeoScintPlnVolume.h"
00034 #include "GeoGeometry/GeoSteelPlnVolume.h"
00035 #include "GeoGeometry/GeoStripVolume.h"
00036 #include "GeoGeometry/GeoScintMdlVolume.h"
00037 #include "GeoGeometry/GeoStripNode.h"
00038 #include "GeoGeometry/GeoScintMdlNode.h"
00039 #include "GeoGeometry/GeoScintPlnNode.h"
00040 #include "GeoGeometry/GeoSteelPlnNode.h"
00041 #include "GeoGeometry/GeoMedium.h"
00042 #include "UgliGeometry/UgliDbiTables.h"
00043 #include "UgliGeometry/UgliDbiStructHash.h"
00044 #include "UgliGeometry/UgliLoanPool.h"
00045 #include "MessageService/MsgService.h"
00046 #include "Plex/PlexVetoShieldHack.h"
00047
00048 ClassImp(GeoGeometry)
00049
00050 CVSID("$Id: GeoGeometry.cxx,v 1.98 2009/05/18 14:57:55 kasahara Exp $");
00051
00052
00053 GeoGeometry::GeoGeometry() : fVldRange(),fAppType(Geo::kRecons),
00054 fScale(1),fHallPath(""),fGeoManager(0),fGeoShield(),
00055 fIsSwimMedia(false),fMediumMap(0),fRot45(0),fRot315(0) {
00056
00057
00058 MSG("Geo",Msg::kDebug) << "GeoGeometry def ctor @ " << this << endl;
00059
00060 UpdateGlobalManager();
00061
00062
00063 for ( int ism = 0; ism < 2; ism++ ) {
00064 fSMZMin[ism] = +999.*fScale;
00065 fSMZMax[ism] = -999.*fScale;
00066 }
00067
00068 for ( int ic = 0; ic < 3; ic++ ) {
00069 fHallMin[ic] = 0;
00070 fHallMax[ic] = 0;
00071 }
00072
00073 }
00074
00075
00076 GeoGeometry::GeoGeometry(const VldContext &vldc, Geo::EAppType apptype) :
00077 fVldRange(),fAppType(apptype),fScale(1),fHallPath(""),
00078 fGeoManager(0),fGeoShield(this),fIsSwimMedia(false),fMediumMap(0),
00079 fRot45(0),fRot315(0) {
00080
00081
00082
00083
00084
00085
00086
00087 MSG("Geo",Msg::kDebug) << "GeoGeometry normal ctor @ " << this << endl;
00088
00089 UpdateGlobalManager();
00090
00091 MSG("Geo",Msg::kInfo) << "GeoGeometry build for validity "
00092 << vldc << "." << endl;
00093
00094
00095 Int_t saveErrorIgnoreLevel = gErrorIgnoreLevel;
00096 gErrorIgnoreLevel = kWarning;
00097
00098
00099
00100
00101 fScale = Geo::GetScale(apptype);
00102
00103
00104 for ( int ism = 0; ism < 2; ism++ ) {
00105 fSMZMin[ism] = +999.*fScale;
00106 fSMZMax[ism] = -999.*fScale;
00107 }
00108
00109 fGeoManager = new TGeoManager(vldc.AsString("s1ac-"),"a MINOS geometry");
00110 UpdateGlobalManager();
00111
00112 fMediumMap = new GeoMediumMap(this,vldc);
00113
00114
00115 this -> BuildAll(vldc);
00116
00117 fGeoManager->CloseGeometry();
00118
00119 BuildHallExtent();
00120
00121 TGeoVolume* volume = fGeoManager->GetTopVolume();
00122 UpdateNodeMatrices(volume);
00123
00124 fGeoManager->CdTop();
00125
00126
00127
00128 fGeoManager->SetVisLevel(4);
00129 fGeoManager->SetVisOption(0);
00130
00131 MSG("Geo",Msg::kInfo) << "GeoGeometry build complete." << endl;
00132 gErrorIgnoreLevel = saveErrorIgnoreLevel;
00133
00134 }
00135
00136
00137 GeoGeometry::~GeoGeometry() {
00138
00139
00140 MSG("Geo",Msg::kDebug) << "GeoGeometry dtor @ " << this << endl;
00141
00142 UpdateGlobalManager();
00143
00144 fPlaneMap.clear();
00145 if ( fMediumMap ) delete fMediumMap; fMediumMap = 0;
00146
00147 if ( fGeoManager ) {
00148 delete fGeoManager; fGeoManager = 0;
00149 }
00150
00151 UpdateGlobalManager();
00152
00153 }
00154
00155
00156 void GeoGeometry::Draw(Option_t* volname) {
00157
00158
00159 UpdateGlobalManager();
00160
00161 std::string volnamestr(volname);
00162 if (volnamestr.empty()) volnamestr = "HALL";
00163
00164 MSG("Geo",Msg::kInfo) << "GeoGeometry::Draw() from top volume "
00165 << volnamestr.empty() << "." << endl;
00166
00167 if ( !fGeoManager ) {
00168 MSG("Geo",Msg::kWarning) << "Null fGeoManager" << endl;
00169 return;
00170 }
00171
00172 TGeoVolume* topVol = fGeoManager -> GetVolume(volnamestr.c_str());
00173 if ( !topVol ) {
00174 MSG("Geo",Msg::kWarning) << "No volume of name " << volnamestr.c_str()
00175 << endl;
00176 return;
00177 }
00178
00179 topVol -> SetVisContainers();
00180 topVol -> Draw();
00181
00182 }
00183
00184
00185 void GeoGeometry::DumpVolume(std::string volname, std::string preface) const {
00186
00187
00188 UpdateGlobalManager();
00189
00190 TGeoVolume* volume = fGeoManager->GetVolume(volname.c_str());
00191 if ( !volume ) {
00192 cout << "No volume of name \"" << volname.c_str() << "\"!" << endl;
00193 return;
00194 }
00195
00196 cout << preface.c_str() << "Volume " << volume->GetName() << ", shape:"
00197 << endl;
00198 cout << preface.c_str();
00199 volume->GetShape()->InspectShape();
00200
00201 Int_t ndaughter = volume -> GetNdaughters();
00202 if ( ndaughter > 0 )
00203 cout << preface.c_str() << ndaughter << " daughter nodes:" << endl;
00204 else
00205 cout << preface.c_str() << "No daughter nodes." << endl;
00206
00207 for ( int id = 0; id < ndaughter; id++ ) {
00208 TGeoNode* daughternode = volume->GetNode(id);
00209 cout << preface.c_str() << " " << id << ")" << daughternode->GetName()
00210 << endl;
00211 cout << preface.c_str() << " ";
00212 daughternode->GetMatrix()->Print();
00213 TGeoVolume* daughtervol = daughternode->GetVolume();
00214 this -> DumpVolume(daughtervol->GetName(),preface+" ");
00215 }
00216
00217 }
00218
00219
00220 std::string GeoGeometry::GetGeoCompatibleName(std::string name) {
00221
00222
00223
00224
00225
00226 std::string okayname = name;
00227
00228
00229 unsigned int ipos = okayname.find("/");
00230 while ( ipos != std::string::npos ) {
00231 okayname.replace(ipos,1,"f");
00232 ipos = okayname.find("/");
00233 }
00234
00235
00236
00237 ipos = okayname.find("-");
00238 while ( ipos != std::string::npos ) {
00239 okayname.replace(ipos,1,"h");
00240 ipos = okayname.find("-");
00241 }
00242
00243 return okayname;
00244 }
00245
00246
00247 void GeoGeometry::BuildHallExtent() {
00248
00249
00250
00251 UpdateGlobalManager();
00252
00253 gGeoManager -> cd(fHallPath.c_str());
00254 TGeoNode* hallNode = gGeoManager->GetCurrentNode();
00255 TGeoVolume* hallVol = hallNode->GetVolume();
00256
00257 TGeoBBox* hallBox = dynamic_cast<TGeoBBox*>(hallVol->GetShape());
00258
00259 Double_t lxyz[3] = {-(hallBox->GetDX()),-(hallBox->GetDY()),
00260 -(hallBox->GetDZ())};
00261 Double_t gxyz[3] = {0};
00262
00263 gGeoManager->LocalToMaster(lxyz,gxyz);
00264
00265 for ( int ic = 0; ic < 3; ic++ ) {
00266 lxyz[ic] *= -1.;
00267 fHallMin[ic] = gxyz[ic];
00268 }
00269
00270 gGeoManager->LocalToMaster(lxyz,gxyz);
00271 for ( int ic = 0; ic < 3; ic++ ) fHallMax[ic] = gxyz[ic];
00272
00273 }
00274
00275
00276 GeoSteelPlnNode* GeoGeometry::GetNearestSteelPlnNode(Double_t z) const {
00277
00278
00279 UpdateGlobalManager();
00280
00281 MSG("Geo",Msg::kDebug) << "GeoGeometry::GetNearestSteelPlnNode to z "
00282 << z << "." << endl;
00283 assert(fGeoManager);
00284
00285 const std::map<Float_t,GeoSteelPlnNode*>& stnodemap = GetSteelPlnNodeMap();
00286
00287
00288
00289 std::map<Float_t,GeoSteelPlnNode*>::const_iterator steelplnItr;
00290
00291
00292 steelplnItr = stnodemap.lower_bound(z);
00293 GeoSteelPlnNode* loplnNode = 0;
00294 Double_t loplnz0 = -9999.;
00295 GeoSteelPlnNode* hiplnNode = 0;
00296 Double_t hiplnz0 = -9999.;
00297 if ( steelplnItr != stnodemap.end() ) {
00298 hiplnNode = steelplnItr->second;
00299 hiplnz0 = steelplnItr->first;
00300 }
00301 if ( steelplnItr != stnodemap.begin() ) {
00302 steelplnItr--;
00303 loplnNode = steelplnItr->second;
00304 loplnz0 = steelplnItr->first;
00305 }
00306 if ( hiplnNode == 0 ) return loplnNode;
00307 else if ( loplnNode == 0 ) return hiplnNode;
00308
00309
00310
00311
00312 return ( TMath::Abs(z-loplnz0) < TMath::Abs(z-hiplnz0) ) ? loplnNode : hiplnNode;
00313
00314
00315 }
00316
00317
00318 PlexPlaneId GeoGeometry::GetPlaneIdFromZ(Double_t z) const {
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 UpdateGlobalManager();
00330
00331 MSG("Geo",Msg::kDebug) << "GeoGeometry::GetPlaneIdFromZ " << z << "."<< endl;
00332 assert(fGeoManager);
00333
00334 PlexPlaneId defplex;
00335
00336 PlaneMapConstItr plnItr;
00337
00338 Double_t xyz_global[3] = {0,0,z};
00339 Double_t xyz_local[3] = {0};
00340
00341
00342 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr) {
00343 if ( (plnItr->first).IsVetoShield() ) continue;
00344 GeoPlnNode* plnNode = dynamic_cast<GeoPlnNode*>(plnItr -> second);
00345 plnNode->GlobalToLocal(xyz_global,xyz_local);
00346 Float_t dz = dynamic_cast<TGeoBBox*>(plnNode->GetVolume()->GetShape())
00347 ->GetDZ();
00348 if ( xyz_local[2] < dz ) {
00349 return plnItr->first;
00350 }
00351 defplex = plnItr->first;
00352 }
00353
00354 return defplex;
00355
00356 }
00357
00358
00359 const vector<GeoPlnNode*>& GeoGeometry::GetPlnNodePtrVector() const {
00360
00361
00362 MSG("Geo",Msg::kDebug) << "GetPlnNodePtrVector" << endl;
00363
00364 UpdateGlobalManager();
00365
00366 if ( fPlnNodes.empty() ) {
00367 PlaneMapConstItr plnItr;
00368 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr) {
00369 GeoPlnNode* plnNode = plnItr->second;
00370 fPlnNodes.push_back(plnNode);
00371 }
00372 }
00373
00374 return fPlnNodes;
00375
00376 }
00377
00378
00379 GeoScintPlnNode* GeoGeometry::GetScintPlnNode(PlexPlaneId planeid) const {
00380
00381
00382 MSG("Geo",Msg::kDebug) << "GetScintPlnNode for plane " << planeid.AsString()
00383 << endl;
00384
00385 UpdateGlobalManager();
00386
00387 GeoScintPlnNode* plnnode = 0;
00388 if ( planeid.IsSteel() ) {
00389 MSG("Geo",Msg::kWarning)
00390 << "GetScintPlnNode called with steel plane id "
00391 << planeid.AsString() << endl;
00392 return 0;
00393 }
00394
00395 PlaneMapConstItr citr = fPlaneMap.find(planeid);
00396 if ( citr != fPlaneMap.end() ) {
00397 plnnode = dynamic_cast<GeoScintPlnNode*>(citr->second);
00398 }
00399
00400 return plnnode;
00401
00402 }
00403
00404
00405 const vector<GeoScintPlnNode*>& GeoGeometry::GetScintPlnNodePtrVector() const {
00406
00407
00408 MSG("Geo",Msg::kDebug) << "GetScintPlnNodePtrVector" << endl;
00409
00410 UpdateGlobalManager();
00411
00412 if ( fScintPlnNodes.empty() ) {
00413 PlaneMapConstItr plnItr;
00414 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr ){
00415 if ( !(plnItr->first).IsSteel() ) {
00416 fScintPlnNodes.push_back(
00417 dynamic_cast<GeoScintPlnNode*>(plnItr->second));
00418 }
00419 }
00420 }
00421
00422 return fScintPlnNodes;
00423
00424 }
00425
00426
00427 GeoSteelPlnNode* GeoGeometry::GetSteelPlnNode(PlexPlaneId planeid) const {
00428
00429
00430 MSG("Geo",Msg::kDebug) << "GetSteelPlnNode for plane " << planeid.AsString()
00431 << endl;
00432
00433 UpdateGlobalManager();
00434
00435 GeoSteelPlnNode* plnnode = 0;
00436 if ( !planeid.IsSteel() ) {
00437 MSG("Geo",Msg::kWarning)
00438 << "GetSteelPlnNode called with non steel plane id "
00439 << planeid.AsString() << endl;
00440 return 0;
00441 }
00442
00443 PlaneMapConstItr citr = fPlaneMap.find(planeid);
00444 if ( citr != fPlaneMap.end() ) {
00445 plnnode = dynamic_cast<GeoSteelPlnNode*>(citr->second);
00446 }
00447
00448 return plnnode;
00449
00450 }
00451
00452
00453 const vector<GeoSteelPlnNode*>& GeoGeometry::GetSteelPlnNodePtrVector() const {
00454
00455
00456
00457 MSG("Geo",Msg::kDebug) << "GetSteelPlnNodePtrVector" << endl;
00458
00459 UpdateGlobalManager();
00460
00461 if ( fSteelPlnNodes.empty() ) {
00462 PlaneMapConstItr plnItr;
00463 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr ){
00464 if ( (plnItr->first).IsSteel() ) {
00465 fSteelPlnNodes.push_back(
00466 dynamic_cast<GeoSteelPlnNode*>(plnItr->second));
00467 }
00468 }
00469 }
00470
00471 return fSteelPlnNodes;
00472
00473 }
00474
00475
00476 const std::map<Float_t,GeoSteelPlnNode*>& GeoGeometry::GetSteelPlnNodeMap()
00477 const {
00478
00479
00480
00481 MSG("Geo",Msg::kDebug) << "GetSteelPlnNodeMap" << endl;
00482
00483 UpdateGlobalManager();
00484
00485 if ( fSteelPlnNodeMap.empty() ) {
00486 PlaneMapConstItr plnItr;
00487 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); plnItr++ ){
00488 if ( (plnItr->first).IsSteel() && !(plnItr->first).IsVetoShield()) {
00489 fSteelPlnNodeMap.insert(make_pair(plnItr->second->GetZ0(),
00490 dynamic_cast<GeoSteelPlnNode*>(plnItr->second)));
00491 }
00492 }
00493 }
00494
00495 return fSteelPlnNodeMap;
00496
00497 }
00498
00499
00500 GeoStripNode* GeoGeometry::GetStripNode(const PlexStripEndId& seid) const {
00501
00502
00503 MSG("Geo",Msg::kDebug) << "GetStripNode for strip " << seid.AsString()
00504 << endl;
00505
00506 UpdateGlobalManager();
00507
00508 GeoStripNode* stripnode = 0;
00509
00510
00511 GeoScintPlnNode* planenode = this -> GetScintPlnNode(seid);
00512 if ( planenode ) {
00513 stripnode = planenode -> GetStripNode(seid);
00514 }
00515
00516 return stripnode;
00517
00518 }
00519
00520
00521 void GeoGeometry::GetTransverseExtent(PlaneView::PlaneView_t view,
00522 Double_t& tmin, Double_t& tmax) const {
00523
00524
00525
00526
00527 MSG("Geo",Msg::kDebug) << "GetTransverseExtent for view "
00528 << PlaneView::AsString(view) << endl;
00529
00530 UpdateGlobalManager();
00531
00532 tmin = -999; tmax=-999;
00533
00534 Detector::Detector_t detector
00535 = (Detector::Detector_t)fVldRange.GetDetectorMask();
00536
00537 switch (detector) {
00538 case Detector::kNear:
00539 switch (view ) {
00540 case PlaneView::kU:
00541 tmin = -2.10 * fScale;
00542 tmax = +2.75 * fScale;
00543 break;
00544 case PlaneView::kV:
00545 tmin = -2.75 * fScale;
00546 tmax = +2.10 * fScale;
00547 break;
00548 default:
00549 MSG("Geo",Msg::kError)
00550 << "GeoGeometry::GetTransverseExtent undefined for "
00551 << Detector::AsString(detector) << " view "
00552 << PlaneView::AsString(view) << endl;
00553 break;
00554 }
00555 case Detector::kFar:
00556 tmin = -4.0 * fScale;
00557 tmax = +4.0 * fScale;
00558 break;
00559 case Detector::kCalib:
00560 tmin = -0.5 * fScale;
00561 tmax = +0.5 * fScale;
00562 break;
00563 default:
00564 MSG("Geo",Msg::kError)
00565 << "GeoGeometry::GetTransverseExtent undefined for "
00566 << Detector::AsString(detector) << endl;
00567 break;
00568 }
00569
00570 Float_t fuzz = 0.5*Geo::kStripWidth*fScale;
00571 tmin = tmin - fuzz;
00572 tmax = tmax + fuzz;
00573
00574 return;
00575
00576 }
00577
00578
00579 void GeoGeometry::GetTransverseExtent(PlaneView::PlaneView_t view,
00580 Float_t& tmin, Float_t& tmax) const {
00581
00582
00583
00584 UpdateGlobalManager();
00585
00586 Double_t tmind,tmaxd;
00587 GetTransverseExtent(view,tmind,tmaxd);
00588 tmin = (Float_t)tmind;
00589 tmax = (Float_t)tmaxd;
00590
00591 return;
00592
00593 }
00594
00595
00596 void GeoGeometry::GetZExtent(Double_t& zmin, Double_t& zmax, Int_t isup) const{
00597
00598
00599
00600 MSG("Geo",Msg::kDebug) << "GetZExtent for isup " << isup << endl;
00601
00602 UpdateGlobalManager();
00603
00604
00605 zmax =-999999;
00606 zmin =+999999;
00607 if ( isup < 0 ) {
00608 zmin = fSMZMin[0];
00609 if ( fSMZMax[1] > 0 ) zmax = fSMZMax[1];
00610 else zmax = fSMZMax[0];
00611 }
00612 else if ( isup < 2 ) {
00613 zmin = fSMZMin[isup];
00614 zmax = fSMZMax[isup];
00615 }
00616 else {
00617 MSG("Geo",Msg::kWarning) << "GetZExtent failed. SuperModule "
00618 << isup << " undefined." << endl;
00619 }
00620
00621 return;
00622
00623
00624 }
00625
00626
00627 void GeoGeometry::GetZExtent(Float_t& zmin, Float_t& zmax, Int_t isup) const {
00628
00629
00630
00631 UpdateGlobalManager();
00632
00633 Double_t zmind,zmaxd;
00634 GetZExtent(zmind,zmaxd,isup);
00635 zmin = (Float_t)zmind;
00636 zmax = (Float_t)zmaxd;
00637
00638 return;
00639 }
00640
00641
00642 TGeoMedium* GeoGeometry::GetMedium(const char* name) const {
00643
00644
00645
00646
00647
00648
00649
00650 UpdateGlobalManager();
00651
00652 TGeoMedium* medium = fGeoManager->GetMedium(name);
00653 if ( !medium && !(fGeoManager->IsClosed()) ) {
00654 MSG("Geo",Msg::kFatal) << "GeoGeometry::GetMedium did not find medium\n"
00655 << name << " during geometry build stage. Abort."
00656 << endl;
00657 abort();
00658 }
00659
00660 return medium;
00661
00662 }
00663
00664
00665 bool GeoGeometry::IsCompatible(const VldContext& vldc,
00666 Geo::EAppType apptype) const {
00667
00668
00669 UpdateGlobalManager();
00670
00671 bool iscompatible = false;
00672 if ( fVldRange.IsCompatible(vldc) && fAppType == apptype )
00673 iscompatible = true;
00674 return iscompatible;
00675 }
00676
00677
00678 void GeoGeometry::ls(Option_t* option) const {
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 UpdateGlobalManager();
00693 PrintHeader();
00694
00695 TString opt = option;
00696 bool isAll = false;
00697 if ( opt.Contains("a") ) isAll = true;
00698
00699 if (opt.Contains("m")) {
00700
00701 fGeoManager->GetListOfMaterials()->Print();
00702 }
00703 if (opt.Contains("M")) {
00704
00705 GeoMedium::PrintHeader();
00706 TIter medItr(fGeoManager->GetListOfMedia());
00707 GeoMedium* medium = 0;
00708 while ( ( medium = dynamic_cast<GeoMedium*>(medItr()) ) ) {
00709 if ( !isAll ) {
00710 std::string medName = medium->GetName();
00711 if ( medName.find("_SWIM") != std::string::npos ) continue;
00712 }
00713 medium -> Print();
00714 }
00715 }
00716 if (opt.Contains("d")) {
00717
00718
00719 GetMediumMap().Print();
00720 }
00721 if (opt.Contains("v")) {
00722
00723 TIter volItr(fGeoManager->GetListOfUVolumes());
00724 TGeoVolume* volume = 0;
00725 while ( ( volume = dynamic_cast<TGeoVolume*>(volItr()) ) ) {
00726 cout << setiosflags(ios::left) << setw(30) << volume->GetName()
00727 << setw(30) << volume->GetMedium()->GetName()
00728 << endl;
00729 }
00730 }
00731
00732 }
00733
00734
00735 void GeoGeometry::Print(Option_t* option) const {
00736
00737
00738 UpdateGlobalManager();
00739
00740 std::string stoption(option);
00741 if (stoption != "") DumpVolume(stoption);
00742 PrintHeader();
00743
00744 }
00745
00746
00747 void GeoGeometry::PrintHeader(Option_t* ) const {
00748
00749
00750 cout << "GeoGeometry " << fGeoManager->GetName() << " "
00751 << fGeoManager->GetTitle() << endl;
00752 cout << "Has " << CountRef() << " reference" << ((CountRef()==1)?"":"s")
00753 << " VldRange:" << fVldRange.AsString("acs-") << endl;
00754
00755 }
00756
00757
00758 void GeoGeometry::SwitchMedia(bool toswim) {
00759
00760
00761
00762
00763
00764 Int_t ntoadd = 0;
00765 Int_t nmedia = fGeoManager->GetListOfMedia()->GetSize();
00766 if ( toswim ) {
00767 if ( fIsSwimMedia ) return;
00768 ntoadd = nmedia/2 - 1;
00769 }
00770 else {
00771 if ( !fIsSwimMedia ) return;
00772 ntoadd = -nmedia/2 - 1;
00773 }
00774
00775 TIter nextvol(fGeoManager->GetListOfVolumes());
00776 TGeoVolume* vol = 0;
00777 while ( ( vol = (TGeoVolume*)nextvol() ) ) {
00778 TGeoMedium* currentMed = vol -> GetMedium();
00779 Int_t twinMedId = currentMed->GetId() + ntoadd;
00780 TGeoMedium* twinMed = (TGeoMedium*)
00781 (fGeoManager->GetListOfMedia()->At(twinMedId));
00782 vol -> SetMedium(twinMed);
00783 }
00784
00785 fIsSwimMedia = toswim;
00786
00787 }
00788
00789
00790 void GeoGeometry::BuildAll(const VldContext &vldc) {
00791
00792
00793 UpdateGlobalManager();
00794
00795 MSG("Geo",Msg::kDebug) << "GeoGeometry BuildAll " << endl;
00796 assert(fGeoManager);
00797
00798
00799 BuildVldRange(vldc);
00800
00801
00802 BuildRotations();
00803
00804
00805 BuildGeometry(vldc);
00806
00807 }
00808
00809
00810 void GeoGeometry::BuildVldRange(const VldContext &vldc) {
00811
00812
00813 UpdateGlobalManager();
00814
00815 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildVldRange for VldContext "
00816 << vldc << endl;
00817
00818 Detector::Detector_t det = vldc.GetDetector();
00819 bool isunknown = (Detector::kUnknown == det);
00820 const char* src = "DBI";
00821 Int_t detmask = Detector::FullMask();
00822 Int_t simmask = SimFlag::FullMask();
00823 if ( isunknown ) {
00824 src = "Fake (unknown detector)";
00825 detmask = det;
00826 simmask = vldc.GetSimFlag();
00827 }
00828
00829
00830 VldTimeStamp starttime = VldTimeStamp::GetBOT();
00831 VldTimeStamp endtime = VldTimeStamp::GetEOT();
00832 fVldRange = VldRange(detmask,simmask,starttime,endtime,src);
00833
00834
00835 if (isunknown) return;
00836
00837 DbiResultPtr<UgliDbiSteelPln> steelTbl(vldc);
00838 TrimVldRange("UgliDbiSteelPln",steelTbl.GetValidityRec());
00839
00840 DbiResultPtr<UgliDbiScintPlnStruct> scintStructTbl(vldc);
00841 TrimVldRange("UgliDbiScintPlnStruct",scintStructTbl.GetValidityRec());
00842
00843 DbiResultPtr<UgliDbiScintPln> scintTbl(vldc);
00844 TrimVldRange("UgliDbiScintPln",scintTbl.GetValidityRec());
00845
00846 DbiResultPtr<UgliDbiScintMdlStruct> mdlStructTbl(vldc);
00847 TrimVldRange("UgliDbiScintMdlStruct",mdlStructTbl.GetValidityRec());
00848
00849 DbiResultPtr<UgliDbiScintMdl> mdlTbl(vldc);
00850 TrimVldRange("UgliDbiScintMdl",mdlTbl.GetValidityRec());
00851
00852 DbiResultPtr<UgliDbiStripStruct> stripStructTbl(vldc);
00853 TrimVldRange("UgliDbiStripStruct",stripStructTbl.GetValidityRec());
00854
00855 DbiResultPtr<UgliDbiStrip> stripTbl(vldc);
00856 TrimVldRange("UgliDbiStrip",stripTbl.GetValidityRec());
00857
00858 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildVldRange built VldRange "
00859 << fVldRange << endl;
00860
00861 }
00862
00863
00864 void GeoGeometry::TrimVldRange(const char* tblName,
00865 const DbiValidityRec* dbivrec) {
00866
00867
00868 UpdateGlobalManager();
00869
00870 if ( dbivrec ) {
00871 fVldRange.TrimTo(dbivrec->GetVldRange());
00872 }
00873 else {
00874 MSG("Geo",Msg::kWarning) << "No DbiValidityRec for table " << tblName
00875 << endl;
00876 }
00877
00878 }
00879
00880
00881 void GeoGeometry::BuildRotations() {
00882
00883
00884
00885 fRot45 = new TGeoRotation("rot45",90,45,90,135,0,0);
00886 fRot45 -> RegisterYourself();
00887
00888
00889
00890 fRot315 = new TGeoRotation("rot315",90,315,90,45,0,0);
00891 fRot315 -> RegisterYourself();
00892
00893 }
00894
00895
00896
00897 void GeoGeometry::BuildGeometry(const VldContext& vldc) {
00898
00899
00900 UpdateGlobalManager();
00901
00902 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildGeometry" << endl;
00903 assert(fGeoManager);
00904
00905 const GeoMediumMap& medMap = GetMediumMap();
00906
00907 if (vldc.GetDetector() == Detector::kUnknown) {
00908
00909 TGeoVolume* volMARS = fGeoManager -> MakeBox("MARS",
00910 medMap.GetMedium(Geo::kMars),1.2,1.2,1.2);
00911 TGeoVolume* volLINR = fGeoManager -> MakeBox("LINR",
00912 medMap.GetMedium(Geo::kLinr),1.1,1.1,1.1);
00913 volMARS -> AddNode(volLINR,1,gGeoIdentity);
00914 TGeoVolume* volHALL = fGeoManager -> MakeBox("HALL",
00915 medMap.GetMedium(Geo::kHall),1.0,1.0,1.0);
00916 volLINR -> AddNode(volHALL,1,gGeoIdentity);
00917 fGeoManager -> SetTopVolume(volMARS);
00918 return;
00919 }
00920
00921 const UgliDbiTables& ugliDbiTables = UgliDbiTables(vldc);
00922 const UgliDbiGeometry* ugliDbiGeo = ugliDbiTables.GetDbiGeometry();
00923 if (!ugliDbiGeo) {
00924 MSG("Geo",Msg::kFatal)
00925 << "No UgliDbiGeometry for " << vldc << endl;
00926 abort();
00927 }
00928
00929
00930 const Float_t* hmin = ugliDbiGeo->GetHallXYZMin();
00931 const Float_t* hmax = ugliDbiGeo->GetHallXYZMax();
00932
00933 TGeoVolume* volHALL = 0;
00934 Double_t hminsc[3] = {0};
00935 Double_t hmaxsc[3] = {0};
00936
00937 bool useNewCavern = UgliLoanPool::Instance()->GetUseNewCavern();
00938 if ( useNewCavern && vldc.GetDetector() == Detector::kFar ) {
00939
00940
00941
00942
00943
00944 Double_t dx[3] = {0};
00945 Double_t dz[3] = {0};
00946 std::string region[3] = {"S","M","N"};
00947
00948
00949 dx[0] = 6.9088*fScale;
00950 dz[0] = 5.461*fScale;
00951
00952
00953 dx[1] = 7.2136*fScale;
00954 dz[1] =15.0114*fScale;
00955
00956
00957 dx[2] = 7.9248*fScale;
00958
00959
00960
00961
00962 dz[2] = 20.9176*fScale;
00963
00964
00965 Double_t dzOffset = -13.6*fScale;
00966 Double_t dzHall = dz[0] + dz[1] + dz[2];
00967
00968
00969
00970 Double_t dyArch = 2.04*fScale;
00971 Double_t dyBox = 5.79*fScale;
00972 Double_t dyHall
00973 = (dyBox*2+dyArch)/2.;
00974 Double_t dyOffset = -5.88*fScale;
00975
00976 hminsc[0] = -dx[2]-(dx[2]-dx[1]);
00977 hmaxsc[0] = +dx[2]-(dx[2]-dx[1]);
00978 hminsc[1] = dyOffset;
00979 hmaxsc[1] = 2.*dyHall+hminsc[1];
00980 hminsc[2] = dzOffset;
00981 hmaxsc[2] = 2.*dzHall+hminsc[2];
00982
00983
00984
00985
00986 TGeoTranslation* trArch=new TGeoTranslation("cavArch",0.,dyHall-dyArch,0.);
00987 trArch -> RegisterYourself();
00988 TGeoTranslation* trBox=new TGeoTranslation("cavBox",0.,-dyHall+dyBox,0.);
00989 trBox -> RegisterYourself();
00990
00991 std::string secName[3];
00992 Double_t epsil = 1.e-4;
00993 for ( int iz = 0; iz < 3; iz++ ) {
00994 std::string archName = "cavArch"+region[iz];
00995 new TGeoEltu(archName.c_str(),dx[iz],dyArch,dz[iz]+epsil);
00996 std::string boxName = "cavBox"+region[iz];
00997 new TGeoBBox(boxName.c_str(),dx[iz],dyBox+epsil,dz[iz]+epsil);
00998 std::string composite = boxName + ":cavBox+" + archName + ":cavArch";
00999 secName[iz] = "hall" + region[iz];
01000 new TGeoCompositeShape(secName[iz].c_str(),composite.c_str());
01001 Double_t dzrel = 0;
01002 for ( int izz = 0; izz < iz; izz++ ) dzrel += 2.*dz[izz];
01003 TGeoTranslation* offset = new TGeoTranslation(secName[iz].c_str(),
01004 dx[2]-dx[iz],0.,-dzHall + dzrel + dz[iz]);
01005 offset -> RegisterYourself();
01006 }
01007
01008
01009 std::string composite = secName[0] + ":" + secName[0] + "+"
01010 + secName[1] + ":" + secName[1] + "+"
01011 + secName[2] + ":" + secName[2];
01012
01013 TGeoCompositeShape* hallShp = new TGeoCompositeShape("HALL",
01014 composite.c_str());
01015 volHALL
01016 = new TGeoVolume("HALL",hallShp,medMap.GetMedium(Geo::kHall));
01017
01018 volHALL -> SetLineColor(42);
01019
01020 }
01021 else {
01022
01023
01024
01025 Double_t xpad = 0.*fScale;
01026
01027
01028 Double_t ypad = 0.*fScale;
01029 if ( vldc.GetDetector() == Detector::kNear ) ypad = 0.01*fScale;
01030
01031 hminsc[0] = hmin[0]*fScale-xpad;
01032 hminsc[1] = hmin[1]*fScale-ypad;
01033 hminsc[2] = hmin[2]*fScale;
01034 hmaxsc[0] = hmax[0]*fScale+xpad;
01035 hmaxsc[1] = hmax[1]*fScale+ypad;
01036 hmaxsc[2] = hmax[2]*fScale;
01037
01038
01039 volHALL = fGeoManager->MakeBox("HALL",
01040 medMap.GetMedium(Geo::kHall),
01041 0.5*(hmaxsc[0]-hminsc[0]),
01042 0.5*(hmaxsc[1]-hminsc[1]),
01043 0.5*(hmaxsc[2]-hminsc[2]));
01044
01045 volHALL-> SetVisibility(kTRUE);
01046 volHALL-> SetVisContainers(kTRUE);
01047 volHALL-> SetLineColor(42);
01048 }
01049
01050
01051 Double_t xhsiz = 0.5*(hmaxsc[0] - hminsc[0]);
01052 Double_t yhsiz = 0.5*(hmaxsc[1] - hminsc[1]);
01053 Double_t zhsiz = 0.5*(hmaxsc[2] - hminsc[2]);
01054
01055
01056 Double_t x0hall = 0.5*(hmaxsc[0] + hminsc[0]);
01057 Double_t y0hall = 0.5*(hmaxsc[1] + hminsc[1]);
01058 Double_t z0hall = 0.5*(hmaxsc[2] + hminsc[2]);
01059
01060 MSG("Geo",Msg::kDebug) << "Hall halfwidths " << xhsiz << ","
01061 << yhsiz << "," << zhsiz << " placed at "
01062 << x0hall << "," << y0hall << "," << z0hall << endl;
01063
01064
01065
01066 Detector::Detector_t dettype = (Detector::Detector_t)vldc.GetDetector();
01067 const Double_t linerpad = 1.0*fScale;
01068
01069 TGeoVolume* volLINR = fGeoManager->MakeBox("LINR",
01070 medMap.GetMedium(Geo::kLinr),
01071 xhsiz+linerpad,yhsiz+linerpad,
01072 zhsiz+linerpad);
01073 volLINR-> SetVisibility(kTRUE);
01074 volLINR-> SetVisContainers(kTRUE);
01075 volLINR-> SetLineColor(kYellow);
01076
01077
01078 TGeoVolume* volMARS = 0;
01079 switch ( dettype ) {
01080 case Detector::kFar:
01081 volMARS = BuildFarMARS();
01082 break;
01083 case Detector::kNear:
01084 volMARS = BuildNearMARS();
01085 break;
01086 default:
01087
01088
01089 const Double_t rockpad = 5.0*fScale;
01090 Double_t absxmax = TMath::Max(TMath::Abs(hminsc[0]),
01091 TMath::Abs(hmaxsc[0]));
01092 Double_t absymax = TMath::Max(TMath::Abs(hminsc[1]),
01093 TMath::Abs(hmaxsc[1]));
01094 Double_t abszmax = TMath::Max(TMath::Abs(hminsc[2]),
01095 TMath::Abs(hmaxsc[2]));
01096 volMARS = fGeoManager->MakeBox("MARS",medMap.GetMedium(Geo::kMars),
01097 absxmax+rockpad,
01098 absymax+rockpad,abszmax+rockpad);
01099 break;
01100 }
01101
01102 volMARS -> SetVisibility(kTRUE);
01103 volMARS -> SetVisContainers(kTRUE);
01104 volMARS -> SetLineColor(kBlack);
01105
01106
01107 fGeoManager -> SetTopVolume(volMARS);
01108
01109 std::string nodename = "LINR_1";
01110 std::string globalpath = "/MARS_1/" + nodename;
01111 volMARS -> AddNode(volLINR,1,
01112 new TGeoTranslation("LINR",x0hall,y0hall,z0hall));
01113
01114 nodename = "HALL_1";
01115 globalpath += "/" + nodename;
01116 fHallPath = globalpath;
01117 volLINR -> AddNode(volHALL,1,gGeoIdentity);
01118
01119 if ( useNewCavern && vldc.GetDetector() == Detector::kFar ) {
01120 BuildFarLeadStacks(volHALL);
01121 }
01122
01123 BuildDetector(vldc,volHALL);
01124
01125 }
01126
01127
01128 void GeoGeometry::BuildDetector(const VldContext& vldc,
01129 TGeoVolume* hallVol) {
01130
01131
01132 UpdateGlobalManager();
01133
01134 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildDetector " << endl;
01135 assert(fGeoManager);
01136
01137 DbiResultPtr<UgliDbiSteelPln> steelTbl(vldc);
01138
01139 BuildPlanePairVolumes(vldc);
01140
01141
01142
01143 bool shieldOff = UgliLoanPool::Instance()->GetShieldOff();
01144 if ( vldc.GetDetector() == Detector::kFar ) {
01145 if ( shieldOff ) {
01146 MSG("Geo",Msg::kInfo)
01147 << "GeoGeometry build of Veto Shield disabled." << endl;
01148 }
01149 else fGeoShield.BuildGroupNodes(hallVol);
01150 }
01151
01152
01153
01154
01155
01156 TGeoNode* linrNode = fGeoManager->GetVolume("MARS")->GetNode("LINR_1");
01157 const Double_t* h0 = linrNode -> GetMatrix() -> GetTranslation();
01158
01159 Int_t plnMin[2] = {-1};
01160 Int_t plnMax[2] = {-1};
01161 Int_t nSM = GetSMPlaneLimits(vldc,plnMin,plnMax);
01162
01163 std::string minPlaneName[2];
01164 std::string maxPlaneName[2];
01165 Int_t minPlane[2] = {9999,9999};
01166 Int_t maxPlane[2] = {-9999,-9999};
01167
01168
01169 std::set<PlexPlaneId> steelset;
01170 for (unsigned int irow=0; irow < steelTbl.GetNumRows(); ++irow) {
01171 const UgliDbiSteelPln* stRow = steelTbl.GetRow(irow);
01172 PlexPlaneId steelId = stRow -> GetPlaneId();
01173 steelset.insert(steelId);
01174 }
01175
01176 std::set<PlexPlaneId>::const_iterator steelitr = steelset.begin();
01177 for ( ; steelitr != steelset.end() ; steelitr++) {
01178 PlexPlaneId steelId = *steelitr;
01179 if ( shieldOff && steelId.IsVetoShield() ) continue;
01180 const UgliDbiSteelPln* stRow = steelTbl.GetRowByIndex(steelId.GetPlane());
01181 if ( (vldc.GetDetector() == Detector::kFar && !steelId.IsVetoShield()) ) {
01182
01183 if ( steelId.GetPlane() > 485 ) continue;
01184
01185
01186 if ( TMath::Abs(stRow->GetX0() ) > 50. ) continue;
01187 }
01188
01189
01190 Int_t vsId = 0;
01191 std::string stName = GetGeoCompatibleName(steelId.AsString());
01192 if ( steelId.IsVetoShield() ) vsId = 1;
01193 if ( steelId.GetPlane() < minPlane[vsId] ) {
01194 minPlane[vsId] = steelId.GetPlane();
01195 minPlaneName[vsId] = stName;
01196 }
01197 if ( steelId.GetPlane() > maxPlane[vsId] ) {
01198 maxPlane[vsId] = steelId.GetPlane();
01199 maxPlaneName[vsId] = stName;
01200 }
01201
01202
01203 if ( vldc.GetDetector() == Detector::kFar && steelId.IsVetoShield() )
01204 continue;
01205
01206 Double_t offxyz[3] = {h0[0],h0[1],h0[2]};
01207
01208
01209 std::string pairName = GetGeoCompatibleName(steelId.AsString("b"));
01210 TGeoVolume* pairVol = fGeoManager -> GetVolume(pairName.c_str());
01211 if ( !pairVol ) {
01212 MSG("Geo",Msg::kFatal)
01213 << "Unable to find pre-built pairvol for volume "
01214 << pairName.c_str() << endl;
01215 abort();
01216 }
01217
01218
01219 TGeoRotation* stRotMatrix = new TGeoRotation(pairName.c_str(),
01220 stRow->GetThetaDeg(0),stRow->GetPhiDeg(0),
01221 stRow->GetThetaDeg(1),stRow->GetPhiDeg(1),
01222 stRow->GetThetaDeg(2),stRow->GetPhiDeg(2));
01223 stRotMatrix -> RegisterYourself();
01224
01225
01226 Float_t x0pair = (stRow->GetX0())*fScale - offxyz[0];
01227 Float_t y0pair = (stRow->GetY0())*fScale - offxyz[1];
01228
01229
01230
01231
01232
01233
01234
01235 Int_t planeno = steelId.GetPlane();
01236 Float_t z0pair = 0;
01237 if ( vldc.GetDetector() == Detector::kCalDet || steelId.IsVetoShield() )
01238 z0pair =(stRow->GetZBack()-0.5*(stRow->GetTotalZ()))*fScale - offxyz[2];
01239 else
01240 z0pair =(stRow->GetZBack()-0.5*(stRow->GetThickness()))*fScale-offxyz[2];
01241
01242 if ( !steelId.IsVetoShield() ) {
01243 if ( planeno != plnMin[0] ) {
01244 if ( nSM == 1 || (nSM > 1 && planeno != plnMin[1]) ) {
01245 const UgliDbiSteelPln* stPrevRow = steelTbl.GetRowByIndex(planeno-1);
01246 z0pair = (stRow->GetZBack()-0.5*(stRow->GetZBack()
01247 -stPrevRow->GetZBack()))*fScale - offxyz[2];
01248 }
01249 }
01250 }
01251
01252 TGeoCombiTrans* pairMatrix = new TGeoCombiTrans(pairName.c_str(),
01253 x0pair,y0pair,z0pair,stRotMatrix);
01254 MSG("Geo",Msg::kDebug) << "Placing plane pair " << pairName.c_str()
01255 << " at " << x0pair << ","
01256 << y0pair << "," << z0pair
01257 << "\n rotmatrix:(thetax/y/z,phix/y/z) ("
01258 << stRow->GetThetaDeg(0) << ","
01259 << stRow->GetPhiDeg(0) << "),("
01260 << stRow->GetThetaDeg(1) << ","
01261 << stRow->GetPhiDeg(1) << "),("
01262 << stRow->GetThetaDeg(2) << ","
01263 << stRow->GetPhiDeg(2) << ")"
01264 << endl;
01265
01266
01267 hallVol -> AddNode(pairVol,1,pairMatrix);
01268 }
01269
01270
01271 MSG("Geo",Msg::kInfo) << "GeoGeometry built detector planes "
01272 << minPlaneName[0].c_str() << " to "
01273 << maxPlaneName[0].c_str() << "." << endl;
01274 if ( !minPlaneName[1].empty() ) {
01275 MSG("Geo",Msg::kInfo) << "GeoGeometry built shield planes "
01276 << minPlaneName[1].c_str() << " to "
01277 << maxPlaneName[1].c_str() << "." << endl;
01278 }
01279
01280
01281
01282 Detector::Detector_t dettype = (Detector::Detector_t)vldc.GetDetector();
01283 switch ( dettype ) {
01284 case Detector::kFar:
01285 BuildFarCoil(hallVol);
01286 break;
01287 case Detector::kNear:
01288 BuildNearCoil(hallVol);
01289 break;
01290 default:
01291 break;
01292 }
01293
01294 return;
01295
01296 }
01297
01298
01299 void GeoGeometry::BuildFarLeadStacks(TGeoVolume* hallVol) {
01300
01301
01302
01303 UpdateGlobalManager();
01304
01305 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildFarLeadStacks " << endl;
01306 assert(fGeoManager);
01307
01308 const GeoMediumMap& medMap = GetMediumMap();
01309
01310
01311 TGeoNode* linrNode = fGeoManager->GetVolume("MARS")->GetNode("LINR_1");
01312 const Double_t* h0 = linrNode -> GetMatrix() -> GetTranslation();
01313 Double_t hallX0 = h0[0];
01314
01315 Double_t hallZ0 = h0[2];
01316
01317 TGeoBBox* hallBox = dynamic_cast<TGeoBBox*>(hallVol->GetShape());
01318 Double_t dyHall = hallBox->GetDY();
01319
01320
01321
01322
01323
01324
01325
01326
01327 Double_t dxSoLo = 0.508*fScale;
01328 Double_t dySoLo = 0.508*fScale;
01329 Double_t dzSoLo = 0.508*fScale;
01330
01331 TGeoVolume* volSoLo = gGeoManager -> MakeBox("SoLo",
01332 medMap.GetMedium(Geo::kSoLo),dxSoLo,dySoLo,dzSoLo);
01333 volSoLo -> SetLineColor(17);
01334
01335
01336 Double_t dzSoLoOffset = -12.3698*fScale;
01337 Double_t dxSoLoOffset = -1.8288*fScale;
01338
01339 Double_t dySoLoOffset = +1.143*fScale;
01340
01341 hallVol -> AddNode(volSoLo,1,
01342 new TGeoTranslation(-hallX0+dxSoLoOffset,
01343 -dyHall+dySoLoOffset,
01344 -hallZ0+dzSoLoOffset));
01345
01346
01347
01348
01349
01350
01351 Float_t dxReeves = 0.5588*fScale;
01352 Float_t dyReeves = 0.4572*fScale;
01353 Float_t dzReeves = 0.5588*fScale;
01354 TGeoVolume* volReeves
01355 = gGeoManager -> MakeBox("Reeves",
01356 medMap.GetMedium(Geo::kSoLo),dxReeves,dyReeves,dzReeves);
01357 volReeves -> SetLineColor(17);
01358
01359
01360 Double_t dzReevesOffset = -11.5062*fScale;
01361
01362 Double_t dxReevesOffset = +3.556*fScale;
01363
01364 Double_t dyReevesOffset = +0.5588*fScale;
01365
01366 hallVol -> AddNode(volReeves,1,
01367 new TGeoTranslation(-hallX0+dxReevesOffset,
01368 -dyHall+dyReevesOffset,
01369 -hallZ0+dzReevesOffset));
01370
01371
01372
01373 return;
01374
01375 }
01376
01377
01378
01379 void GeoGeometry::BuildPlanePairVolumes(const VldContext& vldc) {
01380
01381
01382 UpdateGlobalManager();
01383
01384 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildPlanePairVolumes " << endl;
01385 assert(fGeoManager);
01386
01387 const GeoMediumMap& medMap = GetMediumMap();
01388
01389 DbiResultPtr<UgliDbiSteelPln> steelTbl(vldc);
01390 const UgliDbiTables& ugliDbiTables = UgliDbiTables(vldc);
01391
01392
01393 BuildStripVolumes(vldc);
01394
01395 Int_t plnMin[2] = {-1};
01396 Int_t plnMax[2] = {-1};
01397 Int_t nSM = GetSMPlaneLimits(vldc,plnMin,plnMax);
01398
01399
01400
01401
01402 TGeoVolume* coilVol = BuildCoilAirGapVolume(vldc);
01403 TGeoRotation* rot45 = GetRot45();
01404 Detector::Detector_t dettype = (Detector::Detector_t)vldc.GetDetector();
01405
01406 bool shieldOff = UgliLoanPool::Instance()->GetShieldOff();
01407
01408 for (unsigned int irow=0; irow < steelTbl.GetNumRows(); ++irow) {
01409
01410
01411
01412
01413
01414 GeoSteelPlnVolume* stplnVolume = 0;
01415 const UgliDbiSteelPln* stRow = steelTbl.GetRow(irow);
01416 PlexPlaneId steelId = stRow -> GetPlaneId();
01417 if ( shieldOff && steelId.IsVetoShield() ) continue;
01418
01419 std::string stName = GetGeoCompatibleName(steelId.AsString());
01420
01421 if ( steelId.IsVetoShield()
01422 && vldc.GetDetector() == Detector::kFar ) steelId =
01423 PlexVetoShieldHack::RenumberMuxToMdl(vldc,steelId);
01424 else if ( steelId.GetPlane() > 485 ) continue;
01425
01426
01427 if ( TMath::Abs(stRow->GetX0() ) > 50. ) continue;
01428
01429 Double_t pairhalfx = 0;
01430 Double_t pairhalfy = 0;
01431
01432
01433
01434
01435 Int_t planeno = steelId.GetPlane();
01436 Double_t pairhalfz = 0;
01437 if ( vldc.GetDetector() == Detector::kCalDet || steelId.IsVetoShield() )
01438 pairhalfz = 0.5*(stRow->GetTotalZ())*fScale;
01439 else
01440 pairhalfz = 0.5*(stRow->GetThickness())*fScale;
01441 if ( !steelId.IsVetoShield() ) {
01442 if ( planeno != plnMin[0] ) {
01443 if ( nSM == 1 || (nSM > 1 && planeno != plnMin[1]) ) {
01444 const UgliDbiSteelPln* stPrevRow = steelTbl.GetRowByIndex(planeno-1);
01445 pairhalfz = 0.5*(stRow->GetZBack() - stPrevRow->GetZBack())*fScale;
01446 }
01447 }
01448 }
01449
01450 if ( !steelId.IsVetoShield() ) {
01451 stplnVolume = new GeoSteelPlnVolume(this,steelId,
01452 stRow->GetThickness()*fScale);
01453 stplnVolume -> SetLineColor(kRed);
01454 stplnVolume -> SetVisibility(kTRUE);
01455
01456
01457
01458 TGeoBBox* bbox = dynamic_cast<TGeoBBox*>(stplnVolume->GetShape());
01459 pairhalfx = bbox->GetDX() + TMath::Abs((bbox->GetOrigin())[0]);
01460 pairhalfy = bbox->GetDY() + TMath::Abs((bbox->GetOrigin())[1]);
01461 }
01462
01463
01464 GeoScintPlnVolume* scplnVolume = 0;
01465 const UgliDbiScintPln* scRow = 0;
01466 PlexPlaneId scintId = steelId;
01467 scintId.SetIsSteel(false);
01468 std::string scName = GetGeoCompatibleName(scintId.AsString());
01469 if ( PlaneCoverage::kNoActive != steelId.GetPlaneCoverage() &&
01470 PlaneCoverage::kUnknown != steelId.GetPlaneCoverage() ) {
01471 scRow = ugliDbiTables.GetDbiScintPlnByIndex(scintId.GetPlane());
01472 MSG("Geo",Msg::kDebug) << "Build ScintPln " << scintId.AsString()
01473 << " w/thickness " << scRow->GetThickness()*fScale
01474 << endl;
01475
01476 scplnVolume = new GeoScintPlnVolume(this,scintId,
01477 scRow->GetThickness()*fScale);
01478 scplnVolume -> SetVisibility(kFALSE);
01479 scplnVolume -> SetLineColor(kBlue);
01480
01481
01482
01483 TGeoBBox* bbox = dynamic_cast<TGeoBBox*>(scplnVolume->GetShape());
01484 pairhalfx = TMath::Max(pairhalfx,bbox->GetDX()
01485 + TMath::Abs((bbox->GetOrigin())[0]));
01486 pairhalfy = TMath::Max(pairhalfy,bbox->GetDY()
01487 + TMath::Abs((bbox->GetOrigin())[1]));
01488 }
01489
01490 if ( vldc.GetDetector() == Detector::kNear ) pairhalfy = 2.91*fScale;
01491
01492
01493 std::string pairName = GetGeoCompatibleName(steelId.AsString("b"));
01494 MSG("Geo",Msg::kDebug) << "Build PairBox " << pairName.c_str()
01495 << " w/halfx,y,z " << pairhalfx << ","
01496 << pairhalfy << "," << pairhalfz << "." << endl;
01497
01498 Geo::EDetComponent detcomp = Geo::kPlnAirGap;
01499 if ( steelId.IsVetoShield() ) detcomp = Geo::kHall;
01500 TGeoVolume* pairVol = fGeoManager->MakeBox(pairName.c_str(),
01501 medMap.GetMedium(detcomp),
01502 pairhalfx,pairhalfy,pairhalfz);
01503 pairVol -> SetVisibility(kFALSE);
01504 pairVol -> VisibleDaughters(kTRUE);
01505
01506
01507
01508
01509
01510
01511 if ( !steelId.IsVetoShield() && coilVol ) {
01512 if ( planeno != plnMin[0] ) {
01513 if ( nSM == 1 || (nSM > 1 && planeno != plnMin[1]) ) {
01514 std::string airgap0 = pairName + "_air0";
01515 Double_t airgap0halfz = pairhalfz - 0.5*(stRow->GetTotalZ())*fScale;
01516
01517
01518 if ( !scplnVolume ) airgap0halfz
01519 = pairhalfz - 0.5*(stRow->GetThickness())*fScale;
01520 TGeoVolume* airgap0Vol = fGeoManager->MakeBox(airgap0.c_str(),
01521 medMap.GetMedium(Geo::kPlnAirGap),
01522 pairhalfx,pairhalfy,airgap0halfz);
01523 airgap0Vol -> SetVisibility(kFALSE);
01524 airgap0Vol -> VisibleDaughters(kTRUE);
01525 Double_t airgap0z0 = -pairhalfz + airgap0halfz;
01526 pairVol->AddNode(airgap0Vol,1,new TGeoTranslation(0.,0.,airgap0z0));
01527 if (dettype == Detector::kNear) airgap0Vol->AddNode(coilVol,1,rot45);
01528 else airgap0Vol -> AddNode(coilVol,1,gGeoIdentity);
01529 }
01530 }
01531 if ( scplnVolume ) {
01532 std::string airgap1 = pairName + "_air1";
01533 Double_t airgap1halfz = 0.5*(stRow->GetTotalZ()-stRow->GetThickness()
01534 - scRow->GetThickness())*fScale;
01535 TGeoVolume* airgap1Vol = fGeoManager->MakeBox(airgap1.c_str(),
01536 medMap.GetMedium(Geo::kPlnAirGap),
01537 pairhalfx,pairhalfy,airgap1halfz);
01538 airgap1Vol -> SetVisibility(kFALSE);
01539 airgap1Vol -> VisibleDaughters(kTRUE);
01540 Double_t airgap1z0 = pairhalfz-stRow->GetThickness()*fScale
01541 - airgap1halfz;
01542 pairVol -> AddNode(airgap1Vol,1,new TGeoTranslation(0.,0.,airgap1z0));
01543
01544 if ( dettype == Detector::kNear ) airgap1Vol->AddNode(coilVol,1,rot45);
01545 else airgap1Vol -> AddNode(coilVol,1,gGeoIdentity);
01546 }
01547 }
01548
01549
01550
01551
01552
01553 std::string pairPath = fHallPath + "/" + pairName +"_1";
01554 if ( steelId.IsVetoShield() && vldc.GetDetector() == Detector::kFar ) {
01555 GeoShield::EGroupType group=fGeoShield.AddVolume(pairVol,steelId,stRow);
01556 pairPath = fHallPath + "/" + GeoShield::AsString(group) + "_1/" +
01557 pairName+"_1";
01558 }
01559
01560 int iSM = -1;
01561 if ( !steelId.IsVetoShield() ) {
01562 iSM = 0;
01563 if ( nSM > 1 && steelId.GetPlane() > plnMax[0] ) iSM = 1;
01564 }
01565
01566 if ( stplnVolume ) {
01567
01568 std::string stplnNodeName = stName + "_1";
01569 std::string steelPlnPath = pairPath + "/" + stplnNodeName;
01570 double z0steel = pairhalfz - 0.5*(stRow->GetThickness())*fScale;
01571 MSG("Geo",Msg::kDebug) << "Placing steel pln at " << 0. << ","
01572 << 0. << "," << z0steel << endl;
01573 GeoSteelPlnNode* stplnNode = new GeoSteelPlnNode(this,stplnVolume,
01574 new TGeoTranslation(stName.c_str(),0.,0.,z0steel),
01575 pairVol,steelPlnPath,stplnNodeName,steelId);
01576
01577
01578 if ( vldc.GetDetector() != Detector::kCalDet )
01579 fSMZMin[iSM] = TMath::Min(fSMZMin[iSM],(stRow->GetZBack()
01580 -stRow->GetThickness())*fScale);
01581 else
01582 fSMZMin[iSM] = TMath::Min(fSMZMin[iSM],(stRow->GetZBack()
01583 -stRow->GetTotalZ())*fScale);
01584 fSMZMax[iSM] = TMath::Max(fSMZMax[iSM],(stRow->GetZBack())*fScale);
01585
01586
01587 fPlaneMap[steelId] = stplnNode;
01588 }
01589
01590 if ( scplnVolume ) {
01591
01592 Float_t x0pln = (scRow->GetX0RelSteel())*fScale;
01593 Float_t y0pln = (scRow->GetY0RelSteel())*fScale;
01594 Float_t z0pln = pairhalfz +
01595 (-stRow->GetTotalZ()+0.5*(scRow->GetThickness()))*fScale;
01596
01597
01598
01599
01600
01601 Double_t zrotrelsteel = scRow->GetZRotRelSteelDeg();
01602
01603 MSG("Geo",Msg::kDebug) << "Placing scint pln at " << x0pln << ", "
01604 << y0pln << "," << z0pln
01605 << " zrotrelsteel " << zrotrelsteel << endl;
01606
01607 TGeoRotation* scRotMatrix = new TGeoRotation(scName.c_str(),90.,
01608 zrotrelsteel,90.,90.+zrotrelsteel,0.,0.);
01609 scRotMatrix -> RegisterYourself();
01610
01611 TGeoCombiTrans* combiMatrix
01612 = new TGeoCombiTrans(scName.c_str(),x0pln,y0pln,z0pln,scRotMatrix);
01613
01614 std::string scplnNodeName = scName + "_1";
01615 std::string scintPlnPath = pairPath + "/" + scplnNodeName;
01616 GeoScintPlnNode* scplnNode
01617 = new GeoScintPlnNode(this,scplnVolume,combiMatrix,pairVol,
01618 scintPlnPath,scplnNodeName,scintId);
01619
01620 this -> BuildModules(ugliDbiTables, scplnNode);
01621
01622
01623 fPlaneMap[scintId] = scplnNode;
01624
01625 }
01626
01627 }
01628
01629
01630 return;
01631
01632 }
01633
01634
01635 Int_t GeoGeometry::GetSMPlaneLimits(const VldContext& vldc,
01636 Int_t* plnMin, Int_t* plnMax) {
01637
01638
01639
01640
01641
01642 Detector::Detector_t dettype = vldc.GetDetector();
01643 Int_t nSM = 0;
01644 switch (dettype) {
01645 case Detector::kFar:
01646 nSM = 2;
01647 plnMin[0] = 0;
01648 plnMax[0] = 248;
01649 plnMin[1] = 249;
01650 plnMax[1] = 485;
01651 break;
01652 case Detector::kNear:
01653 nSM = 1;
01654 plnMin[0] = 0;
01655 plnMax[0] = 281;
01656 break;
01657 case Detector::kCalDet:
01658 nSM = 1;
01659 plnMin[0] = 0;
01660 plnMax[0] = 60;
01661 break;
01662 default:
01663 MSG("Geo",Msg::kError)
01664 << "GetSMPlaneLimits failed for unknown detector type\n"
01665 << Detector::AsString(dettype) << "." << endl;
01666 }
01667
01668 return nSM;
01669
01670 }
01671
01672
01673 TGeoVolume* GeoGeometry::BuildFarMARS() {
01674
01675
01676 UpdateGlobalManager();
01677
01678 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildFarMARS " << endl;
01679 assert(fGeoManager);
01680
01681 const GeoMediumMap& medMap = GetMediumMap();
01682
01683
01684 Float_t mars_halfx = 85.*fScale;
01685 Float_t mars_halfy = 30.*fScale;
01686 Float_t mars_halfz = 250.*fScale;
01687
01688
01689 TGeoVolume* volMARS = fGeoManager->MakeBox("MARS",
01690 medMap.GetMedium(Geo::kMars),
01691 mars_halfx,mars_halfy,mars_halfz);
01692
01693
01694
01695
01696 Float_t shft_halfx = 1.*fScale;
01697 Float_t shft_halfy = 30.*fScale;
01698 Float_t shft_halfz = 1.*fScale;
01699 TGeoVolume* volSHFT = gGeoManager->MakeBox("SHFT",
01700 medMap.GetMedium(Geo::kHall),
01701 shft_halfx,shft_halfy,shft_halfz);
01702 volSHFT -> SetVisibility(kTRUE);
01703 volSHFT -> SetVisContainers(kTRUE);
01704
01705
01706 Float_t tunl_halfx = 2.*fScale;
01707 Float_t tunl_halfy = 2.*fScale;
01708 Float_t tunl_halfz = 13.5*fScale;
01709 TGeoVolume* volTUNL = gGeoManager->MakeBox("TUNL",
01710 medMap.GetMedium(Geo::kHall),
01711 tunl_halfx,tunl_halfy,tunl_halfz);
01712 volTUNL -> SetVisibility(kTRUE);
01713 volTUNL -> SetVisContainers(kTRUE);
01714
01715 Float_t s2hl_halfx = 7. *fScale;
01716 Float_t s2hl_halfy = 5.65*fScale;
01717 Float_t s2hl_halfz = 35. *fScale;
01718 TGeoVolume* volS2HL = gGeoManager->MakeBox("S2HL",
01719 medMap.GetMedium(Geo::kHall),
01720 s2hl_halfx,s2hl_halfy,s2hl_halfz);
01721 volS2HL -> SetVisibility(kTRUE);
01722 volS2HL -> SetVisContainers(kTRUE);
01723
01724
01725
01726 Float_t s2dt_halfx = 4. *fScale;
01727 Float_t s2dt_halfy = 2.7*fScale;
01728 Float_t s2dt_halfz = 7.5*fScale;
01729 TGeoVolume* volS2DT = gGeoManager->MakeBox("S2DT",
01730 medMap.GetMedium(Geo::kHall),
01731 s2dt_halfx,s2dt_halfy,s2dt_halfz);
01732 volS2DT -> SetVisibility(kTRUE);
01733 volS2DT -> SetVisContainers(kTRUE);
01734
01735 volS2HL -> AddNode(volS2DT,1,
01736 new TGeoTranslation(0*fScale,-1.15*fScale,-23.5*fScale));
01737
01738
01739 volMARS -> AddNode(volSHFT,1,
01740 new TGeoTranslation(-5.*fScale,0.*fScale,98.18*fScale));
01741 volMARS -> AddNode(volTUNL,1,
01742 new TGeoTranslation(-5.*fScale,-4.1*fScale,83.68*fScale));
01743 TGeoRotation* s2rot = new TGeoRotation("s2rot",64,0,90,90,26,180);
01744 s2rot -> RegisterYourself();
01745 volMARS -> AddNode(volS2HL,1,
01746 new TGeoCombiTrans(36.*fScale,-0.45*fScale,61.68*fScale,
01747 s2rot));
01748
01749 return volMARS;
01750
01751 }
01752
01753
01754 TGeoVolume* GeoGeometry::BuildNearMARS() {
01755
01756
01757 UpdateGlobalManager();
01758
01759 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildNearMARS " << endl;
01760 assert(fGeoManager);
01761
01762 const GeoMediumMap& medMap = GetMediumMap();
01763
01764
01765 Float_t mars_halfx = 85.*fScale;
01766 Float_t mars_halfy = 30.*fScale;
01767 Float_t mars_halfz = 250.*fScale;
01768
01769
01770 TGeoVolume* volMARS = fGeoManager->MakeBox("MARS",
01771 medMap.GetMedium(Geo::kMars),
01772 mars_halfx,mars_halfy,mars_halfz);
01773
01774 return volMARS;
01775
01776 }
01777
01778
01779 void GeoGeometry::BuildNearCoil(TGeoVolume* hallVol) {
01780
01781
01782
01783
01784 UpdateGlobalManager();
01785
01786 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildNearCoil " << endl;
01787 assert(fGeoManager);
01788
01789 const GeoMediumMap& medMap = GetMediumMap();
01790
01791
01792 Float_t shalfx = Geo::kNeckRad*fScale;
01793 Float_t shalfy = shalfx;
01794 Float_t ahalfx = Geo::kThroatRad*fScale;
01795 Float_t ahalfy = ahalfx;
01796 Float_t alhalfx = Geo::kCoilRad*fScale;
01797 Float_t alhalfy = alhalfx;
01798
01799
01800 Float_t zmin,zmax;
01801 GetZExtent(zmin,zmax,-1);
01802
01803 TGeoNode* linrNode = fGeoManager->GetVolume("MARS")->GetNode("LINR_1");
01804 const Double_t* h0 = linrNode -> GetMatrix() -> GetTranslation();
01805 zmin -= h0[2];
01806 zmax -= h0[2];
01807 Float_t x0 = -h0[0];
01808 Float_t y0 = -h0[1];
01809
01810 Float_t zcoillen = zmax - zmin;
01811 TGeoVolume* BUS0 = fGeoManager->MakeBox("BUS0",
01812 medMap.GetMedium(Geo::kRCShaft),
01813 shalfx,shalfy,0.5*zcoillen);
01814 BUS0 -> SetLineColor(14);
01815 BUS0 -> SetVisibility(kTRUE);
01816
01817 TGeoVolume* BUA0 = fGeoManager->MakeBox("BUA0",
01818 medMap.GetMedium(Geo::kRCAir),
01819 ahalfx,ahalfy,0.5*zcoillen);
01820 BUA0 -> SetLineColor(14);
01821 BUA0 -> SetVisibility(kTRUE);
01822 BUS0 -> AddNode(BUA0,1,gGeoIdentity);
01823
01824 TGeoVolume* BUC0 = fGeoManager->MakeBox("BUC0",
01825 medMap.GetMedium(Geo::kRCCoil),
01826 alhalfx,alhalfy,0.5*zcoillen);
01827 BUC0 -> SetLineColor(14);
01828 BUC0 -> SetVisibility(kTRUE);
01829 BUA0 -> AddNode(BUC0,1,gGeoIdentity);
01830
01831
01832 TGeoRotation *rot45 = GetRot45();
01833 Float_t zcoil = (zmin+zmax)/2.;
01834
01835
01836 Float_t steelhalfy = 1.9*fScale;
01837 Float_t xcoil = x0 - steelhalfy;
01838 Float_t ycoil = y0 - steelhalfy;
01839
01840 hallVol -> AddNodeOverlap(BUS0,2,
01841 new TGeoCombiTrans(xcoil,ycoil,zcoil,rot45));
01842
01843
01844 Float_t cos45 = 0.707107;
01845 Float_t coillenxy = steelhalfy/cos45 + 2.*shalfx;
01846 TGeoVolume* BUSXY = fGeoManager->MakeBox("BUSXY",
01847 medMap.GetMedium(Geo::kRCShaft),
01848 shalfx,0.5*coillenxy,shalfy);
01849 BUSXY -> SetLineColor(14);
01850 BUSXY -> SetVisibility(kTRUE);
01851 TGeoVolume* BUAXY = fGeoManager->MakeBox("BUAXY",
01852 medMap.GetMedium(Geo::kRCAir),
01853 ahalfx,0.5*coillenxy,ahalfy);
01854 BUAXY -> SetLineColor(14);
01855 BUAXY -> SetVisibility(kTRUE);
01856 BUSXY -> AddNode(BUAXY,1,gGeoIdentity);
01857
01858 TGeoVolume* BUCXY = fGeoManager->MakeBox("BUCXY",
01859 medMap.GetMedium(Geo::kRCCoil),
01860 alhalfx,0.5*coillenxy,alhalfy);
01861 BUCXY -> SetLineColor(14);
01862 BUCXY -> SetVisibility(kTRUE);
01863 BUAXY -> AddNode(BUCXY,1,gGeoIdentity);
01864
01865
01866 TGeoRotation* rotneg45 = GetRot315();
01867 xcoil = x0 - (0.5*coillenxy - shalfx)*cos45;
01868 ycoil = y0 - (0.5*coillenxy - shalfy)*cos45;
01869 zcoil = zmin - shalfy;
01870 hallVol -> AddNode(BUSXY,1,new TGeoCombiTrans(xcoil,ycoil,zcoil,rotneg45));
01871
01872 zcoil = zmax + shalfy;
01873 hallVol -> AddNode(BUSXY,2,new TGeoCombiTrans(xcoil,ycoil,zcoil,rotneg45));
01874
01875 return;
01876
01877 }
01878
01879
01880 void GeoGeometry::BuildFarCoil(TGeoVolume* hallVol) {
01881
01882
01883
01884
01885 UpdateGlobalManager();
01886
01887 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildFarCoil " << endl;
01888 assert(fGeoManager);
01889
01890 const GeoMediumMap& medMap = GetMediumMap();
01891
01892
01893
01894
01895
01896
01897
01898
01899 Float_t sRad = Geo::kCoilRad*fScale;
01900
01901 Float_t halfhally = dynamic_cast<TGeoBBox*>(hallVol -> GetShape())->GetDY();
01902
01903
01904
01905 Float_t zmin0,zmax0;
01906 GetZExtent(zmin0,zmax0,0);
01907
01908 TGeoNode* linrNode = fGeoManager->GetVolume("MARS")->GetNode("LINR_1");
01909 const Double_t* h0 = linrNode -> GetMatrix() -> GetTranslation();
01910 zmin0 -= h0[2];
01911 zmax0 -= h0[2];
01912 Float_t x0 = -h0[0];
01913 Float_t y0 = -h0[1];
01914
01915
01916
01917
01918 Float_t retcoilhalfx = 0.225*fScale;
01919 Float_t retcoilhalfy = 0.05*fScale;
01920
01921 Float_t zcoillen0 = zmax0-zmin0;
01922 TGeoVolume* BUS0=fGeoManager->MakeBox("BUS0",medMap.GetMedium(Geo::kRCCoil),
01923 retcoilhalfx,retcoilhalfy,0.5*zcoillen0);
01924 BUS0 -> SetLineColor(42);
01925 BUS0 -> SetVisibility(kTRUE);
01926
01927
01928 Float_t z0 = 0.5*(zmin0 + zmax0);
01929 hallVol -> AddNode(BUS0,1,new TGeoTranslation("BUS0",x0,
01930 -halfhally+retcoilhalfy,z0));
01931
01932
01933 Float_t zmin1,zmax1;
01934 GetZExtent(zmin1,zmax1,1);
01935
01936 zmin1 -= h0[2];
01937 zmax1 -= h0[2];
01938
01939 Float_t zcoillen1 = zmax1-zmin1;
01940 TGeoVolume* BUS1=fGeoManager->MakeBox("BUS1",medMap.GetMedium(Geo::kRCCoil),
01941 retcoilhalfx,retcoilhalfy,0.5*zcoillen1);
01942 BUS1 -> SetLineColor(42);
01943 BUS1 -> SetVisibility(kTRUE);
01944
01945
01946 Float_t z1 = 0.5*(zmin1 + zmax1);
01947 hallVol -> AddNode(BUS1,1,new TGeoTranslation("BUS1",x0,
01948 -halfhally+retcoilhalfy,z1));
01949
01950
01951
01952
01953
01954
01955
01956 Float_t ycoillen = y0+halfhally+sRad;
01957
01958
01959 Float_t zbotgap = 0.10*fScale;
01960
01961 Float_t xhalftail = 0.40*fScale;
01962 Float_t yhalftail = 0.5*ycoillen;
01963 Float_t zhalftail = 0.5*(zbotgap+0.4*fScale);
01964 TGeoVolume* BUXY = fGeoManager->MakeBox("BUXY",medMap.GetMedium(Geo::kRCAir),
01965 xhalftail,yhalftail,zhalftail);
01966 BUXY -> SetLineColor(14);
01967 BUXY -> SetVisibility(kFALSE);
01968
01969
01970
01971
01972 TGeoRotation *rotFlip = new TGeoRotation("BUXY",90,180,90,90,180,0);
01973 rotFlip -> RegisterYourself();
01974
01975 Float_t xcoil = x0;
01976 Float_t ycoil = y0 + sRad - ycoillen/2.;
01977 hallVol -> AddNode(BUXY,1,new TGeoTranslation("BUXY_1",xcoil,ycoil,
01978 zmin0-zhalftail));
01979 hallVol -> AddNode(BUXY,2,new TGeoCombiTrans("BUXY_2",xcoil,ycoil,
01980 zmax0+zhalftail,rotFlip));
01981 hallVol -> AddNode(BUXY,3,new TGeoTranslation("BUXY_3",xcoil,ycoil,
01982 zmin1-zhalftail));
01983 hallVol -> AddNode(BUXY,4,new TGeoCombiTrans("BUXY_4",xcoil,ycoil,
01984 zmax1+zhalftail,rotFlip));
01985
01986
01987
01988 Float_t yhalftop = 0.5*0.53*fScale;
01989 Float_t zhalftop = 0.10*fScale;
01990 Float_t xhalfloy = 0.2825*fScale;
01991 Float_t xhalfhiy = 0.12*fScale;
01992 TGeoTrap* bxyTopShp = new TGeoTrap("BXYTOP",zhalftop,0.,0.,
01993 yhalftop,xhalfloy,xhalfhiy,0.,
01994 yhalftop,xhalfloy,xhalfhiy,0.);
01995 TGeoVolume* BXYTOP = new TGeoVolume("BXYTOP",bxyTopShp,
01996 medMap.GetMedium(Geo::kRCCoil));
01997 BXYTOP -> SetLineColor(42);
01998 BXYTOP -> SetVisibility(kTRUE);
01999 BUXY -> AddNode(BXYTOP,1,new TGeoTranslation(0.,yhalftail-sRad-yhalftop,
02000 -zhalftail+zhalftop));
02001
02002
02003
02004
02005 Float_t yhalfmid = 0.5*0.85*fScale;
02006 TGeoArb8* bxyMidShp = new TGeoArb8(yhalfmid);
02007 bxyMidShp -> SetVertex(0,-0.4*fScale,0.05*fScale);
02008 bxyMidShp -> SetVertex(1,-0.4*fScale,0.15*fScale);
02009 bxyMidShp -> SetVertex(2,0.4*fScale,0.15*fScale);
02010 bxyMidShp -> SetVertex(3,0.4*fScale,0.05*fScale);
02011 bxyMidShp -> SetVertex(4,-0.2825*fScale,-0.25*fScale);
02012 bxyMidShp -> SetVertex(5,-0.2825*fScale,-0.05*fScale);
02013 bxyMidShp -> SetVertex(6,0.2825*fScale,-0.05*fScale);
02014 bxyMidShp -> SetVertex(7,0.2825*fScale,-0.25*fScale);
02015
02016 TGeoVolume* BXYMID = new TGeoVolume("BXYMID",bxyMidShp,
02017 medMap.GetMedium(Geo::kRCCoil));
02018 BXYMID -> SetLineColor(42);
02019 BXYMID -> SetVisibility(kTRUE);
02020
02021 TGeoRotation *rotMid = new TGeoRotation("BXYMid",90,0,0,0,90,90);
02022 rotMid -> RegisterYourself();
02023 BUXY -> AddNode(BXYMID,1,new TGeoCombiTrans("BXYMID",0.,
02024 yhalftail-sRad-2.*yhalftop-yhalfmid,0.,rotMid));
02025
02026
02027 Float_t xhalfbot = 0.4*fScale;
02028 Float_t yhalfbot = 0.5*(ycoillen-sRad-2.*yhalftop-2.*yhalfmid);
02029 Float_t zhalfbot = 0.05*fScale;
02030
02031 TGeoVolume* BXYBOT = fGeoManager -> MakeBox("BXYBOT",
02032 medMap.GetMedium(Geo::kRCCoil),
02033 xhalfbot,yhalfbot,zhalfbot);
02034 BXYBOT -> SetLineColor(42);
02035 BXYBOT -> SetVisibility(kTRUE);
02036 BUXY -> AddNode(BXYBOT,1,new TGeoTranslation(0.,-yhalftail+yhalfbot,
02037 zhalftail-zbotgap-zhalfbot));
02038
02039
02040 TGeoVolume* BXYRET = fGeoManager -> MakeBox("BXYRET",
02041 medMap.GetMedium(Geo::kRCCoil),
02042 retcoilhalfx,retcoilhalfy,0.5*zbotgap);
02043 BXYRET -> SetLineColor(42);
02044 BXYRET -> SetVisibility(kTRUE);
02045 BUXY -> AddNode(BXYRET,1,new TGeoTranslation(0.,-yhalftail+retcoilhalfy,
02046 zhalftail-0.5*zbotgap));
02047
02048
02049 TGeoVolume* BXYSTB = fGeoManager -> MakeTube("BXYSTB",
02050 medMap.GetMedium(Geo::kRCCoil),
02051 0.,sRad,zhalftail);
02052 BXYSTB -> SetLineColor(42);
02053 BXYSTB -> SetVisibility(kTRUE);
02054 BUXY -> AddNodeOverlap(BXYSTB,1,new TGeoTranslation(0.,yhalftail-sRad,0.));
02055
02056 return;
02057
02058 }
02059
02060
02061 void GeoGeometry::BuildModules(const UgliDbiTables& ugliDbiTables,
02062 GeoScintPlnNode* plnNode) {
02063
02064
02065 UpdateGlobalManager();
02066
02067 assert(fGeoManager);
02068
02069 const PlexPlaneId& plexPlaneId = plnNode -> GetPlexPlaneId();
02070 MSG("Geo",Msg::kDebug) <<"GeoGeometry::BuildModules for scint pln "
02071 << plnNode->GetName() << endl;
02072
02073
02074 std::string plnPath = plnNode->GetGlobalPath();
02075
02076
02077 UgliDbiStructHash planestructhash(plexPlaneId);
02078 const UgliDbiScintPlnStruct* plnStruct = ugliDbiTables.fScintPlnStructTbl
02079 .GetRowByIndex(planestructhash.HashAsPlane());
02080 Int_t nmodules = plnStruct -> GetNModules();
02081
02082
02083 for ( int imod = 0; imod < nmodules; imod++ ) {
02084
02085 PlexScintMdlId plexModuleId(plexPlaneId,imod);
02086
02087 std::string mdlName = GetGeoCompatibleName(plexModuleId.AsString());
02088
02089
02090
02091
02092
02093 GeoScintMdlVolume* mdlVol = new GeoScintMdlVolume(this,plexModuleId,
02094 ugliDbiTables);
02095
02096
02097
02098 const UgliDbiScintMdl* scModule
02099 = ugliDbiTables.GetDbiScintMdlById(plexModuleId);
02100 Float_t tposMod = (scModule -> GetTPosRelPln())*fScale;
02101 Float_t lposMod = (scModule -> GetLPosRelPln())*fScale;
02102 Float_t zrotMod = scModule -> GetZRotRelPlnDeg();
02103
02104 TGeoRotation* modRotMatrix = new TGeoRotation(mdlName.c_str(), 90.,zrotMod,
02105 90.,90.+zrotMod,0.,0.);
02106 modRotMatrix -> RegisterYourself();
02107
02108 TGeoCombiTrans* combiMatrix = new TGeoCombiTrans(mdlName.c_str(),
02109 lposMod,tposMod,0.,modRotMatrix);
02110 std::string mdlNodeName = mdlName + "_1";
02111
02112 MSG("Geo",Msg::kVerbose) << "Mdl node " << mdlNodeName.c_str()
02113 << "tpos, lpos, zrot(deg) rel pln "
02114 << tposMod << "," << lposMod << "," << zrotMod
02115 << endl;
02116
02117 GeoScintMdlNode* mdlNode = new GeoScintMdlNode(this,mdlVol,combiMatrix,
02118 plnNode,mdlNodeName,
02119 plexModuleId,
02120 scModule->GetClearLenEast()*fScale,
02121 scModule->GetClearLenWest()*fScale,
02122 scModule->GetWlsLenEast()*fScale,
02123 scModule->GetWlsLenWest()*fScale);
02124
02125
02126 BuildStrips(ugliDbiTables,mdlNode);
02127
02128 }
02129
02130 }
02131
02132
02133 void GeoGeometry::BuildStrips(const UgliDbiTables& ugliDbiTables,
02134 GeoScintMdlNode* mdlNode) {
02135
02136
02137
02138
02139 UpdateGlobalManager();
02140 assert(fGeoManager);
02141
02142 PlexScintMdlId plexModuleId = mdlNode->GetPlexScintMdlId();
02143 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildStrips for module "
02144 << mdlNode->GetName() << endl;
02145
02146
02147 UgliDbiStructHash modulestructhash(plexModuleId);
02148 const UgliDbiScintMdlStruct* scModuleStruct
02149 = ugliDbiTables.fScintMdlStructTbl
02150 .GetRowByIndex(modulestructhash.HashAsScintMdl());
02151 Int_t lostrip = scModuleStruct -> GetFirstStrip();
02152 Int_t histrip = scModuleStruct -> GetLastStrip();
02153
02154 for ( int istp = lostrip; istp <= histrip; istp++ ) {
02155
02156 PlexStripEndId seid(plexModuleId,istp);
02157 std::string stpName = GetGeoCompatibleName(seid.AsString());
02158
02159 MSG("Geo",Msg::kVerbose) << "Strip " << istp << " name "
02160 << stpName.c_str() << endl;
02161 const UgliDbiStrip* scStrip = ugliDbiTables.GetDbiStripById(seid);
02162
02163
02164 std::string stpVolName = GetGeoCompatibleName(seid.AsString("s"));
02165 TGeoVolume* stpVol = fGeoManager -> GetVolume(stpVolName.c_str());
02166 if ( !stpVol ) {
02167 MSG("Geo",Msg::kFatal)
02168 << "Unable to find pre-built stripvol for volume "
02169 << stpName.c_str() << " shape name "
02170 << stpVolName.c_str() << endl;
02171 abort();
02172 }
02173
02174
02175 Float_t tposStp = (scStrip -> GetTPosRelMdl())*fScale;
02176 Float_t lposStp = (scStrip -> GetLPosRelMdl())*fScale;
02177 Float_t zrotStp = scStrip -> GetZRotRelMdlDeg();
02178 MSG("Geo",Msg::kVerbose) << "tpos, lpos, zrot(deg) rel to module "
02179 << tposStp << ", " << lposStp << ", "
02180 << zrotStp << endl;
02181
02182 std::string stpNodeName = stpVolName+"_1";
02183
02184 TGeoRotation* stpRotMatrix = new TGeoRotation(stpNodeName.c_str(), 90.,
02185 zrotStp,90.,90.+zrotStp,0.,0.);
02186 stpRotMatrix -> RegisterYourself();
02187 TGeoCombiTrans* combiMatrix
02188 = new TGeoCombiTrans(stpNodeName.c_str(),lposStp,tposStp,0.,stpRotMatrix);
02189
02190 new GeoStripNode(this,stpVol,combiMatrix,mdlNode,stpNodeName,seid);
02191
02192 }
02193
02194 return;
02195
02196 }
02197
02198
02199 void GeoGeometry::BuildStripVolumes(const VldContext& vldc) {
02200
02201
02202
02203
02204 UpdateGlobalManager();
02205
02206 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildStripVolumes " << endl;
02207 assert(fGeoManager);
02208
02209 DbiResultPtr<UgliDbiStripStruct> stripTbl(vldc);
02210 Detector::Detector_t dettype = vldc.GetDetector();
02211
02212 bool shieldOff = UgliLoanPool::Instance()->GetShieldOff();
02213
02214 for ( unsigned int irow = 0; irow < stripTbl.GetNumRows(); irow++ ) {
02215 const UgliDbiStripStruct* sRow = stripTbl.GetRow(irow);
02216 string stpName = GetGeoCompatibleName(sRow -> GetShapeName());
02217 PlaneView::PlaneView_t plnview = sRow->GetPlaneView();
02218 bool isVetoShield = false;
02219 if ( dettype == Detector::kFar ) {
02220 if ( plnview != PlaneView::kU && plnview != PlaneView::kV )
02221 isVetoShield = true;
02222 }
02223 else if ( dettype == Detector::kCalDet ) {
02224 if ( plnview != PlaneView::kX && plnview != PlaneView::kY )
02225 isVetoShield = true;
02226 }
02227
02228 if ( shieldOff && isVetoShield ) continue;
02229
02230
02231 Float_t totallen = (sRow->GetTotalLen())*fScale;
02232 Float_t leneastpart = (sRow->GetLenEastPart())*fScale;
02233 Float_t lenwestpart = (sRow->GetLenWestPart())*fScale;
02234
02235 if ( totallen < 1.E-4*fScale ) continue;
02236 if ( leneastpart < 1.E-4*fScale ) leneastpart = totallen;
02237 if ( lenwestpart < 1.E-4*fScale ) lenwestpart = totallen;
02238
02239 new GeoStripVolume(this,stpName.c_str(),totallen,leneastpart,lenwestpart,
02240 (sRow->GetWlsLenEast())*fScale,
02241 (sRow->GetWlsLenWest())*fScale,
02242 (sRow->GetWlsLenBypass())*fScale,
02243 isVetoShield);
02244 }
02245
02246 }
02247
02248
02249 void GeoGeometry::UpdateNodeMatrices(TGeoVolume* volume) {
02250
02251
02252
02253
02254 UpdateGlobalManager();
02255 if (!volume) {
02256 MSG("Geo",Msg::kFatal) << "UpdateNodeMatrices called with null volume ptr "
02257 << endl;
02258 abort();
02259 }
02260
02261 Int_t ndaughter = volume -> GetNdaughters();
02262 for ( int id = 0; id < ndaughter; id++ ) {
02263 TGeoNode* daughternode = volume->GetNode(id);
02264 GeoNode* geonode = dynamic_cast<GeoNode*>(daughternode);
02265 if ( geonode ) geonode -> UpdateGlobalMatrix();
02266
02267 TGeoVolume* daughtervol = daughternode->GetVolume();
02268 this -> UpdateNodeMatrices(daughtervol);
02269 }
02270
02271 }
02272
02273
02274 TGeoVolume* GeoGeometry::BuildCoilAirGapVolume(const VldContext& vldc) const {
02275
02276
02277
02278 UpdateGlobalManager();
02279
02280 TGeoVolume* coilVol = 0;
02281
02282 Detector::Detector_t dettype = (Detector::Detector_t)vldc.GetDetector();
02283
02284 switch (dettype) {
02285
02286 case Detector::kFar:
02287 coilVol = BuildFarCoilAirGapVolume();
02288 break;
02289
02290 case Detector::kNear:
02291 coilVol = BuildNearCoilAirGapVolume();
02292 break;
02293
02294 default:
02295 break;
02296
02297 }
02298
02299 return coilVol;
02300
02301 }
02302
02303
02304
02305 TGeoVolume* GeoGeometry::BuildFarCoilAirGapVolume() const {
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329
02330 UpdateGlobalManager();
02331
02332
02333
02334
02335 const GeoMediumMap& medMap = GetMediumMap();
02336
02337
02338 TGeoVolume* volBypass = gGeoManager->GetVolume("FGBY");
02339 if ( volBypass ) return volBypass;
02340
02341 Double_t scale = Geo::GetScale(GetAppType());
02342
02343 TGeoVolume* volCoil
02344 = gGeoManager->MakeTube("FGCO",medMap.GetMedium(Geo::kCRGapCoil),
02345 0,Geo::kCoilRad*scale,-1.);
02346 volCoil -> SetLineColor(42);
02347
02348 TGeoVolume* volThroat
02349 = gGeoManager->MakeTube("FGTR",medMap.GetMedium(Geo::kCRGapThroat),
02350 0,Geo::kThroatRad*scale,-1.);
02351 volThroat -> SetLineColor(kBlue);
02352
02353 TGeoVolume* volFlange
02354 = gGeoManager->MakeTube("FGFL",medMap.GetMedium(Geo::kCRGapFlange),
02355 0,Geo::kFlangeRad*scale,-1.);
02356 volFlange -> SetLineColor(46);
02357
02358 volBypass
02359 = gGeoManager->MakeTube("FGBY",medMap.GetMedium(Geo::kCRGapBypass),
02360 0,Geo::kFarBypassRad*scale,-1.);
02361 volBypass -> SetLineColor(kBlue);
02362 volBypass -> SetLineStyle(2);
02363 volBypass -> SetVisibility(kFALSE);
02364
02365 volBypass -> AddNode(volFlange,1,gGeoIdentity);
02366 volFlange -> AddNode(volThroat,1,gGeoIdentity);
02367 volThroat -> AddNode(volCoil,1,new TGeoTranslation(0,-0.01*scale,0));
02368
02369 return volBypass;
02370
02371 }
02372
02373
02374 TGeoVolume* GeoGeometry::BuildNearCoilAirGapVolume() const {
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400 UpdateGlobalManager();
02401
02402 const GeoMediumMap& medMap = GetMediumMap();
02403
02404
02405
02406 std::string preface = "NG";
02407
02408
02409 TGeoVolume* volBypass
02410 = gGeoManager->GetVolume(std::string(preface+"BY").c_str());
02411 if ( volBypass ) return volBypass;
02412
02413 Double_t scale = Geo::GetScale(GetAppType());
02414
02415 TGeoVolume* volWater
02416 = gGeoManager->MakeTube(std::string(preface+"WA").c_str(),
02417 medMap.GetMedium(Geo::kCRGapWater),0,
02418 Geo::kNearCoolRad*scale,-1.);
02419 volWater -> SetLineColor(kGreen);
02420
02421 TGeoVolume* volCoil
02422 = gGeoManager->MakeBox(std::string(preface+"CO").c_str(),
02423 medMap.GetMedium(Geo::kCRGapCoil),
02424 Geo::kCoilRad*scale,Geo::kCoilRad*scale,-1.);
02425 volCoil -> SetLineColor(kBlack);
02426
02427 TGeoVolume* volThroat
02428 = gGeoManager->MakeBox(std::string(preface+"TR").c_str(),
02429 medMap.GetMedium(Geo::kCRGapThroat),
02430 Geo::kThroatRad*scale,Geo::kThroatRad*scale,-1.);
02431 volThroat -> SetLineColor(kBlue);
02432
02433 TGeoVolume* volFlange
02434 = gGeoManager->MakeBox(std::string(preface+"FL").c_str(),
02435 medMap.GetMedium(Geo::kCRGapFlange),
02436 Geo::kFlangeRad*scale,Geo::kFlangeRad*scale,-1.);
02437 volFlange -> SetLineColor(kBlack);
02438
02439 volBypass
02440 = gGeoManager->MakeTube(std::string(preface+"BY").c_str(),
02441 medMap.GetMedium(Geo::kCRGapBypass),0,
02442 Geo::kNearFullBypassRad*scale,-1.);
02443 volBypass -> SetLineColor(kBlue);
02444 volBypass -> SetLineStyle(2);
02445
02446 volBypass -> AddNode(volFlange,1,gGeoIdentity);
02447 volFlange -> AddNode(volThroat,1,gGeoIdentity);
02448
02449 volThroat -> AddNode(volCoil,1,
02450 new TGeoTranslation(-0.01*scale,-0.01*scale,0));
02451
02452 Int_t nx = 6;
02453 Int_t ny = 8;
02454
02455 Float_t xedge = 0.02475*scale;
02456 Float_t x0 = -Geo::kCoilRad*scale + xedge;
02457
02458 Float_t xsep = 2.*(Geo::kCoilRad*scale - xedge)/(Float_t)(nx-1);
02459
02460 Float_t yedge = 0.02221*scale;
02461 Float_t y0 = -Geo::kCoilRad*scale + yedge;
02462
02463 Float_t ysep = 2.*(Geo::kCoilRad*scale - yedge)/(Float_t)(ny-1);
02464
02465 for ( int ix = 0; ix < nx; ix++ ) {
02466 Float_t xpos = x0 + (Float_t)ix*xsep;
02467 for ( int iy = 0; iy < ny; iy++ ) {
02468 Float_t ypos = y0 + (Float_t)iy*ysep;
02469 Int_t itube = ix*ny+iy+1;
02470 volCoil -> AddNode(volWater,itube,new TGeoTranslation(xpos,ypos,0));
02471 }
02472 }
02473
02474 return volBypass;
02475
02476 }