00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012 #include "UgliGeometry/UgliGeometry.h"
00013
00014 #include "UgliGeometry/UgliLoanPool.h"
00015 #include "UgliGeometry/UgliScintPlnNode.h"
00016 #include "UgliGeometry/UgliSteelPlnNode.h"
00017
00018 #include "DatabaseInterface/DbiResultPtr.h"
00019
00020 #include "DatabaseInterface/DbiTableProxy.h"
00021 #include "DatabaseInterface/DbiCache.h"
00022
00023 #include "UgliGeometry/UgliDbiTables.h"
00024
00025 #include "UgliGeometry/UgliDbiGeometry.h"
00026 #include "UgliGeometry/UgliDbiScintPlnStruct.h"
00027 #include "UgliGeometry/UgliDbiScintMdlStruct.h"
00028 #include "UgliGeometry/UgliDbiStripStruct.h"
00029 #include "UgliGeometry/UgliDbiSteelPln.h"
00030 #include "UgliGeometry/UgliDbiScintPln.h"
00031 #include "UgliGeometry/UgliDbiScintMdl.h"
00032 #include "UgliGeometry/UgliDbiStrip.h"
00033
00034 #include "UgliGeometry/UgliStripShape.h"
00035 #include "UgliGeometry/TNodeX.h"
00036 #include "UgliGeometry/MinosOutline.h"
00037
00038 #include "Conventions/Munits.h"
00039 #include "Plex/PlexVetoShieldHack.h"
00040 #include "Fabrication/FabPlnInstallLookup.h"
00041
00042 #include "MessageService/MsgService.h"
00043 CVSID("$Id: UgliGeometry.cxx,v 1.68 2007/02/19 05:57:31 rhatcher Exp $");
00044
00045 #include "TMath.h"
00046 #include "TCanvas.h"
00047 #include "TMixture.h"
00048 #include "TRotMatrix.h"
00049 #include "TBRIK.h"
00050 #include "TSPHE.h"
00051 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,3)
00052 #include "TView3D.h"
00053 #else
00054 #include "TView.h"
00055 #endif
00056 #include "TObjArray.h"
00057 #include "TList.h"
00058
00059 #include <cassert>
00060 #include <float.h>
00061
00062 ClassImp(UgliGeometry)
00063
00064 typedef map<PlexPlaneId,UgliPlnNode*>::const_iterator nodeItr_t;
00065 typedef map<PlexPlaneId,UgliPlnNode*>::const_reverse_iterator nodeRevItr_t;
00066 typedef pair<PlexPlaneId,UgliPlnNode*> nodePair_t;
00067
00068
00069
00070
00071 size_t BinarySearchNearestLarger(const std::vector<Double_t>& array,
00072 Double_t value )
00073 {
00074
00075
00076
00077
00078
00079
00080
00081 size_t n(array.size());
00082
00083
00084 if ( value > array[n-1] ) return n;
00085 if ( value < array[0] ) return 0;
00086
00087 size_t nabove(n+1);
00088 size_t nbelow(0);
00089 size_t middle;
00090 while ( nabove-nbelow > 1 ) {
00091 middle = (nabove+nbelow)/2;
00092
00093
00094
00095
00096
00097
00098 Double_t vtest = array[middle-1];
00099 if ( value == vtest) return middle-1;
00100 if ( value < vtest) nabove = middle;
00101 else nbelow = middle;
00102 }
00103
00104 return nabove-1;
00105
00106 }
00107
00108
00109 UgliGeometry::UgliGeometry()
00110 : fFrozen(true), fAlgorithmic(false), fRootGeom(0),
00111 fCachedSteelPlnNode(0), fCachedScintPlnNode(0)
00112 {
00113
00114 MSG("Ugli",Msg::kVerbose) << "UgliGeometry default ctor" << endl;
00115 }
00116
00117
00118 UgliGeometry::UgliGeometry(const VldContext &vldc, Bool_t frozen)
00119 : fFrozen(frozen), fAlgorithmic(false), fRootGeom(0),
00120 fCachedSteelPlnNode(0), fCachedScintPlnNode(0)
00121 {
00122
00123
00124 fAlgorithmic = UgliDbiTables::IsAlgorithmic(vldc.GetDetector());
00125
00126
00127
00128
00129 if (vldc.GetDetector() == Detector::kFar)
00130 PlexVetoShieldHack::SetDefaultContext(vldc);
00131
00132
00133
00134 BuildAll(vldc);
00135 }
00136
00137
00138 UgliGeometry::~UgliGeometry()
00139 {
00140
00141
00142
00143
00144 delete fRootGeom; fRootGeom=0;
00145
00146 if (CountRef()) {
00147 MSG("Ugli",Msg::kWarning)
00148 << "~UgliGeometry still had " << CountRef()
00149 << " outstanding references " << endl;
00150 }
00151
00152 }
00153
00154
00155 UgliGeometry::EMINFStatus UgliGeometry::GetMINFStatus() const
00156 { return UgliGeometry::kNotNeeded; }
00157
00158
00159 Bool_t UgliGeometry::IsCompatible(const VldContext &vldc)
00160 {
00161
00162
00163 return fVldRange.IsCompatible(vldc);
00164
00165 }
00166
00167
00168 Bool_t UgliGeometry::IsCompatible(const VldContext *vldc)
00169 {
00170
00171
00172 return fVldRange.IsCompatible(vldc);
00173
00174 }
00175
00176
00177 UgliScintPlnNode* UgliGeometry::GetScintPlnNode(PlexPlaneId planeid) const
00178 {
00179
00180
00181 fRootGeom->cd();
00182 TNodeX* hallnode = dynamic_cast<TNodeX*>(fRootGeom->GetNode("hall"));
00183 if (!hallnode) {
00184 static int nmsg = 5;
00185 if (nmsg) {
00186 MSG("Ugli",Msg::kError)
00187 << "GetScintPlnNode found no hall node" << endl;
00188 nmsg--;
00189 if (nmsg==0) MSG("Ugli",Msg::kError)
00190 << " ... last of these warnings" << endl;
00191 }
00192 return 0;
00193 }
00194 hallnode->cd();
00195
00196
00197 PlexPlaneId scintplnid(planeid);
00198 if (scintplnid.IsSteel()) {
00199 static Int_t nmsg = 2;
00200 if (nmsg>0) {
00201 MSG("Ugli",Msg::kError)
00202 << "::GetScintPlnNode passed steel plane id "
00203 << planeid.AsString("c") << endl;
00204 nmsg--;
00205 if (nmsg==0) MSG("Ugli",Msg::kInfo)
00206 << " ... last message " << endl;
00207 }
00208 scintplnid.SetIsSteel(kFALSE);
00209
00210 assert(0);
00211 }
00212
00213
00214 if (scintplnid.GetDetector() == Detector::kFar &&
00215 scintplnid.IsVetoShield()) {
00216 VldContext vldc =
00217 PlexVetoShieldHack::ConvertRangeToContext(GetVldRange());
00218 scintplnid = PlexVetoShieldHack::RenumberMuxToMdl(vldc,scintplnid);
00219 }
00220
00221 if (scintplnid.GetPlaneCoverage() == PlaneCoverage::kNoActive) {
00222 static int msglimit = 20;
00223 if (msglimit) {
00224 MSG("Ugli",Msg::kError)
00225 << "::GetScintPlnNode impossible for "
00226 << scintplnid.AsString("c")
00227 << ", THERE IS NO SCINTILLATOR!"
00228 << endl;
00229 if (--msglimit == 0)
00230 MSG("Ugli",Msg::kError)
00231 << " ... last warning of this type" << endl;
00232 }
00233
00234 return 0;
00235 }
00236
00237
00238
00239
00240 if (fCachedScintPlnId == scintplnid) return fCachedScintPlnNode;
00241
00242 UgliScintPlnNode* the_node =
00243 #ifdef USENODETODEPTH
00244 dynamic_cast<UgliScintPlnNode*>(hallnode->GetNodeToDepth(scintplnid.AsString("p"),1));
00245 #else
00246
00247 0;
00248
00249 typedef std::map<PlexPlaneId,UgliPlnNode*>::const_iterator planeTableItr_t;
00250 planeTableItr_t pt_itr = fPlaneTable.find(scintplnid);
00251 if (pt_itr != fPlaneTable.end())
00252 the_node = dynamic_cast<UgliScintPlnNode*>(pt_itr->second);
00253 if ( ! the_node ) {
00254
00255 RestorePlaneTable(false);
00256 pt_itr = fPlaneTable.find(scintplnid);
00257 if (pt_itr != fPlaneTable.end())
00258 the_node = dynamic_cast<UgliScintPlnNode*>(pt_itr->second);
00259 }
00260 #endif
00261 if ( ! the_node ) {
00262 MSG("Ugli",Msg::kError)
00263 << "GetScintPlnNode could not find pre-constructed plane "
00264 << scintplnid.AsString("c")
00265 << " in " << fRootGeom->GetName() << endl;
00266 the_node = 0;
00267
00268
00269
00270 }
00271
00272
00273 fCachedScintPlnId = scintplnid;
00274 fCachedScintPlnNode = the_node;
00275
00276 return the_node;
00277 }
00278
00279
00280 UgliSteelPlnNode* UgliGeometry::GetSteelPlnNode(PlexPlaneId planeid) const
00281 {
00282
00283
00284 fRootGeom->cd();
00285 TNodeX* hallnode = dynamic_cast<TNodeX*>(fRootGeom->GetNode("hall"));
00286 if (!hallnode) {
00287 static int nmsg = 5;
00288 if (nmsg) {
00289 MSG("Ugli",Msg::kError)
00290 << "GetSteelPlnNode found no hall node" << endl;
00291 nmsg--;
00292 if (nmsg==0) MSG("Ugli",Msg::kError)
00293 << " ... last of these warnings" << endl;
00294 }
00295 return 0;
00296 }
00297 hallnode->cd();
00298
00299
00300 PlexPlaneId steelplnid(planeid);
00301 if (!steelplnid.IsSteel()) {
00302 static Int_t nmsg = 2;
00303 if (nmsg>0) {
00304 MSG("Ugli",Msg::kWarning)
00305 << "::GetSteelPlnNode passed scint plane id "
00306 << planeid.AsString("c") << endl;
00307 nmsg--;
00308 if (nmsg==0) MSG("Ugli",Msg::kInfo)
00309 << " ... last message " << endl;
00310 }
00311 steelplnid.SetIsSteel(kTRUE);
00312
00313 assert(0);
00314 }
00315
00316
00317
00318 if (fCachedSteelPlnId == steelplnid) return fCachedSteelPlnNode;
00319
00320 UgliSteelPlnNode* the_node =
00321 #ifdef USENODETODEPTH
00322 dynamic_cast<UgliSteelPlnNode*>(hallnode->GetNodeToDepth(steelplnid.AsString("p"),1));
00323 #else
00324
00325 0;
00326
00327 typedef std::map<PlexPlaneId,UgliPlnNode*>::const_iterator planeTableItr_t;
00328 planeTableItr_t pt_itr = fPlaneTable.find(steelplnid);
00329 if ( pt_itr != fPlaneTable.end() )
00330 the_node = dynamic_cast<UgliSteelPlnNode*>(pt_itr->second);
00331 if ( ! the_node ) {
00332
00333 RestorePlaneTable(false);
00334 pt_itr = fPlaneTable.find(steelplnid);
00335 if ( pt_itr != fPlaneTable.end() )
00336 the_node = dynamic_cast<UgliSteelPlnNode*>(pt_itr->second);
00337 }
00338 #endif
00339 if ( ! the_node ) {
00340 MSG("Ugli",Msg::kError)
00341 << "GetSteelPlnNode could not find pre-constructed plane "
00342 << steelplnid
00343 << " in " << fRootGeom->GetName() << endl;
00344 the_node = 0;
00345 }
00346
00347
00348 fCachedSteelPlnId = steelplnid;
00349 fCachedSteelPlnNode = the_node;
00350
00351 return the_node;
00352 }
00353
00354
00355 UgliStripNode* UgliGeometry::GetStripNode(PlexStripEndId seid) const
00356 {
00357
00358
00359 fRootGeom->cd();
00360 TNodeX* hallnode = dynamic_cast<TNodeX*>(fRootGeom->GetNode("hall"));
00361 if (!hallnode) {
00362 static int nmsg = 5;
00363 if (nmsg) {
00364 MSG("Ugli",Msg::kError)
00365 << "GetStripNode found no hall node" << endl;
00366 nmsg--;
00367 if (nmsg==0) MSG("Ugli",Msg::kError)
00368 << " ... last of these warnings" << endl;
00369 }
00370 return 0;
00371 }
00372 hallnode->cd();
00373
00374 PlexStripEndId geom_seid = seid;
00375
00376 if (geom_seid.GetDetector() == Detector::kFar &&
00377 geom_seid.IsVetoShield()) {
00378 VldContext vldc =
00379 PlexVetoShieldHack::ConvertRangeToContext(GetVldRange());
00380 geom_seid = PlexVetoShieldHack::RenumberMuxToMdl(vldc,geom_seid);
00381 }
00382
00383 UgliScintPlnNode* the_plane = GetScintPlnNode(geom_seid);
00384 if (!the_plane) return 0;
00385
00386 return the_plane->GetStripNode(geom_seid);
00387 }
00388
00389
00390 const vector<UgliScintPlnNode*>& UgliGeometry::GetScintPlnNodePtrVector() const
00391 {
00392
00393
00394 if (fScintPlnNodes.empty()) {
00395
00396 nodeItr_t node_itr = fPlaneTable.begin();
00397 nodeItr_t node_end = fPlaneTable.end();
00398
00399 while (node_itr != node_end) {
00400 nodePair_t map_pair = *node_itr;
00401 UgliScintPlnNode* scintPlnNode =
00402 dynamic_cast<UgliScintPlnNode*>(map_pair.second);
00403 if (scintPlnNode)
00404 fScintPlnNodes.push_back(scintPlnNode);
00405 node_itr++;
00406 }
00407 }
00408
00409 return fScintPlnNodes;
00410 }
00411
00412
00413 const vector<UgliSteelPlnNode*>& UgliGeometry::GetSteelPlnNodePtrVector() const
00414 {
00415
00416
00417
00418 if (fNormalSteelNodes.empty()) {
00419
00420 nodeItr_t node_itr = fPlaneTable.begin();
00421 nodeItr_t node_end = fPlaneTable.end();
00422
00423 while (node_itr != node_end) {
00424 nodePair_t map_pair = *node_itr;
00425 UgliSteelPlnNode* steelPlnNode =
00426 dynamic_cast<UgliSteelPlnNode*>(map_pair.second);
00427 if (steelPlnNode && !steelPlnNode->GetPlexPlaneId().IsVetoShield())
00428 fNormalSteelNodes.push_back(steelPlnNode);
00429 node_itr++;
00430 }
00431 }
00432
00433 return fNormalSteelNodes;
00434 }
00435
00436
00437 const vector<UgliPlnNode*>& UgliGeometry::GetPlnNodePtrVector() const
00438 {
00439
00440
00441 if (fAllPlnNodes.empty()) {
00442
00443 nodeItr_t node_itr = fPlaneTable.begin();
00444 nodeItr_t node_end = fPlaneTable.end();
00445
00446 while (node_itr != node_end) {
00447 nodePair_t map_pair = *node_itr;
00448 UgliPlnNode* plnNode = map_pair.second;
00449 if (plnNode) fAllPlnNodes.push_back(plnNode);
00450 node_itr++;
00451 }
00452 }
00453
00454 return fAllPlnNodes;
00455 }
00456
00457
00458 void UgliGeometry::Draw(Option_t * )
00459 {
00460
00461
00462 MSG("Ugli",Msg::kInfo) << "UgliGeometry::Draw()" << endl;
00463
00464
00465 TCanvas *uglicanvas = new TCanvas("ugli","ugli",200,10,700,700);
00466
00467 TPad *uglipad = new TPad("ugli","ugli",0.02,0.02,0.98,0.98,0);
00468 uglipad->Draw();
00469 uglipad->cd();
00470
00471
00472 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,3)
00473 TView *ugliview = new TView3D(1,0,0);
00474 #else
00475 TView *ugliview = new TView(1);
00476 #endif
00477
00478 Float_t phi = 90;
00479 Float_t theta = 180;
00480 Float_t psi = 0;
00481
00482 ugliview->SetLongitude(phi);
00483 ugliview->SetLatitude(theta);
00484 ugliview->SetPsi(psi);
00485
00486 Float_t zmin, zmax;
00487 Float_t t[4];
00488
00489 GetZExtent(zmin,zmax);
00490 GetTransverseExtent(PlaneView::kU,t[0],t[1]);
00491 GetTransverseExtent(PlaneView::kV,t[2],t[3]);
00492
00493 for (Int_t i=0; i<4; i++) t[i] = TMath::Abs(t[i]);
00494 Int_t imax = TMath::LocMax(4,t);
00495
00496
00497 Float_t tsize = TMath::Sqrt(2.) * t[imax];
00498
00499 Float_t x0 = 0;
00500 Float_t y0 = 0;
00501 Float_t z0 = 0.5*(zmin+zmax);
00502
00503 Float_t dz = 0.5*(zmax-zmin);
00504 ugliview->SetRange(x0-tsize,y0-tsize,z0-dz,x0+tsize,y0+tsize,z0+dz);
00505
00506
00507 fRootGeom->Draw("same");
00508
00509 uglicanvas->Update();
00510 }
00511
00512
00513 void UgliGeometry::Print(Option_t * ) const
00514 {
00515
00516
00517 MSG("Ugli",Msg::kInfo)
00518 << " " << TObject::GetName()
00519 << " has " << CountRef() << " references " << endl
00520 << " " << fVldRange.AsString("a") << endl;
00521 MSG("Ugli",Msg::kInfo)
00522 << " fRootGeom \"" << fRootGeom->GetName() << "\"" << endl;
00523 }
00524
00525
00526 void UgliGeometry::ls(Option_t *option) const
00527 {
00528
00529
00530 fRootGeom->ls(option);
00531 }
00532
00533
00534 void UgliGeometry::SetFrozen(Bool_t frozen)
00535 {
00536
00537
00538 fFrozen = frozen;
00539 if (fRootGeom) {
00540 TString name = (frozen?"Frozen":"Modifiable");
00541 name += fVldRange.AsString("s1ac-");
00542 fRootGeom->SetName(name.Data());
00543 }
00544 }
00545
00546
00547 void UgliGeometry::BuildAll(const VldContext &vldc)
00548 {
00549
00550
00551
00552
00553 BuildVldRange(vldc);
00554
00555 TString name = (IsFrozen()?"Frozen":"Modifiable");
00556 name += fVldRange.AsString("s1ac-");
00557 fRootGeom = new TGeometryX(name.Data(),"a MINOS geometry");
00558 fRootGeom->cd();
00559
00560 if (vldc.GetDetector() == Detector::kUnknown) {
00561 MSG("Ugli",Msg::kWarning)
00562 << "no possibility of building a geometry for " << endl
00563 << " VldContext: " << vldc << endl;
00564 return;
00565 }
00566
00567
00568
00569 BuildMaterials(vldc);
00570
00571
00572
00573 BuildRotMatrices(vldc);
00574
00575
00576
00577 BuildShapes(vldc);
00578
00579
00580
00581 BuildNodes(vldc);
00582
00583
00584
00585 ClearDbiCache(vldc);
00586 }
00587
00588
00589 void UgliGeometry::GetTransverseExtent(PlaneView::PlaneView_t view,
00590 Float_t& tmin, Float_t& tmax) const
00591 {
00592
00593
00594 Double_t tmind, tmaxd;
00595 GetTransverseExtent(view,tmind,tmaxd);
00596 tmin = (Float_t)tmind;
00597 tmax = (Float_t)tmaxd;
00598 }
00599
00600
00601 void UgliGeometry::GetTransverseExtent(PlaneView::PlaneView_t view,
00602 Double_t& tmin, Double_t& tmax) const
00603 {
00604
00605
00606
00607
00608 Detector::Detector_t detector =
00609 (Detector::Detector_t) fVldRange.GetDetectorMask();
00610
00611 switch (detector) {
00612 case Detector::kNear:
00613 switch (view) {
00614 case PlaneView::kU:
00615 tmin = -210. * Munits::cm;
00616 tmax = +275. * Munits::cm;
00617 break;
00618 case PlaneView::kV:
00619 tmin = -275. * Munits::cm;
00620 tmax = +210. * Munits::cm;
00621 break;
00622 default:
00623 MSG("Ugli",Msg::kError)
00624 << "UgliGeometry::GetTransverseExtent undefined for "
00625 << Detector::AsString(detector) << " view "
00626 << PlaneView::AsString(view) << endl;
00627 break;
00628 }
00629 case Detector::kFar:
00630 tmin = -400. * Munits::cm;
00631 tmax = +400. * Munits::cm;
00632 break;
00633 case Detector::kCalib:
00634 tmin = -50. * Munits::cm;
00635 tmax = +50. * Munits::cm;
00636 break;
00637 default:
00638 MSG("Ugli",Msg::kError)
00639 << "UgliGeometry::GetTransverseExtent undefined for "
00640 << Detector::AsString(detector) << endl;
00641 break;
00642 }
00643
00644 #ifdef OLDFUZZ
00645 Float_t fuzz_abs = 10. * Munits::cm;
00646 Float_t fuzz_frac = 0.025;
00647 #else
00648 Float_t fuzz_abs = 0.5 * 4.1 * Munits::cm;
00649 Float_t fuzz_frac = 0.0;
00650 #endif
00651 Float_t extra_per_side = 0.5*(tmax-tmin)*fuzz_frac;
00652
00653 tmin = tmin - fuzz_abs - extra_per_side;
00654 tmax = tmax + fuzz_abs + extra_per_side;
00655
00656
00657 }
00658
00659
00660 void UgliGeometry::GetZExtent(Float_t& zmin, Float_t& zmax, Int_t isuper) const
00661 {
00662
00663
00664
00665
00666 Double_t zmind, zmaxd;
00667 GetZExtent(zmind,zmaxd,isuper);
00668 zmin = (Float_t)zmind;
00669 zmax = (Float_t)zmaxd;
00670 }
00671
00672
00673 void UgliGeometry::GetZExtent(Double_t& zmin, Double_t& zmax, Int_t isuper) const
00674 {
00675
00676
00677
00678
00679
00680 Detector::Detector_t det =
00681 (Detector::Detector_t) fVldRange.GetDetectorMask();
00682
00683
00684 RestorePlaneTable(true);
00685 if ( fPlaneTable.empty() ) {
00686 MSG("Ugli",Msg::kWarning)
00687 << "GetZExtent() No planes found." << endl
00688 << " Perhaps this geometry was built with a bad VldContext" << endl
00689 << " or the database lacked an appropriate table" << endl
00690 << fVldRange.AsString()
00691 << endl;
00692
00693 Float_t spacing = 5.94*Munits::cm;
00694
00695 switch (det) {
00696 case Detector::kNear:
00697 zmin = -5.0*spacing;
00698 zmax = (float)282*spacing + 20.*Munits::cm + 5.0*spacing;
00699 break;
00700 case Detector::kCalDet:
00701 zmin = -5.0*spacing;
00702 zmax = (float)60*spacing + 20.*Munits::cm + 5.0*spacing;
00703 break;
00704 case Detector::kFar:
00705 zmin = -5.0*spacing;
00706 zmax = (float)484*spacing + 125.*Munits::cm + 5.0*spacing;
00707 break;
00708 default:
00709 zmin = -5.0*spacing;
00710 zmax = 60*Munits::m;
00711 break;
00712 }
00713
00714 return;
00715 }
00716
00717
00718
00719
00720 UgliPlnNode* upln_beg = fPlaneTable.begin()->second;
00721
00722 UgliPlnNode* upln_end = 0;
00723
00724
00725
00726 nodeRevItr_t node_ritr = fPlaneTable.rbegin();
00727 nodeRevItr_t node_rend = fPlaneTable.rend();
00728 for ( ; node_ritr != node_rend ; ++node_ritr ) {
00729 upln_end = node_ritr->second;
00730 PlexPlaneId plnid = upln_end->GetPlexPlaneId();
00731 PlaneView::PlaneView_t view = plnid.GetPlaneView();
00732
00733
00734 if (det == Detector::kCalDet){
00735 if (view != PlaneView::kA && view != PlaneView::kB) break;
00736 }
00737 else {
00738 if (view == PlaneView::kU || view == PlaneView::kV) break;
00739 }
00740 }
00741
00742 if ( -1 != isuper ) {
00743 if ( Detector::kFar != det ) {
00744 MSG("Ugli",Msg::kError)
00745 << "UgliGeometry::GetZExtent does not support supermodules "
00746 << "other than -1 for " << Detector::AsString(det)
00747 << endl << " return value for whole detector" << endl;
00748 }
00749 else {
00750
00751
00752
00753 UgliPlnNode* upln_mid0 = upln_beg;
00754 UgliPlnNode* upln_mid1 = upln_beg;
00755
00756 nodeItr_t node_itr = fPlaneTable.begin();
00757 nodeItr_t node_end = fPlaneTable.end();
00758
00759 node_itr++;
00760
00761 for ( ; node_itr != node_end ; node_itr++ ) {
00762 upln_mid0 = upln_mid1;
00763 upln_mid1 = node_itr->second;
00764 if (upln_mid1 == upln_end) {
00765 MSG("Ugli",Msg::kWarning)
00766 << "GetZExtent found no SM break for this geometry "
00767 << fVldRange << endl;
00768 upln_mid0 = upln_end;
00769 break;
00770 }
00771 PlexPlaneId plnid = upln_mid1->GetPlexPlaneId();
00772 PlaneCoverage::PlaneCoverage_t cover = plnid.GetPlaneCoverage();
00773 if (cover == PlaneCoverage::kNoActive) break;
00774 }
00775 switch (isuper) {
00776 case 0:
00777 MSG("Ugli",Msg::kDebug)
00778 << " SM 0 upln_end set to upln_mid0" << endl;
00779 upln_end = upln_mid0;
00780 break;
00781 case 1:
00782 MSG("Ugli",Msg::kDebug)
00783 << " SM 1 upln_beg set to upln_mid1" << endl;
00784 upln_beg = upln_mid1;
00785 break;
00786 default:
00787 MSG("Ugli",Msg::kError)
00788 << "GetZExtent" << endl << " FarDet only has SM 0 and 1"
00789 << ", return value for whole detector." << endl;
00790 }
00791
00792 }
00793 }
00794
00795 zmin = upln_beg->GetZ0() - upln_beg->GetHalfThickness();
00796 MSG("Ugli",Msg::kDebug)
00797 << "GetZExtent first was " << upln_beg->GetPlexPlaneId()
00798 << " Z0 " << upln_beg->GetZ0() << " - dz " << upln_beg->GetHalfThickness()
00799 << endl;
00800
00801 zmax = upln_end->GetZ0() + upln_end->GetHalfThickness();
00802 MSG("Ugli",Msg::kDebug)
00803 << "GetZExtent last was " << upln_end->GetPlexPlaneId()
00804 << " Z0 " << upln_end->GetZ0() << " + dz " << upln_end->GetHalfThickness()
00805 << endl;
00806
00807 #ifdef OLDFUZZ
00808 Float_t fuzz_abs = 10. * Munits::cm;
00809 Float_t fuzz_frac = 0.025;
00810 Float_t extra_per_side = 0.5*(zmax-zmin)*fuzz_frac;
00811
00812 zmin = zmin - fuzz_abs - extra_per_side;
00813 zmax = zmax + fuzz_abs + extra_per_side;
00814 #endif
00815
00816 }
00817
00818
00819 TVector3 UgliGeometry::GetHallExtentMin() const
00820 {
00821
00822
00823 TNodeX* hallnode = dynamic_cast<TNodeX*>(fRootGeom->GetNode("hall"));
00824 TShape* hallshape = hallnode->GetShape();
00825 TBRIK* hallbrik = dynamic_cast<TBRIK*>(hallshape);
00826 if (!hallbrik) {
00827 MSG("Ugli",Msg::kInfo)
00828 << "UgliGeometry::GetHallExtentMin() hall is not a BRIK " << endl;
00829 return TVector3(-9999.,-9999.,-9999.);
00830 }
00831 TVector3 xyz0(hallnode->GetX(), hallnode->GetY(), hallnode->GetZ());
00832 TVector3 dxyz(hallbrik->GetDx(),hallbrik->GetDy(),hallbrik->GetDz());
00833 TVector3 result = xyz0 - dxyz;
00834 return result;
00835
00836 }
00837
00838
00839 TVector3 UgliGeometry::GetHallExtentMax() const
00840 {
00841
00842
00843 TNodeX* hallnode = dynamic_cast<TNodeX*>(fRootGeom->GetNode("hall"));
00844 TShape* hallshape = hallnode->GetShape();
00845 TBRIK* hallbrik = dynamic_cast<TBRIK*>(hallshape);
00846 if (!hallbrik) {
00847 MSG("Ugli",Msg::kInfo)
00848 << "UgliGeometry::GetHallExtentMax() hall is not a BRIK " << endl;
00849 return TVector3(+9999.,+9999.,+9999.);
00850 }
00851 TVector3 xyz0(hallnode->GetX(), hallnode->GetY(), hallnode->GetZ());
00852 TVector3 dxyz(hallbrik->GetDx(),hallbrik->GetDy(),hallbrik->GetDz());
00853 TVector3 result = xyz0 + dxyz;
00854 return result;
00855 }
00856
00857
00858 void UgliGeometry::BuildVldRange(const VldContext &vldc)
00859 {
00860
00861
00862 MSG("Ugli",Msg::kDebug) << "UgliGeometry::BuildVldRange " << endl;
00863
00864 Detector::Detector_t det = vldc.GetDetector();
00865 bool isunknown = (Detector::kUnknown == det);
00866 const char* src = "DBI";
00867 if (isunknown) src = "Fake (unknown detector)";
00868
00869
00870
00871 VldTimeStamp starttime = VldTimeStamp((time_t)0,0);
00872 VldTimeStamp endtime = VldTimeStamp(2038,1,18,0,0,0);
00873 fVldRange = VldRange(vldc.GetDetector(),vldc.GetSimFlag(),
00874 starttime,endtime,src);
00875
00876
00877 if (isunknown) return;
00878
00879 if (fAlgorithmic) {
00880 MSG("Ugli",Msg::kInfo)
00881 << "UgliGeometry::VldRange: Algorithmic! valid until "
00882 << endtime
00883 << endl;
00884 return;
00885 }
00886
00887
00888
00889
00890
00891 MSG("Ugli",Msg::kInfo) << "UgliGeometry::VldRange: UgliDbiSteelPln"
00892 << " \r" << flush;
00893 DbiResultPtr<UgliDbiSteelPln> steelTbl(vldc);
00894 TrimVldRange("UgliDbiSteelPln",steelTbl.GetValidityRec());
00895
00896 MSG("Ugli",Msg::kInfo) << "UgliGeometry::VldRange: UgliDbiScintPlnStruct"
00897 << " \r" << flush;
00898 DbiResultPtr<UgliDbiScintPlnStruct> scintStructTbl(vldc);
00899 TrimVldRange("UgliDbiScintPlnStruct",scintStructTbl.GetValidityRec());
00900
00901 MSG("Ugli",Msg::kInfo) << "UgliGeometry::VldRange: UgliDbiScintPln"
00902 << " \r" << flush;
00903 DbiResultPtr<UgliDbiScintPln> scintTbl(vldc);
00904 TrimVldRange("UgliDbiScintPln",scintTbl.GetValidityRec());
00905
00906 MSG("Ugli",Msg::kInfo) << "UgliGeometry::VldRange: UgliDbiScintMdlStruct"
00907 << " \r" << flush;
00908 DbiResultPtr<UgliDbiScintMdlStruct> mdlStructTbl(vldc);
00909 TrimVldRange("UgliDbiScintMdlStruct",mdlStructTbl.GetValidityRec());
00910
00911 MSG("Ugli",Msg::kInfo) << "UgliGeometry::VldRange: UgliDbiScintMdl"
00912 << " \r" << flush;
00913 DbiResultPtr<UgliDbiScintMdl> mdlTbl(vldc);
00914 TrimVldRange("UgliDbiScintMdl",mdlTbl.GetValidityRec());
00915
00916 MSG("Ugli",Msg::kInfo) << "UgliGeometry::VldRange: UgliDbiStripStruct"
00917 << " \r" << flush;
00918 DbiResultPtr<UgliDbiStripStruct> stripStructTbl(vldc);
00919 TrimVldRange("UgliDbiStripStruct",stripStructTbl.GetValidityRec());
00920
00921 MSG("Ugli",Msg::kInfo) << "UgliGeometry::VldRange: UgliDbiStrip"
00922 << " \r" << flush;
00923 DbiResultPtr<UgliDbiStrip> stripTbl(vldc);
00924 TrimVldRange("UgliDbiStrip",stripTbl.GetValidityRec());
00925
00926 MSG("Ugli",Msg::kInfo) << "UgliGeometry::VldRange: done " << endl;
00927
00928
00929 }
00930
00931
00932 void UgliGeometry::ClearDbiCache(const VldContext &vldc)
00933 {
00934
00935
00936 MSG("Ugli",Msg::kDebug) << "UgliGeometry::ClearDbiCache " << endl;
00937
00938
00939 if (fAlgorithmic) return;
00940
00941
00942 if ( ! UgliLoanPool::Instance()->PurgeDbiTableCache() ) return;
00943
00944
00945
00946 DbiCache* steelTblCache = 0;
00947 DbiCache* scintStructTblCache = 0;
00948 DbiCache* scintTblCache = 0;
00949 DbiCache* mdlStructTblCache = 0;
00950 DbiCache* mdlTblCache = 0;
00951 DbiCache* stripStructTblCache = 0;
00952 DbiCache* stripTblCache = 0;
00953
00954 {
00955
00956
00957
00958
00959
00960
00961 MSG("Ugli",Msg::kDebug) << "UgliGeometry::GetCache: UgliDbiSteelPln"
00962 << " \r" << flush;
00963 DbiResultPtr<UgliDbiSteelPln> steelTbl(vldc);
00964 steelTblCache = steelTbl.TableProxy().GetCache();
00965
00966 MSG("Ugli",Msg::kDebug) << "UgliGeometry::GetCache: UgliDbiScintPlnStruct"
00967 << " \r" << flush;
00968 DbiResultPtr<UgliDbiScintPlnStruct> scintStructTbl(vldc);
00969 scintStructTblCache = scintStructTbl.TableProxy().GetCache();
00970
00971 MSG("Ugli",Msg::kDebug) << "UgliGeometry::GetCache: UgliDbiScintPln"
00972 << " \r" << flush;
00973 DbiResultPtr<UgliDbiScintPln> scintTbl(vldc);
00974 scintTblCache = scintTbl.TableProxy().GetCache();
00975
00976 MSG("Ugli",Msg::kDebug) << "UgliGeometry::GetCache: UgliDbiScintMdlStruct"
00977 << " \r" << flush;
00978 DbiResultPtr<UgliDbiScintMdlStruct> mdlStructTbl(vldc);
00979 mdlStructTblCache = mdlStructTbl.TableProxy().GetCache();
00980
00981 MSG("Ugli",Msg::kDebug) << "UgliGeometry::GetCache: UgliDbiScintMdl"
00982 << " \r" << flush;
00983 DbiResultPtr<UgliDbiScintMdl> mdlTbl(vldc);
00984 mdlTblCache = mdlTbl.TableProxy().GetCache();
00985
00986 MSG("Ugli",Msg::kDebug) << "UgliGeometry::GetCache: UgliDbiStripStruct"
00987 << " \r" << flush;
00988 DbiResultPtr<UgliDbiStripStruct> stripStructTbl(vldc);
00989 stripStructTblCache = stripStructTbl.TableProxy().GetCache();
00990
00991
00992 MSG("Ugli",Msg::kDebug) << "UgliGeometry::GetCache: UgliDbiStrip"
00993 << " \r" << flush;
00994 DbiResultPtr<UgliDbiStrip> stripTbl(vldc);
00995 stripTblCache = stripTbl.TableProxy().GetCache();
00996
00997 MSG("Ugli",Msg::kDebug) << "UgliGeometry::GetCache: done " << endl;
00998 }
00999
01000
01001
01002
01003 MSG("Ugli",Msg::kDebug) << "UgliGeometry::PurgeCache: UgliDbiSteelPln"
01004 << " \r" << flush;
01005 if (steelTblCache) steelTblCache->Purge();
01006
01007 MSG("Ugli",Msg::kDebug) << "UgliGeometry::PurgeCache: UgliDbiScintPlnStruct"
01008 << " \r" << flush;
01009 if (scintStructTblCache) scintStructTblCache->Purge();
01010
01011 MSG("Ugli",Msg::kDebug) << "UgliGeometry::PurgeCache: UgliDbiScintPln"
01012 << " \r" << flush;
01013 if (scintTblCache) scintTblCache->Purge();
01014
01015 MSG("Ugli",Msg::kDebug) << "UgliGeometry::PurgeCache: UgliDbiScintMdlStruct"
01016 << " \r" << flush;
01017 if (mdlStructTblCache) mdlStructTblCache->Purge();
01018
01019 MSG("Ugli",Msg::kDebug) << "UgliGeometry::PurgeCache: UgliDbiScintMdl"
01020 << " \r" << flush;
01021 if (mdlTblCache) mdlTblCache->Purge();
01022
01023 MSG("Ugli",Msg::kDebug) << "UgliGeometry::PurgeCache: UgliDbiStripStruct"
01024 << " \r" << flush;
01025 if (stripStructTblCache) stripStructTblCache->Purge();
01026
01027
01028 MSG("Ugli",Msg::kDebug) << "UgliGeometry::PurgeCache: UgliDbiStrip"
01029 << " \r" << flush;
01030 if (stripTblCache) stripTblCache->Purge();
01031
01032 MSG("Ugli",Msg::kDebug) << "UgliGeometry::PurgeCache: done " << endl;
01033
01034
01035 }
01036
01037
01038 void UgliGeometry::RestorePlaneTable(bool onlyIfEmpty) const
01039 {
01040
01041
01042
01043
01044
01045 if ( onlyIfEmpty && ! fPlaneTable.empty() ) return;
01046
01047 MSG("Ugli",Msg::kDebug) << "UgliGeometry::RestorePlaneTable " << endl;
01048
01049 fRootGeom->cd();
01050 TNodeX* hallnode = dynamic_cast<TNodeX*>(fRootGeom->GetNode("hall"));
01051
01052
01053 TIter nodeInHallItr(hallnode->GetListOfNodes());
01054 TNode* nodeInHall = 0;
01055 while ( ( nodeInHall = dynamic_cast<TNode*>(nodeInHallItr()) ) ) {
01056
01057 MSG("Ugli",Msg::kVerbose)
01058 << " found " << nodeInHall->GetName() << " in hall " << endl;
01059 TIter nodeInBoxItr(nodeInHall->GetListOfNodes());
01060 TObject* nodeInBox = 0;
01061 while ( ( nodeInBox = nodeInBoxItr() ) ) {
01062
01063 MSG("Ugli",Msg::kVerbose)
01064 << " found " << nodeInBox->GetName()
01065 << " in " << nodeInHall->GetName()<< endl;
01066 UgliPlnNode* upn = dynamic_cast<UgliPlnNode*>(nodeInBox);
01067 if (upn) {
01068 fPlaneTable[upn->GetPlexPlaneId()] = upn;
01069 MSG("Ugli",Msg::kDebug)
01070 << "UgliGeometry::RestorePlaneTable add "
01071 << upn->GetPlexPlaneId() << endl;
01072 }
01073 }
01074 }
01075
01076
01077 }
01078
01079
01080 void UgliGeometry::BuildMaterials(const VldContext& )
01081 {
01082
01083
01084 MSG("Ugli",Msg::kVerbose) << "UgliGeometry BuildMaterials " << endl;
01085
01086
01087 TMixture *mix;
01088
01089
01090 mix = new TMixture("scint","polystyrene C6H5CH-CH2",-2);
01091 mix->DefineElement(0,1.00794,1.,8.);
01092 mix->DefineElement(1,12.011,6.,8.);
01093
01094
01095 mix = new TMixture("steel","generic steel",2);
01096 mix->DefineElement(0,55.84999,26,.98);
01097 mix->DefineElement(1,12.01,6,.02);
01098
01099
01100 }
01101
01102
01103 void UgliGeometry::BuildRotMatrices(const VldContext& )
01104 {
01105
01106
01107
01108 new TRotMatrix("Identity","Identity matrix",90,0,90,90,0,0);
01109
01110 new TRotMatrix("XY","WorldAsXY", 90., 0., 90., 90., 0., 0.);
01111 new TRotMatrix("UV","WorldAsUV", 90.,-45., 90., 45., 0., 0.);
01112
01113 }
01114
01115
01116 void UgliGeometry::BuildShapes(const VldContext& )
01117 {
01118
01119
01120 MSG("Ugli",Msg::kVerbose) << "UgliGeometry BuildShapes " << endl;
01121
01122
01123
01124
01125
01126
01127 Float_t nsx[] = { 3, 3, 1.5,-1.5, -3, -3,-1.5, -.5, 0, 0,
01128 .49, .49, 0, 0, 1, 1, .51, .51, 1, 1,
01129 .5, -1, -2, -2, -1, 1, 2, 2};
01130 Float_t nsy[] = { 0, 1.5, 3, 3, 1.5,-1.5, -3, -3,-3.5, -5,
01131 -5, -6, -6, -7, -7, -6, -6, -5, -5, -3,
01132 -2, -2, -1, 1, 2, 2, 1, 0};
01133 TXTRU *noshape = new TXTRU("noshape","noshape","void",28,2);
01134 Float_t dz = 5.94 * Munits::cm;
01135 noshape->DefineSection(0,-dz,1.,0.,0.);
01136 noshape->DefineSection(1,+dz,1.,0.,0.);
01137 for (unsigned int i=0; i < sizeof(nsx)/sizeof(Float_t); i++)
01138 noshape->DefineVertex(i,nsx[i]*Munits::m,nsy[i]*Munits::m);
01139 noshape->SetLineColor(kRed); noshape->SetLineWidth(1);
01140
01141 }
01142
01143
01144 void UgliGeometry::BuildNodes(const VldContext& vldc)
01145 {
01146
01147
01148 MSG("Ugli",Msg::kDebug) << "UgliGeometry::BuildNodes UgliDbiTables" << endl;
01149 const UgliDbiTables& ugliTables =
01150 ((fAlgorithmic) ? UgliDbiTables(vldc,false) : UgliDbiTables(vldc));
01151
01152 fRootGeom->cd();
01153
01154
01155 TShape *pshape = 0;
01156 TNodeX *pnode = 0;
01157
01158 bool world_is_uv = true;
01159 const char* world_rotm = "UV";
01160
01161 bool force_xy = true;
01162
01163 if (vldc.GetDetector() == Detector::kCalDet) {
01164 world_is_uv = false;
01165 world_rotm = "XY";
01166 }
01167 else if (force_xy) {
01168 MSG("Ugli",Msg::kDebug)
01169 << vldc.AsString("c") << " should use Hall oriented in UV space"
01170 << " ... but we won't for now" << endl;
01171 world_is_uv = false;
01172 world_rotm = "XY";
01173 }
01174
01175 MSG("Ugli",Msg::kDebug) << "Build the hall" << endl;
01176
01177 const UgliDbiGeometry* geo = ugliTables.GetDbiGeometry();
01178 if (!geo) {
01179 MSG("Ugli",Msg::kFatal)
01180 << "No UgliDbiGeometry for " << vldc << endl;
01181 return;
01182 }
01183
01184 const Float_t* hmin = geo->GetHallXYZMin();
01185 const Float_t* hmax = geo->GetHallXYZMax();
01186
01187
01188
01189
01190 Float_t absxmax = TMath::Max(TMath::Abs(hmax[0]),TMath::Abs(hmin[0]));
01191 Float_t absymax = TMath::Max(TMath::Abs(hmax[1]),TMath::Abs(hmin[1]));
01192 Float_t abszmax = TMath::Max(TMath::Abs(hmax[2]),TMath::Abs(hmin[2]));
01193 Float_t absxymax = TMath::Max(absxmax,absymax);
01194 Float_t sqrt2 = TMath::Sqrt(2.0);
01195 if (world_is_uv) absxymax *= sqrt2;
01196
01197
01198 pshape = new TBRIK("universe","all the ever is","void",
01199 absxymax,absxymax,abszmax);
01200 pnode = new TNodeX("universe","fixed center of all",
01201 "universe",0,0,0,"Identity");
01202 pnode->SetVisibility(0);
01203 pnode->SetVisibility(1);
01204 pnode->SetLineColor(kYellow);
01205 pnode->cd();
01206
01207
01208 pshape = new TBRIK("world","the shape of the world","void",
01209 absxymax,absxymax,abszmax);
01210 pnode = new TNodeX("world","it depends how we look at it",
01211 "world",0,0,0,world_rotm);
01212 pnode->SetVisibility(1);
01213 pnode->SetLineColor(kBlack);
01214 pnode->cd();
01215
01216
01217 Double_t xhsiz = 0.5 * (hmax[0] - hmin[0]);
01218 Double_t yhsiz = 0.5 * (hmax[1] - hmin[1]);
01219 Double_t zhsiz = 0.5 * (hmax[2] - hmin[2]);
01220
01221 Double_t x0hall = 0.5 * (hmax[0] + hmin[0]);
01222 Double_t y0hall = 0.5 * (hmax[1] + hmin[1]);
01223 Double_t z0hall = 0.5 * (hmax[2] + hmin[2]);
01224
01225 pshape = new TBRIK("hall","The Hall","void",
01226 xhsiz,yhsiz,zhsiz);
01227 TNodeX *hall_node = new TNodeX("hall","The Hall","hall",
01228 x0hall,y0hall,z0hall);
01229 hall_node->cd();
01230 hall_node->SetVisibility(1);
01231 hall_node->SetLineColor(kRed);
01232
01233
01234
01235 Float_t rmkr = 20.*Munits::cm;
01236 if (vldc.GetDetector() == Detector::kCalDet) rmkr = 1.*Munits::cm;
01237 pshape = new TSPHE("axismkr","axismkr","void",rmkr);
01238 pnode = new TNodeX("+x","+x","axismkr",
01239 xhsiz-x0hall-rmkr,-y0hall,-zhsiz+rmkr);
01240 pnode->SetLineColor(kRed);
01241 pnode->SetVisibility(1);
01242 pnode = new TNodeX("+y","+y","axismkr",
01243 -x0hall,yhsiz-y0hall-rmkr,-zhsiz+rmkr);
01244 pnode->SetLineColor(kGreen);
01245 pnode->SetVisibility(1);
01246 pnode = new TNodeX("+z","+z","axismkr",
01247 -x0hall,-y0hall,+zhsiz-rmkr);
01248 pnode->SetLineColor(kBlue);
01249 pnode->SetVisibility(1);
01250 MSG("Ugli",Msg::kDebug) << "The Hall has been installed" << endl;
01251
01252
01253 BuildStripShapes(vldc);
01254
01255
01256
01257
01258 Msg::LogLevel_t cutMsgLevel = Msg::kSynopsis;
01259 VldTimeStamp geomStartTime = vldc.GetTimeStamp();
01260 bool cutOnPlnInstall = UgliDbiTables::IsCutOnPlnInstall(vldc.GetDetector());
01261
01262 VldContext vldc_install = vldc;
01263 Registry& config = UgliLoanPool::Instance()->GetConfig();
01264 int cutAppliesToVetoShield = false;
01265 if (vldc.GetDetector() == Detector::kFar)
01266 config.Get("CutAppliesToVetoShield",cutAppliesToVetoShield);
01267 if ( cutOnPlnInstall && vldc.GetSimFlag() != SimFlag::kData ) {
01268 int applyToMC = 0;
01269 config.Get("CutAppliesToMC",applyToMC);
01270 switch ( applyToMC ) {
01271 case 1:
01272 cutOnPlnInstall = true;
01273 break;
01274 case 2:
01275 cutOnPlnInstall = true;
01276 vldc_install =
01277 VldContext(vldc.GetDetector(),SimFlag::kData,vldc.GetTimeStamp());
01278 MSG("Ugli",Msg::kInfo)
01279 << "UgliGeometry::BuildNodes use kData instead of k"
01280 << SimFlag::AsString(vldc.GetSimFlag())
01281 << " for FabPlnInstall." << endl;
01282 break;
01283 default:
01284 cutOnPlnInstall = false;
01285 break;
01286 }
01287 }
01288
01289 TString fabCutAction = "not to cut on ";
01290 if (cutOnPlnInstall) {
01291 fabCutAction = "to cut on ";
01292 if (vldc.GetDetector() == Detector::kFar) {
01293 if (cutAppliesToVetoShield) fabCutAction += "all ";
01294 else fabCutAction += "non-VetoShield ";
01295 }
01296 }
01297 MSG("Ugli",Msg::kInfo)
01298 << "UgliGeometry configured " << fabCutAction
01299 << "FabPlnInstall entries." << endl;
01300
01301 FabPlnInstallLookup installInfo(vldc_install);
01302 if ( cutOnPlnInstall ) {
01303 const char* level = "Synopsis";
01304 config.Get("CutMsgLevel",level);
01305 cutMsgLevel = Msg::GetLevelCode(level);
01306
01307
01308
01309 const FabPlnInstall* fab = installInfo.NextInstall(geomStartTime,true);
01310 if (fab) {
01311 const VldTimeStamp time_end = fVldRange.GetTimeEnd();
01312 const VldTimeStamp& time_next = fab->GetInstallDate();
01313 MSG("Ugli",cutMsgLevel)
01314 << "UgliGeometry VldRange was "
01315 << time_end.AsString("sql") << " PlnInstall::NextInstall gives "
01316 << time_next.AsString("sql") << "." << endl;
01317 if ( time_next < time_end ) {
01318 MSG("Ugli",cutMsgLevel)
01319 << "UgliGeometry VldRange TimeEnd trimmed from "
01320 << time_end.AsString("sql") << " to "
01321 << time_next.AsString("sql") << "." << endl;
01322 fVldRange.SetTimeEnd(time_next);
01323 }
01324 }
01325 else {
01326 MSG("Ugli",Msg::kInfo)
01327 << "UgliGeometry: No VldRange trimming as no PlnInstall::NextInstall."
01328 << endl;
01329 }
01330 }
01331
01332
01333
01334
01335 unsigned int nsteel = ugliTables.GetNumSteelRows();
01336 for (unsigned int irow=0; irow < nsteel; ++irow) {
01337
01338 const UgliDbiSteelPln* steelRow = ugliTables.GetDbiSteelPln(irow);
01339
01340 PlexPlaneId steelid = steelRow->GetPlaneId();
01341
01342
01343
01344
01345 bool checkit = true;
01346 if (steelid.IsVetoShield() && !cutAppliesToVetoShield) checkit = false;
01347 if (cutOnPlnInstall && checkit) {
01348
01349
01350 const FabPlnInstall* fab =
01351 installInfo.fPlnInstallTbl.GetRowByIndex(steelid.GetPlane());
01352 if ( fab ) {
01353 if ( fab->GetInstallDate() > geomStartTime ) {
01354 MSG("Ugli",cutMsgLevel)
01355 << endl
01356 << "UgliDbiTables has entry for " << steelid
01357 << " but FabPlnInstall says "
01358 << fab->GetInstallDate().AsString("sql")
01359 << endl;
01360 continue;
01361 }
01362 }
01363 else {
01364 MSG("Ugli",cutMsgLevel)
01365 << endl
01366 << "UgliDbiTables has entry for " << steelid
01367 << " but no entry in FabPlnInstall "
01368 << endl;
01369 continue;
01370 }
01371
01372 }
01373
01374
01375 int vis = 1;
01376
01377
01378
01379
01380
01381 MSG("Ugli",Msg::kDebug) << " build " << steelid.AsString("c")
01382 << "\r" << flush;
01383
01384 hall_node->cd();
01385 UgliSteelPlnNode* steel =
01386 new UgliSteelPlnNode(steelid,this,ugliTables);
01387 fPlaneTable[steelid] = steel;
01388
01389
01390
01391
01392
01393
01394
01395 steel->SetVisibility(vis);
01396 TNode* box_from_steel = steel->GetParent();
01397 box_from_steel->SetVisibility(vis);
01398
01399 if (PlaneCoverage::kNoActive == steelid.GetPlaneCoverage()) continue;
01400 if (PlaneCoverage::kUnknown == steelid.GetPlaneCoverage()) continue;
01401
01402 PlexPlaneId scintid = steelid;
01403 scintid.SetIsSteel(false);
01404
01405 MSG("Ugli",Msg::kSynopsis) << " build " << scintid.AsString("c")
01406 << "\r" << flush;
01407
01408 box_from_steel->cd();
01409 UgliScintPlnNode* scint =
01410 new UgliScintPlnNode(scintid,this,ugliTables);
01411 fPlaneTable[scintid] = scint;
01412
01413
01414
01415
01416 scint->SetVisibility(vis);
01417
01418 }
01419 hall_node->cd();
01420
01421 MSG("Ugli",Msg::kSynopsis) << endl << " build done" << endl;
01422
01423
01424
01425
01426
01427 PlexPlaneId loNormal, hiNormal, loShield, hiShield;
01428 const PlexPlaneId unsetPlnId;
01429 unsigned int nmdlShieldSection[5] = {0,0,0,0,0};
01430
01431 nodeItr_t node_itr = fPlaneTable.begin();
01432 nodeItr_t node_end = fPlaneTable.end();
01433
01434 while (node_itr != node_end) {
01435 nodePair_t map_pair = *node_itr;
01436 PlexPlaneId aPlnId = node_itr->second->GetPlexPlaneId();
01437 node_itr++;
01438
01439 if (!aPlnId.IsVetoShield()) {
01440 if ( loNormal == unsetPlnId ) loNormal = aPlnId;
01441 hiNormal = aPlnId;
01442 }
01443 else if ( ! aPlnId.IsSteel() ) {
01444 if ( loShield == unsetPlnId ) loShield = aPlnId;
01445 hiShield = aPlnId;
01446
01447 int isection = aPlnId.GetVetoSection();
01448 nmdlShieldSection[isection]++;
01449 }
01450 }
01451
01452 MSG("Ugli",Msg::kInfo)
01453 << "Built Normal planes: " << loNormal << " to " << hiNormal << "." << endl;
01454 if ( loShield != unsetPlnId) {
01455 MSG("Ugli",Msg::kInfo)
01456 << "Built VetoShield: " << loShield
01457 << " to " << hiShield << "; Section/Mdls: ";
01458 for (unsigned int isec=1; isec <= 4; ++isec) {
01459 if ( nmdlShieldSection[isec] > 0 )
01460 MSG("Ugli",Msg::kInfo)
01461 << " " << isec << "/" << nmdlShieldSection[isec];
01462 }
01463 MSG("Ugli",Msg::kInfo) << "." << endl;
01464 }
01465 else if ( vldc.GetDetector() == Detector::kFar )
01466 MSG("Ugli",Msg::kInfo) << "Built No VetoShield sections." << endl;
01467 }
01468
01469
01470
01471 void UgliGeometry::BuildStripShapes(const VldContext& vldc)
01472 {
01473
01474
01475 MSG("Ugli",Msg::kDebug) << "UgliGeometry::BuildStripShapes " << endl;
01476
01477 DbiResultPtr<UgliDbiStripStruct> stripTbl(vldc);
01478 TrimVldRange("UgliDbiStripStruct",stripTbl.GetValidityRec());
01479
01480 for (unsigned int irow=0; irow < stripTbl.GetNumRows(); ++irow) {
01481 const UgliDbiStripStruct* sRow = stripTbl.GetRow(irow);
01482 string sname = sRow->GetShapeName();
01483
01484
01485 new UgliStripShape(sname.c_str(),sRow->GetTotalLen(),
01486 sRow->GetWlsLenEast(),sRow->GetWlsLenWest(),
01487 sRow->GetLenEastPart(),sRow->GetLenWestPart(),
01488 sRow->GetWlsLenBypass());
01489 }
01490
01491
01492 }
01493
01494
01495 PlexPlaneId UgliGeometry::GetPlaneIdFromZ(Double_t z) const
01496 {
01497
01498
01499
01500
01501
01502
01503
01504 RestorePlaneTable(true);
01505
01506 nodeRevItr_t node_itr = fPlaneTable.rbegin();
01507 nodeRevItr_t node_end = fPlaneTable.rend();
01508 UgliPlnNode *uplane = 0, *prev_uplane = 0;
01509 for ( ; node_itr != node_end ; ++node_itr ) {
01510 uplane = node_itr->second;
01511 PlexPlaneId plnid = uplane->GetPlexPlaneId();
01512 PlaneView::PlaneView_t view = plnid.GetPlaneView();
01513
01514
01515
01516 if (view == PlaneView::kA || view == PlaneView::kB) continue;
01517 if (view > PlaneView::kUnknown ) continue;
01518 Float_t zback = uplane->GetZ0() + uplane->GetHalfThickness();
01519 if ( ! prev_uplane ) prev_uplane = uplane;
01520 if ( z > zback ) return prev_uplane->GetPlexPlaneId();
01521 prev_uplane = uplane;
01522 }
01523 return uplane->GetPlexPlaneId();
01524
01525 }
01526
01527
01528 UgliSteelPlnNode* UgliGeometry::GetNearestSteelPlnNode(Double_t z) const
01529 {
01530
01531
01532
01533 const std::vector<UgliSteelPlnNode*>& steelNodes =
01534 GetSteelPlnNodePtrVector();
01535 size_t nplns = steelNodes.size();
01536
01537
01538 if ( nplns == 0) {
01539
01540 MSG("Ugli",Msg::kError)
01541 << "GetNearestSteelPlnNode was passed 0 UgliSteelPlnNode's"
01542 << endl;
01543 return 0;
01544 }
01545 else if ( nplns == 1 ) return steelNodes[0];
01546
01547
01548 if ( fZSteelPlnMidPoint.empty() ) {
01549
01550
01551
01552 UgliSteelPlnNode* steelNode = steelNodes[0];
01553 Double_t dz = steelNode->GetHalfThickness();
01554 Double_t z0 = steelNode->GetZ0();
01555 Double_t zDownSide = z0 - dz;
01556 Double_t zUpSide = z0 + dz;
01557 for ( size_t indx = 1; indx < nplns; ++indx ) {
01558 Double_t zUpSideLast = zUpSide;
01559 UgliSteelPlnNode* steelNode = steelNodes[indx];
01560 dz = steelNode->GetHalfThickness();
01561 z0 = steelNode->GetZ0();
01562 zDownSide = z0 - dz;
01563 zUpSide = z0 + dz;
01564 Double_t zMid = 0.5 * ( zUpSideLast + zDownSide );
01565 fZSteelPlnMidPoint.push_back(zMid);
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576 }
01577 }
01578
01579 size_t index = BinarySearchNearestLarger(fZSteelPlnMidPoint,z);
01580 return steelNodes[index];
01581
01582 }
01583
01584
01585 void UgliGeometry::TrimVldRange(const char* tblName,
01586 const DbiValidityRec* dbivrec)
01587 {
01588
01589
01590 if (dbivrec) {
01591 fVldRange.TrimTo(dbivrec->GetVldRange());
01592 } else {
01593 MSG("Ugli",Msg::kWarning)
01594 << "No DbiValidityRec for table " << tblName << endl;
01595 }
01596 }
01597
01598