-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcalculate_volume2.py
More file actions
111 lines (78 loc) · 3.17 KB
/
Copy pathcalculate_volume2.py
File metadata and controls
111 lines (78 loc) · 3.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
from pathlib import Path
import csv
from datetime import datetime
FLOW_COLUMN = "Flow Unit #1 [Flowboard (1384)]"
THRESHOLD_UL_MIN = 0.4
STOP_AFTER_BELOW_THRESHOLD_SECONDS = 1.0
USE_ABSOLUTE_FLOW = True
def parse_time(t):
return datetime.strptime(t, "%Y-%m-%d %H:%M:%S.%f")
def main():
print("RUNNING NEW VERSION - sustained stop + trapezoidal integration")
script_dir = Path(__file__).resolve().parent
csv_files = sorted(script_dir.glob("*.csv"))
if not csv_files:
raise FileNotFoundError(f"No CSV files found in: {script_dir}")
csv_path = csv_files[0]
print(f"Using CSV file: {csv_path.name}")
rows = []
with open(csv_path, newline="", encoding="utf-8-sig") as f:
reader = csv.DictReader(f, delimiter=";")
for row in reader:
time = parse_time(row["Time"])
flow = float(row[FLOW_COLUMN].replace(",", "."))
rows.append((time, flow))
rows.sort(key=lambda x: x[0])
if len(rows) < 2:
raise ValueError("Need at least two rows to calculate volume.")
start_index = None
for i, (_, flow) in enumerate(rows):
if abs(flow) > THRESHOLD_UL_MIN:
start_index = i
break
if start_index is None:
print(f"No flow above {THRESHOLD_UL_MIN} µL/min found.")
return
below_start_index = None
stop_index = None
for i in range(start_index, len(rows)):
time, flow = rows[i]
if abs(flow) < THRESHOLD_UL_MIN:
if below_start_index is None:
below_start_index = i
below_duration = (rows[i][0] - rows[below_start_index][0]).total_seconds()
if below_duration >= STOP_AFTER_BELOW_THRESHOLD_SECONDS:
stop_index = below_start_index
break
else:
below_start_index = None
if stop_index is None:
stop_index = len(rows) - 1
print("Warning: no sustained stop found; integrating until end of file.")
total_volume_ul = 0.0
for i in range(start_index + 1, stop_index + 1):
previous_time, previous_flow = rows[i - 1]
current_time, current_flow = rows[i]
dt_seconds = (current_time - previous_time).total_seconds()
if USE_ABSOLUTE_FLOW:
f1 = abs(previous_flow)
f2 = abs(current_flow)
else:
f1 = previous_flow
f2 = current_flow
average_flow_ul_min = (f1 + f2) / 2.0
total_volume_ul += average_flow_ul_min * dt_seconds / 60.0
start_time = rows[start_index][0]
stop_time = rows[stop_index][0]
active_duration_s = (stop_time - start_time).total_seconds()
print(f"Number of samples: {len(rows)}")
print(f"Start threshold: {THRESHOLD_UL_MIN} µL/min")
print(f"Stop delay below threshold: {STOP_AFTER_BELOW_THRESHOLD_SECONDS} s")
print(f"Use absolute flow: {USE_ABSOLUTE_FLOW}")
print(f"Pumping start time: {start_time}")
print(f"Pumping stop time: {stop_time}")
print(f"Integrated pumping time: {active_duration_s:.3f} s")
print(f"Total pumped volume: {total_volume_ul:.6f} µL")
print(f"Total pumped volume: {total_volume_ul / 1000.0:.9f} mL")
if __name__ == "__main__":
main()