Skip to content

Commit b8bc286

Browse files
authored
Replace os with pathlib (#30)
1 parent a898644 commit b8bc286

5 files changed

Lines changed: 63 additions & 54 deletions

File tree

src/flekspy/__init__.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,39 @@
22
flekspy Public API.
33
"""
44

5-
import glob
6-
import os
5+
from pathlib import Path
76
import errno
87
from flekspy.idl import IDLData
98
from flekspy.yt import FLEKSData, extract_phase
109
from flekspy.tp import FLEKSTP
1110

1211

13-
def load(filename: str, iDomain=0, iSpecies=0, readFieldData=False):
12+
def load(filename: str, iDomain=0, iSpecies=0, readFieldData: bool = False):
1413
"""Load FLEKS data.
1514
1615
Args:
17-
filename (str): Input file name.
16+
filename (str): Input file name pattern.
1817
iDomain (int, optional): Test particle domain index. Defaults to 0.
1918
iSpecies (int, optional): Test particle species index. Defaults to 0.
2019
readFieldData (bool, optional): Whether or not to read field data for test particles. Defaults to False.
2120
2221
Returns:
2322
FLEKS data: IDLData, FLEKSData, or FLEKSTP
2423
"""
25-
files = glob.glob(filename)
24+
files = list(Path().glob(filename))
2625
if len(files) == 0:
27-
raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), files)
28-
filename = files[0]
26+
message = f"No files found matching pattern: '{filename}'"
27+
raise FileNotFoundError(errno.ENOENT, message, filename)
28+
filename = str(files[0].resolve())
2929

30-
basename = os.path.basename(os.path.normpath(filename))
30+
filepath = Path(filename)
31+
basename = filepath.name
3132

3233
if basename == "test_particles":
3334
return FLEKSTP(filename, iDomain=iDomain, iSpecies=iSpecies)
34-
elif basename.find(".") != -1 and basename.split(".")[-1] in ["out", "outs"]:
35+
elif filepath.suffix in [".out", ".outs"]:
3536
return IDLData(filename)
36-
elif basename[-6:] == "_amrex":
37+
elif basename.endswith("_amrex"):
3738
return FLEKSData(filename, readFieldData)
3839
else:
3940
raise Exception("Error: unknown file format!")

src/flekspy/tp/test_particles.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import List, Tuple, Dict, Union, Callable
22

33
import matplotlib.pyplot as plt
4-
import os
4+
from pathlib import Path
55
import numpy as np
66
import glob
77
import struct
@@ -51,8 +51,8 @@ def __init__(
5151
if type(dirs) == str:
5252
dirs = [dirs]
5353

54-
header = dirs[0] + "/Header"
55-
if os.path.exists(header):
54+
header = Path(dirs[0] + "/Header")
55+
if header.exists():
5656
with open(header, "r") as f:
5757
self.nReal = int(f.readline())
5858
else:
@@ -88,8 +88,8 @@ def __init__(
8888
self.pfiles = self.pfiles[iListStart:iListEnd]
8989

9090
self.plists: List[Dict[Tuple[int, int], int]] = []
91-
for fileName in self.plistfiles:
92-
self.plists.append(self.read_particle_list(fileName))
91+
for filename in self.plistfiles:
92+
self.plists.append(self.read_particle_list(filename))
9393

9494
self.IDs = set()
9595
for plist in self.plists:
@@ -122,28 +122,28 @@ def get_index_to_time(self) -> List:
122122
print("Index to time mapping was not initialized")
123123
return self.indextotime
124124

125-
def read_particle_list(self, fileName: str) -> Dict[Tuple[int, int], int]:
125+
def read_particle_list(self, filename: str) -> Dict[Tuple[int, int], int]:
126126
"""
127127
Read and return a list of the particle IDs.
128128
"""
129129
# 2 integers + 1 unsigned long long
130130
listUnitSize = 2 * 4 + 8
131-
nByte = os.path.getsize(fileName)
131+
nByte = Path(filename).stat().st_size
132132
nPart = int(nByte / listUnitSize)
133133
plist = {}
134-
with open(fileName, "rb") as f:
134+
with open(filename, "rb") as f:
135135
for _ in range(nPart):
136136
binaryData = f.read(listUnitSize)
137137
(cpu, id, loc) = struct.unpack("iiQ", binaryData)
138138
plist.update({(cpu, id): loc})
139139
return plist
140140

141-
def _read_the_first_record(self, fileName: str) -> Union[List[float], None]:
141+
def _read_the_first_record(self, filename: str) -> Union[List[float], None]:
142142
"""
143143
Get the first record stored in one file.
144144
"""
145145
dataList = list()
146-
with open(fileName, "rb") as f:
146+
with open(filename, "rb") as f:
147147
while True:
148148
binaryData = f.read(4 * 4)
149149

@@ -184,11 +184,11 @@ def read_particles_at_time(
184184
break
185185
iFile += 1
186186

187-
fileName = self.pfiles[iFile]
187+
filename = self.pfiles[iFile]
188188

189189
dataList: list[float] = []
190190
idList: list[tuple] = []
191-
with open(fileName, "rb") as f:
191+
with open(filename, "rb") as f:
192192
while True:
193193
binaryData = f.read(4 * 4)
194194
if not binaryData:
@@ -217,14 +217,14 @@ def read_particles_at_time(
217217
raise Exception(f"There are no particles at time {time}.")
218218

219219
if doSave:
220-
fileName = f"particles_t{time}.csv"
220+
filename = f"particles_t{time}.csv"
221221
header = "cpu,iid,time,x,y,z,ux,uy,uz"
222222
if self.nReal == 10:
223223
header += ",bx,by,bz"
224224
elif self.nReal == 13:
225225
header += ",bx,by,bz,ex,ey,ez"
226226

227-
with open(fileName, "w") as f:
227+
with open(filename, "w") as f:
228228
f.write(header + "\n")
229229
for id_row, data_row in zip(idData, npData):
230230
f.write(
@@ -236,7 +236,7 @@ def read_particles_at_time(
236236
def save_trajectory_to_csv(
237237
self,
238238
pID: Tuple[int, int],
239-
fileName: str = None,
239+
filename: str = None,
240240
shiftTime: bool = False,
241241
scaleTime: bool = False,
242242
) -> None:
@@ -252,8 +252,8 @@ def save_trajectory_to_csv(
252252
>>> tp.save_trajectory_to_csv((3,15))
253253
"""
254254
pData = self.read_particle_trajectory(pID)
255-
if fileName == None:
256-
fileName = "trajectory_" + str(pID[0]) + "_" + str(pID[1]) + ".csv"
255+
if filename == None:
256+
filename = "trajectory_" + str(pID[0]) + "_" + str(pID[1]) + ".csv"
257257
header = "time [s], X [R], Y [R], Z [R], U_x [km/s], U_y [km/s], U_z [km/s]"
258258
if self.nReal == 10:
259259
header += ", B_x [nT], B_y [nT], B_z [nT]"
@@ -265,7 +265,7 @@ def save_trajectory_to_csv(
265265
pData[:, 0] -= pData[0, 0]
266266
if scaleTime:
267267
pData[:, 0] /= pData[-1, 0]
268-
np.savetxt(fileName, pData, delimiter=",", header=header, comments="")
268+
np.savetxt(filename, pData, delimiter=",", header=header, comments="")
269269

270270
def read_particle_trajectory(self, pID: Tuple[int, int]):
271271
"""
@@ -278,10 +278,10 @@ def read_particle_trajectory(self, pID: Tuple[int, int]):
278278
>>> trajectory = tp.read_particle_trajectory((66,888))
279279
"""
280280
dataList = list()
281-
for fileName, plist in zip(self.pfiles, self.plists):
281+
for filename, plist in zip(self.pfiles, self.plists):
282282
if pID in plist:
283283
ploc = plist[pID]
284-
with open(fileName, "rb") as f:
284+
with open(filename, "rb") as f:
285285
f.seek(ploc)
286286
binaryData = f.read(4 * 4)
287287
(cpu, idtmp, nRecord, weight) = struct.unpack("iiif", binaryData)
@@ -298,10 +298,10 @@ def read_initial_location(self, pID):
298298
Return the initial location of a test particle.
299299
"""
300300

301-
for fileName, plist in zip(self.pfiles, self.plists):
301+
for filename, plist in zip(self.pfiles, self.plists):
302302
if pID in plist:
303303
ploc = plist[pID]
304-
with open(fileName, "rb") as f:
304+
with open(filename, "rb") as f:
305305
f.seek(ploc)
306306
binaryData = f.read(4 * 4)
307307
(cpu, idtmp, nRecord, weight) = struct.unpack("iiif", binaryData)

src/flekspy/util/utilities.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -135,26 +135,29 @@ def download_testfile(url: str, target_path="."):
135135
url (str): the URL of the tar.gz file.
136136
target_path (str): the directory to extract the files to. Defaults to the current directory.
137137
"""
138-
import os, requests
138+
import requests
139+
from pathlib import Path
140+
141+
target_dir = Path(target_path)
142+
temp_file = Path("temp.tar.gz")
139143

140144
try:
141145
response = requests.get(url, stream=True)
142-
response.raise_for_status() # Raise an exception for bad status codes
146+
response.raise_for_status() # Raise an exception for bad status codes
143147

144-
with open("temp.tar.gz", "wb") as f:
148+
with open(temp_file, "wb") as f:
145149
for chunk in response.iter_content(chunk_size=8192):
146150
f.write(chunk)
147151

148-
if not os.path.exists(target_path):
149-
os.makedirs(target_path)
152+
target_dir.mkdir(parents=True, exist_ok=True)
150153

151-
with tarfile.open("temp.tar.gz", "r:gz") as tar:
152-
tar.extractall(target_path)
154+
with tarfile.open(temp_file, "r:gz") as tar:
155+
tar.extractall(target_dir)
153156

154157
except requests.exceptions.RequestException as e:
155158
print(f"Error downloading file: {e}")
156159
except tarfile.TarError as e:
157160
print(f"Error extracting tar file: {e}")
158161
finally:
159-
if os.path.exists("temp.tar.gz"):
160-
os.remove("temp.tar.gz") # Clean up temporary file
162+
if temp_file.exists():
163+
temp_file.unlink(missing_ok=True) # Clean up temporary file

src/flekspy/yt/yt.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import os
2-
import glob
1+
from pathlib import Path
32
import numpy as np
43

54
import yt
@@ -159,7 +158,7 @@ def __init__(
159158
def _parse_parameter_file(self):
160159
super(FLEKSData, self)._parse_parameter_file()
161160

162-
fleks_header = os.path.join(self.output_dir, "FLEKSHeader")
161+
fleks_header = Path(self.output_dir) / "FLEKSHeader"
163162
with open(fleks_header, "r") as f:
164163
plot_string = f.readline().lower()
165164
self.radius = float(f.readline()) # should be in unit [m]
@@ -178,8 +177,10 @@ def _parse_parameter_file(self):
178177
else:
179178
self.parameters["fleks_unit"] = "unknown"
180179

181-
particle_types = glob.glob(self.output_dir + "/*/Header")
182-
particle_types = [cpt.split(os.sep)[-2] for cpt in particle_types]
180+
output_dir_path = Path(self.output_dir)
181+
header_paths_generator = output_dir_path.glob("*/Header")
182+
particle_types = [p.parent.name for p in header_paths_generator]
183+
183184
if len(particle_types) > 0 and not self.read_field_data:
184185
self.parameters["particles"] = 1
185186
self.particle_types = tuple(particle_types)

tests/test_fleks.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626

2727

2828
class TestIDL:
29-
files = (
29+
filenames = (
3030
"1d__raw_2_t25.60000_n00000258.out",
3131
"z=0_fluid_region0_0_t00001640_n00010142.out",
3232
"3d_raw.out",
3333
)
34-
files = [os.path.join("tests/data/", file) for file in files]
34+
files = [os.path.join("tests/data/", file) for file in filenames]
3535

3636
def test_load(self):
3737
ds = fs.load(self.files[0])
@@ -91,9 +91,14 @@ def test_phase(self):
9191

9292
## Select and plot the particles inside a box defined by xleft and xright
9393
region = ds.box(xleft, xright)
94-
x, y, w = ds.get_phase(x_field, y_field, z_field, region=region,
95-
domain_size=(xleft[0], xright[0], xleft[1], xright[1]))
96-
assert x.shape == (128,) and w.max() == 2.8024863240162035e+23
94+
x, y, w = ds.get_phase(
95+
x_field,
96+
y_field,
97+
z_field,
98+
region=region,
99+
domain_size=(xleft[0], xright[0], xleft[1], xright[1]),
100+
)
101+
assert x.shape == (128,) and w.max() == 2.8024863240162035e23
97102
pp = ds.plot_phase(
98103
x_field,
99104
y_field,
@@ -183,12 +188,11 @@ def load(files):
183188

184189

185190
def test_load(benchmark):
186-
path = "tests/data/"
187-
files = (
191+
filenames = (
188192
"1d__raw_2_t25.60000_n00000258.out",
189193
"z=0_fluid_region0_0_t00001640_n00010142.out",
190194
)
191-
files = [os.path.join(path, file) for file in files]
195+
files = [os.path.join("tests/data/", file) for file in filenames]
192196

193197
result = benchmark(load, files)
194198

0 commit comments

Comments
 (0)