Accessing TGeoVolume by name and copy number

So, this is a question about Geant4 and ROOT. I am new to Geant4 and working with gdml. I also asked this question in the ROOT forum but they suggested to ask here. And it’s my first post here, so hello everybody!

I have a Geant4 code (not mine) which generates multiple copies of SiPM detector, like this:

G4Box* Sipm = new G4Box("SiPM", SiPM_X/2, SiPM_Y/2, SiPM_Z/2);
G4LogicalVolume* lSipm = new G4LogicalVolume(Sipm, Optmat, "SiPM");
 
for(G4int i=0; i<52; i++) {
    new G4PVPlacement(0, G4ThreeVector(SP_X[i], SP_Y[i], SiPM_Z[i]),
                                       "Physi_SiPM", lSipm, physiWorld, true, i);
  }

and I added exporting the geometry to gdml:

Geant4GM::Factory factory;
factory.SetDebug(1);
factory.Import(physiWorld);
XmlVGM::GDMLExporter xmlExporter2(&factory);
xmlExporter2.GenerateXMLGeometry();

It works nice, I have gdml file (this is only part relevant for SiPM):

   <solids>
      <box  lunit="cm" aunit="degree"
         name="SiPM_s"
         x="    0.6000"  y="    0.6000"  z="    0.0500" />
   </solids>
   <structure>
      <volume name="SiPM">
         <materialref ref="optgelmat"/>
         <solidref ref="SiPM_s"/>
      </volume>
      <volume name="World">
         <physvol>
            <volumeref ref="SiPM"/>
               <positionref ref="pos_6"/>
               <rotationref ref="rot_0"/>
         </physvol>
         <physvol>
            <volumeref ref="SiPM"/>
               <positionref ref="pos_7"/>
               <rotationref ref="rot_0"/>
         </physvol>
         <!-- and so on... -->
      </volume>
   </structure>

I can import it into ROOT and TEve:

Info in <TGeoManager::Import>: Reading geometry from file: World.gdml
Info in <TGeoManager::TGeoManager>: Geometry GDMLImport, Geometry imported from GDML created
Info in <TGeoManager::SetTopVolume>: Top volume is World. Master volume is World
Info in <TGeoNavigator::BuildCache>: --- Maximum geometry depth set to 100
Info in <TGeoManager::CheckGeometry>: Fixing runtime shapes...
Info in <TGeoManager::CheckGeometry>: ...Nothing to fix
Info in <TGeoManager::CloseGeometry>: Counting nodes...
Info in <TGeoManager::Voxelize>: Voxelizing...
Info in <TGeoManager::CloseGeometry>: Building cache...
Info in <TGeoManager::CountLevels>: max level = 2, max placements = 88
Info in <TGeoManager::CloseGeometry>: 117 nodes/ 11 volume UID's in Geometry imported from GDML
Info in <TGeoManager::CloseGeometry>: ----------------modeler ready----------------

and when displayed in TEve I see that all SiPMs have the same name SiPM_0:

How can I access each copy of the SiPMs? I can access only single volume using the SiPM name (not even SiPM_0 or any other number).

root [1] auto vol = aGeom->GetVolume("SiPM")
(TGeoVolume *) 0x55a41b7bf2c0
root [2] auto vol = aGeom->GetVolume("SiPM_0")
(TGeoVolume *) nullptr

What I would like, is to be able to have/access e.g. SiPM clone nr 15 directly. How can it be done? Perhaps can I somehow export from Geant4 the name already as SiPM_0, SiPM_1, etc.

What do you need from these volumes after construction?

For example I think this answers your question if you wrapped it in a function for a particular index i:

G4PhysicalVolumeStore* store = G4PhysicalVolumeStore::GetInstance();
for (auto pv : *store) {
    if (pv->GetName() == "Physi_SiPM" && pv->GetCopyNo() == i) {
        // Found it
    }
}

That is fairly clunky. Usually you only need to access these volumes in the stepping or tracking action such as in sensitive detectors. Because generally every other property is something you control. In that case as an example in the stepping action if you just want the ID:

step->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(0)+ step->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(1)+ step->GetPreStepPoint()->GetTouchableHandle()->GetCopyNumber(2) + ...

Where GetCopyNumber(N) gives you the copy number of the Nth generation in ascending order. So 0 is the SIPM (i.e. SIPM_0), 1 is the mother (defaults to world), 2 would be the grandmother (if it exists), etc. In general GetTouchableHandle will give you access to most of what you could need for particles traversing your geometry.

I actually don’t need to use them in G4. I need them in ROOT. E.g. I am writing some event viewer so when a certain channel is fired, I want to access the geometry volume to play with it.

But apparently, although each volume has some copy number 0, 1, 2, …, this indexing is not forwarded into gdml, and into TGeoManager in ROOT. So, is there a way that the nodes have the copy id somehow forwarded into gdml and ROOT?

How did you export the gdml file, through Geant4 or through ROOT?

If the geometry is exported/imported through Geant4 the copy numbers should be properly exported/imported.

It was through G4. This is the code:

Geant4GM::Factory factory;
factory.SetDebug(1);
factory.Import(physiWorld);
XmlVGM::GDMLExporter xmlExporter2(&factory);
xmlExporter2.GenerateXMLGeometry();

Is Geant4GM::Factory and XmlVGM::GDMLExporter custom code?

Note that the ability to import/export volumes copy-numbers was added in Geant4 version 10.1 (and GDML schema 3.1.3). So, if you’re using an older version it won’t work.

I have Geant4 11.3.2 and Geant4GM::Factory and XmlVGM::GDMLExporter come from VGM 5.3.1. So I think everything is pretty new. This is the gdml schema:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<gdml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="
http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd">

and it was written by XmlVGM::GDMLExporter. Can I control the schema version?

VGM is not part of Geant4. I don’t know how GDML files are exported/imported in VGM… it likely does not use the G4GDMLParser of Geant4, but rather uses its own tools and is not filling/considering the copynumber attribute defined for volumes in recent GDML schema.

You should contact VGM developers.

Thank you for the clarification. I was aware that vmg isn’t part of G4, however when googling the topic, most hits was referring to it.

Can you perhaps guide me into some documentation about how to export GDML file natively in Geant4? Documentation is very sparse, I also didn’t found any example in the examples at Geant4 page. Maybe I was looking wrong? Some help or simple code snipped as a starting point would be appreciated.

I think I found the example code. Will come again if I had some more issues.

I will also report this topic to VGM team, maybe they will be interested.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.