Hi, Robert,
I've to investigate your macro carefully
Mean time did you try to compile your code ?
Valery
> 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