/*
<img src="gif/t_graf.jpg">
*/
//End_Html
// End_Html
/*
<img src="gif/t_root.jpg">
*/
//End_Html
/*
<img src="gif/t_mgr.jpg">
*/
//End_Html
/*
<img src="gif/t_browser.jpg">
*/
//End_Html
/*
<img src="gif/t_frame0.jpg">
*/
//End_Html
/*
<img src="gif/t_frame1.jpg">
*/
//End_Html
/*
<img src="gif/t_frameexp.jpg">
*/
//End_Html
/*
<img src="gif/t_checkpoint.jpg">
*/
//End_Html
/*
<img src="gif/t_random1.jpg">
*/
//End_Html
/*
<img src="gif/t_random2.jpg">
*/
//End_Html
#include <stdlib.h>
#include "Riostream.h"
#include "TROOT.h"
#include "TGeoManager.h"
#include "TSystem.h"
#include "TStyle.h"
#include "TVirtualPad.h"
#include "TBrowser.h"
#include "TFile.h"
#include "TKey.h"
#include "THashList.h"
#include "TClass.h"
#include "TThread.h"
#include "ThreadLocalStorage.h"
#include "TGeoVoxelFinder.h"
#include "TGeoElement.h"
#include "TGeoMaterial.h"
#include "TGeoMedium.h"
#include "TGeoMatrix.h"
#include "TGeoNode.h"
#include "TGeoPhysicalNode.h"
#include "TGeoManager.h"
#include "TGeoPara.h"
#include "TGeoParaboloid.h"
#include "TGeoTube.h"
#include "TGeoEltu.h"
#include "TGeoHype.h"
#include "TGeoCone.h"
#include "TGeoSphere.h"
#include "TGeoArb8.h"
#include "TGeoPgon.h"
#include "TGeoTrd1.h"
#include "TGeoTrd2.h"
#include "TGeoTorus.h"
#include "TGeoXtru.h"
#include "TGeoCompositeShape.h"
#include "TGeoBoolNode.h"
#include "TGeoBuilder.h"
#include "TVirtualGeoPainter.h"
#include "TPluginManager.h"
#include "TVirtualGeoTrack.h"
#include "TQObject.h"
#include "TMath.h"
#include "TEnv.h"
#include "TGeoParallelWorld.h"
TGeoManager *gGeoManager = 0;
ClassImp(TGeoManager)
Bool_t TGeoManager::fgLock = kFALSE;
Bool_t TGeoManager::fgLockNavigators = kFALSE;
Int_t TGeoManager::fgVerboseLevel = 1;
Int_t TGeoManager::fgMaxLevel = 1;
Int_t TGeoManager::fgMaxDaughters = 1;
Int_t TGeoManager::fgMaxXtruVert = 1;
Int_t TGeoManager::fgNumThreads = 0;
TGeoManager::ThreadsMap_t *TGeoManager::fgThreadId = 0;
TGeoManager::TGeoManager()
{
if (!fgThreadId) fgThreadId = new TGeoManager::ThreadsMap_t;
if (TClass::IsCallingNew() == TClass::kDummyNew) {
fTimeCut = kFALSE;
fTmin = 0.;
fTmax = 999.;
fPhiCut = kFALSE;
fPhimin = 0;
fPhimax = 360;
fDrawExtra = kFALSE;
fStreamVoxels = kFALSE;
fIsGeomReading = kFALSE;
fIsGeomCleaning = kFALSE;
fClosed = kFALSE;
fLoopVolumes = kFALSE;
fBits = 0;
fCurrentNavigator = 0;
fMaterials = 0;
fHashPNE = 0;
fArrayPNE = 0;
fMatrices = 0;
fNodes = 0;
fOverlaps = 0;
fNNodes = 0;
fMaxVisNodes = 10000;
fVolumes = 0;
fPhysicalNodes = 0;
fShapes = 0;
fGVolumes = 0;
fGShapes = 0;
fTracks = 0;
fMedia = 0;
fNtracks = 0;
fNpdg = 0;
fPdgNames = 0;
memset(fPdgId, 0, 1024*sizeof(Int_t));
fCurrentTrack = 0;
fCurrentVolume = 0;
fTopVolume = 0;
fTopNode = 0;
fMasterVolume = 0;
fPainter = 0;
fActivity = kFALSE;
fIsNodeSelectable = kFALSE;
fVisDensity = 0.;
fVisLevel = 3;
fVisOption = 1;
fExplodedView = 0;
fNsegments = 20;
fNLevel = 0;
fUniqueVolumes = 0;
fNodeIdArray = 0;
fClippingShape = 0;
fMatrixTransform = kFALSE;
fMatrixReflection = kFALSE;
fGLMatrix = 0;
fPaintVolume = 0;
fElementTable = 0;
fHashVolumes = 0;
fHashGVolumes = 0;
fSizePNEId = 0;
fNPNEId = 0;
fKeyPNEId = 0;
fValuePNEId = 0;
fMultiThread = kFALSE;
fMaxThreads = 0;
fUsePWNav = kFALSE;
fParallelWorld = 0;
ClearThreadsMap();
} else {
Init();
if (!gGeoIdentity && TClass::IsCallingNew() == TClass::kRealNew) gGeoIdentity = new TGeoIdentity("Identity");
BuildDefaultMaterials();
}
}
TGeoManager::TGeoManager(const char *name, const char *title)
:TNamed(name, title)
{
if (!gROOT->GetListOfGeometries()->FindObject(this)) gROOT->GetListOfGeometries()->Add(this);
if (!gROOT->GetListOfBrowsables()->FindObject(this)) gROOT->GetListOfBrowsables()->Add(this);
Init();
gGeoIdentity = new TGeoIdentity("Identity");
BuildDefaultMaterials();
if (fgVerboseLevel>0) Info("TGeoManager","Geometry %s, %s created", GetName(), GetTitle());
}
void TGeoManager::Init()
{
if (gGeoManager) {
Warning("Init","Deleting previous geometry: %s/%s",gGeoManager->GetName(),gGeoManager->GetTitle());
delete gGeoManager;
if (fgLock) Fatal("Init", "New geometry created while the old one locked !!!");
}
gGeoManager = this;
if (!fgThreadId) fgThreadId = new TGeoManager::ThreadsMap_t;
fTimeCut = kFALSE;
fTmin = 0.;
fTmax = 999.;
fPhiCut = kFALSE;
fPhimin = 0;
fPhimax = 360;
fDrawExtra = kFALSE;
fStreamVoxels = kFALSE;
fIsGeomReading = kFALSE;
fIsGeomCleaning = kFALSE;
fClosed = kFALSE;
fLoopVolumes = kFALSE;
fBits = new UChar_t[50000];
fCurrentNavigator = 0;
fHashPNE = new THashList(256,3);
fArrayPNE = 0;
fMaterials = new THashList(200,3);
fMatrices = new TObjArray(256);
fNodes = new TObjArray(30);
fOverlaps = new TObjArray(256);
fNNodes = 0;
fMaxVisNodes = 10000;
fVolumes = new TObjArray(256);
fPhysicalNodes = new TObjArray(256);
fShapes = new TObjArray(256);
fGVolumes = new TObjArray(256);
fGShapes = new TObjArray(256);
fTracks = new TObjArray(256);
fMedia = new THashList(200,3);
fNtracks = 0;
fNpdg = 0;
fPdgNames = 0;
memset(fPdgId, 0, 1024*sizeof(Int_t));
fCurrentTrack = 0;
fCurrentVolume = 0;
fTopVolume = 0;
fTopNode = 0;
fMasterVolume = 0;
fPainter = 0;
fActivity = kFALSE;
fIsNodeSelectable = kFALSE;
fVisDensity = 0.;
fVisLevel = 3;
fVisOption = 1;
fExplodedView = 0;
fNsegments = 20;
fNLevel = 0;
fUniqueVolumes = new TObjArray(256);
fNodeIdArray = 0;
fClippingShape = 0;
fMatrixTransform = kFALSE;
fMatrixReflection = kFALSE;
fGLMatrix = new TGeoHMatrix();
fPaintVolume = 0;
fElementTable = 0;
fHashVolumes = 0;
fHashGVolumes = 0;
fSizePNEId = 0;
fNPNEId = 0;
fKeyPNEId = 0;
fValuePNEId = 0;
fMultiThread = kFALSE;
fMaxThreads = 0;
fUsePWNav = kFALSE;
fParallelWorld = 0;
ClearThreadsMap();
}
TGeoManager::TGeoManager(const TGeoManager& gm) :
TNamed(gm),
fPhimin(gm.fPhimin),
fPhimax(gm.fPhimax),
fTmin(gm.fTmin),
fTmax(gm.fTmax),
fNNodes(gm.fNNodes),
fParticleName(gm.fParticleName),
fVisDensity(gm.fVisDensity),
fExplodedView(gm.fExplodedView),
fVisOption(gm.fVisOption),
fVisLevel(gm.fVisLevel),
fNsegments(gm.fNsegments),
fNtracks(gm.fNtracks),
fMaxVisNodes(gm.fMaxVisNodes),
fCurrentTrack(gm.fCurrentTrack),
fNpdg(gm.fNpdg),
fClosed(gm.fClosed),
fLoopVolumes(gm.fLoopVolumes),
fStreamVoxels(gm.fStreamVoxels),
fIsGeomReading(gm.fIsGeomReading),
fIsGeomCleaning(kFALSE),
fPhiCut(gm.fPhiCut),
fTimeCut(gm.fTimeCut),
fDrawExtra(gm.fDrawExtra),
fMatrixTransform(gm.fMatrixTransform),
fMatrixReflection(gm.fMatrixReflection),
fActivity(gm.fActivity),
fIsNodeSelectable(gm.fIsNodeSelectable),
fPainter(gm.fPainter),
fMatrices(gm.fMatrices),
fShapes(gm.fShapes),
fVolumes(gm.fVolumes),
fPhysicalNodes(gm.fPhysicalNodes),
fGShapes(gm.fGShapes),
fGVolumes(gm.fGVolumes),
fTracks(gm.fTracks),
fPdgNames(gm.fPdgNames),
fMaterials(gm.fMaterials),
fMedia(gm.fMedia),
fNodes(gm.fNodes),
fOverlaps(gm.fOverlaps),
fBits(gm.fBits),
fCurrentNavigator(gm.fCurrentNavigator),
fCurrentVolume(gm.fCurrentVolume),
fTopVolume(gm.fTopVolume),
fTopNode(gm.fTopNode),
fMasterVolume(gm.fMasterVolume),
fGLMatrix(gm.fGLMatrix),
fUniqueVolumes(gm.fUniqueVolumes),
fClippingShape(gm.fClippingShape),
fElementTable(gm.fElementTable),
fNodeIdArray(gm.fNodeIdArray),
fNLevel(gm.fNLevel),
fPaintVolume(gm.fPaintVolume),
fHashVolumes(gm.fHashVolumes),
fHashGVolumes(gm.fHashGVolumes),
fHashPNE(gm.fHashPNE),
fArrayPNE(gm.fArrayPNE),
fSizePNEId(0),
fNPNEId(0),
fKeyPNEId(0),
fValuePNEId(0),
fMaxThreads(0),
fMultiThread(kFALSE),
fUsePWNav(kFALSE),
fParallelWorld(0)
{
for(Int_t i=0; i<1024; i++)
fPdgId[i]=gm.fPdgId[i];
if (!fgThreadId) fgThreadId = new TGeoManager::ThreadsMap_t;
ClearThreadsMap();
}
TGeoManager& TGeoManager::operator=(const TGeoManager& gm)
{
if (!fgThreadId) fgThreadId = new TGeoManager::ThreadsMap_t;
if(this!=&gm) {
TNamed::operator=(gm);
fPhimin=gm.fPhimin;
fPhimax=gm.fPhimax;
fTmin=gm.fTmin;
fTmax=gm.fTmax;
fNNodes=gm.fNNodes;
fParticleName=gm.fParticleName;
fVisDensity=gm.fVisDensity;
fExplodedView=gm.fExplodedView;
fVisOption=gm.fVisOption;
fVisLevel=gm.fVisLevel;
fNsegments=gm.fNsegments;
fNtracks=gm.fNtracks;
fMaxVisNodes=gm.fMaxVisNodes;
fCurrentTrack=gm.fCurrentTrack;
fNpdg=gm.fNpdg;
for(Int_t i=0; i<1024; i++)
fPdgId[i]=gm.fPdgId[i];
fClosed=gm.fClosed;
fLoopVolumes=gm.fLoopVolumes;
fStreamVoxels=gm.fStreamVoxels;
fIsGeomReading=gm.fIsGeomReading;
fIsGeomCleaning = kFALSE;
fPhiCut=gm.fPhiCut;
fTimeCut=gm.fTimeCut;
fDrawExtra=gm.fDrawExtra;
fMatrixTransform=gm.fMatrixTransform;
fMatrixReflection=gm.fMatrixReflection;
fActivity=gm.fActivity;
fIsNodeSelectable=gm.fIsNodeSelectable;
fPainter=gm.fPainter;
fMatrices=gm.fMatrices;
fShapes=gm.fShapes;
fVolumes=gm.fVolumes;
fPhysicalNodes=gm.fPhysicalNodes;
fGShapes=gm.fGShapes;
fGVolumes=gm.fGVolumes;
fTracks=gm.fTracks;
fPdgNames=gm.fPdgNames;
fMaterials=gm.fMaterials;
fMedia=gm.fMedia;
fNodes=gm.fNodes;
fOverlaps=gm.fOverlaps;
fBits=gm.fBits;
fCurrentNavigator=gm.fCurrentNavigator;
fCurrentVolume = gm.fCurrentVolume;
fTopVolume=gm.fTopVolume;
fTopNode=gm.fTopNode;
fMasterVolume=gm.fMasterVolume;
fGLMatrix=gm.fGLMatrix;
fUniqueVolumes=gm.fUniqueVolumes;
fClippingShape=gm.fClippingShape;
fElementTable=gm.fElementTable;
fNodeIdArray=gm.fNodeIdArray;
fNLevel=gm.fNLevel;
fPaintVolume=gm.fPaintVolume;
fHashVolumes=gm.fHashVolumes;
fHashGVolumes=gm.fHashGVolumes;
fHashPNE=gm.fHashPNE;
fArrayPNE=gm.fArrayPNE;
fSizePNEId = 0;
fNPNEId = 0;
fKeyPNEId = 0;
fValuePNEId = 0;
fMultiThread = kFALSE;
fMaxThreads = 0;
fUsePWNav = kFALSE;
fParallelWorld = 0;
ClearThreadsMap();
ClearThreadData();
}
return *this;
}
TGeoManager::~TGeoManager()
{
if (gGeoManager != this) gGeoManager = this;
fIsGeomCleaning = kTRUE;
if (gROOT->GetListOfFiles()) {
gROOT->GetListOfGeometries()->Remove(this);
gROOT->GetListOfBrowsables()->Remove(this);
}
ClearThreadsMap();
ClearThreadData();
delete TGeoBuilder::Instance(this);
if (fBits) delete [] fBits;
SafeDelete(fNodes);
SafeDelete(fTopNode);
if (fOverlaps) {fOverlaps->Delete(); SafeDelete(fOverlaps);}
if (fMaterials) {fMaterials->Delete(); SafeDelete(fMaterials);}
SafeDelete(fElementTable);
if (fMedia) {fMedia->Delete(); SafeDelete(fMedia);}
if (fHashVolumes) fHashVolumes->Clear("nodelete"); SafeDelete(fHashVolumes);
if (fHashGVolumes) fHashGVolumes->Clear("nodelete"); SafeDelete(fHashGVolumes);
if (fHashPNE) {fHashPNE->Delete(); SafeDelete(fHashPNE);}
if (fArrayPNE) {delete fArrayPNE;}
if (fVolumes) {fVolumes->Delete(); SafeDelete(fVolumes);}
if (fShapes) {fShapes->Delete(); SafeDelete( fShapes );}
if (fPhysicalNodes) {fPhysicalNodes->Delete(); SafeDelete( fPhysicalNodes );}
if (fMatrices) {fMatrices->Delete(); SafeDelete( fMatrices );}
if (fTracks) {fTracks->Delete(); SafeDelete( fTracks );}
SafeDelete( fUniqueVolumes );
if (fPdgNames) {fPdgNames->Delete(); SafeDelete( fPdgNames );}
ClearNavigators();
CleanGarbage();
SafeDelete( fPainter );
SafeDelete( fGLMatrix );
if (fSizePNEId) {
delete [] fKeyPNEId;
delete [] fValuePNEId;
}
delete fParallelWorld;
fIsGeomCleaning = kFALSE;
gGeoIdentity = 0;
gGeoManager = 0;
}
Int_t TGeoManager::AddMaterial(const TGeoMaterial *material)
{
return TGeoBuilder::Instance(this)->AddMaterial((TGeoMaterial*)material);
}
Int_t TGeoManager::AddOverlap(const TNamed *ovlp)
{
Int_t size = fOverlaps->GetEntriesFast();
fOverlaps->Add((TObject*)ovlp);
return size;
}
Int_t TGeoManager::AddTransformation(const TGeoMatrix *matrix)
{
return TGeoBuilder::Instance(this)->AddTransformation((TGeoMatrix*)matrix);
}
Int_t TGeoManager::AddShape(const TGeoShape *shape)
{
return TGeoBuilder::Instance(this)->AddShape((TGeoShape*)shape);
}
Int_t TGeoManager::AddTrack(Int_t id, Int_t pdgcode, TObject *particle)
{
Int_t index = fNtracks;
fTracks->AddAtAndExpand(GetGeomPainter()->AddTrack(id,pdgcode,particle),fNtracks++);
return index;
}
Int_t TGeoManager::AddTrack(TVirtualGeoTrack *track)
{
Int_t index = fNtracks;
fTracks->AddAtAndExpand(track,fNtracks++);
return index;
}
TVirtualGeoTrack *TGeoManager::MakeTrack(Int_t id, Int_t pdgcode, TObject *particle)
{
TVirtualGeoTrack *track = GetGeomPainter()->AddTrack(id,pdgcode,particle);
return track;
}
Int_t TGeoManager::AddVolume(TGeoVolume *volume)
{
if (!volume) {
Error("AddVolume", "invalid volume");
return -1;
}
Int_t uid = fUniqueVolumes->GetEntriesFast();
if (!uid) uid++;
if (!fCurrentVolume) {
fCurrentVolume = volume;
fUniqueVolumes->AddAtAndExpand(volume,uid);
} else {
if (!strcmp(volume->GetName(), fCurrentVolume->GetName())) {
uid = fCurrentVolume->GetNumber();
} else {
fCurrentVolume = volume;
Int_t olduid = GetUID(volume->GetName());
if (olduid<0) {
fUniqueVolumes->AddAtAndExpand(volume,uid);
} else {
uid = olduid;
}
}
}
volume->SetNumber(uid);
if (!fHashVolumes) {
fHashVolumes = new THashList(256);
fHashGVolumes = new THashList(256);
}
TObjArray *list = fVolumes;
if (!volume->GetShape() || volume->IsRunTime() || volume->IsVolumeMulti()) {
list = fGVolumes;
fHashGVolumes->Add(volume);
} else {
fHashVolumes->Add(volume);
}
Int_t index = list->GetEntriesFast();
list->AddAtAndExpand(volume,index);
return uid;
}
TGeoNavigator *TGeoManager::AddNavigator()
{
if (fMultiThread) TThread::Lock();
Long_t threadId = fMultiThread ? TThread::SelfId() : 0;
NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
TGeoNavigatorArray *array = 0;
if (it != fNavigators.end()) array = it->second;
else {
array = new TGeoNavigatorArray(this);
fNavigators.insert(NavigatorsMap_t::value_type(threadId, array));
}
TGeoNavigator *nav = array->AddNavigator();
if (fClosed) nav->GetCache()->BuildInfoBranch();
if (fMultiThread) TThread::UnLock();
return nav;
}
TGeoNavigator *TGeoManager::GetCurrentNavigator() const
{
TTHREAD_TLS(TGeoNavigator*) tnav = 0;
if (!fMultiThread) return fCurrentNavigator;
TGeoNavigator *nav = tnav;
if (nav) return nav;
Long_t threadId = TThread::SelfId();
NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
if (it == fNavigators.end()) return 0;
TGeoNavigatorArray *array = it->second;
nav = array->GetCurrentNavigator();
tnav = nav;
return nav;
}
TGeoNavigatorArray *TGeoManager::GetListOfNavigators() const
{
Long_t threadId = fMultiThread ? TThread::SelfId() : 0;
NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
if (it == fNavigators.end()) return 0;
TGeoNavigatorArray *array = it->second;
return array;
}
Bool_t TGeoManager::SetCurrentNavigator(Int_t index)
{
Long_t threadId = fMultiThread ? TThread::SelfId() : 0;
NavigatorsMap_t::const_iterator it = fNavigators.find(threadId);
if (it == fNavigators.end()) {
Error("SetCurrentNavigator", "No navigator defined for thread %ld\n", threadId);
return kFALSE;
}
TGeoNavigatorArray *array = it->second;
TGeoNavigator *nav = array->SetCurrentNavigator(index);
if (!nav) {
Error("SetCurrentNavigator", "Navigator %d not existing for thread %ld\n", index, threadId);
return kFALSE;
}
if (!fMultiThread) fCurrentNavigator = nav;
return kTRUE;
}
void TGeoManager::SetNavigatorsLock(Bool_t flag)
{
fgLockNavigators = flag;
}
void TGeoManager::ClearNavigators()
{
if (fMultiThread) TThread::Lock();
TGeoNavigatorArray *arr = 0;
for (NavigatorsMap_t::iterator it = fNavigators.begin();
it != fNavigators.end(); it++) {
arr = (*it).second;
if (arr) delete arr;
}
fNavigators.clear();
if (fMultiThread) TThread::UnLock();
}
void TGeoManager::RemoveNavigator(const TGeoNavigator *nav)
{
if (fMultiThread) TThread::Lock();
for (NavigatorsMap_t::iterator it = fNavigators.begin();
it != fNavigators.end(); it++) {
TGeoNavigatorArray *arr = (*it).second;
if (arr) {
if ((TGeoNavigator*)arr->Remove((TObject*)nav)) {
delete nav;
if (!arr->GetEntries()) fNavigators.erase(it);
if (fMultiThread) TThread::UnLock();
return;
}
}
}
Error("Remove navigator", "Navigator %p not found", nav);
if (fMultiThread) TThread::UnLock();
}
void TGeoManager::SetMaxThreads(Int_t nthreads)
{
if (!fClosed) {
Error("SetMaxThreads", "Cannot set maximum number of threads before closing the geometry");
return;
}
if (!fMultiThread) {
TThread::Initialize();
Long_t threadId = TThread::SelfId();
NavigatorsMap_t::const_iterator it = fNavigators.find(0);
if (it != fNavigators.end()) {
TGeoNavigatorArray *array = it->second;
fNavigators.erase(it);
fNavigators.insert(NavigatorsMap_t::value_type(threadId, array));
}
}
if (fMaxThreads) {
ClearThreadsMap();
ClearThreadData();
}
fMaxThreads = nthreads+1;
if (fMaxThreads>0) {
fMultiThread = kTRUE;
CreateThreadData();
}
}
void TGeoManager::ClearThreadData() const
{
if (!fMaxThreads) return;
TThread::Lock();
TIter next(fVolumes);
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next())) vol->ClearThreadData();
TThread::UnLock();
}
void TGeoManager::CreateThreadData() const
{
if (!fMaxThreads) return;
TThread::Lock();
TIter next(fVolumes);
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next())) vol->CreateThreadData(fMaxThreads);
TThread::UnLock();
}
void TGeoManager::ClearThreadsMap()
{
if (gGeoManager && !gGeoManager->IsMultiThread()) return;
TThread::Lock();
if (!fgThreadId->empty()) fgThreadId->clear();
fgNumThreads = 0;
TThread::UnLock();
}
Int_t TGeoManager::ThreadId()
{
TTHREAD_TLS(Int_t) tid = -1;
Int_t ttid = tid;
if (ttid > -1) return ttid;
if (gGeoManager && !gGeoManager->IsMultiThread()) return 0;
TGeoManager::ThreadsMapIt_t it = fgThreadId->find(TThread::SelfId());
if (it != fgThreadId->end()) return it->second;
TThread::Lock();
(*fgThreadId)[TThread::SelfId()] = fgNumThreads;
tid = fgNumThreads;
ttid = fgNumThreads++;
TThread::UnLock();
return ttid;
}
void TGeoManager::Browse(TBrowser *b)
{
if (!b) return;
if (fMaterials) b->Add(fMaterials, "Materials");
if (fMedia) b->Add(fMedia, "Media");
if (fMatrices) b->Add(fMatrices, "Local transformations");
if (fOverlaps) b->Add(fOverlaps, "Illegal overlaps");
if (fTracks) b->Add(fTracks, "Tracks");
if (fMasterVolume) b->Add(fMasterVolume, "Master Volume", fMasterVolume->IsVisible());
if (fTopVolume) b->Add(fTopVolume, "Top Volume", fTopVolume->IsVisible());
if (fTopNode) b->Add(fTopNode);
TString browserImp(gEnv->GetValue("Browser.Name", "TRootBrowserLite"));
TQObject::Connect(browserImp.Data(), "Checked(TObject*,Bool_t)",
"TGeoManager", this, "SetVisibility(TObject*,Bool_t)");
}
void TGeoManager::Edit(Option_t *option) {
AppendPad("");
GetGeomPainter()->EditGeometry(option);
}
void TGeoManager::SetVisibility(TObject *obj, Bool_t vis)
{
if(obj->IsA() == TGeoVolume::Class()) {
TGeoVolume *vol = (TGeoVolume *) obj;
vol->SetVisibility(vis);
} else {
if (obj->InheritsFrom(TGeoNode::Class())) {
TGeoNode *node = (TGeoNode *) obj;
node->SetVisibility(vis);
} else return;
}
GetGeomPainter()->ModifiedPad(kTRUE);
}
void TGeoManager::BombTranslation(const Double_t *tr, Double_t *bombtr)
{
if (fPainter) fPainter->BombTranslation(tr, bombtr);
return;
}
void TGeoManager::UnbombTranslation(const Double_t *tr, Double_t *bombtr)
{
if (fPainter) fPainter->UnbombTranslation(tr, bombtr);
return;
}
void TGeoManager::DoBackupState()
{
GetCurrentNavigator()->DoBackupState();
}
void TGeoManager::DoRestoreState()
{
GetCurrentNavigator()->DoRestoreState();
}
void TGeoManager::RegisterMatrix(const TGeoMatrix *matrix)
{
return TGeoBuilder::Instance(this)->RegisterMatrix((TGeoMatrix*)matrix);
}
Int_t TGeoManager::ReplaceVolume(TGeoVolume *vorig, TGeoVolume *vnew)
{
Int_t nref = 0;
if (!vorig || !vnew) return nref;
TGeoMedium *morig = vorig->GetMedium();
Bool_t checkmed = kFALSE;
if (morig) checkmed = kTRUE;
TGeoMedium *mnew = vnew->GetMedium();
if (!mnew && !vnew->IsAssembly()) {
Error("ReplaceVolume","Replacement volume %s has no medium and it is not an assembly",
vnew->GetName());
return nref;
}
if (mnew && checkmed) {
if (mnew->GetId() != morig->GetId())
Warning("ReplaceVolume","Replacement volume %s has different medium than original volume %s",
vnew->GetName(), vorig->GetName());
checkmed = kFALSE;
}
Int_t nvol = fVolumes->GetEntriesFast();
Int_t i,j,nd;
Int_t ierr = 0;
TGeoVolume *vol;
TGeoNode *node;
TGeoVoxelFinder *voxels;
for (i=0; i<nvol; i++) {
vol = (TGeoVolume*)fVolumes->At(i);
if (!vol) continue;
if (vol==vorig || vol==vnew) continue;
nd = vol->GetNdaughters();
for (j=0; j<nd; j++) {
node = vol->GetNode(j);
if (node->GetVolume() == vorig) {
if (checkmed) {
mnew = node->GetMotherVolume()->GetMedium();
if (mnew && mnew->GetId()!=morig->GetId()) ierr++;
}
nref++;
if (node->IsOverlapping()) {
node->SetOverlapping(kFALSE);
Info("ReplaceVolume","%s replaced with assembly and declared NON-OVERLAPPING!",node->GetName());
}
node->SetVolume(vnew);
voxels = node->GetMotherVolume()->GetVoxels();
if (voxels) voxels->SetNeedRebuild();
} else {
if (node->GetMotherVolume() == vorig) {
nref++;
node->SetMotherVolume(vnew);
if (node->IsOverlapping()) {
node->SetOverlapping(kFALSE);
Info("ReplaceVolume","%s inside substitute assembly %s declared NON-OVERLAPPING!",node->GetName(),vnew->GetName());
}
}
}
}
}
if (ierr) Warning("ReplaceVolume", "Volumes should not be replaced with assemblies if they are positioned in containers having a different medium ID.\n %i occurences for assembly replacing volume %s",
ierr, vorig->GetName());
return nref;
}
Int_t TGeoManager::TransformVolumeToAssembly(const char *vname)
{
TGeoVolume *toTransform = FindVolumeFast(vname);
if (!toTransform) {
Warning("TransformVolumeToAssembly", "Volume %s not found", vname);
return 0;
}
Int_t index = fVolumes->IndexOf(toTransform);
Int_t count = 0;
Int_t indmax = fVolumes->GetEntries();
Bool_t replace = kTRUE;
TGeoVolume *transformed;
while (index<indmax) {
if (replace) {
replace = kFALSE;
transformed = TGeoVolumeAssembly::MakeAssemblyFromVolume(toTransform);
if (transformed) {
ReplaceVolume(toTransform, transformed);
count++;
} else {
if (toTransform->IsAssembly())
Warning("TransformVolumeToAssembly", "Volume %s already assembly", toTransform->GetName());
if (!toTransform->GetNdaughters())
Warning("TransformVolumeToAssembly", "Volume %s has no daughters, cannot transform", toTransform->GetName());
if (toTransform->IsVolumeMulti())
Warning("TransformVolumeToAssembly", "Volume %s divided, cannot transform", toTransform->GetName());
}
}
index++;
if (index >= indmax) return count;
toTransform = (TGeoVolume*)fVolumes->At(index);
if (!strcmp(toTransform->GetName(),vname)) replace = kTRUE;
}
return count;
}
TGeoVolume *TGeoManager::Division(const char *name, const char *mother, Int_t iaxis,
Int_t ndiv, Double_t start, Double_t step, Int_t numed, Option_t *option)
{
return TGeoBuilder::Instance(this)->Division(name, mother, iaxis, ndiv, start, step, numed, option);
}
void TGeoManager::Matrix(Int_t index, Double_t theta1, Double_t phi1,
Double_t theta2, Double_t phi2,
Double_t theta3, Double_t phi3)
{
TGeoBuilder::Instance(this)->Matrix(index, theta1, phi1, theta2, phi2, theta3, phi3);
}
TGeoMaterial *TGeoManager::Material(const char *name, Double_t a, Double_t z, Double_t dens, Int_t uid,Double_t radlen, Double_t intlen)
{
return TGeoBuilder::Instance(this)->Material(name, a, z, dens, uid, radlen, intlen);
}
TGeoMaterial *TGeoManager::Mixture(const char *name, Float_t *a, Float_t *z, Double_t dens,
Int_t nelem, Float_t *wmat, Int_t uid)
{
return TGeoBuilder::Instance(this)->Mixture(name, a, z, dens, nelem, wmat, uid);
}
TGeoMaterial *TGeoManager::Mixture(const char *name, Double_t *a, Double_t *z, Double_t dens,
Int_t nelem, Double_t *wmat, Int_t uid)
{
return TGeoBuilder::Instance(this)->Mixture(name, a, z, dens, nelem, wmat, uid);
}
TGeoMedium *TGeoManager::Medium(const char *name, Int_t numed, Int_t nmat, Int_t isvol,
Int_t ifield, Double_t fieldm, Double_t tmaxfd,
Double_t stemax, Double_t deemax, Double_t epsil,
Double_t stmin)
{
return TGeoBuilder::Instance(this)->Medium(name, numed, nmat, isvol, ifield, fieldm, tmaxfd, stemax, deemax, epsil, stmin);
}
void TGeoManager::Node(const char *name, Int_t nr, const char *mother,
Double_t x, Double_t y, Double_t z, Int_t irot,
Bool_t isOnly, Float_t *upar, Int_t npar)
{
TGeoBuilder::Instance(this)->Node(name, nr, mother, x, y, z, irot, isOnly, upar, npar);
}
void TGeoManager::Node(const char *name, Int_t nr, const char *mother,
Double_t x, Double_t y, Double_t z, Int_t irot,
Bool_t isOnly, Double_t *upar, Int_t npar)
{
TGeoBuilder::Instance(this)->Node(name, nr, mother, x, y, z, irot, isOnly, upar, npar);
}
TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed,
Float_t *upar, Int_t npar)
{
return TGeoBuilder::Instance(this)->Volume(name, shape, nmed, upar, npar);
}
TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed,
Double_t *upar, Int_t npar)
{
return TGeoBuilder::Instance(this)->Volume(name, shape, nmed, upar, npar);
}
void TGeoManager::SetAllIndex()
{
Int_t index = 1;
TIter next(fMaterials);
TGeoMaterial *mater;
while ((mater=(TGeoMaterial*)next())) {
mater->SetUniqueID(index++);
mater->ResetBit(TGeoMaterial::kMatSavePrimitive);
}
index = 1;
TIter next1(fMedia);
TGeoMedium *med;
while ((med=(TGeoMedium*)next1())) {
med->SetUniqueID(index++);
med->ResetBit(TGeoMedium::kMedSavePrimitive);
}
index = 1;
TIter next2(fShapes);
TGeoShape *shape;
while ((shape=(TGeoShape*)next2())) {
shape->SetUniqueID(index++);
if (shape->IsComposite()) ((TGeoCompositeShape*)shape)->GetBoolNode()->RegisterMatrices();
}
TIter next3(fMatrices);
TGeoMatrix *matrix;
while ((matrix=(TGeoMatrix*)next3())) {
matrix->RegisterYourself();
}
TIter next4(fMatrices);
index = 1;
while ((matrix=(TGeoMatrix*)next4())) {
matrix->SetUniqueID(index++);
matrix->ResetBit(TGeoMatrix::kGeoSavePrimitive);
}
TIter next5(fVolumes);
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next5())) vol->UnmarkSaved();
}
void TGeoManager::ClearAttributes()
{
if (gPad) delete gPad;
gPad = 0;
SetVisOption(0);
SetVisLevel(3);
SetExplodedView(0);
SetBombFactors();
if (!gStyle) return;
TIter next(fVolumes);
TGeoVolume *vol = 0;
while ((vol=(TGeoVolume*)next())) {
if (!vol->IsVisTouched()) continue;
vol->SetVisTouched(kFALSE);
}
}
void TGeoManager::CloseGeometry(Option_t *option)
{
if (fClosed) {
Warning("CloseGeometry", "geometry already closed");
return;
}
if (!fMasterVolume) {
Error("CloseGeometry","you MUST call SetTopVolume() first !");
return;
}
if (!gROOT->GetListOfGeometries()->FindObject(this)) gROOT->GetListOfGeometries()->Add(this);
if (!gROOT->GetListOfBrowsables()->FindObject(this)) gROOT->GetListOfBrowsables()->Add(this);
TString opt(option);
opt.ToLower();
Bool_t nodeid = opt.Contains("i");
TGeoNavigator *nav = 0;
Int_t nnavigators = 0;
if (fIsGeomReading) {
if (fgVerboseLevel>0) Info("CloseGeometry","Geometry loaded from file...");
gGeoIdentity=(TGeoIdentity *)fMatrices->At(0);
if (!fElementTable) fElementTable = new TGeoElementTable(200);
if (!fTopNode) {
if (!fMasterVolume) {
Error("CloseGeometry", "Master volume not streamed");
return;
}
SetTopVolume(fMasterVolume);
if (fStreamVoxels && fgVerboseLevel>0) Info("CloseGeometry","Voxelization retrieved from file");
}
if (!GetCurrentNavigator()) fCurrentNavigator = AddNavigator();
nnavigators = GetListOfNavigators()->GetEntriesFast();
TIter next(fShapes);
TGeoShape *shape;
while ((shape = (TGeoShape*)next())) shape->AfterStreamer();
Voxelize("ALL");
CountLevels();
for (Int_t i=0; i<nnavigators; i++) {
nav = (TGeoNavigator*)GetListOfNavigators()->At(i);
nav->GetCache()->BuildInfoBranch();
if (nodeid) nav->GetCache()->BuildIdArray();
}
if (!fHashVolumes) {
Int_t nvol = fVolumes->GetEntriesFast();
Int_t ngvol = fGVolumes->GetEntriesFast();
fHashVolumes = new THashList(nvol+1);
fHashGVolumes = new THashList(ngvol+1);
Int_t i;
for (i=0; i<ngvol; i++) fHashGVolumes->AddLast(fGVolumes->At(i));
for (i=0; i<nvol; i++) fHashVolumes->AddLast(fVolumes->At(i));
}
fClosed = kTRUE;
if (fParallelWorld) {
if (fgVerboseLevel>0) Info("CloseGeometry","Recreating parallel world %s ...",fParallelWorld->GetName());
fParallelWorld->CloseGeometry();
}
if (fgVerboseLevel>0) Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
if (fgVerboseLevel>0) Info("CloseGeometry","----------------modeler ready----------------");
return;
}
if (!GetCurrentNavigator()) fCurrentNavigator = AddNavigator();
nnavigators = GetListOfNavigators()->GetEntriesFast();
SelectTrackingMedia();
CheckGeometry();
if (fgVerboseLevel>0) Info("CloseGeometry","Counting nodes...");
fNNodes = CountNodes();
fNLevel = fMasterVolume->CountNodes(1,3)+1;
if (fNLevel<30) fNLevel = 100;
Voxelize("ALL");
if (fgVerboseLevel>0) Info("CloseGeometry","Building cache...");
CountLevels();
for (Int_t i=0; i<nnavigators; i++) {
nav = (TGeoNavigator*)GetListOfNavigators()->At(i);
nav->GetCache()->BuildInfoBranch();
if (nodeid) nav->GetCache()->BuildIdArray();
}
fClosed = kTRUE;
if (fgVerboseLevel>0) {
Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
Info("CloseGeometry","----------------modeler ready----------------");
}
}
void TGeoManager::ClearOverlaps()
{
if (fOverlaps) {
fOverlaps->Delete();
delete fOverlaps;
}
fOverlaps = new TObjArray();
}
void TGeoManager::ClearShape(const TGeoShape *shape)
{
if (fShapes->FindObject(shape)) fShapes->Remove((TGeoShape*)shape);
delete shape;
}
void TGeoManager::CleanGarbage()
{
if (!fGVolumes && !fGShapes) return;
Int_t i,nentries;
if (fGVolumes) {
nentries = fGVolumes->GetEntries();
TGeoVolume *vol = 0;
for (i=0; i<nentries; i++) {
vol=(TGeoVolume*)fGVolumes->At(i);
if (vol) vol->SetFinder(0);
}
fGVolumes->Delete();
delete fGVolumes;
fGVolumes = 0;
}
if (fGShapes) {
fGShapes->Delete();
delete fGShapes;
fGShapes = 0;
}
}
void TGeoManager::CdNode(Int_t nodeid)
{
GetCurrentNavigator()->CdNode(nodeid);
}
Int_t TGeoManager::GetCurrentNodeId() const
{
return GetCurrentNavigator()->GetCurrentNodeId();
}
void TGeoManager::CdTop()
{
GetCurrentNavigator()->CdTop();
}
void TGeoManager::CdUp()
{
GetCurrentNavigator()->CdUp();
}
void TGeoManager::CdDown(Int_t index)
{
GetCurrentNavigator()->CdDown(index);
}
void TGeoManager::CdNext()
{
GetCurrentNavigator()->CdNext();
}
Bool_t TGeoManager::cd(const char *path)
{
return GetCurrentNavigator()->cd(path);
}
Bool_t TGeoManager::CheckPath(const char *path) const
{
return GetCurrentNavigator()->CheckPath(path);
}
void TGeoManager::ConvertReflections()
{
if (!fTopNode) return;
if (fgVerboseLevel>0) Info("ConvertReflections", "Converting reflections in: %s - %s ...", GetName(), GetTitle());
TGeoIterator next(fTopVolume);
TGeoNode *node;
TGeoNodeMatrix *nodematrix;
TGeoMatrix *matrix, *mclone;
TGeoVolume *reflected;
while ((node=next())) {
matrix = node->GetMatrix();
if (matrix->IsReflection()) {
mclone = new TGeoCombiTrans(*matrix);
mclone->RegisterYourself();
mclone->ReflectZ(kFALSE, kTRUE);
nodematrix = (TGeoNodeMatrix*)node;
nodematrix->SetMatrix(mclone);
reflected = node->GetVolume()->MakeReflectedVolume();
node->SetVolume(reflected);
}
}
if (fgVerboseLevel>0) Info("ConvertReflections", "Done");
}
void TGeoManager::CountLevels()
{
if (!fTopNode) {
Error("CountLevels", "Top node not defined.");
return;
}
TGeoIterator next(fTopVolume);
Bool_t fixrefs = fIsGeomReading && (fMasterVolume->GetRefCount()==1);
if (fMasterVolume->GetRefCount()>1) fMasterVolume->Release();
if (fgVerboseLevel>1 && fixrefs) Info("CountLevels", "Fixing volume reference counts");
TGeoNode *node;
Int_t maxlevel = 1;
Int_t maxnodes = fTopVolume->GetNdaughters();
Int_t maxvertices = 1;
while ((node=next())) {
if (fixrefs) {
node->GetVolume()->Grab();
for (Int_t ibit=10; ibit<14; ibit++) {
node->SetBit(BIT(ibit+4), node->TestBit(BIT(ibit)));
}
}
if (node->GetVolume()->GetVoxels()) {
if (node->GetNdaughters()>maxnodes) maxnodes = node->GetNdaughters();
}
if (next.GetLevel()>maxlevel) maxlevel = next.GetLevel();
if (node->GetVolume()->GetShape()->IsA()==TGeoXtru::Class()) {
TGeoXtru *xtru = (TGeoXtru*)node->GetVolume()->GetShape();
if (xtru->GetNvert()>maxvertices) maxvertices = xtru->GetNvert();
}
}
fgMaxLevel = maxlevel;
fgMaxDaughters = maxnodes;
fgMaxXtruVert = maxvertices;
if (fgVerboseLevel>0) Info("CountLevels", "max level = %d, max placements = %d", fgMaxLevel, fgMaxDaughters);
}
Int_t TGeoManager::CountNodes(const TGeoVolume *vol, Int_t nlevels, Int_t option)
{
TGeoVolume *top;
if (!vol) {
top = fTopVolume;
} else {
top = (TGeoVolume*)vol;
}
Int_t count = top->CountNodes(nlevels, option);
return count;
}
void TGeoManager::DefaultAngles()
{
if (fPainter) fPainter->DefaultAngles();
}
void TGeoManager::DrawCurrentPoint(Int_t color)
{
if (fPainter) fPainter->DrawCurrentPoint(color);
}
void TGeoManager::AnimateTracks(Double_t tmin, Double_t tmax, Int_t nframes, Option_t *option)
{
SetAnimateTracks();
GetGeomPainter();
if (tmin<0 || tmin>=tmax || nframes<1) return;
Double_t *box = fPainter->GetViewBox();
box[0] = box[1] = box[2] = 0;
box[3] = box[4] = box[5] = 100;
Double_t dt = (tmax-tmin)/Double_t(nframes);
Double_t delt = 2E-9;
Double_t t = tmin;
Int_t i, j;
TString opt(option);
Bool_t save = kFALSE, geomanim=kFALSE;
TString fname;
if (opt.Contains("/S")) save = kTRUE;
if (opt.Contains("/G")) geomanim = kTRUE;
SetTminTmax(0,0);
DrawTracks(opt.Data());
Double_t start[6], end[6];
Double_t dd[6] = {0,0,0,0,0,0};
Double_t dlat=0, dlong=0, dpsi=0;
if (geomanim) {
fPainter->EstimateCameraMove(tmin+5*dt, tmin+15*dt, start, end);
for (i=0; i<3; i++) {
start[i+3] = 20 + 1.3*start[i+3];
end[i+3] = 20 + 0.9*end[i+3];
}
for (i=0; i<6; i++) {
dd[i] = (end[i]-start[i])/10.;
}
memcpy(box, start, 6*sizeof(Double_t));
fPainter->GetViewAngles(dlong,dlat,dpsi);
dlong = (-206-dlong)/Double_t(nframes);
dlat = (126-dlat)/Double_t(nframes);
dpsi = (75-dpsi)/Double_t(nframes);
fPainter->GrabFocus();
}
for (i=0; i<nframes; i++) {
if (t-delt<0) SetTminTmax(t-delt,t);
else gGeoManager->SetTminTmax(t-delt,t);
if (geomanim) {
for (j=0; j<6; j++) box[j]+=dd[j];
fPainter->GrabFocus(1,dlong,dlat,dpsi);
} else {
ModifiedPad();
}
if (save) {
fname = TString::Format("anim%04d.gif", i);
gPad->Print(fname);
}
t += dt;
}
SetAnimateTracks(kFALSE);
}
void TGeoManager::DrawTracks(Option_t *option)
{
TVirtualGeoTrack *track;
SetAnimateTracks();
for (Int_t i=0; i<fNtracks; i++) {
track = GetTrack(i);
if (track) track->Draw(option);
}
SetAnimateTracks(kFALSE);
ModifiedPad();
}
void TGeoManager::DrawPath(const char *path, Option_t *option)
{
if (!fTopVolume) return;
fTopVolume->SetVisBranch();
GetGeomPainter()->DrawPath(path, option);
}
void TGeoManager::RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *option)
{
GetGeomPainter()->RandomPoints((TGeoVolume*)vol, npoints, option);
}
void TGeoManager::Test(Int_t npoints, Option_t *option)
{
GetGeomPainter()->Test(npoints, option);
}
void TGeoManager::TestOverlaps(const char* path)
{
GetGeomPainter()->TestOverlaps(path);
}
void TGeoManager::GetBranchNames(Int_t *names) const
{
GetCurrentNavigator()->GetBranchNames(names);
}
const char *TGeoManager::GetPdgName(Int_t pdg) const
{
static char defaultname[5] = { "XXX" };
if (!fPdgNames || !pdg) return defaultname;
for (Int_t i=0; i<fNpdg; i++) {
if (fPdgId[i]==pdg) return fPdgNames->At(i)->GetName();
}
return defaultname;
}
void TGeoManager::SetPdgName(Int_t pdg, const char *name)
{
if (!pdg) return;
if (!fPdgNames) {
fPdgNames = new TObjArray(1024);
}
if (!strcmp(name, GetPdgName(pdg))) return;
if (fNpdg>1023) {
Warning("SetPdgName", "No more than 256 different pdg codes allowed");
return;
}
fPdgId[fNpdg] = pdg;
TNamed *pdgname = new TNamed(name, "");
fPdgNames->AddAtAndExpand(pdgname, fNpdg++);
}
void TGeoManager::GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
{
GetCurrentNavigator()->GetBranchNumbers(copyNumbers, volumeNumbers);
}
void TGeoManager::GetBranchOnlys(Int_t *isonly) const
{
GetCurrentNavigator()->GetBranchOnlys(isonly);
}
void TGeoManager::GetBombFactors(Double_t &bombx, Double_t &bomby, Double_t &bombz, Double_t &bombr) const
{
if (fPainter) {
fPainter->GetBombFactors(bombx, bomby, bombz, bombr);
return;
}
bombx = bomby = bombz = bombr = 1.3;
}
Int_t TGeoManager::GetMaxDaughters()
{
return fgMaxDaughters;
}
Int_t TGeoManager::GetMaxLevels()
{
return fgMaxLevel;
}
Int_t TGeoManager::GetMaxXtruVert()
{
return fgMaxXtruVert;
}
Int_t TGeoManager::GetNumThreads()
{
return fgNumThreads;
}
TGeoHMatrix *TGeoManager::GetHMatrix()
{
if (!GetCurrentNavigator()) return NULL;
return GetCurrentNavigator()->GetHMatrix();
}
Int_t TGeoManager::GetVisLevel() const
{
return fVisLevel;
}
Int_t TGeoManager::GetVisOption() const
{
return fVisOption;
}
Int_t TGeoManager::GetVirtualLevel()
{
return GetCurrentNavigator()->GetVirtualLevel();
}
TVirtualGeoTrack *TGeoManager::FindTrackWithId(Int_t id) const
{
TVirtualGeoTrack* trk = 0;
trk = GetTrackOfId(id);
if (trk) return trk;
TIter next(fTracks);
TVirtualGeoTrack* prim;
while ((prim = (TVirtualGeoTrack*)next())) {
trk = prim->FindTrackWithId(id);
if (trk) return trk;
}
return NULL;
}
TVirtualGeoTrack *TGeoManager::GetTrackOfId(Int_t id) const
{
TVirtualGeoTrack *track;
for (Int_t i=0; i<fNtracks; i++) {
if ((track = (TVirtualGeoTrack *)fTracks->UncheckedAt(i))) {
if (track->GetId() == id) return track;
}
}
return 0;
}
TVirtualGeoTrack *TGeoManager::GetParentTrackOfId(Int_t id) const
{
TVirtualGeoTrack *track = fCurrentTrack;
while ((track=track->GetMother())) {
if (track->GetId()==id) return track;
}
return 0;
}
Int_t TGeoManager::GetTrackIndex(Int_t id) const
{
TVirtualGeoTrack *track;
for (Int_t i=0; i<fNtracks; i++) {
if ((track = (TVirtualGeoTrack *)fTracks->UncheckedAt(i))) {
if (track->GetId() == id) return i;
}
}
return -1;
}
Bool_t TGeoManager::GotoSafeLevel()
{
return GetCurrentNavigator()->GotoSafeLevel();
}
Int_t TGeoManager::GetSafeLevel() const
{
return GetCurrentNavigator()->GetSafeLevel();
}
void TGeoManager::DefaultColors()
{
const Int_t nmax = 110;
Int_t col[nmax];
for (Int_t i=0;i<nmax;i++) col[i] = kGray;
col[ 3] = kYellow-10;
col[ 4] = col[ 5] = kGreen-10;
col[ 6] = col[ 7] = kBlue-7;
col[ 8] = col[ 9] = kMagenta-3;
col[10] = col[11] = kRed-10;
col[12] = kGray+1;
col[13] = kBlue-10;
col[14] = kOrange+7;
col[16] = kYellow+1;
col[20] = kYellow-10;
col[24] = col[25] = col[26] = kBlue-8;
col[29] = kOrange+9;
col[79] = kOrange-2;
TGeoVolume *vol;
TIter next(fVolumes);
while ((vol=(TGeoVolume*)next())) {
TGeoMedium *med = vol->GetMedium();
if (!med) continue;
TGeoMaterial *mat = med->GetMaterial();
Int_t matZ = (Int_t)mat->GetZ();
vol->SetLineColor(col[matZ]);
if (mat->GetDensity()<0.1) vol->SetTransparency(60);
}
}
Double_t TGeoManager::Safety(Bool_t inside)
{
return GetCurrentNavigator()->Safety(inside);
}
void TGeoManager::SetVolumeAttribute(const char *name, const char *att, Int_t val)
{
TGeoVolume *volume;
Bool_t all = kFALSE;
if (strstr(name,"*")) all=kTRUE;
Int_t ivo=0;
TIter next(fVolumes);
TString chatt = att;
chatt.ToLower();
while ((volume=(TGeoVolume*)next())) {
if (strcmp(volume->GetName(), name) && !all) continue;
ivo++;
if (chatt.Contains("colo")) volume->SetLineColor(val);
if (chatt.Contains("lsty")) volume->SetLineStyle(val);
if (chatt.Contains("lwid")) volume->SetLineWidth(val);
if (chatt.Contains("fill")) volume->SetFillColor(val);
if (chatt.Contains("seen")) volume->SetVisibility(val);
}
TIter next1(fGVolumes);
while ((volume=(TGeoVolume*)next1())) {
if (strcmp(volume->GetName(), name) && !all) continue;
ivo++;
if (chatt.Contains("colo")) volume->SetLineColor(val);
if (chatt.Contains("lsty")) volume->SetLineStyle(val);
if (chatt.Contains("lwid")) volume->SetLineWidth(val);
if (chatt.Contains("fill")) volume->SetFillColor(val);
if (chatt.Contains("seen")) volume->SetVisibility(val);
}
if (!ivo) {
Warning("SetVolumeAttribute","volume: %s does not exist",name);
}
}
void TGeoManager::SetBombFactors(Double_t bombx, Double_t bomby, Double_t bombz, Double_t bombr)
{
if (fPainter) fPainter->SetBombFactors(bombx, bomby, bombz, bombr);
}
void TGeoManager::SetClippingShape(TGeoShape *shape)
{
TVirtualGeoPainter *painter = GetGeomPainter();
if (shape) {
if (fClippingShape && (fClippingShape!=shape)) ClearShape(fClippingShape);
fClippingShape = shape;
}
painter->SetClippingShape(shape);
}
void TGeoManager::SetMaxVisNodes(Int_t maxnodes) {
fMaxVisNodes = maxnodes;
if (maxnodes>0 && fgVerboseLevel>0)
Info("SetMaxVisNodes","Automatic visible depth for %d visible nodes", maxnodes);
if (!fPainter) return;
fPainter->CountVisibleNodes();
Int_t level = fPainter->GetVisLevel();
if (level != fVisLevel) fVisLevel = level;
}
void TGeoManager::SetTopVisible(Bool_t vis) {
GetGeomPainter();
fPainter->SetTopVisible(vis);
}
void TGeoManager::SetCheckedNode(TGeoNode *node) {
GetGeomPainter()->SetCheckedNode(node);
}
void TGeoManager::SetNmeshPoints(Int_t npoints)
{
GetGeomPainter()->SetNmeshPoints(npoints);
}
void TGeoManager::SetVisOption(Int_t option) {
if ((option>=0) && (option<3)) fVisOption=option;
if (fPainter) fPainter->SetVisOption(option);
}
void TGeoManager::ViewLeaves(Bool_t flag)
{
if (flag) SetVisOption(1);
else SetVisOption(0);
}
void TGeoManager::SetVisDensity(Double_t density)
{
fVisDensity = density;
if (fPainter) fPainter->ModifiedPad();
}
void TGeoManager::SetVisLevel(Int_t level) {
if (level>0) {
fVisLevel = level;
fMaxVisNodes = 0;
if (fgVerboseLevel>0)
Info("SetVisLevel","Automatic visible depth disabled");
if (fPainter) fPainter->CountVisibleNodes();
} else {
SetMaxVisNodes();
}
}
void TGeoManager::SortOverlaps()
{
fOverlaps->Sort();
}
void TGeoManager::OptimizeVoxels(const char *filename)
{
if (!fTopNode) {
Error("OptimizeVoxels","Geometry must be closed first");
return;
}
std::ofstream out;
TString fname = filename;
if (fname.IsNull()) fname = "tgeovox.C";
out.open(fname, std::ios::out);
if (!out.good()) {
Error("OptimizeVoxels", "cannot open file");
return;
}
TDatime t;
TString sname(fname);
sname.ReplaceAll(".C", "");
out << sname.Data()<<"()"<<std::endl;
out << "{" << std::endl;
out << "//=== Macro generated by ROOT version "<< gROOT->GetVersion()<<" : "<<t.AsString()<<std::endl;
out << "//=== Voxel optimization for " << GetTitle() << " geometry"<<std::endl;
out << "//===== <run this macro JUST BEFORE closing the geometry>"<<std::endl;
out << " TGeoVolume *vol = 0;"<<std::endl;
out << " // parse all voxelized volumes"<<std::endl;
TGeoVolume *vol = 0;
Bool_t cyltype;
TIter next(fVolumes);
while ((vol=(TGeoVolume*)next())) {
if (!vol->GetVoxels()) continue;
out<<" vol = gGeoManager->GetVolume(\""<<vol->GetName()<<"\");"<<std::endl;
cyltype = vol->OptimizeVoxels();
if (cyltype) {
out<<" vol->SetCylVoxels();"<<std::endl;
} else {
out<<" vol->SetCylVoxels(kFALSE);"<<std::endl;
}
}
out << "}" << std::endl;
out.close();
}
Int_t TGeoManager::Parse(const char *expr, TString &expr1, TString &expr2, TString &expr3)
{
TString startstr(expr);
Int_t len = startstr.Length();
Int_t i;
TString e0 = "";
expr3 = "";
for (i=0; i< len; i++) {
if (startstr(i)==' ') continue;
e0 += startstr(i, 1);
}
Int_t level = 0;
Int_t levmin = 999;
Int_t boolop = 0;
Int_t indop = 0;
Int_t iloop = 1;
Int_t lastop = 0;
Int_t lastdp = 0;
Int_t lastpp = 0;
Bool_t foundmat = kFALSE;
while (iloop==1) {
iloop = 0;
lastop = 0;
lastdp = 0;
lastpp = 0;
len = e0.Length();
for (i=0; i<len; i++) {
if (e0(i)=='(') {
if (!level) iloop++;
level++;
continue;
}
if (e0(i)==')') {
level--;
if (level==0) lastpp=i;
continue;
}
if ((e0(i)=='+') || (e0(i)=='-') || (e0(i)=='*')) {
lastop = i;
if (level<levmin) {
levmin = level;
indop = i;
}
continue;
}
if ((e0(i)==':') && (level==0)) {
lastdp = i;
continue;
}
}
if (level!=0) {
if (gGeoManager) gGeoManager->Error("Parse","paranthesys does not match");
return -1;
}
if (iloop==1 && (e0(0)=='(') && (e0(len-1)==')')) {
e0=e0(1, len-2);
continue;
}
if (foundmat) break;
if (((lastop==0) && (lastdp>0)) || ((lastpp>0) && (lastdp>lastpp) && (indop<lastpp))) {
expr3 = e0(lastdp+1, len-lastdp);
e0=e0(0, lastdp);
foundmat = kTRUE;
iloop = 1;
continue;
} else break;
}
levmin = 999;
for (i=0; i<len; i++) {
if (e0(i)=='(') {
level++;
continue;
}
if (e0(i)==')') {
level--;
continue;
}
if (level<=levmin) {
if (e0(i)=='+') {
boolop = 1;
levmin = level;
indop = i;
}
if (e0(i)=='-') {
boolop = 2;
levmin = level;
indop = i;
}
if (e0(i)=='*') {
boolop = 3;
levmin = level;
indop = i;
}
}
}
if (indop==0) {
expr1=e0;
return indop;
}
expr1 = e0(0, indop);
expr2 = e0(indop+1, len-indop);
return boolop;
}
void TGeoManager::SaveAttributes(const char *filename)
{
if (!fTopNode) {
Error("SaveAttributes","geometry must be closed first\n");
return;
}
std::ofstream out;
TString fname(filename);
if (fname.IsNull()) fname = "tgeoatt.C";
out.open(fname, std::ios::out);
if (!out.good()) {
Error("SaveAttributes", "cannot open file");
return;
}
TDatime t;
TString sname(fname);
sname.ReplaceAll(".C", "");
out << sname.Data()<<"()"<<std::endl;
out << "{" << std::endl;
out << "//=== Macro generated by ROOT version "<< gROOT->GetVersion()<<" : "<<t.AsString()<<std::endl;
out << "//=== Attributes for " << GetTitle() << " geometry"<<std::endl;
out << "//===== <run this macro AFTER loading the geometry in memory>"<<std::endl;
out << " TGeoVolume *top = gGeoManager->GetVolume(\""<<fTopVolume->GetName()<<"\");"<<std::endl;
out << " TGeoVolume *vol = 0;"<<std::endl;
out << " TGeoNode *node = 0;"<<std::endl;
out << " // clear all volume attributes and get painter"<<std::endl;
out << " gGeoManager->ClearAttributes();"<<std::endl;
out << " gGeoManager->GetGeomPainter();"<<std::endl;
out << " // set visualization modes and bomb factors"<<std::endl;
out << " gGeoManager->SetVisOption("<<GetVisOption()<<");"<<std::endl;
out << " gGeoManager->SetVisLevel("<<GetVisLevel()<<");"<<std::endl;
out << " gGeoManager->SetExplodedView("<<GetBombMode()<<");"<<std::endl;
Double_t bombx, bomby, bombz, bombr;
GetBombFactors(bombx, bomby, bombz, bombr);
out << " gGeoManager->SetBombFactors("<<bombx<<","<<bomby<<","<<bombz<<","<<bombr<<");"<<std::endl;
out << " // iterate volumes coontainer and set new attributes"<<std::endl;
TGeoVolume *vol = 0;
fTopNode->SaveAttributes(out);
TIter next(fVolumes);
while ((vol=(TGeoVolume*)next())) {
vol->SetVisStreamed(kFALSE);
}
out << " // draw top volume with new settings"<<std::endl;
out << " top->Draw();"<<std::endl;
out << " gPad->x3d();"<<std::endl;
out << "}" << std::endl;
out.close();
}
TGeoNode *TGeoManager::SearchNode(Bool_t downwards, const TGeoNode *skipnode)
{
return GetCurrentNavigator()->SearchNode(downwards, skipnode);
}
TGeoNode *TGeoManager::CrossBoundaryAndLocate(Bool_t downwards, TGeoNode *skipnode)
{
return GetCurrentNavigator()->CrossBoundaryAndLocate(downwards, skipnode);
}
TGeoNode *TGeoManager::FindNextBoundaryAndStep(Double_t stepmax, Bool_t compsafe)
{
return GetCurrentNavigator()->FindNextBoundaryAndStep(stepmax, compsafe);
}
TGeoNode *TGeoManager::FindNextBoundary(Double_t stepmax, const char *path, Bool_t frombdr)
{
return GetCurrentNavigator()->FindNextBoundary(stepmax,path, frombdr);
}
TGeoNode *TGeoManager::FindNextDaughterBoundary(Double_t *point, Double_t *dir, Int_t &idaughter, Bool_t compmatrix)
{
return GetCurrentNavigator()->FindNextDaughterBoundary(point, dir, idaughter, compmatrix);
}
void TGeoManager::ResetState()
{
GetCurrentNavigator()->ResetState();
}
TGeoNode *TGeoManager::FindNode(Bool_t safe_start)
{
return GetCurrentNavigator()->FindNode(safe_start);
}
TGeoNode *TGeoManager::FindNode(Double_t x, Double_t y, Double_t z)
{
return GetCurrentNavigator()->FindNode(x, y, z);
}
Double_t *TGeoManager::FindNormalFast()
{
return GetCurrentNavigator()->FindNormalFast();
}
Double_t *TGeoManager::FindNormal(Bool_t forward)
{
return GetCurrentNavigator()->FindNormal(forward);
}
Bool_t TGeoManager::IsSameLocation(Double_t x, Double_t y, Double_t z, Bool_t change)
{
return GetCurrentNavigator()->IsSameLocation(x,y,z,change);
}
Bool_t TGeoManager::IsSamePoint(Double_t x, Double_t y, Double_t z) const
{
return GetCurrentNavigator()->IsSamePoint(x,y,z);
}
Bool_t TGeoManager::IsInPhiRange() const
{
if (!fPhiCut) return kTRUE;
const Double_t *origin;
if (!GetCurrentNavigator() || !GetCurrentNavigator()->GetCurrentNode()) return kFALSE;
origin = ((TGeoBBox*)GetCurrentNavigator()->GetCurrentVolume()->GetShape())->GetOrigin();
Double_t point[3];
LocalToMaster(origin, &point[0]);
Double_t phi = TMath::ATan2(point[1], point[0])*TMath::RadToDeg();
if (phi<0) phi+=360.;
if ((phi>=fPhimin) && (phi<=fPhimax)) return kFALSE;
return kTRUE;
}
TGeoNode *TGeoManager::InitTrack(const Double_t *point, const Double_t *dir)
{
return GetCurrentNavigator()->InitTrack(point, dir);
}
TGeoNode *TGeoManager::InitTrack(Double_t x, Double_t y, Double_t z, Double_t nx, Double_t ny, Double_t nz)
{
return GetCurrentNavigator()->InitTrack(x,y,z,nx,ny,nz);
}
void TGeoManager::InspectState() const
{
GetCurrentNavigator()->InspectState();
}
const char *TGeoManager::GetPath() const
{
return GetCurrentNavigator()->GetPath();
}
Int_t TGeoManager::GetByteCount(Option_t * )
{
Int_t count = 0;
TIter next(fVolumes);
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next())) count += vol->GetByteCount();
TIter next1(fMatrices);
TGeoMatrix *matrix;
while ((matrix=(TGeoMatrix*)next1())) count += matrix->GetByteCount();
TIter next2(fMaterials);
TGeoMaterial *mat;
while ((mat=(TGeoMaterial*)next2())) count += mat->GetByteCount();
TIter next3(fMedia);
TGeoMedium *med;
while ((med=(TGeoMedium*)next3())) count += med->GetByteCount();
if (fgVerboseLevel>0) Info("GetByteCount","Total size of logical tree : %i bytes", count);
return count;
}
TVirtualGeoPainter *TGeoManager::GetGeomPainter()
{
if (!fPainter) {
TPluginHandler *h;
if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualGeoPainter"))) {
if (h->LoadPlugin() == -1)
return 0;
fPainter = (TVirtualGeoPainter*)h->ExecPlugin(1,this);
if (!fPainter) {
Error("GetGeomPainter", "could not create painter");
return 0;
}
}
}
return fPainter;
}
TGeoVolume *TGeoManager::GetVolume(const char *name) const
{
TString sname = name;
sname = sname.Strip();
TGeoVolume *vol = (TGeoVolume*)fVolumes->FindObject(sname.Data());
return vol;
}
TGeoVolume *TGeoManager::FindVolumeFast(const char *name, Bool_t multi)
{
if (!fHashVolumes) {
Int_t nvol = fVolumes->GetEntriesFast();
Int_t ngvol = fGVolumes->GetEntriesFast();
fHashVolumes = new THashList(nvol+1);
fHashGVolumes = new THashList(ngvol+1);
Int_t i;
for (i=0; i<ngvol; i++) fHashGVolumes->AddLast(fGVolumes->At(i));
for (i=0; i<nvol; i++) fHashVolumes->AddLast(fVolumes->At(i));
}
TString sname = name;
sname = sname.Strip();
THashList *list = fHashVolumes;
if (multi) list = fHashGVolumes;
TGeoVolume *vol = (TGeoVolume*)list->FindObject(sname.Data());
return vol;
}
Int_t TGeoManager::GetUID(const char *volname) const
{
TGeoManager *geom = (TGeoManager*)this;
TGeoVolume *vol = geom->FindVolumeFast(volname, kFALSE);
if (!vol) vol = geom->FindVolumeFast(volname, kTRUE);
if (!vol) return -1;
return vol->GetNumber();
}
TGeoMaterial *TGeoManager::FindDuplicateMaterial(const TGeoMaterial *mat) const
{
Int_t index = fMaterials->IndexOf(mat);
if (index <= 0) return 0;
TGeoMaterial *other;
for (Int_t i=0; i<index; i++) {
other = (TGeoMaterial*)fMaterials->At(i);
if (other == mat) continue;
if (other->IsEq(mat)) return other;
}
return 0;
}
TGeoMaterial *TGeoManager::GetMaterial(const char *matname) const
{
TString sname = matname;
sname = sname.Strip();
TGeoMaterial *mat = (TGeoMaterial*)fMaterials->FindObject(sname.Data());
return mat;
}
TGeoMedium *TGeoManager::GetMedium(const char *medium) const
{
TString sname = medium;
sname = sname.Strip();
TGeoMedium *med = (TGeoMedium*)fMedia->FindObject(sname.Data());
return med;
}
TGeoMedium *TGeoManager::GetMedium(Int_t numed) const
{
TIter next(fMedia);
TGeoMedium *med;
while ((med=(TGeoMedium*)next())) {
if (med->GetId()==numed) return med;
}
return 0;
}
TGeoMaterial *TGeoManager::GetMaterial(Int_t id) const
{
if (id<0 || id >= fMaterials->GetSize()) return 0;
TGeoMaterial *mat = (TGeoMaterial*)fMaterials->At(id);
return mat;
}
Int_t TGeoManager::GetMaterialIndex(const char *matname) const
{
TIter next(fMaterials);
TGeoMaterial *mat;
Int_t id = 0;
TString sname = matname;
sname = sname.Strip();
while ((mat = (TGeoMaterial*)next())) {
if (!strcmp(mat->GetName(),sname.Data()))
return id;
id++;
}
return -1;
}
void TGeoManager::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
{
GetGeomPainter()->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
}
void TGeoManager::RemoveMaterial(Int_t index)
{
TObject *obj = fMaterials->At(index);
if (obj) fMaterials->Remove(obj);
}
void TGeoManager::ResetUserData()
{
TIter next(fVolumes);
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next())) vol->SetField(0);
}
void TGeoManager::RestoreMasterVolume()
{
if (fTopVolume == fMasterVolume) return;
if (fMasterVolume) SetTopVolume(fMasterVolume);
}
void TGeoManager::Voxelize(Option_t *option)
{
TGeoVolume *vol;
if (!fStreamVoxels && fgVerboseLevel>0) Info("Voxelize","Voxelizing...");
TIter next(fVolumes);
while ((vol = (TGeoVolume*)next())) {
if (!fIsGeomReading) vol->SortNodes();
if (!fStreamVoxels) {
vol->Voxelize(option);
}
if (!fIsGeomReading) vol->FindOverlaps();
}
}
void TGeoManager::ModifiedPad() const
{
if (!fPainter) return;
fPainter->ModifiedPad();
}
TGeoVolume *TGeoManager::MakeArb8(const char *name, TGeoMedium *medium,
Double_t dz, Double_t *vertices)
{
return TGeoBuilder::Instance(this)->MakeArb8(name, medium, dz, vertices);
}
TGeoVolume *TGeoManager::MakeBox(const char *name, TGeoMedium *medium,
Double_t dx, Double_t dy, Double_t dz)
{
return TGeoBuilder::Instance(this)->MakeBox(name, medium, dx, dy, dz);
}
TGeoVolume *TGeoManager::MakePara(const char *name, TGeoMedium *medium,
Double_t dx, Double_t dy, Double_t dz,
Double_t alpha, Double_t theta, Double_t phi)
{
return TGeoBuilder::Instance(this)->MakePara(name, medium, dx, dy, dz, alpha, theta, phi);
}
TGeoVolume *TGeoManager::MakeSphere(const char *name, TGeoMedium *medium,
Double_t rmin, Double_t rmax, Double_t themin, Double_t themax,
Double_t phimin, Double_t phimax)
{
return TGeoBuilder::Instance(this)->MakeSphere(name, medium, rmin, rmax, themin, themax, phimin, phimax);
}
TGeoVolume *TGeoManager::MakeTorus(const char *name, TGeoMedium *medium, Double_t r,
Double_t rmin, Double_t rmax, Double_t phi1, Double_t dphi)
{
return TGeoBuilder::Instance(this)->MakeTorus(name, medium, r, rmin, rmax, phi1, dphi);
}
TGeoVolume *TGeoManager::MakeTube(const char *name, TGeoMedium *medium,
Double_t rmin, Double_t rmax, Double_t dz)
{
return TGeoBuilder::Instance(this)->MakeTube(name, medium, rmin, rmax, dz);
}
TGeoVolume *TGeoManager::MakeTubs(const char *name, TGeoMedium *medium,
Double_t rmin, Double_t rmax, Double_t dz,
Double_t phiStart, Double_t phiEnd)
{
return TGeoBuilder::Instance(this)->MakeTubs(name, medium, rmin, rmax, dz, phiStart, phiEnd);
}
TGeoVolume *TGeoManager::MakeEltu(const char *name, TGeoMedium *medium,
Double_t a, Double_t b, Double_t dz)
{
return TGeoBuilder::Instance(this)->MakeEltu(name, medium, a, b, dz);
}
TGeoVolume *TGeoManager::MakeHype(const char *name, TGeoMedium *medium,
Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
{
return TGeoBuilder::Instance(this)->MakeHype(name, medium, rin, stin, rout, stout, dz);
}
TGeoVolume *TGeoManager::MakeParaboloid(const char *name, TGeoMedium *medium,
Double_t rlo, Double_t rhi, Double_t dz)
{
return TGeoBuilder::Instance(this)->MakeParaboloid(name, medium, rlo, rhi, dz);
}
TGeoVolume *TGeoManager::MakeCtub(const char *name, TGeoMedium *medium,
Double_t rmin, Double_t rmax, Double_t dz, Double_t phi1, Double_t phi2,
Double_t lx, Double_t ly, Double_t lz, Double_t tx, Double_t ty, Double_t tz)
{
return TGeoBuilder::Instance(this)->MakeCtub(name, medium, rmin, rmax, dz, phi1, phi2, lx, ly, lz, tx, ty, tz);
}
TGeoVolume *TGeoManager::MakeCone(const char *name, TGeoMedium *medium,
Double_t dz, Double_t rmin1, Double_t rmax1,
Double_t rmin2, Double_t rmax2)
{
return TGeoBuilder::Instance(this)->MakeCone(name, medium, dz, rmin1, rmax1, rmin2, rmax2);
}
TGeoVolume *TGeoManager::MakeCons(const char *name, TGeoMedium *medium,
Double_t dz, Double_t rmin1, Double_t rmax1,
Double_t rmin2, Double_t rmax2,
Double_t phi1, Double_t phi2)
{
return TGeoBuilder::Instance(this)->MakeCons(name, medium, dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
}
TGeoVolume *TGeoManager::MakePcon(const char *name, TGeoMedium *medium,
Double_t phi, Double_t dphi, Int_t nz)
{
return TGeoBuilder::Instance(this)->MakePcon(name, medium, phi, dphi, nz);
}
TGeoVolume *TGeoManager::MakePgon(const char *name, TGeoMedium *medium,
Double_t phi, Double_t dphi, Int_t nedges, Int_t nz)
{
return TGeoBuilder::Instance(this)->MakePgon(name, medium, phi, dphi, nedges, nz);
}
TGeoVolume *TGeoManager::MakeTrd1(const char *name, TGeoMedium *medium,
Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
{
return TGeoBuilder::Instance(this)->MakeTrd1(name, medium, dx1, dx2, dy, dz);
}
TGeoVolume *TGeoManager::MakeTrd2(const char *name, TGeoMedium *medium,
Double_t dx1, Double_t dx2, Double_t dy1, Double_t dy2,
Double_t dz)
{
return TGeoBuilder::Instance(this)->MakeTrd2(name, medium, dx1, dx2, dy1, dy2, dz);
}
TGeoVolume *TGeoManager::MakeTrap(const char *name, TGeoMedium *medium,
Double_t dz, Double_t theta, Double_t phi, Double_t h1,
Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
Double_t tl2, Double_t alpha2)
{
return TGeoBuilder::Instance(this)->MakeTrap(name, medium, dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2);
}
TGeoVolume *TGeoManager::MakeGtra(const char *name, TGeoMedium *medium,
Double_t dz, Double_t theta, Double_t phi, Double_t twist, Double_t h1,
Double_t bl1, Double_t tl1, Double_t alpha1, Double_t h2, Double_t bl2,
Double_t tl2, Double_t alpha2)
{
return TGeoBuilder::Instance(this)->MakeGtra(name, medium, dz, theta, phi, twist, h1, bl1, tl1, alpha1, h2, bl2, tl2, alpha2);
}
TGeoVolume *TGeoManager::MakeXtru(const char *name, TGeoMedium *medium, Int_t nz)
{
return TGeoBuilder::Instance(this)->MakeXtru(name, medium, nz);
}
TGeoPNEntry *TGeoManager::SetAlignableEntry(const char *unique_name, const char *path,
Int_t uid)
{
if (!CheckPath(path)) return NULL;
if (!fHashPNE) fHashPNE = new THashList(256,3);
if (!fArrayPNE) fArrayPNE = new TObjArray(256);
TGeoPNEntry *entry = GetAlignableEntry(unique_name);
if (entry) {
Error("SetAlignableEntry", "An alignable object with name %s already existing. NOT ADDED !", unique_name);
return 0;
}
entry = new TGeoPNEntry(unique_name, path);
Int_t ientry = fHashPNE->GetSize();
fHashPNE->Add(entry);
fArrayPNE->AddAtAndExpand(entry, ientry);
if (uid>=0) {
Bool_t added = InsertPNEId(uid, ientry);
if (!added) Error("SetAlignableEntry", "A PN entry: has already uid=%i", uid);
}
return entry;
}
TGeoPNEntry *TGeoManager::GetAlignableEntry(const char *name) const
{
if (!fHashPNE) return 0;
return (TGeoPNEntry*)fHashPNE->FindObject(name);
}
TGeoPNEntry *TGeoManager::GetAlignableEntry(Int_t index) const
{
if (!fArrayPNE && !InitArrayPNE()) return 0;
return (TGeoPNEntry*)fArrayPNE->At(index);
}
TGeoPNEntry *TGeoManager::GetAlignableEntryByUID(Int_t uid) const
{
if (!fNPNEId || (!fArrayPNE && !InitArrayPNE())) return NULL;
Int_t index = TMath::BinarySearch(fNPNEId, fKeyPNEId, uid);
if (index<0 || fKeyPNEId[index]!=uid) return NULL;
return (TGeoPNEntry*)fArrayPNE->At(fValuePNEId[index]);
}
Int_t TGeoManager::GetNAlignable(Bool_t with_uid) const
{
if (!fHashPNE) return 0;
if (with_uid) return fNPNEId;
return fHashPNE->GetSize();
}
Bool_t TGeoManager::InsertPNEId(Int_t uid, Int_t ientry)
{
if (!fSizePNEId) {
fSizePNEId = 128;
fKeyPNEId = new Int_t[fSizePNEId];
memset(fKeyPNEId, 0, fSizePNEId*sizeof(Int_t));
fValuePNEId = new Int_t[fSizePNEId];
memset(fValuePNEId, 0, fSizePNEId*sizeof(Int_t));
fKeyPNEId[fNPNEId] = uid;
fValuePNEId[fNPNEId++] = ientry;
return kTRUE;
}
Int_t index = TMath::BinarySearch(fNPNEId, fKeyPNEId, uid);
if (index>0 && fKeyPNEId[index]==uid) return kFALSE;
Bool_t resize = (fNPNEId==fSizePNEId)?kTRUE:kFALSE;
if (resize) {
fSizePNEId *= 2;
Int_t *keys = new Int_t[fSizePNEId];
memset(keys, 0, fSizePNEId*sizeof(Int_t));
Int_t *values = new Int_t[fSizePNEId];
memset(values, 0, fSizePNEId*sizeof(Int_t));
memcpy(keys, fKeyPNEId, (index+1)*sizeof(Int_t));
memcpy(values, fValuePNEId, (index+1)*sizeof(Int_t));
keys[index+1] = uid;
values[index+1] = ientry;
memcpy(&keys[index+2], &fKeyPNEId[index+1], (fNPNEId-index-1)*sizeof(Int_t));
memcpy(&values[index+2], &fValuePNEId[index+1], (fNPNEId-index-1)*sizeof(Int_t));
delete [] fKeyPNEId;
fKeyPNEId = keys;
delete [] fValuePNEId;
fValuePNEId = values;
fNPNEId++;
return kTRUE;
}
Int_t i;
for (i=fNPNEId-1; i>index; i--) {
fKeyPNEId[i+1] = fKeyPNEId[i];
fValuePNEId[i+1] = fValuePNEId[i];
}
fKeyPNEId[index+1] = uid;
fValuePNEId[index+1] = ientry;
fNPNEId++;
return kTRUE;
}
TGeoPhysicalNode *TGeoManager::MakeAlignablePN(const char *name)
{
TGeoPNEntry *entry = GetAlignableEntry(name);
if (!entry) {
Error("MakeAlignablePN","No alignable object named %s found !", name);
return 0;
}
return MakeAlignablePN(entry);
}
TGeoPhysicalNode *TGeoManager::MakeAlignablePN(TGeoPNEntry *entry)
{
if (!entry) {
Error("MakeAlignablePN","No alignable object specified !");
return 0;
}
const char *path = entry->GetTitle();
if (!cd(path)) {
Error("MakeAlignablePN", "Alignable object %s poins to invalid path: %s",
entry->GetName(), path);
return 0;
}
TGeoPhysicalNode *node = MakePhysicalNode(path);
entry->SetPhysicalNode(node);
return node;
}
TGeoPhysicalNode *TGeoManager::MakePhysicalNode(const char *path)
{
TGeoPhysicalNode *node;
if (path) {
if (!CheckPath(path)) {
Error("MakePhysicalNode", "path: %s not valid", path);
return NULL;
}
node = new TGeoPhysicalNode(path);
} else {
node = new TGeoPhysicalNode(GetPath());
}
fPhysicalNodes->Add(node);
return node;
}
void TGeoManager::RefreshPhysicalNodes(Bool_t lock)
{
TIter next(gGeoManager->GetListOfPhysicalNodes());
TGeoPhysicalNode *pn;
while ((pn=(TGeoPhysicalNode*)next())) pn->Refresh();
if (fParallelWorld && fParallelWorld->IsClosed()) fParallelWorld->RefreshPhysicalNodes();
if (lock) LockGeometry();
}
void TGeoManager::ClearPhysicalNodes(Bool_t mustdelete)
{
if (mustdelete) fPhysicalNodes->Delete();
else fPhysicalNodes->Clear();
}
TGeoVolumeAssembly *TGeoManager::MakeVolumeAssembly(const char *name)
{
return TGeoBuilder::Instance(this)->MakeVolumeAssembly(name);
}
TGeoVolumeMulti *TGeoManager::MakeVolumeMulti(const char *name, TGeoMedium *medium)
{
return TGeoBuilder::Instance(this)->MakeVolumeMulti(name, medium);
}
void TGeoManager::SetExplodedView(Int_t ibomb)
{
if ((ibomb>=0) && (ibomb<4)) fExplodedView = ibomb;
if (fPainter) fPainter->SetExplodedView(ibomb);
}
void TGeoManager::SetPhiRange(Double_t phimin, Double_t phimax)
{
if ((phimin==0) && (phimax==360)) {
fPhiCut = kFALSE;
return;
}
fPhiCut = kTRUE;
fPhimin = phimin;
fPhimax = phimax;
}
void TGeoManager::SetNsegments(Int_t nseg)
{
if (fNsegments==nseg) return;
if (nseg>2) fNsegments = nseg;
if (fPainter) fPainter->SetNsegments(nseg);
}
Int_t TGeoManager::GetNsegments() const
{
return fNsegments;
}
void TGeoManager::BuildDefaultMaterials()
{
GetElementTable();
TGeoVolume::CreateDummyMedium();
}
TGeoElementTable *TGeoManager::GetElementTable()
{
if (!fElementTable) fElementTable = new TGeoElementTable(200);
return fElementTable;
}
TGeoNode *TGeoManager::Step(Bool_t is_geom, Bool_t cross)
{
return GetCurrentNavigator()->Step(is_geom, cross);
}
TGeoNode *TGeoManager::SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil,
const char* g3path)
{
return GetGeomPainter()->SamplePoints(npoints, dist, epsil, g3path);
}
void TGeoManager::SetTopVolume(TGeoVolume *vol)
{
if (fTopVolume==vol) return;
TSeqCollection *brlist = gROOT->GetListOfBrowsers();
TIter next(brlist);
TBrowser *browser = 0;
if (fTopVolume) fTopVolume->SetTitle("");
fTopVolume = vol;
vol->SetTitle("Top volume");
if (fTopNode) {
TGeoNode *topn = fTopNode;
fTopNode = 0;
while ((browser=(TBrowser*)next())) browser->RecursiveRemove(topn);
delete topn;
} else {
fMasterVolume = vol;
fMasterVolume->Grab();
fUniqueVolumes->AddAtAndExpand(vol,0);
if (fgVerboseLevel>0) Info("SetTopVolume","Top volume is %s. Master volume is %s", fTopVolume->GetName(),
fMasterVolume->GetName());
}
fTopNode = new TGeoNodeMatrix(vol, gGeoIdentity);
fTopNode->SetName(TString::Format("%s_1",vol->GetName()));
fTopNode->SetNumber(1);
fTopNode->SetTitle("Top logical node");
fNodes->AddAt(fTopNode, 0);
if (!GetCurrentNavigator()) {
fCurrentNavigator = AddNavigator();
return;
}
Int_t nnavigators = 0;
TGeoNavigatorArray *arr = GetListOfNavigators();
if (!arr) return;
nnavigators = arr->GetEntriesFast();
for (Int_t i=0; i<nnavigators; i++) {
TGeoNavigator *nav = (TGeoNavigator*)arr->At(i);
nav->ResetAll();
if (fClosed) nav->GetCache()->BuildInfoBranch();
}
}
void TGeoManager::SelectTrackingMedia()
{
}
void TGeoManager::CheckBoundaryErrors(Int_t ntracks, Double_t radius)
{
GetGeomPainter()->CheckBoundaryErrors(ntracks, radius);
}
void TGeoManager::CheckBoundaryReference(Int_t icheck)
{
GetGeomPainter()->CheckBoundaryReference(icheck);
}
void TGeoManager::CheckPoint(Double_t x, Double_t y, Double_t z, Option_t *option)
{
GetGeomPainter()->CheckPoint(x,y,z,option);
}
void TGeoManager::CheckShape(TGeoShape *shape, Int_t testNo, Int_t nsamples, Option_t *option)
{
GetGeomPainter()->CheckShape(shape, testNo, nsamples, option);
}
void TGeoManager::CheckGeometryFull(Int_t ntracks, Double_t vx, Double_t vy, Double_t vz, Option_t *option)
{
TString opt(option);
opt.ToLower();
if (!opt.Length()) {
Error("CheckGeometryFull","The option string must contain a letter. See method documentation.");
return;
}
Bool_t checkoverlaps = opt.Contains("o");
Bool_t checkcrossings = opt.Contains("b");
Double_t vertex[3];
vertex[0] = vx;
vertex[1] = vy;
vertex[2] = vz;
GetGeomPainter()->CheckGeometryFull(checkoverlaps,checkcrossings,ntracks,vertex);
}
void TGeoManager::CheckGeometry(Option_t * )
{
if (fgVerboseLevel>0) Info("CheckGeometry","Fixing runtime shapes...");
TIter next(fShapes);
TIter nextv(fVolumes);
TGeoShape *shape;
TGeoVolume *vol;
Bool_t has_runtime = kFALSE;
while ((shape = (TGeoShape*)next())) {
if (shape->IsRunTimeShape()) {
has_runtime = kTRUE;
}
if (fIsGeomReading) shape->AfterStreamer();
if (shape->TestShapeBit(TGeoShape::kGeoPcon) || shape->TestShapeBit(TGeoShape::kGeoArb8))
if (!shape->TestShapeBit(TGeoShape::kGeoClosedShape)) shape->ComputeBBox();
}
if (has_runtime) fTopNode->CheckShapes();
else if (fgVerboseLevel>0) Info("CheckGeometry","...Nothing to fix");
TGeoMedium *dummy = TGeoVolume::DummyMedium();
while ((vol = (TGeoVolume*)nextv())) {
if (vol->IsAssembly()) vol->GetShape()->ComputeBBox();
else if (vol->GetMedium() == dummy) {
Warning("CheckGeometry", "Volume \"%s\" has no medium: assigned dummy medium and material", vol->GetName());
vol->SetMedium(dummy);
}
}
}
void TGeoManager::CheckOverlaps(Double_t ovlp, Option_t * option)
{
if (!fTopNode) {
Error("CheckOverlaps","Top node not set");
return;
}
fTopNode->CheckOverlaps(ovlp,option);
}
void TGeoManager::PrintOverlaps() const
{
if (!fOverlaps) return;
Int_t novlp = fOverlaps->GetEntriesFast();
if (!novlp) return;
TGeoManager *geom = (TGeoManager*)this;
geom->GetGeomPainter()->PrintOverlaps();
}
Double_t TGeoManager::Weight(Double_t precision, Option_t *option)
{
GetGeomPainter();
TString opt(option);
opt.ToLower();
Double_t weight;
TGeoVolume *volume = fTopVolume;
if (opt.Contains("v")) {
if (opt.Contains("a")) {
if (fgVerboseLevel>0) Info("Weight", "Computing analytically weight of %s", volume->GetName());
weight = volume->WeightA();
if (fgVerboseLevel>0) Info("Weight", "Computed weight: %f [kg]\n", weight);
return weight;
}
if (fgVerboseLevel>0) {
Info("Weight", "Estimating weight of %s with %g %% precision", fTopVolume->GetName(), 100.*precision);
printf(" event weight err\n");
printf("========================================\n");
}
}
weight = fPainter->Weight(precision, option);
return weight;
}
ULong_t TGeoManager::SizeOf(const TGeoNode * , Option_t * )
{
return 0;
}
void TGeoManager::Streamer(TBuffer &R__b)
{
if (R__b.IsReading()) {
R__b.ReadClassBuffer(TGeoManager::Class(), this);
fIsGeomReading = kTRUE;
CloseGeometry();
fStreamVoxels = kFALSE;
fIsGeomReading = kFALSE;
} else {
R__b.WriteClassBuffer(TGeoManager::Class(), this);
}
}
void TGeoManager::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
if (!fPainter) return;
fPainter->ExecuteManagerEvent(this, event, px, py);
}
Int_t TGeoManager::Export(const char *filename, const char *name, Option_t *option)
{
TString sfile(filename);
if (sfile.Contains(".C")) {
if (fgVerboseLevel>0) Info("Export","Exporting %s %s as C++ code", GetName(), GetTitle());
fTopVolume->SaveAs(filename);
return 1;
}
if (sfile.Contains(".gdml")) {
if (fgVerboseLevel>0) Info("Export","Exporting %s %s as gdml code", GetName(), GetTitle());
TString cmd ;
cmd = TString::Format("TGDMLWrite::StartGDMLWriting(gGeoManager,\"%s\",\"%s\")", filename, option);
gROOT->ProcessLineFast(cmd);
return 1;
}
if (sfile.Contains(".root") || sfile.Contains(".xml")) {
TFile *f = TFile::Open(filename,"recreate");
if (!f || f->IsZombie()) {
Error("Export","Cannot open file");
return 0;
}
TString keyname = name;
if (keyname.IsNull()) keyname = GetName();
TString opt = option;
opt.ToLower();
if (opt.Contains("v")) {
fStreamVoxels = kTRUE;
if (fgVerboseLevel>0) Info("Export","Exporting %s %s as root file. Optimizations streamed.", GetName(), GetTitle());
} else {
fStreamVoxels = kFALSE;
if (fgVerboseLevel>0) Info("Export","Exporting %s %s as root file. Optimizations not streamed.", GetName(), GetTitle());
}
Int_t nbytes = Write(keyname);
fStreamVoxels = kFALSE;
delete f;
return nbytes;
}
return 0;
}
void TGeoManager::LockGeometry()
{
fgLock = kTRUE;
}
void TGeoManager::UnlockGeometry()
{
fgLock = kFALSE;
}
Bool_t TGeoManager::IsLocked()
{
return fgLock;
}
Int_t TGeoManager::GetVerboseLevel()
{
return fgVerboseLevel;
}
void TGeoManager::SetVerboseLevel(Int_t vl)
{
fgVerboseLevel = vl;
}
TGeoManager *TGeoManager::Import(const char *filename, const char *name, Option_t * )
{
if (fgLock) {
::Warning("TGeoManager::Import", "TGeoMananager in lock mode. NOT IMPORTING new geometry");
return NULL;
}
if (!filename) return 0;
if (fgVerboseLevel>0) ::Info("TGeoManager::Import","Reading geometry from file: %s",filename);
if (gGeoManager) delete gGeoManager;
gGeoManager = 0;
if (strstr(filename,".gdml")) {
new TGeoManager("GDMLImport", "Geometry imported from GDML");
TString cmd = TString::Format("TGDMLParse::StartGDML(\"%s\")", filename);
TGeoVolume* world = (TGeoVolume*)gROOT->ProcessLineFast(cmd);
if(world == 0) {
::Error("TGeoManager::Import", "Cannot open file");
}
else {
gGeoManager->SetTopVolume(world);
gGeoManager->CloseGeometry();
gGeoManager->DefaultColors();
}
} else {
TDirectory::TContext ctxt;
TFile *f = 0;
if (strstr(filename,"http")) f = TFile::Open(filename,"CACHEREAD");
else f = TFile::Open(filename);
if (!f || f->IsZombie()) {
::Error("TGeoManager::Import", "Cannot open file");
return 0;
}
if (name && strlen(name) > 0) {
gGeoManager = (TGeoManager*)f->Get(name);
} else {
TIter next(f->GetListOfKeys());
TKey *key;
while ((key = (TKey*)next())) {
if (strcmp(key->GetClassName(),"TGeoManager") != 0) continue;
gGeoManager = (TGeoManager*)key->ReadObj();
break;
}
}
delete f;
}
if (!gGeoManager) return 0;
if (!gROOT->GetListOfGeometries()->FindObject(gGeoManager)) gROOT->GetListOfGeometries()->Add(gGeoManager);
if (!gROOT->GetListOfBrowsables()->FindObject(gGeoManager)) gROOT->GetListOfBrowsables()->Add(gGeoManager);
gGeoManager->UpdateElements();
return gGeoManager;
}
void TGeoManager::UpdateElements()
{
if (!fElementTable) return;
TIter next(fMaterials);
TGeoMaterial *mat;
TGeoMixture *mix;
TGeoElement *elem, *elem_table;
Int_t i, nelem;
while ((mat=(TGeoMaterial*)next())) {
if (mat->IsMixture()) {
mix = (TGeoMixture*)mat;
nelem = mix->GetNelements();
for (i=0; i<nelem; i++) {
elem = mix->GetElement(i);
if (!elem) continue;
elem_table = fElementTable->GetElement(elem->Z());
if (!elem_table) continue;
if (elem != elem_table) {
elem_table->SetDefined(elem->IsDefined());
elem_table->SetUsed(elem->IsUsed());
} else {
elem_table->SetDefined();
}
}
} else {
elem = mat->GetElement();
if (!elem) continue;
elem_table = fElementTable->GetElement(elem->Z());
if (!elem_table) continue;
if (elem != elem_table) {
elem_table->SetDefined(elem->IsDefined());
elem_table->SetUsed(elem->IsUsed());
} else {
elem_table->SetUsed();
}
}
}
}
Bool_t TGeoManager::InitArrayPNE() const
{
if (fHashPNE) {
fArrayPNE = new TObjArray(fHashPNE->GetSize());
TIter next(fHashPNE);
TObject *obj;
while ((obj = next())) {
fArrayPNE->Add(obj);
}
return kTRUE;
}
return kFALSE;
}
Bool_t TGeoManager::GetTminTmax(Double_t &tmin, Double_t &tmax) const
{
tmin = fTmin;
tmax = fTmax;
return fTimeCut;
}
void TGeoManager::SetTminTmax(Double_t tmin, Double_t tmax)
{
fTmin = tmin;
fTmax = tmax;
if (tmin==0 && tmax==999) fTimeCut = kFALSE;
else fTimeCut = kTRUE;
if (fTracks && !IsAnimatingTracks()) ModifiedPad();
}
void TGeoManager::MasterToTop(const Double_t *master, Double_t *top) const
{
GetCurrentNavigator()->MasterToLocal(master, top);
}
void TGeoManager::TopToMaster(const Double_t *top, Double_t *master) const
{
GetCurrentNavigator()->LocalToMaster(top, master);
}
TGeoParallelWorld *TGeoManager::CreateParallelWorld(const char *name)
{
fParallelWorld = new TGeoParallelWorld(name, this);
return fParallelWorld;
}
void TGeoManager::SetUseParallelWorldNav(Bool_t flag)
{
if (!fParallelWorld) {
Error("SetUseParallelWorldNav", "No parallel world geometry defined. Use CreateParallelWorld.");
return;
}
if (!flag) {
fUsePWNav = flag;
return;
}
if (!fClosed) {
Error("SetUseParallelWorldNav", "The geometry must be closed first");
return;
}
if (fParallelWorld->CloseGeometry()) fUsePWNav=kTRUE;
}