00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012 #include <iostream>
00013 #include <cassert>
00014 using namespace std;
00015
00016 #include "TGeoManager.h"
00017 #include "TGeoNode.h"
00018 #include "TGeoBBox.h"
00019
00020 #include "Conventions/Munits.h"
00021 #include "GeoGeometry/Geo.h"
00022 #include "GeoGeometry/GeoGeometry.h"
00023 #include "GeoGeometry/GeoScintPlnVolume.h"
00024 #include "GeoGeometry/GeoSteelPlnVolume.h"
00025 #include "GeoGeometry/GeoStripVolume.h"
00026 #include "GeoGeometry/GeoScintMdlVolume.h"
00027 #include "GeoGeometry/GeoStripNode.h"
00028 #include "GeoGeometry/GeoScintMdlNode.h"
00029 #include "GeoGeometry/GeoScintPlnNode.h"
00030 #include "GeoGeometry/GeoSteelPlnNode.h"
00031 #include "UgliGeometry/UgliDbiTables.h"
00032 #include "UgliGeometry/UgliDbiStructHash.h"
00033 #include "MessageService/MsgService.h"
00034 #include "Plex/PlexVetoShieldHack.h"
00035
00036 ClassImp(GeoGeometry)
00037
00038 CVSID("$Id: GeoGeometry.cxx,v 1.22 2005/06/27 16:47:06 schubert Exp $");
00039
00040
00041 GeoGeometry::GeoGeometry() : fVldRange(),fAppType(Geo::kRecons),
00042 fScale(1),fGeoManager(0) {
00043
00044
00045 UpdateGlobalManager();
00046
00047 for ( int ism = 0; ism < 2; ism++ ) {
00048 fSMZMin[ism] = +999.*fScale;
00049 fSMZMax[ism] = -999.*fScale;
00050 }
00051
00052 MSG("Geo",Msg::kVerbose) << "GeoGeometry def ctor @ " << this << endl;
00053
00054 }
00055
00056
00057 GeoGeometry::GeoGeometry(const VldContext &vldc, Geo::EAppType apptype) :
00058 fVldRange(),fAppType(apptype),fScale(1),fGeoManager(0) {
00059
00060
00061
00062
00063
00064
00065
00066 UpdateGlobalManager();
00067
00068 MSG("Geo",Msg::kVerbose) << "GeoGeometry normal ctor @ " << this << endl;
00069
00070
00071
00072
00073 for ( int ism = 0; ism < 2; ism++ ) {
00074 fSMZMin[ism] = +999.*fScale;
00075 fSMZMax[ism] = -999.*fScale;
00076 }
00077
00078 fScale = Geo::GetScale(apptype);
00079
00080 TString name = vldc.AsString("s1ac-");
00081 fGeoManager = new TGeoManager(name.Data(),"a MINOS geometry");
00082 UpdateGlobalManager();
00083
00084
00085 this -> BuildAll(vldc);
00086 fGeoManager->CloseGeometry();
00087
00088 TGeoVolume* volume = fGeoManager->GetTopVolume();
00089 UpdateNodeMatrices(volume);
00090
00091
00092
00093 fGeoManager->SetVisLevel(3);
00094 fGeoManager->SetVisOption(0);
00095
00096
00097 }
00098
00099
00100 GeoGeometry::~GeoGeometry() {
00101
00102
00103 UpdateGlobalManager();
00104
00105 MSG("Geo",Msg::kVerbose) << "GeoGeometry dtor @ " << this << endl;
00106
00107 fPlaneMap.clear();
00108 if ( fGeoManager ) {
00109 delete fGeoManager; fGeoManager = 0;
00110 }
00111
00112 UpdateGlobalManager();
00113
00114 }
00115
00116
00117 void GeoGeometry::Draw(Option_t* volname) {
00118
00119
00120 UpdateGlobalManager();
00121
00122 std::string volnamestr(volname);
00123 if (volnamestr.empty()) volnamestr = "HALL";
00124
00125 MSG("Geo",Msg::kInfo) << "GeoGeometry::Draw() from top volume "
00126 << volnamestr.empty() << "." << endl;
00127
00128 if ( !fGeoManager ) {
00129 MSG("Geo",Msg::kWarning) << "Null fGeoManager" << endl;
00130 return;
00131 }
00132
00133 TGeoVolume* topVol = fGeoManager -> GetVolume(volnamestr.c_str());
00134 if ( !topVol ) {
00135 MSG("Geo",Msg::kWarning) << "No volume of name " << volnamestr.c_str()
00136 << endl;
00137 return;
00138 }
00139
00140
00141 topVol -> Draw();
00142
00143 }
00144
00145
00146 void GeoGeometry::DumpVolume(std::string volname, std::string preface) const {
00147
00148
00149 UpdateGlobalManager();
00150
00151 TGeoVolume* volume = fGeoManager->GetVolume(volname.c_str());
00152 if ( !volume ) {
00153 cout << "No volume of name " << volname.c_str() << "!" << endl;
00154 return;
00155 }
00156
00157 cout << preface.c_str() << "Volume " << volume->GetName() << ", shape:"
00158 << endl;
00159 cout << preface.c_str();
00160 volume->GetShape()->InspectShape();
00161
00162 Int_t ndaughter = volume -> GetNdaughters();
00163 if ( ndaughter > 0 )
00164 cout << preface.c_str() << ndaughter << " daughter nodes:" << endl;
00165 else
00166 cout << preface.c_str() << "No daughter nodes." << endl;
00167
00168 for ( int id = 0; id < ndaughter; id++ ) {
00169 TGeoNode* daughternode = volume->GetNode(id);
00170 cout << preface.c_str() << " " << id << ")" << daughternode->GetName()
00171 << endl;
00172 cout << preface.c_str() << " ";
00173 daughternode->GetMatrix()->Print();
00174 TGeoVolume* daughtervol = daughternode->GetVolume();
00175 this -> DumpVolume(daughtervol->GetName(),preface+" ");
00176 }
00177
00178 }
00179
00180
00181 std::string GeoGeometry::GetGeoCompatibleName(std::string name) {
00182
00183
00184
00185
00186
00187 std::string okayname = name;
00188
00189
00190 unsigned int ipos = okayname.find("/");
00191 while ( ipos != std::string::npos ) {
00192 okayname.replace(ipos,1,"f");
00193 ipos = okayname.find("/");
00194 }
00195
00196
00197
00198 ipos = okayname.find("-");
00199 while ( ipos != std::string::npos ) {
00200 okayname.replace(ipos,1,"h");
00201 ipos = okayname.find("-");
00202 }
00203
00204 return okayname;
00205 }
00206
00207
00208 TVector3 GeoGeometry::GetHallExtentMin() const {
00209
00210
00211
00212 UpdateGlobalManager();
00213
00214 TGeoVolume* linrVol = fGeoManager->GetVolume("LINR");
00215 GeoNode* hallNode = dynamic_cast<GeoNode*>(linrVol->GetNode(0));
00216 TGeoVolume* hallVol = hallNode -> GetVolume();
00217 TGeoBBox* hallBox = dynamic_cast<TGeoBBox*>(hallVol->GetShape());
00218
00219 TVector3 localXYZ(-(hallBox->GetDX()),-(hallBox->GetDY()),
00220 -(hallBox->GetDZ()));
00221
00222 return (hallNode -> LocalToGlobal(localXYZ));
00223
00224 }
00225
00226
00227 TVector3 GeoGeometry::GetHallExtentMax() const {
00228
00229
00230
00231 UpdateGlobalManager();
00232
00233 TGeoVolume* linrVol = fGeoManager->GetVolume("LINR");
00234 GeoNode* hallNode = dynamic_cast<GeoNode*>(linrVol->GetNode(0));
00235 TGeoVolume* hallVol = hallNode -> GetVolume();
00236 TGeoBBox* hallBox = dynamic_cast<TGeoBBox*>(hallVol->GetShape());
00237
00238 TVector3 localXYZ(+(hallBox->GetDX()),+(hallBox->GetDY()),
00239 +(hallBox->GetDZ()));
00240 return (hallNode -> LocalToGlobal(localXYZ));
00241
00242 }
00243
00244
00245 GeoSteelPlnNode* GeoGeometry::GetNearestSteelPlnNode(Double_t z) {
00246
00247
00248
00249
00250 UpdateGlobalManager();
00251
00252 MSG("Geo",Msg::kDebug) << "GeoGeometry::GetNearestSteelPlnNode to z "
00253 << z << "." << endl;
00254 assert(fGeoManager);
00255
00256 const std::map<Float_t,GeoSteelPlnNode*>& stnodemap = GetSteelPlnNodeMap();
00257
00258
00259
00260 std::map<Float_t,GeoSteelPlnNode*>::const_iterator steelplnItr;
00261
00262
00263 steelplnItr = stnodemap.lower_bound(z);
00264 GeoSteelPlnNode* loplnNode = 0;
00265 GeoSteelPlnNode* hiplnNode = 0;
00266 if ( steelplnItr != stnodemap.end() ) {
00267 hiplnNode = steelplnItr->second;
00268 }
00269 if ( steelplnItr != stnodemap.begin() ) {
00270 steelplnItr--;
00271 loplnNode = steelplnItr->second;
00272 }
00273 if ( hiplnNode == 0 ) return loplnNode;
00274 else if ( loplnNode == 0 ) return hiplnNode;
00275
00276
00277 Double_t xyz_global[3] = {0,0,z};
00278 Double_t lo_xyz_local[3] = {0};
00279 loplnNode->GlobalToLocal(xyz_global,lo_xyz_local);
00280 Double_t hi_xyz_local[3] = {0};
00281 hiplnNode->GlobalToLocal(xyz_global,hi_xyz_local);
00282
00283 if ( TMath::Abs(lo_xyz_local[2]) < TMath::Abs(hi_xyz_local[2]) ) {
00284 return loplnNode;
00285 }
00286
00287 return hiplnNode;
00288
00289 }
00290
00291
00292 PlexPlaneId GeoGeometry::GetPlaneIdFromZ(Double_t z) const {
00293
00294
00295
00296
00297
00298
00299 UpdateGlobalManager();
00300
00301 MSG("Geo",Msg::kDebug) << "GeoGeometry::GetPlaneIdFromZ " << z << "."<< endl;
00302 assert(fGeoManager);
00303
00304 PlexPlaneId invalidplex;
00305
00306
00307 PlaneMapConstItr plnItr;
00308 Double_t xyz_global[3] = {0,0,z};
00309 Double_t xyz_local[3] = {0};
00310
00311
00312 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr) {
00313 if ( (plnItr->first).IsVetoShield() ) continue;
00314 GeoPlnNode* plnNode = dynamic_cast<GeoPlnNode*>(plnItr -> second);
00315 plnNode->GlobalToLocal(xyz_global,xyz_local);
00316 Float_t dz = dynamic_cast<TGeoBBox*>(plnNode->GetVolume()->GetShape())
00317 ->GetDZ();
00318 if ( TMath::Abs(xyz_local[2]) < dz ) {
00319 return plnItr->first;
00320 }
00321 else if ( xyz_local[2] < -dz ) {
00322
00323
00324 return invalidplex;
00325 }
00326 }
00327
00328 return invalidplex;
00329
00330 }
00331
00332
00333 const vector<GeoPlnNode*>& GeoGeometry::GetPlnNodePtrVector() {
00334
00335
00336 UpdateGlobalManager();
00337
00338 if ( fPlnNodes.empty() ) {
00339 PlaneMapConstItr plnItr;
00340 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr) {
00341 GeoPlnNode* plnNode = plnItr->second;
00342 fPlnNodes.push_back(plnNode);
00343 }
00344 }
00345
00346 return fPlnNodes;
00347
00348 }
00349
00350
00351 GeoScintPlnNode* GeoGeometry::GetScintPlnNode(PlexPlaneId planeid) const {
00352
00353
00354 UpdateGlobalManager();
00355
00356 GeoScintPlnNode* plnnode = 0;
00357 if ( planeid.IsSteel() ) {
00358 MSG("Geo",Msg::kWarning)
00359 << "GetScintPlnNode called with steel plane id "
00360 << planeid.AsString() << endl;
00361 return 0;
00362 }
00363
00364 PlaneMapConstItr citr = fPlaneMap.find(planeid);
00365 if ( citr != fPlaneMap.end() ) {
00366 plnnode = dynamic_cast<GeoScintPlnNode*>(citr->second);
00367 }
00368
00369 return plnnode;
00370
00371 }
00372
00373
00374 const vector<GeoScintPlnNode*>& GeoGeometry::GetScintPlnNodePtrVector() {
00375
00376
00377 UpdateGlobalManager();
00378
00379 if ( fScintPlnNodes.empty() ) {
00380 PlaneMapConstItr plnItr;
00381 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr ){
00382 if ( !(plnItr->first).IsSteel() ) {
00383 fScintPlnNodes.push_back(
00384 dynamic_cast<GeoScintPlnNode*>(plnItr->second));
00385 }
00386 }
00387 }
00388
00389 return fScintPlnNodes;
00390
00391 }
00392
00393
00394 GeoSteelPlnNode* GeoGeometry::GetSteelPlnNode(PlexPlaneId planeid) const {
00395
00396
00397 UpdateGlobalManager();
00398
00399 GeoSteelPlnNode* plnnode = 0;
00400 if ( !planeid.IsSteel() ) {
00401 MSG("Geo",Msg::kWarning)
00402 << "GetSteelPlnNode called with non steel plane id "
00403 << planeid.AsString() << endl;
00404 return 0;
00405 }
00406
00407 PlaneMapConstItr citr = fPlaneMap.find(planeid);
00408 if ( citr != fPlaneMap.end() ) {
00409 plnnode = dynamic_cast<GeoSteelPlnNode*>(citr->second);
00410 }
00411
00412 return plnnode;
00413
00414 }
00415
00416
00417 const vector<GeoSteelPlnNode*>& GeoGeometry::GetSteelPlnNodePtrVector() {
00418
00419
00420
00421 UpdateGlobalManager();
00422
00423 if ( fSteelPlnNodes.empty() ) {
00424 PlaneMapConstItr plnItr;
00425 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr ){
00426 if ( (plnItr->first).IsSteel() ) {
00427 fSteelPlnNodes.push_back(
00428 dynamic_cast<GeoSteelPlnNode*>(plnItr->second));
00429 }
00430 }
00431 }
00432
00433 return fSteelPlnNodes;
00434
00435 }
00436
00437
00438 const std::map<Float_t,GeoSteelPlnNode*>& GeoGeometry::GetSteelPlnNodeMap() {
00439
00440
00441
00442 UpdateGlobalManager();
00443
00444 if ( fSteelPlnNodeMap.empty() ) {
00445 PlaneMapConstItr plnItr;
00446 for ( plnItr = fPlaneMap.begin(); plnItr != fPlaneMap.end(); ++plnItr ){
00447 if ( (plnItr->first).IsSteel() ) {
00448
00449 fSteelPlnNodeMap.insert(make_pair(plnItr->second->GetZ0(),
00450 dynamic_cast<GeoSteelPlnNode*>(plnItr->second)));
00451 }
00452 }
00453 }
00454
00455 return fSteelPlnNodeMap;
00456
00457 }
00458
00459
00460 GeoStripNode* GeoGeometry::GetStripNode(const PlexStripEndId& seid) const {
00461
00462
00463 UpdateGlobalManager();
00464
00465 GeoStripNode* stripnode = 0;
00466
00467
00468 GeoScintPlnNode* planenode = this -> GetScintPlnNode(seid);
00469 if ( planenode ) {
00470 stripnode = planenode -> GetStripNode(seid);
00471 }
00472
00473 return stripnode;
00474
00475 }
00476
00477
00478 void GeoGeometry::GetTransverseExtent(PlaneView::PlaneView_t view,
00479 Double_t& tmin, Double_t& tmax) const {
00480
00481
00482
00483
00484 UpdateGlobalManager();
00485
00486 tmin = -999; tmax=-999;
00487
00488 DetectorType::Detector_t detector
00489 = (DetectorType::Detector_t)fVldRange.GetDetectorMask();
00490
00491 switch (detector) {
00492 case DetectorType::kNear:
00493 switch (view ) {
00494 case PlaneView::kU:
00495 tmin = -2.10 * fScale;
00496 tmax = +2.75 * fScale;
00497 case PlaneView::kV:
00498 tmin = -2.75 * fScale;
00499 tmax = +2.10 * fScale;
00500 default:
00501 MSG("Geo",Msg::kError)
00502 << "GeoGeometry::GetTransverseExtent undefined for "
00503 << DetectorType::AsString(detector) << " view "
00504 << PlaneView::AsString(view) << endl;
00505 break;
00506 }
00507 case DetectorType::kFar:
00508 tmin = -4.0 * fScale;
00509 tmax = +4.0 * fScale;
00510 break;
00511 case DetectorType::kCalib:
00512 tmin = -0.5 * fScale;
00513 tmax = +0.5 * fScale;
00514 break;
00515 default:
00516 MSG("Geo",Msg::kError)
00517 << "GeoGeometry::GetTransverseExtent undefined for "
00518 << DetectorType::AsString(detector) << endl;
00519 break;
00520 }
00521
00522 Float_t fuzz = 0.5*Geo::kStripWidth*fScale;
00523 tmin = tmin - fuzz;
00524 tmax = tmax + fuzz;
00525
00526 return;
00527
00528 }
00529
00530
00531 void GeoGeometry::GetTransverseExtent(PlaneView::PlaneView_t view,
00532 Float_t& tmin, Float_t& tmax) const {
00533
00534
00535
00536 UpdateGlobalManager();
00537
00538 Double_t tmind,tmaxd;
00539 GetTransverseExtent(view,tmind,tmaxd);
00540 tmin = (Float_t)tmind;
00541 tmax = (Float_t)tmaxd;
00542
00543 return;
00544
00545 }
00546
00547
00548 void GeoGeometry::GetZExtent(Double_t& zmin, Double_t& zmax, Int_t isup) const{
00549
00550
00551
00552 UpdateGlobalManager();
00553
00554
00555 zmax =-999999;
00556 zmin =+999999;
00557 if ( isup < 0 ) {
00558 zmin = fSMZMin[0];
00559 if ( fSMZMax[1] > 0 ) zmax = fSMZMax[1];
00560 else zmax = fSMZMax[0];
00561 }
00562 else if ( isup < 2 ) {
00563 zmin = fSMZMin[isup];
00564 zmax = fSMZMax[isup];
00565 }
00566 else {
00567 MSG("Geo",Msg::kWarning) << "GetZExtent failed. SuperModule "
00568 << isup << " undefined." << endl;
00569 }
00570
00571 return;
00572
00573
00574 }
00575
00576
00577 void GeoGeometry::GetZExtent(Float_t& zmin, Float_t& zmax, Int_t isup) const {
00578
00579
00580
00581 UpdateGlobalManager();
00582
00583 Double_t zmind,zmaxd;
00584 GetZExtent(zmind,zmaxd,isup);
00585 zmin = (Float_t)zmind;
00586 zmax = (Float_t)zmaxd;
00587
00588 return;
00589 }
00590
00591
00592 bool GeoGeometry::IsCompatible(const VldContext& vldc, Geo::EAppType apptype)
00593 const {
00594
00595
00596 UpdateGlobalManager();
00597
00598 bool iscompatible = false;
00599 if ( fVldRange.IsCompatible(vldc) && fAppType == apptype )
00600 iscompatible = true;
00601 return iscompatible;
00602 }
00603
00604
00605 void GeoGeometry::ls(Option_t *option) const {
00606
00607
00608 UpdateGlobalManager();
00609
00610 fGeoManager->ls(option);
00611
00612 }
00613
00614
00615 void GeoGeometry::Print(Option_t* option) const {
00616
00617
00618 UpdateGlobalManager();
00619
00620 std::string stoption(option);
00621 DumpVolume(stoption);
00622
00623 cout << "GeoGeometry::Print\n"
00624 << fVldRange.AsString() << endl;
00625 if ( fGeoManager )
00626 cout << "GeoManager " << fGeoManager->GetName()
00627 << "," << fGeoManager->GetTitle() << endl;
00628 else
00629 cout << "GeoManager not initialized." << endl;
00630
00631 }
00632
00633
00634
00635 void GeoGeometry::BuildAll(const VldContext &vldc) {
00636
00637
00638 UpdateGlobalManager();
00639
00640 MSG("Geo",Msg::kVerbose) << "GeoGeometry BuildAll " << endl;
00641 assert(fGeoManager);
00642
00643
00644 BuildVldRange(vldc);
00645
00646 if (vldc.GetDetector() == DetectorType::kUnknown) {
00647 MSG("Geo",Msg::kWarning)
00648 << "no possibility of building a geometry for " << endl
00649 << " VldContext: " << vldc << endl;
00650 return;
00651 }
00652
00653
00654 BuildMaterials(vldc);
00655
00656
00657 BuildGeometry(vldc);
00658
00659 }
00660
00661
00662 void GeoGeometry::BuildVldRange(const VldContext &vldc) {
00663
00664
00665 UpdateGlobalManager();
00666
00667 MSG("Geo",Msg::kDebug) << "GeoGeometry BuildVldRange " << endl;
00668
00669
00670 VldTimeStamp starttime = VldTimeStamp((time_t)0,0);
00671 VldTimeStamp endtime = VldTimeStamp(2038,1,18,0,0,0);
00672 fVldRange = VldRange(vldc.GetDetector(),vldc.GetSimFlag(),
00673 starttime,endtime,"DBI");
00674
00675 DbiResultPtr<UgliDbiSteelPln> steelTbl(vldc);
00676 TrimVldRange("UgliDbiSteelPln",steelTbl.GetValidityRec());
00677
00678 DbiResultPtr<UgliDbiScintPlnStruct> scintStructTbl(vldc);
00679 TrimVldRange("UgliDbiScintPlnStruct",scintStructTbl.GetValidityRec());
00680
00681 DbiResultPtr<UgliDbiScintPln> scintTbl(vldc);
00682 TrimVldRange("UgliDbiScintPln",scintTbl.GetValidityRec());
00683
00684 DbiResultPtr<UgliDbiScintMdlStruct> mdlStructTbl(vldc);
00685 TrimVldRange("UgliDbiScintMdlStruct",mdlStructTbl.GetValidityRec());
00686
00687 DbiResultPtr<UgliDbiScintMdl> mdlTbl(vldc);
00688 TrimVldRange("UgliDbiScintMdl",mdlTbl.GetValidityRec());
00689
00690 DbiResultPtr<UgliDbiStripStruct> stripStructTbl(vldc);
00691 TrimVldRange("UgliDbiStripStruct",stripStructTbl.GetValidityRec());
00692
00693 DbiResultPtr<UgliDbiStrip> stripTbl(vldc);
00694 TrimVldRange("UgliDbiStrip",stripTbl.GetValidityRec());
00695
00696 }
00697
00698
00699 void GeoGeometry::TrimVldRange(const char* tblName,
00700 const DbiValidityRec* dbivrec) {
00701
00702
00703 UpdateGlobalManager();
00704
00705 if ( dbivrec ) {
00706 fVldRange.TrimTo(dbivrec->GetVldRange());
00707 }
00708 else {
00709 MSG("Geo",Msg::kWarning) << "No DbiValidityRec for table " << tblName
00710 << endl;
00711 }
00712
00713 }
00714
00715
00716 void GeoGeometry::BuildMaterials(const VldContext& ) {
00717
00718
00719 UpdateGlobalManager();
00720
00721 MSG("Geo",Msg::kVerbose) << "GeoGeometry BuildMaterials " << endl;
00722 assert(fGeoManager);
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 TGeoMaterial *mat1 = new TGeoMaterial("ALUMINIUM",26.98,13,2.7);
00736 mat1->SetUniqueID( 1);
00737 new TGeoMedium("ALUMINIUM",1,1,0,0,0,20,0.1000000E+11,0.1829598,
00738 0.1000000E-03,0.2236820E-01);
00739
00740 TGeoMaterial *mat2 = new TGeoMaterial("IRON",55.85,26,7.87);
00741 mat2->SetUniqueID( 2);
00742 new TGeoMedium("IRON",2,2,0,1,20,20,0.1000000E+11,0.25,
00743 0.1000000E-02,0.1952315E-01);
00744 new TGeoMedium("STEEL",3,2,0,0,20,20,0.1000000E+11,0.25,
00745 0.1000000E-02,0.1952315E-01);
00746
00747 TGeoMixture *mat3 = new TGeoMixture("AIR",2,0.1205000E-02);
00748 mat3->SetUniqueID( 3);
00749 mat3->DefineElement(0,14.01,7,0.7);
00750 mat3->DefineElement(1,16.00,8,0.3);
00751 new TGeoMedium("AIR",4,3,0,0,0,20,0.1000000E+11,0.2488534,
00752 0.1000000E-03,0.7712014);
00753
00754 TGeoMixture *mat4 = new TGeoMixture("CONCRETE",6, 2.50000 );
00755 mat4->SetUniqueID( 4);
00756 mat4->DefineElement(0,16,8,0.53);
00757 mat4->DefineElement(1,28.09,14,0.33);
00758 mat4->DefineElement(2,40.078,20,0.6300000E-01);
00759 mat4->DefineElement(3,22.99,11,0.1500000E-01);
00760 mat4->DefineElement(4,55.85,26,0.2000000E-01);
00761 mat4->DefineElement(5,26.98,13,0.4200000E-01);
00762 new TGeoMedium("CONCRETE",5,4,0,0,0,20,0.1000000E+11,0.1880915,
00763 0.1000000E-03,0.2108371E-01);
00764
00765 TGeoMixture *mat5 = new TGeoMixture("ROCK",6, 2.50000 );
00766 mat5->SetUniqueID( 5);
00767 mat5->DefineElement(0,16,8,0.53);
00768 mat5->DefineElement(1,28.09,14,0.33);
00769 mat5->DefineElement(2,40.078,20,0.6300000E-01);
00770 mat5->DefineElement(3,22.99,11,0.1500000E-01);
00771 mat5->DefineElement(4,55.85,26,0.2000000E-01);
00772 mat5->DefineElement(5,26.98,13,0.4200000E-01);
00773 new TGeoMedium("ROCK",6,5,0,0,0,20,0.1000000E+11,0.1880915,
00774 0.1000000E-03,0.2108371E-01);
00775
00776 TGeoMixture *mat6 = new TGeoMixture("PSTYRENE SCINT",2, 1.03200 );
00777 mat6->SetUniqueID( 6);
00778 mat6->DefineElement(0,1.00794,1,0.7742105E-01);
00779 mat6->DefineElement(1,12.011,6,0.9225789);
00780 new TGeoMedium("PSTYRENE SCINT",7,6,2,0,0,20,0.1000000E+11,0.3084481E-01,
00781 0.1000000E-03,0.8242410E-02);
00782
00783 TGeoMixture *mat7 = new TGeoMixture("COEX TIO2 PSTYRENE",4, 1.03200 );
00784 mat7->SetUniqueID( 7);
00785 mat7->DefineElement(0,1.00794,1,0.6967895E-01);
00786 mat7->DefineElement(1,12.011,6,0.8303211);
00787 mat7->DefineElement(2,44.88,22,0.5837760E-01);
00788 mat7->DefineElement(3,15.9994,8,0.4162240E-01);
00789 new TGeoMedium("COEX TIO2 PSTYRENE",8,7,0,0,0,20,0.1000000E+11,0.217354,
00790 0.1000000E-03,0.2307702E-01);
00791
00792 TGeoMixture *mat8 = new TGeoMixture("FARCOIL",5, 2.34881 );
00793 mat8->SetUniqueID( 8);
00794 mat8->DefineElement(0,1.00794,1,0.1281415E-01);
00795 mat8->DefineElement(1,12.0107,6,0.6021570E-01);
00796 mat8->DefineElement(2,14.00674,7,0.1974151E-03);
00797 mat8->DefineElement(3,15.9994,8,0.2134690E-01);
00798 mat8->DefineElement(4,63.546,29,0.9054258);
00799 new TGeoMedium("FARCOIL",9,8,0,0,0,20,0.1000000E+11,0.1673649,
00800 0.1000000E-03,0.3520523E-01);
00801
00802
00803 return;
00804
00805 }
00806
00807
00808 void GeoGeometry::BuildGeometry(const VldContext& vldc) {
00809
00810
00811 UpdateGlobalManager();
00812
00813 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildGeometry" << endl;
00814 assert(fGeoManager);
00815
00816 const UgliDbiTables& ugliDbiTables = UgliDbiTables(vldc);
00817 const UgliDbiGeometry* ugliDbiGeo = ugliDbiTables.GetDbiGeometry();
00818 if (!ugliDbiGeo) {
00819 MSG("Geo",Msg::kFatal)
00820 << "No UgliDbiGeometry for " << vldc << endl;
00821 abort();
00822 }
00823
00824
00825 const Float_t* hmin = ugliDbiGeo->GetHallXYZMin();
00826 const Float_t* hmax = ugliDbiGeo->GetHallXYZMax();
00827
00828
00829 const Double_t xypad = 0.*fScale;
00830 Double_t hminsc[3] = {hmin[0]*fScale,hmin[1]*fScale,hmin[2]*fScale};
00831 Double_t hmaxsc[3] = {hmax[0]*fScale,hmax[1]*fScale,hmax[2]*fScale};
00832
00833
00834 Double_t xhsiz = 0.5*(hmaxsc[0] - hminsc[0]) + xypad;
00835 Double_t yhsiz = 0.5*(hmaxsc[1] - hminsc[1]) + xypad;
00836 Double_t zhsiz = 0.5*(hmaxsc[2] - hminsc[2]);
00837
00838
00839 Double_t x0hall = 0.5*(hmaxsc[0] + hminsc[0]);
00840 Double_t y0hall = 0.5*(hmaxsc[1] + hminsc[1]);
00841 Double_t z0hall = 0.5*(hmaxsc[2] + hminsc[2]);
00842
00843 MSG("Geo",Msg::kDebug) << "Hall halfwidths " << xhsiz << ","
00844 << yhsiz << "," << zhsiz << " placed at "
00845 << x0hall << "," << y0hall << "," << z0hall << endl;
00846
00847
00848
00849 TGeoMedium* medAIR = fGeoManager->GetMedium("AIR");
00850 TGeoVolume* volHALL = fGeoManager->MakeBox("HALL",medAIR,
00851 xhsiz,yhsiz,zhsiz);
00852 volHALL-> SetVisibility(kTRUE);
00853 volHALL-> SetLineColor(kGreen);
00854
00855
00856
00857 const Double_t linerpad = 1.0*fScale;
00858 TGeoMedium* medCONCRETE = fGeoManager->GetMedium("CONCRETE");
00859 TGeoVolume* volLINR = fGeoManager->MakeBox("LINR",medCONCRETE,
00860 xhsiz+linerpad,yhsiz+linerpad,
00861 zhsiz+linerpad);
00862 volLINR-> SetVisibility(kTRUE);
00863 volLINR-> SetLineColor(kYellow);
00864
00865
00866
00867 const Double_t rockpad = 5.0*fScale;
00868 Double_t absxmax = TMath::Max(TMath::Abs(hminsc[0]-xypad),
00869 TMath::Abs(hmaxsc[0]+xypad));
00870 Double_t absymax = TMath::Max(TMath::Abs(hminsc[1]-xypad),
00871 TMath::Abs(hmaxsc[1]+xypad));
00872 Double_t abszmax = TMath::Max(TMath::Abs(hminsc[2]),
00873 TMath::Abs(hmaxsc[2]));
00874 TGeoMedium* medROCK = fGeoManager->GetMedium("ROCK");
00875 TGeoVolume* volMARS = fGeoManager->MakeBox("MARS",medROCK,
00876 absxmax+rockpad,absymax+rockpad,
00877 abszmax+rockpad);
00878 volMARS -> SetVisibility(kTRUE);
00879 volMARS -> SetLineColor(kBlack);
00880
00881
00882
00883 fGeoManager -> SetTopVolume(volMARS);
00884
00885 std::string nodename = "LINR_1";
00886 std::string globalpath = "/MARS_1/" + nodename;
00887 new GeoNode(this,volLINR,new TGeoTranslation("LINR",x0hall,y0hall,z0hall),
00888 volMARS,globalpath,nodename);
00889
00890 nodename = "HALL_1";
00891 globalpath += "/" + nodename;
00892 GeoNode* hallNode = new GeoNode(this,volHALL,gGeoIdentity,
00893 volLINR,globalpath,nodename);
00894
00895 BuildDetector(vldc,hallNode);
00896
00897 }
00898
00899
00900 void GeoGeometry::BuildDetector(const VldContext& vldc,
00901 const GeoNode* hallNode) {
00902
00903
00904 UpdateGlobalManager();
00905
00906 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildPlanes " << endl;
00907 assert(fGeoManager);
00908
00909 DbiResultPtr<UgliDbiSteelPln> steelTbl(vldc);
00910 const UgliDbiTables& ugliDbiTables = UgliDbiTables(vldc);
00911
00912 TGeoVolume* hallVol = hallNode -> GetVolume();
00913 std::string hallPath = hallNode -> GetGlobalPath();
00914
00915
00916
00917
00918
00919 TGeoNode* linrNode = fGeoManager->GetVolume("MARS")->GetNode(0);
00920 const Double_t* h0 = linrNode -> GetMatrix() -> GetTranslation();
00921
00922 TGeoMedium* steelMed = fGeoManager -> GetMedium("IRON");
00923 TGeoMedium* airMed = fGeoManager -> GetMedium("AIR");
00924
00925
00926 BuildStripVolumes(vldc);
00927
00928 Int_t plnMin[2] = {-1};
00929 Int_t plnMax[2] = {-1};
00930 Int_t nSM = GetSMPlaneLimits(vldc,plnMin,plnMax);
00931
00932
00933
00934 Float_t detx0 = 0;
00935 Float_t dety0 = 0;
00936
00937 for (unsigned int irow=0; irow < steelTbl.GetNumRows(); ++irow) {
00938
00939
00940
00941
00942
00943 GeoSteelPlnVolume* stplnVolume = 0;
00944 const UgliDbiSteelPln* stRow = steelTbl.GetRow(irow);
00945 PlexPlaneId steelId = stRow -> GetPlaneId();
00946 std::string stName = GetGeoCompatibleName(steelId.AsString());
00947
00948 if ( steelId.IsVetoShield() ) steelId =
00949 PlexVetoShieldHack::RenumberMuxToMdl(vldc,steelId);
00950 else if ( steelId.GetPlane() > 485 ) continue;
00951
00952
00953 if ( TMath::Abs(stRow->GetX0() ) > 50. ) continue;
00954
00955 if ( irow % 20 == 0 ) {
00956 MSG("Geo",Msg::kInfo) << "Building steel row "<< stName.c_str()<< endl;
00957 }
00958
00959 Float_t pairhalfx = 0;
00960 Float_t pairhalfy = 0;
00961 Float_t pairhalfz = 0.5*(stRow->GetTotalZ())*fScale;
00962
00963 if ( !steelId.IsVetoShield() ) {
00964 stplnVolume = new GeoSteelPlnVolume(this,steelId,
00965 stRow->GetThickness()*fScale,steelMed);
00966 stplnVolume -> SetLineColor(kRed);
00967 stplnVolume -> SetVisibility(kTRUE);
00968
00969 pairhalfx = dynamic_cast<TGeoBBox*>(stplnVolume->GetShape())->GetDX();
00970
00971
00972
00973
00974 if ( vldc.GetDetector() == Detector::kNear ) pairhalfx +=
00975 fScale*TMath::Abs(Geo::kNearXOffset);
00976 pairhalfy = dynamic_cast<TGeoBBox*>(stplnVolume->GetShape())->GetDY();
00977 }
00978
00979
00980 GeoScintPlnVolume* scplnVolume = 0;
00981 const UgliDbiScintPln* scRow = 0;
00982 PlexPlaneId scintId = steelId;
00983 scintId.SetIsSteel(false);
00984 std::string scName = GetGeoCompatibleName(scintId.AsString());
00985 if ( PlaneCoverage::kNoActive != steelId.GetPlaneCoverage() &&
00986 PlaneCoverage::kUnknown != steelId.GetPlaneCoverage() ) {
00987 MSG("Geo",Msg::kVerbose) << "scint pln name " << scName.c_str()
00988 << endl;
00989 scRow = ugliDbiTables.GetDbiScintPlnByIndex(scintId.GetPlane());
00990
00991 scplnVolume = new GeoScintPlnVolume(this,scintId,
00992 scRow->GetThickness()*fScale,
00993 airMed);
00994 scplnVolume -> SetVisibility(kFALSE);
00995 scplnVolume -> SetLineColor(kBlue);
00996
00997
00998
00999 pairhalfx = TMath::Max(pairhalfx,(Float_t)dynamic_cast<TGeoBBox*>
01000 (scplnVolume->GetShape())->GetDX());
01001 pairhalfy = TMath::Max(pairhalfy,(Float_t)dynamic_cast<TGeoBBox*>
01002 (scplnVolume->GetShape())->GetDY());
01003 }
01004
01005
01006 std::string pairName = GetGeoCompatibleName(steelId.AsString("b"));
01007 TGeoVolume* pairVol = fGeoManager->MakeBox(pairName.c_str(),airMed,
01008 pairhalfx,pairhalfy,pairhalfz);
01009 pairVol -> SetVisibility(kFALSE);
01010 pairVol -> VisibleDaughters(kTRUE);
01011
01012 TGeoRotation* stRotMatrix = new TGeoRotation(pairName.c_str(),
01013 stRow->GetThetaDeg(0),stRow->GetPhiDeg(0),
01014 stRow->GetThetaDeg(1),stRow->GetPhiDeg(1),
01015 stRow->GetThetaDeg(2),stRow->GetPhiDeg(2));
01016 stRotMatrix -> RegisterYourself();
01017
01018
01019
01020 Float_t x0pair = (stRow->GetX0())*fScale - h0[0];
01021 Float_t y0pair = (stRow->GetY0())*fScale - h0[1];
01022 Float_t z0pair = (stRow->GetZBack()-0.5*(stRow->GetTotalZ()))*fScale-h0[2];
01023 TGeoCombiTrans* pairMatrix = new TGeoCombiTrans(pairName.c_str(),
01024 x0pair,y0pair,z0pair,stRotMatrix);
01025 MSG("Geo",Msg::kDebug) << "Placing plane pair at " << x0pair << ","
01026 << y0pair << "," << z0pair << endl;
01027
01028 std::string pairPath = hallPath + "/" + pairName+"_1";
01029 new GeoNode(this,pairVol,pairMatrix,hallVol,pairPath,pairName+"_1");
01030
01031 if ( stplnVolume ) {
01032
01033 std::string stplnNodeName = stName + "_1";
01034 std::string steelPlnPath = pairPath + "/" + stplnNodeName;
01035 new GeoSteelPlnNode(this,stplnVolume,
01036 new TGeoTranslation(stName.c_str(),0.,0.,
01037 0.5*(stRow->GetTotalZ()-stRow->GetThickness())*fScale),pairVol,
01038 steelPlnPath,stplnNodeName,steelId);
01039 int iSM = 0;
01040 if ( nSM > 1 && steelId.GetPlane() > plnMax[0] ) iSM = 1;
01041 detx0 = x0pair;
01042 dety0 = y0pair;
01043
01044 fSMZMin[iSM] = TMath::Min(fSMZMin[iSM],(stRow->GetZBack()
01045 -stRow->GetTotalZ())*fScale);
01046 fSMZMax[iSM] = TMath::Max(fSMZMax[iSM],(stRow->GetZBack())*fScale);
01047
01048 }
01049
01050 if ( scplnVolume ) {
01051
01052 Float_t x0pln = (scRow->GetX0RelSteel())*fScale;
01053 Float_t y0pln = (scRow->GetY0RelSteel())*fScale;
01054 Float_t z0pln = 0.5*(-stRow->GetTotalZ()+scRow->GetThickness())*fScale;
01055
01056 MSG("Geo",Msg::kVerbose) << "Placing scint pln at " << x0pln << ", "
01057 << y0pln << "," << z0pln << endl;
01058
01059
01060
01061
01062
01063 Double_t zrotrelsteel = scRow->GetZRotRelSteelDeg();
01064 TGeoRotation* scRotMatrix = new TGeoRotation(scName.c_str(),90.,
01065 zrotrelsteel,90.,90.+zrotrelsteel,0.,0.);
01066 scRotMatrix -> RegisterYourself();
01067 TGeoCombiTrans* combiMatrix
01068 = new TGeoCombiTrans(scName.c_str(),x0pln,y0pln,z0pln,scRotMatrix);
01069
01070 std::string scplnNodeName = scName + "_1";
01071 std::string scintPlnPath = pairPath + "/" + scplnNodeName;
01072 GeoScintPlnNode* scplnNode
01073 = new GeoScintPlnNode(this,scplnVolume,combiMatrix,pairVol,
01074 scintPlnPath,scplnNodeName,scintId);
01075
01076 this -> BuildModules(ugliDbiTables, scplnNode);
01077 }
01078 }
01079
01080
01081
01082 DetectorType::Detector_t dettype = (DetectorType::Detector_t)
01083 vldc.GetDetector();
01084 switch ( dettype ) {
01085 case DetectorType::kFar:
01086 BuildFarCoil(hallNode,detx0,dety0);
01087 break;
01088 case DetectorType::kNear:
01089 BuildNearCoil(hallNode,detx0,dety0);
01090 break;
01091 default:
01092 break;
01093 }
01094
01095 return;
01096
01097 }
01098
01099
01100 Int_t GeoGeometry::GetSMPlaneLimits(const VldContext& vldc,
01101 Int_t* plnMin, Int_t* plnMax) {
01102
01103
01104
01105
01106
01107 DetectorType::Detector_t dettype = vldc.GetDetector();
01108 Int_t nSM = 0;
01109 switch (dettype) {
01110 case Detector::kFar:
01111 nSM = 2;
01112 plnMin[0] = 0;
01113 plnMax[0] = 248;
01114 plnMin[1] = 249;
01115 plnMax[1] = 485;
01116 break;
01117 case Detector::kNear:
01118 nSM = 1;
01119 plnMin[0] = 0;
01120 plnMax[0] = 281;
01121 break;
01122 case Detector::kCalDet:
01123 nSM = 1;
01124 plnMin[0] = 0;
01125 plnMax[0] = 60;
01126 break;
01127 default:
01128 MSG("Geo",Msg::kError)
01129 << "GetSMPlaneLimits failed for unknown detector type\n"
01130 << DetectorType::AsString(dettype) << "." << endl;
01131 }
01132
01133 return nSM;
01134
01135 }
01136
01137
01138 void GeoGeometry::BuildNearCoil(const TGeoNode* hallNode,
01139 Float_t x0, Float_t y0) {
01140
01141
01142
01143
01144 UpdateGlobalManager();
01145
01146 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildNearCoil " << endl;
01147 assert(fGeoManager);
01148
01149 TGeoMedium* medSTEEL = fGeoManager->GetMedium("STEEL");
01150 TGeoMedium* medAIR = fGeoManager->GetMedium("AIR");
01151 TGeoMedium* medAL = fGeoManager->GetMedium("ALUMINIUM");
01152
01153 TGeoVolume* hallVol = hallNode -> GetVolume();
01154
01155
01156 Float_t shalfx = Geo::kNearSteelHoleHalfWidth*fScale;
01157 Float_t shalfy = shalfx;
01158 Float_t ahalfx = 0.13*fScale;
01159 Float_t ahalfy = ahalfx;
01160 Float_t alhalfx = 0.1118*fScale;
01161 Float_t alhalfy = 0.1143*fScale;
01162
01163
01164 Float_t zmin,zmax;
01165 GetZExtent(zmin,zmax,-1);
01166
01167 TGeoNode* linrNode = fGeoManager->GetVolume("MARS")->GetNode(0);
01168 const Double_t* h0 = linrNode -> GetMatrix() -> GetTranslation();
01169 zmin -= h0[2];
01170 zmax -= h0[2];
01171
01172 Float_t zcoillen = zmax - zmin;
01173 TGeoVolume* BUS0 = fGeoManager->MakeBox("BUS0",medSTEEL,
01174 shalfx,shalfy,0.5*zcoillen);
01175 BUS0 -> SetLineColor(14);
01176 BUS0 -> SetVisibility(kTRUE);
01177
01178 TGeoVolume* BUA0 = fGeoManager->MakeBox("BUA0",medAIR,
01179 ahalfx,ahalfy,0.5*zcoillen);
01180 BUA0 -> SetLineColor(14);
01181 BUA0 -> SetVisibility(kTRUE);
01182 BUS0 -> AddNode(BUA0,1,gGeoIdentity);
01183
01184 TGeoVolume* BUC0 = fGeoManager->MakeBox("BUC0",medAL,
01185 alhalfx,alhalfy,0.5*zcoillen);
01186 BUC0 -> SetLineColor(14);
01187 BUC0 -> SetVisibility(kTRUE);
01188 BUA0 -> AddNode(BUC0,1,gGeoIdentity);
01189
01190
01191
01192 TGeoRotation *rot45 = new TGeoRotation("BUS0",90,45,90,135,0,0);
01193 rot45 -> RegisterYourself();
01194 Float_t xcoil = x0;
01195 Float_t ycoil = y0;
01196 Float_t zcoil = (zmin+zmax)/2.;
01197 hallVol -> AddNode(BUS0,1,new TGeoCombiTrans(xcoil,ycoil,zcoil,rot45));
01198
01199
01200 Float_t steelhalfy = 1.9*fScale;
01201 xcoil = x0 - steelhalfy;
01202 ycoil = y0 - steelhalfy;
01203 hallVol -> AddNode(BUS0,2,new TGeoCombiTrans(xcoil,ycoil,zcoil,rot45));
01204
01205
01206 Float_t cos45 = 0.707107;
01207 Float_t coillenxy = steelhalfy/cos45 + 2.*shalfx;
01208 TGeoVolume* BUSXY = fGeoManager->MakeBox("BUSXY",medSTEEL,
01209 shalfx,0.5*coillenxy,shalfy);
01210 BUSXY -> SetLineColor(14);
01211 BUSXY -> SetVisibility(kTRUE);
01212 TGeoVolume* BUAXY = fGeoManager->MakeBox("BUAXY",medAIR,
01213 ahalfx,0.5*coillenxy,ahalfy);
01214 BUAXY -> SetLineColor(14);
01215 BUAXY -> SetVisibility(kTRUE);
01216 BUSXY -> AddNode(BUAXY,1,gGeoIdentity);
01217
01218 TGeoVolume* BUCXY = fGeoManager->MakeBox("BUCXY",medAL,
01219 alhalfx,0.5*coillenxy,alhalfy);
01220 BUCXY -> SetLineColor(14);
01221 BUCXY -> SetVisibility(kTRUE);
01222 BUAXY -> AddNode(BUCXY,1,gGeoIdentity);
01223
01224
01225 TGeoRotation *rotneg45 = new TGeoRotation("BUSXY",90,315,90,45,0,0);
01226 rotneg45 -> RegisterYourself();
01227 xcoil = x0 - (0.5*coillenxy - shalfx)*cos45;
01228 ycoil = y0 - (0.5*coillenxy - shalfy)*cos45;
01229 zcoil = zmin - shalfy;
01230 hallVol -> AddNode(BUSXY,1,new TGeoCombiTrans(xcoil,ycoil,zcoil,rotneg45));
01231
01232 zcoil = zmax + shalfy;
01233 hallVol -> AddNode(BUSXY,2,new TGeoCombiTrans(xcoil,ycoil,zcoil,rotneg45));
01234
01235 return;
01236
01237 }
01238
01239
01240 void GeoGeometry::BuildFarCoil(const TGeoNode* hallNode,
01241 Float_t x0, Float_t y0) {
01242
01243
01244
01245
01246 UpdateGlobalManager();
01247
01248 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildFarCoil " << endl;
01249 assert(fGeoManager);
01250
01251
01252
01253 Float_t deltay = 5.*fScale;
01254
01255
01256
01257 TGeoMedium* medFARCOIL = fGeoManager->GetMedium("FARCOIL");
01258 TGeoMedium* medSTEEL = fGeoManager->GetMedium("STEEL");
01259
01260 TGeoVolume* hallVol = hallNode -> GetVolume();
01261
01262
01263 Float_t sRad = Geo::kFarSteelHoleRad*fScale;
01264 Float_t cRad = 0.125*fScale;
01265
01266
01267 Float_t zmin0,zmax0;
01268 GetZExtent(zmin0,zmax0,0);
01269
01270 TGeoNode* linrNode = fGeoManager->GetVolume("MARS")->GetNode(0);
01271 const Double_t* h0 = linrNode -> GetMatrix() -> GetTranslation();
01272 zmin0 -= h0[2];
01273 zmax0 -= h0[2];
01274
01275 Float_t zcoillen0 = zmax0-zmin0;
01276 TGeoVolume* BUS0=fGeoManager->MakeTube("BUS0",medSTEEL,0,sRad,0.5*zcoillen0);
01277 BUS0 -> SetLineColor(14);
01278 BUS0 -> SetVisibility(kTRUE);
01279 TGeoVolume* BUC0=fGeoManager->MakeTube("BUC0",medFARCOIL,0,cRad,
01280 0.5*zcoillen0);
01281 BUC0 -> SetLineColor(14);
01282 BUC0 -> SetVisibility(kTRUE);
01283 BUS0 -> AddNode(BUC0,1,gGeoIdentity);
01284
01285
01286 Float_t z0 = 0.5*(zmin0 + zmax0);
01287 hallVol -> AddNode(BUS0,1,new TGeoTranslation("BUS0",x0,y0,z0));
01288
01289 hallVol -> AddNode(BUC0,1,new TGeoTranslation("BUC0",x0,y0-deltay,z0));
01290
01291
01292 Float_t zmin1,zmax1;
01293 GetZExtent(zmin1,zmax1,1);
01294
01295 zmin1 -= h0[2];
01296 zmax1 -= h0[2];
01297
01298 Float_t zcoillen1 = zmax1-zmin1;
01299 TGeoVolume* BUS1=fGeoManager->MakeTube("BUS1",medSTEEL,0,sRad,0.5*zcoillen1);
01300 BUS1 -> SetLineColor(14);
01301 BUS1 -> SetVisibility(kTRUE);
01302 TGeoVolume* BUC1=fGeoManager->MakeTube("BUC1",medFARCOIL,
01303 0,cRad,0.5*zcoillen1);
01304 BUC1 -> SetLineColor(14);
01305 BUC1 -> SetVisibility(kTRUE);
01306 BUS1 -> AddNode(BUC1,1,gGeoIdentity);
01307
01308
01309 Float_t z1 = 0.5*(zmin1 + zmax1);
01310 hallVol -> AddNode(BUS1,1,new TGeoTranslation("BUS1",x0,y0,z1));
01311
01312 hallVol -> AddNode(BUC1,1,new TGeoTranslation("BUC1",x0,y0-deltay,z1));
01313
01314
01315 Float_t ycoillen = deltay + 2.*cRad;
01316 TGeoVolume* BUXY=fGeoManager->MakeTube("BUXY",medFARCOIL,
01317 0,cRad,0.5*ycoillen);
01318 BUXY -> SetLineColor(14);
01319 BUXY -> SetVisibility(kTRUE);
01320
01321
01322 TGeoRotation *rot90 = new TGeoRotation("BUXY",90,0,180,0,90,90);
01323 rot90 -> RegisterYourself();
01324
01325 Float_t xcoil = x0;
01326 Float_t ycoil = (y0 + cRad) - ycoillen/2.;
01327 hallVol -> AddNode(BUXY,1,
01328 new TGeoCombiTrans("BUXY_1",xcoil,ycoil,zmin0-cRad,rot90));
01329 hallVol -> AddNode(BUXY,2,
01330 new TGeoCombiTrans("BUXY_2",xcoil,ycoil,zmax0+cRad,rot90));
01331 hallVol -> AddNode(BUXY,3,
01332 new TGeoCombiTrans("BUXY_3",xcoil,ycoil,zmin1-cRad,rot90));
01333 hallVol -> AddNode(BUXY,4,
01334 new TGeoCombiTrans("BUXY_4",xcoil,ycoil,zmax1+cRad,rot90));
01335
01336 return;
01337
01338 }
01339
01340
01341 void GeoGeometry::BuildModules(const UgliDbiTables& ugliDbiTables,
01342 GeoScintPlnNode* plnNode) {
01343
01344
01345 UpdateGlobalManager();
01346
01347 assert(fGeoManager);
01348
01349 TGeoMedium* medAL = fGeoManager -> GetMedium("ALUMINIUM");
01350 TGeoMedium* medAIR = fGeoManager -> GetMedium("AIR");
01351
01352 const PlexPlaneId& plexPlaneId = plnNode -> GetPlexPlaneId();
01353 MSG("Geo",Msg::kDebug) <<"GeoGeometry::BuildModules for scint pln "
01354 << plnNode->GetName() << endl;
01355
01356
01357 std::string plnPath = plnNode->GetGlobalPath();
01358
01359
01360 UgliDbiStructHash planestructhash(plexPlaneId);
01361 const UgliDbiScintPlnStruct* plnStruct = ugliDbiTables.fScintPlnStructTbl
01362 .GetRowByIndex(planestructhash.HashAsPlane());
01363 Int_t nmodules = plnStruct -> GetNModules();
01364
01365
01366 for ( int imod = 0; imod < nmodules; imod++ ) {
01367
01368 PlexScintMdlId plexModuleId(plexPlaneId,imod);
01369
01370 std::string mdlName = GetGeoCompatibleName(plexModuleId.AsString());
01371
01372
01373
01374
01375
01376 GeoScintMdlVolume* mdlVol = new GeoScintMdlVolume(this,plexModuleId,
01377 ugliDbiTables,medAL,
01378 medAIR);
01379
01380
01381
01382 const UgliDbiScintMdl* scModule
01383 = ugliDbiTables.GetDbiScintMdlById(plexModuleId);
01384 Float_t tposMod = (scModule -> GetTPosRelPln())*fScale;
01385 Float_t lposMod = (scModule -> GetLPosRelPln())*fScale;
01386 Float_t zrotMod = scModule -> GetZRotRelPlnDeg();
01387
01388 TGeoRotation* modRotMatrix = new TGeoRotation(mdlName.c_str(), 90.,zrotMod,
01389 90.,90.+zrotMod,0.,0.);
01390 modRotMatrix -> RegisterYourself();
01391
01392 TGeoCombiTrans* combiMatrix = new TGeoCombiTrans(mdlName.c_str(),
01393 lposMod,tposMod,0.,modRotMatrix);
01394 std::string mdlNodeName = mdlName + "_1";
01395
01396 MSG("Geo",Msg::kVerbose) << "Mdl node " << mdlNodeName.c_str()
01397 << "tpos, lpos, zrot(deg) rel pln "
01398 << tposMod << "," << lposMod << "," << zrotMod
01399 << endl;
01400
01401 GeoScintMdlNode* mdlNode = new GeoScintMdlNode(this,mdlVol,combiMatrix,
01402 plnNode,mdlNodeName,
01403 plexModuleId,
01404 scModule->GetClearLenEast()*fScale,
01405 scModule->GetClearLenWest()*fScale,
01406 scModule->GetWlsLenEast()*fScale,
01407 scModule->GetWlsLenWest()*fScale);
01408
01409
01410 BuildStrips(ugliDbiTables,mdlNode);
01411
01412 }
01413
01414 }
01415
01416
01417 void GeoGeometry::BuildStrips(const UgliDbiTables& ugliDbiTables,
01418 GeoScintMdlNode* mdlNode) {
01419
01420
01421
01422
01423 UpdateGlobalManager();
01424 assert(fGeoManager);
01425
01426 PlexScintMdlId plexModuleId = mdlNode->GetPlexScintMdlId();
01427 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildStrips for module "
01428 << mdlNode->GetName() << endl;
01429
01430
01431 UgliDbiStructHash modulestructhash(plexModuleId);
01432 const UgliDbiScintMdlStruct* scModuleStruct
01433 = ugliDbiTables.fScintMdlStructTbl
01434 .GetRowByIndex(modulestructhash.HashAsScintMdl());
01435 Int_t lostrip = scModuleStruct -> GetFirstStrip();
01436 Int_t histrip = scModuleStruct -> GetLastStrip();
01437
01438 for ( int istp = lostrip; istp <= histrip; istp++ ) {
01439
01440 PlexStripEndId seid(plexModuleId,istp);
01441 std::string stpName = GetGeoCompatibleName(seid.AsString());
01442
01443 MSG("Geo",Msg::kVerbose) << "Strip " << istp << " name "
01444 << stpName.c_str() << endl;
01445 const UgliDbiStrip* scStrip = ugliDbiTables.GetDbiStripById(seid);
01446
01447
01448 std::string stpVolName = GetGeoCompatibleName(seid.AsString("s"));
01449 TGeoVolume* stpVol = fGeoManager -> GetVolume(stpVolName.c_str());
01450 if ( !stpVol ) {
01451 MSG("Geo",Msg::kFatal)
01452 << "Unable to find pre-built stripvol for volume "
01453 << stpName.c_str() << " shape name "
01454 << stpVolName.c_str() << endl;
01455 abort();
01456 }
01457
01458
01459 Float_t tposStp = (scStrip -> GetTPosRelMdl())*fScale;
01460 Float_t lposStp = (scStrip -> GetLPosRelMdl())*fScale;
01461 Float_t zrotStp = scStrip -> GetZRotRelMdlDeg();
01462 MSG("Geo",Msg::kVerbose) << "tpos, lpos, zrot(deg) rel to module "
01463 << tposStp << ", " << lposStp << ", "
01464 << zrotStp << endl;
01465
01466 std::string stpNodeName = stpName+"_1";
01467
01468 TGeoRotation* stpRotMatrix = new TGeoRotation(stpNodeName.c_str(), 90.,
01469 zrotStp,90.,90.+zrotStp,0.,0.);
01470 stpRotMatrix -> RegisterYourself();
01471 TGeoCombiTrans* combiMatrix
01472 = new TGeoCombiTrans(stpNodeName.c_str(),lposStp,tposStp,0.,stpRotMatrix);
01473
01474 new GeoStripNode(this,stpVol,combiMatrix,mdlNode,stpNodeName,seid);
01475
01476 }
01477
01478 return;
01479
01480 }
01481
01482
01483 void GeoGeometry::BuildStripVolumes(const VldContext& vldc) {
01484
01485
01486
01487
01488 UpdateGlobalManager();
01489
01490 MSG("Geo",Msg::kDebug) << "GeoGeometry::BuildStripVolumes " << endl;
01491 assert(fGeoManager);
01492
01493 TGeoMedium* scintMed = fGeoManager -> GetMedium("PSTYRENE SCINT");
01494 TGeoMedium* coexMed = fGeoManager -> GetMedium("COEX TIO2 PSTYRENE");
01495
01496 DbiResultPtr<UgliDbiStripStruct> stripTbl(vldc);
01497
01498 for ( unsigned int irow = 0; irow < stripTbl.GetNumRows(); irow++ ) {
01499 const UgliDbiStripStruct* sRow = stripTbl.GetRow(irow);
01500 string stpName = GetGeoCompatibleName(sRow -> GetShapeName());
01501
01502
01503 Float_t totallen = (sRow->GetTotalLen())*fScale;
01504 Float_t leneastpart = (sRow->GetLenEastPart())*fScale;
01505 Float_t lenwestpart = (sRow->GetLenWestPart())*fScale;
01506
01507 if ( totallen < 1.E-4*fScale ) continue;
01508 if ( leneastpart < 1.E-4*fScale ) leneastpart = totallen;
01509 if ( lenwestpart < 1.E-4*fScale ) lenwestpart = totallen;
01510
01511 new GeoStripVolume(this,stpName.c_str(),totallen,leneastpart,lenwestpart,
01512 (sRow->GetWlsLenEast())*fScale,
01513 (sRow->GetWlsLenWest())*fScale,
01514 (sRow->GetWlsLenBypass())*fScale,
01515 scintMed,coexMed);
01516 }
01517
01518 }
01519
01520
01521 void GeoGeometry::UpdateNodeMatrices(TGeoVolume* volume) {
01522
01523
01524
01525
01526 UpdateGlobalManager();
01527 if (!volume) {
01528 MSG("Geo",Msg::kFatal) << "UpdateNodeMatrices called with null volume ptr "
01529 << endl;
01530 abort();
01531 }
01532
01533 Int_t ndaughter = volume -> GetNdaughters();
01534 for ( int id = 0; id < ndaughter; id++ ) {
01535 TGeoNode* daughternode = volume->GetNode(id);
01536 GeoNode* geonode = dynamic_cast<GeoNode*>(daughternode);
01537 if ( geonode ) geonode -> UpdateGlobalMatrix();
01538
01539 TGeoVolume* daughtervol = daughternode->GetVolume();
01540 this -> UpdateNodeMatrices(daughtervol);
01541 }
01542
01543 }