Coverage for labnirs2snirf / model.py: 100%

22 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2025-11-28 06:02 +0000

1""" 

2NIRS data model definitions for Labnirs --> SNIRF conversion. 

3 

4Based on the SNIRF specification v1.1. 

5See https://github.com/fNIRS/snirf/blob/v1.1/snirf_specification.md for details. 

6""" 

7 

8from dataclasses import dataclass, field 

9 

10import numpy as np 

11 

12 

13@dataclass(slots=True, frozen=True) 

14class Metadata: 

15 """ 

16 Metadata container for NIRS measurements following SNIRF specification. 

17 

18 Attributes 

19 ---------- 

20 SubjectID : str 

21 Subject identifier string. 

22 MeasurementDate : str 

23 Date of measurement in YYYY-MM-DD format. 

24 MeasurementTime : str 

25 Time of measurement in HH:MM:SS format. 

26 LengthUnit : str, default="m" 

27 Unit of length measurements (meters). 

28 TimeUnit : str, default="s" 

29 Unit of time measurements (seconds). 

30 FrequencyUnit : str, default="Hz" 

31 Unit of frequency measurements (Hertz). 

32 additional_fields : dict[str, str], default=empty dict 

33 Additional optional metadata fields as key-value pairs. 

34 """ 

35 

36 SubjectID: str 

37 MeasurementDate: str 

38 MeasurementTime: str 

39 LengthUnit: str = "m" 

40 TimeUnit: str = "s" 

41 FrequencyUnit: str = "Hz" 

42 additional_fields: dict[str, str] = field(default_factory=dict) 

43 

44 

45@dataclass(slots=True, frozen=True) 

46class Measurement: 

47 """ 

48 Measurement channel specification following SNIRF specification. 

49 

50 Each Measurement describes a single data channel with information about 

51 the source-detector pair, wavelength, and data type. 

52 

53 Attributes 

54 ---------- 

55 sourceIndex : int 

56 Index of the source optode (1-based). 

57 detectorIndex : int 

58 Index of the detector optode (1-based). 

59 dataType : int 

60 Type of data: 1 for continuous wave, 99999 for processed (e.g., HbO, HbR). 

61 dataTypeIndex : int 

62 Index for grouping measurements of the same type (typically 0). 

63 wavelengthIndex : int 

64 Index into the wavelengths array, indicating the wavelength used. 

65 dataTypeLabel : str or None, default=None 

66 Optional label for processed data types (e.g., "HbO", "HbR", "HbT"). 

67 """ 

68 

69 sourceIndex: int 

70 detectorIndex: int 

71 dataType: int 

72 dataTypeIndex: int 

73 wavelengthIndex: int 

74 dataTypeLabel: str | None = None 

75 

76 

77@dataclass(slots=True, frozen=True) 

78class Data: 

79 """ 

80 Experimental time series data following SNIRF specification. 

81 

82 Attributes 

83 ---------- 

84 time : np.ndarray 

85 1D array of time points in seconds. 

86 Possible dtypes: float64 (recommended), float32. 

87 dataTimeSeries : np.ndarray 

88 2D array (time x channels) of measurement values. 

89 Possible dtypes: float64 (recommended), float32. 

90 measurementList : list[Measurement] 

91 List of Measurement objects describing each data channel. 

92 """ 

93 

94 time: np.ndarray 

95 dataTimeSeries: np.ndarray 

96 measurementList: list[Measurement] 

97 

98 

99@dataclass(slots=True, frozen=True) 

100class Probe: 

101 """ 

102 Probe geometry and configuration following SNIRF specification. 

103 

104 Attributes 

105 ---------- 

106 wavelengths : np.ndarray 

107 1D array of wavelengths in nanometers. 

108 sourcePos3D : np.ndarray 

109 2D array (n_sources x 3) of source 3D coordinates [x, y, z]. 

110 detectorPos3D : np.ndarray 

111 2D array (n_detectors x 3) of detector 3D coordinates [x, y, z]. 

112 sourceLabels : list[str] or None, default=None 

113 Optional list of source labels (e.g., ["S1", "S2", ...]). 

114 detectorLabels : list[str] or None, default=None 

115 Optional list of detector labels (e.g., ["D1", "D2", ...]). 

116 """ 

117 

118 wavelengths: np.ndarray 

119 sourcePos3D: np.ndarray 

120 detectorPos3D: np.ndarray 

121 sourceLabels: list[str] | None = None 

122 detectorLabels: list[str] | None = None 

123 

124 

125@dataclass(slots=True, frozen=True) 

126class Stim: 

127 """ 

128 Stimulus/event information following SNIRF specification. 

129 

130 Attributes 

131 ---------- 

132 name : str 

133 Name or identifier for the stimulus condition. 

134 data : np.ndarray 

135 1D array of stimulus onset times in seconds. 

136 """ 

137 

138 name: str 

139 data: np.ndarray 

140 # The following field may become necessary in the future is this tool 

141 # is extended to support .csv files that include pre- and post-rest periods. 

142 # dataLabels: list[str] | None = None 

143 

144 

145@dataclass(slots=True, frozen=True) 

146class Nirs: 

147 """ 

148 Complete NIRS dataset following SNIRF specification. 

149 

150 This is the top-level container for a complete NIRS measurement, 

151 including metadata, experimental data, probe geometry, and stimuli. 

152 

153 Attributes 

154 ---------- 

155 metadata : Metadata 

156 Metadata about the subject and measurement. 

157 data : list[Data] 

158 List of Data objects (in this package, it always contains one Data object). 

159 probe : Probe 

160 Probe geometry and configuration information. 

161 stim : list[Stim] or None, default=None 

162 Optional list of stimulus/event information. 

163 """ 

164 

165 metadata: Metadata 

166 data: list[Data] 

167 probe: Probe 

168 stim: list[Stim] | None = None