//Begin_Html
/*
<img src="gif/t_graf.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_root.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_mgr.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_browser.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_frame0.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_frame1.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_frameexp.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_checkpoint.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_random1.jpg">
*/
//End_Html
//Begin_Html
/*
<img src="gif/t_random2.jpg">
*/
//End_Html
#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 "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 "TVirtualGeoPainter.h"
#include "TPluginManager.h"
#include "TVirtualGeoTrack.h"
#include "TQObject.h"
TGeoManager *gGeoManager = 0;
const char *kGeoOutsidePath = " ";
const Int_t kN3 = 3*sizeof(Double_t);
ClassImp(TGeoManager)
Bool_t TGeoManager::fgLock = kFALSE;
TGeoManager::TGeoManager()
{
if (TClass::IsCallingNew() == TClass::kDummyNew) {
fTimeCut = kFALSE;
fTmin = 0.;
fTmax = 999.;
fPhiCut = kFALSE;
fPhimin = 0;
fPhimax = 360;
fDrawExtra = kFALSE;
fStreamVoxels = kFALSE;
fIsGeomReading = kFALSE;
fSearchOverlaps = kFALSE;
fLoopVolumes = kFALSE;
fStartSafe = kTRUE;
fSafety = 0;
fLastSafety = -1.;
fStep = 0;
fBits = 0;
fMaterials = 0;
fHashPNE = 0;
fMatrices = 0;
fNodes = 0;
fOverlaps = 0;
fNNodes = 0;
fLevel = 0;
fNmany = 0;
fMaxVisNodes = 10000;
memset(fLastPoint, 0, kN3);
fPoint = 0;
fDirection = 0;
fCldirChecked = 0;
memset(fNormal, 0, kN3);
fCldir = 0;
fVolumes = 0;
fPhysicalNodes = 0;
fShapes = 0;
fGVolumes = 0;
fGShapes = 0;
fTracks = 0;
fMedia = 0;
fNtracks = 0;
fNpdg = 0;
fPdgNames = 0;
memset(fPdgId, 0, 256*sizeof(Int_t));
fCurrentTrack = 0;
fTopVolume = 0;
fTopNode = 0;
fCurrentVolume = 0;
fMasterVolume = 0;
fCurrentNode = 0;
fLastNode = 0;
fCurrentOverlapping = kFALSE;
fPath = "";
fCache = 0;
fPainter = 0;
fActivity = kFALSE;
fIsEntering = kFALSE;
fIsExiting = kFALSE;
fIsNodeSelectable = kFALSE;
fIsStepEntering = kFALSE;
fIsStepExiting = kFALSE;
fIsOutside = kFALSE;
fIsOnBoundary = kFALSE;
fIsSameLocation = kTRUE;
fIsNullStep = kFALSE;
fVisDensity = 0.;
fVisLevel = 3;
fVisOption = 1;
fExplodedView = 0;
fNsegments = 20;
fNLevel = 0;
fCurrentMatrix = 0;
fUniqueVolumes = 0;
fNodeIdArray = 0;
fClippingShape = 0;
fIntSize = fDblSize = 1000;
fIntBuffer = 0;
fDblBuffer = 0;
fOverlapMark = 0;
fOverlapSize = 1000;
fOverlapClusters = 0;
fMatrixTransform = kFALSE;
fMatrixReflection = kFALSE;
fGLMatrix = 0;
fPaintVolume = 0;
fElementTable = 0;
fHashVolumes = 0;
fHashGVolumes = 0;
} else {
Init();
gGeoIdentity = 0;
}
}
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();
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;
fTimeCut = kFALSE;
fTmin = 0.;
fTmax = 999.;
fPhiCut = kFALSE;
fPhimin = 0;
fPhimax = 360;
fDrawExtra = kFALSE;
fStreamVoxels = kFALSE;
fIsGeomReading = kFALSE;
fSearchOverlaps = kFALSE;
fLoopVolumes = kFALSE;
fStartSafe = kTRUE;
fSafety = 0;
fLastSafety = -1.;
fStep = 0;
fBits = new UChar_t[50000];
fHashPNE = new THashList(256,3);
fMaterials = new THashList(200,3);
fMatrices = new TObjArray(256);
fNodes = new TObjArray(30);
fOverlaps = new TObjArray(256);
fNNodes = 0;
fLevel = 0;
fNmany = 0;
fMaxVisNodes = 10000;
memset(fLastPoint, 0, kN3);
fPoint = new Double_t[3];
fDirection = new Double_t[3];
fCldirChecked = new Double_t[3];
memset(fNormal, 0, kN3);
fCldir = new Double_t[3];
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, 256*sizeof(Int_t));
fCurrentTrack = 0;
fTopVolume = 0;
fTopNode = 0;
fCurrentVolume = 0;
fMasterVolume = 0;
fCurrentNode = 0;
fLastNode = 0;
fCurrentOverlapping = kFALSE;
fPath = "";
fCache = 0;
fPainter = 0;
fActivity = kFALSE;
fIsEntering = kFALSE;
fIsExiting = kFALSE;
fIsStepEntering = kFALSE;
fIsStepExiting = kFALSE;
fIsNodeSelectable = kFALSE;
fIsOutside = kFALSE;
fIsOnBoundary = kFALSE;
fIsSameLocation = kTRUE;
fIsNullStep = kFALSE;
fVisDensity = 0.;
fVisLevel = 3;
fVisOption = 1;
fExplodedView = 0;
fNsegments = 20;
fNLevel = 0;
fCurrentMatrix = 0;
fUniqueVolumes = new TObjArray(256);
fNodeIdArray = 0;
fClippingShape = 0;
fIntSize = fDblSize = 1000;
fIntBuffer = new Int_t[1000];
fDblBuffer = new Double_t[1000];
fOverlapMark = 0;
fOverlapSize = 1000;
fOverlapClusters = new Int_t[fOverlapSize];
fMatrixTransform = kFALSE;
fMatrixReflection = kFALSE;
fGLMatrix = new TGeoHMatrix();
fPaintVolume = 0;
fElementTable = 0;
fHashVolumes = 0;
fHashGVolumes = 0;
}
TGeoManager::TGeoManager(const TGeoManager& gm) :
TNamed(gm),
fStep(gm.fStep),
fSafety(gm.fSafety),
fLastSafety(gm.fLastSafety),
fPhimin(gm.fPhimin),
fPhimax(gm.fPhimax),
fTmin(gm.fTmin),
fTmax(gm.fTmax),
fLevel(gm.fLevel),
fNNodes(gm.fNNodes),
fPath(gm.fPath),
fParticleName(gm.fParticleName),
fCldir(gm.fCldir),
fCldirChecked(gm.fCldirChecked),
fPoint(gm.fPoint),
fDirection(gm.fDirection),
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),
fSearchOverlaps(gm.fSearchOverlaps),
fCurrentOverlapping(gm.fCurrentOverlapping),
fLoopVolumes(gm.fLoopVolumes),
fStartSafe(gm.fStartSafe),
fIsEntering(gm.fIsEntering),
fIsExiting(gm.fIsExiting),
fIsStepEntering(gm.fIsStepEntering),
fIsStepExiting(gm.fIsStepExiting),
fIsOutside(gm.fIsOutside),
fIsOnBoundary(gm.fIsOnBoundary),
fIsSameLocation(gm.fIsSameLocation),
fIsNullStep(gm.fIsNullStep),
fStreamVoxels(gm.fStreamVoxels),
fIsGeomReading(gm.fIsGeomReading),
fPhiCut(gm.fPhiCut),
fTimeCut(gm.fTimeCut),
fDrawExtra(gm.fDrawExtra),
fMatrixTransform(gm.fMatrixTransform),
fMatrixReflection(gm.fMatrixReflection),
fActivity(gm.fActivity),
fIsNodeSelectable(gm.fIsNodeSelectable),
fCache(gm.fCache),
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),
fCurrentVolume(gm.fCurrentVolume),
fTopVolume(gm.fTopVolume),
fCurrentNode(gm.fCurrentNode),
fTopNode(gm.fTopNode),
fLastNode(gm.fLastNode),
fNextNode(gm.fNextNode),
fMasterVolume(gm.fMasterVolume),
fCurrentMatrix(gm.fCurrentMatrix),
fGLMatrix(gm.fGLMatrix),
fUniqueVolumes(gm.fUniqueVolumes),
fClippingShape(gm.fClippingShape),
fElementTable(gm.fElementTable),
fNodeIdArray(gm.fNodeIdArray),
fIntSize(gm.fIntSize),
fDblSize(gm.fDblSize),
fOverlapSize(gm.fOverlapSize),
fOverlapMark(gm.fOverlapMark),
fIntBuffer(gm.fIntBuffer),
fOverlapClusters(gm.fOverlapClusters),
fNLevel(gm.fNLevel),
fNmany(gm.fNmany),
fDblBuffer(gm.fDblBuffer),
fPaintVolume(gm.fPaintVolume),
fHashVolumes(gm.fHashVolumes),
fHashGVolumes(gm.fHashGVolumes),
fHashPNE(gm.fHashPNE)
{
for(Int_t i=0; i<3; i++) {
fNormal[i]=gm.fNormal[i];
fLastPoint[i]=gm.fLastPoint[i];
}
for(Int_t i=0; i<256; i++)
fPdgId[i]=gm.fPdgId[i];
}
TGeoManager& TGeoManager::operator=(const TGeoManager& gm)
{
if(this!=&gm) {
TNamed::operator=(gm);
fStep=gm.fStep;
fSafety=gm.fSafety;
fLastSafety=gm.fLastSafety;
fPhimin=gm.fPhimin;
fPhimax=gm.fPhimax;
fTmin=gm.fTmin;
fTmax=gm.fTmax;
fLevel=gm.fLevel;
fNNodes=gm.fNNodes;
fPath=gm.fPath;
fParticleName=gm.fParticleName;
for(Int_t i=0; i<3; i++) {
fNormal[i]=gm.fNormal[i];
fLastPoint[i]=gm.fLastPoint[i];
}
fCldir=gm.fCldir;
fCldirChecked=gm.fCldirChecked;
fPoint=gm.fPoint;
fDirection=gm.fDirection;
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<256; i++)
fPdgId[i]=gm.fPdgId[i];
fSearchOverlaps=gm.fSearchOverlaps;
fCurrentOverlapping=gm.fCurrentOverlapping;
fLoopVolumes=gm.fLoopVolumes;
fStartSafe=gm.fStartSafe;
fIsEntering=gm.fIsEntering;
fIsExiting=gm.fIsExiting;
fIsStepEntering=gm.fIsStepEntering;
fIsStepExiting=gm.fIsStepExiting;
fIsOutside=gm.fIsOutside;
fIsOnBoundary=gm.fIsOnBoundary;
fIsSameLocation=gm.fIsSameLocation;
fIsNullStep=gm.fIsNullStep;
fStreamVoxels=gm.fStreamVoxels;
fIsGeomReading=gm.fIsGeomReading;
fPhiCut=gm.fPhiCut;
fTimeCut=gm.fTimeCut;
fDrawExtra=gm.fDrawExtra;
fMatrixTransform=gm.fMatrixTransform;
fMatrixReflection=gm.fMatrixReflection;
fActivity=gm.fActivity;
fIsNodeSelectable=gm.fIsNodeSelectable;
fCache=gm.fCache;
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;
fCurrentVolume=gm.fCurrentVolume;
fTopVolume=gm.fTopVolume;
fCurrentNode=gm.fCurrentNode;
fTopNode=gm.fTopNode;
fLastNode=gm.fLastNode;
fNextNode=gm.fNextNode;
fMasterVolume=gm.fMasterVolume;
fCurrentMatrix=gm.fCurrentMatrix;
fGLMatrix=gm.fGLMatrix;
fUniqueVolumes=gm.fUniqueVolumes;
fClippingShape=gm.fClippingShape;
fElementTable=gm.fElementTable;
fNodeIdArray=gm.fNodeIdArray;
fIntSize=gm.fIntSize;
fDblSize=gm.fDblSize;
fOverlapSize=gm.fOverlapSize;
fOverlapMark=gm.fOverlapMark;
fIntBuffer=gm.fIntBuffer;
fOverlapClusters=gm.fOverlapClusters;
fNLevel=gm.fNLevel;
fNmany=gm.fNmany;
fDblBuffer=gm.fDblBuffer;
fPaintVolume=gm.fPaintVolume;
fHashVolumes=gm.fHashVolumes;
fHashGVolumes=gm.fHashGVolumes;
fHashPNE=gm.fHashPNE;
}
return *this;
}
TGeoManager::~TGeoManager()
{
if (gGeoManager != this) gGeoManager = this;
gROOT->GetListOfGeometries()->Remove(this);
gROOT->GetListOfBrowsables()->Remove(this);
delete [] fBits;
if (fCache) delete fCache;
if (fNodes) delete fNodes;
if (fTopNode) delete fTopNode;
if (fOverlaps) {fOverlaps->Delete(); delete fOverlaps;}
if (fMaterials) {fMaterials->Delete(); delete fMaterials;}
if (fElementTable) delete fElementTable;
if (fMedia) {fMedia->Delete(); delete fMedia;}
if (fHashVolumes) delete fHashVolumes;
if (fHashGVolumes) delete fHashGVolumes;
if (fHashPNE) {fHashPNE->Delete(); delete fHashPNE;}
if (fVolumes) {fVolumes->Delete(); delete fVolumes;}
fVolumes = 0;
if (fShapes) {fShapes->Delete(); delete fShapes;}
if (fPhysicalNodes) {fPhysicalNodes->Delete(); delete fPhysicalNodes;}
if (fMatrices) {fMatrices->Delete(); delete fMatrices;}
if (fTracks) {fTracks->Delete(); delete fTracks;}
if (fUniqueVolumes) delete fUniqueVolumes;
if (fPdgNames) {fPdgNames->Delete(); delete fPdgNames;}
CleanGarbage();
if (fPainter) delete fPainter;
delete [] fPoint;
delete [] fDirection;
delete [] fCldirChecked;
delete [] fCldir;
delete [] fDblBuffer;
delete [] fIntBuffer;
delete [] fOverlapClusters;
delete fGLMatrix;
gGeoIdentity = 0;
gGeoManager = 0;
}
Int_t TGeoManager::AddMaterial(const TGeoMaterial *material)
{
if (!material) {
Error("AddMaterial", "invalid material");
return -1;
}
Int_t index = fMaterials->GetSize();
((TGeoMaterial*)material)->SetIndex(index);
fMaterials->Add((TGeoMaterial*)material);
return index;
}
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)
{
if (!matrix) {
Error("AddMatrix", "invalid matrix");
return -1;
}
Int_t index = fMatrices->GetEntriesFast();
fMatrices->AddAtAndExpand((TGeoMatrix*)matrix,index);
return index;
}
Int_t TGeoManager::AddShape(const TGeoShape *shape)
{
if (!shape) {
Error("AddShape", "invalid shape");
return -1;
}
TObjArray *list = fShapes;
if (shape->IsRunTimeShape()) list = fGShapes;;
Int_t index = list->GetEntriesFast();
list->AddAtAndExpand((TGeoShape*)shape,index);
return index;
}
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;
}
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;
}
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);
TQObject::Connect("TRootBrowser", "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::BuildCache(Bool_t dummy, Bool_t nodeid)
{
static Bool_t first = kTRUE;
if (!fCache) {
if (fNLevel<30) {
fNLevel = 100;
if (first) Info("BuildCache","--- Maximum geometry depth set to 100");
} else {
if (first) Info("BuildCache","--- Maximum geometry depth is %i", fNLevel);
}
if (fNNodes>5000000 || dummy)
fCache = new TGeoCacheDummy(fTopNode, nodeid, fNLevel+1);
else
fCache = new TGeoNodeCache(fNLevel+1,nodeid);
}
first = kFALSE;
}
void TGeoManager::BuildIdArray()
{
if (fCache) fCache->BuildIdArray();
}
void TGeoManager::RegisterMatrix(const TGeoMatrix *matrix)
{
if (matrix->IsRegistered()) return;
TGeoMatrix *mat = (TGeoMatrix*)matrix;
Int_t nmat = fMatrices->GetEntriesFast();
fMatrices->AddAtAndExpand(mat, nmat);
}
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)
{
TGeoVolume *amother;
TString sname = name;
sname = sname.Strip();
const char *vname = sname.Data();
TString smname = mother;
smname = smname.Strip();
const char *mname = smname.Data();
amother = (TGeoVolume*)fGVolumes->FindObject(mname);
if (!amother) amother = GetVolume(mname);
if (amother) return amother->Divide(vname,iaxis,ndiv,start,step,numed, option);
Error("Division","VOLUME: \"%s\" not defined",mname);
return 0;
}
void TGeoManager::Matrix(Int_t index, Double_t theta1, Double_t phi1,
Double_t theta2, Double_t phi2,
Double_t theta3, Double_t phi3)
{
TGeoRotation * rot = new TGeoRotation("",theta1,phi1,theta2,phi2,theta3,phi3);
rot->SetUniqueID(index);
rot->RegisterYourself();
}
TGeoMaterial *TGeoManager::Material(const char *name, Double_t a, Double_t z, Double_t dens, Int_t uid,Double_t radlen, Double_t intlen)
{
TGeoMaterial *material = new TGeoMaterial(name,a,z,dens,radlen,intlen);
material->SetUniqueID(uid);
return material;
}
TGeoMaterial *TGeoManager::Mixture(const char *name, Float_t *a, Float_t *z, Double_t dens,
Int_t nelem, Float_t *wmat, Int_t uid)
{
TGeoMixture *mix = new TGeoMixture(name,nelem,dens);
mix->SetUniqueID(uid);
Int_t i;
for (i=0;i<nelem;i++) {
mix->DefineElement(i,a[i],z[i],wmat[i]);
}
return (TGeoMaterial*)mix;
}
TGeoMaterial *TGeoManager::Mixture(const char *name, Double_t *a, Double_t *z, Double_t dens,
Int_t nelem, Double_t *wmat, Int_t uid)
{
TGeoMixture *mix = new TGeoMixture(name,nelem,dens);
mix->SetUniqueID(uid);
Int_t i;
for (i=0;i<nelem;i++) {
mix->DefineElement(i,a[i],z[i],wmat[i]);
}
return (TGeoMaterial*)mix;
}
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 new TGeoMedium(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)
{
TGeoVolume *amother= 0;
TGeoVolume *volume = 0;
amother = FindVolumeFast(mother,kTRUE);
if (!amother) amother = FindVolumeFast(mother);
if (!amother) {
TString mname = mother;
mname = mname.Strip();
Error("Node","Mother VOLUME \"%s\" not defined",mname.Data());
return;
}
Int_t i;
if (npar<=0) {
if (gDebug > 0) Info("Node","Calling gspos, mother=%s, name=%s, nr=%d, x=%g, y=%g, z=%g, irot=%d, konly=%i",mother,name,nr,x,y,z,irot,(Int_t)isOnly);
volume = FindVolumeFast(name,kTRUE);
if (!volume) volume = FindVolumeFast(name);
if (!volume) {
TString vname = name;
vname = vname.Strip();
Error("Node","VOLUME: \"%s\" not defined",vname.Data());
return;
}
if (((TObject*)volume)->TestBit(TGeoVolume::kVolumeMulti) && !volume->GetShape()) {
Error("Node", "cannot add multiple-volume object %s as node", volume->GetName());
return;
}
} else {
TGeoVolumeMulti *vmulti = (TGeoVolumeMulti*)FindVolumeFast(name, kTRUE);
if (!vmulti) {
volume = FindVolumeFast(name);
if (volume) {
Warning("Node", "volume: %s is defined as single -> ignoring shape parameters", volume->GetName());
Node(name,nr,mother,x,y,z,irot,isOnly, upar);
return;
}
TString vname = name;
vname = vname.Strip();
Error("Node","VOLUME: \"%s\" not defined ",vname.Data());
return;
}
TGeoMedium *medium = vmulti->GetMedium();
TString sh = vmulti->GetTitle();
sh.ToLower();
if (sh.Contains("box")) {
volume = MakeBox(name,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("trd1")) {
volume = MakeTrd1(name,medium,upar[0],upar[1],upar[2],upar[3]);
} else if (sh.Contains("trd2")) {
volume = MakeTrd2(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("trap")) {
volume = MakeTrap(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
} else if (sh.Contains("gtra")) {
volume = MakeGtra(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10],upar[11]);
} else if (sh.Contains("tube")) {
volume = MakeTube(name,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("tubs")) {
volume = MakeTubs(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("cone")) {
volume = MakeCone(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("cons")) {
volume = MakeCons(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6]);
} else if (sh.Contains("pgon")) {
volume = MakePgon(name,medium,upar[0],upar[1],(Int_t)upar[2],(Int_t)upar[3]);
Int_t nz = (Int_t)upar[3];
for (i=0;i<nz;i++) {
((TGeoPgon*)volume->GetShape())->DefineSection(i,upar[3*i+4],upar[3*i+5],upar[3*i+6]);
}
} else if (sh.Contains("pcon")) {
volume = MakePcon(name,medium,upar[0],upar[1],(Int_t)upar[2]);
Int_t nz = (Int_t)upar[2];
for (i=0;i<nz;i++) {
((TGeoPcon*)volume->GetShape())->DefineSection(i,upar[3*i+3],upar[3*i+4],upar[3*i+5]);
}
} else if (sh.Contains("eltu")) {
volume = MakeEltu(name,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("sphe")) {
volume = MakeSphere(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
} else if (sh.Contains("ctub")) {
volume = MakeCtub(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
} else if (sh.Contains("para")) {
volume = MakePara(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
} else {
Error("Node","cannot create shape %s",sh.Data());
}
if (!volume) return;
vmulti->AddVolume(volume);
}
if (irot) {
TGeoRotation *matrix = 0;
TGeoMatrix *mat;
TIter next(fMatrices);
while ((mat=(TGeoMatrix*)next())) {
if (mat->GetUniqueID()==UInt_t(irot)) {
matrix = (TGeoRotation*)mat;
break;
}
}
if (!matrix) {
Error("Node", "rotation %i not found", irot);
return;
}
if (isOnly) amother->AddNode(volume,nr,new TGeoCombiTrans(x,y,z,matrix));
else amother->AddNodeOverlap(volume,nr,new TGeoCombiTrans(x,y,z,matrix));
} else {
if (x == 0 && y== 0 && z == 0) {
if (isOnly) amother->AddNode(volume,nr);
else amother->AddNodeOverlap(volume,nr);
} else {
if (isOnly) amother->AddNode(volume,nr,new TGeoTranslation(x,y,z));
else amother->AddNodeOverlap(volume,nr,new TGeoTranslation(x,y,z));
}
}
}
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)
{
TGeoVolume *amother= 0;
TGeoVolume *volume = 0;
amother = FindVolumeFast(mother,kTRUE);
if (!amother) amother = FindVolumeFast(mother);
if (!amother) {
TString mname = mother;
mname = mname.Strip();
Error("Node","Mother VOLUME \"%s\" not defined",mname.Data());
return;
}
Int_t i;
if (npar<=0) {
if (gDebug > 0) Info("Node","Calling gspos, mother=%s, name=%s, nr=%d, x=%g, y=%g, z=%g, irot=%d, konly=%i",mother,name,nr,x,y,z,irot,(Int_t)isOnly);
volume = FindVolumeFast(name,kTRUE);
if (!volume) volume = FindVolumeFast(name);
if (!volume) {
TString vname = name;
vname = vname.Strip();
Error("Node","VOLUME: \"%s\" not defined",vname.Data());
return;
}
if (((TObject*)volume)->TestBit(TGeoVolume::kVolumeMulti) && !volume->GetShape()) {
Error("Node", "cannot add multiple-volume object %s as node", volume->GetName());
return;
}
} else {
TGeoVolumeMulti *vmulti = (TGeoVolumeMulti*)FindVolumeFast(name, kTRUE);
if (!vmulti) {
volume = FindVolumeFast(name);
if (volume) {
Warning("Node", "volume: %s is defined as single -> ignoring shape parameters", volume->GetName());
Node(name,nr,mother,x,y,z,irot,isOnly, upar);
return;
}
TString vname = name;
vname = vname.Strip();
Error("Node","VOLUME: \"%s\" not defined ",vname.Data());
return;
}
TGeoMedium *medium = vmulti->GetMedium();
TString sh = vmulti->GetTitle();
sh.ToLower();
if (sh.Contains("box")) {
volume = MakeBox(name,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("trd1")) {
volume = MakeTrd1(name,medium,upar[0],upar[1],upar[2],upar[3]);
} else if (sh.Contains("trd2")) {
volume = MakeTrd2(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("trap")) {
volume = MakeTrap(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
} else if (sh.Contains("gtra")) {
volume = MakeGtra(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10],upar[11]);
} else if (sh.Contains("tube")) {
volume = MakeTube(name,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("tubs")) {
volume = MakeTubs(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("cone")) {
volume = MakeCone(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("cons")) {
volume = MakeCons(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6]);
} else if (sh.Contains("pgon")) {
volume = MakePgon(name,medium,upar[0],upar[1],(Int_t)upar[2],(Int_t)upar[3]);
Int_t nz = (Int_t)upar[3];
for (i=0;i<nz;i++) {
((TGeoPgon*)volume->GetShape())->DefineSection(i,upar[3*i+4],upar[3*i+5],upar[3*i+6]);
}
} else if (sh.Contains("pcon")) {
volume = MakePcon(name,medium,upar[0],upar[1],(Int_t)upar[2]);
Int_t nz = (Int_t)upar[2];
for (i=0;i<nz;i++) {
((TGeoPcon*)volume->GetShape())->DefineSection(i,upar[3*i+3],upar[3*i+4],upar[3*i+5]);
}
} else if (sh.Contains("eltu")) {
volume = MakeEltu(name,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("sphe")) {
volume = MakeSphere(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
} else if (sh.Contains("ctub")) {
volume = MakeCtub(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
} else if (sh.Contains("para")) {
volume = MakePara(name,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
} else {
Error("Node","cannot create shape %s",sh.Data());
}
if (!volume) return;
vmulti->AddVolume(volume);
}
if (irot) {
TGeoRotation *matrix = 0;
TGeoMatrix *mat;
TIter next(fMatrices);
while ((mat=(TGeoMatrix*)next())) {
if (mat->GetUniqueID()==UInt_t(irot)) {
matrix = (TGeoRotation*)mat;
break;
}
}
if (!matrix) {
Error("Node", "rotation %i not found", irot);
return;
}
if (isOnly) amother->AddNode(volume,nr,new TGeoCombiTrans(x,y,z,matrix));
else amother->AddNodeOverlap(volume,nr,new TGeoCombiTrans(x,y,z,matrix));
} else {
if (x == 0 && y== 0 && z == 0) {
if (isOnly) amother->AddNode(volume,nr);
else amother->AddNodeOverlap(volume,nr);
} else {
if (isOnly) amother->AddNode(volume,nr,new TGeoTranslation(x,y,z));
else amother->AddNodeOverlap(volume,nr,new TGeoTranslation(x,y,z));
}
}
}
TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed,
Float_t *upar, Int_t npar)
{
Int_t i;
TGeoVolume *volume = 0;
TGeoMedium *medium = GetMedium(nmed);
if (!medium) {
Error("Volume","cannot create volume: %s, medium: %d is unknown",name,nmed);
return 0;
}
TString sh = shape;
TString sname = name;
sname = sname.Strip();
const char *vname = sname.Data();
if (npar <= 0) {
volume = MakeVolumeMulti(vname,medium);
volume->SetTitle(shape);
TGeoVolumeMulti *vmulti = (TGeoVolumeMulti*)fGVolumes->FindObject(vname);
if (!vmulti) {
Error("Volume","volume multi: %s not created",vname);
return 0;
}
return vmulti;
}
sh.ToLower();
if (sh.Contains("box")) {
volume = MakeBox(vname,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("trd1")) {
volume = MakeTrd1(vname,medium,upar[0],upar[1],upar[2],upar[3]);
} else if (sh.Contains("trd2")) {
volume = MakeTrd2(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("trap")) {
volume = MakeTrap(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
} else if (sh.Contains("gtra")) {
volume = MakeGtra(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10],upar[11]);
} else if (sh.Contains("tube")) {
volume = MakeTube(vname,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("tubs")) {
volume = MakeTubs(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("cone")) {
volume = MakeCone(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("cons")) {
volume = MakeCons(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6]);
} else if (sh.Contains("pgon")) {
volume = MakePgon(vname,medium,upar[0],upar[1],(Int_t)upar[2],(Int_t)upar[3]);
Int_t nz = (Int_t)upar[3];
for (i=0;i<nz;i++) {
((TGeoPgon*)volume->GetShape())->DefineSection(i,upar[3*i+4],upar[3*i+5],upar[3*i+6]);
}
} else if (sh.Contains("pcon")) {
volume = MakePcon(vname,medium,upar[0],upar[1],(Int_t)upar[2]);
Int_t nz = (Int_t)upar[2];
for (i=0;i<nz;i++) {
((TGeoPcon*)volume->GetShape())->DefineSection(i,upar[3*i+3],upar[3*i+4],upar[3*i+5]);
}
} else if (sh.Contains("eltu")) {
volume = MakeEltu(vname,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("sphe")) {
volume = MakeSphere(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
} else if (sh.Contains("ctub")) {
volume = MakeCtub(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
} else if (sh.Contains("para")) {
volume = MakePara(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
} else if (sh.Contains("tor")) {
volume = MakeTorus(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
}
if (!volume) {
Error("Volume","volume: %s not created",vname);
return 0;
}
return volume;
}
TGeoVolume *TGeoManager::Volume(const char *name, const char *shape, Int_t nmed,
Double_t *upar, Int_t npar)
{
Int_t i;
TGeoVolume *volume = 0;
TGeoMedium *medium = GetMedium(nmed);
if (!medium) {
Error("Volume","cannot create volume: %s, medium: %d is unknown",name,nmed);
return 0;
}
TString sh = shape;
TString sname = name;
sname = sname.Strip();
const char *vname = sname.Data();
if (npar <= 0) {
volume = MakeVolumeMulti(vname,medium);
volume->SetTitle(shape);
TGeoVolumeMulti *vmulti = (TGeoVolumeMulti*)fGVolumes->FindObject(vname);
if (!vmulti) {
Error("Volume","volume multi: %s not created",vname);
return 0;
}
return vmulti;
}
sh.ToLower();
if (sh.Contains("box")) {
volume = MakeBox(vname,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("trd1")) {
volume = MakeTrd1(vname,medium,upar[0],upar[1],upar[2],upar[3]);
} else if (sh.Contains("trd2")) {
volume = MakeTrd2(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("trap")) {
volume = MakeTrap(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
} else if (sh.Contains("gtra")) {
volume = MakeGtra(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10],upar[11]);
} else if (sh.Contains("tube")) {
volume = MakeTube(vname,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("tubs")) {
volume = MakeTubs(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("cone")) {
volume = MakeCone(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
} else if (sh.Contains("cons")) {
volume = MakeCons(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6]);
} else if (sh.Contains("pgon")) {
volume = MakePgon(vname,medium,upar[0],upar[1],(Int_t)upar[2],(Int_t)upar[3]);
Int_t nz = (Int_t)upar[3];
for (i=0;i<nz;i++) {
((TGeoPgon*)volume->GetShape())->DefineSection(i,upar[3*i+4],upar[3*i+5],upar[3*i+6]);
}
} else if (sh.Contains("pcon")) {
volume = MakePcon(vname,medium,upar[0],upar[1],(Int_t)upar[2]);
Int_t nz = (Int_t)upar[2];
for (i=0;i<nz;i++) {
((TGeoPcon*)volume->GetShape())->DefineSection(i,upar[3*i+3],upar[3*i+4],upar[3*i+5]);
}
} else if (sh.Contains("eltu")) {
volume = MakeEltu(vname,medium,upar[0],upar[1],upar[2]);
} else if (sh.Contains("sphe")) {
volume = MakeSphere(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
} else if (sh.Contains("ctub")) {
volume = MakeCtub(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5],upar[6],upar[7],upar[8],upar[9],upar[10]);
} else if (sh.Contains("para")) {
volume = MakePara(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4],upar[5]);
} else if (sh.Contains("tor")) {
volume = MakeTorus(vname,medium,upar[0],upar[1],upar[2],upar[3],upar[4]);
}
if (!volume) {
Error("Volume","volume: %s not created",vname);
return 0;
}
return volume;
}
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 (IsClosed()) {
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 dummy = opt.Contains("d");
Bool_t nodeid = opt.Contains("i");
if (fIsGeomReading) {
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) Info("CloseGeometry","Voxelization retrieved from file");
Voxelize("ALL");
if (!fCache) BuildCache(dummy,nodeid);
} else {
Warning("CloseGeometry", "top node was streamed!");
Voxelize("ALL");
if (!fCache) BuildCache(dummy,nodeid);
}
Info("CloseGeometry","%i nodes/ %i volume UID's in %s", fNNodes, fUniqueVolumes->GetEntriesFast()-1, GetTitle());
Info("CloseGeometry","----------------modeler ready----------------");
return;
}
SelectTrackingMedia();
CheckGeometry();
Info("CloseGeometry","Counting nodes...");
fNNodes = CountNodes();
fNLevel = fMasterVolume->CountNodes(1,3)+1;
Voxelize("ALL");
Info("CloseGeometry","Building cache...");
BuildCache(dummy,nodeid);
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)
{
fCache->CdNode(nodeid);
}
Int_t TGeoManager::GetCurrentNodeId() const
{
return fCache->GetCurrentNodeId();
}
void TGeoManager::CdTop()
{
fLevel = 0;
fNmany = 0;
if (fCurrentOverlapping) fLastNode = fCurrentNode;
fCurrentNode = fTopNode;
fCache->CdTop();
fCurrentOverlapping = fCurrentNode->IsOverlapping();
if (fCurrentOverlapping) fNmany++;
}
void TGeoManager::CdUp()
{
if (!fLevel) return;
fLevel--;
if (!fLevel) {
CdTop();
return;
}
fCache->CdUp();
if (fCurrentOverlapping) {
fLastNode = fCurrentNode;
fNmany--;
}
fCurrentNode = fCache->GetNode();
if (!fCurrentNode->IsOffset()) {
fCurrentOverlapping = fCurrentNode->IsOverlapping();
} else {
Int_t up = 1;
Bool_t offset = kTRUE;
TGeoNode *mother = 0;
while (offset) {
mother = GetMother(up++);
offset = mother->IsOffset();
}
fCurrentOverlapping = mother->IsOverlapping();
}
}
void TGeoManager::CdDown(Int_t index)
{
TGeoNode *node = fCurrentNode->GetDaughter(index);
Bool_t is_offset = node->IsOffset();
if (is_offset)
node->cd();
else
fCurrentOverlapping = node->IsOverlapping();
fCache->CdDown(index);
fCurrentNode = node;
if (fCurrentOverlapping) fNmany++;
fLevel++;
}
Bool_t TGeoManager::cd(const char *path)
{
if (!strlen(path)) return kFALSE;
CdTop();
TString spath = path;
TGeoVolume *vol;
Int_t length = spath.Length();
Int_t ind1 = spath.Index("/");
Int_t ind2 = 0;
Bool_t end = kFALSE;
TString name;
TGeoNode *node;
while (!end) {
ind2 = spath.Index("/", ind1+1);
if (ind2<0) {
ind2 = length;
end = kTRUE;
}
name = spath(ind1+1, ind2-ind1-1);
if (name==fTopNode->GetName()) {
ind1 = ind2;
continue;
}
vol = fCurrentNode->GetVolume();
if (vol) {
node = vol->GetNode(name.Data());
} else node = 0;
if (!node) {
Error("cd", "Path %s not valid", path);
return kFALSE;
}
CdDown(fCurrentNode->GetVolume()->GetIndex(node));
ind1 = ind2;
}
return kTRUE;
}
Bool_t TGeoManager::CheckPath(const char *path) const
{
Int_t length = strlen(path);
if (!length) return kFALSE;
TString spath = path;
TGeoVolume *vol;
Int_t ind1 = spath.Index("/");
if (ind1<0) {
if (strcmp(path,fTopNode->GetName())) return kFALSE;
return kTRUE;
}
Int_t ind2 = ind1;
Bool_t end = kFALSE;
if (ind1>0) ind1 = -1;
else ind2 = spath.Index("/", ind1+1);
if (ind2<0) ind2 = length;
TString name(spath(ind1+1, ind2-ind1-1));
if (name==fTopNode->GetName()) {
if (ind2>=length-1) return kTRUE;
ind1 = ind2;
} else return kFALSE;
TGeoNode *node = fTopNode;
while (!end) {
ind2 = spath.Index("/", ind1+1);
if (ind2<0) {
ind2 = length;
end = kTRUE;
}
vol = node->GetVolume();
name = spath(ind1+1, ind2-ind1-1);
node = vol->GetNode(name.Data());
if (!node) return kFALSE;
if (ind2>=length-1) return kTRUE;
ind1 = ind2;
}
return kTRUE;
}
void TGeoManager::ConvertReflections()
{
if (!fTopNode) return;
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);
}
}
Info("ConvertReflections", "Done");
}
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;
char fname[15];
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) {
Int_t ndigits=1;
Int_t result=i;
while ((result /= 10)) ndigits++;
sprintf(fname, "anim0000.gif");
char *fpos = fname+8-ndigits;
sprintf(fpos, "%d.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);
track->Draw(option);
}
SetAnimateTracks(kFALSE);
ModifiedPad();
}
void TGeoManager::DrawPath(const char *path)
{
if (!fTopVolume) return;
fTopVolume->SetVisBranch();
GetGeomPainter()->DrawPath(path);
}
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
{
fCache->GetBranchNames(names);
}
const char *TGeoManager::GetPdgName(Int_t pdg) const
{
static char *defaultname = "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(256);
}
if (!strcmp(name, GetPdgName(pdg))) return;
if (fNpdg>255) {
Warning("SetPdgName", "No more than 256 different pdg codes allowed");
return;
}
fPdgId[fNpdg] = pdg;
TNamed *pdgname = new TNamed(name, "");
fPdgNames->AddAt(pdgname, fNpdg++);
}
void TGeoManager::GetBranchNumbers(Int_t *copyNumbers, Int_t *volumeNumbers) const
{
fCache->GetBranchNumbers(copyNumbers, volumeNumbers);
}
void TGeoManager::GetBranchOnlys(Int_t *isonly) const
{
fCache->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;
}
TGeoHMatrix *TGeoManager::GetHMatrix()
{
if (!fCurrentMatrix) {
fCurrentMatrix = new TGeoHMatrix();
fCurrentMatrix->RegisterYourself();
}
return fCurrentMatrix;
}
Int_t TGeoManager::GetVisLevel() const
{
return fVisLevel;
}
Int_t TGeoManager::GetVisOption() const
{
return fVisOption;
}
Int_t TGeoManager::GetVirtualLevel()
{
if (!fCurrentOverlapping) return 0;
Int_t new_media = 0;
TGeoMedium *medium = fCurrentNode->GetMedium();
Int_t virtual_level = 1;
TGeoNode *mother = 0;
while ((mother=GetMother(virtual_level))) {
if (!mother->IsOverlapping() && !mother->IsOffset()) {
if (!new_media) new_media=(mother->GetMedium()==medium)?0:virtual_level;
break;
}
if (!new_media) new_media=(mother->GetMedium()==medium)?0:virtual_level;
virtual_level++;
}
return (new_media==0)?virtual_level:(new_media-1);
}
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()
{
while (fCurrentOverlapping && fLevel) CdUp();
Double_t point[3];
fCache->MasterToLocal(fPoint, point);
if (!fCurrentNode->GetVolume()->Contains(point)) return kFALSE;
if (fNmany) {
Int_t up = 1;
Int_t imother;
Int_t nmany = fNmany;
Bool_t ovlp = kFALSE;
Bool_t nextovlp = kFALSE;
TGeoNode *current = fCurrentNode;
TGeoNode *mother, *mup;
TGeoHMatrix *matrix;
while (nmany) {
mother = GetMother(up);
if (!mother) return kTRUE;
mup = mother;
imother = up+1;
while (mup->IsOffset()) mup = GetMother(imother++);
nextovlp = mup->IsOverlapping();
if (ovlp) nmany--;
if (ovlp || nextovlp) {
matrix = GetMotherMatrix(up);
matrix->MasterToLocal(fPoint,point);
if (!mother->GetVolume()->Contains(point)) {
up++;
while (up--) CdUp();
return GotoSafeLevel();
}
}
current = mother;
ovlp = nextovlp;
up++;
}
}
return kTRUE;
}
Int_t TGeoManager::GetSafeLevel() const
{
Bool_t overlapping = fCurrentOverlapping;
if (!overlapping) return fLevel;
Int_t level = fLevel;
TGeoNode *node;
while (overlapping && level) {
level--;
node = GetMother(fLevel-level);
if (!node->IsOffset()) overlapping = node->IsOverlapping();
}
return level;
}
TGeoNode *TGeoManager::FindInCluster(Int_t *cluster, Int_t nc)
{
TGeoNode *clnode = 0;
TGeoNode *priority = fLastNode;
TGeoNode *current = fCurrentNode;
TGeoNode *found = 0;
Int_t ipop = PushPath();
fSearchOverlaps = kTRUE;
Int_t deepest = fLevel;
Int_t deepest_virtual = fLevel-GetVirtualLevel();
Int_t found_virtual = 0;
Bool_t replace = kFALSE;
Bool_t added = kFALSE;
Int_t i;
for (i=0; i<nc; i++) {
clnode = current->GetDaughter(cluster[i]);
CdDown(cluster[i]);
found = SearchNode(kTRUE, clnode);
if (!fSearchOverlaps) {
PopDummy(ipop);
return found;
}
found_virtual = fLevel-GetVirtualLevel();
if (added) {
if (found_virtual>deepest_virtual) {
replace = kTRUE;
} else {
if (found_virtual==deepest_virtual) {
if (fLevel>deepest) {
replace = kTRUE;
} else {
if ((fLevel==deepest) && (clnode==priority)) replace=kTRUE;
else replace = kFALSE;
}
} else replace = kFALSE;
}
if (i==(nc-1)) {
if (replace) {
PopDummy(ipop);
return found;
} else {
fCurrentOverlapping = PopPath();
PopDummy(ipop);
return fCurrentNode;
}
}
if (replace) {
PopDummy();
PushPath();
deepest = fLevel;
deepest_virtual = found_virtual;
}
fCurrentOverlapping = PopPath(ipop);
} else {
PushPath();
added = kTRUE;
deepest = fLevel;
deepest_virtual = found_virtual;
fCurrentOverlapping = PopPath(ipop);
}
}
PopDummy(ipop);
return fCurrentNode;
}
Int_t TGeoManager::GetTouchedCluster(Int_t start, Double_t *point,
Int_t *check_list, Int_t ncheck, Int_t *result)
{
TGeoNode *current = fCurrentNode->GetDaughter(check_list[start]);
Int_t novlps = 0;
Int_t *ovlps = current->GetOverlaps(novlps);
if (!ovlps) return 0;
Double_t local[3];
Int_t ntotal = 0;
current->MasterToLocal(point, &local[0]);
if (current->GetVolume()->Contains(&local[0])) {
result[ntotal++]=check_list[start];
}
Int_t jst=0, i, j;
while ((ovlps[jst]<=check_list[start]) && (jst<novlps)) jst++;
if (jst==novlps) return 0;
for (i=start; i<ncheck; i++) {
for (j=jst; j<novlps; j++) {
if (check_list[i]==ovlps[j]) {
current = fCurrentNode->GetDaughter(check_list[i]);
if (fActivity && !current->GetVolume()->IsActive()) continue;
current->MasterToLocal(point, &local[0]);
if (current->GetVolume()->Contains(&local[0])) {
result[ntotal++]=check_list[i];
}
}
}
}
return ntotal;
}
void TGeoManager::DefaultColors()
{
const Int_t nmax = 250;
Int_t col[nmax];
for (Int_t i=0;i<nmax;i++) col[i] = 18;
col[ 8] = 15;
col[ 9] = 16;
col[ 10] = 17;
col[ 11] = 21;
col[ 12] = 20;
col[ 13] = 18;
col[ 14] = 23;
col[ 15] = 24;
col[ 16] = 24+100;
col[ 17] = 24+150;
col[ 18] = 23+150;
col[ 19] = 23+100;
col[ 20] = 25;
col[ 21] = 26;
col[ 22] = 26+100;
col[ 23] = 26+150;
col[ 24] = 27;
col[ 25] = 28;
col[ 26] = 17;
col[ 27] = 30;
col[ 28] = 30+100;
col[ 29] = 30+150;
col[ 30] = 14;
col[ 31] = 31;
col[ 32] = 31+100;
col[ 33] = 31+150;
col[ 38] = 33;
col[ 39] = 2;
col[ 41] = 38;
col[ 42] = 40;
col[ 45] = 37;
col[ 55] = 41;
col[ 63] = 42;
col[ 64] = 44;
col[169] = 45;
col[170] = 50;
col[207] = 38;
TGeoVolume *vol;
TIter next(fVolumes);
while ((vol=(TGeoVolume*)next())) {
TGeoMedium *med = vol->GetMedium();
if (!med) continue;
TGeoMaterial *mat = med->GetMaterial();
Int_t matA = (Int_t)mat->GetA();
vol->SetLineColor(col[matA]);
}
}
Double_t TGeoManager::Safety(Bool_t inside)
{
if (fIsOnBoundary) {
fSafety = 0;
return fSafety;
}
Double_t point[3];
if (!inside) fSafety = TGeoShape::Big();
if (fIsOutside) {
fSafety = fTopVolume->GetShape()->Safety(fPoint,kFALSE);
if (fSafety < TGeoShape::Tolerance()) {
fSafety = 0;
fIsOnBoundary = kTRUE;
}
return fSafety;
}
fCache->MasterToLocal(fPoint, point);
TGeoVolume *vol = fCurrentNode->GetVolume();
if (!inside) {
fSafety = vol->GetShape()->Safety(point, kTRUE);
if (fSafety < TGeoShape::Tolerance()) {
fSafety = 0;
fIsOnBoundary = kTRUE;
return fSafety;
}
}
TObjArray *nodes = vol->GetNodes();
Int_t nd = fCurrentNode->GetNdaughters();
if (!nd && !fCurrentOverlapping) return fSafety;
TGeoNode *node;
Double_t safe;
Int_t id;
TGeoPatternFinder *finder = vol->GetFinder();
if (finder) {
Int_t ifirst = finder->GetDivIndex();
node = (TGeoNode*)nodes->UncheckedAt(ifirst);
node->cd();
safe = node->Safety(point, kFALSE);
if (safe < TGeoShape::Tolerance()) {
fSafety=0;
fIsOnBoundary = kTRUE;
return fSafety;
}
if (safe<fSafety) fSafety=safe;
Int_t ilast = ifirst+finder->GetNdiv()-1;
if (ilast==ifirst) return fSafety;
node = (TGeoNode*)nodes->UncheckedAt(ilast);
node->cd();
safe = node->Safety(point, kFALSE);
if (safe < TGeoShape::Tolerance()) {
fSafety=0;
fIsOnBoundary = kTRUE;
return fSafety;
}
if (safe<fSafety) fSafety=safe;
if (fCurrentOverlapping && !inside) SafetyOverlaps();
return fSafety;
}
TGeoVoxelFinder *voxels = vol->GetVoxels();
if (!voxels) {
for (id=0; id<nd; id++) {
node = (TGeoNode*)nodes->UncheckedAt(id);
safe = node->Safety(point, kFALSE);
if (safe < TGeoShape::Tolerance()) {
fSafety=0;
fIsOnBoundary = kTRUE;
return fSafety;
}
if (safe<fSafety) fSafety=safe;
}
if (fNmany && !inside) SafetyOverlaps();
return fSafety;
}
Double_t *boxes = voxels->GetBoxes();
for (id=0; id<nd; id++) {
Int_t ist = 6*id;
Double_t dxyz = 0.;
Double_t dxyz0 = TMath::Abs(point[0]-boxes[ist+3])-boxes[ist];
if (dxyz0 > fSafety) continue;
Double_t dxyz1 = TMath::Abs(point[1]-boxes[ist+4])-boxes[ist+1];
if (dxyz1 > fSafety) continue;
Double_t dxyz2 = TMath::Abs(point[2]-boxes[ist+5])-boxes[ist+2];
if (dxyz2 > fSafety) continue;
if (dxyz0>0) dxyz+=dxyz0*dxyz0;
if (dxyz1>0) dxyz+=dxyz1*dxyz1;
if (dxyz2>0) dxyz+=dxyz2*dxyz2;
if (dxyz >= fSafety*fSafety) continue;
node = (TGeoNode*)nodes->UncheckedAt(id);
safe = node->Safety(point, kFALSE);
if (safe<TGeoShape::Tolerance()) {
fSafety=0;
fIsOnBoundary = kTRUE;
return fSafety;
}
if (safe<fSafety) fSafety = safe;
}
if (fNmany && !inside) SafetyOverlaps();
return fSafety;
}
void TGeoManager::SafetyOverlaps()
{
Double_t point[3], local[3];
Double_t safe;
Bool_t contains;
TGeoNode *nodeovlp;
TGeoVolume *vol;
Int_t novlp, io;
Int_t *ovlp;
Int_t safelevel = GetSafeLevel();
PushPath(safelevel+1);
while (fCurrentOverlapping) {
ovlp = fCurrentNode->GetOverlaps(novlp);
CdUp();
vol = fCurrentNode->GetVolume();
gGeoManager->MasterToLocal(fPoint, point);
contains = fCurrentNode->GetVolume()->Contains(point);
safe = fCurrentNode->GetVolume()->GetShape()->Safety(point, contains);
if (safe<fSafety && safe>=0) fSafety=safe;
if (!novlp || !contains) continue;
for (io=0; io<novlp; io++) {
nodeovlp = vol->GetNode(ovlp[io]);
nodeovlp->GetMatrix()->MasterToLocal(point,local);
contains = nodeovlp->GetVolume()->Contains(local);
if (contains) {
CdDown(ovlp[io]);
safe = Safety(kTRUE);
CdUp();
} else {
safe = nodeovlp->GetVolume()->GetShape()->Safety(local, kFALSE);
}
if (safe<fSafety && safe>=0) fSafety=safe;
}
}
if (fNmany) {
Int_t up = 1;
Int_t imother;
Int_t nmany = fNmany;
Bool_t ovlp = kFALSE;
Bool_t nextovlp = kFALSE;
TGeoNode *current = fCurrentNode;
TGeoNode *mother, *mup;
TGeoHMatrix *matrix;
while (nmany) {
mother = GetMother(up);
mup = mother;
imother = up+1;
while (mup->IsOffset()) mup = GetMother(imother++);
nextovlp = mup->IsOverlapping();
if (ovlp) nmany--;
if (ovlp || nextovlp) {
matrix = GetMotherMatrix(up);
matrix->MasterToLocal(fPoint,local);
safe = mother->GetVolume()->GetShape()->Safety(local,kTRUE);
if (safe<fSafety) fSafety = safe;
current = mother;
ovlp = nextovlp;
}
up++;
}
}
PopPath();
if (fSafety < TGeoShape::Tolerance()) {
fSafety = 0.;
fIsOnBoundary = kTRUE;
}
}
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) 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::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;
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;
}
ofstream out;
char *fname = new char[20];
char quote = '"';
if (!strlen(filename))
sprintf(fname, "tgeovox.C");
else
sprintf(fname, "%s", filename);
out.open(fname, ios::out);
if (!out.good()) {
Error("OptimizeVoxels", "cannot open file");
delete [] fname;
return;
}
TDatime t;
TString sname(fname);
sname.ReplaceAll(".C", "");
out << sname.Data()<<"()"<<endl;
out << "{" << endl;
out << "//=== Macro generated by ROOT version "<< gROOT->GetVersion()<<" : "<<t.AsString()<<endl;
out << "//=== Voxel optimization for " << GetTitle() << " geometry"<<endl;
out << "//===== <run this macro JUST BEFORE closing the geometry>"<<endl;
out << " TGeoVolume *vol = 0;"<<endl;
out << " // parse all voxelized volumes"<<endl;
TGeoVolume *vol = 0;
Bool_t cyltype;
TIter next(fVolumes);
while ((vol=(TGeoVolume*)next())) {
if (!vol->GetVoxels()) continue;
out<<" vol = gGeoManager->GetVolume("<<quote<<vol->GetName()<<quote<<");"<<endl;
cyltype = vol->OptimizeVoxels();
if (cyltype) {
out<<" vol->SetCylVoxels();"<<endl;
} else {
out<<" vol->SetCylVoxels(kFALSE);"<<endl;
}
}
out << "}" << endl;
out.close();
delete [] fname;
}
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;
}
ofstream out;
char *fname = new char[20];
char quote = '"';
if (!strlen(filename))
sprintf(fname, "tgeoatt.C");
else
sprintf(fname, "%s", filename);
out.open(fname, ios::out);
if (!out.good()) {
Error("SaveAttributes", "cannot open file");
delete [] fname;
return;
}
TDatime t;
TString sname(fname);
sname.ReplaceAll(".C", "");
out << sname.Data()<<"()"<<endl;
out << "{" << endl;
out << "//=== Macro generated by ROOT version "<< gROOT->GetVersion()<<" : "<<t.AsString()<<endl;
out << "//=== Attributes for " << GetTitle() << " geometry"<<endl;
out << "//===== <run this macro AFTER loading the geometry in memory>"<<endl;
out << " TGeoVolume *top = gGeoManager->GetVolume("<<quote<<fTopVolume->GetName()<<quote<<");"<<endl;
out << " TGeoVolume *vol = 0;"<<endl;
out << " TGeoNode *node = 0;"<<endl;
out << " // clear all volume attributes and get painter"<<endl;
out << " gGeoManager->ClearAttributes();"<<endl;
out << " gGeoManager->GetGeomPainter();"<<endl;
out << " // set visualization modes and bomb factors"<<endl;
out << " gGeoManager->SetVisOption("<<GetVisOption()<<");"<<endl;
out << " gGeoManager->SetVisLevel("<<GetVisLevel()<<");"<<endl;
out << " gGeoManager->SetExplodedView("<<GetBombMode()<<");"<<endl;
Double_t bombx, bomby, bombz, bombr;
GetBombFactors(bombx, bomby, bombz, bombr);
out << " gGeoManager->SetBombFactors("<<bombx<<","<<bomby<<","<<bombz<<","<<bombr<<");"<<endl;
out << " // iterate volumes coontainer and set new attributes"<<endl;
TGeoVolume *vol = 0;
fTopNode->SaveAttributes(out);
TIter next(fVolumes);
while ((vol=(TGeoVolume*)next())) {
vol->SetVisStreamed(kFALSE);
}
out << " // draw top volume with new settings"<<endl;
out << " top->Draw();"<<endl;
out << " gPad->x3d();"<<endl;
out << "}" << endl;
out.close();
delete [] fname;
}
TGeoNode *TGeoManager::SearchNode(Bool_t downwards, const TGeoNode *skipnode)
{
Double_t point[3];
TGeoVolume *vol = 0;
Bool_t inside_current = (fCurrentNode==skipnode)?kTRUE:kFALSE;
if (!downwards) {
if (fActivity && !vol->IsActive()) {
CdUp();
fIsSameLocation = kFALSE;
return SearchNode(kFALSE, skipnode);
}
vol=fCurrentNode->GetVolume();
if (vol->IsAssembly()) inside_current=kTRUE;
if (!inside_current) {
fCache->MasterToLocal(fPoint, point);
inside_current = vol->Contains(point);
}
if (fNmany) {
inside_current = GotoSafeLevel();
}
if (!inside_current) {
fIsSameLocation = kFALSE;
TGeoNode *skip = fCurrentNode;
if (!fLevel) {
fIsOutside = kTRUE;
return 0;
}
CdUp();
return SearchNode(kFALSE, skip);
}
}
vol = fCurrentNode->GetVolume();
fCache->MasterToLocal(fPoint, point);
if (!inside_current && downwards) {
inside_current = vol->Contains(point);
if (!inside_current) {
fIsSameLocation = kFALSE;
return 0;
} else {
if (fIsOutside) {
fIsOutside = kFALSE;
fIsSameLocation = kFALSE;
}
}
}
TGeoNode *node;
Int_t ncheck = 0;
if (!fCurrentOverlapping) {
fSearchOverlaps = kFALSE;
}
Int_t crtindex = vol->GetCurrentNodeIndex();
while (crtindex>=0 && downwards) {
CdDown(crtindex);
vol = fCurrentNode->GetVolume();
crtindex = vol->GetCurrentNodeIndex();
if (crtindex<0) fCache->MasterToLocal(fPoint, point);
}
Int_t nd = vol->GetNdaughters();
if (!nd) return fCurrentNode;
if (fActivity && !vol->IsActiveDaughters()) return fCurrentNode;
TGeoPatternFinder *finder = vol->GetFinder();
if (finder) {
node=finder->FindNode(&point[0]);
if (node) {
fIsSameLocation = kFALSE;
CdDown(node->GetIndex());
return SearchNode(kTRUE, node);
}
return fCurrentNode;
}
TGeoVoxelFinder *voxels = vol->GetVoxels();
Int_t *check_list = 0;
Int_t id;
if (voxels) {
check_list = voxels->GetCheckList(&point[0], ncheck);
if (!check_list) {
if (!fCurrentNode->GetVolume()->IsAssembly()) return fCurrentNode;
node = fCurrentNode;
if (!fLevel) {
fIsOutside = kTRUE;
return 0;
}
CdUp();
return SearchNode(kFALSE,node);
}
for (id=0; id<ncheck; id++) {
node = vol->GetNode(check_list[id]);
if (node==skipnode) continue;
if (fActivity && !node->GetVolume()->IsActive()) continue;
if ((id<(ncheck-1)) && node->IsOverlapping()) {
if (ncheck+fOverlapMark > fOverlapSize) {
fOverlapSize = 2*(ncheck+fOverlapMark);
delete [] fOverlapClusters;
fOverlapClusters = new Int_t[fOverlapSize];
}
Int_t *cluster = fOverlapClusters + fOverlapMark;
Int_t nc = GetTouchedCluster(id, &point[0], check_list, ncheck, cluster);
if (nc>1) {
fOverlapMark += nc;
node = FindInCluster(cluster, nc);
fOverlapMark -= nc;
return node;
}
}
CdDown(check_list[id]);
node = SearchNode(kTRUE);
if (node) {
fIsSameLocation = kFALSE;
return node;
}
CdUp();
}
if (!fCurrentNode->GetVolume()->IsAssembly()) return fCurrentNode;
node = fCurrentNode;
if (!fLevel) {
fIsOutside = kTRUE;
return 0;
}
CdUp();
return SearchNode(kFALSE,node);
}
for (id=0; id<nd; id++) {
node=fCurrentNode->GetDaughter(id);
if (node==skipnode) continue;
if (fActivity && !node->GetVolume()->IsActive()) continue;
CdDown(id);
node = SearchNode(kTRUE);
if (node) {
fIsSameLocation = kFALSE;
return node;
}
CdUp();
}
if (fCurrentNode->GetVolume()->IsAssembly()) {
node = fCurrentNode;
if (!fLevel) {
fIsOutside = kTRUE;
return 0;
}
CdUp();
return SearchNode(kFALSE,node);
}
return fCurrentNode;
}
TGeoNode *TGeoManager::FindNextBoundaryAndStep(Double_t stepmax, Bool_t compsafe)
{
static Int_t icount = 0;
icount++;
Int_t iact = 3;
Int_t nextindex;
Bool_t is_assembly;
fIsStepExiting = kFALSE;
TGeoNode *skip;
fIsStepEntering = kFALSE;
fStep = stepmax;
Double_t snext = TGeoShape::Big();
if (compsafe) {
fIsOnBoundary = kFALSE;
Safety();
}
Double_t extra = (fIsOnBoundary)?TGeoShape::Tolerance():0.0;
fIsOnBoundary = kFALSE;
fPoint[0] += extra*fDirection[0];
fPoint[1] += extra*fDirection[1];
fPoint[2] += extra*fDirection[2];
*fCurrentMatrix = GetCurrentMatrix();
if (fIsOutside) {
snext = fTopVolume->GetShape()->DistFromOutside(fPoint, fDirection, iact, fStep);
if (snext < fStep) {
if (snext<=0) {
snext = 0.0;
fStep = snext;
fPoint[0] -= extra*fDirection[0];
fPoint[1] -= extra*fDirection[1];
fPoint[2] -= extra*fDirection[2];
} else {
fStep = snext+extra;
}
fIsStepEntering = kTRUE;
fNextNode = fTopNode;
nextindex = fNextNode->GetVolume()->GetNextNodeIndex();
while (nextindex>=0) {
CdDown(nextindex);
fNextNode = fCurrentNode;
nextindex = fNextNode->GetVolume()->GetNextNodeIndex();
if (nextindex<0) *fCurrentMatrix = GetCurrentMatrix();
}
fPoint[0] += snext*fDirection[0];
fPoint[1] += snext*fDirection[1];
fPoint[2] += snext*fDirection[2];
fIsOnBoundary = kTRUE;
fIsOutside = kFALSE;
return CrossBoundaryAndLocate(kTRUE, fCurrentNode);
}
if (snext<TGeoShape::Big()) {
fNextNode = fTopNode;
fPoint[0] += (fStep-extra)*fDirection[0];
fPoint[1] += (fStep-extra)*fDirection[1];
fPoint[2] += (fStep-extra)*fDirection[2];
return fNextNode;
}
fNextNode = 0;
fIsOnBoundary = kFALSE;
return 0;
}
Double_t point[3],dir[3];
Int_t icrossed = -2;
fCache->MasterToLocal(fPoint, &point[0]);
fCache->MasterToLocalVect(fDirection, &dir[0]);
TGeoVolume *vol = fCurrentNode->GetVolume();
snext = vol->GetShape()->DistFromInside(point, dir, iact, fStep);
fNextNode = fCurrentNode;
if (snext <= TGeoShape::Tolerance()) {
snext = TGeoShape::Tolerance();
fStep = snext;
fIsOnBoundary = kTRUE;
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
skip = fCurrentNode;
is_assembly = fCurrentNode->GetVolume()->IsAssembly();
if (!fLevel && !is_assembly) {
fIsOutside = kTRUE;
return 0;
}
if (fLevel) CdUp();
else skip = 0;
return CrossBoundaryAndLocate(kFALSE, skip);
}
if (snext < fStep) {
icrossed = -1;
fStep = snext;
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
}
Int_t idaughter = -1;
TGeoNode *crossed = FindNextDaughterBoundary(point,dir, idaughter, kTRUE);
if (crossed) {
fIsStepExiting = kFALSE;
icrossed = idaughter;
fIsStepEntering = kTRUE;
}
TGeoNode *current = 0;
TGeoNode *dnode = 0;
TGeoVolume *mother = 0;
if (fNmany) {
Double_t mothpt[3];
Double_t vecpt[3];
Double_t dpt[3], dvec[3];
Int_t novlps;
Int_t safelevel = GetSafeLevel();
PushPath(safelevel+1);
while (fCurrentOverlapping) {
Int_t *ovlps = fCurrentNode->GetOverlaps(novlps);
CdUp();
mother = fCurrentNode->GetVolume();
fCache->MasterToLocal(fPoint, &mothpt[0]);
fCache->MasterToLocalVect(fDirection, &vecpt[0]);
snext = TGeoShape::Big();
if (!mother->IsAssembly()) snext = mother->GetShape()->DistFromInside(mothpt, vecpt, iact, fStep);
if (snext<fStep) {
icrossed = -1;
PopDummy();
PushPath(safelevel+1);
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
fStep = snext;
*fCurrentMatrix = GetCurrentMatrix();
fNextNode = fCurrentNode;
}
for (Int_t i=0; i<novlps; i++) {
current = mother->GetNode(ovlps[i]);
if (!current->IsOverlapping()) {
current->cd();
current->MasterToLocal(&mothpt[0], &dpt[0]);
current->MasterToLocalVect(&vecpt[0], &dvec[0]);
snext = current->GetVolume()->GetShape()->DistFromOutside(dpt, dvec, iact, fStep);
if (snext<fStep) {
PopDummy();
PushPath(safelevel+1);
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(current->GetMatrix());
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
icrossed = ovlps[i];
fStep = snext;
fNextNode = current;
}
} else {
current->cd();
current->MasterToLocal(&mothpt[0], &dpt[0]);
current->MasterToLocalVect(&vecpt[0], &dvec[0]);
if (current->GetVolume()->Contains(dpt)) {
if (current->GetVolume()->GetNdaughters()) {
CdDown(ovlps[i]);
dnode = FindNextDaughterBoundary(dpt,dvec,idaughter,kFALSE);
if (dnode) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(dnode->GetMatrix());
icrossed = idaughter;
PopDummy();
PushPath(safelevel+1);
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
fNextNode = dnode;
}
CdUp();
}
} else {
snext = current->GetVolume()->GetShape()->DistFromOutside(dpt, dvec, iact, fStep);
if (snext<fStep) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(current->GetMatrix());
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
fStep = snext;
fNextNode = current;
icrossed = ovlps[i];
PopDummy();
PushPath(safelevel+1);
}
}
}
}
}
if (fNmany) {
Int_t up = 1;
Int_t imother;
Int_t nmany = fNmany;
Bool_t ovlp = kFALSE;
Bool_t nextovlp = kFALSE;
Bool_t offset = kFALSE;
TGeoNode *current = fCurrentNode;
TGeoNode *mother, *mup;
TGeoHMatrix *matrix;
while (nmany) {
mother = GetMother(up);
mup = mother;
imother = up+1;
offset = kFALSE;
while (mup->IsOffset()) {
mup = GetMother(imother++);
offset = kTRUE;
}
nextovlp = mup->IsOverlapping();
if (offset) {
mother = mup;
if (nextovlp) nmany -= imother-up;
up = imother-1;
} else {
if (ovlp) nmany--;
}
if (ovlp || nextovlp) {
matrix = GetMotherMatrix(up);
matrix->MasterToLocal(fPoint,dpt);
matrix->MasterToLocalVect(fDirection,dvec);
snext = TGeoShape::Big();
if (!mother->GetVolume()->IsAssembly()) snext = mother->GetVolume()->GetShape()->DistFromInside(dpt,dvec,iact,fStep);
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
if (snext<fStep) {
fNextNode = mother;
*fCurrentMatrix = matrix;
fStep = snext;
while (up--) CdUp();
PopDummy();
PushPath();
icrossed = -1;
up = 1;
current = fCurrentNode;
ovlp = current->IsOverlapping();
continue;
}
}
current = mother;
ovlp = nextovlp;
up++;
}
}
PopPath();
}
fPoint[0] += fStep*fDirection[0];
fPoint[1] += fStep*fDirection[1];
fPoint[2] += fStep*fDirection[2];
fStep += extra;
if (icrossed == -2) {
return fCurrentNode;
}
fIsOnBoundary = kTRUE;
if (icrossed == -1) {
TGeoNode *skip = fCurrentNode;
is_assembly = fCurrentNode->GetVolume()->IsAssembly();
if (!fLevel && !is_assembly) {
fIsOutside = kTRUE;
return 0;
}
if (fLevel) CdUp();
else skip = 0;
return CrossBoundaryAndLocate(kFALSE, skip);
}
current = fCurrentNode;
CdDown(icrossed);
nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
while (nextindex>=0) {
current = fCurrentNode;
CdDown(nextindex);
nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
}
return CrossBoundaryAndLocate(kTRUE, current);
}
TGeoNode *TGeoManager::CrossBoundaryAndLocate(Bool_t downwards, TGeoNode *skipnode)
{
Double_t extra = TGeoShape::Tolerance();
fPoint[0] += extra*fDirection[0];
fPoint[1] += extra*fDirection[1];
fPoint[2] += extra*fDirection[2];
TGeoNode *current = SearchNode(downwards, skipnode);
fPoint[0] -= extra*fDirection[0];
fPoint[1] -= extra*fDirection[1];
fPoint[2] -= extra*fDirection[2];
if (!current) return 0;
if (downwards) {
Int_t nextindex = current->GetVolume()->GetNextNodeIndex();
while (nextindex>=0) {
CdDown(nextindex);
current = fCurrentNode;
nextindex = fCurrentNode->GetVolume()->GetNextNodeIndex();
}
return current;
}
if ((skipnode && current == skipnode) || current->GetVolume()->IsAssembly()) {
if (!fLevel) {
fIsOutside = kTRUE;
return fTopNode;
}
CdUp();
while (fLevel && fCurrentNode->GetVolume()->IsAssembly()) CdUp();
if (!fLevel && fCurrentNode->GetVolume()->IsAssembly()) {
fIsOutside = kTRUE;
return fTopNode;
}
return fTopNode;
}
return current;
}
TGeoNode *TGeoManager::FindNextBoundary(Double_t stepmax, const char *path)
{
Int_t iact = 3;
fStep = TGeoShape::Big();
fIsStepEntering = kFALSE;
fIsStepExiting = kFALSE;
Bool_t computeGlobal = kFALSE;
fIsOnBoundary = kFALSE;
if (stepmax<1E20) {
if (stepmax <= 0) {
stepmax = - stepmax;
computeGlobal = kTRUE;
}
if (IsSamePoint(fPoint[0], fPoint[1], fPoint[2]) && fLastSafety>=0.) fSafety = fLastSafety;
else fSafety = Safety();
fSafety = TMath::Abs(fSafety);
memcpy(fLastPoint, fPoint, kN3);
fLastSafety = fSafety;
if (fSafety<TGeoShape::Tolerance()) fIsOnBoundary = kTRUE;
else fIsOnBoundary = kFALSE;
fStep = stepmax;
if (stepmax<fSafety) {
fStep = stepmax;
return fCurrentNode;
}
}
if (computeGlobal) *fCurrentMatrix = GetCurrentMatrix();
Double_t snext = TGeoShape::Big();
Double_t safe;
Double_t point[3];
Double_t dir[3];
if (strlen(path)) {
PushPath();
if (!cd(path)) {
PopPath();
return 0;
}
if (computeGlobal) *fCurrentMatrix = GetCurrentMatrix();
fNextNode = fCurrentNode;
TGeoVolume *tvol=fCurrentNode->GetVolume();
fCache->MasterToLocal(fPoint, &point[0]);
fCache->MasterToLocalVect(fDirection, &dir[0]);
if (tvol->Contains(&point[0])) {
fStep=tvol->GetShape()->DistFromInside(&point[0], &dir[0], iact, fStep, &safe);
} else {
fStep=tvol->GetShape()->DistFromOutside(&point[0], &dir[0], iact, fStep, &safe);
}
PopPath();
return fNextNode;
}
if (fIsOutside) {
snext = fTopVolume->GetShape()->DistFromOutside(fPoint, fDirection, iact, fStep, &safe);
fNextNode = fTopNode;
if (snext < fStep) {
fIsStepEntering = kTRUE;
fStep = snext;
Int_t indnext = fNextNode->GetVolume()->GetNextNodeIndex();;
while (indnext>=0) {
fNextNode = fNextNode->GetDaughter(indnext);
if (computeGlobal) fCurrentMatrix->Multiply(fNextNode->GetMatrix());
indnext = fNextNode->GetVolume()->GetNextNodeIndex();
}
return fNextNode;
}
return 0;
}
fCache->MasterToLocal(fPoint, &point[0]);
fCache->MasterToLocalVect(fDirection, &dir[0]);
TGeoVolume *vol = fCurrentNode->GetVolume();
snext = vol->GetShape()->DistFromInside(&point[0], &dir[0], iact, fStep, &safe);
if (snext < fStep) {
fNextNode = fCurrentNode;
fIsStepExiting = kTRUE;
fStep = snext;
fIsStepEntering = kFALSE;
if (fStep<1E-6) return fCurrentNode;
}
fNextNode = (fStep<1E20)?fCurrentNode:0;
Int_t idaughter = -1;
FindNextDaughterBoundary(point,dir,idaughter,computeGlobal);
TGeoNode *current = 0;
TGeoNode *dnode = 0;
TGeoVolume *mother = 0;
if (fNmany) {
Double_t mothpt[3];
Double_t vecpt[3];
Double_t dpt[3], dvec[3];
Int_t novlps;
Int_t idovlp = -1;
Int_t safelevel = GetSafeLevel();
PushPath(safelevel+1);
while (fCurrentOverlapping) {
Int_t *ovlps = fCurrentNode->GetOverlaps(novlps);
CdUp();
mother = fCurrentNode->GetVolume();
fCache->MasterToLocal(fPoint, &mothpt[0]);
fCache->MasterToLocalVect(fDirection, &vecpt[0]);
snext = TGeoShape::Big();
if (!mother->IsAssembly()) snext = mother->GetShape()->DistFromInside(&mothpt[0], &vecpt[0], iact, fStep, &safe);
fIsStepExiting = kTRUE;
if (snext<fStep) {
fIsStepEntering = kFALSE;
fStep = snext;
if (computeGlobal) *fCurrentMatrix = GetCurrentMatrix();
fNextNode = fCurrentNode;
}
for (Int_t i=0; i<novlps; i++) {
current = mother->GetNode(ovlps[i]);
if (!current->IsOverlapping()) {
current->cd();
current->MasterToLocal(&mothpt[0], &dpt[0]);
current->MasterToLocalVect(&vecpt[0], &dvec[0]);
snext = current->GetVolume()->GetShape()->DistFromOutside(&dpt[0], &dvec[0], iact, fStep, &safe);
if (snext<fStep) {
if (computeGlobal) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(current->GetMatrix());
fIsStepExiting = kTRUE;
}
fIsStepEntering = kFALSE;
fStep = snext;
fNextNode = current;
}
} else {
current->cd();
current->MasterToLocal(&mothpt[0], &dpt[0]);
current->MasterToLocalVect(&vecpt[0], &dvec[0]);
if (current->GetVolume()->Contains(dpt)) {
if (current->GetVolume()->GetNdaughters()) {
CdDown(ovlps[i]);
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
dnode = FindNextDaughterBoundary(dpt,dvec,idovlp,computeGlobal);
if (dnode && computeGlobal) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(dnode->GetMatrix());
}
fNextNode = dnode;
CdUp();
}
} else {
snext = current->GetVolume()->GetShape()->DistFromOutside(&dpt[0], &dvec[0], iact, fStep, &safe);
if (snext<fStep) {
if (computeGlobal) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(current->GetMatrix());
fIsStepExiting = kTRUE;
}
fIsStepEntering = kFALSE;
fStep = snext;
fNextNode = current;
}
}
}
}
}
if (fNmany) {
Int_t up = 1;
Int_t imother;
Int_t nmany = fNmany;
Bool_t ovlp = kFALSE;
Bool_t nextovlp = kFALSE;
Bool_t offset = kFALSE;
TGeoNode *current = fCurrentNode;
TGeoNode *mother, *mup;
TGeoHMatrix *matrix;
while (nmany) {
mother = GetMother(up);
mup = mother;
imother = up+1;
offset = kFALSE;
while (mup->IsOffset()) {
mup = GetMother(imother++);
offset = kTRUE;
}
nextovlp = mup->IsOverlapping();
if (offset) {
mother = mup;
if (nextovlp) nmany -= imother-up;
up = imother-1;
} else {
if (ovlp) nmany--;
}
if (ovlp || nextovlp) {
matrix = GetMotherMatrix(up);
matrix->MasterToLocal(fPoint,dpt);
matrix->MasterToLocalVect(fDirection,dvec);
snext = TGeoShape::Big();
if (!mother->GetVolume()->IsAssembly()) snext = mother->GetVolume()->GetShape()->DistFromInside(dpt,dvec,iact,fStep);
if (snext<fStep) {
fIsStepEntering = kFALSE;
fIsStepExiting = kTRUE;
fStep = snext;
fNextNode = mother;
if (computeGlobal) *fCurrentMatrix = matrix;
while (up--) CdUp();
up = 1;
current = fCurrentNode;
ovlp = current->IsOverlapping();
continue;
}
}
current = mother;
ovlp = nextovlp;
up++;
}
}
PopPath();
}
return fNextNode;
}
TGeoNode *TGeoManager::FindNextDaughterBoundary(Double_t *point, Double_t *dir, Int_t &idaughter, Bool_t compmatrix)
{
Double_t snext = TGeoShape::Big();
idaughter = -1;
TGeoNode *nodefound = 0;
TGeoVolume *vol = fCurrentNode->GetVolume();
Int_t nd = vol->GetNdaughters();
if (!nd) return 0;
if (fActivity && !vol->IsActiveDaughters()) return 0;
Double_t lpoint[3], ldir[3];
TGeoNode *current = 0;
Int_t i=0;
TGeoPatternFinder *finder = vol->GetFinder();
if (finder) {
Int_t ifirst = finder->GetDivIndex();
current = vol->GetNode(ifirst);
current->cd();
current->MasterToLocal(&point[0], lpoint);
current->MasterToLocalVect(&dir[0], ldir);
snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, fStep);
if (snext<fStep) {
if (compmatrix) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(current->GetMatrix());
fIsStepExiting = kFALSE;
}
fIsStepEntering = kTRUE;
fStep=snext;
fNextNode = current;
nodefound = current;
idaughter = ifirst;
}
Int_t ilast = ifirst+finder->GetNdiv()-1;
if (ilast==ifirst) return fNextNode;
current = vol->GetNode(ilast);
current->cd();
current->MasterToLocal(&point[0], lpoint);
current->MasterToLocalVect(&dir[0], ldir);
snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, fStep);
if (snext<fStep) {
if (compmatrix) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(current->GetMatrix());
fIsStepExiting = kFALSE;
}
fIsStepEntering = kTRUE;
fStep=snext;
fNextNode = current;
nodefound = current;
idaughter = ilast;
}
return nodefound;
}
TGeoVoxelFinder *voxels = vol->GetVoxels();
Int_t indnext;
if (nd<5 || !voxels) {
for (i=0; i<nd; i++) {
current = vol->GetNode(i);
if (fActivity && !current->GetVolume()->IsActive()) continue;
current->cd();
if (voxels && voxels->IsSafeVoxel(point, i, fStep)) continue;
current->MasterToLocal(point, lpoint);
current->MasterToLocalVect(dir, ldir);
if (current->IsOverlapping() && current->GetVolume()->Contains(lpoint)) continue;
snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, fStep);
if (snext<fStep) {
indnext = current->GetVolume()->GetNextNodeIndex();
if (compmatrix) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(current->GetMatrix());
fIsStepExiting = kFALSE;
}
fIsStepEntering = kTRUE;
fStep=snext;
fNextNode = current;
nodefound = fNextNode;
idaughter = i;
while (indnext>=0) {
current = current->GetDaughter(indnext);
if (compmatrix) fCurrentMatrix->Multiply(current->GetMatrix());
fNextNode = current;
nodefound = current;
indnext = current->GetVolume()->GetNextNodeIndex();
}
}
}
return nodefound;
}
Int_t ncheck = 0;
Int_t *vlist = 0;
voxels->SortCrossedVoxels(point, dir);
while ((vlist=voxels->GetNextVoxel(point, dir, ncheck))) {
for (i=0; i<ncheck; i++) {
current = vol->GetNode(vlist[i]);
if (fActivity && !current->GetVolume()->IsActive()) continue;
current->cd();
current->MasterToLocal(point, lpoint);
current->MasterToLocalVect(dir, ldir);
if (current->IsOverlapping() && current->GetVolume()->Contains(lpoint)) continue;
snext = current->GetVolume()->GetShape()->DistFromOutside(lpoint, ldir, 3, fStep);
if (snext<fStep) {
indnext = current->GetVolume()->GetNextNodeIndex();
if (compmatrix) {
*fCurrentMatrix = GetCurrentMatrix();
fCurrentMatrix->Multiply(current->GetMatrix());
fIsStepExiting = kFALSE;
}
fIsStepEntering = kTRUE;
fStep=snext;
fNextNode = current;
nodefound = fNextNode;
idaughter = vlist[i];
while (indnext>=0) {
current = current->GetDaughter(indnext);
if (compmatrix) fCurrentMatrix->Multiply(current->GetMatrix());
fNextNode = current;
nodefound = current;
indnext = current->GetVolume()->GetNextNodeIndex();
}
}
}
}
return nodefound;
}
void TGeoManager::ResetState()
{
fSearchOverlaps = kFALSE;
fIsOutside = kFALSE;
fIsEntering = fIsExiting = kFALSE;
fIsOnBoundary = kFALSE;
fIsStepEntering = fIsStepExiting = kFALSE;
}
TGeoNode *TGeoManager::FindNode(Bool_t safe_start)
{
fSafety = 0;
fSearchOverlaps = kFALSE;
fIsOutside = kFALSE;
fIsEntering = fIsExiting = kFALSE;
fIsOnBoundary = kFALSE;
fStartSafe = safe_start;
fIsSameLocation = kTRUE;
TGeoNode *last = fCurrentNode;
TGeoNode *found = SearchNode();
if (found != last) {
fIsSameLocation = kFALSE;
} else {
if (last->IsOverlapping()) fIsSameLocation = kTRUE;
}
return found;
}
TGeoNode *TGeoManager::FindNode(Double_t x, Double_t y, Double_t z)
{
fPoint[0] = x;
fPoint[1] = y;
fPoint[2] = z;
fSafety = 0;
fSearchOverlaps = kFALSE;
fIsOutside = kFALSE;
fIsEntering = fIsExiting = kFALSE;
fIsOnBoundary = kFALSE;
fStartSafe = kTRUE;
fIsSameLocation = kTRUE;
TGeoNode *last = fCurrentNode;
TGeoNode *found = SearchNode();
if (found != last) {
fIsSameLocation = kFALSE;
} else {
if (last->IsOverlapping()) fIsSameLocation = kTRUE;
}
return found;
}
Double_t *TGeoManager::FindNormalFast()
{
if (!fNextNode) return 0;
Double_t local[3];
Double_t ldir[3];
Double_t lnorm[3];
fCurrentMatrix->MasterToLocal(fPoint, local);
fCurrentMatrix->MasterToLocalVect(fDirection, ldir);
fNextNode->GetVolume()->GetShape()->ComputeNormal(local, ldir,lnorm);
fCurrentMatrix->LocalToMasterVect(lnorm, fNormal);
return fNormal;
}
Double_t *TGeoManager::FindNormal(Bool_t forward)
{
Double_t lnorm[3];
Double_t lpt[3];
Double_t ldir[3];
if ((fIsStepEntering||fIsStepExiting) && !forward) {
MasterToLocal(fPoint, lpt);
MasterToLocalVect(fDirection, ldir);
fCurrentNode->GetVolume()->GetShape()->ComputeNormal(lpt,ldir,lnorm);
LocalToMasterVect(lnorm, fNormal);
return fNormal;
}
Double_t saved_point[3];
Double_t saved_direction[3];
Double_t saved_step = fStep;
Double_t is_entering = fIsEntering;
Double_t bigstep = 1.E6;
Int_t i, istep;
Int_t start = PushPath();
memcpy(saved_point, fPoint, kN3);
memcpy(saved_direction, fDirection, kN3);
if (!forward) {
for (i=0; i<3; i++) fDirection[i] *= -1.;
FindNextBoundary();
if (fStep>bigstep) {
memcpy(fPoint, saved_point, kN3);
memcpy(fDirection, saved_direction, kN3);
fStep = saved_step;
fIsEntering = is_entering;
PopPath();
Warning("FindNormal","nothing backwards\n");
return 0;
}
istep = 0;
Step();
while (!fIsEntering) {
istep++;
if (istep>1E3) {
Error("FindNormal", "cannot reach backward boundary");
Error("FindNormal", "starting point was : (%f, %f, %f)", saved_point[0], saved_point[1], saved_point[2]);
Error("FindNormal", "direction was : (%f, %f, %f)", fDirection[0], fDirection[1], fDirection[2]);
memcpy(fPoint, saved_point, kN3);
memcpy(fDirection, saved_direction, kN3);
fStep = saved_step;
fIsEntering = is_entering;
PopPath();
return 0;
}
fStep = 1E-2;
Step();
}
if (!(fIsStepEntering||fIsStepExiting)) PopPath(start);
memcpy(fDirection, saved_direction, kN3);
} else {
FindNextBoundary();
if (fStep>bigstep) {
memcpy(fPoint, saved_point, kN3);
memcpy(fDirection, saved_direction, kN3);
fStep = saved_step;
fIsEntering = is_entering;
PopPath();
Error("FindNormal","nothing forward...");
return 0;
}
istep = 0;
Step();
while (!fIsEntering) {
istep++;
if (istep>1E3) {
Error("FindNormal", "cannot reach forward boundary");
Error("FindNormal", "starting point was : (%f, %f, %f)", saved_point[0], saved_point[1], saved_point[2]);
Error("FindNormal", "direction was : (%f, %f, %f)", fDirection[0], fDirection[1], fDirection[2]);
memcpy(fPoint, saved_point, kN3);
memcpy(fDirection, saved_direction, kN3);
fStep = saved_step;
fIsEntering = is_entering;
PopPath();
return 0;
}
fStep = 1E-2;
Step();
}
if (!(fIsStepEntering||fIsStepExiting)) PopPath(start);
}
MasterToLocal(fPoint, lpt);
MasterToLocalVect(fDirection, ldir);
fCurrentNode->GetVolume()->GetShape()->ComputeNormal(lpt,ldir,lnorm);
LocalToMasterVect(lnorm, fNormal);
memcpy(fPoint, saved_point, kN3);
memcpy(fDirection, saved_direction, kN3);
fStep = saved_step;
fIsEntering = is_entering;
PopPath();
return fNormal;
}
Bool_t TGeoManager::IsSameLocation(Double_t x, Double_t y, Double_t z, Bool_t change)
{
Double_t oldpt[3];
if (fLastSafety>0) {
Double_t dx = (x-fLastPoint[0]);
Double_t dy = (y-fLastPoint[1]);
Double_t dz = (z-fLastPoint[2]);
Double_t dsq = dx*dx+dy*dy+dz*dz;
if (dsq<fLastSafety*fLastSafety) return kTRUE;
}
if (fCurrentOverlapping) {
Int_t cid = GetCurrentNodeId();
if (!change) PushPoint();
memcpy(oldpt, fPoint, kN3);
gGeoManager->SetCurrentPoint(x,y,z);
gGeoManager->SearchNode();
memcpy(fPoint, oldpt, kN3);
Bool_t same = (cid==GetCurrentNodeId())?kTRUE:kFALSE;
if (!change) PopPoint();
return same;
}
Double_t point[3];
point[0] = x;
point[1] = y;
point[2] = z;
if (change) memcpy(fPoint, point, kN3);
TGeoVolume *vol = fCurrentNode->GetVolume();
if (fIsOutside) {
if (vol->GetShape()->Contains(point)) {
if (!change) return kFALSE;
FindNode(x,y,z);
return kFALSE;
}
return kTRUE;
}
Double_t local[3];
MasterToLocal(point,local);
if (!vol->GetShape()->Contains(local)) {
if (!change) return kFALSE;
CdUp();
FindNode(x,y,z);
return kFALSE;
}
Int_t nd = vol->GetNdaughters();
if (!nd) return kTRUE;
TGeoNode *node;
TGeoPatternFinder *finder = vol->GetFinder();
if (finder) {
node=finder->FindNode(local);
if (node) {
if (!change) return kFALSE;
CdDown(node->GetIndex());
SearchNode(kTRUE,node);
return kFALSE;
}
return kTRUE;
}
TGeoVoxelFinder *voxels = vol->GetVoxels();
Int_t *check_list = 0;
Int_t ncheck = 0;
Double_t local1[3];
if (voxels) {
check_list = voxels->GetCheckList(local, ncheck);
if (!check_list) return kTRUE;
if (!change) PushPath();
for (Int_t id=0; id<ncheck; id++) {
node = vol->GetNode(check_list[id]);
CdDown(check_list[id]);
fCurrentNode->GetMatrix()->MasterToLocal(local,local1);
if (fCurrentNode->GetVolume()->GetShape()->Contains(local1)) {
if (!change) {
PopPath();
return kFALSE;
}
SearchNode(kTRUE);
return kFALSE;
}
CdUp();
}
if (!change) PopPath();
return kTRUE;
}
Int_t id = 0;
if (!change) PushPath();
while ((node=fCurrentNode->GetDaughter(id++))) {
CdDown(id-1);
fCurrentNode->GetMatrix()->MasterToLocal(local,local1);
if (fCurrentNode->GetVolume()->GetShape()->Contains(local1)) {
if (!change) {
PopPath();
return kFALSE;
}
SearchNode(kTRUE);
return kFALSE;
}
CdUp();
if (id == nd) {
if (!change) PopPath();
return kTRUE;
}
}
if (!change) PopPath();
return kTRUE;
}
Bool_t TGeoManager::IsSamePoint(Double_t x, Double_t y, Double_t z) const
{
if (x==fLastPoint[0]) {
if (y==fLastPoint[1]) {
if (z==fLastPoint[2]) return kTRUE;
}
}
return kFALSE;
}
Bool_t TGeoManager::IsInPhiRange() const
{
if (!fPhiCut) return kTRUE;
const Double_t *origin;
if (!fCurrentNode) return kFALSE;
origin = ((TGeoBBox*)fCurrentNode->GetVolume()->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(Double_t *point, Double_t *dir)
{
SetCurrentPoint(point);
SetCurrentDirection(dir);
return FindNode();
}
TGeoNode *TGeoManager::InitTrack(Double_t x, Double_t y, Double_t z, Double_t nx, Double_t ny, Double_t nz)
{
SetCurrentPoint(x,y,z);
SetCurrentDirection(nx,ny,nz);
return FindNode();
}
void TGeoManager::InspectState() const
{
Info("InspectState","Current path is: %s",GetPath());
Int_t level;
TGeoNode *node;
Bool_t is_offset, is_overlapping;
for (level=0; level<fLevel+1; level++) {
node = GetMother(fLevel-level);
if (!node) continue;
is_offset = node->IsOffset();
is_overlapping = node->IsOverlapping();
Info("InspectState","level %i: %s div=%i many=%i",level,node->GetName(),is_offset,is_overlapping);
}
Info("InspectState","on_bound=%i entering=%i", fIsOnBoundary, fIsEntering);
}
const char *TGeoManager::GetPath() const
{
if (fIsOutside) return kGeoOutsidePath;
return fCache->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();
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->AddAt(fGVolumes->At(i),i);
for (i=0; i<nvol; i++) fHashVolumes->AddAt(fVolumes->At(i),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)
{
GetGeomPainter()->RandomRays(nrays, startx, starty, startz);
}
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;
TGeoVoxelFinder *vox = 0;
if (!fStreamVoxels) Info("Voxelize","Voxelizing...");
TIter next(fVolumes);
while ((vol = (TGeoVolume*)next())) {
if (!fIsGeomReading) vol->SortNodes();
if (!fStreamVoxels) {
vol->Voxelize(option);
} else {
vox = vol->GetVoxels();
if (vox) vox->CreateCheckList();
}
if (!fIsGeomReading) vol->FindOverlaps();
}
}
void TGeoManager::ModifiedPad() const
{
if (!fPainter) return;
fPainter->ModifiedPad();
}
TGeoVolume *TGeoManager::MakeArb8(const char *name, const TGeoMedium *medium,
Double_t dz, Double_t *vertices)
{
TGeoArb8 *arb = new TGeoArb8(dz, vertices);
TGeoVolume *vol = new TGeoVolume(name, arb, medium);
return vol;
}
TGeoVolume *TGeoManager::MakeBox(const char *name, const TGeoMedium *medium,
Double_t dx, Double_t dy, Double_t dz)
{
TGeoBBox *box = new TGeoBBox(dx, dy, dz);
TGeoVolume *vol = 0;
if (box->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(box);
} else {
vol = new TGeoVolume(name, box, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakePara(const char *name, const TGeoMedium *medium,
Double_t dx, Double_t dy, Double_t dz,
Double_t alpha, Double_t theta, Double_t phi)
{
if ((alpha==0) && (theta==0)) {
Warning("MakePara","parallelipiped %s having alpha=0, theta=0 -> making box instead", name);
return MakeBox(name, medium, dx, dy, dz);
}
TGeoPara *para=0;
para = new TGeoPara(dx, dy, dz, alpha, theta, phi);
TGeoVolume *vol = 0;
if (para->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(para);
} else {
vol = new TGeoVolume(name, para, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeSphere(const char *name, const TGeoMedium *medium,
Double_t rmin, Double_t rmax, Double_t themin, Double_t themax,
Double_t phimin, Double_t phimax)
{
TGeoSphere *sph = new TGeoSphere(rmin, rmax, themin, themax, phimin, phimax);
TGeoVolume *vol = new TGeoVolume(name, sph, medium);
return vol;
}
TGeoVolume *TGeoManager::MakeTorus(const char *name, const TGeoMedium *medium, Double_t r,
Double_t rmin, Double_t rmax, Double_t phi1, Double_t dphi)
{
TGeoTorus *tor = new TGeoTorus(name,r,rmin,rmax,phi1,dphi);
TGeoVolume *vol = new TGeoVolume(name, tor, medium);
return vol;
}
TGeoVolume *TGeoManager::MakeTube(const char *name, const TGeoMedium *medium,
Double_t rmin, Double_t rmax, Double_t dz)
{
if (rmin>rmax) {
Error("MakeTube", "tube %s, Rmin=%g greater than Rmax=%g", name,rmin,rmax);
}
TGeoTube *tube = new TGeoTube(rmin, rmax, dz);
TGeoVolume *vol = 0;
if (tube->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(tube);
} else {
vol = new TGeoVolume(name, tube, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeTubs(const char *name, const TGeoMedium *medium,
Double_t rmin, Double_t rmax, Double_t dz,
Double_t phi1, Double_t phi2)
{
TGeoTubeSeg *tubs = new TGeoTubeSeg(rmin, rmax, dz, phi1, phi2);
TGeoVolume *vol = 0;
if (tubs->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(tubs);
} else {
vol = new TGeoVolume(name, tubs, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeEltu(const char *name, const TGeoMedium *medium,
Double_t a, Double_t b, Double_t dz)
{
TGeoEltu *eltu = new TGeoEltu(a, b, dz);
TGeoVolume *vol = 0;
if (eltu->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(eltu);
} else {
vol = new TGeoVolume(name, eltu, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeHype(const char *name, const TGeoMedium *medium,
Double_t rin, Double_t stin, Double_t rout, Double_t stout, Double_t dz)
{
TGeoHype * hype = new TGeoHype(name, rin,stin,rout,stout,dz);
TGeoVolume *vol = 0;
if (hype->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(hype);
} else {
vol = new TGeoVolume(name, hype, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeParaboloid(const char *name, const TGeoMedium *medium,
Double_t rlo, Double_t rhi, Double_t dz)
{
TGeoParaboloid *parab = new TGeoParaboloid(rlo, rhi, dz);
TGeoVolume *vol = 0;
if (parab->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(parab);
} else {
vol = new TGeoVolume(name, parab, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeCtub(const char *name, const 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)
{
TGeoCtub *ctub = new TGeoCtub(rmin, rmax, dz, phi1, phi2, lx, ly, lz, tx, ty, tz);
TGeoVolume *vol = new TGeoVolume(name, ctub, medium);
return vol;
}
TGeoVolume *TGeoManager::MakeCone(const char *name, const TGeoMedium *medium,
Double_t dz, Double_t rmin1, Double_t rmax1,
Double_t rmin2, Double_t rmax2)
{
TGeoCone *cone = new TGeoCone(dz, rmin1, rmax1, rmin2, rmax2);
TGeoVolume *vol = 0;
if (cone->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(cone);
} else {
vol = new TGeoVolume(name, cone, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeCons(const char *name, const TGeoMedium *medium,
Double_t dz, Double_t rmin1, Double_t rmax1,
Double_t rmin2, Double_t rmax2,
Double_t phi1, Double_t phi2)
{
TGeoConeSeg *cons = new TGeoConeSeg(dz, rmin1, rmax1, rmin2, rmax2, phi1, phi2);
TGeoVolume *vol = 0;
if (cons->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(cons);
} else {
vol = new TGeoVolume(name, cons, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakePcon(const char *name, const TGeoMedium *medium,
Double_t phi, Double_t dphi, Int_t nz)
{
TGeoPcon *pcon = new TGeoPcon(phi, dphi, nz);
TGeoVolume *vol = new TGeoVolume(name, pcon, medium);
return vol;
}
TGeoVolume *TGeoManager::MakePgon(const char *name, const TGeoMedium *medium,
Double_t phi, Double_t dphi, Int_t nedges, Int_t nz)
{
TGeoPgon *pgon = new TGeoPgon(phi, dphi, nedges, nz);
TGeoVolume *vol = new TGeoVolume(name, pgon, medium);
return vol;
}
TGeoVolume *TGeoManager::MakeTrd1(const char *name, const TGeoMedium *medium,
Double_t dx1, Double_t dx2, Double_t dy, Double_t dz)
{
TGeoTrd1 *trd1 = new TGeoTrd1(dx1, dx2, dy, dz);
TGeoVolume *vol = 0;
if (trd1->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(trd1);
} else {
vol = new TGeoVolume(name, trd1, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeTrd2(const char *name, const TGeoMedium *medium,
Double_t dx1, Double_t dx2, Double_t dy1, Double_t dy2,
Double_t dz)
{
TGeoTrd2 *trd2 = new TGeoTrd2(dx1, dx2, dy1, dy2, dz);
TGeoVolume *vol = 0;
if (trd2->IsRunTimeShape()) {
vol = MakeVolumeMulti(name, medium);
vol->SetShape(trd2);
} else {
vol = new TGeoVolume(name, trd2, medium);
}
return vol;
}
TGeoVolume *TGeoManager::MakeTrap(const char *name, const 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)
{
TGeoTrap *trap = new TGeoTrap(dz, theta, phi, h1, bl1, tl1, alpha1, h2, bl2,
tl2, alpha2);
TGeoVolume *vol = new TGeoVolume(name, trap, medium);
return vol;
}
TGeoVolume *TGeoManager::MakeGtra(const char *name, const 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)
{
TGeoGtra *gtra = new TGeoGtra(dz, theta, phi, twist, h1, bl1, tl1, alpha1, h2, bl2,
tl2, alpha2);
TGeoVolume *vol = new TGeoVolume(name, gtra, medium);
return vol;
}
TGeoVolume *TGeoManager::MakeXtru(const char *name, const TGeoMedium *medium, Int_t nz)
{
TGeoXtru *xtru = new TGeoXtru(nz);
TGeoVolume *vol = new TGeoVolume(name, xtru, medium);
return vol;
}
TGeoPNEntry *TGeoManager::SetAlignableEntry(const char *unique_name, const char *path)
{
if (!CheckPath(path)) return NULL;
if (!fHashPNE) fHashPNE = new THashList(256,3);
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);
fHashPNE->Add(entry);
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 (!fHashPNE) return 0;
return (TGeoPNEntry*)fHashPNE->At(index);
}
Int_t TGeoManager::GetNAlignable() const
{
if (!fHashPNE) return 0;
return fHashPNE->GetSize();
}
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) {
node = new TGeoPhysicalNode(path);
} else {
node = new TGeoPhysicalNode();
node->SetBranchAsState();
}
fPhysicalNodes->Add(node);
return node;
}
void TGeoManager::ClearPhysicalNodes(Bool_t mustdelete)
{
if (mustdelete) fPhysicalNodes->Delete();
else fPhysicalNodes->Clear();
}
TGeoVolumeAssembly *TGeoManager::MakeVolumeAssembly(const char *name)
{
return (new TGeoVolumeAssembly(name));
}
TGeoVolumeMulti *TGeoManager::MakeVolumeMulti(const char *name, const TGeoMedium *medium)
{
return (new TGeoVolumeMulti(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()
{
fElementTable = new TGeoElementTable(200);
}
TGeoNode *TGeoManager::Step(Bool_t is_geom, Bool_t cross)
{
Double_t epsil = 0;
if (fStep<1E-6) {
fIsNullStep=kTRUE;
if (fStep<0) fStep = 0.;
} else {
fIsNullStep=kFALSE;
}
if (is_geom) epsil=(cross)?1E-6:-1E-6;
TGeoNode *old = fCurrentNode;
Int_t idold = GetNodeId();
if (fIsOutside) old = 0;
fStep += epsil;
for (Int_t i=0; i<3; i++) fPoint[i]+=fStep*fDirection[i];
TGeoNode *current = FindNode();
if (is_geom) {
fIsEntering = (current==old)?kFALSE:kTRUE;
if (!fIsEntering) {
Int_t id = GetNodeId();
fIsEntering = (id==idold)?kFALSE:kTRUE;
}
fIsExiting = !fIsEntering;
if (fIsEntering && fIsNullStep) fIsNullStep = kFALSE;
fIsOnBoundary = kTRUE;
} else {
fIsEntering = fIsExiting = kFALSE;
fIsOnBoundary = kFALSE;
}
return current;
}
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;
fUniqueVolumes->AddAtAndExpand(vol,0);
GetHMatrix();
Info("SetTopVolume","Top volume is %s. Master volume is %s", fTopVolume->GetName(),
fMasterVolume->GetName());
}
*fCurrentMatrix = gGeoIdentity;
fTopNode = new TGeoNodeMatrix(vol, gGeoIdentity);
char *name = new char[strlen(vol->GetName())+3];
sprintf(name, "%s_1", vol->GetName());
fTopNode->SetName(name);
delete [] name;
fTopNode->SetNumber(1);
fTopNode->SetTitle("Top logical node");
fCurrentNode = fTopNode;
fNodes->AddAt(fTopNode, 0);
fLevel = 0;
if (fCache) {
Bool_t dummy=fCache->IsDummy();
Bool_t nodeid = fCache->HasIdArray();
delete fCache;
fCache = 0;
BuildCache(dummy,nodeid);
}
}
void TGeoManager::SelectTrackingMedia()
{
}
void TGeoManager::CheckPoint(Double_t x, Double_t y, Double_t z, Option_t *option)
{
GetGeomPainter()->CheckPoint(x,y,z,option);
}
void TGeoManager::CheckGeometry(Option_t * )
{
Info("CheckGeometry","Fixing runtime shapes...");
TIter next(fShapes);
TGeoShape *shape;
Bool_t has_runtime = kFALSE;
while ((shape = (TGeoShape*)next())) {
if (shape->IsRunTimeShape()) {
has_runtime = kTRUE;
}
if (shape->TestShapeBit(TGeoShape::kGeoPcon) || shape->TestShapeBit(TGeoShape::kGeoArb8))
if (!shape->TestShapeBit(TGeoShape::kGeoClosedShape)) shape->ComputeBBox();
}
if (has_runtime) fTopNode->CheckShapes();
else Info("CheckGeometry","...Nothing to fix");
}
void TGeoManager::CheckOverlaps(Double_t ovlp, Option_t * option)
{
ClearOverlaps();
Info("CheckOverlaps", "Checking overlaps for %s within a limit of %g", GetName(),ovlp);
fSearchOverlaps = kTRUE;
Int_t nvol = fVolumes->GetEntriesFast();
Int_t i10 = nvol/10;
Int_t iv=0;
TIter next(fVolumes);
TGeoVolume *vol;
while ((vol=(TGeoVolume*)next())) {
iv++;
if (i10 && nvol>1000) {
if ((iv%i10) == 0) printf("%i percent\n", Int_t(10*iv/i10));
}
if (!vol->GetNdaughters() || vol->GetFinder()) continue;
vol->CheckOverlaps(ovlp, option);
}
SortOverlaps();
Int_t novlps = fOverlaps->GetEntriesFast();
TNamed *obj;
char name[15];
char num[15];
Int_t ndigits=1;
Int_t i,j, result=novlps;
while ((result /= 10)) ndigits++;
for (i=0; i<novlps; i++) {
obj = (TNamed*)fOverlaps->At(i);
result = i;
name[0] = 'o';
name[1] = 'v';
for (j=0; j<ndigits; j++) name[j+2]='0';
name[ndigits+2] = 0;
sprintf(num,"%i", i);
memcpy(name+2+ndigits-strlen(num), num, strlen(num));
obj->SetName(name);
}
fSearchOverlaps = kFALSE;
Info("CheckOverlaps","number of illegal overlaps/extrusions : %d", novlps);
}
void TGeoManager::PrintOverlaps() const
{
if (!fOverlaps) return;
Int_t novlp = fOverlaps->GetEntriesFast();
if (!novlp) return;
fPainter->PrintOverlaps();
}
void TGeoManager::UpdateCurrentPosition(Double_t * )
{
}
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")) {
Info("Weight", "Computing analytically weight of %s", volume->GetName());
weight = volume->WeightA();
Info("Weight", "Computed weight: %f [kg]\n", weight);
return weight;
}
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()) {
TGeoManager::Class()->ReadBuffer(R__b, this);
fIsGeomReading = kTRUE;
CloseGeometry();
fStreamVoxels = kFALSE;
fIsGeomReading = kFALSE;
} else {
TGeoManager::Class()->WriteBuffer(R__b, 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")) {
Info("Export","Exporting %s %s as C++ code", GetName(), GetTitle());
fTopVolume->SaveAs(filename);
return 1;
}
if (sfile.Contains(".gdml")) {
Info("Export","Exporting %s %s as gdml code", GetName(), GetTitle());
gROOT->ProcessLine("TPython::Exec(\"from math import *\")");
gROOT->ProcessLine("TPython::Exec(\"from units import *\")");
gROOT->ProcessLine("TPython::Exec(\"import writer\")");
gROOT->ProcessLine("TPython::Exec(\"import ROOTwriter\")");
gROOT->ProcessLine("TPython::Exec(\"geomgr = ROOT.gGeoManager\")");
gROOT->ProcessLine("TPython::Exec(\"topV = geomgr.GetTopVolume()\")");
const char *cmd=Form("TPython::Exec(\"gdmlwriter = writer.writer('%s')\")",filename);
gROOT->ProcessLine(cmd);
gROOT->ProcessLine("TPython::Exec(\"binding = ROOTwriter.ROOTwriter(gdmlwriter)\")");
gROOT->ProcessLine("TPython::Exec(\"matlist = geomgr.GetListOfMaterials()\")");
gROOT->ProcessLine("TPython::Exec(\"binding.dumpMaterials(matlist)\")");
gROOT->ProcessLine("TPython::Exec(\"shapelist = geomgr.GetListOfShapes()\")");
gROOT->ProcessLine("TPython::Exec(\"binding.dumpSolids(shapelist)\")");
gROOT->ProcessLine("TPython::Exec(\"print 'Traversing geometry tree'\")");
gROOT->ProcessLine("TPython::Exec(\"gdmlwriter.addSetup('default', '1.0', topV.GetName())\")");
gROOT->ProcessLine("TPython::Exec(\"binding.examineVol(topV)\")");
gROOT->ProcessLine("TPython::Exec(\"gdmlwriter.writeFile()\")");
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;
}
char keyname[256];
if (name) strcpy(keyname,name);
if (strlen(keyname) == 0) strcpy(keyname,GetName());
TString opt = option;
opt.ToLower();
if (opt.Contains("v")) {
fStreamVoxels = kTRUE;
Info("Export","Exporting %s %s as root file. Optimizations streamed.", GetName(), GetTitle());
} else {
fStreamVoxels = kFALSE;
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;
}
TGeoManager *TGeoManager::Import(const char *filename, const char *name, Option_t * )
{
if (fgLock) {
printf("WARNING: TGeoManager::Import : TGeoMananager in lock mode. NOT IMPORTING new geometry\n");
return NULL;
}
if (!filename) return 0;
printf("Info: TGeoManager::Import : Reading geometry from file: %s\n",filename);
if (gGeoManager) delete gGeoManager;
gGeoManager = 0;
if (strstr(filename,".gdml")) {
const char* cmd = Form("TGDMLParse::StartGDML(\"%s\")", filename);
TGeoVolume* world = (TGeoVolume*)gROOT->ProcessLineFast(cmd);
gGeoManager->SetTopVolume(world);
gGeoManager->CloseGeometry();
gGeoManager->DefaultColors();
} else {
TFile *old = gFile;
TFile *f = TFile::Open(filename);
if (!f || f->IsZombie()) {
if (old) old->cd();
printf("Error: TGeoManager::Import : Cannot open file\n");
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;
}
}
if (old) old->cd();
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);
elem_table = fElementTable->GetElement(elem->Z());
if (elem != elem_table) {
elem_table->SetDefined(elem->IsDefined());
elem_table->SetUsed(elem->IsUsed());
} else {
elem_table->SetDefined();
}
}
} else {
elem = mat->GetElement();
elem_table = fElementTable->GetElement(elem->Z());
if (elem != elem_table) {
elem_table->SetDefined(elem->IsDefined());
elem_table->SetUsed(elem->IsUsed());
} else {
elem_table->SetUsed();
}
}
}
}
Int_t *TGeoManager::GetIntBuffer(Int_t length)
{
if (length>fIntSize) {
delete [] fIntBuffer;
fIntBuffer = new Int_t[length];
fIntSize = length;
}
return fIntBuffer;
}
Double_t *TGeoManager::GetDblBuffer(Int_t length)
{
if (length>fDblSize) {
delete [] fDblBuffer;
fDblBuffer = new Double_t[length];
fDblSize = length;
}
return fDblBuffer;
}
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
{
fCurrentMatrix->MasterToLocal(master, top);
}
void TGeoManager::TopToMaster(const Double_t *top, Double_t *master) const
{
fCurrentMatrix->LocalToMaster(top, master);
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.