5757)
5858
5959# Kernel
60- kernel_path = testing_path / "SNIRF" / "Kernel" / "Flow50" / "Portal_2021_11"
61- kernel_hb = kernel_path / "hb.snirf"
62- kernel_td = kernel_path / "td_moments.snirf"
60+ kernel_flow1_path = testing_path / "SNIRF" / "Kernel" / "Flow50" / "Portal_2021_11"
61+ kernel_hb_old = kernel_flow1_path / "hb.snirf"
62+ kernel_td_moments_old = kernel_flow1_path / "td_moments.snirf"
63+ kernel_flow2_path = testing_path / "SNIRF" / "Kernel" / "Flow2" / "Portal_2024_10_23"
64+ kernel_td_gated = kernel_flow2_path / "c345d04_2.snirf" # Type 201 (TD Gated, 201)
65+ kernel_td_moments = kernel_flow2_path / "c345d04_3.snirf" # Type 202 (TD Moments, 301)
66+ kernel_hb = kernel_flow2_path / "c345d04_5.snirf" # Type 203 (Hb, 99999)
67+
6368
6469h5py = pytest .importorskip ("h5py" ) # module-level
6570
@@ -87,8 +92,13 @@ def _get_loc(raw, ch_name):
8792 nirx_nirsport2_103 ,
8893 nirx_nirsport2_103_2 ,
8994 nirx_nirsport2_103_2 ,
90- kernel_hb ,
91- kernel_td ,
95+ pytest .param (kernel_hb_old , id = f"kernel: { kernel_hb_old .stem } " ),
96+ pytest .param (
97+ kernel_td_moments_old , id = f"kernel: { kernel_td_moments_old .stem } "
98+ ),
99+ pytest .param (kernel_td_gated , id = f"kernel: { kernel_td_gated .stem } " ),
100+ pytest .param (kernel_td_moments , id = f"kernel: { kernel_td_moments .stem } " ),
101+ pytest .param (kernel_hb , id = f"kernel: { kernel_hb .stem } " ),
92102 lumo110 ,
93103 ]
94104 ),
@@ -97,15 +107,26 @@ def test_basic_reading_and_min_process(fname):
97107 """Test reading SNIRF files and minimum typical processing."""
98108 raw = read_raw_snirf (fname , preload = True )
99109 # SNIRF data can contain several types, so only apply appropriate functions
110+ kinds = [
111+ "fnirs_cw_amplitude" ,
112+ "fnirs_od" ,
113+ "fnirs_td_gated_amplitude" ,
114+ "fnirs_td_moments_intensity" ,
115+ "hbo" ,
116+ # TODO: add fd_*
117+ ]
118+ ch_types = raw .get_channel_types (unique = True )
119+ got_kinds = [kind for kind in kinds if kind in raw ]
120+ assert len (got_kinds ) == 1 , f"Need one data type, { got_kinds = } and { ch_types = } "
100121 if "fnirs_cw_amplitude" in raw :
101122 raw = optical_density (raw )
102- if "fnirs_od" in raw :
123+ elif "fnirs_od" in raw :
103124 raw = beer_lambert_law (raw , ppf = 6 )
104- if "fnirs_td_moments_intensity" in raw :
105- # TODO: Re-enable once types are triaged
106- # assert "fnirs_td_moments_mean" in raw
107- # assert "fnirs_td_moments_variance" in raw
125+ elif "fnirs_td_gated_amplitude" in raw :
108126 pass
127+ elif "fnirs_td_moments_intensity" in raw :
128+ assert "fnirs_td_moments_mean" in raw
129+ assert "fnirs_td_moments_variance" in raw
109130 else :
110131 assert "hbo" in raw
111132 assert "hbr" in raw
@@ -422,40 +443,80 @@ def test_snirf_fieldtrip_od():
422443
423444
424445@requires_testing_data
425- @pytest .mark .parametrize ("kind" , ("hb" , "td" ))
426- def test_snirf_kernel (kind ):
446+ @pytest .mark .parametrize (
447+ "kind, ver, shape, n_nan, fname" ,
448+ [
449+ pytest .param ("hb" , "new" , (4 , 38 ), 0 , kernel_hb , id = "hb" ),
450+ pytest .param ("hb" , "old" , (180 * 2 , 14 ), 20 , kernel_hb_old , id = "hb old" ),
451+ pytest .param (
452+ "td moments" , "new" , (12 , 38 ), 0 , kernel_td_moments , id = "td moments"
453+ ),
454+ pytest .param ("td gated" , "new" , (100 , 38 ), 0 , kernel_td_gated , id = "td gated" ),
455+ pytest .param (
456+ "td moments" ,
457+ "old" ,
458+ (1080 , 14 ),
459+ 60 ,
460+ kernel_td_moments_old ,
461+ id = "td moments old" ,
462+ ),
463+ ],
464+ )
465+ def test_snirf_kernel_basic (kind , ver , shape , n_nan , fname ):
427466 """Test reading Kernel SNIRF files with haemoglobin or TD data."""
428- fname = dict (hb = kernel_hb , td = kernel_td )[kind ]
429467 raw = read_raw_snirf (fname , preload = True )
430468 if kind == "hb" :
431469 # Test data import
432- assert raw ._data .shape == ( 180 * 2 , 14 )
470+ assert raw ._data .shape == shape
433471 hbo_data = raw .get_data ("hbo" )
434472 hbr_data = raw .get_data ("hbr" )
435- assert hbo_data .shape == hbr_data .shape == (180 , 14 )
473+ assert hbo_data .shape == hbr_data .shape == (shape [ 0 ] // 2 , shape [ 1 ] )
436474 hbo_norm = np .nanmedian (np .linalg .norm (hbo_data , axis = - 1 ))
437475 hbr_norm = np .nanmedian (np .linalg .norm (hbr_data , axis = - 1 ))
438- assert 1 < hbr_norm < hbo_norm < 3
439- n_nan = 20
476+ # TODO: Old file vs new file scaling, one is wrong!
477+ if ver == "new" :
478+ assert 1e-5 < hbr_norm < hbo_norm < 1e-4
479+ else :
480+ assert 1 < hbr_norm < 3
481+ elif kind == "td moments" :
482+ assert raw ._data .shape == shape
483+ n_ch = 0
484+ # TODO: Reasonable values here???
485+ lims = dict (intensity = (1e4 , 1e7 ), mean = (1e3 , 1e4 ), variance = (1e5 , 1e7 ))
486+ for key , val in lims .items ():
487+ data = raw .get_data (f"fnirs_td_moments_{ key } " )
488+ assert data .shape [1 ] == len (raw .times )
489+ norm = np .nanmedian (np .linalg .norm (data , axis = - 1 ))
490+ min_ , max_ = val
491+ assert min_ < norm < max_ , key
492+ n_ch += data .shape [0 ]
493+ assert raw ._data .shape [0 ] == len (raw .ch_names ) == n_ch
440494 else :
441- assert raw . _data . shape == ( 1080 , 14 )
442- data = raw . get_data ( "fnirs_td_moments_intensity" )
443- # TODO: This will need to update once we triage properly
444- assert data . shape == raw . _data . shape
445- norm = np . nanmedian ( np . linalg . norm ( data , axis = - 1 ))
446- assert 1e5 < norm < 1e6 # TODO: 429256, is this reasonable Molars!??
447- n_nan = 60
495+ pass # TODO: add some gated tests
496+ if ver == "old" :
497+ sfreq = 8.257638
498+ n_annot = 2
499+ else :
500+ sfreq = 3.759398
501+ n_annot = 8
448502
449- assert_allclose (raw .info ["sfreq" ], 8.257638 )
503+ assert_allclose (raw .info ["sfreq" ], sfreq , atol = 1e-5 )
450504
451505 bad_nans = np .isnan (raw .get_data ()).any (axis = 1 )
452506 assert np .sum (bad_nans ) == n_nan
453507
454- assert len (raw .annotations .description ) == 2
455- assert raw .annotations .onset [0 ] == 0.036939
456- assert raw .annotations .onset [1 ] == 0.874633
457- assert raw .annotations .description [0 ] == "StartTrial"
458- assert raw .annotations .description [1 ] == "StartIti"
508+ if n_annot == 2 :
509+ assert len (raw .annotations .description ) == n_annot
510+ assert raw .annotations .onset [0 ] == 0.036939
511+ assert raw .annotations .onset [1 ] == 0.874633
512+ assert raw .annotations .description [0 ] == "StartTrial"
513+ assert raw .annotations .description [1 ] == "StartIti"
514+ else :
515+ assert len (raw .annotations .description ) == n_annot
516+ assert raw .annotations .onset [0 ] == 4.988107
517+ assert raw .annotations .onset [1 ] == 5.988107
518+ assert raw .annotations .description [0 ] == "StartBlock"
519+ assert raw .annotations .description [1 ] == "StartTrial"
459520
460521
461522@requires_testing_data
0 commit comments