liammatt5 commited on
Commit
7d078da
·
verified ·
1 Parent(s): e7b09cd

Update interface.py

Browse files
Files changed (1) hide show
  1. interface.py +92 -9
interface.py CHANGED
@@ -8,7 +8,7 @@ import numpy as np
8
  import soundfile as sf
9
  from pathlib import Path
10
  from itertools import permutations
11
- from typing import Any, Dict, List, Optional
12
 
13
  from reasoning_pipeline import aggregate_reasoning_summaries
14
 
@@ -24,6 +24,17 @@ def get_model():
24
  return _model
25
 
26
 
 
 
 
 
 
 
 
 
 
 
 
27
  def apply_wiener_filter(est_sources, mixture, iterations=1):
28
  """
29
  A simplified Wiener filter refinement.
@@ -197,6 +208,7 @@ def save_audio_file(path, waveform, sample_rate):
197
  RESULTS_DIR = Path("pipeline_results")
198
  REASONING_SUMMARY_PATH = RESULTS_DIR / "reasoning_summary.json"
199
  PATIENT_REGISTRY_PATH = RESULTS_DIR / "patient_registry.json"
 
200
  HISTORY_RECORDS_PATH = RESULTS_DIR / "history_records.json"
201
  DB_PATH = RESULTS_DIR / "speformer.db"
202
  AUDIO_STORAGE_DIR = RESULTS_DIR / "audio"
@@ -218,7 +230,7 @@ def initialize_database():
218
  """
219
  CREATE TABLE IF NOT EXISTS patient_registry (
220
  id INTEGER PRIMARY KEY,
221
- patient_id TEXT UNIQUE,
222
  name TEXT,
223
  reference_audio TEXT,
224
  local_reference_audio TEXT,
@@ -253,6 +265,33 @@ def initialize_database():
253
  )
254
  """
255
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  conn.commit()
257
  conn.close()
258
 
@@ -296,12 +335,48 @@ def _copy_audio_to_storage(src_path: Optional[str], subdir: str, prefix: str) ->
296
  return str(dest)
297
 
298
 
299
- def save_patient_registry(patient_entries: List[Dict[str, str]], registry_path: Optional[Path] = None) -> Path:
300
  path = Path(registry_path) if registry_path is not None else PATIENT_REGISTRY_PATH
301
  path.parent.mkdir(parents=True, exist_ok=True)
 
 
 
 
 
 
 
 
 
302
 
303
  initialize_database()
304
  conn = _get_db_connection()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  local_entries = []
306
  for entry in patient_entries:
307
  patient_id = entry.get("patient_id") or entry.get("id") or ""
@@ -309,7 +384,7 @@ def save_patient_registry(patient_entries: List[Dict[str, str]], registry_path:
309
  ref_audio = entry.get("reference_audio")
310
  local_ref_audio = _copy_audio_to_storage(ref_audio, "patient_reference", patient_id) if ref_audio else None
311
  conn.execute(
312
- "INSERT OR REPLACE INTO patient_registry (patient_id, name, reference_audio, local_reference_audio, created_at) VALUES (?, ?, ?, ?, ?)",
313
  (
314
  patient_id,
315
  name,
@@ -328,7 +403,16 @@ def save_patient_registry(patient_entries: List[Dict[str, str]], registry_path:
328
 
329
  with open(path, "w", encoding="utf-8") as f:
330
  json.dump(local_entries, f, indent=2)
331
- return path
 
 
 
 
 
 
 
 
 
332
 
333
 
334
  def load_patient_registry(registry_path: Optional[Path] = None) -> List[Dict[str, str]]:
@@ -612,10 +696,9 @@ def monitoring_table_rows(results_path: Optional[Path] = None):
612
  for item in records:
613
  rows.append([
614
  item.get("audio_id"),
615
- item.get("overall_state"),
616
- item.get("mean_wheeze_prob"),
617
- item.get("mean_crackle_prob"),
618
- item.get("breathing_rate_mean"),
619
  item.get("comment"),
620
  ])
621
  return rows
 
8
  import soundfile as sf
9
  from pathlib import Path
10
  from itertools import permutations
11
+ from typing import Any, Dict, List, Optional, Tuple
12
 
13
  from reasoning_pipeline import aggregate_reasoning_summaries
14
 
 
24
  return _model
25
 
26
 
27
+ def round_value(value):
28
+ if value is None:
29
+ return None
30
+ if isinstance(value, bool):
31
+ return value
32
+ try:
33
+ return round(float(value), 2)
34
+ except (ValueError, TypeError):
35
+ return value
36
+
37
+
38
  def apply_wiener_filter(est_sources, mixture, iterations=1):
39
  """
40
  A simplified Wiener filter refinement.
 
208
  RESULTS_DIR = Path("pipeline_results")
209
  REASONING_SUMMARY_PATH = RESULTS_DIR / "reasoning_summary.json"
210
  PATIENT_REGISTRY_PATH = RESULTS_DIR / "patient_registry.json"
211
+ PATIENT_REGISTRY_BATCHES_PATH = RESULTS_DIR / "patient_registry_batches.json"
212
  HISTORY_RECORDS_PATH = RESULTS_DIR / "history_records.json"
213
  DB_PATH = RESULTS_DIR / "speformer.db"
214
  AUDIO_STORAGE_DIR = RESULTS_DIR / "audio"
 
230
  """
231
  CREATE TABLE IF NOT EXISTS patient_registry (
232
  id INTEGER PRIMARY KEY,
233
+ patient_id TEXT,
234
  name TEXT,
235
  reference_audio TEXT,
236
  local_reference_audio TEXT,
 
265
  )
266
  """
267
  )
268
+
269
+ legacy_sql = conn.execute(
270
+ "SELECT sql FROM sqlite_master WHERE type='table' AND name='patient_registry'"
271
+ ).fetchone()
272
+ if legacy_sql and legacy_sql[0] and "patient_id TEXT UNIQUE" in legacy_sql[0]:
273
+ conn.execute("ALTER TABLE patient_registry RENAME TO patient_registry_old")
274
+ conn.execute(
275
+ """
276
+ CREATE TABLE patient_registry (
277
+ id INTEGER PRIMARY KEY,
278
+ patient_id TEXT,
279
+ name TEXT,
280
+ reference_audio TEXT,
281
+ local_reference_audio TEXT,
282
+ created_at TEXT
283
+ )
284
+ """
285
+ )
286
+ conn.execute(
287
+ """
288
+ INSERT INTO patient_registry (id, patient_id, name, reference_audio, local_reference_audio, created_at)
289
+ SELECT id, patient_id, name, reference_audio, local_reference_audio, created_at
290
+ FROM patient_registry_old
291
+ """
292
+ )
293
+ conn.execute("DROP TABLE patient_registry_old")
294
+
295
  conn.commit()
296
  conn.close()
297
 
 
335
  return str(dest)
336
 
337
 
338
+ def save_patient_registry(patient_entries: List[Dict[str, str]], registry_path: Optional[Path] = None) -> Tuple[Optional[Path], Optional[str]]:
339
  path = Path(registry_path) if registry_path is not None else PATIENT_REGISTRY_PATH
340
  path.parent.mkdir(parents=True, exist_ok=True)
341
+ # Normalize names for duplicate-batch detection
342
+ normalized_names = [(entry.get("name") or "").strip() for entry in patient_entries]
343
+ normalized_names = [n for n in normalized_names if n]
344
+
345
+ if not normalized_names:
346
+ return None, "Error: Please enter at least one patient name before registering."
347
+
348
+ if len(normalized_names) != len(set(name.lower() for name in normalized_names)):
349
+ return None, "Error: Duplicate patient names were entered in this registration. Please use unique names."
350
 
351
  initialize_database()
352
  conn = _get_db_connection()
353
+ try:
354
+ cursor = conn.execute("SELECT name FROM patient_registry")
355
+ existing_names = {row["name"].strip().lower() for row in cursor.fetchall() if row["name"]}
356
+ except Exception:
357
+ existing_names = set()
358
+
359
+ conflicts = [name for name in normalized_names if name.lower() in existing_names]
360
+ if conflicts:
361
+ conn.close()
362
+ conflict_list = ", ".join(sorted(set(conflicts)))
363
+ return None, f"Error: Patient name(s) already registered: {conflict_list}. Registration aborted."
364
+
365
+ # Load existing registration batches and check for duplicates (set equality)
366
+ try:
367
+ batches = []
368
+ if PATIENT_REGISTRY_BATCHES_PATH.exists():
369
+ with open(PATIENT_REGISTRY_BATCHES_PATH, "r", encoding="utf-8") as bf:
370
+ batches = json.load(bf) or []
371
+ # Build set of non-empty names for comparison
372
+ new_set = set(normalized_names)
373
+ for b in batches:
374
+ if set([x for x in (b.get("names") or []) if x]) == new_set:
375
+ conn.close()
376
+ return None, "Error: This exact set of patient names has already been registered."
377
+ except Exception:
378
+ batches = []
379
+
380
  local_entries = []
381
  for entry in patient_entries:
382
  patient_id = entry.get("patient_id") or entry.get("id") or ""
 
384
  ref_audio = entry.get("reference_audio")
385
  local_ref_audio = _copy_audio_to_storage(ref_audio, "patient_reference", patient_id) if ref_audio else None
386
  conn.execute(
387
+ "INSERT INTO patient_registry (patient_id, name, reference_audio, local_reference_audio, created_at) VALUES (?, ?, ?, ?, ?)",
388
  (
389
  patient_id,
390
  name,
 
403
 
404
  with open(path, "w", encoding="utf-8") as f:
405
  json.dump(local_entries, f, indent=2)
406
+
407
+ # Record the saved batch for future duplicate checks
408
+ try:
409
+ batch_record = {"timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "names": [e.get("name") for e in local_entries]}
410
+ batches.append(batch_record)
411
+ with open(PATIENT_REGISTRY_BATCHES_PATH, "w", encoding="utf-8") as bf:
412
+ json.dump(batches, bf, indent=2)
413
+ except Exception:
414
+ pass
415
+ return path, None
416
 
417
 
418
  def load_patient_registry(registry_path: Optional[Path] = None) -> List[Dict[str, str]]:
 
696
  for item in records:
697
  rows.append([
698
  item.get("audio_id"),
699
+ round_value(item.get("mean_wheeze_prob")),
700
+ round_value(item.get("mean_crackle_prob")),
701
+ round_value(item.get("breathing_rate_mean")),
 
702
  item.get("comment"),
703
  ])
704
  return rows