Coverage for labnirs2snirf / labnirs2snirf.py: 100%
45 statements
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-28 06:02 +0000
« prev ^ index » next coverage.py v7.12.0, created at 2025-11-28 06:02 +0000
1"""
2Main entrypoint for LABNIRS to SNIRF conversion when run as a script.
3"""
5import logging
6import sys
7from pprint import pformat
9from .args import ArgumentError, Arguments
10from .error import Labnirs2SnirfError
11from .labnirs import read_labnirs
12from .layout import read_layout, update_layout
13from .log import config_logger
14from .snirf import write_snirf
17def main() -> int:
18 """
19 LABNIRS to SNIRF conversion script.
21 This function coordinates the full conversion workflow when
22 run as `python -m labnirs2snirf` on the command line:
24 1. Parse command-line arguments
25 2. Configure logging based on user preferences
26 3. Read and parse LABNIRS data file
27 4. Optionally add probe position information
28 5. Write output in SNIRF format
30 Returns
31 -------
32 int
33 Exit code: 0 for success, 1 for failure.
35 Notes
36 -----
37 Exception handling is designed with the intention to reduce end-user exposure
38 to stack traces and technical details. Most exceptions are hidden from end users,
39 providing only a concise error message. Detailed error information can be
40 obtained by increasing verbosity with -v flags and/or using --log to write
41 to a log file.
42 """
43 log = None
44 args = None
45 try:
46 # 1. Read and check arguments
47 args = Arguments().parse(sys.argv[1:])
49 # Since we're not a library, we will configure logging here.
50 config_logger(file_logging=args.log, verbosity_level=args.verbosity)
51 log = logging.getLogger(__name__)
52 log.info("Logger configured")
54 log.debug("Parsed arguments: %s", pformat(args, indent=2))
56 # 2. Read in labNIRS file
57 log.info("Reading labNIRS data")
58 data = read_labnirs(
59 data_file=args.source_file,
60 keep_category=args.type,
61 drop_subtype=args.drop,
62 )
63 # raise RuntimeError("Test exception")
65 # 3. Add probe positions if provided
66 if args.locations is not None:
67 log.info("Reading probe layout from file")
68 layout = read_layout(args.locations)
69 update_layout(data, layout)
71 # 4. Export SNIRF data
72 log.info("Writing SNIRF file")
73 write_snirf(data, args.target_file)
75 log.info("Successfully completed conversion")
76 return 0
78 # Hide all exceptions from end users as they aren't necessarily developers.
79 # Provide error message, explain how to enable logging and get more information about the issue.
80 except ArgumentError as e:
81 print(f"Argument error: {e}")
82 return 1
83 except Labnirs2SnirfError as e:
84 if log is not None:
85 log.exception("%s", e)
86 print(
87 f"Conversion failed: {e}\n"
88 "Increase verbosity (-v, -vv, -vvv) for more details. Use --log to log messages to a file.",
89 )
90 return 1
91 except Exception as e: # pylint: disable=W0718
92 print(
93 "Something went wrong. Increase verbosity (-v, -vv, -vvv) for more details. Use --log to log messages to a file.",
94 )
95 if log is not None:
96 log.exception("Exception received. Error message: %s", e)
97 else:
98 print("Logging not configured, dumping exception:")
99 raise
100 return 1
103if __name__ == "__main__":
104 sys.exit(main())