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