Skip to content

Commit 73c43a7

Browse files
committed
Add --csv-txyz-idxs and rename --txyz to --csv-txyz
src/actinet/actinet.py: - Rename --txyz to --csv-txyz for consistency with other --csv-* options - Add --csv-txyz-idxs to specify column indices (0-indexed), overrides --csv-txyz - Add index validation (non-integer, negative, out-of-range) - Warn when --csv-* options are used with non-CSV device files Closes #36
1 parent a867819 commit 73c43a7

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

src/actinet/actinet.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import argparse
77
import json
88
import hashlib
9+
import warnings
910
import numpy as np
1011
import pandas as pd
1112
import joblib
@@ -99,13 +100,14 @@ def main():
99100
type=int,
100101
default=1,
101102
)
102-
parser.add_argument("--txyz",
103-
help="Use this option to specify the column names for time, x, y, z " +
104-
"in the input file, in that order. Use a comma-separated string. " +
105-
"Only needed for CSV files, can be ignored for other file types. " +
106-
"Default: 'time,x,y,z'",
103+
parser.add_argument("--csv-txyz",
104+
help="Column names for time, x, y, z in CSV files. "
105+
"Comma-separated string. Default: 'time,x,y,z'",
107106
type=str, default="time,x,y,z"
108107
)
108+
parser.add_argument("--csv-txyz-idxs",
109+
help="Column indices for time,x,y,z (0-indexed, e.g., '0,1,2,3'). Overrides --csv-txyz.",
110+
type=str, default=None)
109111
parser.add_argument('--csv-date-format',
110112
default="%Y-%m-%d %H:%M:%S.%f",
111113
type=str,
@@ -164,12 +166,13 @@ def main():
164166
# Load file
165167
data, info_read = read(
166168
args.filepath,
167-
args.txyz,
169+
args.csv_txyz,
168170
args.csv_start_row-1, # -1 to convert to zero-based index
169171
args.csv_date_format,
170172
args.calibration_stdtol_min,
171173
resample_hz="uniform",
172174
sample_rate=args.sample_rate,
175+
csv_txyz_idxs=args.csv_txyz_idxs,
173176
verbose=verbose,
174177
)
175178
info.update(info_read)
@@ -305,7 +308,7 @@ def main():
305308

306309
def read(
307310
filepath, usecols=None, skipRows=0, dateFormat=None, calibration_stdtol_min=None,
308-
resample_hz="uniform", sample_rate=None, lowpass_hz=None, verbose=True
311+
resample_hz="uniform", sample_rate=None, lowpass_hz=None, csv_txyz_idxs=None, verbose=True
309312
):
310313
p = pathlib.Path(filepath)
311314
fsize = round(p.stat().st_size / (1024 * 1024), 1)
@@ -316,7 +319,21 @@ def read(
316319

317320
if ftype in (".csv", ".pkl"):
318321
if ftype == ".csv":
319-
tcol, xcol, ycol, zcol = usecols.split(',')
322+
# Determine column names: either from indices or from usecols
323+
if csv_txyz_idxs is not None:
324+
try:
325+
tidx, xidx, yidx, zidx = map(int, csv_txyz_idxs.split(','))
326+
except ValueError:
327+
raise ValueError(f"csv_txyz_idxs must be 4 comma-separated integers, got: '{csv_txyz_idxs}'")
328+
if any(i < 0 for i in [tidx, xidx, yidx, zidx]):
329+
raise ValueError(f"csv_txyz_idxs must be non-negative integers, got: '{csv_txyz_idxs}'")
330+
header = pd.read_csv(filepath, nrows=0).columns.tolist()
331+
max_idx = max(tidx, xidx, yidx, zidx)
332+
if max_idx >= len(header):
333+
raise ValueError(f"Column index {max_idx} out of range. CSV has {len(header)} columns.")
334+
tcol, xcol, ycol, zcol = header[tidx], header[xidx], header[yidx], header[zidx]
335+
else:
336+
tcol, xcol, ycol, zcol = usecols.split(',')
320337

321338
data = pd.read_csv(
322339
filepath,
@@ -366,6 +383,9 @@ def read(
366383

367384
elif ftype in (".cwa", ".gt3x", ".bin"):
368385

386+
if csv_txyz_idxs is not None:
387+
warnings.warn("--csv-* options are only supported for CSV files. Ignoring.")
388+
369389
data, info = actipy.read_device(
370390
filepath,
371391
lowpass_hz=None,

0 commit comments

Comments
 (0)