GDML import: how to correctly operate translation in selected volume

I am importing a gdml file into root and drawing only some of the volumes, though TGeoManager::GetVolume().

This works pretty fine, as I am able to draw only those volumes that I am interested in.

However, I can’t figure out how to move one of the volumes by a certain distance. I have tried TGeoTranslation according to the code I am pasting, but the distances are not right.

The gdml file contains only two 14x14x.5 mm boxes that are placed at exactly the same position. If I move one of them by 1mm, I would expect to have the two boxes at 0.5mm from each other. Using the box’s thickness as a scale, it seems more like 3mm…

What am I doing wrong?

{
    gStyle->SetCanvasPreferGL("kTRUE");

    // import the gdml file
    TGeoManager *geom = TGeoManager::Import("example.gdml");

    // Select only the volumes I want to draw (they overlapping at exactly the same position)
    TGeoVolume *vol1 = geom->GetVolume("Sensor_G3_vol");
    TGeoVolume *vol2 = geom->GetVolume("Sensor_G3_vol_2");

    // The translation (1mm in the x-direction)
    TGeoTranslation *tr1 = new TGeoTranslation("tr1", .1, 0, 0);

    // apply the translation to vol2
    vol2->AddNode(vol2, 1, tr1);

    // Draw and wonder why vol2 moved around 3mm, instead of 1mm
    vol1->Draw("");
    vol2->Draw("same");

    // This is only to draw the axes
    Bool_t axis = kTRUE;
    TView *view = gPad->GetView();
    if (view)
    {
        //      view->RotateView(248,66);
        if (axis)
        {
            view->ShowAxis();
            view->SetParallel();
        }
    }
}

The public link to the gdml file:
example.gdml

_ROOT Version: 6.26
_Platform: Mac OS
Compiler: Not Provided


I guess @agheata can help.

Is there really no solution to this? Are these TGeo classes that exotic?
I would be very grateful for any help…

As I said, as it is a TGeo question, @agheata should know.

Hi @hugonluz and sorry for the delay. You are adding a volume to itself (vol2) which is incorrect. In addition, after importing the gdml file you are not allowed to add new nodes because the geometry is closed, but you can align nodes changing their position. There is an example in the tutorials .x $ROOTSYS/tutorials/geom/geodemo.C clicking on Aligned (ideal) then Un-aligned. Applied to your problem, you need to replace the line vol2->AddNode(vol2...) with:

    TGeoPhysicalNode pn("/World_1/Sensor_G3_vol_2_0");
    pn.Align(tr1);

P.S. It is not a good idea to do this if your geometry has a single configuration, in such case the translations should be hardcoded in the gdml file directly without the need to “un-align”

Thank you @agheata, I got the idea. This works if I draw everything that is in the gdml file:

TGeoManager *geom = TGeoManager::Import("example.gdml");
TGeoVolume *top = geom->GetVolume("World");
geom->SetTopVolume(top);
TGeoTranslation *tr1 = new TGeoTranslation("tr1", .1, 0, 0);
TGeoPhysicalNode pn("/World_1/Sensor_G3_vol_2_0");
pn.Align(tr1);
top->Draw();

My problem is that I would like to draw only the volumes that are relevant to my plot. That is why I am defining the TGeoVolume instances. I could simply comment them in the gdml file, but this is not practical for aligning one single piece of a complex system…

Is there a way to do this? (select two specific volumes of a detector with 1000 parts, (un)align one of them and plot only those two volumes)

Volumes are hierarchic, when you draw one you actually draw either the volume itself or its content at a given depth, in the local reference frame of the volume. To draw sibling volumes at the same level you need to draw the parent volume and set the visibility depth (TGeoManager::SetVisDepth) to 1 (otherwise you will see the deeper content). You can play with the volume visibility if the placed nodes are not replicas of the same volume object. In your case, after you call Align, you can do something like:

    TIter next(top->GetNodes());
    while (auto node = (TGeoNode*)next()) {
      node->GetVolume()->SetVisibility(false);
      if (!strcmp(node->GetName(), "Sensor_G3_vol_2_0"))
        node->GetVolume()->SetVisibility(true);
    }

This does what I need.
I got it: I should work with the top volume, setting the visibility only for those nodes I want to draw.
Thank you very much!