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