NeuroAnalyzer tutorials: NIRS

Load NIRS data:

using NeuroAnalyzer
n = import_nirs("files/fnirs.nirs");
info(n)
[ Info: Imported: NIRS (12 × 9015 × 1; 359.98 s)
              Data type: NIRS
            File format: NIRS
            Source file: files/fnirs.nirs
         File size [MB]: 0.72
       Memory size [MB]: 0.9
                Subject:  
              Recording: 
        Recording notes: 
         Recording date: 
         Recording time: 
     Sampling rate (Hz): 25
Signal length [samples]: 9015
Signal length [seconds]: 360.6
     Number of channels: 12
              Epochs ID: 
       Number of epochs: 1
 Epoch length [samples]: 9015
 Epoch length [seconds]: 360.6
        Wavelength [nm]: [690.0, 830.0]
                Markers: no
      Channel locations: yes
             Components: no
Number of NIRS channels: 12

Channels:
 ch     label           type        unit    wavelength
 ------ --------------- ----------- ------- ------------
 1      S1_D1 690       NIRS_INT    V       690.0   
 2      S1_D2 690       NIRS_INT    V       690.0   
 3      S1_D1 830       NIRS_INT    V       830.0   
 4      S1_D2 830       NIRS_INT    V       830.0   
 5      AUX1            NIRS_AUX    
 6      AUX2            NIRS_AUX    
 7      AUX3            NIRS_AUX    
 8      AUX4            NIRS_AUX    
 9      AUX5            NIRS_AUX    
 10     AUX6            NIRS_AUX    
 11     AUX7            NIRS_AUX    
 12     AUX8            NIRS_AUX    

Load SNIRF data:

n = import_snirf("files/fnirs.snirf");
info(n)
[ Info: Imported: NIRS (72 × 500 × 1; 9.98 s)
              Data type: NIRS
            File format: SNIRF
            Source file: files/fnirs.snirf
         File size [MB]: 1.91
       Memory size [MB]: 0.29
                Subject: default:  
              Recording: 
        Recording notes: 
         Recording date: 2022-03-03
         Recording time: 12:03:48
     Sampling rate (Hz): 50
Signal length [samples]: 500
Signal length [seconds]: 10.0
     Number of channels: 72
              Epochs ID: 
       Number of epochs: 1
 Epoch length [samples]: 500
 Epoch length [seconds]: 10.0
        Wavelength [nm]: [760.0, 850.0]
                Markers: yes
      Channel locations: yes
             Components: no
Number of NIRS channels: 72

Channels:
 ch     label           type        unit    wavelength
 ------ --------------- ----------- ------- ------------
 1      S2_D1 760       NIRS_OD     V       760.0   
 2      S4_D1 760       NIRS_OD     V       760.0   
 3      S1_D1 760       NIRS_OD     V       760.0   
 4      S4_D2 760       NIRS_OD     V       760.0   
 5      S6_D2 760       NIRS_OD     V       760.0   
 6      S3_D2 760       NIRS_OD     V       760.0   
 7      S2_D3 760       NIRS_OD     V       760.0   
 8      S4_D3 760       NIRS_OD     V       760.0   
 9      S7_D3 760       NIRS_OD     V       760.0   
 10     S5_D3 760       NIRS_OD     V       760.0   
 11     S4_D4 760       NIRS_OD     V       760.0   
 12     S6_D4 760       NIRS_OD     V       760.0   
 13     S7_D4 760       NIRS_OD     V       760.0   
 14     S8_D4 760       NIRS_OD     V       760.0   
 15     S10_D5 760      NIRS_OD     V       760.0   
 16     S9_D5 760       NIRS_OD     V       760.0   
 17     S12_D6 760      NIRS_OD     V       760.0   
 18     S14_D6 760      NIRS_OD     V       760.0   
 19     S11_D6 760      NIRS_OD     V       760.0   
 20     S10_D7 760      NIRS_OD     V       760.0   
 21     S15_D7 760      NIRS_OD     V       760.0   
 22     S13_D7 760      NIRS_OD     V       760.0   
 23     S12_D8 760      NIRS_OD     V       760.0   
 24     S14_D8 760      NIRS_OD     V       760.0   
 25     S16_D8 760      NIRS_OD     V       760.0   
 26     S17_D9 760      NIRS_OD     V       760.0   
 27     S18_D9 760      NIRS_OD     V       760.0   
 28     S21_D9 760      NIRS_OD     V       760.0   
 29     S17_D10 760     NIRS_OD     V       760.0   
 30     S18_D10 760     NIRS_OD     V       760.0   
 31     S23_D10 760     NIRS_OD     V       760.0   
 32     S19_D11 760     NIRS_OD     V       760.0   
 33     S22_D11 760     NIRS_OD     V       760.0   
 34     S19_D12 760     NIRS_OD     V       760.0   
 35     S20_D12 760     NIRS_OD     V       760.0   
 36     S24_D12 760     NIRS_OD     V       760.0   
 37     S2_D1 850       NIRS_OD     V       850.0   
 38     S4_D1 850       NIRS_OD     V       850.0   
 39     S1_D1 850       NIRS_OD     V       850.0   
 40     S4_D2 850       NIRS_OD     V       850.0   
 41     S6_D2 850       NIRS_OD     V       850.0   
 42     S3_D2 850       NIRS_OD     V       850.0   
 43     S2_D3 850       NIRS_OD     V       850.0   
 44     S4_D3 850       NIRS_OD     V       850.0   
 45     S7_D3 850       NIRS_OD     V       850.0   
 46     S5_D3 850       NIRS_OD     V       850.0   
 47     S4_D4 850       NIRS_OD     V       850.0   
 48     S6_D4 850       NIRS_OD     V       850.0   
 49     S7_D4 850       NIRS_OD     V       850.0   
 50     S8_D4 850       NIRS_OD     V       850.0   
 51     S10_D5 850      NIRS_OD     V       850.0   
 52     S9_D5 850       NIRS_OD     V       850.0   
 53     S12_D6 850      NIRS_OD     V       850.0   
 54     S14_D6 850      NIRS_OD     V       850.0   
 55     S11_D6 850      NIRS_OD     V       850.0   
 56     S10_D7 850      NIRS_OD     V       850.0   
 57     S15_D7 850      NIRS_OD     V       850.0   
 58     S13_D7 850      NIRS_OD     V       850.0   
 59     S12_D8 850      NIRS_OD     V       850.0   
 60     S14_D8 850      NIRS_OD     V       850.0   
 61     S16_D8 850      NIRS_OD     V       850.0   
 62     S17_D9 850      NIRS_OD     V       850.0   
 63     S18_D9 850      NIRS_OD     V       850.0   
 64     S21_D9 850      NIRS_OD     V       850.0   
 65     S17_D10 850     NIRS_OD     V       850.0   
 66     S18_D10 850     NIRS_OD     V       850.0   
 67     S23_D10 850     NIRS_OD     V       850.0   
 68     S19_D11 850     NIRS_OD     V       850.0   
 69     S22_D11 850     NIRS_OD     V       850.0   
 70     S19_D12 850     NIRS_OD     V       850.0   
 71     S20_D12 850     NIRS_OD     V       850.0   
 72     S24_D12 850     NIRS_OD     V       850.0   

View optode locations:

plot_locs(n, ch="all", src_labels=false, det_labels=false, opt_labels=false, head=false)

(!) Red (or black in monochrome mode) optodes represent sources, green (white) optodes are detectors.

Get wavelengths:

n.header.recording[:wavelengths]
2-element Vector{Float64}:
 760.0
 850.0

Get channel of 760 or 850 nm wavelength:

ch760 = get_channel(n, ch=get_channel(n, wl=760))
ch850 = get_channel(n, ch=get_channel(n, wl=850))
36-element Vector{Int64}:
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
  ⋮
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72

Get data associated with these channels:

d760 = n.data[ch760, :, :]
d850 = n.data[ch850, :, :]
36×500×1 Array{Float64, 3}:
[:, :, 1] =
 4.81625  1.2555   1.25525  1.25525  …  1.2635   1.2635   1.26375  1.264
 4.81625  1.105    1.105    1.10475     1.0925   1.092    1.0915   1.09125
 4.81625  1.4645   1.46425  1.46425     1.47075  1.47075  1.471    1.47125
 4.81625  1.8875   1.887    1.887       1.8895   1.89     1.89     1.8905
 4.81625  0.9755   0.97525  0.975       0.9775   0.97725  0.97725  0.97725
 4.81625  1.046    1.046    1.04575  …  1.03925  1.039    1.03875  1.039
 4.81625  1.1375   1.1375   1.1375      1.12875  1.12875  1.1285   1.1285
 4.81625  1.936    1.9355   1.9355      1.9345   1.9345   1.9345   1.935
 4.81625  1.25925  1.25925  1.259       1.2435   1.2435   1.24325  1.24325
 4.81625  1.23375  1.2335   1.23325     1.22525  1.22475  1.2245   1.2245
 4.81625  0.93625  0.936    0.93575  …  0.9195   0.91875  0.91825  0.91775
 4.81625  1.50075  1.5005   1.50025     1.50175  1.50175  1.50175  1.50175
 4.81625  2.0225   2.0225   2.02175     2.00475  2.004    2.00475  2.00475
 ⋮                                   ⋱                             
 4.81625  0.98325  0.983    0.983       0.967    0.967    0.967    0.967
 4.81625  0.9285   0.928    0.92725  …  0.8855   0.88525  0.88475  0.88425
 4.81625  0.452    0.4515   0.45075     0.43725  0.43675  0.43625  0.43575
 4.81625  0.27875  0.27875  0.27875     0.27525  0.275    0.27475  0.27475
 4.81625  0.84575  0.845    0.84425     0.7775   0.77725  0.77725  0.777
 4.81625  0.66325  0.66275  0.66225     0.64425  0.64375  0.64325  0.643
 4.81625  1.2735   1.2735   1.27325  …  1.2655   1.2655   1.2655   1.26525
 4.81625  1.16825  1.168    1.168       1.12325  1.123    1.1225   1.122
 4.81625  1.14825  1.14825  1.14825     1.13725  1.137    1.13675  1.13625
 4.81625  1.247    1.24675  1.2465      1.207    1.2065   1.206    1.2055
 4.81625  1.15625  1.156    1.15575     1.11625  1.11575  1.11525  1.1145
 4.81625  1.63575  1.63575  1.63525  …  1.625    1.6245   1.62425  1.62375

Convert RAW intensity to OD (optical density):

n = import_nirs("files/fnirs.nirs");
info(n)
[ Info: Imported: NIRS (12 × 9015 × 1; 359.98 s)
              Data type: NIRS
            File format: NIRS
            Source file: files/fnirs.nirs
         File size [MB]: 0.72
       Memory size [MB]: 0.9
                Subject:  
              Recording: 
        Recording notes: 
         Recording date: 
         Recording time: 
     Sampling rate (Hz): 25
Signal length [samples]: 9015
Signal length [seconds]: 360.6
     Number of channels: 12
              Epochs ID: 
       Number of epochs: 1
 Epoch length [samples]: 9015
 Epoch length [seconds]: 360.6
        Wavelength [nm]: [690.0, 830.0]
                Markers: no
      Channel locations: yes
             Components: no
Number of NIRS channels: 12

Channels:
 ch     label           type        unit    wavelength
 ------ --------------- ----------- ------- ------------
 1      S1_D1 690       NIRS_INT    V       690.0   
 2      S1_D2 690       NIRS_INT    V       690.0   
 3      S1_D1 830       NIRS_INT    V       830.0   
 4      S1_D2 830       NIRS_INT    V       830.0   
 5      AUX1            NIRS_AUX    
 6      AUX2            NIRS_AUX    
 7      AUX3            NIRS_AUX    
 8      AUX4            NIRS_AUX    
 9      AUX5            NIRS_AUX    
 10     AUX6            NIRS_AUX    
 11     AUX7            NIRS_AUX    
 12     AUX8            NIRS_AUX    
intensity2od!(n)
info(n)
              Data type: NIRS
            File format: NIRS
            Source file: files/fnirs.nirs
         File size [MB]: 0.72
       Memory size [MB]: 1.18
                Subject:  
              Recording: 
        Recording notes: 
         Recording date: 
         Recording time: 
     Sampling rate (Hz): 25
Signal length [samples]: 9015
Signal length [seconds]: 360.6
     Number of channels: 16
              Epochs ID: 
       Number of epochs: 1
 Epoch length [samples]: 9015
 Epoch length [seconds]: 360.6
        Wavelength [nm]: [690.0, 830.0]
                Markers: no
      Channel locations: yes
             Components: no
Number of NIRS channels: 16

Channels:
 ch     label           type        unit    wavelength
 ------ --------------- ----------- ------- ------------
 1      S1_D1 690       NIRS_INT    V       690.0   
 2      S1_D2 690       NIRS_INT    V       690.0   
 3      S1_D1 830       NIRS_INT    V       830.0   
 4      S1_D2 830       NIRS_INT    V       830.0   
 5      S1_D1 690 OD    NIRS_OD     V       690.0   
 6      S1_D2 690 OD    NIRS_OD     V       690.0   
 7      S1_D1 830 OD    NIRS_OD     V       830.0   
 8      S1_D2 830 OD    NIRS_OD     V       830.0   
 9      AUX1            NIRS_AUX    
 10     AUX2            NIRS_AUX    
 11     AUX3            NIRS_AUX    
 12     AUX4            NIRS_AUX    
 13     AUX5            NIRS_AUX    
 14     AUX6            NIRS_AUX    
 15     AUX7            NIRS_AUX    
 16     AUX8            NIRS_AUX    

(!) OD channels will be added to the object as nirs_od channel type. OD channels will be placed after RAW (intensity channels) and before other channels.

Convert OD (optical density) to hemoglobin concentration:

od2conc!(n)
info(n)
              Data type: NIRS
            File format: NIRS
            Source file: files/fnirs.nirs
         File size [MB]: 0.72
       Memory size [MB]: 1.59
                Subject:  
              Recording: 
        Recording notes: 
         Recording date: 
         Recording time: 
     Sampling rate (Hz): 25
Signal length [samples]: 9015
Signal length [seconds]: 360.6
     Number of channels: 22
              Epochs ID: 
       Number of epochs: 1
 Epoch length [samples]: 9015
 Epoch length [seconds]: 360.6
        Wavelength [nm]: [690.0, 830.0]
                Markers: no
      Channel locations: yes
             Components: no
Number of NIRS channels: 22

Channels:
 ch     label           type        unit    wavelength
 ------ --------------- ----------- ------- ------------
 1      S1_D1 690       NIRS_INT    V       690.0   
 2      S1_D2 690       NIRS_INT    V       690.0   
 3      S1_D1 830       NIRS_INT    V       830.0   
 4      S1_D2 830       NIRS_INT    V       830.0   
 5      S1_D1 690 OD    NIRS_OD     V       690.0   
 6      S1_D2 690 OD    NIRS_OD     V       690.0   
 7      S1_D1 830 OD    NIRS_OD     V       830.0   
 8      S1_D2 830 OD    NIRS_OD     V       830.0   
 9      AUX1            NIRS_AUX    
 10     AUX2            NIRS_AUX    
 11     AUX3            NIRS_AUX    
 12     AUX4            NIRS_AUX    
 13     AUX5            NIRS_AUX    
 14     AUX6            NIRS_AUX    
 15     AUX7            NIRS_AUX    
 16     AUX8            NIRS_AUX    
 17     S1_D1 HbO       NIRS_HBO    
 18     S1_D1 HbR       NIRS_HBR    
 19     S1_D1 HbT       NIRS_HBT    
 20     S1_D2 HbO       NIRS_HBO    
 21     S1_D2 HbR       NIRS_HBR    
 22     S1_D2 HbT       NIRS_HBT    

(!) For each channel three channels will be added: nirs_hbo (oxygenated hemoglobin), nirs_hbr (deoxgenated hemoglobin) and nirs_hbt (total hemoglobin). The sequence of added channels is: ch1 HbO, ch1 HbR, ch1 HbT, ch2 HbO, ch2 HbR, ch2 HbT etc.

(!) It is recommended to run a band-pass filter prior to calculating Hb concentration:

n = import_nirs("files/fnirs.nirs");
intensity2od!(n)
[ Info: Imported: NIRS (12 × 9015 × 1; 359.98 s)

OD of channel 1:

ch1_od = n.data[5, :, :]
9015×1 Matrix{Float64}:
 -0.0005150299141518043
  0.0010209688274578903
 -0.002445900500786136
 -0.0052140011428542495
 -0.008772120789647224
 -0.010092098928011477
 -0.008707687021497932
 -0.006070397302632848
 -0.004462030215970816
 -0.006320714237476389
 -0.009778359554364867
 -0.012116968545753415
 -0.011169325736148709
  ⋮
  0.022383449987165117
  0.023243333582738144
  0.026777728371919527
  0.027705172813399886
  0.0284731365000764
  0.02903944991903703
  0.02833334151231847
  0.03368347704639658
  0.04037981487859521
  0.04240412723556646
  0.044218836966165624
  0.042366900503228146
NeuroAnalyzer.filter!(n, ch="all", fprototype=:fir, ftype=:bp, cutoff=(0.01, 10))
od2conc!(n)
[ Info: Signal should be tapered prior to filtering to reduce edge artifacts
[ Info: Creating BP filter:
[ Info:  Using default window: hamming(2)
[ Info:  Attenuation: 16 dB
[ Info:  Transition bandwidth: 0.4156 Hz
[ Info:  F1_stop: -0.1898 Hz
[ Info:  F1_pass: 0.01 Hz
[ Info:  Cutoff frequency: -0.1978 Hz
[ Info:  F2_pass: 10 Hz
[ Info:  F2_stop: 10.1998 Hz
[ Info:  Cutoff frequency: 10.2078 Hz

HbO, HbR, HbT of channel 1:

labels(n)[17:22]
n.header.recording[:channel_type][17:22]
ch1_od = n.data[17:22, :, :]
6×9015×1 Array{Float64, 3}:
[:, :, 1] =
 -132.676   -132.397   -136.272   -141.853   …  129.526   132.831   135.192
   25.2166    26.7194    23.9568    22.2336      17.8564   19.0548   16.7195
 -107.46    -105.678   -112.315   -119.62       147.382   151.885   151.911
   40.7612    35.1063    36.4021    26.8672      91.334    91.2172   85.1749
  124.74     127.68     123.276    121.35       -14.277   -12.6902  -15.7291
  165.502    162.786    159.678    148.217   …   77.0569   78.527    69.4458

Plot channels:

NeuroAnalyzer.plot(n, ch="all")

Plot Hb concentrations:

p1 = NeuroAnalyzer.plot(n, ch=["S1_D1 HbO", "S1_D2 HbO"], type=:butterfly, seg=(0, 30), title="HbO", ylabel="HbO [μM/mm]", xlabel="")
p2 = NeuroAnalyzer.plot(n, ch=["S1_D1 HbR", "S1_D2 HbR"], type=:butterfly, seg=(0, 30), title="HbR", ylabel="HbR [μM/mm]", xlabel="")
p3 = NeuroAnalyzer.plot(n, ch=["S1_D1 HbT", "S1_D2 HbT"], type=:butterfly, seg=(0, 30), title="HbT", ylabel="HbT [μM/mm]")
Plots.plot(p1, p2, p3, layout=(3,1), legend=:outertopright)