Skip to content

Commit 47cd323

Browse files
committed
should remove temporary files after tests
1 parent 75faca5 commit 47cd323

2 files changed

Lines changed: 145 additions & 122 deletions

File tree

tests/pyptv/conftest.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,29 @@
66
@pytest.fixture(scope="session")
77
def test_data_dir():
88
"""Fixture to set up test data directory"""
9-
test_dir = Path(__file__).parent.parent / "working_folder"
9+
test_dir = Path(__file__).parent.parent / "testing_folder"
1010
if not test_dir.exists():
1111
pytest.skip(f"Test data directory {test_dir} not found")
1212
return test_dir
1313

1414

15-
@pytest.fixture(scope="session")
15+
@pytest.fixture(scope="session", autouse=True)
1616
def clean_test_environment(test_data_dir):
1717
"""Clean up test environment before and after tests"""
18-
# Clean up any existing test results
19-
results_dir = test_data_dir / "res"
20-
if results_dir.exists():
21-
shutil.rmtree(results_dir)
18+
# Clean up any existing test results anywhere under the shared fixture tree.
19+
for results_dir in test_data_dir.rglob("res"):
20+
if results_dir.is_dir():
21+
shutil.rmtree(results_dir)
2222

23-
# Create fresh directories
24-
results_dir.mkdir(exist_ok=True)
23+
# Create a fresh top-level results directory for tests that expect one.
24+
(test_data_dir / "res").mkdir(exist_ok=True)
2525

2626
yield
2727

2828
# Cleanup after tests
29-
if results_dir.exists():
30-
shutil.rmtree(results_dir)
29+
for results_dir in test_data_dir.rglob("res"):
30+
if results_dir.is_dir():
31+
shutil.rmtree(results_dir)
3132

3233

3334
def pytest_runtest_setup(item):

tests/pyptv/test_pyptv_batch.py

Lines changed: 134 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
def test_pyptv_batch(test_data_dir):
1717
"""Test batch processing with test cavity data using YAML parameters and validate output."""
18-
test_dir = test_data_dir
18+
test_dir = test_data_dir / "test_cavity"
1919
assert test_dir.exists(), f"Test directory {test_dir} not found"
2020

2121
yaml_file = test_dir / "parameters_Run1.yaml"
@@ -48,7 +48,7 @@ def test_pyptv_batch(test_data_dir):
4848

4949
def test_pyptv_batch_with_repetitions(test_data_dir):
5050
"""Test batch processing with multiple repetitions"""
51-
test_dir = test_data_dir
51+
test_dir = test_data_dir / "test_cavity"
5252
yaml_file = test_dir / "parameters_Run1.yaml"
5353

5454
# Test smaller frame range with repetitions
@@ -81,7 +81,7 @@ def test_pyptv_batch_validation_errors():
8181

8282
def test_pyptv_batch_produces_results(test_data_dir):
8383
"""Test that batch processing actually produces correspondence and tracking results"""
84-
test_dir = test_data_dir
84+
test_dir = test_data_dir / "test_cavity"
8585
yaml_file = test_dir / "parameters_Run1.yaml"
8686

8787
# Test specific frame
@@ -119,7 +119,7 @@ def test_pyptv_batch_produces_results(test_data_dir):
119119

120120
def test_pyptv_batch_tracking_results(test_data_dir):
121121
"""Test that batch processing with multiple frames produces tracking results and validates output."""
122-
test_dir = test_data_dir
122+
test_dir = test_data_dir / "test_cavity"
123123
yaml_file = test_dir / "parameters_Run1.yaml"
124124
start_frame = 10000
125125
end_frame = 10004
@@ -141,7 +141,7 @@ def test_pyptv_batch_tracking_results(test_data_dir):
141141

142142
def test_pyptv_batch_tracking_mode_only(test_data_dir):
143143
"""Test batch processing with mode='tracking' only, with debug output"""
144-
test_dir = test_data_dir
144+
test_dir = test_data_dir / "test_cavity"
145145
yaml_file = test_dir / "parameters_Run1.yaml"
146146
start_frame = 10000
147147
end_frame = 10004
@@ -176,34 +176,38 @@ def test_pyptv_batch_tracking_mode_only_with_temp_yaml(test_data_dir):
176176
import tempfile
177177
import shutil
178178
import yaml
179-
test_dir = test_data_dir
179+
test_dir = test_data_dir / "test_cavity"
180180
orig_yaml = test_dir / "parameters_Run1.yaml"
181181
start_frame = 10000
182182
end_frame = 10004
183183
res_dir = test_dir / "res"
184184
if res_dir.exists():
185185
shutil.rmtree(res_dir)
186186
# Copy original YAML to temp file
187-
with tempfile.NamedTemporaryFile('w', delete=False, suffix='.yaml', dir=test_dir) as tmp:
188-
temp_yaml = tmp.name
189-
with open(orig_yaml, 'r') as orig_f:
190-
orig_content = yaml.safe_load(orig_f)
191-
yaml.safe_dump(orig_content, tmp)
192-
print(f"Running tracking mode with temp YAML: {temp_yaml}")
193-
print(f"Frame range: {start_frame} to {end_frame}")
194-
pyptv_batch.main(temp_yaml, start_frame, end_frame, mode="sequence")
195-
# Extract and print tracking parameters
196-
with open(temp_yaml, 'r') as f:
197-
params = yaml.safe_load(f)
198-
track_params = params.get('track', {})
199-
print("Tracking parameters:")
200-
for k, v in track_params.items():
201-
print(f" {k}: {v}")
187+
temp_yaml = None
202188
try:
189+
with tempfile.NamedTemporaryFile('w', delete=False, suffix='.yaml', dir=test_dir) as tmp:
190+
temp_yaml = tmp.name
191+
with open(orig_yaml, 'r') as orig_f:
192+
orig_content = yaml.safe_load(orig_f)
193+
yaml.safe_dump(orig_content, tmp)
194+
print(f"Running tracking mode with temp YAML: {temp_yaml}")
195+
print(f"Frame range: {start_frame} to {end_frame}")
196+
pyptv_batch.main(temp_yaml, start_frame, end_frame, mode="sequence")
197+
# Extract and print tracking parameters
198+
with open(temp_yaml, 'r') as f:
199+
params = yaml.safe_load(f)
200+
track_params = params.get('track', {})
201+
print("Tracking parameters:")
202+
for k, v in track_params.items():
203+
print(f" {k}: {v}")
203204
pyptv_batch.main(temp_yaml, start_frame, end_frame, mode="tracking")
204205
except Exception as e:
205206
print(f"Tracking mode batch processing failed: {str(e)}")
206207
pytest.fail(f"Tracking mode batch processing failed: {str(e)}")
208+
finally:
209+
if temp_yaml is not None:
210+
Path(temp_yaml).unlink(missing_ok=True)
207211
assert res_dir.exists(), "Results directory should be created in tracking mode"
208212
print(f"Tracking mode test completed for frames {start_frame} to {end_frame}")
209213
for frame in range(start_frame, end_frame+1):
@@ -222,104 +226,122 @@ def test_pyptv_batch_tracking_mode_only_with_temp_yaml_collect_results(test_data
222226
import yaml
223227
import re
224228
import subprocess
225-
test_dir = test_data_dir
229+
test_dir = test_data_dir / "test_cavity"
226230
orig_yaml = test_dir / "parameters_Run1.yaml"
227231
start_frame = 10000
228232
end_frame = 10004
229233
res_dir = test_dir / "res"
230234
if res_dir.exists():
231235
shutil.rmtree(res_dir)
232-
# Copy original YAML to temp file
233-
with tempfile.NamedTemporaryFile('w', delete=False, suffix='.yaml', dir=test_dir) as tmp:
234-
temp_yaml = tmp.name
235-
with open(orig_yaml, 'r') as orig_f:
236-
orig_content = yaml.safe_load(orig_f)
237-
yaml.safe_dump(orig_content, tmp)
238-
# Extract tracking parameters
239-
with open(temp_yaml, 'r') as f:
240-
params = yaml.safe_load(f)
241-
track_params = params.get('track', {})
242-
# Run sequence mode (no need to capture output)
243-
pyptv_batch.main(temp_yaml, start_frame, end_frame, mode="sequence")
244-
# Run tracking mode and capture output to file, set cwd to test_dir
245-
with tempfile.NamedTemporaryFile('w+', delete=False, suffix='.txt', dir=test_dir) as out_file:
246-
out_path = out_file.name
247-
cmd = [sys.executable, '-m', 'pyptv.pyptv_batch', os.path.basename(temp_yaml), str(start_frame), str(end_frame), '--mode', 'tracking']
248-
try:
249-
subprocess.run(cmd, stdout=out_file, stderr=subprocess.STDOUT, check=True, cwd=test_dir)
250-
except subprocess.CalledProcessError:
251-
out_file.flush()
252-
with open(out_path, 'r') as f:
253-
print("\n--- Subprocess output ---")
254-
print(f.read())
255-
raise
256-
# Parse 'Average over sequence' line from file
257-
avg_particles = avg_links = avg_lost = None
258-
with open(out_path, 'r') as f:
259-
for line in f:
260-
m = re.search(r"Average over sequence, particles:\s*([\d\.-]+), links:\s*([\d\.-]+), lost:\s*([\d\.-]+)", line)
261-
if m:
262-
avg_particles = float(m.group(1))
263-
avg_links = float(m.group(2))
264-
avg_lost = float(m.group(3))
265-
break
266-
# Create DataFrame to collect results
267-
results = []
268-
# Store original run
269-
row = {**track_params, 'avg_particles': avg_particles, 'avg_links': avg_links, 'avg_lost': avg_lost, 'param_changed': None, 'change': 0.0}
270-
results.append(row)
271-
272-
# Loop: for each numeric track_param, perturb by +10% and rerun tracking
273-
for param, value in track_params.items():
274-
if isinstance(value, (int, float)):
275-
# Create new temp YAML with perturbed parameter
276-
with tempfile.NamedTemporaryFile('w', delete=False, suffix='.yaml', dir=test_dir) as tmp2:
277-
temp_yaml2 = tmp2.name
278-
with open(orig_yaml, 'r') as orig_f:
279-
orig_content2 = yaml.safe_load(orig_f)
280-
# Update the parameter by +10%
281-
new_val = value * 1.1
282-
orig_content2['track'][param] = type(value)(new_val)
283-
yaml.safe_dump(orig_content2, tmp2)
284-
# Run sequence mode (to prep files)
285-
pyptv_batch.main(temp_yaml2, start_frame, end_frame, mode="sequence")
286-
# Run tracking mode and capture output
287-
with tempfile.NamedTemporaryFile('w+', delete=False, suffix='.txt', dir=test_dir) as out_file2:
288-
out_path2 = out_file2.name
289-
cmd2 = [sys.executable, '-m', 'pyptv.pyptv_batch', os.path.basename(temp_yaml2), str(start_frame), str(end_frame), '--mode', 'tracking']
236+
temp_yaml = None
237+
out_path = None
238+
summary_path = test_dir / "tracking_run_summary.csv"
239+
try:
240+
# Copy original YAML to temp file
241+
with tempfile.NamedTemporaryFile('w', delete=False, suffix='.yaml', dir=test_dir) as tmp:
242+
temp_yaml = tmp.name
243+
with open(orig_yaml, 'r') as orig_f:
244+
orig_content = yaml.safe_load(orig_f)
245+
yaml.safe_dump(orig_content, tmp)
246+
# Extract tracking parameters
247+
with open(temp_yaml, 'r') as f:
248+
params = yaml.safe_load(f)
249+
track_params = params.get('track', {})
250+
# Run sequence mode (no need to capture output)
251+
pyptv_batch.main(temp_yaml, start_frame, end_frame, mode="sequence")
252+
# Run tracking mode and capture output to file, set cwd to test_dir
253+
with tempfile.NamedTemporaryFile('w+', delete=False, suffix='.txt', dir=test_dir) as out_file:
254+
out_path = out_file.name
255+
cmd = [sys.executable, '-m', 'pyptv.pyptv_batch', os.path.basename(temp_yaml), str(start_frame), str(end_frame), '--mode', 'tracking']
256+
try:
257+
subprocess.run(cmd, stdout=out_file, stderr=subprocess.STDOUT, check=True, cwd=test_dir)
258+
except subprocess.CalledProcessError:
259+
out_file.flush()
260+
with open(out_path, 'r') as f:
261+
print("\n--- Subprocess output ---")
262+
print(f.read())
263+
raise
264+
# Parse 'Average over sequence' line from file
265+
avg_particles = avg_links = avg_lost = None
266+
with open(out_path, 'r') as f:
267+
for line in f:
268+
m = re.search(r"Average over sequence, particles:\s*([\d\.-]+), links:\s*([\d\.-]+), lost:\s*([\d\.-]+)", line)
269+
if m:
270+
avg_particles = float(m.group(1))
271+
avg_links = float(m.group(2))
272+
avg_lost = float(m.group(3))
273+
break
274+
# Create DataFrame to collect results
275+
results = []
276+
# Store original run
277+
row = {**track_params, 'avg_particles': avg_particles, 'avg_links': avg_links, 'avg_lost': avg_lost, 'param_changed': None, 'change': 0.0}
278+
results.append(row)
279+
280+
# Loop: for each numeric track_param, perturb by +10% and rerun tracking
281+
for param, value in track_params.items():
282+
if isinstance(value, (int, float)):
283+
temp_yaml2 = None
284+
out_path2 = None
285+
# Create new temp YAML with perturbed parameter
286+
with tempfile.NamedTemporaryFile('w', delete=False, suffix='.yaml', dir=test_dir) as tmp2:
287+
temp_yaml2 = tmp2.name
288+
with open(orig_yaml, 'r') as orig_f:
289+
orig_content2 = yaml.safe_load(orig_f)
290+
# Update the parameter by +10%
291+
new_val = value * 1.1
292+
orig_content2['track'][param] = type(value)(new_val)
293+
yaml.safe_dump(orig_content2, tmp2)
290294
try:
291-
subprocess.run(cmd2, stdout=out_file2, stderr=subprocess.STDOUT, check=True, cwd=test_dir)
292-
except subprocess.CalledProcessError:
293-
out_file2.flush()
295+
# Run sequence mode (to prep files)
296+
pyptv_batch.main(temp_yaml2, start_frame, end_frame, mode="sequence")
297+
# Run tracking mode and capture output
298+
with tempfile.NamedTemporaryFile('w+', delete=False, suffix='.txt', dir=test_dir) as out_file2:
299+
out_path2 = out_file2.name
300+
cmd2 = [sys.executable, '-m', 'pyptv.pyptv_batch', os.path.basename(temp_yaml2), str(start_frame), str(end_frame), '--mode', 'tracking']
301+
try:
302+
subprocess.run(cmd2, stdout=out_file2, stderr=subprocess.STDOUT, check=True, cwd=test_dir)
303+
except subprocess.CalledProcessError:
304+
out_file2.flush()
305+
with open(out_path2, 'r') as f:
306+
print(f"\n--- Subprocess output for {param} +10% ---")
307+
print(f.read())
308+
continue # Skip this run if it failed
309+
# Parse output
310+
avg_particles2 = avg_links2 = avg_lost2 = None
294311
with open(out_path2, 'r') as f:
295-
print(f"\n--- Subprocess output for {param} +10% ---")
296-
print(f.read())
297-
continue # Skip this run if it failed
298-
# Parse output
299-
avg_particles2 = avg_links2 = avg_lost2 = None
300-
with open(out_path2, 'r') as f:
301-
for line in f:
302-
m = re.search(r"Average over sequence, particles:\s*([\d\.-]+), links:\s*([\d\.-]+), lost:\s*([\d\.-]+)", line)
303-
if m:
304-
avg_particles2 = float(m.group(1))
305-
avg_links2 = float(m.group(2))
306-
avg_lost2 = float(m.group(3))
307-
break
308-
# Store result
309-
perturbed_params = dict(track_params)
310-
perturbed_params[param] = type(value)(new_val)
311-
row2 = {**perturbed_params, 'avg_particles': avg_particles2, 'avg_links': avg_links2, 'avg_lost': avg_lost2, 'param_changed': param, 'change': 0.1}
312-
results.append(row2)
313-
314-
df = pd.DataFrame(results)
315-
print("\nTracking run summary (including perturbations):")
316-
print(df)
317-
df.to_csv(test_dir / "tracking_run_summary.csv", index=False)
318-
319-
# Find best row: least avg_lost, then most avg_links
320-
best = df.sort_values(['avg_lost', 'avg_links'], ascending=[True, False]).iloc[0]
321-
print("\nBest tracking result (least lost, most links):")
322-
print(best)
312+
for line in f:
313+
m = re.search(r"Average over sequence, particles:\s*([\d\.-]+), links:\s*([\d\.-]+), lost:\s*([\d\.-]+)", line)
314+
if m:
315+
avg_particles2 = float(m.group(1))
316+
avg_links2 = float(m.group(2))
317+
avg_lost2 = float(m.group(3))
318+
break
319+
# Store result
320+
perturbed_params = dict(track_params)
321+
perturbed_params[param] = type(value)(new_val)
322+
row2 = {**perturbed_params, 'avg_particles': avg_particles2, 'avg_links': avg_links2, 'avg_lost': avg_lost2, 'param_changed': param, 'change': 0.1}
323+
results.append(row2)
324+
finally:
325+
if temp_yaml2 is not None:
326+
Path(temp_yaml2).unlink(missing_ok=True)
327+
if out_path2 is not None:
328+
Path(out_path2).unlink(missing_ok=True)
329+
330+
df = pd.DataFrame(results)
331+
print("\nTracking run summary (including perturbations):")
332+
print(df)
333+
df.to_csv(summary_path, index=False)
334+
335+
# Find best row: least avg_lost, then most avg_links
336+
best = df.sort_values(['avg_lost', 'avg_links'], ascending=[True, False]).iloc[0]
337+
print("\nBest tracking result (least lost, most links):")
338+
print(best)
339+
finally:
340+
if temp_yaml is not None:
341+
Path(temp_yaml).unlink(missing_ok=True)
342+
if out_path is not None:
343+
Path(out_path).unlink(missing_ok=True)
344+
summary_path.unlink(missing_ok=True)
323345

324346

325347
def optimize_tracking_parameters(test_data_dir):
@@ -332,7 +354,7 @@ def optimize_tracking_parameters(test_data_dir):
332354
import numpy as np
333355
from scipy.optimize import minimize
334356

335-
test_dir = test_data_dir
357+
test_dir = test_data_dir / "test_cavity"
336358
orig_yaml = test_dir / "parameters_Run1.yaml"
337359
start_frame = 10000
338360
end_frame = 10004 # Use only 2 frames for speed

0 commit comments

Comments
 (0)