Skip to content

Commit 820752d

Browse files
authored
Add OpenEphys version check for timestamps alignment (#27)
1 parent 1d71053 commit 820752d

164 files changed

Lines changed: 42357 additions & 5 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/aind_ephys_transformation/ephys_job.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
import shutil
77
import sys
88
import json
9+
from packaging.version import parse
910
from datetime import datetime
1011
from pathlib import Path
1112
from typing import Iterator, Literal, Optional, List
1213
from pydantic import model_validator, field_validator
14+
import xml.etree.ElementTree as ET
1315

1416
import numpy as np
1517
import pandas as pd
@@ -68,8 +70,11 @@ class EphysJobSettings(BasicJobSettings):
6870
# Check timestamps alignment
6971
check_timestamps: bool = Field(
7072
default=True,
71-
description="Check if timestamps are aligned and raise an error if "
72-
"they are not.",
73+
description=(
74+
"Check if timestamps are aligned and raise an error if they are "
75+
"not. This check is applied only for Open Ephys < 1.1 data, "
76+
"as >=1.1 versions of Open Ephys have already aligned timestamps."
77+
),
7378
title="Check Timestamps",
7479
)
7580
chronic_chunks_to_compress: Optional[List[str]] = Field(
@@ -641,11 +646,50 @@ def _check_timestamps_alignment(self) -> bool:
641646
True if timestamps are aligned, False otherwise.
642647
"""
643648
if self.job_settings.reader_name == ReaderName.CHRONIC:
644-
# Chronic data does not have timestamps, so we return True
649+
# Chronic data do harp sync on-the-fly, so we return True
645650
return True
646651
else:
647-
# OpenEphys data has timestamps, so we check for them
648-
return self._check_openephys_timestamps()
652+
# Read Open Ephys version from settings file
653+
openephys_folder = self.job_settings.input_source
654+
# We use the first settings file we find, because the version
655+
# is the same
656+
settings_file = list(openephys_folder.glob("**/settings*.xml"))[0]
657+
658+
# Read xml file and check for OpenEphys version
659+
tree = ET.parse(str(settings_file))
660+
root = tree.getroot()
661+
662+
info_chain = root.find("INFO")
663+
oe_version = parse(info_chain.find("VERSION").text)
664+
if oe_version >= parse("1.1.0-preview"):
665+
# Look for SYNC STATUS in CUSTOM_PARAMETERS section of settings
666+
# If not all HARP_SYNCED, check timestamps files to see if
667+
# they have been aligned
668+
signal_chains = root.findall("SIGNALCHAIN")
669+
for sc in signal_chains:
670+
record_node = [
671+
p for p in sc.findall("PROCESSOR")
672+
if p.attrib["name"] == "Record Node"
673+
]
674+
if len(record_node) > 0:
675+
record_node = record_node[0]
676+
custom_parameters = record_node.find(
677+
"CUSTOM_PARAMETERS"
678+
)
679+
sync_statuses = custom_parameters.findall(
680+
"SYNC_STATUS"
681+
)
682+
all_synced = all(
683+
sync_status.attrib["status"] == "HARP_SYNCED"
684+
for sync_status in sync_statuses
685+
)
686+
if all_synced:
687+
return True
688+
else:
689+
self._check_openephys_timestamps()
690+
else:
691+
# OE version < 1.1.0-preview -> timestamps may not be aligned
692+
return self._check_openephys_timestamps()
649693

650694
def _check_openephys_timestamps(self) -> bool:
651695
"""

0 commit comments

Comments
 (0)