@@ -288,9 +288,16 @@ def natural_keys(text):
288288 "location information"
289289 )
290290
291+ # Uniform scale factor assumed here!
292+ snirf_data_unit = np .array (
293+ dat .get ("nirs/data1/measurementList1/dataUnit" , b"M" )
294+ )
295+ snirf_data_unit = snirf_data_unit .item ().decode ("utf-8" )
296+ scale = _get_dataunit_scaling (snirf_data_unit )
297+
291298 chnames = []
292299 ch_types = []
293- need_data_scale = False
300+ ch_cals = []
294301 for chan in channels :
295302 ch_root = f"nirs/data1/{ chan } "
296303 src_idx = int (
@@ -300,6 +307,7 @@ def natural_keys(text):
300307 _correct_shape (np .array (dat .get (f"{ ch_root } /detectorIndex" )))[0 ]
301308 )
302309 ch_name = f"{ sources [src_idx ]} _{ detectors [det_idx ]} "
310+ ch_cal = scale
303311
304312 if snirf_data_type in (
305313 SNIRF_CW_AMPLITUDE ,
@@ -324,7 +332,6 @@ def natural_keys(text):
324332 # append time delay
325333 ch_name = f"{ ch_name } bin{ fnirs_time_delays [bin_idx - 1 ]} "
326334 ch_type = "fnirs_td_gated_amplitude"
327- need_data_scale = True
328335 else :
329336 assert snirf_data_type == SNIRF_TD_MOMENTS_AMPLITUDE
330337 moment_idx = int (
@@ -340,8 +347,13 @@ def natural_keys(text):
340347 _TD_MOMENT_ORDER_MAP ,
341348 )
342349 ch_name = f"{ ch_name } moment{ order } "
343- ch_type = f"fnirs_td_moments_{ _TD_MOMENT_ORDER_MAP [order ]} "
344-
350+ kind = _TD_MOMENT_ORDER_MAP [order ]
351+ ch_type = f"fnirs_td_moments_{ kind } "
352+ if kind == "mean" :
353+ # Stored in picoseconds
354+ ch_cal = 1e-12
355+ elif kind == "variance" :
356+ ch_cal = 1e-24
345357 elif snirf_data_type == SNIRF_PROCESSED :
346358 dt_id = _correct_shape (
347359 np .array (dat .get (f"{ ch_root } /dataTypeLabel" ))
@@ -365,25 +377,18 @@ def natural_keys(text):
365377 f"HbO/HbR, but got type f{ dt_id } "
366378 )
367379 suffix = dt_id .lower ()
368- need_data_scale = True
369380 ch_name = f"{ ch_name } { suffix } "
370381 ch_type = dt_id
371382 chnames .append (ch_name )
372383 ch_types .append (ch_type )
373- del ch_root , ch_name , ch_type
384+ ch_cals .append (ch_cal )
385+ del ch_root , ch_name , ch_type , ch_cal
386+ del scale
374387
375388 # Create mne structure
376389 info = create_info (chnames , sampling_rate , ch_types = ch_types )
377-
378- if need_data_scale :
379- snirf_data_unit = np .array (
380- dat .get ("nirs/data1/measurementList1/dataUnit" , b"M" )
381- )
382- snirf_data_unit = snirf_data_unit .item ().decode ("utf-8" )
383- scale = _get_dataunit_scaling (snirf_data_unit ) # " " or "M")
384- if scale is not None :
385- for ch in info ["chs" ]:
386- ch ["cal" ] = scale
390+ for ch , ch_cal in zip (info ["chs" ], ch_cals ):
391+ ch ["cal" ] = ch_cal
387392
388393 subject_info = {}
389394 names = np .array (dat .get ("nirs/metaDataTags/SubjectID" ))
@@ -417,8 +422,8 @@ def natural_keys(text):
417422 length_unit = _get_metadata_str (dat , "LengthUnit" )
418423 length_scaling = _get_lengthunit_scaling (length_unit )
419424
420- srcPos3D / = length_scaling
421- detPos3D / = length_scaling
425+ srcPos3D * = length_scaling
426+ detPos3D * = length_scaling
422427
423428 if optode_frame in ["mri" , "meg" ]:
424429 # These are all in MNI or MEG coordinates, so let's transform
@@ -651,7 +656,7 @@ def _get_timeunit_scaling(time_unit):
651656
652657def _get_lengthunit_scaling (length_unit ):
653658 """MNE expects distance in m, return required scaling."""
654- scalings = {"m" : 1 , "cm" : 100 , "mm" : 1000 }
659+ scalings = {"m" : 1.0 , "cm" : 1e-2 , "mm" : 1e-3 }
655660 if length_unit in scalings :
656661 return scalings [length_unit ]
657662 else :
@@ -664,7 +669,7 @@ def _get_lengthunit_scaling(length_unit):
664669
665670def _get_dataunit_scaling (hbx_unit ):
666671 """MNE expects hbo/hbr in M, return required scaling."""
667- scalings = {"M" : None , "uM" : 1e-6 }
672+ scalings = {"M" : 1.0 , "uM" : 1e-6 , "" : 1.0 }
668673 try :
669674 return scalings [hbx_unit ]
670675 except KeyError :
0 commit comments