py-pluto 1.1.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. pyPLUTO/__init__.py +22 -0
  2. pyPLUTO/amr.py +745 -0
  3. pyPLUTO/baseloadmixin.py +258 -0
  4. pyPLUTO/baseloadstate.py +45 -0
  5. pyPLUTO/codes/echo_load.py +161 -0
  6. pyPLUTO/configure.py +261 -0
  7. pyPLUTO/gui/config.py +174 -0
  8. pyPLUTO/gui/custom_var.py +435 -0
  9. pyPLUTO/gui/globals.py +108 -0
  10. pyPLUTO/gui/main.py +17 -0
  11. pyPLUTO/gui/main_window.py +177 -0
  12. pyPLUTO/gui/panels.py +66 -0
  13. pyPLUTO/gui/utils.py +273 -0
  14. pyPLUTO/h_pypluto.py +84 -0
  15. pyPLUTO/image.py +302 -0
  16. pyPLUTO/imagefuncs/colorbar.py +240 -0
  17. pyPLUTO/imagefuncs/contour.py +254 -0
  18. pyPLUTO/imagefuncs/create_axes.py +464 -0
  19. pyPLUTO/imagefuncs/display.py +306 -0
  20. pyPLUTO/imagefuncs/figure.py +395 -0
  21. pyPLUTO/imagefuncs/imagetools.py +487 -0
  22. pyPLUTO/imagefuncs/interactive.py +403 -0
  23. pyPLUTO/imagefuncs/legend.py +250 -0
  24. pyPLUTO/imagefuncs/plot.py +311 -0
  25. pyPLUTO/imagefuncs/range.py +242 -0
  26. pyPLUTO/imagefuncs/scatter.py +270 -0
  27. pyPLUTO/imagefuncs/set_axis.py +497 -0
  28. pyPLUTO/imagefuncs/streamplot.py +297 -0
  29. pyPLUTO/imagefuncs/zoom.py +428 -0
  30. pyPLUTO/imagemixin.py +259 -0
  31. pyPLUTO/imagestate.py +45 -0
  32. pyPLUTO/load.py +447 -0
  33. pyPLUTO/loadfuncs/baseloadtools.py +71 -0
  34. pyPLUTO/loadfuncs/codeselection.py +48 -0
  35. pyPLUTO/loadfuncs/defpluto.py +123 -0
  36. pyPLUTO/loadfuncs/descriptor.py +102 -0
  37. pyPLUTO/loadfuncs/findfiles.py +182 -0
  38. pyPLUTO/loadfuncs/findformat.py +245 -0
  39. pyPLUTO/loadfuncs/initload.py +203 -0
  40. pyPLUTO/loadfuncs/loadvars.py +227 -0
  41. pyPLUTO/loadfuncs/offsetdata.py +87 -0
  42. pyPLUTO/loadfuncs/offsetfluid.py +408 -0
  43. pyPLUTO/loadfuncs/read_files.py +213 -0
  44. pyPLUTO/loadfuncs/readdata.py +619 -0
  45. pyPLUTO/loadfuncs/readdata_old.py +567 -0
  46. pyPLUTO/loadfuncs/readdefplini.py +101 -0
  47. pyPLUTO/loadfuncs/readfluid.py +479 -0
  48. pyPLUTO/loadfuncs/readformat.py +277 -0
  49. pyPLUTO/loadfuncs/readgridalone.py +224 -0
  50. pyPLUTO/loadfuncs/readgridfile.py +255 -0
  51. pyPLUTO/loadfuncs/readgridout.py +451 -0
  52. pyPLUTO/loadfuncs/readpart.py +419 -0
  53. pyPLUTO/loadfuncs/readtab.py +105 -0
  54. pyPLUTO/loadfuncs/write_files.py +283 -0
  55. pyPLUTO/loadmixin.py +419 -0
  56. pyPLUTO/loadpart.py +233 -0
  57. pyPLUTO/loadstate.py +68 -0
  58. pyPLUTO/newload.py +81 -0
  59. pyPLUTO/pytools.py +145 -0
  60. pyPLUTO/toolfuncs/findlines.py +551 -0
  61. pyPLUTO/toolfuncs/fourier.py +149 -0
  62. pyPLUTO/toolfuncs/nabla.py +676 -0
  63. pyPLUTO/toolfuncs/parttools.py +152 -0
  64. pyPLUTO/toolfuncs/transform.py +638 -0
  65. pyPLUTO/utils/annotator.py +27 -0
  66. pyPLUTO/utils/inspector.py +145 -0
  67. pyPLUTO/utils/make_docstrings.py +3 -0
  68. py_pluto-1.1.4.dist-info/METADATA +218 -0
  69. py_pluto-1.1.4.dist-info/RECORD +73 -0
  70. py_pluto-1.1.4.dist-info/WHEEL +5 -0
  71. py_pluto-1.1.4.dist-info/entry_points.txt +2 -0
  72. py_pluto-1.1.4.dist-info/licenses/LICENSE +27 -0
  73. py_pluto-1.1.4.dist-info/top_level.txt +1 -0
@@ -0,0 +1,123 @@
1
+ import re
2
+
3
+
4
+ def _convert_value(value):
5
+ """Convert a string value to its appropriate type. This function
6
+ attempts to convert a string value into a boolean, integer, float,
7
+ or leave it as a string if it cannot be converted.
8
+
9
+ Returns
10
+ -------
11
+ bool | int | float | str
12
+ The converted value, which can be a boolean, integer, float, or the
13
+ original string if conversion is not possible.
14
+
15
+ Parameters
16
+ ----------
17
+ value : str
18
+ The string value to convert.
19
+
20
+ """
21
+ # Convert the value to uppercase to handle case-insensitive comparisons
22
+ value_upper = value.upper()
23
+
24
+ # Check for boolean values first
25
+ if value_upper in {"YES", "TRUE"}:
26
+ return True
27
+ if value_upper in {"NO", "FALSE"}:
28
+ return False
29
+
30
+ # Try to convert to an integer or float, if possible
31
+ try:
32
+ return float(value) if "." in value or "e" in value else int(value)
33
+ except ValueError:
34
+ return value
35
+
36
+
37
+ def _read_defh(self, filepath):
38
+ """Read a header file and extract definitions.
39
+
40
+ This function reads a header file, extracts lines that start with
41
+ '#define', and converts the values to their appropriate types (boolean,
42
+ integer, float, or string).
43
+
44
+ Returns
45
+ -------
46
+ dict
47
+ A dictionary where keys are the defined names and values are the
48
+ converted values.
49
+
50
+ Parameters
51
+ ----------
52
+ filepath : str
53
+ The path to the header file to read.
54
+
55
+ """
56
+ # Read the file, check if a line starts with '#define',
57
+ # and split the line into key and value.
58
+ # Convert the value using _convert_value function.
59
+ with open(filepath) as file:
60
+ # Return a dictionary comprehension that processes each line
61
+ return {
62
+ key: _convert_value(value)
63
+ for line in file
64
+ if line.strip().startswith("#define")
65
+ for _, key, value in [re.split(r"\s+", line.strip(), maxsplit=2)]
66
+ }
67
+
68
+
69
+ def _read_plini(self, path):
70
+ """Read the pluto.ini file and extract relevant sections.
71
+
72
+ This function reads the pluto.ini file, extracts sections that are of
73
+ interest (Solver, Parameters, Boundary, Time), and converts the values to
74
+ their appropriate types (boolean, integer, float, or string).
75
+
76
+ Returns
77
+ -------
78
+ dict
79
+ A dictionary where keys are the parameter names and values are the
80
+ converted values.
81
+
82
+ Parameters
83
+ ----------
84
+ path : str
85
+ The path to the pluto.ini file to read.
86
+
87
+ """
88
+ # Define the sections we are interested in
89
+ wanted_sections = {"Solver", "Parameters", "Boundary", "Time"}
90
+ plini = {}
91
+
92
+ # Regular expressions to match sections and entries in the pluto.ini file
93
+ section_re = re.compile(r"\[(.+)]")
94
+ entry_re = re.compile(r"^(\w[\w\-\d]*)\s+(.*)$")
95
+
96
+ current_sec = None
97
+
98
+ # Open the file and read it line by line
99
+ with open(path) as f:
100
+ for line in f:
101
+ line = line.strip()
102
+
103
+ if not line or line.startswith("#"):
104
+ continue
105
+
106
+ # Check if the line is a section header or an entry
107
+ if section_match := section_re.match(line):
108
+ section = section_match.group(1)
109
+ current_sec = section if section in wanted_sections else None
110
+ continue
111
+
112
+ # If we are not in a wanted section, skip the line
113
+ if not current_sec:
114
+ continue
115
+
116
+ # If we are in a wanted section, check for entries
117
+ # and convert the values using _convert_value function
118
+ if entry_match := entry_re.match(line):
119
+ key, value = entry_match.groups()
120
+ plini[key] = _convert_value(value.strip())
121
+
122
+ # Return the dictionary containing the extracted parameters
123
+ return plini
@@ -0,0 +1,102 @@
1
+ """Descriptor management utilities for reading PLUTO descriptor files."""
2
+
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ import numpy as np
7
+
8
+ from pyPLUTO.loadfuncs.baseloadtools import BaseLoadTools
9
+ from pyPLUTO.loadmixin import LoadMixin
10
+ from pyPLUTO.loadstate import LoadState
11
+
12
+
13
+ class DescriptorManager(LoadMixin):
14
+ """Class that manages the descriptor files for loading data."""
15
+
16
+ def __init__(
17
+ self,
18
+ state: LoadState,
19
+ nout: int | str | list[int | str],
20
+ **kwargs: Any,
21
+ ) -> None:
22
+ """Initialize the DescriptorManager class."""
23
+ self.state = state
24
+ self.LoadToolManager = BaseLoadTools(self.state)
25
+ self.load_descriptor(nout, **kwargs)
26
+
27
+ def load_descriptor(
28
+ self, nout: int | str | list[int | str], **kwargs: Any
29
+ ) -> None:
30
+ """Read the datatype.out file and stores the information.
31
+
32
+ Such information are the time array, the output variables, the file type
33
+ (single or multiples), the endianess, the simulation path and the bin
34
+ format. All these information are relevant in order to open the output
35
+ files and access the data.
36
+
37
+ Returns
38
+ -------
39
+ - None
40
+
41
+ Parameters
42
+ ----------
43
+ - endian (not optional): str
44
+ The endianess of the files.
45
+ - nout (not optional): int
46
+ The output file to be opened. If default ('last'), the code assumes
47
+ the last file should be opened. Other options available are 'last'
48
+ (all the files should be opened) and -1 (same as 'last').
49
+
50
+ ----
51
+
52
+ Examples
53
+ --------
54
+ - Example #1: Read the 'filetype'.out file
55
+
56
+ >>> _read_outfile(0, "big")
57
+
58
+ """
59
+ if self.format is None:
60
+ raise ValueError("Format not defined. Cannot read descriptor file.")
61
+
62
+ # Read and parse the 'filetype'.out file — pure Python split, no Pandas
63
+ pathdata = self.pathdir / Path(self.format + ".out")
64
+ rows = [
65
+ line.split()
66
+ for line in pathdata.read_text().splitlines()
67
+ if line.strip()
68
+ ]
69
+
70
+ # Store the output and the time full list
71
+ self.outlist = np.array([r[0] for r in rows], dtype=np.int32)
72
+ self.timelist = np.array([r[1] for r in rows], dtype=np.float64)
73
+ self.lennoutlist = len(self.outlist)
74
+
75
+ # Check the output lines
76
+ self.LoadToolManager.check_nout(nout)
77
+ self.ntimelist = self.timelist[self.noutlist]
78
+ self.lennout = len(self.noutlist)
79
+
80
+ # Initialize the info dictionary
81
+ self.d_info = {
82
+ "typefile": np.array([rows[k][4] for k in self.outlist]),
83
+ "endianess": np.array(
84
+ [">" if rows[k][5] == "big" else "<" for k in self.outlist]
85
+ ),
86
+ }
87
+
88
+ # Compute the endianess (vtk always big endian).
89
+ # If endian is given, it is used instead of the one in the file.
90
+ self.d_info["endianess"][:] = (
91
+ ">" if self.format == "vtk" else self.d_info["endianess"]
92
+ )
93
+ self.d_info["endianess"][:] = (
94
+ self.endian if self.endian is not None else self.d_info["endianess"]
95
+ )
96
+ self.d_info["varslist"] = [rows[k][6:] for k in self.outlist]
97
+
98
+ self.d_info["binformat"] = np.char.add(
99
+ self.d_info["endianess"], "f" + str(self.charsize)
100
+ )
101
+ format_string = f".%04d.{self.format}"
102
+ self.d_info["endpath"] = np.char.mod(format_string, self.outlist)
@@ -0,0 +1,182 @@
1
+ """Docstring for findfiles.py."""
2
+
3
+ from pathlib import Path
4
+ from typing import Any
5
+
6
+ import numpy as np
7
+
8
+ from pyPLUTO.baseloadmixin import BaseLoadMixin
9
+ from pyPLUTO.baseloadstate import BaseLoadState
10
+ from pyPLUTO.loadfuncs.baseloadtools import BaseLoadTools
11
+
12
+
13
+ class FindFilesManager(BaseLoadMixin[BaseLoadState]):
14
+ """Class that manages file finding operations."""
15
+
16
+ def __init__(
17
+ self,
18
+ state: BaseLoadState,
19
+ nout: int | str | list[int | str],
20
+ **kwargs: Any,
21
+ ) -> None:
22
+ """Initialize the FindFilesManager class."""
23
+ self.state = state
24
+ self.LoadToolManager = BaseLoadTools(self.state)
25
+ self.find_files(nout, **kwargs)
26
+
27
+ def find_files(
28
+ self, nout: int | str | list[int | str], **kwargs: Any
29
+ ) -> None:
30
+ """Find the files to be loaded.
31
+
32
+ If nout is a list, the function loops over the list and finds the
33
+ corresponding files. If nout is an integer, the function finds the
34
+ corresponding file. If nout is 'last', the function finds the last file.
35
+ If nout is 'all', the function finds all the files. Then, the function
36
+ stores the relevant information in a dictionary d_info.
37
+
38
+ Returns
39
+ -------
40
+ - None
41
+
42
+ Parameters
43
+ ----------
44
+ - nout (not optional): int | str | list[int|str]
45
+ The output file to be loaded
46
+
47
+ ----
48
+
49
+ Examples
50
+ --------
51
+ - Example #1: Load the last file
52
+
53
+ >>> _findfiles("last")
54
+
55
+ - Example #2: Load the first file
56
+
57
+ >>> _findfiles(0)
58
+
59
+ - Example #3: Load all the files
60
+
61
+ >>> _findfiles("all")
62
+
63
+ - Example #4: Load multiple specific files
64
+
65
+ >>> _findfiles([0, 1, 2, 3])
66
+
67
+ """
68
+ # Initialization or declaration of variables
69
+ set_vars: set[str] = set()
70
+ set_outs: set[str] = set()
71
+ self.d_info = {}
72
+
73
+ if self.matching_files is None:
74
+ raise ValueError("No files are found! Cannot proceed.")
75
+ # Find the files to be loaded
76
+ for elem in self.matching_files:
77
+ self.varsout(elem, set_vars, set_outs)
78
+
79
+ # Check if the files are present
80
+ if len(set_vars) == 0 or len(set_outs) == 0:
81
+ raise FileNotFoundError(f"No files found in {self.pathdir}!")
82
+
83
+ self.outlist = np.array(sorted(set_outs))
84
+ self.lennoutlist = len(self.outlist)
85
+ self.LoadToolManager.check_nout(nout)
86
+ self.lennout = len(self.noutlist)
87
+ self.ntimelist = np.full(self.lennout, np.nan)
88
+ self.timelist = np.full(len(self.outlist), np.nan)
89
+
90
+ # Find the max size of the output numbers to allow for loading if some
91
+ # files are missing
92
+ d_info_size = int(np.max(self.outlist)) + 1
93
+
94
+ # Initialize the info dictionary and initialize some relevant variables
95
+ self.d_info["typefile"] = np.empty(d_info_size, dtype="U20")
96
+ self.d_info["endianess"] = np.empty(d_info_size, dtype="U20")
97
+ self.d_info["binformat"] = np.empty(d_info_size, dtype="U20")
98
+ if self.class_name == "LoadPart":
99
+ raise NotImplementedError(
100
+ "FindFilesManager for LoadPart is not implemented yet."
101
+ )
102
+ elif self.class_name == "Load":
103
+ # Check if the fluid files are present as multiple files
104
+ if "data" not in set_vars or self.multiple is True:
105
+ # If the files are multiple, the typefile is set accordingly
106
+ self.d_info["typefile"][:] = "multiple_files"
107
+ self.d_info["varslist"] = [[] for _ in range(d_info_size)]
108
+ for elem in self.matching_files:
109
+ raw_str = Path(elem).name.split(".")
110
+ self.d_info["varslist"][int(raw_str[1])].append(raw_str[0])
111
+ else:
112
+ # If the files are single, the typefile is set to 'single_file'
113
+ self.d_info["typefile"][:] = "single_file"
114
+ self.d_info["varslist"] = [[] for _ in range(d_info_size)]
115
+ else:
116
+ raise ValueError(f"Unknown class name: {self.class_name}")
117
+
118
+ # Sparse map indexed by output number
119
+ endpath = np.empty(d_info_size, dtype=f"<U{len(self.format) + 6}")
120
+ endpath[:] = ""
121
+ for out in self.outlist:
122
+ endpath[int(out)] = f".{int(out):04d}.{self.format}"
123
+ self.d_info["endpath"] = endpath
124
+
125
+ def varsout(
126
+ self,
127
+ elem: str,
128
+ set_vars: set,
129
+ set_outs: set,
130
+ ) -> None:
131
+ """Find the variables and the outputs for the fluid and particles files.
132
+
133
+ Returns
134
+ -------
135
+ - None
136
+
137
+ Parameters
138
+ ----------
139
+ - class_name (not optional): str
140
+ The name of the class. Supported classes are 'Load' or 'LoadPart'.
141
+ - elem (not optional): str
142
+ The matching file.
143
+
144
+ ----
145
+
146
+ Examples
147
+ --------
148
+ - Example #1: Find the outputs (particles, non LP)
149
+
150
+ >>> _varsouts_p("particles.0000.dbl")
151
+
152
+ - Example #2: Find the outputs (fluid)
153
+
154
+ >>> _varsouts_f("rho.0000.dbl")
155
+
156
+ - Example #3: Find the outputs (LP)
157
+
158
+ >>> _varsouts_lp("particles.0000_ch_00.dbl")
159
+
160
+ """
161
+ # Splits the matching filename (variable/data and output number)
162
+ raw_str = Path(elem).name.split(".")
163
+ var = raw_str[0]
164
+ out = raw_str[1]
165
+
166
+ # Set the conditions if the file is fluid or particles
167
+ isfluid = var != "particles" and self.class_name == "Load"
168
+ ispart = var == "particles" and self.class_name == "LoadPart"
169
+
170
+ if isfluid or (ispart and "_" not in out):
171
+ # Control variable set to True
172
+ outc = True
173
+ elif ispart and "_" in out:
174
+ pass
175
+ else:
176
+ # Control variable set to False
177
+ outc = False
178
+
179
+ # Add the variables and the outputs
180
+ if outc is True:
181
+ set_vars.add(var)
182
+ set_outs.add(int(out))
@@ -0,0 +1,245 @@
1
+ """Module to find the format of the PLUTO output files."""
2
+
3
+ import glob
4
+ from collections.abc import Callable
5
+ from pathlib import Path
6
+ from typing import Any
7
+
8
+ from pyPLUTO.baseloadmixin import BaseLoadMixin
9
+ from pyPLUTO.baseloadstate import BaseLoadState
10
+ from pyPLUTO.utils.inspector import track_kwargs
11
+
12
+
13
+ class FindFormat(BaseLoadMixin[BaseLoadState]):
14
+ """Class to find the format of the PLUTO output files."""
15
+
16
+ @track_kwargs
17
+ def __init__(self, state: BaseLoadState, **kwargs: Any) -> None:
18
+ """Initialize the FindFormat class."""
19
+ self.state = state
20
+
21
+ datatype = kwargs.get("datatype")
22
+ alone = kwargs.get("alone")
23
+ self.check_format(datatype, alone)
24
+
25
+ def check_format(
26
+ self,
27
+ datatype: str | None,
28
+ alone: bool | None,
29
+ ) -> None:
30
+ """Find the format of the data files to load.
31
+
32
+ This checks whether outputs are fluid or particles and searches for
33
+ available filetypes in the target directory. Depending on the requested
34
+ datatype and whether files are standalone, it probes formats in order
35
+ and sets self.format, self._alone and self._charsize accordingly.
36
+ Supported types are dbl, flt, vtk, dbl.h5 and flt.h5; hdf5 and tab are
37
+ not implemented.
38
+
39
+ Parameters
40
+ ----------
41
+ alone: bool | None
42
+ If the output files are standalone or they require a .out
43
+ file to be loaded. Only suggested for fluid files, .vtk
44
+ format and standalone files, otherwise the code finds
45
+ the alone property by itself.
46
+ datatype: str | None
47
+ The file format. If None the format is recovered between
48
+ (in order) dbl, flt, vtk, dbl.h5 and flt.h5.
49
+ Formats hdf5 (AMR) and tab have not been implemented yet.
50
+
51
+ Returns
52
+ -------
53
+ None
54
+
55
+ Examples
56
+ --------
57
+ - Example #1: Find the format of the fluid files
58
+
59
+ >>> find_format("dbl", False)
60
+
61
+ - Example #2: Find the format of the standalone files
62
+
63
+ >>> find_format("vtk", True)
64
+
65
+ - Example #3: Find the format of the fluid files (no format given)
66
+
67
+ >>> find_format(None, False)
68
+
69
+ - Example #4: Find the format of the particles files
70
+
71
+ >>> find_format("dbl", True) --------
72
+
73
+ """
74
+ # Initialization or declaration of variables
75
+ dbl = {"dbl", "dbl.h5"} # The set of double filetypes
76
+
77
+ # Define the possible filetypes and set the keyword "alone" accordingly
78
+ if self.class_name == "Load":
79
+ # Divide the formats between standalone and not standalone
80
+ type_out = ["dbl", "flt", "vtk", "dbl.h5", "flt.h5", "tab"]
81
+ type_lon = ["vtk", "dbl.h5", "flt.h5", "tab", "hdf5"]
82
+ # If datatype is dbl or flt the files are not standalone
83
+ if datatype in {"dbl", "flt"}:
84
+ alone = False
85
+ elif self.class_name == "LoadPart":
86
+ # Particle files are always standalone
87
+ alone = True
88
+ type_out = []
89
+ type_lon = ["dbl", "flt", "vtk"]
90
+ else:
91
+ # If the class name is not recognized, raise an error
92
+ raise NameError("Invalid class name.")
93
+
94
+ # Check if the given datatype is valid, if not raise an error
95
+ if datatype not in type_out + type_lon + [None]:
96
+ if self.class_name == "Load":
97
+ err = (
98
+ f"Invalid datatype {datatype}.\n"
99
+ f"Possible formats are: dbl, flt, vtk, dbl.h5, flt.h5, tab"
100
+ )
101
+ elif self.class_name == "LoadPart":
102
+ err = (
103
+ f"Invalid datatype {datatype}.\n"
104
+ f"Possible formats are: dbl, flt, vtk"
105
+ )
106
+ else:
107
+ err = f"Invalid class name: {self.class_name}"
108
+ raise ValueError(err)
109
+
110
+ # Create the list of types to iterate over. If the datatype is None
111
+ # then the list is the full list of types, otherwise the list is the
112
+ # datatype itself.
113
+ typeout0, typelon0 = (
114
+ ([], []) if datatype is not None else (type_out, type_lon)
115
+ )
116
+ type_out = [datatype] if datatype in type_out else typeout0
117
+ type_lon = [datatype] if datatype in type_lon else typelon0
118
+
119
+ if alone is True:
120
+ type_out = []
121
+
122
+ # Create the list of functions to be called (.out or alone)
123
+ funcf: list[Callable[[list[str]], None]] = []
124
+ funcf += (
125
+ [self.check_typeout]
126
+ if len(type_out) > 0 and alone is not True
127
+ else []
128
+ )
129
+ funcf += (
130
+ [self.check_typelon]
131
+ if len(type_lon) > 0 and alone is not False
132
+ else []
133
+ )
134
+
135
+ # Iterate over the functions to be called
136
+ for do_check, arg in (
137
+ (self.check_typeout, type_out),
138
+ (self.check_typelon, type_lon),
139
+ ):
140
+ do_check([x for x in arg if x is not None])
141
+ # Check if the format has been found
142
+ if self.format != "Unknown":
143
+ # Store the charsize depending on the format
144
+ self.charsize = 8 if self.format in dbl else 4
145
+ # If the format is found, end the function
146
+ return None
147
+
148
+ # No file has been found, so raise an error depending on the case.
149
+ # If the datatype is None, raise a general error, otherwise raise
150
+ # an error for the specific datatype.
151
+ scrh = f"No available type has been found in {self.pathdir}."
152
+
153
+ if datatype is not None:
154
+ scrh = f"Type {datatype} not found."
155
+ raise FileNotFoundError(scrh)
156
+
157
+ def check_typeout(self, type_out: list[str]) -> None:
158
+ """Loop over possible formats in order to findthe descriptor files.
159
+
160
+ If the datatype.out file is found, the file format is selected and the
161
+ flag alone is set to False.
162
+
163
+ Returns
164
+ -------
165
+ - None
166
+
167
+ Parameters
168
+ ----------
169
+ - type_out (not optional): list[str]
170
+ The list of possible formats for the output file.
171
+
172
+ ----
173
+
174
+ Examples
175
+ --------
176
+ - Example #1: Check the format of the output files
177
+
178
+ >>> _check_typeout(["dbl", "flt", "vtk", "dbl.h5", "flt.h5", "tab"])
179
+
180
+ - Example #2: Check the format of the output files (no format given)
181
+
182
+ >>> _check_typeout([])
183
+
184
+ """
185
+ # Loop over the possible formats
186
+ for try_type in type_out:
187
+ # Create the path to the grid.out and datatype.out files
188
+ pathgrid = self.pathdir / Path("grid.out")
189
+ pathdata = self.pathdir / Path(try_type + ".out")
190
+
191
+ # Check if the datatype.out file is present
192
+ if pathdata.is_file() and pathgrid.is_file():
193
+ # Store the format and set the flag alone to False
194
+ self.format = try_type
195
+ self.alone = False
196
+ # Format is found, break the loop
197
+ break
198
+
199
+ # End of the function
200
+
201
+ def check_typelon(self, type_lon: list[str]) -> None:
202
+ """Loop over possible formats in order to find the datatype.
203
+
204
+ If the file is found, the file format is selected and the flag alone is
205
+ set to True.
206
+
207
+ Returns
208
+ -------
209
+ - None
210
+
211
+ Parameters
212
+ ----------
213
+ - type_lon (not optional): list[str]
214
+ The list of possible formats for the output file.
215
+
216
+ ----
217
+
218
+ Examples
219
+ --------
220
+ - Example #1: Check the format of the output files
221
+
222
+ >>> _check_typelon(["dbl", "flt", "vtk"])
223
+
224
+ - Example #2: Check the format of the output files (no format given)
225
+
226
+ >>> _check_typelon([])
227
+
228
+ """
229
+ # Loop over the possible formats
230
+ for try_type in type_lon:
231
+ # Create the pattern to be searched
232
+ pattern = self.pathdir / Path("*.*." + try_type)
233
+
234
+ # Find the files matching the pattern
235
+ self.matching_files = glob.glob(str(pattern))
236
+
237
+ # Check if the file is present
238
+ if self.matching_files:
239
+ # Store the format and set the flag alone to True
240
+ self.format = try_type
241
+ self.alone = True
242
+ # Format is found, break the loop
243
+ break
244
+
245
+ # End of the function