Closed jirakova closed 2 years ago
Thanks for reporting this. We also need to specify in the docstring that simulation_path
is a path to the run directory. Because for a SOLPS user, the simulation directory is the one with run and baserun subdirectories.
There are two use cases I regularly see used for load_solps_from_raw_output
:
The cherab-solps module was originally developed with option 2 in mind (the original authors did not run SOLPS). So the expectation was that you would receive all the files necessary from somebody else, stick them in a single directory and point Cherab at that directory.
Now more cherab-solps users are actually SOLPS users too, option 1 is important to support. But I don't think we should make any implicit, hard coded assumptions about the directory structure. It would be fine to add an additional argument, called something like baserun_path
, so a user can direct the code to look in this additional directory for files it doesn't find in simulation_path
. It could even default to simulation_path/../baserun
. But this should be clearly documented rather than work like black magic under the hood.
What about having a separate method rather than an argument? The only difference is getting the correct paths and then the rest function is the same. Separating it in two methods might be clearer and it could have simple docs
I think that baserun
and run
directories are hard coded into SOLPS, so there are only two possible cases:
1) all the files are in the same directory,
2) b2fgmtry is in the baserun
and all other files are in the run
.
@jirakova, can you comment on this?
I don't think that we need another argument, especially if baserun and run are hard coded into SOLPS. However, I certainly agree with @jacklovell that the search paths should be documented.
"""
:param str simulation_path: String path to simulation directory.
Example: '/home/user/solps5/runs/simulation_name/run'.
Note that 'b2fgmtry' will be searched for in
'simulation_path/../baserun', if it is not found in
'simulation_path'.
"""
As far as I know, it is mandatory that "simulations" are stored in $SOLPSTOP/runs
under an arbitrary name. Each "simulation" must contain exactly one baserun folder. Individual "runs" are usually stored in parallel to baserun, each under an arbitrary name within the simulation folder, but they can be grouped in subdirectories as well. Therefore, run_path/../baserun
will usually point to the baserun directory, but not necessarily so.
In my experience, it would be best to search for any missing files in run_path/../baserun
by default, but also to offer the user a possibility to define their own path to the baserun directory.
Individual "runs" are usually stored in parallel to baserun, each under an arbitrary name within the simulation folder, but they can be grouped in subdirectories as well.
I see, thank you. This means that I was wrong about the directory structure.
It would be fine to add an additional argument, called something like baserun_path, so a user can direct the code to look in this additional directory for files it doesn't find in simulation_path. It could even default to simulation_path/../baserun.
Then it seems like the correct solution.
I think that PR #62 now implements the solution suggested by @jacklovell and @jirakova.
I still think that the separation of the two @jacklovell described deserves 2 separate methods. There can be a method, which will get paths to the files as parameters (e.g. load_solps_raw_files
) which should be loaded and could be called by other methods for loading files from a single directory (e.g. load_solps_from_raw_output
) and from the run directory (e.g. load_solps_from_run_directory
). The bonus is that any other directory structure users have can be loaded with the load_solps_raw_files
after adding their own simple script. Also this would move any searching of dirs and other logic outside, separate it from the parsing and interpretation.
I still think that the separation of the two @jacklovell described deserves 2 separate methods.
I think we can have very similar behaviour with a single method avoiding any assumptions about the directory structure:
def load_solps_from_raw_output(simulation_path='', debug=False, mesh_file_path=None,
b2_state_file_path=None, b2_plasma_file_path=None,
eirene_fort44_file_path=None):
mesh_file_path = mesh_file_path or os.path.join(simulation_path, 'b2fgmtry')
b2_state_file_path = b2_state_file_path or os.path.join(simulation_path, 'b2fstate')
b2_plasma_file_path = b2_plasma_file_path or os.path.join(simulation_path, 'b2fplasmf')
eirene_fort44_file_path = eirene_fort44_file_path or os.path.join(simulation_path, 'fort.44')
if not os.path.isfile(mesh_file_path):
raise RuntimeError("No B2 mesh description file ({}) found.".format(mesh_file_path))
_, _, geom_data_dict = load_b2f_file(mesh_file_path, debug=debug)
if not os.path.isfile(b2_state_file_path):
raise RuntimeError("No B2 plasma state file ({}) found.".format(b2_state_file_path))
header_dict, sim_info_dict, mesh_data_dict = load_b2f_file(b2_state_file_path, debug=debug)
if not os.path.isfile(b2_plasma_file_path):
print("Warning! No B2 plasma solution formatted file ({}) found.".format(b2_plasma_file_path),
"No total_radiation data will be available.")
have_b2plasmf = False
else:
_, _, plasma_solution_dict = load_b2f_file(b2_plasma_file_path, debug=debug, header_dict=header_dict)
have_b2plasmf = True
if not os.path.isfile(eirene_fort44_file_path):
print("Warning! No EIRENE output file ({}) found.".format(eirene_fort44_file_path),
"Assuming B2 stand-alone simulation.")
b2_standalone = True
else:
# Load data for neutral species from EIRENE output file
eirene = load_fort44_file(eirene_fort44_file_path, debug=debug)
b2_standalone = False
If a specific file is not in simulation_path
, the user can specify the path to it.
In the case that @vsnever's solution is adopted, I'd drop a note in a visible place of the documentation (examples, docstring, file-not-found message) that the user may redefine the individual file paths. It will be a bit of a drag to write the paths out every time I want to load a simulation, especially since I may not know from the get-go where the files are stored, but divining some general rules for file placement which can be implemented directly into Cherab would be even less reliable. At least the Cherab user who runs SOLPS will learn which files are important to read the simulation state.
Right, thanks for explanation.
Here is a variant for the docstring for load_solps_from_raw_output()
:
Load a SOLPS simulation from raw SOLPS output files.
Relevant files are:
* mesh description file (b2fgmtry)
* B2 plasma state (b2fstate)
* B2 plasma solution, formatted (b2fplasmf), optional
* Eirene output file (fort.44), optional
:param str simulation_path: String path to simulation directory.
The SOLPS output files will be searched for in this directory
by their default names, unless the paths to specific files are
explicitly provided by the user.
Example: '/home/user/solps5/runs/simulation_name/run'.
Defaults to the current working directory.
:param bool debug: A flag for displaying textual debugging information when parsing
the SOLPS files. Defaults to False.
:param str mesh_file_path: String path to mesh description file (b2fgmtry).
Defaults to '{simulation_path}/b2fgmtry' if None.
:param str b2_state_file_path: String path to B2 plasma state file (b2fstate).
Defaults to '{simulation_path}/b2fstate' if None.
:param str b2_plasma_file_path: String path to formatted B2 plasma solution file (b2fplasmf).
Defaults to '{simulation_path}/b2fplasmf' if None.
:param str eirene_fort44_file_path: String path to Eirene output file (fort.44).
Defaults to '{simulation_path}/fort.44' if None.
:rtype: SOLPSSimulation
@vsnever This looks fantastic.
I pushed this change to #62, so let's wait for @jacklovell's decision.
When using
load_solps_from_raw_output
, theb2fgmtry
file is expected to be in the run directory (which is passed as argument toload_solps_from_raw_output
). However, usually one sets up the geometry usingb2run b2ag
in the baserun directory (usually../baserun
relative to the run directory), sob2fgmtry
is stored there and SOLPS refers to it from every run directory. It would, therefore, be helpful if Cherab searched forb2fgmtry
in baserun if the file isn't found in the run directory.