Problem 2288

Summary: Can't write to GDML file if it already exists
Product: Geant4 Reporter: seligman
Component: persistency/gdmlAssignee: Witold.Pokorski
Status: RESOLVED FIXED    
Severity: minor    
Priority: P4    
Version: 10.6   
Hardware: All   
OS: All   

Description seligman 2020-11-05 01:23:55 CET
If you try to write to a GDML file, and that file already exists, a G4 application program will terminate with a fatal exception. 

For a simple example, go to examples/extended/persistency/gdml/G01. Build the example and execute:

load_gdml axes.gdml axes-out.gdml

It will execute without any problems. But if just hit an up-arrow and run the program again:

G4GDML: Writing 'axes-out.gdml'...

-------- EEEE ------- G4Exception-START -------- EEEE -------
*** G4Exception : InvalidSetup
      issued by : G4GDMLWrite::Write()
File 'axes-out.gdml' already exists!
*** Fatal Exception *** core dump ***
 **** Track information is not available at this moment
 **** Step information is not available at this moment

-------- EEEE -------- G4Exception-END --------- EEEE -------

This makes testing any G4 application that can write a GDML file more difficult to test, since you always have to remember to delete the GDML output file. 

I tried to work around this in my application by deleting the GDML output file from my application if it existed:

      G4String gdmlOutput = \*whatever*\     
      G4FileUtilities utilities;
      if ( utilities.FileExists( gdmlOutput ) ) {
        auto result = utilities.DeleteFile ( gdmlOutput, "-f");
      }
      G4cout << "Writing geometry to '" << gdmlOutput << "'" << G4endl;
      fGDMLparser.Write(gdmlOutput, fGDMLparser.GetWorldVolume());

But this does not work as intended. While the file 'gdmlOutput' is deleted, and the program appears to create the output file; e.g.,:

Writing geometry to 'parsed.gdml'
G4GDML: Writing 'parsed.gdml'...
G4GDML: Writing definitions...
G4GDML: Writing materials...
G4GDML: Writing solids...
G4GDML: Writing structure...
G4GDML: Writing setup...
G4GDML: Writing surfaces...
G4GDML: Writing 'parsed.gdml' done !

the GDML output file is _not_ created. 

Why won't G4GDMLWrite::Write() overwrite an existing GDML file if that's what the user wants to do? And why, when I try the work-around above, is no actual GDML file created?
Comment 1 Witold.Pokorski 2020-11-05 19:53:09 CET
Thanks for pointing out this potential improvement. I have added a new method to the parser SetOutputFileOverwrite(G4bool flag) which allows you to set the flag to overwrite output files. To use it you will have to call:

fGDMLparser.SetOutputFileOverwrite(true);
fGDMLparser.Write(gdmlOutput, fGDMLparser.GetWorldVolume());

This functionality will be available in the next release of Geant4.

As far as your work around is concerned, to be honest I don't know why it does not work...

If you want to hack your current Geant4 installation to overwrite the file, you can edit G4GDMLWrite.cc file and comment out the lines 205-210 where the check for the file is done.
Comment 2 Gabriele Cosmo 2020-11-24 10:17:38 CET
Modification will be available in the next coming release.