Re: delete time for complex geometries

From: Valeri Fine (Faine) (fine@bnl.gov)
Date: Sat Apr 01 2000 - 03:07:43 MEST


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