Divided node path of a TGeoVolume

Hi,
I use the following lines to split a volume to sub-volumes along x, y and z axis:

  TGeoManager * gGeoManager = new TGeoManager("top","");
  TGeoVolume *vbox = gGeoManager->MakeBox("vbox", 0, 20,30,40);
  gGeoManager->SetTopVolume(vbox);

  TGeoVolume *divx = (TGeoVolume *)vbox->Divide("SLICEX",1, 5, -10, 2);
  TGeoVolume *divy = (TGeoVolume *)divx->Divide("SLICEY",2, 20, -10, 2);
  TGeoVolume *divz = (TGeoVolume *)divy->Divide("SLICEZ",3, 20, -10, 2);  
  gGeoManager->cd("/vbox_1/SLICEX_2/SLICEY_3/SLICEZ_4");

The path format, [ul]/vbox_1/SLICEX_2/SLICEY_3/SLICEZ_4[/ul] looks not right. The error is:
[ul] Error in TGeoNavigator::cd: Path /vbox_1/SLICEX_2/SLICEY_3/SLICEZ_4 not valid [/ul]

How can I get the correct path format of one of nodes created?

Thanks,
Zhiyi.

And another puzzle is: The total number of nodes by gGeoManager->CountNodes(vbox) is 2106, why not 2000?

Hi,
For the first puzzle, you solve it if you first call gGeoManager->CloseGeometry() - as the manual recommends if you want to have a valid geometry.

For the second puzzle, you have to count also the intermediate nodes in your hierarchy:
/vbox_1/SLICEX_2/SLICEY_3/SLICEZ_4 is the path to a node, but also:
/vbox_1
/vbox_1/SLICEX_2
or:
/vbox_1/SLICEX_2/SLICEY_3
In this particular case these intermediate paths are empty (i.e. you are always in an inner cell), but generally this is not the case so these can be real physical nodes. Up to you to solve exactly the math problem giving the formula that puts the count to 2106 :wink:

Cheers,

Maybe 1+5+520+520*20 ?

thank you so much, Andrei. That works!

Actually, the next step is to set different colors of individual ‘cells’ split by “geovolume->Divide(…)”. I looked through your post replies at:
[url]Q: Is there any way to get pointer to a node by using path?
and it addressed that it is not possible to set different colors. However, by using TGeoIteratorPlugin, it did the trick. I try to use the following code


  TGeoManager * gGeoManager = new TGeoManager("top","");
  TGeoVolume *vbox = gGeoManager->MakeBox("vbox", 0, 20,30,40);
  gGeoManager->SetTopVolume(vbox);

  cout << gGeoManager->AddVolume(vbox) << endl;
  vbox->Draw("ogl");

  TView *view = gPad->GetView();  
  view->ShowAxis();
  
  TGeoVolume *divx = (TGeoVolume *)vbox->Divide("SLICEX",1, 5, -10, 2);
  TGeoVolume *divy = (TGeoVolume *)divx->Divide("SLICEY",2, 20, -10, 2);
  TGeoVolume *divz = (TGeoVolume *)divy->Divide("SLICEZ",3, 20, -10, 2);
  gGeoManager->CloseGeometry();

  gPad->Update();
  gPad->Modified();

  iterplugin *plugin = new iterplugin();
  cout << "Total nodes: " << divy->GetNtotal() << endl;

  TGeoNode *node;
  int index = 0;
  TString name("/vbox_1/SLICEX_5/SLICEY_20/SLICEZ_20");
  gGeoManager->cd(name.Data());
  TGeoIterator * next = new TGeoIterator(gGeoManager->GetCurrentNode()->GetVolume());
  gGeoManager->GetGeomPainter()->SetIteratorPlugin(plugin);
  plugin->SetIterator(next);
  plugin->Select(2);
  gGeoManager->GetGeomPainter()->ModifiedPad();  
}

with the attached modified class “iterplugin”. However, it is not successful. Could you give me some hints why it failed?

Thank you,
Zhiyi.
iterplugin_zyliu.cxx (921 Bytes)

Hi,
If you want that, you have to do something like $ROOTSYS/tutorials/geom/runplugin.C (and attach the plugin to the painter’s iterator)

Cheers,

Hi Andrei,
the macro runplugin.C is the exact example that I was looking at to produce my code above. As you can see, the modified class is based on the example class.

What do you mean exactly “attach the plugin to the painter’s iterator”? In my code above, I did

  gGeoManager->GetGeomPainter()->SetIteratorPlugin(plugin);
  plugin->SetIterator(next);
  plugin->Select(2);
  gGeoManager->GetGeomPainter()->ModifiedPad(); 

I expect this should be working, however, not.

Cheers,
Zhiyi.

[quote=“agheata”]Hi,
If you want that, you have to do something like $ROOTSYS/tutorials/geom/runplugin.C (and attach the plugin to the painter’s iterator)

Cheers,[/quote]

Hi,
That fails because you have to derive your own iterator plugin class and implement the method ProcessNode(). When this is connected via: gGeoManager->GetGeomPainter()->SetIteratorPlugin(plugin); your ProcessNode gets called for every physical node that gets painted. In your ProcessNode() you have to check if the physical node corresponds to what you want to select, then you are allowed to change its line properties (in the trunk you can also change transparency). Your code did not work because that iterator plugin was made for a different geometry and was looking for volumes named REPLICA.

The attached macro allows you to select one cell via the select() method. Do:

.L test.C+ test(); // selects the cell you wanted select(3,20,15,kRed); // selects another cell
Use the trunk to get the correct transparency. You can use ‘w’ on the gl window to see the wireframe mode.

test.C (3.32 KB)

Cheers,

Hi Andrei,
Fantastic! I know my problem now, thank you so much! I changed your code a bit to try to set transparency or set visibility for one specific cell. It looks like ‘SetVisibility’ not only changed the cell itself, but also all the cells which are located behind the cell. Any hint?

Thanks,
Zhiyi.
test_vis.C (3.44 KB)

SetVisibility is not supported, i.e. you can just change color and transparency.
Cheers,

Thank you so much, Andrei. My problem has been solved by you!

Cheers,
Zhiyi.
P.S. For other interested guys, I uploaded a modified version to change color of multi-cells and set non-touched cells invisible …
test_many.C (4.27 KB)