Problem 2343 - Multiple Assemblies aren't written to GDML fully
Summary: Multiple Assemblies aren't written to GDML fully
Status: RESOLVED FIXED
Alias: None
Product: Geant4
Classification: Unclassified
Component: persistency/gdml (show other problems)
Version: 10.7
Hardware: All All
: P4 major
Assignee: Witold.Pokorski
URL:
Depends on:
Blocks:
 
Reported: 2021-03-03 20:50 CET by Laurie Nevay
Modified: 2021-11-08 11:02 CET (History)
0 users

See Also:


Attachments
patch file for fix (1.96 KB, text/plain)
2021-03-03 20:50 CET, Laurie Nevay
Details

Note You need to log in before you can comment on or make changes to this problem.
Description Laurie Nevay 2021-03-03 20:50:09 CET
Created attachment 680 [details]
patch file for fix

If you use more than one assembly in a model it will not write out to GDML fully using G4GDMLParser. The contents of the assembly are written out (like a logical volume) correctly, but the physvol is made once (avoiding a new physvol for the assembly per physical volume inside it), but by the imprint ID. If a second assembly comes along it can also have an imprint ID of say 1, so then the imprint / physvol isn't made of the second assembly.

To recreate: model with two unique assembly volumes placed in the world. Export to GDML, read in again -> second assembly volume missing in phsvols. 

In my model I used 5 assemblies, some with a few (e.g. 3-5) volumes, one with ~120 volumes. When I view my exported model again, half of it is missing. Proposed solution below fixes it.

I think the problem is in source/persistency/gdml/src/G4GDMLWriteStructure.cc ::TraverseVolumeTree, line 707

(addedImprints is of type std::vector<int>)
if(std::find(addedImprints.cbegin(), addedImprints.cend(), imprintID) == addedImprints.cend())
{
  // write phys vol
  addedImprints.push_back(imprintID)
}

I think this can be fixed by keeping a vector of imprintIDs *per* assembly volume ID. So for example,

std::map<int, std::vector<int> >
assemblyID -> vector<imprintIDs>

I've attached a patch file (needs removal of old variables still) that fixes the issue for me.

Note, use & to ensure vector in map is updated, not a copy. map entry is initialised with empty vector when assembly is added before so it can be safely accessed in the map without searching.

Also, when you write Imprint_ID  there's no trailing _ so it becomes Imprint_ID0xpointer. Given a good part of GDML reading is based on breaking up the names to form IDs, I also fixed this - line 710.

Is this right?  What do you think?

Best,
Laurie
Comment 1 Witold.Pokorski 2021-03-17 19:04:47 CET
Thanks for this fix. I have tested it and it seems to work fine! The code is now in the repository and will be part of the next release.