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