I'm attempting to build a large geometry (484 x 193 = 93412 objects)
using TShape and TNode objects and I'm finding that while the
construction time is tolerable, the time to delete the object is
impossibly long (scales not linearly with the number of objects but
N^2 or N! ?).
Is there anything that can be done about this behaviour?
Also while everything appears to run fine for small numbers, at larger
numbers earlier attempts also generated a SEGV in the TGeometry deletion.
I don't think it was a coding error on my part, but I haven't run
to "completion" on this latest version.
-robert
========= running the macro =================================
* Version 2.23/12 1 February 2000 *
<on Linux (RedHat 5.2 I believe)>
Compiled with thread support.
CINT/ROOT C/C++ Interpreter version 5.14.25, Nov 25 1999
root [0] .L time_geom.C
root [1] time_geom(48,0);
build geometry nplanes=48 nstrips=192
cummulative time
basics Real time 0:0:0, CP time 0.010
matrices Real time 0:0:0, CP time 0.010
shapes Real time 0:0:1, CP time 1.350
nodes Real time 0:0:10, CP time 10.440
done building
shape list has 9266 entries
world node has 51 sub-nodes
destroy geometry Real time 0:0:14, CP time 14.920
done destruction
root [2] time_geom(484,0);
build geometry nplanes=484 nstrips=192
cummulative time
basics Real time 0:0:0, CP time -0.000
matrices Real time 0:0:0, CP time -0.000
shapes Real time 0:0:13, CP time 13.660
nodes Real time 0:1:45, CP time 105.630
done building
shape list has 93414 entries
world node has 487 sub-nodes
<hours pass.....>
========= time_geom.C =================================
void time_geom(int nplanes=48, int drawlevel=0)
{
// Stuff to run this under root and see the result
gROOT->Reset();
gStyle->SetPalette(1,0);
TStopwatch sw;
int nstrips;
float hwplane,dzpln,zpos;
char *planename = "pXXX";
char *stripname = "pXXXsXX";
// int nplanes;
// dbi_detinfo(nplanes);
dbi_plninfo(nplanes-1,nstrips,hwplane,dzpln,zpos);
sw.Start(true);
cout << endl << " build geometry "
<< " nplanes=" << nplanes << " nstrips=" << nstrips << endl;
cout << " cummulative time" << endl;
cout << " basics ";
TGeometry *mygeom = new TGeometry("mygeom","my detector");
// define the world
Float_t hxysize = hwplane * 1.1;
Float_t hzsize = (zpos+dzpln) * 1.25;
TBRIK *worldvol = new TBRIK("worldvol","The world space","void",
hxysize,hxysize,hzsize);
TNode *worldnode = new TNode("worldnode","The world node",worldvol);
// passing 0 for TRotMatrix* produces a rotation matrix named "Identity"
Float_t tmarkerxy = hwplane;
Float_t tmarkerz = (zpos+dzpln);
// create little x,y,z markers
TSPHE *sphere = new TSPHE("sphere","sphere","void",10.);
TNode *xmarker = new TNode("xmarker","xmarker",sphere,tmarkerxy,0.,0.);
TNode *ymarker = new TNode("ymarker","ymarker",sphere,0.,tmarkerxy,0.);
TNode *zmarker = new TNode("zmarker","zmarker",sphere,0.,0.,tmarkerz);
sw.Stop();
sw.Print();
sw.Continue();
cout << " matrices ";
build_matrices();
sw.Stop();
sw.Print();
sw.Continue();
cout << " shapes ";
build_shapes(nplanes);
sw.Stop();
sw.Print();
sw.Continue();
cout << " nodes ";
build_nodes(nplanes,worldnode,drawlevel);
sw.Stop();
sw.Print();
sw.Continue();
cout << endl << " done building " << endl << endl;
sw.Stop();
if (drawlevel) {
sw.Start(true);
cout << " draw geometry ";
TCanvas *c1 = new TCanvas("c1","detector geometry",200,10,700,700);
mygeom->Draw();
c1->Update();
sw.Stop();
sw.Print();
sw.Continue();
cout << " done draw " << endl << endl;
sw.Stop();
}
THashList *shapelist = mygeom->GetListOfShapes();
Int_t entries_s = shapelist->GetSize();
cout << " shape list has " << entries_s << " entries " << endl << endl;
TList *planelist = worldnode->GetListOfNodes();
Int_t entries_p = planelist->GetSize();
cout << " world node has " << entries_p << " sub-nodes" << endl << endl;
sw.Start(true);
cout << " destroy geometry ";
delete mygeom;
sw.Stop();
sw.Print();
sw.Continue();
cout << " done destruction " << endl << endl;
sw.Stop();
}
void build_matrices(void)
{
TRotMatrix *rotX =
new TRotMatrix("rotX","X rotation", 90., 0., 90., 90., 0., 0.);
TRotMatrix *rotU =
new TRotMatrix("rotU","U rotation", 90.,-45., 90., 45., 0., 0.);
TRotMatrix *rotV =
new TRotMatrix("rotV","Y rotation", 90., 45., 90.,135., 0., 0.);
}
void build_shapes(int nplanes)
{
// Normally these dimensions would all come out of the
// detector construction database ... but for our purposes
// we'll just use a fake DBI
int istrip;
int iplane;
int nstrips;
float hwplane,dzpln,zpos;
char *planename = "pXXX";
char *stripname = "pXXXsXX";
float dx,dy,dz,x0,y0,z0;
char *rotname = "rotX";
// int nplanes;
// dbi_detinfo(nplanes);
// loop over all strips in all planes and construct the shape
// using info from fake database interface
TPGON *aplanevol;
TBRIK *astripvol;
for (iplane = 0; iplane != nplanes; iplane++) {
// octogonal planes
dbi_plnname(iplane,planename);
dbi_plninfo(iplane,nstrips,hwplane,dzpln,zpos);
Float_t rout = hwplane;
Float_t rin = (1-1.0e-6)*rout;
Float_t deg2rad = TMath::Pi()/180;
Float_t cos22p5 = TMath::Cos(deg2rad*45/2);
Float_t sin45 = TMath::Sin(deg2rad*45);
rout = rout * sin45 / cos22p5;
rin = rin * sin45 / cos22p5;
aplanevol = new TPGON(planename,planename,"void",-22.5,360.,8,2);
aplanevol->DefineSection(0,-dzpln,rin,rout);
aplanevol->DefineSection(1,+dzpln,rin,rout);
for (istrip = 0; istrip != nstrips; istrip++) {
// individual strips
dbi_stripname(iplane,istrip,stripname);
dbi_stripinfo(iplane,istrip,dx,dy,dz,x0,y0,z0,rotname);
astripvol = new TBRIK(stripname,stripname,"void",dx,dy,dz);
}
}
}
void build_nodes(int nplanes, TNode *worldnode, int drawlevel)
{
// Normally these positions would all come out of the
// detector construction database ... but for our purposes
// we'll just use a fake DBI
// if "drawlevel" = 0 set everything invisible
// 1 draw some strips of first/last plane
// 2 all strips
int istrip;
int iplane;
int nstrips;
float hwplane,dzpln,zpos;
char *planename = "pXXX";
char *stripname = "pXXXsXX";
float dx,dy,dz,x0,y0,z0;
char *rotname = "rotX";
// int nplanes;
// dbi_detinfo(nplanes);
// loop over all strips in all planes and construct the shape
// using info from fake database interface
TNode *aplanenode;
TNode *astripnode;
for (iplane = 0; iplane != nplanes; iplane++) {
dbi_plnname(iplane,planename);
dbi_plninfo(iplane,nstrips,hwplane,dzpln,zpos);
worldnode->cd();
aplanenode = new TNode(planename,planename,
planename,0,0,zpos,"Identity");
switch (drawlevel)
{
case 0: // everything invisible
aplanenode->SetVisibility(-1);
break;
case 1: // most are invisible (neither node nor sons)
aplanenode->SetVisibility(-1);
if (iplane==0 || iplane == nplanes-1) aplanenode->SetVisibility(1);
break;
case 2: // everything visible
aplanenode->SetVisibility(1);
break;
}
for (istrip = 0; istrip != nstrips; istrip++) {
// individual strips
dbi_stripname(iplane,istrip,stripname);
dbi_stripinfo(iplane,istrip,dx,dy,dz,x0,y0,z0,rotname);
aplanenode->cd();
astripnode =
new TNode(stripname,stripname,stripname,x0,y0,z0,rotname);
switch (drawlevel)
{
case 0: // everything invisible
astripnode->SetVisibility(0);
break;
case 1: // draw every 4th of first/last plane)
astripnode->SetVisibility(0);
if (iplane==0 || iplane == nplanes-1) {
if (istrip%4 == 0) astripnode->SetVisibility(1);
astripnode->SetLineColor(51+istrip/4);
}
break;
case 2: // everything visible
astripnode->SetVisibility(1);
break;
}
}
}
}
void dbi_detinfo(int &nplanes)
{
// number of planes in the detector
nplanes = 24;
nplanes = 48;
// nplanes = 484;
}
void dbi_plnname(int ipln, char *planename)
{
sprintf(planename,"p%3.3x",ipln);
}
void dbi_stripname(int ipln, int istrip, char *stripname)
{
sprintf(stripname,"p%3.3xs%2.2x",ipln,istrip);
}
void dbi_plninfo(int ipln,
int &nstrips, float &hwplane, float &dzpln, float &zpos)
{
// info about each plane ... for now they're all the same
nstrips = 192;
hwplane = 400;
dzpln = 0.5 * 1.1;
zpos = dzpln + ipln*5.25;
}
void dbi_stripinfo(int ipln, int istrip,
float &dx, float &dy, float &dz,
float &x0, float &y0, float &z0,
char *rotname)
{
int nstrips;
float hwplane,dzpln,zpos;
dbi_plninfo(ipln,nstrips,hwplane,dzpln,zpos);
// constraint nstrips*(2*dy) + (nstrips-1)*(2*hgap) = 2*hwplane
Float_t hgap = 0.033; // average .66mm gap between strips
dy = (hwplane - (nstrips-1)*hgap) / nstrips;
Float_t deltat = 2.0 * (dy+hgap);
Float_t toffset = (float)(nstrips-1)/2. * (-deltat);
z0 = 0.; // no offset within the plane
Float_t t, tabs, tcut;
tcut = hwplane * TMath::Tan(22.5*TMath::Pi()/180.);
t = toffset + istrip*deltat;
tabs = TMath::Abs(t);
dx = hwplane;
if ((tabs+dy) > tcut) {
dx = tcut + hwplane-(tabs+dy);
}
Float_t dxdy;
if ((ipln&1) == 0) {
sprintf(rotname,"rotU");
dxdy = +1;
} else {
sprintf(rotname,"rotV");
dxdy = -1;
}
Float_t rsqrt2 = 1./TMath::Sqrt(2.);
y0 = t * rsqrt2;
x0 = dxdy * y0;
}
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:22 MET