diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..50b6fb3 --- /dev/null +++ b/404.html @@ -0,0 +1,653 @@ + + + + + + + + + + + + + + + + + + + + + + openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API_analysis/index.html b/API_analysis/index.html new file mode 100644 index 0000000..b9a0058 --- /dev/null +++ b/API_analysis/index.html @@ -0,0 +1,1888 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + analysis - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

analysis

+ +

Description

+

This module contains all the functions used to analyse the MUs properties when +not involving the MUs action potential shape.

+


+ + +
+ + + +

+compute_thresholds(emgfile, event_='rt_dert', type_='abs_rel', mvc=0) + +

+ + +
+ +

Calculates recruitment/derecruitment thresholds.

+

Values are calculated both in absolute and relative therms.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
event_ +
+

When to calculate the thresholds.

+

rt_dert +Both recruitment and derecruitment tresholds will be calculated. +rt +Only recruitment tresholds will be calculated. +dert +Only derecruitment tresholds will be calculated.

+
+

+ + TYPE: + str {"rt_dert", "rt", "dert"} + + + DEFAULT: + "rt_dert" + +

+
type_ +
+

The tipe of value to calculate.

+

abs_rel +Both absolute and relative tresholds will be calculated. +rel +Only relative tresholds will be calculated. +abs +Only absolute tresholds will be calculated.

+
+

+ + TYPE: + str {"abs_rel", "rel", "abs"} + + + DEFAULT: + "abs_rel" + +

+
mvc +
+

The maximum voluntary contraction (MVC). +if mvc is 0, the user is asked to input MVC; otherwise, the value +passed is used.

+
+

+ + TYPE: + float + + + DEFAULT: + 0 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ mus_thresholds + +
+

A DataFrame containing the requested thresholds.

+
+

+ + TYPE: + pd.DataFrame + +

+
+

See also

+
    +
  • compute_dr : calculate the discharge rate.
  • +
  • basic_mus_properties : calculate basic MUs properties on a trapezoidal + contraction.
  • +
  • compute_covisi : calculate the coefficient of variation of interspike + interval.
  • +
  • compute_drvariability : claculate the DR variability.
  • +
+ +

Examples:

+

Load the EMG file and compute the thresholds.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> mus_thresholds = emg.compute_thresholds(
+...     emgfile=emgfile,
+...     event_="rt_dert",
+... )
+>>> mus_thresholds
+       abs_RT    abs_DERT     rel_RT   rel_DERT
+0  160.148294  137.682351  18.665302  16.046894
+1   39.138554   49.860936   4.561603   5.811298
+2   88.155160   95.133218  10.274494  11.087788
+3   37.776982   41.010716   4.402912   4.779804
+
+

Type of output can be adjusted, e.g., to have only absolute values at +recruitment.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> mus_thresholds = emg.compute_thresholds(
+...     emgfile=emgfile,
+...     event_="rt",
+...     type_="abs",
+... )
+>>> mus_thresholds
+       abs_RT
+0  160.148294
+1   39.138554
+2   88.155160
+3   37.776982
+
+ +
+ +


+ + +
+ + + +

+compute_dr(emgfile, n_firings_RecDerec=4, n_firings_steady=10, start_steady=-1, end_steady=-1, event_='rec_derec_steady') + +

+ + +
+ +

Calculate the discharge rate (DR).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
n_firings_RecDerec +
+

The number of firings at recruitment and derecruitment to consider for +the calculation of the DR.

+
+

+ + TYPE: + int + + + DEFAULT: + 4 + +

+
n_firings_steady +
+

The number of firings to consider for the calculation of the DR at the +start and at the end +of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + 10 + +

+
start_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
end_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
event_ +
+

When to calculate the DR.

+

rec_derec_steady +DR is calculated at recruitment, derecruitment and during the +steady-state phase. +rec +DR is calculated at recruitment. +derec +DR is calculated at derecruitment. +rec_derec +DR is calculated at recruitment and derecruitment. +steady +DR is calculated during the steady-state phase.

+
+

+ + TYPE: + str {"rec_derec_steady", "rec", "derec", "rec_derec", "steady"} + + + DEFAULT: + "rec_derec_steady" + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ mus_dr + +
+

A pd.DataFrame containing the requested DR.

+
+

+ + TYPE: + pd.DataFrame + +

+
+ + + + + + + + + + + + + + +
WARNSDESCRIPTION
+ + warning + + +
+

When calculation of DR at rec/derec fails due to not enough firings.

+
+
+

See also

+
    +
  • compute_thresholds : calculates recruitment/derecruitment thresholds.
  • +
  • basic_mus_properties : calculate basic MUs properties on a trapezoidal + contraction.
  • +
  • compute_covisi : calculate the coefficient of variation of interspike + interval.
  • +
  • compute_drvariability : claculate the DR variability.
  • +
+

Notes

+

DR for all the contraction is automatically calculated and returned.

+ +

Examples:

+

Load the EMG file and compute the DR.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> mus_dr = emg.compute_dr(emgfile=emgfile)
+>>> mus_dr
+     DR_rec  DR_derec  DR_start_steady  DR_end_steady  DR_all_steady     DR_all
+0  5.701081  4.662196         7.321255       6.420720       6.907559   6.814342
+1  7.051127  6.752467        14.919066      10.245462      11.938671  11.683134
+2  6.101529  4.789000         7.948740       6.133345       7.695189   8.055731
+3  6.345692  5.333535        11.121785       9.265212      11.544140  11.109796
+
+

Type of output can be adjusted, e.g., to have only the DR at recruitment.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> mus_dr = emg.compute_dr(emgfile=emgfile, event_="rec")
+>>> mus_dr
+     DR_rec     DR_all
+0  5.701081   6.814342
+1  7.051127  11.683134
+2  6.101529   8.055731
+3  6.345692  11.109796
+
+

The manual selection of the steady state phase can be bypassed +if previously calculated with an automated method.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> mus_dr = emg.compute_dr(
+...     emgfile=emgfile,
+...     start_steady=20000,
+...     end_steady=50000,
+...     event_="steady",
+... )
+>>> mus_dr
+   DR_start_steady  DR_end_steady  DR_all_steady     DR_all
+0         7.476697       6.271750       6.794170   6.814342
+1        14.440561      10.019572      11.822081  11.683134
+2         7.293547       5.846093       7.589531   8.055731
+3        13.289651       9.694317      11.613640  11.109796
+
+ +
+ +


+ + +
+ + + +

+basic_mus_properties(emgfile, n_firings_RecDerec=4, n_firings_steady=10, start_steady=-1, end_steady=-1, mvc=0) + +

+ + +
+ +

Calculate basic MUs properties on a trapezoidal contraction.

+

The function is meant to be used on trapezoidal contractions and +calculates: +the absolute/relative recruitment/derecruitment thresholds, +the discharge rate at recruitment, derecruitment, during the steady-state +phase and during the entire contraction, +the coefficient of variation of interspike interval, +the coefficient of variation of force signal.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
n_firings_RecDerec +
+

The number of firings at recruitment and derecruitment to consider for +the calculation of the DR.

+
+

+ + TYPE: + int + + + DEFAULT: + 4 + +

+
n_firings_steady +
+

The number of firings to consider for the calculation of the DR at the +start and at the end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + 10 + +

+
start_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
end_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
mvc +
+

The maximum voluntary contraction (MVC). It is suggest to report +MVC in Newton (N). If 0 (default), the user will be asked to imput it +manually. Otherwise, the passed value will be used.

+
+

+ + TYPE: + float + + + DEFAULT: + 0 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ exportable_df + +
+

A pd.DataFrame containing the results of the analysis.

+
+

+ + TYPE: + pd.DataFrame + +

+
+

See also

+
    +
  • compute_thresholds : calculates recruitment/derecruitment thresholds.
  • +
  • compute_dr : calculate the discharge rate.
  • +
  • compute_covisi : calculate the coefficient of variation of interspike + interval.
  • +
  • compute_drvariability : claculate the DR variability.
  • +
+ +

Examples:

+

Get full summary of all the MUs properties.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> df = emg.basic_mus_properties(emgfile=emgfile)
+>>> df
+     MVC  MU_number      abs_RT    abs_DERT     rel_RT   rel_DERT    DR_rec  DR_derec  DR_start_steady  DR_end_steady  DR_all_steady     DR_all  COVisi_steady  COVisi_all  COV_steady
+0  786.0          1  146.709276  126.128587  18.665302  16.046894  5.701081  4.662196         7.467810       6.242360       6.902616   6.814342      11.296316   16.309681    1.423286
+1    NaN          2   35.854200   45.676801   4.561603   5.811298  7.051127  6.752467        11.798908       9.977337      11.784061  11.683134      15.871254   21.233615         NaN
+2    NaN          3   80.757524   87.150011  10.274494  11.087788  6.101529  4.789000         7.940926       5.846093       7.671361   8.055731      35.755090   35.308650         NaN
+3    NaN          4   34.606886   37.569257   4.402912   4.779804  6.345692  5.333535        11.484875       9.636914      11.594712  11.109796      24.611246   29.372524         NaN
+
+

We can bypass manual prompting the MVC by pre-specifying it and/or +bypass the manual selection of the steady state phase if previously +calculated with an automated method.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> df = emg.basic_mus_properties(
+...     emgfile=emgfile,
+...     start_steady=20000,
+...     end_steady=50000,
+...     mvc=786,
+... )
+>>> df
+     MVC  MU_number      abs_RT    abs_DERT     rel_RT   rel_DERT    DR_rec  DR_derec  DR_start_steady  DR_end_steady  DR_all_steady     DR_all  COVisi_steady  COVisi_all  COV_steady
+0  786.0          1  146.709276  126.128587  18.665302  16.046894  5.701081  4.662196         7.476697       6.271750       6.794170   6.814342      11.066966   16.309681    1.431752
+1    NaN          2   35.854200   45.676801   4.561603   5.811298  7.051127  6.752467        14.440561      10.019572      11.822081  11.683134      15.076819   21.233615         NaN
+2    NaN          3   80.757524   87.150011  10.274494  11.087788  6.101529  4.789000         7.293547       5.846093       7.589531   8.055731      36.996894   35.308650         NaN
+3    NaN          4   34.606886   37.569257   4.402912   4.779804  6.345692  5.333535        13.289651       9.694317      11.613640  11.109796      26.028689   29.372524         NaN
+
+ +
+ +


+ + +
+ + + +

+compute_covisi(emgfile, n_firings_RecDerec=4, start_steady=-1, end_steady=-1, event_='rec_derec_steady', single_mu_number=-1) + +

+ + +
+ +

Calculate theCOVisi.

+

This function calculates the coefficient of variation of interspike +interval (COVisi).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
n_firings_RecDerec +
+

The number of firings at recruitment and derecruitment to consider for +the calculation of the COVisi.

+
+

+ + TYPE: + int + + + DEFAULT: + 4 + +

+
start_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
end_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
event_ +
+

When to calculate the COVisi.

+

rec_derec_steady +covisi is calculated at recruitment, derecruitment and during +the steady-state phase. +rec +covisi is calculated at recruitment. +derec +covisi is calculated at derecruitment. +rec_derec +covisi is calculated at recruitment and derecruitment. +steady +covisi is calculated during the steady-state phase.

+
+

+ + TYPE: + str {"rec_derec_steady", "rec", "derec", "rec_derec", "steady"} + + + DEFAULT: + "rec_derec_steady" + +

+
single_mu_number +
+

Number of the specific MU to compute the COVisi. +If single_mu_number >= 0, only the COVisi of the entire contraction +will be returned. If -1 (default), COVisi will be calculated for all +the MUs.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ covisi + +
+

A pd.DataFrame containing the requested COVisi.

+
+

+ + TYPE: + pd.DataFrame + +

+
+

See also

+
    +
  • compute_thresholds : calculates recruitment/derecruitment thresholds.
  • +
  • compute_dr : calculate the discharge rate.
  • +
  • basic_mus_properties : calculate basic MUs properties on a trapezoidal + contraction.
  • +
  • compute_drvariability : claculate the DR variability.
  • +
+

Notes

+

COVisi for all the contraction is automatically calculated and returned.

+ +

Examples:

+

Compute covisi during the various parts of the trapezoidal contraction.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> df = emg.compute_covisi(emgfile=emgfile)
+>>> df
+   COVisi_rec  COVisi_derec  COVisi_steady  COVisi_all
+0    8.600651     24.007405      11.230602   16.309681
+1   46.874208     19.243432      16.657603   21.233615
+2   32.212757     18.642514      35.421124   35.308650
+3   62.995864     13.080768      24.966372   29.372524
+
+

If the steady-state phase has been pre-identified, the manual selection +of the area can be bypassed.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> df = emg.compute_covisi(
+...     emgfile=emgfile,
+...     event_="rec_derec",
+...     start_steady=20000,
+...     end_steady=50000,
+... )
+>>> df
+   COVisi_rec  COVisi_derec  COVisi_all
+0    8.600651     24.007405   16.309681
+1   46.874208     19.243432   21.233615
+2   32.212757     18.642514   35.308650
+3   62.995864     13.080768   29.372524
+
+

To access the covisi of the entire contraction of a single MU.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> df = emg.compute_covisi(emgfile=emgfile, single_mu_number=2)
+>>> df
+   COVisi_all
+0    35.30865
+
+ +
+ +


+ + +
+ + + +

+compute_drvariability(emgfile, n_firings_RecDerec=4, start_steady=-1, end_steady=-1, event_='rec_derec_steady') + +

+ + +
+ +

Claculate the DR variability.

+

This function calculates the variability (as the coefficient of variation) +of the instantaneous discharge rate (DR) at recruitment, derecruitment, +during the steady-state phase and during all the contraction.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
n_firings_RecDerec +
+

The number of firings at recruitment and derecruitment to consider for +the calculation of the DR variability.

+
+

+ + TYPE: + int + + + DEFAULT: + 4 + +

+
start_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
end_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
event_ +
+

When to calculate the DR variability.

+

rec_derec_steady +DR variability is calculated at recruitment, derecruitment and +during the steady-state phase. +rec +DR variability is calculated at recruitment. +derec +DR variability is calculated at derecruitment. +rec_derec +DR variability is calculated at recruitment and derecruitment. +steady +DR variability is calculated during the steady-state phase.

+
+

+ + TYPE: + str {"rec_derec_steady", "rec", "derec", "rec_derec", "steady"} + + + DEFAULT: + "rec_derec_steady" + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ drvariability + +
+

A pd.DataFrame containing the requested DR variability.

+
+

+ + TYPE: + pd.DataFrame + +

+
+

See also

+
    +
  • compute_thresholds : calculates recruitment/derecruitment thresholds.
  • +
  • compute_dr : calculate the discharge rate.
  • +
  • basic_mus_properties : calculate basic MUs properties on a trapezoidal + contraction.
  • +
  • compute_covisi : calculate the coefficient of variation of interspike + interval.
  • +
+

Notes

+

DR variability for all the contraction is automatically calculated and +returned.

+ +

Examples:

+

Compute covisi during the various parts of the trapezoidal contraction.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> df = emg.compute_covisi(emgfile=emgfile)
+>>> df
+   DRvar_rec  DRvar_derec  DRvar_steady  DRvar_all
+0   8.560971    21.662783     11.051780  13.937779
+1  36.934213    17.714761     55.968609  52.726356
+2  28.943139    17.263000     49.375100  54.420703
+3  48.322396    12.873456     54.718482  48.019809
+
+

If the steady-state phase has been pre-identified, the manual selection +of the area can be bypassed.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> df = emg.compute_covisi(
+...     emgfile=emgfile,
+...     event_="rec_derec",
+...     start_steady=20000,
+...     end_steady=50000,
+... )
+>>> df
+   DRvar_rec  DRvar_derec  DRvar_all
+0   8.560971    21.662783  13.937779
+1  36.934213    17.714761  52.726356
+2  28.943139    17.263000  54.420703
+3  48.322396    12.873456  48.019809
+
+ +
+ +


+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API_electrodes/index.html b/API_electrodes/index.html new file mode 100644 index 0000000..b90af4b --- /dev/null +++ b/API_electrodes/index.html @@ -0,0 +1,1005 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + electrodes - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

electrodes

+ +

Description

+

This module contains informations about the electrodes commonly used for +HD-EMG recordings. +Functions to sort the electrode position are also included.

+

Notes

+

The files saved from the DEMUSE software are supposed to be already sorted.

+


+ + +
+ + + +

+sort_rawemg(emgfile, code='GR08MM1305', orientation=180, dividebycolumn=True, n_rows=None, n_cols=None) + +

+ + +
+ +

Sort RAW_SIGNAL based on matrix type and orientation.

+

To date, built-in sorting functions have been implemented for the matrices: + Code (Orientation) + GR08MM1305 (0, 180), + GR04MM1305 (0, 180), + GR10MM0808 (0, 180).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
code +
+

The code of the matrix used. +If "None", the electodes are not sorted but n_rows and n_cols must be +specified when dividebycolumn == True.

+
+

+ + TYPE: + str {"GR08MM1305", "GR04MM1305", "GR10MM0808", "None"} + + + DEFAULT: + "GR08MM1305" + +

+
orientation +
+

Orientation in degree of the matrix. +E.g. 180 corresponds to the matrix connection toward the researcher or +the ground (depending on the limb).

+
+

+ + TYPE: + int {0, 180} + + + DEFAULT: + 180 + +

+
dividebycolumn +
+

Whether to return the sorted channels classified by matrix column.

+
+

+ + DEFAULT: + True + +

+
n_rows +
+

The number of rows and columns of the matrix. This parameter is used to +divide the channels based on the matrix shape. These are normally +inferred by the matrix code and must be specified only if code == None.

+
+

+ + TYPE: + None or int + + + DEFAULT: + None + +

+
n_cols +
+

The number of rows and columns of the matrix. This parameter is used to +divide the channels based on the matrix shape. These are normally +inferred by the matrix code and must be specified only if code == None.

+
+

+ + TYPE: + None or int + + + DEFAULT: + None + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ sorted_rawemg + +
+

If dividebycolumn == True a dict containing the sorted electrodes. +Every key of the dictionary represents a different column of the +matrix. Rows are stored in the dict as a pd.DataFrame. +If dividebycolumn == False a pd.DataFrame containing the sorted +electrodes. The matrix channels are stored in the pd.DataFrame columns.

+
+

+ + TYPE: + dict or pd.DataFrame + +

+
+

Notes

+

The returned file is called sorted_rawemg for convention.

+ +

Examples:

+

Sort emgfile RAW_SIGNAL and divide it by columns.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True,
+... )
+>>> sorted_rawemg["col0"]
+        0          1          2 ...        10         11         12
+0     NaN -11.189778   3.560384 ... -2.034505  -3.051758  -0.508626
+1     NaN -12.715657   4.577637 ...  2.034505  -7.120768  -0.508626
+2     NaN   0.508626  21.870932 ... 17.801920   8.646647  16.276041
+3     NaN   6.103516  26.957193 ... 26.448568  19.327799  19.836426
+4     NaN  -5.594889  13.224284 ... 10.681152   2.034505   3.560384
+...    ..        ...        ... ...       ...        ...        ...
+63483 NaN -15.767415 -22.379557 ...-12.207031 -12.207031 -15.767415
+63484 NaN  -9.155273 -19.327799 ... -7.629395  -8.138021  -8.138021
+63485 NaN  -6.103516 -12.207031 ... -6.103516  -5.086263  -3.051758
+63486 NaN  -6.103516 -15.767415 ... -3.560384  -0.508626   2.543132
+63487 NaN  -8.138021 -18.819174 ... -2.034505  -1.525879   3.560384
+
+

Sort emgfile RAW_SIGNAL without dividing it by columns.

+
>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=False,
+... )
+>>> sorted_rawemg
+       0          1          2  ...        62         63         64
+0     NaN -11.189778   3.560384 ... -5.086263  -9.663899   2.034505
+1     NaN -12.715657   4.577637 ... -3.560384  -8.646647   1.017253
+2     NaN   0.508626  21.870932 ... 11.189778   6.612142  17.293295
+3     NaN   6.103516  26.957193 ... 22.888184  14.750163  21.362305
+4     NaN  -5.594889  13.224284 ...  9.663899   1.525879   6.612142
+...    ..        ...        ... ...       ...        ...        ...
+63483 NaN -15.767415 -22.379557 ... -8.646647 -20.345053 -15.258789
+63484 NaN  -9.155273 -19.327799 ... -7.120768 -19.327799 -13.732910
+63485 NaN  -6.103516 -12.207031 ... -3.051758 -10.681152  -6.103516
+63486 NaN  -6.103516 -15.767415 ...  2.543132  -7.120768  -4.069010
+63487 NaN  -8.138021 -18.819174 ...  2.034505  -3.051758  -0.508626
+
+

Avoid RAW_SIGNAL sorting but divide it by columns.

+
>>> emgfile = emg.askopenfile(filesource="CUSTOM")
+>>> sorted_rawemg = emg.sort_rawemg(emgfile, code="None", n_cols=5, n_rows=13)
+>>> sorted_rawemg["col0"]
+             0         1         2  ...       10        11  12
+0      0.008138  0.001017  0.002035 ... 0.005595  0.008647 NaN
+1     -0.005595 -0.011190 -0.014750 ... 0.000000  0.005086 NaN
+2     -0.017293 -0.020854 -0.021871 ... 0.009664 -0.004578 NaN
+3     -0.003560 -0.012716 -0.009155 ... 0.004578  0.007121 NaN
+4      0.001526 -0.005595 -0.005595 ... 0.007121  0.010173 NaN
+...         ...       ...       ... ...      ...       ...  ..
+62459  0.011698  0.015259  0.004069 ... 0.000000  0.031026 NaN
+62460  0.007629  0.011698  0.002543 ... 0.002035  0.026449 NaN
+62461  0.001526  0.009664  0.000000 ... 0.001526  0.025940 NaN
+62462  0.033061  0.037130  0.027974 ... 0.022380  0.049845 NaN
+62463  0.020854  0.028992  0.017802 ... 0.013733  0.037638 NaN
+
+ +
+ +


+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API_info/index.html b/API_info/index.html new file mode 100644 index 0000000..a746cea --- /dev/null +++ b/API_info/index.html @@ -0,0 +1,1021 @@ + + + + + + + + + + + + + + + + + + + + + + + + info - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

info

+ +

Description

+

This module contains all the information regarding:

+
    +
  • Data
      +
    • Structures of data
    • +
    • How to access data
    • +
    +
  • +
  • Abbreviations
  • +
  • AboutUs
  • +
  • Contacts
  • +
  • Links
  • +
  • CiteUs
  • +
+


+ + +
+ + + +

+data(emgfile) + +

+ + +
+ +

Print a description of the emgfile data structure.

+

Print a detailed description of the emgfile data structure and of how +to access the contained elements.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
+ +

Examples:

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="DEMUSE")
+>>> emg.info().data(emgfile)
+emgfile type is:
+<class 'dict'>
+emgfile keys are:
+dict_keys(['SOURCE', 'FILENAME', 'RAW_SIGNAL', 'REF_SIGNAL', 'PNR', 'SIL', 'IPTS', 'MUPULSES', 'FSAMP', 'IED', 'EMG_LENGTH', 'NUMBER_OF_MUS', 'BINARY_MUS_FIRING'])
+Any key can be acced as emgfile[key].
+emgfile['SOURCE'] is a <class 'str'> of value:
+DEMUSE
+.
+.
+.
+
+ +
+ +


+ + +
+ + + +

+abbreviations() + +

+ + +
+ +

Print common abbreviations.

+ +

Examples:

+
>>> import openhdemg.library as emg
+>>> emg.info().abbreviations()
+"COV": "Coefficient of variation",
+"DERT": "DERecruitment threshold",
+"DD": "Double differential",
+"DR": "Discharge rate",
+"FSAMP": "Sampling frequency",
+"IDR": "Instantaneous discharge rate",
+"IED": "Inter electrode distance",
+"IPTS": "Impulse train (decomposed source)",
+"MU": "Motor units",
+"MUAP": "MUs action potential",
+"PNR": "Pulse to noise ratio",
+"RT": "Recruitment threshold",
+"SD": "Single differential",
+"SIL": "Silhouette score",
+"STA": "Spike-triggered average",
+"XCC": "Cross-correlation coefficient"
+
+ +
+ +


+ + +
+ + + +

+aboutus() + +

+ + +
+ +

Print informations about the library and the authors.

+ +

Examples:

+
>>> import openhdemg.library as emg
+>>> emg.info().aboutus()
+The openhdemg project was born in 2022 with the aim to provide a
+free and open-source framework to analyse HIGH-DENSITY EMG
+recordings...
+
+ +
+ +


+ + +
+ + + +

+contacts() + +

+ + +
+ +

Print the contacts.

+ +

Examples:

+
>>> import openhdemg.library as emg
+>>> emg.info().contacts()
+"Name": "Giacomo Valli",
+"Email": "giacomo.valli@phd.unipd.it",
+"Twitter": "@giacomo_valli"
+
+ +
+ +


+ + +
+ + + + + + +
+ +

Print a collection of useful links.

+ +
+ +


+ + +
+ + + +

+citeus() + +

+ + +
+ +

Print how to cite the project.

+ +
+ +


+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API_mathtools/index.html b/API_mathtools/index.html new file mode 100644 index 0000000..3348d7c --- /dev/null +++ b/API_mathtools/index.html @@ -0,0 +1,1392 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + mathtools - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

mathtools

+ +

Description

+

This module contains all the mathematical functions that are necessary for the +library.

+


+ + +
+ + + +

+min_max_scaling(series_or_df) + +

+ + +
+ +

Min-max scaling of pd.series or pd.dataframes.

+

Min-max feature scaling is often simply referred to as normalization, +which rescales the dataset feature to a range of 0 - 1. +It's calculated by subtracting the feature's minimum value from the value +and then dividing it by the difference between the maximum and minimum +value.

+

The formula looks like this: xnorm = x - xmin / xmax - xmin.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
series_or_df +
+

The min-max scaling is performed for the entire series, +or for single columns in a pd.DataFrame.

+
+

+ + TYPE: + pd.Series or pd.DataFrame + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ object + +
+

The normalised pd.Series or pd.DataFrame (normalised by column).

+
+

+ + TYPE: + pd.Series or pd.DataFrame + +

+
+ +
+ +


+ + +
+ + + +

+norm_xcorr(sig1, sig2, out='both') + +

+ + +
+ +

Normalized cross-correlation of 2 signals.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
sig1 +
+

The two signals to correlate. +These signals must be 1-dimensional and of same length.

+
+

+ + TYPE: + pd.Series or np.ndarray + +

+
sig2 +
+

The two signals to correlate. +These signals must be 1-dimensional and of same length.

+
+

+ + TYPE: + pd.Series or np.ndarray + +

+
out +
+

A string indicating the output value:

+

both +The output is the greatest positive or negative cross-correlation +value. +max +The output is the maximum cross-correlation value.

+
+

+ + TYPE: + str {"both", "max"} + + + DEFAULT: + "both" + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ xcc + +
+

The cross-correlation value depending on "out".

+
+

+ + TYPE: + float + +

+
+

See also

+
    +
  • norm_twod_xcorr : Normalised 2-dimensional cross-correlation of STAs of + two MUS.
  • +
+ +
+ +


+ + +
+ + + +

+norm_twod_xcorr(df1, df2, mode='full') + +

+ + +
+ +

Normalised 2-dimensional cross-correlation of STAs of two MUS.

+

Any pre-processing of the RAW_SIGNAL (i.e., normal, differential or double +differential) can be passed as long as the two inputs have same shape.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
df1 +
+

A pd.DataFrame containing the STA of the first MU without np.nan +column.

+
+

+ + TYPE: + pd.DataFrame + +

+
df2 +
+

A pd.DataFrame containing the STA of the second MU without np.nan +column.

+
+

+ + TYPE: + pd.DataFrame + +

+
mode +
+

A string indicating the size of the output:

+

full +The output is the full discrete linear cross-correlation +of the inputs. (Default) +valid +The output consists only of those elements that do not +rely on the zero-padding. In 'valid' mode, either sta_mu1 or +sta_mu2 must be at least as large as the other in every dimension. +same +The output is the same size as in1, centered +with respect to the 'full' output.

+
+

+ + TYPE: + str {"full", "valid", "same"} + + + DEFAULT: + "full" + +

+
+ + + + + + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ normxcorr_df + +
+

The results of the normalised 2d cross-correlation.

+
+

+ + TYPE: + pd.DataFrame + +

+
+ normxcorr_max + +
+

The maximum value of the 2d cross-correlation.

+
+

+ + TYPE: + float + +

+
+

See also

+
    +
  • align_by_xcorr : to align the two STAs before calling norm_twod_xcorr.
  • +
  • unpack_sta : for unpacking the sta dict in a pd.DataFrame + before passing it to norm_twod_xcorr.
  • +
  • pack_sta : for packing the sta pd.DataFrame in a dict where + each matrix column corresponds to a dict key.
  • +
+ +

Examples:

+

Full steps to pass two dataframes to norm_twod_xcorr from the same EMG +file.

+
    +
  1. Load the EMG file and band-pass filter the raw EMG signal
  2. +
  3. Sort the matrix channels and compute the spike-triggered average
  4. +
  5. Extract the STA of the MUs of interest from all the STAs
  6. +
  7. Unpack the STAs of single MUs and remove np.nan to pas them to + norm_twod_xcorr
  8. +
  9. Compute 2dxcorr to identify a common lag/delay
  10. +
+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emgfile = emg.filter_rawemg(emgfile, order=2, lowcut=20, highcut=500)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     )
+>>> sta = emg.sta(emgfile, sorted_rawemg, firings=[0, 50], timewindow=100)
+>>> mu0 = 0
+>>> mu1 = 1
+>>> sta_mu1 = sta[mu0]
+>>> sta_mu2 = sta[mu1]
+>>> df1 = emg.unpack_sta(sta_mu1)
+>>> no_nan_sta1 = df1.dropna(axis=1)
+>>> df2 = emg.unpack_sta(sta_mu2)
+>>> no_nan_sta2 = df2.dropna(axis=1)
+>>> normxcorr_df, normxcorr_max = emg.norm_twod_xcorr(
+...     no_nan_sta1,
+...     no_nan_sta2,
+...     )
+>>> normxcorr_max
+0.7241553627564273
+>>> normxcorr_df
+            0             1             2               125       126
+0   -0.000002 -1.467778e-05 -3.013564e-05 ... -1.052780e-06  0.000001
+1   -0.000004 -2.818055e-05 -6.024427e-05 ... -4.452469e-06  0.000001
+2   -0.000007 -4.192479e-05 -9.223725e-05 ... -1.549197e-05 -0.000002
+3   -0.000009 -5.071660e-05 -1.174545e-04 ... -3.078518e-05 -0.000007
+4   -0.000007 -4.841255e-05 -1.239106e-04 ... -4.232094e-05 -0.000012
+..        ...           ...           ... ...           ...       ...
+402  0.000005  1.641773e-05  3.994943e-05 ...  8.170792e-07 -0.000006
+403 -0.000001  4.535878e-06  1.858700e-05 ...  2.087135e-06 -0.000003
+404 -0.000004 -1.241530e-06  5.704194e-06 ...  1.027966e-05  0.000002
+405 -0.000004 -1.693078e-06  1.054646e-06 ...  1.811828e-05  0.000007
+406 -0.000002 -2.473282e-07  6.006046e-07 ...  1.605406e-05  0.000007
+
+ +
+ +


+ + +
+ + + +

+compute_sil(ipts, mupulses) + +

+ + +
+ +

Calculate the Silhouette score for a single MU.

+

The SIL is defined as the difference between the within-cluster sums of +point-to-centroid distances and the same measure calculated between +clusters. The output measure is normalised in a range between 0 and 1.

+ + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
ipts +
+

The decomposed source (or pulse train, IPTS[mu]) of the MU of +interest.

+
+

+ + TYPE: + pd.Series + +

+
mupulses +
+

The time of firing (MUPULSES[mu]) of the MU of interest.

+
+

+ + TYPE: + ndarray + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ sil + +
+

The SIL score.

+
+

+ + TYPE: + float + +

+
+

See also

+
    +
  • compute_pnr : to calculate the Pulse to Noise ratio of a single MU.
  • +
+ +
+ +


+ + +
+ + + +

+compute_pnr(ipts, mupulses, fsamp, separate_paired_firings=True) + +

+ + +
+ +

Calculate the pulse to noise ratio for a single MU.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
ipts +
+

The decomposed source (or pulse train, IPTS[mu]) of the MU of +interest.

+
+

+ + TYPE: + pd.Series + +

+
mupulses +
+

The time of firing (MUPULSES[mu]) of the MU of interest.

+
+

+ + TYPE: + ndarray + +

+
separate_paired_firings +
+

Whether to treat differently paired and non-paired firings during +the estimation of the signal/noise threshold. According to Holobar +2012, this is common in pathological tremor. The user is encouraged to +use the default value (True) to increase the robustness of the +estimation.

+
+

+ + TYPE: + bool + + + DEFAULT: + False + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ pnr + +
+

The PNR in decibels.

+
+

+ + TYPE: + float + +

+
+

See also

+
    +
  • compute_sil : to calculate the Silhouette score for a single MU.
  • +
+ +
+ +


+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API_muap/index.html b/API_muap/index.html new file mode 100644 index 0000000..a9eafd0 --- /dev/null +++ b/API_muap/index.html @@ -0,0 +1,2788 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + muap - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

muap

+ +

Description

+

This module contains functions to produce and analyse MUs anction potentials +(MUAPs).

+


+ + +
+ + + +

+diff(sorted_rawemg) + +

+ + +
+ +

Calculate single differential (SD) of RAW_SIGNAL on matrix rows.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
sorted_rawemg +
+

A dict containing the sorted electrodes. +Every key of the dictionary represents a different column of the +matrix. Rows are stored in the dict as a pd.DataFrame. +Electrodes can be sorted with the function emg.sort_rawemg.

+
+

+ + TYPE: + dict + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ sd + +
+

A dict containing the double differential signal. +Every key of the dictionary represents a different column of the +matrix. +Rows are stored in the dict as a pd.DataFrame.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • double_diff : calculate double differential of RAW_SIGNAL on matrix rows.
  • +
+

Notes

+

The returned sd will contain one less matrix row.

+ +

Examples:

+

Calculate single differential of a DEMUSE file with the channels already +sorted.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="DEMUSE")
+>>> sorted_rawemg = emg.sort_rawemg(
+>>>     emgfile,
+...     code="None",
+...     orientation=180,
+...     dividebycolumn=True,
+...     n_rows=13,
+...     n_cols=5,
+... )
+>>> sd = emg.diff(sorted_rawemg)
+>>> sd["col0"]
+             1         2         3  ...        10        11  12
+0     -0.003052  0.005086 -0.009155 ...  0.001526  0.016785 NaN
+1     -0.008647  0.008138 -0.010173 ... -0.001017 -0.015259 NaN
+2     -0.005595  0.005595 -0.013733 ...  0.003560  0.007629 NaN
+3     -0.010681  0.007121 -0.009664 ... -0.001526 -0.015259 NaN
+4     -0.005595  0.005086 -0.011190 ...  0.001017  0.017293 NaN
+...         ...       ...       ... ...       ...       ...  ..
+63483 -0.000509  0.007121 -0.007629 ... -0.006612  0.022380 NaN
+63484 -0.005086  0.005595 -0.004578 ... -0.005595 -0.045776 NaN
+63485 -0.004069  0.001017 -0.003560 ... -0.005086 -0.005086 NaN
+63486 -0.002035  0.006104 -0.010681 ... -0.007121  0.020345 NaN
+63487 -0.008647  0.000000 -0.010681 ... -0.011190 -0.027466 NaN
+
+

Calculate single differential of an OTB file where the channels need to be +sorted.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+... )
+>>> sd = emg.diff(sorted_rawemg)
+
+ +
+ +


+ + +
+ + + +

+double_diff(sorted_rawemg) + +

+ + +
+ +

Calculate double differential (DD) of RAW_SIGNAL on matrix rows.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
sorted_rawemg +
+

A dict containing the sorted electrodes. +Every key of the dictionary represents a different column of the +matrix. Rows are stored in the dict as a pd.DataFrame. +Electrodes can be sorted with the function emg.sort_rawemg.

+
+

+ + TYPE: + dict + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ dd + +
+

A dict containing the double differential signal. +Every key of the dictionary represents a different column of the +matrix. Rows are stored in the dict as a pd.DataFrame.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • diff : Calculate single differential of RAW_SIGNAL on matrix rows.
  • +
+

Notes

+

The returned dd will contain two less matrix rows.

+ +

Examples:

+

Calculate double differential of a DEMUSE file with the channels already +sorted.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="DEMUSE")
+>>> sorted_rawemg = emg.sort_rawemg(
+>>>     emgfile,
+...     code="None",
+...     orientation=180,
+...     dividebycolumn=True,
+...     n_rows=13,
+...     n_cols=5,
+... )
+>>> dd = emg.double_diff(sorted_rawemg)
+>>> dd["col0"]
+             2         3         4  ...            10        11  12
+0      0.008138 -0.014242  0.012716 ...  4.577637e-03  0.015259 NaN
+1      0.016785 -0.018311  0.022380 ...  8.138018e-03 -0.014242 NaN
+2      0.011190 -0.019328  0.021362 ...  1.780192e-02  0.004069 NaN
+3      0.017802 -0.016785  0.014750 ...  1.118978e-02 -0.013733 NaN
+4      0.010681 -0.016276  0.017802 ...  4.577637e-03  0.016276 NaN
+...         ...       ...       ... ...           ...       ...  ..
+63483  0.007629 -0.014750  0.011698 ... -4.656613e-10  0.028992 NaN
+63484  0.010681 -0.010173  0.011698 ... -2.543131e-03 -0.040181 NaN
+63485  0.005086 -0.004578  0.004069 ... -6.612142e-03  0.000000 NaN
+63486  0.008138 -0.016785  0.013733 ... -1.068115e-02  0.027466 NaN
+63487  0.008647 -0.010681  0.019836 ... -1.068115e-02 -0.016276 NaN
+
+

Calculate single differential of an OTB file where the channels need to be +sorted.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True,
+... )
+>>> dd = emg.double_diff(sorted_rawemg)
+
+ +
+ +


+ + +
+ + + +

+sta(emgfile, sorted_rawemg, firings=[0, 50], timewindow=50) + +

+ + +
+ +

Computes the spike-triggered average (STA) of every MUs.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
sorted_rawemg +
+

A dict containing the sorted electrodes. +Every key of the dictionary represents a different column of the +matrix. Rows are stored in the dict as a pd.DataFrame.

+
+

+ + TYPE: + dict + +

+
firings +
+

The range of firnings to be used for the STA. +If a MU has less firings than the range, the upper limit +is adjusted accordingly. +all +The STA is calculated over all the firings.

+
+

+ + TYPE: + list or str {"all"} + + + DEFAULT: + [0, 50] + +

+
timewindow +
+

Timewindow to compute STA in milliseconds.

+
+

+ + TYPE: + int + + + DEFAULT: + 50 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ sta_dict + +
+

dict containing a dict of STA (pd.DataFrame) for every MUs.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • unpack_sta : build a common pd.DataFrame from the sta dict containing + all the channels.
  • +
  • pack_sta : pack the pd.DataFrame containing STA to a dict.
  • +
  • st_muap : generate spike triggered MUs action potentials + over the entire spike train of every MUs.
  • +
+

Notes

+

The returned file is called sta_dict for convention.

+ +

Examples:

+

Calculate STA of all the MUs in the emgfile on the first 25 firings +and in a 50 ms time-window. +Access the STA of the column 0 of the first MU (number 0).

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+... )
+>>> sta = emg.sta(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     firings=[0,25],
+...     timewindow=50,
+... )
+>>> sta[0]["col0"]
+     0          1          2  ...        10         11         12
+0   NaN  -7.527668  -7.141111 ... -1.464846 -21.606445 -14.180500
+1   NaN -16.662600 -14.038087 ...  2.868650 -19.246420 -15.218098
+2   NaN -21.443687 -15.116375 ...  5.615236 -16.052244 -13.854978
+3   NaN -17.822264  -9.989420 ...  6.876628 -12.451175 -12.268069
+4   NaN -14.567060  -8.748373 ... -1.403812 -14.241538 -16.703283
+..   ..        ...        ... ...       ...        ...        ...
+97  NaN  19.388836  25.166826 ... 39.591473  23.681641  19.653318
+98  NaN   8.870444  16.337074 ... 28.706865  20.548504   8.422853
+99  NaN  -1.037601   7.446290 ... 18.086752  16.276041   0.040688
+100 NaN  -2.766926   5.371094 ... 11.006674  14.261881  -0.712078
+101 NaN   3.214517   9.562176 ...  4.475910  10.742184  -0.284828
+
+

Calculate STA of the differential signal on all the firings.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+... )
+>>> sd = emg.diff(sorted_rawemg=sorted_rawemg)
+>>> sta = emg.sta(
+...     emgfile=emgfile,
+...     sorted_rawemg=sd,
+...     firings="all",
+...     timewindow=50,
+... )
+>>> sta[0]["col0"]
+     1         2          3  ...         10         11         12
+0   NaN -0.769545  11.807394 ...   3.388641  14.423187   1.420190
+1   NaN -1.496154  11.146843 ...   4.637086  12.312718   3.408456
+2   NaN -3.263135   9.660598 ...   6.258748   9.478946   5.974706
+3   NaN -4.125159   9.257659 ...   6.532877   5.558562   7.708665
+4   NaN -4.234151   9.379863 ...   6.034157   1.506064   8.722610
+..   ..       ...        ... ...        ...        ...        ...
+97  NaN -6.126635   1.225329 ... -10.050324   1.522576  -9.568117
+98  NaN -6.565903   0.571378 ...  -8.669765   4.643692 -10.714180
+99  NaN -6.153056  -0.105689 ...  -6.836730   7.272696 -12.623180
+100 NaN -5.452869  -0.587892 ...  -7.411412   8.504627 -14.727043
+101 NaN -4.587545  -0.855417 ... -10.549041   9.802613 -15.820260
+
+ +
+ +


+ + +
+ + + +

+st_muap(emgfile, sorted_rawemg, timewindow=50) + +

+ + +
+ +

Generate spike triggered MUAPs of every MUs.

+

Generate single spike triggered (ST) MUs action potentials (MUAPs) +over the entire spike train of every MUs.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
sorted_rawemg +
+

A dict containing the sorted electrodes. +Every key of the dictionary represents a different column of the +matrix. Rows are stored in the dict as a pd.DataFrame.

+
+

+ + TYPE: + dict + +

+
timewindow +
+

Timewindow to compute ST MUAPs in milliseconds.

+
+

+ + TYPE: + int + + + DEFAULT: + 50 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ stmuap + +
+

dict containing a dict of ST MUAPs (pd.DataFrame) for every MUs. +pd.DataFrames containing the ST MUAPs are organised based on matrix +rows (dict) and matrix channel. +For example, the ST MUAPs of the first MU (0), in the second electrode +of the matrix can be accessed as stmuap[0]["col0"][1].

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • sta : computes the STA of every MUs.
  • +
+

Notes

+

The returned file is called stmuap for convention.

+ +

Examples:

+

Calculate the MUAPs of the differential signal. +Access the MUAPs of the first MU (number 0), channel 15 that is contained +in the second matrix column ("col1").

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+... )
+>>> sd = emg.diff(sorted_rawemg=sorted_rawemg)
+>>> stmuap = emg.st_muap(emgfile=emgfile, sorted_rawemg=sd, timewindow=50)
+>>> stmuap[0]["col1"][15]
+           0          1          2   ...        151         152         153
+0   -14.750162 -26.957193   6.103516 ...  23.905434    4.069008  150.553375
+1    -9.155273 -22.379557  12.715660 ...   8.138023    0.000000  133.260086
+2    -4.069010 -12.207031  17.293289 ...  -6.612144    6.612141   74.768066
+3     1.525879  -6.612143  22.379562 ... -25.939949   21.362305  -14.750168
+4     3.051758  -4.577637  24.414062 ... -35.603844   34.586590  -83.923347
+..         ...        ...        ... ...        ...         ...         ...
+97    9.155273 -24.922688  43.233238 ... -92.569984 -107.320145  -40.181477
+98   -2.543133 -14.241535  28.483074 ...-102.233887  -68.155922  -19.836430
+99  -23.905437 -13.732906  15.767414 ... -89.518234  -42.215984  -10.681152
+100 -52.388512 -20.853680  14.241537 ... -71.716309  -26.448566    0.000000
+101 -61.543785 -16.784668  21.362305 ... -52.388504   -3.560385    6.103516
+
+ +
+ +


+ + +
+ + + +

+unpack_sta(sta_mu) + +

+ + +
+ +

Build a common pd.DataFrame from the sta_dict containing all the channels.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
sta_mu +
+

A dict containing the STA of a single MU.

+
+

+ + TYPE: + dict + +

+
+ + + + + + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ df1 + +
+

A pd.DataFrame containing the STA of the MU +(including the empty channel).

+
+

+ + TYPE: + pd.DataFrame + +

+
+ keys + +
+

The matrix columns (dict keys) of the unpacked sta.

+
+

+ + TYPE: + list + +

+
+

See also

+
    +
  • sta : computes the STA of every MUs.
  • +
  • pack_sta : pack the pd.DataFrame containing STA to a dict.
  • +
+ +
+ +


+ + +
+ + + +

+pack_sta(df_sta, keys) + +

+ + +
+ +

Pack the pd.DataFrame containing STA to a dict.

+ + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
df_sta +
+

(including the empty channel).

+
+

+ + TYPE: + A pd.DataFrame containing the STA of a single MU + +

+
keys +
+

The matrix columns (dict keys) by which to pack the sta.

+
+

+ + TYPE: + list + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ packed_sta + +
+

dict containing STA of the input pd.DataFrame divided by matrix column. +Dict columns are "col0", col1", "col2", "col3", "col4".

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • sta : computes the STA of every MUs.
  • +
  • unpack_sta : build a common pd.DataFrame from the sta dict containing + all the channels.
  • +
+ +
+ +


+ + +
+ + + +

+align_by_xcorr(sta_mu1, sta_mu2, finalduration=0.5) + +

+ + +
+ +

Align the STA of 2 MUs by cross-correlation.

+

Any pre-processing of the RAW_SIGNAL +(i.e., normal, differential or double differential) +can be passed as long as the two inputs have same shape. +Since the returned STA is cut based on finalduration, +the input STA should account for this.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
sta_mu1 +
+

A dictionary containing the STA of the first MU.

+
+

+ + TYPE: + dict + +

+
sta_mu2 +
+

A dictionary containing the STA of the second MU.

+
+

+ + TYPE: + dict + +

+
finalduration +
+

Duration of the aligned STA compared to the original +in percent. (e.g., 0.5 corresponds to 50%).

+
+

+ + TYPE: + float + + + DEFAULT: + 0.5 + +

+
+ + + + + + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ aligned_sta1 + +
+

A dictionary containing the aligned and STA of the first MU +with the final expected timewindow +(duration of sta_mu1 * finalduration).

+
+

+ + TYPE: + dict + +

+
+ aligned_sta2 + +
+

A dictionary containing the aligned and STA of the second MU +with the final expected timewindow +(duration of sta_mu1 * finalduration).

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • sta : computes the STA of every MUs.
  • +
  • norm_twod_xcorr : normalised 2-dimensional cross-correlation of STAs of + two MUS.
  • +
+

Notes

+

STAs are aligned by a common lag/delay for the entire matrix and not +channel by channel because this might lead to misleading results.

+ +

Examples:

+

Align two MUs with a final duration of 50% the original one.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+... )
+>>> sta = emg.sta(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     timewindow=100,
+... )
+>>> aligned_sta1, aligned_sta2 = emg.align_by_xcorr(
+...     sta_mu1=sta[0], sta_mu2=sta[1], finalduration=0.5,
+... )
+>>> aligned_sta1["col0"]
+     0          1          2  ...        10         11         12
+0   NaN -10.711670  -7.008868 ... 21.809900 -33.447262 -21.545408
+1   NaN  -5.584714  -2.380372 ... 22.664387 -33.081059 -18.931072
+2   NaN  -4.262290  -1.139323 ... 23.244226 -33.020020 -17.456057
+3   NaN  -4.638671  -1.078290 ... 23.111980 -34.118645 -18.147787
+4   NaN  -7.405599  -4.018145 ... 22.888189 -35.797115 -22.247314
+..   ..        ...        ... ...       ...        ...        ...
+97  NaN   6.764731  13.081865 ... 30.954998  39.672852  42.429604
+98  NaN   4.455567  10.467529 ... 31.311037  41.280106  44.403072
+99  NaN   0.356039   6.856283 ... 30.436195  43.701172  46.142574
+100 NaN  -2.960206   4.872639 ... 30.008953  44.342041  46.366371
+101 NaN  -7.008870   1.708984 ... 25.634764  40.100101  43.009445
+
+ +
+ +


+ + +
+ + + +

+tracking(emgfile1, emgfile2, firings='all', derivation='sd', timewindow=50, threshold=0.8, matrixcode='GR08MM1305', orientation=180, n_rows=None, n_cols=None, exclude_belowthreshold=True, filter=True, show=False) + +

+ + +
+ +

Track MUs across two different files.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile1 +
+

The dictionary containing the first emgfile.

+
+

+ + TYPE: + dict + +

+
emgfile2 +
+

The dictionary containing the second emgfile.

+
+

+ + TYPE: + dict + +

+
firings +
+

The range of firnings to be used for the STA. +If a MU has less firings than the range, the upper limit +is adjusted accordingly. +all +The STA is calculated over all the firings. +A list can be passed as [start, stop] e.g., [0, 25] +to compute the STA on the first 25 firings.

+
+

+ + TYPE: + list or str {"all"} + + + DEFAULT: + "all" + +

+
derivation +
+

Whether to compute the sta on the monopolar signal, or on the single or +double differential derivation.

+
+

+ + TYPE: + str {mono, sd, dd} + + + DEFAULT: + sd + +

+
timewindow +
+

Timewindow to compute STA in milliseconds.

+
+

+ + TYPE: + int + + + DEFAULT: + 50 + +

+
threshold +
+

The 2-dimensional cross-correlation minimum value +to consider two MUs to be the same. Ranges 0-1.

+
+

+ + TYPE: + float + + + DEFAULT: + 0.8 + +

+
matrixcode +
+

The code of the matrix used. This is necessary to sort the channels in +the correct order. If matrixcode="None", the electrodes are not sorted. +In this case, n_rows and n_cols must be specified.

+
+

+ + TYPE: + str {"GR08MM1305", "GR04MM1305", "GR10MM0808", "None"} + + + DEFAULT: + "GR08MM1305" + +

+
orientation +
+

Orientation in degree of the matrix (same as in OTBiolab). +E.g. 180 corresponds to the matrix connection toward the user.

+
+

+ + TYPE: + int {0, 180} + + + DEFAULT: + 180 + +

+
n_rows +
+

The number of rows and columns of the matrix. This parameter is used to +divide the channels based on the matrix shape. These are normally +inferred by the matrix code and must be specified only if code == None.

+
+

+ + TYPE: + None or int + + + DEFAULT: + None + +

+
n_cols +
+

The number of rows and columns of the matrix. This parameter is used to +divide the channels based on the matrix shape. These are normally +inferred by the matrix code and must be specified only if code == None.

+
+

+ + TYPE: + None or int + + + DEFAULT: + None + +

+
exclude_belowthreshold +
+

Whether to exclude results with XCC below threshold.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
filter +
+

If true, when the same MU has a match of XCC > threshold with +multiple MUs, only the match with the highest XCC is returned.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
show +
+

Whether to plot the STA of pairs of MUs with XCC above threshold.

+
+

+ + TYPE: + bool + + + DEFAULT: + False + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ tracking_res + +
+

The results of the tracking including the MU from file 1, +MU from file 2 and the normalised cross-correlation value (XCC).

+
+

+ + TYPE: + pd.DataFrame + +

+
+ + + + + + + + + + + + + + +
WARNSDESCRIPTION
+ + UserWarning + + +
+

If the number of plots to show exceeds that of available cores.

+
+
+

See also

+
    +
  • sta : computes the STA of every MUs.
  • +
  • norm_twod_xcorr : normalised 2-dimensional cross-correlation of STAs of + two MUS.
  • +
  • remove_duplicates_between : remove duplicated MUs across two different + files based on STA.
  • +
+

Notes

+

Parallel processing can improve performances by 5-10 times compared to +serial processing. In this function, parallel processing has been +implemented for the tasks involving 2-dimensional cross-correlation, sta +and plotting.

+ +

Examples:

+

Track MUs between two OTB files and show the filtered results.

+
>>> import openhdemg.library as emg
+>>> emgfile1 = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emgfile2 = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> tracking_res = emg.tracking(
+...     emgfile1=emgfile1,
+...     emgfile2=emgfile2,
+...     firings="all",
+...     derivation="mono",
+...     timewindow=50,
+...     threshold=0.8,
+...     matrixcode="GR08MM1305",
+...     orientation=180,
+...     n_rows=None,
+...     n_cols=None,
+...     exclude_belowthreshold=True,
+...     filter=True,
+...     show=False,
+... )
+    MU_file1  MU_file2       XCC
+0          0         3  0.820068
+1          2         4  0.860272
+2          4         8  0.857346
+3          5         0  0.878373
+4          6         9  0.877321
+5          7         1  0.823371
+6          9        13  0.873388
+7         11         5  0.862537
+8         19        10  0.802635
+9         21        14  0.896419
+10        22        16  0.836356
+
+ +
+ +


+ + +
+ + + +

+remove_duplicates_between(emgfile1, emgfile2, firings='all', derivation='sd', timewindow=50, threshold=0.9, matrixcode='GR08MM1305', orientation=180, n_rows=None, n_cols=None, filter=True, show=False, which='munumber') + +

+ + +
+ +

Remove duplicated MUs across two different files based on STA.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile1 +
+

The dictionary containing the first emgfile.

+
+

+ + TYPE: + dict + +

+
emgfile2 +
+

The dictionary containing the second emgfile.

+
+

+ + TYPE: + dict + +

+
firings +
+

The range of firnings to be used for the STA. +If a MU has less firings than the range, the upper limit +is adjusted accordingly. +all +The STA is calculated over all the firings. +A list can be passed as [start, stop] e.g., [0, 25] +to compute the STA on the first 25 firings.

+
+

+ + TYPE: + list or str {"all"} + + + DEFAULT: + "all" + +

+
derivation +
+

Whether to compute the sta on the monopolar signal, or on the single or +double differential derivation.

+
+

+ + TYPE: + str {mono, sd, dd} + + + DEFAULT: + sd + +

+
timewindow +
+

Timewindow to compute STA in milliseconds.

+
+

+ + TYPE: + int + + + DEFAULT: + 50 + +

+
threshold +
+

The 2-dimensional cross-correlation minimum value +to consider two MUs to be the same. Ranges 0-1.

+
+

+ + TYPE: + float + + + DEFAULT: + 0.9 + +

+
matrixcode +
+

The code of the matrix used. This is necessary to sort the channels in +the correct order. If matrixcode="None", the electrodes are not sorted. +In this case, n_rows and n_cols must be specified.

+
+

+ + TYPE: + str {"GR08MM1305", "GR04MM1305", "GR10MM0808", "None"} + + + DEFAULT: + "GR08MM1305" + +

+
orientation +
+

Orientation in degree of the matrix (same as in OTBiolab). +E.g. 180 corresponds to the matrix connection toward the user.

+
+

+ + TYPE: + int {0, 180} + + + DEFAULT: + 180 + +

+
n_rows +
+

The number of rows and columns of the matrix. This parameter is used to +divide the channels based on the matrix shape. These are normally +inferred by the matrix code and must be specified only if code == None.

+
+

+ + TYPE: + None or int + + + DEFAULT: + None + +

+
n_cols +
+

The number of rows and columns of the matrix. This parameter is used to +divide the channels based on the matrix shape. These are normally +inferred by the matrix code and must be specified only if code == None.

+
+

+ + TYPE: + None or int + + + DEFAULT: + None + +

+
filter +
+

If true, when the same MU has a match of XCC > threshold with +multiple MUs, only the match with the highest XCC is returned.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
show +
+

Whether to plot the STA of pairs of MUs with XCC above threshold.

+
+

+ + TYPE: + bool + + + DEFAULT: + False + +

+
which +
+

How to remove the duplicated MUs.

+

munumber +Duplicated MUs are removed from the file with more MUs. +SIL +The MU with the lowest SIL is removed. +PNR +The MU with the lowest PNR is removed.

+
+

+ + TYPE: + str {"munumber", "PNR", "SIL"} + + + DEFAULT: + 'munumber' + +

+
+ + + + + + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ + emgfile1, emgfile2 : dict + + +
+

The original emgfiles without the duplicated MUs.

+
+
+ tracking_res + +
+

The results of the tracking including the MU from file 1, +MU from file 2 and the normalised cross-correlation value (XCC).

+
+

+ + TYPE: + pd.DataFrame + +

+
+

See also

+
    +
  • sta : computes the STA of every MUs.
  • +
  • norm_twod_xcorr : normalised 2-dimensional cross-correlation of STAs of + two MUS.
  • +
  • tracking : track MUs across two different files.
  • +
+ +

Examples:

+

Remove duplicated MUs between two OTB files and save the emgfiles +without duplicates. The duplicates are removed from the file with +more MUs.

+
>>> emgfile1 = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emgfile2 = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emgfile1, emgfile2, tracking_res = emg.remove_duplicates_between(
+...     emgfile1,
+...     emgfile2,
+...     firings="all",
+...     derivation="mono",
+...     timewindow=50,
+...     threshold=0.9,
+...     matrixcode="GR08MM1305",
+...     orientation=180,
+...     n_rows=None,
+...     n_cols=None,
+...     filter=True,
+...     show=False,
+...     which="munumber",
+... )
+>>> emg.asksavefile(emgfile1)
+>>> emg.asksavefile(emgfile2)
+
+ +
+ +


+ + +
+ + + +

+xcc_sta(sta) + +

+ + +
+ +

Cross-correlation between the STA of adjacent channels.

+

Calculate the normalised cross-correlation coefficient (XCC) between the +MUs action potential shapes on adjacent channels. +The XCC will be calculated for all the MUs and all the pairs of electrodes.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
sta +
+

The dict containing the spike-triggered average (STA) of all the MUs +computed with the function sta().

+
+

+ + TYPE: + dict + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ xcc_sta + +
+

A dict containing the XCC for all the pairs of channels and all the +MUs. This dict is organised as the sta dict.

+
+

+ + TYPE: + dict + +

+
+ +

Examples:

+

Calculate the XCC of adjacent channels of the double differential +derivation as done to calculate MUs conduction velocity.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True
+... )
+>>> dd = emg.double_diff(sorted_rawemg)
+>>> sta = emg.sta(
+...     emgfile=emgfile,
+...     sorted_rawemg=dd,
+...     firings=[0, 50],
+...     timewindow=50,
+... )
+>>> xcc_sta = emg.xcc_sta(sta)
+
+ +
+ +


+ + +
+ + + +

+MUcv_gui(emgfile, sorted_rawemg, n_firings=[0, 50], muaps_timewindow=50) + +

+ + +
+ + +

Graphical user interface for the estimation of MUs conduction velocity.

+

GUI for the estimation of MUs conduction velocity (CV) and amplitude of +the action potentials (root mean square - RMS).

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the first emgfile.

+
+

+ + TYPE: + dict + +

+
sorted_rawemg +
+

A dict containing the sorted electrodes. +Every key of the dictionary represents a different column of the +matrix. +Rows are stored in the dict as a pd.DataFrame.

+
+

+ + TYPE: + dict + +

+
n_firings +
+

The range of firnings to be used for the STA. +If a MU has less firings than the range, the upper limit +is adjusted accordingly. +all +The STA is calculated over all the firings.

+
+

+ + TYPE: + list or str {"all"} + + + DEFAULT: + [0, 50] + +

+
muaps_timewindow +
+

Timewindow to compute ST MUAPs in milliseconds.

+
+

+ + TYPE: + int + + + DEFAULT: + 50 + +

+
+ +

Examples:

+

Call the GUI.

+
>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True
+... )
+>>> gui = emg.MUcv_gui(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     n_firings=[0,50],
+...     muaps_timewindow=50
+... )
+
+ + + + + +
+ + + + + + + + + + + +
+ +
+ +


+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API_openfiles/index.html b/API_openfiles/index.html new file mode 100644 index 0000000..fcaa0f7 --- /dev/null +++ b/API_openfiles/index.html @@ -0,0 +1,2292 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + openfiles - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + +

openfiles

+ +

Description

+

This module contains all the functions that are necessary to open or save +MATLAB (.mat), JSON (.json) or custom (.csv) files.
+MATLAB files are used to store data from the DEMUSE and the OTBiolab+ +software while JSON files are used to save and load files from this +library.
+The choice of saving files in the open standard JSON file format was +preferred over the MATLAB file format since it has a better integration +with Python and has a very high cross-platform compatibility.

+

Function's scope

+
    +
  • emg_from_samplefile:
    + Used to load the sample file provided with the library.
  • +
  • emg_from_otb and emg_from_demuse:
    + Used to load .mat files coming from the DEMUSE or the OTBiolab+ + software. Demuse has a fixed file structure while the OTB file, in + order to be compatible with this library should be exported with a + strict structure as described in the function emg_from_otb. + In both cases, the input file is a .mat file.
  • +
  • refsig_from_otb:
    + Used to load files from the OTBiolab+ software that contain only + the REF_SIGNAL.
  • +
  • emg_from_customcsv:
    + Used to load custom file formats contained in .csv files.
  • +
  • save_json_emgfile, emg_from_json:
    + Used to save the working file to a .json file or to load the .json + file.
  • +
  • askopenfile, asksavefile:
    + A quick GUI implementation that allows users to select the file to + open or save.
  • +
+

Notes

+

Once opened, the file is returned as a dictionary with keys:

+

"SOURCE" : source of the file (e.g., "DEMUSE", "OTB", "custom")
+"RAW_SIGNAL" : the raw EMG signal
+"REF_SIGNAL" : the reference signal
+"PNR" : pulse to noise ratio
+"SIL" : silouette score
+"IPTS" : pulse train (decomposed source)
+"MUPULSES" : instants of firing
+"FSAMP" : sampling frequency
+"IED" : interelectrode distance
+"EMG_LENGTH" : length of the emg file (in samples)
+"NUMBER_OF_MUS" : total number of MUs
+"BINARY_MUS_FIRING" : binary representation of MUs firings

+

The only exception is when OTB files are loaded with just the reference signal:

+

"SOURCE": source of the file (i.e., "OTB_refsig")
+"FSAMP": sampling frequency
+"REF_SIGNAL": the reference signal

+

Additional informations can be found in the +info module and in the +function's description.

+


+ + +
+ + + +

+emg_from_samplefile() + +

+ + +
+ +

Load the sample file. This file has been decomposed with the OTBiolab+ +software and contains some reference MUs together with the force/reference +signal.

+

This file contains only few MUs for storage reasons.

+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ emgfile + +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
+ +
+ +


+ + +
+ + + +

+emg_from_otb(filepath, ext_factor=8, refsig=[True, 'fullsampled'], version='1.5.8.0') + +

+ + +
+ +

Import the .mat file exportable by OTBiolab+.

+

This function is used to import the .mat file exportable by the OTBiolab+ +software as a dictionary of Python objects (mainly pandas dataframes).

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
filepath +
+

The directory and the name of the file to load +(including file extension .mat). +This can be a simple string, the use of Path is not necessary.

+
+

+ + TYPE: + str or Path + +

+
ext_factor +
+

The extension factor used for the decomposition in OTbiolab+.

+
+

+ + TYPE: + int + + + DEFAULT: + 8 + +

+
refsig +
+

Whether to seacrh also for the REF_SIGNAL and whether to load the full +or sub-sampled one. The list is composed as [bool, str]. str can be +"fullsampled" or "subsampled". Please read notes section.

+
+

+ + TYPE: + list + + + DEFAULT: + [True, "fullsampled"] + +

+
version +
+

Version of the OTBiolab+ software used (4 points). +Tested versions are: +"1.5.3.0", +"1.5.4.0", +"1.5.5.0", +"1.5.6.0", +"1.5.7.2", +"1.5.7.3", +"1.5.8.0", +If your specific version is not available in the tested versions, +trying with the closer one usually works, but please double check the +results.

+
+

+ + TYPE: + str + + + DEFAULT: + "1.5.8.0" + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ emgfile + +
+

A dictionary containing all the useful variables.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • refsig_from_otb : import REF_SIGNAL in the .mat file exportable from + OTBiolab+.
  • +
  • emg_from_demuse : import the .mat file used in DEMUSE.
  • +
  • emg_from_customcsv : Import custom data from a .csv file.
  • +
+ + + + + + + + + + + + + + +
RAISESDESCRIPTION
+ + ValueError + + +
+

When a wrong value is passed to version=.

+
+
+

Notes

+

The returned file is called emgfile for convention.

+

The input .mat file exported from the OTBiolab+ software should have a +specific content: +- refsig signal is optional but, if present, there should be the + fullsampled or the subsampled version (in OTBioLab+ the "performed + path" refers to the subsampled signal, the "acquired data" to the + fullsampled signal), REF_SIGNAL is expected to be expressed as % of + the MVC (but not compulsory). +- Both the IPTS ('Source for decomposition...' in OTBioLab+) and the + BINARY_MUS_FIRING ('Decomposition of...' in OTBioLab+) should be + present. +- The raw EMG signal should be present (it has no specific name in + OTBioLab+) with all the channels. Don't exclude unwanted channels + before exporting the .mat file. +- NO OTHER ELEMENTS SHOULD BE PRESENT!

+

Structure of the returned emgfile: + emgfile = { + "SOURCE": SOURCE, + "FILENAME": FILENAME, + "RAW_SIGNAL": RAW_SIGNAL, + "REF_SIGNAL": REF_SIGNAL, + "PNR": PNR, + "SIL": SIL, + "IPTS": IPTS, + "MUPULSES": MUPULSES, + "FSAMP": FSAMP, + "IED": IED, + "EMG_LENGTH": EMG_LENGTH, + "NUMBER_OF_MUS": NUMBER_OF_MUS, + "BINARY_MUS_FIRING": BINARY_MUS_FIRING, + }

+ +

Examples:

+

For an extended explanation of the imported emgfile use:

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.emg_from_otb(filepath="path/filename.mat")
+>>> info = emg.info()
+>>> info.data(emgfile)
+
+ +
+ +


+ + +
+ + + +

+refsig_from_otb(filepath, refsig='fullsampled', version='1.5.8.0') + +

+ + +
+ +

Import REF_SIGNAL in the .mat file exportable by OTBiolab+.

+

This function is used to import the .mat file exportable by the OTBiolab+ +software as a dictionary of Python objects (mainly pandas dataframes). +Compared to the function emg_from_otb, this function only imports the +REF_SIGNAL and, therefore, it can be used for special cases where only the +REF_SIGNAL is necessary. This will allow a faster execution of the script +and to avoid exceptions for missing data.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
filepath +
+

The directory and the name of the file to load (including file +extension .mat). This can be a simple string, the use of Path is not +necessary.

+
+

+ + TYPE: + str or Path + +

+
refsig +
+

Whether to load the full or sub-sampled one. +Please read notes section.

+
+

+ + TYPE: + str {"fullsampled", "subsampled"} + + + DEFAULT: + "fullsampled" + +

+
version +
+

Version of the OTBiolab+ software used (4 points). +Tested versions are: +"1.5.3.0", +"1.5.4.0", +"1.5.5.0", +"1.5.6.0", +"1.5.7.2", +"1.5.7.3", +"1.5.8.0", +If your specific version is not available in the tested versions, +trying with the closer one usually works, but please double check the +results.

+
+

+ + TYPE: + str + + + DEFAULT: + "1.5.8.0" + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ emg_refsig + +
+

A dictionary containing all the useful variables.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • emg_from_otb : import the .mat file exportable by OTBiolab+.
  • +
  • emg_from_demuse : import the .mat file used in DEMUSE.
  • +
  • emg_from_customcsv : Import custom data from a .csv file.
  • +
+

Notes

+

The returned file is called emg_refsig for convention.

+

The input .mat file exported from the OTBiolab+ software should contain: +- refsig signal: there should be the fullsampled or the subsampled + version (in OTBioLab+ the "performed path" refers to the subsampled + signal, the "acquired data" to the fullsampled signal), REF_SIGNAL is + expected to be expressed as % of the MVC (but not compulsory).

+

Structure of the returned emg_refsig: + emg_refsig = { + "SOURCE": SOURCE, + "FILENAME": FILENAME, + "FSAMP": FSAMP, + "REF_SIGNAL": REF_SIGNAL, + }

+ +

Examples:

+

For an extended explanation of the imported emgfile use:

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.refsig_from_otb(filepath="path/filename.mat")
+>>> info = emg.info()
+>>> info.data(emgfile)
+
+ +
+ +


+ + +
+ + + +

+emg_from_demuse(filepath) + +

+ + +
+ +

Import the .mat file used in DEMUSE.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
filepath +
+

The directory and the name of the file to load +(including file extension .mat). +This can be a simple string, the use of Path is not necessary.

+
+

+ + TYPE: + str or Path + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ emgfile + +
+

A dictionary containing all the useful variables.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • emg_from_otb : import the .mat file exportable by OTBiolab+.
  • +
  • refsig_from_otb : import REF_SIGNAL in the .mat file exportable by + OTBiolab+.
  • +
  • emg_from_customcsv : Import custom data from a .csv file.
  • +
+

Notes

+

The returned file is called emgfile for convention.

+

The demuse file contains 65 raw EMG channels (1 empty) instead of 64 +(as for OTB matrix standards) in the case of a 64 electrodes matrix.

+

Structure of the emgfile: + emgfile = { + "SOURCE": SOURCE, + "FILENAME": FILENAME, + "RAW_SIGNAL": RAW_SIGNAL, + "REF_SIGNAL": REF_SIGNAL, + "PNR": PNR, + "SIL": SIL + "IPTS": IPTS, + "MUPULSES": MUPULSES, + "FSAMP": FSAMP, + "IED": IED, + "EMG_LENGTH": EMG_LENGTH, + "NUMBER_OF_MUS": NUMBER_OF_MUS, + "BINARY_MUS_FIRING": BINARY_MUS_FIRING, + }

+ +

Examples:

+

For an extended explanation of the imported emgfile:

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.emg_from_demuse(filepath="path/filename.mat")
+>>> info = emg.info()
+>>> info.data(emgfile)
+
+ +
+ +


+ + +
+ + + +

+emg_from_customcsv(filepath, ref_signal='REF_SIGNAL', raw_signal='RAW_SIGNAL', ipts='IPTS', mupulses='MUPULSES', binary_mus_firing='BINARY_MUS_FIRING', fsamp=2048, ied=8) + +

+ + +
+ +

Import custom data from a .csv file.

+

The variables of interest should be contained in columns. The name of the +columns containing each variable can be specified by the user if different +from the default values.

+

This function detects the content of the .csv by parsing the .csv columns. +For parsing, column labels should be provided. A label is a term common +to all the columns containing the same information. +For example, if the raw signal is contained in the columns 'RAW_SIGNAL_1', +'RAW_SIGNAL_2', ... , 'RAW_SIGNAL_n', the label of the columns should be +'RAW_SIGNAL'. +If the parameters in input are not present in the .csv file, the user +can simply leave the original inputs.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
filepath +
+

The directory and the name of the file to load +(including file extension .mat). +This can be a simple string, the use of Path is not necessary.

+
+

+ + TYPE: + str or Path + +

+
ref_signal +
+

Label of the column(s) containing the reference signal.

+
+

+ + TYPE: + str + + + DEFAULT: + 'REF_SIGNAL' + +

+
raw_signal +
+

Label of the column(s) containing the raw emg signal.

+
+

+ + TYPE: + str + + + DEFAULT: + 'RAW_SIGNAL' + +

+
ipts +
+

Label of the column(s) containing the pulse train.

+
+

+ + TYPE: + str + + + DEFAULT: + 'IPTS' + +

+
mupulses +
+

Label of the column(s) containing the times of firing.

+
+

+ + TYPE: + str + + + DEFAULT: + 'MUPULSES' + +

+
binary_mus_firing +
+

Label of the column(s) containing the binary representation +of the MUs firings.

+
+

+ + TYPE: + str + + + DEFAULT: + 'BINARY_MUS_FIRING' + +

+
fsamp +
+

Tha sampling frequency.

+
+

+ + TYPE: + int + + + DEFAULT: + 2048 + +

+
ied +
+

The inter-electrode distance in mm.

+
+

+ + TYPE: + int + + + DEFAULT: + 8 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ emgfile + +
+

A dictionary containing all the useful variables.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • emg_from_demuse : import the .mat file used in DEMUSE.
  • +
  • emg_from_otb : import the .mat file exportable by OTBiolab+.
  • +
  • refsig_from_otb : import REF_SIGNAL in the .mat file exportable by + OTBiolab+.
  • +
+

Notes

+

The returned file is called emgfile for convention.

+

Structure of the emgfile: + emgfile = { + "SOURCE": SOURCE, + "FILENAME": FILENAME, + "RAW_SIGNAL": RAW_SIGNAL, + "REF_SIGNAL": REF_SIGNAL, + "PNR": PNR, + "SIL": SIL + "IPTS": IPTS, + "MUPULSES": MUPULSES, + "FSAMP": FSAMP, + "IED": IED, + "EMG_LENGTH": EMG_LENGTH, + "NUMBER_OF_MUS": NUMBER_OF_MUS, + "BINARY_MUS_FIRING": BINARY_MUS_FIRING, + }

+ +

Examples:

+

An example of the .csv file to load:

+
>>>
+    REF_SIGNAL  RAW_SIGNAL (1)  RAW_SIGNAL (2)  RAW_SIGNAL (3) ...  IPTS (1)  IPTS (2)  MUPULSES (1)  MUPULSES (2)  BINARY_MUS_FIRING (1)  BINARY_MUS_FIRING (2)
+0            1        0.100000        0.100000        0.100000 ...  0.010000  0.010000           2.0           1.0                      0                      0
+1            2        2.000000        2.000000        2.000000 ...  0.001000  0.001000           5.0           2.0                      0                      0
+2            3        0.500000        0.500000        0.500000 ...  0.020000  0.020000           8.0           9.0                      0                      0
+3            4        0.150000        0.150000        0.150000 ...  0.002000  0.002000           9.0          15.0                      0                      1
+4            5        0.350000        0.350000        0.350000 ... -0.100000 -0.100000          15.0          18.0                      1                      1
+5            6        0.215000        0.215000        0.215000 ...  0.200000  0.200000          16.0           NaN                      1                      0
+
+

For an extended explanation of the imported emgfile use:

+
>>> import openhdemg.library as emg
+>>> emgfile = emg_from_customcsv(filepath = "mypath/file.csv")
+>>> info = emg.info()
+>>> info.data(emgfile)
+
+ +
+ +


+ + +
+ + + +

+save_json_emgfile(emgfile, filepath) + +

+ + +
+ +

Save the emgfile or emg_refsig as a JSON file.

+ + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
filepath +
+

The directory and the name of the file to save (including file +extension .json). +This can be a simple string; The use of Path is not necessary.

+
+

+ + TYPE: + str or Path + +

+
+ +
+ +


+ + +
+ + + +

+emg_from_json(filepath) + +

+ + +
+ +

Load the emgfile or emg_refsig stored in json format.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
filepath +
+

The directory and the name of the file to load (including file +extension .json). +This can be a simple string, the use of Path is not necessary.

+
+

+ + TYPE: + str or Path + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ emgfile + +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • emg_from_demuse : import the .mat file used in DEMUSE.
  • +
  • emg_from_otb : import the .mat file exportable by OTBiolab+.
  • +
  • refsig_from_otb : import REF_SIGNAL in the .mat file exportable by + OTBiolab+.
  • +
  • emg_from_customcsv : import custom data from a .csv file.
  • +
+

Notes

+

The returned file is called emgfile for convention +(or emg_refsig if SOURCE = "OTB_REFSIG").

+ +

Examples:

+

For an extended explanation of the imported emgfile use:

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile()
+>>> info = emg.info()
+>>> info.data(emgfile)
+
+ +
+ +


+ + +
+ + + +

+askopenfile(initialdir='/', filesource='OPENHDEMG', **kwargs) + +

+ + +
+ +

Select and open files with a GUI.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
initialdir +
+

The directory of the file to load (excluding file name). +This can be a simple string, the use of Path is not necessary.

+
+

+ + TYPE: + str or Path + + + DEFAULT: + "/" + +

+
filesource +
+

See notes for how files should be exported from OTB.

+

DEMUSE +File saved from DEMUSE (.mat). +OTB +File exported from OTB with decomposition and reference signal +(.mat). +OTB_REFSIG +File exported from OTB with only the reference signal (.mat). +CUSTOM +Custom file format (.csv). +OPENHDEMG +File saved from openhdemg (.json).

+
+

+ + TYPE: + str {"OPENHDEMG", "DEMUSE", "OTB", "OTB_REFSIG", "CUSTOM"} + + + DEFAULT: + "OPENHDEMG" + +

+
otb_ext_factor +
+

The extension factor used for the decomposition in the OTbiolab+ +software. +Ignore if loading other files.

+
+

+ + TYPE: + int + + + DEFAULT: + 8 + +

+
otb_refsig_type +
+

Whether to seacrh also for the REF_SIGNAL and whether to load the full +or sub-sampled one. The list is composed as [bool, str]. str can be +"fullsampled" or "subsampled". +Ignore if loading other files.

+
+

+ + TYPE: + list + + + DEFAULT: + [True, "fullsampled"] + +

+
otb_version +
+

Version of the OTBiolab+ software used (4 points). +Tested versions are: +"1.5.3.0", +"1.5.4.0", +"1.5.5.0", +"1.5.6.0", +"1.5.7.2", +"1.5.7.3", +"1.5.8.0", +If your specific version is not available in the tested versions, +trying with the closer one usually works, but please double check the +results. Ignore if loading other files.

+
+

+ + TYPE: + str + + + DEFAULT: + "1.5.8.0" + +

+
custom_ref_signal +
+

Label of the column(s) containing the reference signal of the custom +file. +This and the following arguments are needed only for custom files. +Ignore if loading other files.

+
+

+ + TYPE: + str + + + DEFAULT: + 'REF_SIGNAL' + +

+
custom_raw_signal +
+

Label of the column(s) containing the raw emg signal of the custom +file. Ignore if loading other files.

+
+

+ + TYPE: + str + + + DEFAULT: + 'RAW_SIGNAL' + +

+
custom_ipts +
+

Label of the column(s) containing the pulse train of the custom file. +Ignore if loading other files.

+
+

+ + TYPE: + str + + + DEFAULT: + 'IPTS' + +

+
custom_mupulses +
+

Label of the column(s) containing the times of firing of the custom +file. Ignore if loading other files.

+
+

+ + TYPE: + str + + + DEFAULT: + 'MUPULSES' + +

+
custom_binary_mus_firing +
+

Label of the column(s) containing the binary representation +of the MUs firings of the custom file. +Ignore if loading other files.

+
+

+ + TYPE: + str + + + DEFAULT: + 'BINARY_MUS_FIRING' + +

+
custom_fsamp +
+

Tha sampling frequency of the custom file. +Ignore if loading other files.

+
+

+ + TYPE: + int + + + DEFAULT: + 2048 + +

+
custom_ied +
+

The inter-electrode distance in mm of the custom file. +Ignore if loading other files.

+
+

+ + TYPE: + int + + + DEFAULT: + 8 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ emgfile + +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • asksavefile : select where to save files with a GUI.
  • +
+

Notes

+

The returned file is called emgfile for convention (or emg_refsig +if SOURCE = "OTB_REFSIG").

+

The input .mat file exported from the OTBiolab+ software should have a +specific content: +- refsig signal is optional but, if present, there should be both the + fullsampled and the subsampled version (in OTBioLab+ the "performed + path" refers to the subsampled signal, the "acquired data" to the + fullsampled signal), REF_SIGNAL is expected to be expressed as % of + the MViF (but not compulsory). +- Both the IPTS ('Source for decomposition...' in OTBioLab+) and the + BINARY_MUS_FIRING ('Decomposition of...' in OTBioLab+) should be + present. +- The raw EMG signal should be present (it has no specific name in + OTBioLab+) with all the channels. Don't exclude unwanted channels + before exporting the .mat file. +- NO OTHER ELEMENTS SHOULD BE PRESENT!

+

For custom .csv files: +The variables of interest should be contained in columns. The name of the +columns containing each variable can be specified by the user if different +from the default values. +This function detects the content of the .csv by parsing the .csv columns. +For parsing, column labels should be provided. A label is a term common +to all the columns containing the same information. +For example, if the raw signal is contained in the columns 'RAW_SIGNAL_1', +'RAW_SIGNAL_2', ... , 'RAW_SIGNAL_n', the label of the columns should be +'RAW_SIGNAL'. +If the parameters in input are not present in the .csv file, the user +can simply leave the original inputs. +Please see the documentation of the function emg_from_customcsv for +additional informations.

+

Structure of the returned emgfile: + emgfile = { + "SOURCE": SOURCE, + "FILENAME": FILENAME, + "RAW_SIGNAL": RAW_SIGNAL, + "REF_SIGNAL": REF_SIGNAL, + "PNR": PNR, + "SIL": SIL, + "IPTS": IPTS, + "MUPULSES": MUPULSES, + "FSAMP": FSAMP, + "IED": IED, + "EMG_LENGTH": EMG_LENGTH, + "NUMBER_OF_MUS": NUMBER_OF_MUS, + "BINARY_MUS_FIRING": BINARY_MUS_FIRING, + }

+

Structure of the returned emg_refsig: + emg_refsig = { + "SOURCE": SOURCE, + "FILENAME": FILENAME, + "FSAMP": FSAMP, + "REF_SIGNAL": REF_SIGNAL, + }

+ +

Examples:

+

For an extended explanation of the imported emgfile use:

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile()
+>>> info = emg.info()
+>>> info.data(emgfile)
+
+ +
+ +


+ + +
+ + + +

+asksavefile(emgfile) + +

+ + +
+ +

Select where to save files with a GUI.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile to save.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • askopenfile : select and open files with a GUI.
  • +
+ +
+ +


+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API_plotemg/index.html b/API_plotemg/index.html new file mode 100644 index 0000000..62c2164 --- /dev/null +++ b/API_plotemg/index.html @@ -0,0 +1,2949 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + plotemg - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

plotemg

+ +

Description

+

This module contains all the functions used to visualise the emg file, +the MUs properties or to save figures.

+


+ + +
+ + + +

+showgoodlayout(tight_layout=True, despined=False) + +

+ + +
+ +

Despine and show plots with a good layout.

+

This function is called by the various plot functions contained in the +library but can also be used by the user to quickly adjust the layout of +custom plots.

+ + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
tight_layout +
+

If true (default), plt.tight_layout() is applied to the figure.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
despined +
+

False: left and bottom is not despined (standard plotting). +True: all the sides are despined. +2yaxes +Only the top is despined. +This is used to show y axes both on the right and left side at the +same time.

+
+

+ + TYPE: + bool or str {"2yaxes"} + + + DEFAULT: + False + +

+
+ +
+ +


+ + +
+ + + +

+plot_emgsig(emgfile, channels, addrefsig=False, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True) + +

+ + +
+ +

Plot the RAW_SIGNAL. Single or multiple channels.

+

Up to 12 channels (a common matrix row) can be easily observed togheter +but more can be plotted.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
channels +
+

The channel (int) or channels (list of int) to plot. +The list can be passed as a manually-written list or with: +channels=[*range(0, 13)]. +We need the " * " operator to unpack the results of range into a list. +channels is expected to be with base 0 (i.e., the first channel +in the file is the number 0).

+
+

+ + TYPE: + int or list + +

+
addrefsig +
+

If True, the REF_SIGNAL is plotted in front of the signal with a +separated y-axes.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
timeinseconds +
+

Whether to show the time on the x-axes in seconds (True) +or in samples (False).

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
tight_layout +
+

If True (default), the plt.tight_layout() is called and the figure's +layout is improved. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+

See also

+
    +
  • plot_differentials : plot the differential derivation of the RAW_SIGNAL + by matrix column.
  • +
+ +

Examples:

+

Plot channels 0 to 12 and overlay the reference signal.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emg.plot_emgsig(
+...     emgfile=emgfile,
+...     channels=[*range(0,13)],
+...     addrefsig=True,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+... )
+
+ +
+ +


+ + +
+ + + +

+plot_differentials(emgfile, differential, column='col0', addrefsig=False, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True) + +

+ + +
+ +

Plot the differential derivation of the RAW_SIGNAL by matrix column.

+

Both the single and the double differencials can be plotted. +This function is used to plot also the sorted RAW_SIGNAL.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the original emgfile.

+
+

+ + TYPE: + dict + +

+
differential +
+

The dictionary containing the differential derivation of the +RAW_SIGNAL.

+
+

+ + TYPE: + dict + +

+
column +
+

The matrix column to plot. +Options are usyally "col0", "col1", "col2", "col3", "col4". +but might change based on the size of the matrix used.

+
+

+ + TYPE: + str {"col0", "col1", "col2", "col3", "col4", ...} + + + DEFAULT: + "col0" + +

+
addrefsig +
+

If True, the REF_SIGNAL is plotted in front of the signal with a +separated y-axes.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
timeinseconds +
+

Whether to show the time on the x-axes in seconds (True) +or in samples (False).

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
tight_layout +
+

If True (default), the plt.tight_layout() is called and the figure's +layout is improved. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+

See also

+
    +
  • diff : calculate single differential of RAW_SIGNAL on matrix rows.
  • +
  • double_diff : calculate double differential of RAW_SIGNAL on matrix rows.
  • +
  • plot_emgsig : pot the RAW_SIGNAL. Single or multiple channels.
  • +
+ +

Examples:

+

Plot the differential derivation of the first matrix column (col0).

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+>>>     emgfile=emgfile,
+>>>     code="GR08MM1305",
+>>>     orientation=180,
+>>> )
+>>> sd=emg.diff(sorted_rawemg=sorted_rawemg)
+>>> emg.plot_differentials(
+...     emgfile=emgfile,
+...     differential=sd,
+...     column="col0",
+...     addrefsig=False,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+ +
+ +


+ + +
+ + + +

+plot_refsig(emgfile, ylabel='MVC', timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True) + +

+ + +
+ +

Plot the REF_SIGNAL.

+

The REF_SIGNAL is usually expressed as % MVC for submaximal contractions +or as Kilograms (Kg) or Newtons (N) for maximal contractions, but any +value can be plotted.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
ylabel +
+

The unit of measure to show on the Y axis.

+
+

+ + TYPE: + str + + + DEFAULT: + "MVC" + +

+
timeinseconds +
+

Whether to show the time on the x-axes in seconds (True) +or in samples (False).

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
tight_layout +
+

If True (default), the plt.tight_layout() is called and the figure's +layout is improved. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+ +

Examples:

+

Plot the reference signal.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emg.plot_refsig(emgfile=emgfile)
+
+

Change Y axis label and show time in samples.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emg.plot_refsig(
+>>>     emgfile=emgfile,
+>>>     ylabel="Custom unit e.g., N or kg",
+>>>     timeinseconds=False,
+>>> )
+
+ +
+ +


+ + +
+ + + +

+plot_mupulses(emgfile, munumber='all', linewidths=0.5, addrefsig=True, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True) + +

+ + +
+ +

Plot all the MUPULSES (binary representation of the firings time).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
munumber +
+

all +IPTS of all the MUs is plotted.

+

Otherwise, a single MU (int) or multiple MUs (list of int) can be +specified. +The list can be passed as a manually-written list or with: +munumber=[*range(0, 12)]. +We need the " * " operator to unpack the results of range into a list. +munumber is expected to be with base 0 (i.e., the first MU in the file +is the number 0).

+
+

+ + TYPE: + str {"all"}, int or list + + + DEFAULT: + "all" + +

+
linewidths +
+

The width of the vertical lines representing the MU firing.

+
+

+ + TYPE: + float + + + DEFAULT: + 0.5 + +

+
addrefsig +
+

If True, the REF_SIGNAL is plotted in front of the MUs pulses with a +separated y-axes.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
timeinseconds +
+

Whether to show the time on the x-axes in seconds (True) +or in samples (False).

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
tight_layout +
+

If True (default), the plt.tight_layout() is called and the figure's +layout is improved. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+

See also

+
    +
  • plot_ipts : plot the MUs impulse train per second (IPTS).
  • +
  • plot_idr : plot the instantaneous discharge rate.
  • +
+ +

Examples:

+

Plot MUs pulses based on recruitment order and overlay the reference +signal.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emg.plot_mupulses(
+...     emgfile=emgfile,
+...     linewidths=0.5,
+...     order=True,
+...     addrefsig=True,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+ +
+ +


+ + +
+ + + +

+plot_ipts(emgfile, munumber='all', addrefsig=False, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True) + +

+ + +
+ +

Plot the IPTS (decomposed source).

+

IPTS is the non-binary representation of the MUs firing times.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
munumber +
+

all +IPTS of all the MUs is plotted.

+

Otherwise, a single MU (int) or multiple MUs (list of int) can be +specified. +The list can be passed as a manually-written list or with: +munumber=[*range(0, 12)]. +We need the " * " operator to unpack the results of range into a list. +munumber is expected to be with base 0 (i.e., the first MU in the file +is the number 0).

+
+

+ + TYPE: + str {"all"}, int or list + + + DEFAULT: + "all" + +

+
timeinseconds +
+

Whether to show the time on the x-axes in seconds (True) +or in samples (False).

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
tight_layout +
+

If True (default), the plt.tight_layout() is called and the figure's +layout is improved. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+

See also

+
    +
  • plot_mupulses : plot the binary representation of the firings.
  • +
  • plot_idr : plot the instantaneous discharge rate.
  • +
+

Notes

+

munumber = "all" corresponds to: +munumber = [*range(0, emgfile["NUMBER_OF_MUS"])]

+ +

Examples:

+

Plot IPTS of all the MUs and overlay the reference signal.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emg.plot_ipts(
+...     emgfile=emgfile,
+...     munumber="all",
+...     addrefsig=True,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+

Plot IPTS of two MUs.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emg.plot_ipts(
+...     emgfile=emgfile,
+...     munumber=[1, 3],
+...     addrefsig=False,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+ +
+ +


+ + +
+ + + +

+plot_idr(emgfile, munumber='all', addrefsig=True, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True) + +

+ + +
+ +

Plot the instantaneous discharge rate (IDR).

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
munumber +
+

``all" +IDR of all the MUs is plotted.

+

Otherwise, a single MU (int) or multiple MUs (list of int) can be +specified. +The list can be passed as a manually-written list or with: +munumber=[*range(0, 12)]. +We need the " * " operator to unpack the results of range into a list. +munumber is expected to be with base 0 (i.e., the first MU in the file +is the number 0).

+
+

+ + TYPE: + str, int or list + + + DEFAULT: + "all" + +

+
addrefsig +
+

If True, the REF_SIGNAL is plotted in front of the MUs IDR with a +separated y-axes.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
timeinseconds +
+

Whether to show the time on the x-axes in seconds (True) +or in samples (False).

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
tight_layout +
+

If True (default), the plt.tight_layout() is called and the figure's +layout is improved. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+

See also

+
    +
  • plot_mupulses : plot the binary representation of the firings.
  • +
  • plot_ipts : plot the impulse train per second (IPTS).
  • +
+

Notes

+

munumber = "all" corresponds to +munumber = [*range(0, emgfile["NUMBER_OF_MUS"])]

+ +

Examples:

+

Plot IDR of all the MUs and overlay the reference signal.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emg.plot_idr(
+...     emgfile=emgfile,
+...     munumber="all",
+...     addrefsig=True,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+

Plot IDR of two MUs.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emg.plot_idr(
+...     emgfile=emgfile,
+...     munumber=[1, 3],
+...     addrefsig=False,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+ +
+ +


+ + +
+ + + +

+plot_muaps(sta_dict, title='MUAPs from STA', figsize=[20, 15], showimmediately=True) + +

+ + +
+ +

Plot MUAPs obtained from STA from one or multiple MUs.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
sta_dict +
+

dict containing STA of the specified MU or a list of dicts containing +STA of specified MUs. +If a list is passed, different MUs are overlayed. This is useful for +visualisation of MUAPs during tracking or duplicates removal.

+
+

+ + TYPE: + dict or list + +

+
title +
+

Title of the plot.

+
+

+ + TYPE: + str + + + DEFAULT: + "MUAPs from STA" + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+

See also

+
    +
  • sta : computes the spike-triggered average (STA) of every MUs.
  • +
  • plot_muap : for overplotting all the STAs and the average STA of a MU.
  • +
  • align_by_xcorr : for alignin the STAs of two different MUs.
  • +
+

Notes

+

There is no limit to the number of MUs and STA files that can be +overplotted. +Remember: the different STAs should be matched with same number of + electrode, processing (i.e., differential) and computed on the same + timewindow.

+ +

Examples:

+

Plot MUAPs of a single MU.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True,
+... )
+>>> sta = emg.sta(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     firings="all",
+...     timewindow=50,
+... )
+>>> emg.plot_muaps(sta_dict=sta[1])
+
+

Plot single differential derivation MUAPs of a single MU.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True,
+... )
+>>> sorted_rawemg = emg.diff(sorted_rawemg=sorted_rawemg)
+>>> sta = emg.sta(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     firings="all",
+...     timewindow=50,
+... )
+>>> emg.plot_muaps(sta_dict=sta[1])
+
+

Plot single differential derivation MUAPs of two MUs from the same file.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True,
+... )
+>>> sorted_rawemg = emg.diff(sorted_rawemg=sorted_rawemg)
+>>> sta = emg.sta(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     firings="all",
+...     timewindow=50,
+... )
+>>> emg.plot_muaps(sta_dict=[sta[1], sta[2]])
+
+ +
+ +


+ + +
+ + + +

+plot_muap(emgfile, stmuap, munumber, column, channel, channelprog=False, average=True, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True) + +

+ + +
+ +

Plot the MUAPs of a specific matrix channel.

+

Plot the MUs action potential (MUAPs) shapes with or without average.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
stmuap +
+

dict containing a dict of ST MUAPs (pd.DataFrame) for every MUs.

+
+

+ + TYPE: + dict + +

+
munumber +
+

The number of the MU to plot.

+
+

+ + TYPE: + int + +

+
column +
+

The matrix columns. +Options are usyally "col0", "col1", "col2", ..., last column.

+
+

+ + TYPE: + str + +

+
channel +
+

The channel of the matrix to plot. +This can be the real channel number if channelprog=False (default), +or a progressive number (from 0 to the length of the matrix column) +if channelprog=True.

+
+

+ + TYPE: + int + +

+
channelprog +
+

Whether to use the real channel number or a progressive number +(see channel).

+
+

+ + TYPE: + bool + + + DEFAULT: + False + +

+
average +
+

Whether to plot also the MUAPs average obtained by spike triggered +average.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
timeinseconds +
+

Whether to show the time on the x-axes in seconds (True) +or in samples (False).

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
tight_layout +
+

If True (default), the plt.tight_layout() is called and the figure's +layout is improved. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+

See also

+
    +
  • plot_muaps : Plot MUAPs obtained from STA from one or multiple MUs.
  • +
  • st_muap : Generate spike triggered MUAPs of every MUs + (as input to this function).
  • +
+ +

Examples:

+

Plot all the consecutive MUAPs of a single MU. +In this case we are plotting the matrix channel 45 which is placed in +column 4 ("col3") as Python numbering is base 0.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True,
+... )
+>>> stmuap = emg.st_muap(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     timewindow=50,
+... )
+>>> emg.plot_muap(
+...     emgfile=emgfile,
+...     stmuap=stmuap,
+...     munumber=1,
+...     column="col3",
+...     channel=45,
+...     channelprog=False,
+...     average=False,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+

To avoid the problem of remebering which channel number is present in +which matrix column, we can set channelprog=True and locate the channel +with a value ranging from 0 to the length of each column.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True,
+... )
+>>> stmuap = emg.st_muap(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     timewindow=50,
+... )
+>>> emg.plot_muap(
+...     emgfile=emgfile,
+...     stmuap=stmuap,
+...     munumber=1,
+...     column="col3",
+...     channel=5,
+...     channelprog=True,
+...     average=False,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+

It is also possible to visualise the spike triggered average +of the MU with average=True. +In this example the single differential derivation is used.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile=emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True,
+... )
+>>> sorted_rawemg = emg.diff(sorted_rawemg=sorted_rawemg)
+>>> stmuap = emg.st_muap(
+...     emgfile=emgfile,
+...     sorted_rawemg=sorted_rawemg,
+...     timewindow=50,
+... )
+>>> emg.plot_muap(
+...     emgfile=emgfile,
+...     stmuap=stmuap,
+...     munumber=1,
+...     column="col2",
+...     channel=6,
+...     channelprog=True,
+...     average=True,
+...     timeinseconds=True,
+...     figsize=[20, 15],
+...     showimmediately=True,
+... )
+
+ +
+ +


+ + +
+ + + +

+plot_muaps_for_cv(sta_dict, xcc_sta_dict, title='MUAPs for CV', figsize=[20, 15], showimmediately=True) + +

+ + +
+ +

Visualise MUAPs on which to calculate MUs CV.

+

Plot MUAPs obtained from the STA of the double differential signal and +their paired cross-correlation value.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
sta_dict +
+

dict containing the STA of the double-differential derivation of a +specific MU.

+
+

+ + TYPE: + dict + +

+
xcc_sta_dict +
+

dict containing the normalised cross-correlation coefficient of the +double-differential derivation of a specific MU.

+
+

+ + TYPE: + dict + +

+
title +
+

Title of the plot.

+
+

+ + TYPE: + str + + + DEFAULT: + "MUAPs from STA" + +

+
figsize +
+

Size of the figure in centimeters [width, height].

+
+

+ + TYPE: + list + + + DEFAULT: + [20, 15] + +

+
showimmediately +
+

If True (default), plt.show() is called and the figure showed to the +user. +It is useful to set it to False when calling the function from the GUI.

+
+

+ + TYPE: + bool + + + DEFAULT: + True + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ fig + +
+ +
+

+ + TYPE: + pyplot `~.figure.Figure` + +

+
+ +

Examples:

+

Plot the double differential derivation and the XCC of adjacent channels +for the first MU (0).

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> sorted_rawemg = emg.sort_rawemg(
+...     emgfile,
+...     code="GR08MM1305",
+...     orientation=180,
+...     dividebycolumn=True
+... )
+>>> dd = emg.double_diff(sorted_rawemg)
+>>> sta = emg.sta(
+...     emgfile=emgfile,
+...     sorted_rawemg=dd,
+...     firings=[0, 50],
+...     timewindow=50,
+... )
+>>> xcc_sta = emg.xcc_sta(sta)
+>>> fig = emg.plot_muaps_for_cv(
+...     sta_dict=sta[0],
+...     xcc_sta_dict=xcc_sta[0],
+...     showimmediately=False,
+... )
+
+ +
+ +


+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/API_tools/index.html b/API_tools/index.html new file mode 100644 index 0000000..ec8b453 --- /dev/null +++ b/API_tools/index.html @@ -0,0 +1,2381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + tools - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+ +
+ + + +
+
+ + + + + + + +

tools

+ +

Description

+

This module contains the functions that don't properly apply to the plot +or analysis category but that are necessary for the usability of the library. +The functions contained in this module can be considered as "tools" or +shortcuts necessary to operate with the HD-EMG recordings.

+


+ + +
+ + + +

+showselect(emgfile, title='', titlesize=12, nclic=2) + +

+ + +
+ +

Select a part of the recording.

+

The area can be selected (based on the REF_SIGNAL) with any letter or +number in the keyboard, wrong points can be removed by pressing the +right mouse button. Once finished, press enter to continue.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile and in particular the REF_SIGNAL +(which is used for the selection).

+
+

+ + TYPE: + dict + +

+
title +
+

The title of the plot. It is optional but strongly recommended. +It should describe the task to do.

+
+

+ + TYPE: + str + + + DEFAULT: + '' + +

+
titlesize +
+

The font size of the title.

+
+

+ + TYPE: + int + + + DEFAULT: + 12 + +

+
nclic +
+

The number of clics to be collected. If nclic < 1, all the clicks are +collected.

+
+

+ + DEFAULT: + 2 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ points + +
+

A list containing the selected points sorted in ascending order.

+
+

+ + TYPE: + list + +

+
+ + + + + + + + + + + + + + +
RAISESDESCRIPTION
+ + ValueError + + +
+

When the user clicked a wrong number of inputs in the GUI.

+
+
+ +

Examples:

+

Load the EMG file and select the points.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB_REFSIG")
+>>> points = emg.showselect(
+...     emgfile,
+...     title="Select 2 points",
+...     nclic=2,
+... )
+>>> points
+[16115, 40473]
+
+ +
+ +


+ + +
+ + + +

+create_binary_firings(emg_length, number_of_mus, mupulses) + +

+ + +
+ +

Create a binary representation of the MU firing.

+

Create a binary representation of the MU firing over time +based on the times of firing of each MU.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emg_length +
+

Number of samples (length) in the emg file.

+
+

+ + TYPE: + int + +

+
number_of_mus +
+

Number of MUs in the emg file.

+
+

+ + TYPE: + int + +

+
mupulses +
+

Each ndarray should contain the times of firing of each MU.

+
+

+ + TYPE: + list of ndarrays + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ binary_MUs_firing + +
+

A pd.DataFrame containing the binary representation of MUs firing or +np.nan if the variable was not found.

+
+

+ + TYPE: + pd.DataFrame + +

+
+ +
+ +


+ + +
+ + + +

+resize_emgfile(emgfile, area=None) + +

+ + +
+ +

Resize all the emgfile.

+

This function can be useful to compute the various parameters only in the +area of interest.

+ + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile to resize.

+
+

+ + TYPE: + dict + +

+
area +
+

The resizing area. If already known, it can be passed in samples, as a +list (e.g., [120,2560]). +If None, the user can select the area of interest manually.

+
+

+ + TYPE: + None or list + + + DEFAULT: + None + +

+
+ + + + + + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ rs_emgfile + +
+

the new (resized) emgfile.

+
+

+ + TYPE: + dict + +

+
+ + start_, end_ : int + + +
+

the start and end of the selection (can be used for code automation).

+
+
+

Notes

+

Suggested names for the returned objects: rs_emgfile, start_, end_.

+

PNR and SIL are computed again in the new resized area.

+ +
+ +


+ + +
+ + + +

+compute_idr(emgfile) + +

+ + +
+ +

Compute the IDR.

+

This function computes the instantaneous discharge rate (IDR) from the +MUPULSES. +The IDR is very useful for plotting and visualisation of the MUs behaviour.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ idr + +
+

A dict containing a pd.DataFrame for each MU (keys are integers). +Accessing the key, we have a pd.DataFrame containing: +mupulses: firing sample. +diff_mupulses: delta between consecutive firing samples. +timesec: delta between consecutive firing samples in seconds. +idr: instantaneous discharge rate.

+
+

+ + TYPE: + dict + +

+
+ +

Examples:

+

Load the EMG file, compute IDR and access the results for the first MU.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> idr = emg.compute_idr(emgfile=emgfile)
+>>> munumber = 0
+>>> idr[munumber]
+    mupulses  diff_mupulses    timesec       idr
+0        9221            NaN   4.502441       NaN
+1        9580          359.0   4.677734  5.704735
+2        9973          393.0   4.869629  5.211196
+3       10304          331.0   5.031250  6.187311
+4       10617          313.0   5.184082  6.543131
+..        ...            ...        ...       ...
+149     54521          395.0  26.621582  5.184810
+150     54838          317.0  26.776367  6.460568
+151     55417          579.0  27.059082  3.537133
+152     55830          413.0  27.260742  4.958838
+153     56203          373.0  27.442871  5.490617
+
+ +
+ +


+ + +
+ + + +

+delete_mus(emgfile, munumber, if_single_mu='ignore') + +

+ + +
+ +

Delete unwanted MUs.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
munumber +
+

The MUs to remove. If a single MU has to be removed, this should be an +int (number of the MU). +If multiple MUs have to be removed, a list of int should be passed. +An unpacked (*) range can also be passed as munumber=[*range(0, 5)]. +munumber is expected to be with base 0 (i.e., the first MU in the file +is the number 0).

+
+

+ + TYPE: + int, list of int + +

+
if_single_mu +
+

A string indicating how to behave in case of a file with a single MU.

+

ignore +Ignore the process and return the original emgfile. (Default) +remove +Remove the MU and return the emgfile without the MU. (Default) +This should allow full compatibility with the use of this file +in following processing (i.e., save/load and analyse).

+
+

+ + TYPE: + str {"ignore", "remove"} + + + DEFAULT: + "ignore" + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ emgfile + +
+

The dictionary containing the emgfile without the unwanted MUs.

+
+

+ + TYPE: + dict + +

+
+ +

Examples:

+

Delete MUs 1,4,5 from the emgfile.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> emgfile = emg.delete_mus(emgfile=emgfile, munumber=[1,4,5])
+
+ +
+ +


+ + +
+ + + +

+sort_mus(emgfile) + +

+ + +
+ +

Sort the MUs in order of recruitment.

+ + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ sorted_emgfile + +
+

The dictionary containing the sorted emgfile.

+
+

+ + TYPE: + dict + +

+
+ +
+ +


+ + +
+ + + +

+compute_covsteady(emgfile, start_steady=-1, end_steady=-1) + +

+ + +
+ +

Calculates the covsteady.

+

This function calculates the coefficient of variation of the steady-state +phase (covsteady of the REF_SIGNAL).

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
start_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
end_steady +
+

The start and end point (in samples) of the steady-state phase. +If < 0 (default), the user will need to manually select the start and +end of the steady-state phase.

+
+

+ + TYPE: + int + + + DEFAULT: + -1 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ covsteady + +
+

The coefficient of variation of the steady-state phase in %.

+
+

+ + TYPE: + float + +

+
+

See also

+
    +
  • compute_idr : computes the instantaneous discharge rate.
  • +
+ +

Examples:

+

Load the EMG file, compute covsteady and access the result from GUI.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> covsteady = emg.compute_covsteady(emgfile=emgfile)
+>>> covsteady
+1.452806
+
+

The process can be automated by bypassing the GUI.

+
>>> import openhdemg.library as emg
+>>> emgfile = emg.askopenfile(filesource="OTB", otb_ext_factor=8)
+>>> covsteady = emg.compute_covsteady(
+...     emgfile=emgfile,
+...     start_steady=3580,
+...     end_steady=15820,
+... )
+>>> covsteady
+35.611263
+
+ +
+ +


+ + +
+ + + +

+filter_rawemg(emgfile, order=2, lowcut=20, highcut=500) + +

+ + +
+ +

Band-pass filter the RAW_SIGNAL.

+

The filter is a Zero-lag band-pass Butterworth.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
order +
+

The filter order.

+
+

+ + TYPE: + int + + + DEFAULT: + 2 + +

+
lowcut +
+

The lower cut-off frequency in Hz.

+
+

+ + TYPE: + int + + + DEFAULT: + 20 + +

+
highcut +
+

The higher cut-off frequency in Hz.

+
+

+ + TYPE: + int + + + DEFAULT: + 500 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ filteredrawsig + +
+

The dictionary containing the emgfile with a filtered RAW_SIGNAL.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • filter_refsig : low-pass filter the REF_SIGNAL.
  • +
+ +
+ +


+ + +
+ + + +

+filter_refsig(emgfile, order=4, cutoff=15) + +

+ + +
+ +

Low-pass filter the REF_SIGNAL.

+

This function is used to low-pass filter the REF_SIGNAL and remove noise. +The filter is a Zero-lag low-pass Butterworth.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
order +
+

The filter order.

+
+

+ + TYPE: + int + + + DEFAULT: + 4 + +

+
cutoff +
+

The cut-off frequency in Hz.

+
+

+ + TYPE: + int + + + DEFAULT: + 15 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ filteredrefsig + +
+

The dictionary containing the emgfile with a filtered REF_SIGNAL.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • remove_offset : remove the offset from the REF_SIGNAL.
  • +
  • filter_rawemg : band-pass filter the RAW_SIGNAL.
  • +
+ +
+ +


+ + +
+ + + +

+remove_offset(emgfile, offsetval=0, auto=0) + +

+ + +
+ +

Remove the offset from the REF_SIGNAL.

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile.

+
+

+ + TYPE: + dict + +

+
offsetval +
+

Value of the offset. If offsetval is 0 (default), the user will be +asked to manually select an aerea to compute the offset value. +Otherwise, the value passed to offsetval will be used. +Negative offsetval can be passed.

+
+

+ + TYPE: + float + + + DEFAULT: + 0 + +

+
auto +
+

If auto > 0, the script automatically removes the offset based on the +number of samples passed in input.

+
+

+ + TYPE: + int + + + DEFAULT: + 0 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ offs_emgfile + +
+

The dictionary containing the emgfile with a corrected offset of the +REF_SIGNAL.

+
+

+ + TYPE: + dict + +

+
+

See also

+
    +
  • filter_refsig : low-pass filter REF_SIGNAL.
  • +
+ +
+ +


+ + +
+ + + +

+get_mvc(emgfile, how='showselect', conversion_val=0) + +

+ + +
+ +

Measure the maximum voluntary contraction (MVC).

+ + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile with the reference signal.

+
+

+ + TYPE: + dict + +

+
how +
+

showselect +Ask the user to select the area where to calculate the MVC +with a GUI. +all +Calculate the MVC on the entire file.

+
+

+ + TYPE: + str {"showselect", "all"} + + + DEFAULT: + "showselect" + +

+
conversion_val +
+

The conversion value to multiply the original reference signal. +I.e., if the original reference signal is in kilogram (kg) and +conversion_val=9.81, the output will be in Newton/Sec (N/Sec). +If conversion_val=0 (default), the results will simply be Original +measure unit. conversion_val can be any custom int or float.

+
+

+ + TYPE: + float or int + + + DEFAULT: + 0 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ mvc + +
+

The MVC value in the original (or converted) unit of measurement.

+
+

+ + TYPE: + float + +

+
+

See also

+
    +
  • compute_rfd : calculate the RFD.
  • +
  • remove_offset : remove the offset from the REF_SIGNAL.
  • +
  • filter_refsig : low-pass filter REF_SIGNAL.
  • +
+ +

Examples:

+

Load the EMG file, remove reference signal offset and get MVC value.

+
>>> import openhdemg.library as emg
+>>> emg_refsig = emg.askopenfile(filesource="OTB_REFSIG")
+>>> offs_refsig = emg.remove_offset(emgfile=emg_refsig)
+>>> mvc = emg.get_mvc(emgfile=offs_refsig )
+>>> mvc
+50.72
+
+

The process can be automated by bypassing the GUI and +calculating the MVC of the entire file.

+
>>> import openhdemg.library as emg
+>>> emg_refsig = emg.askopenfile(filesource="OTB_REFSIG")
+>>> mvc = emg.get_mvc(emgfile=emg_refsig, how="all")
+>>> print(mvc)
+50.86
+
+ +
+ +


+ + +
+ + + +

+compute_rfd(emgfile, ms=[50, 100, 150, 200], startpoint=None, conversion_val=0) + +

+ + +
+ +

Calculate the RFD.

+

Rate of force development (RFD) is reported as X/Sec +where "X" is the unit of measurement based on conversion_val.

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
PARAMETERDESCRIPTION
emgfile +
+

The dictionary containing the emgfile with the reference signal.

+
+

+ + TYPE: + dict + +

+
ms +
+

Milliseconds (ms). A list containing the ranges in ms to calculate the +RFD.

+
+

+ + TYPE: + list + + + DEFAULT: + [50, 100, 150, 200] + +

+
startpoint +
+

The starting point to calculate the RFD in samples, +If None, the user will be requested to manually select the starting +point.

+
+

+ + TYPE: + None or int + + + DEFAULT: + None + +

+
conversion_val +
+

The conversion value to multiply the original reference signal. +I.e., if the original reference signal is in kilogram (kg) and +conversion_val=9.81, the output will be in Newton/Sec (N/Sec). +If conversion_val=0 (default), the results will simply be Original +measure unit/Sec. conversion_val can be any custom int or float.

+
+

+ + TYPE: + float or int + + + DEFAULT: + 0 + +

+
+ + + + + + + + + + + + + + +
RETURNSDESCRIPTION
+ rfd + +
+

A pd.DataFrame containing the RFD at the different times.

+
+

+ + TYPE: + pd.DataFrame + +

+
+

See also

+
    +
  • get_mvif : measure the MViF.
  • +
  • remove_offset : remove the offset from the REF_SIGNAL.
  • +
  • filter_refsig : low-pass filter REF_SIGNAL.
  • +
+ +

Examples:

+

Load the EMG file, low-pass filter the reference signal and compute RFD.

+
>>> import openhdemg.library as emg
+>>> emg_refsig = emg.askopenfile(filesource="OTB_REFSIG")
+>>> filteredrefsig  = emg.filter_refsig(
+...     emgfile=emg_refsig,
+...     order=4,
+...     cutoff=15,
+... )
+>>> rfd = emg.compute_rfd(
+...     emgfile=filteredrefsig,
+...     ms=[50, 100, 200],
+...     conversion_val=9.81,
+...     )
+>>> rfd
+        50         100        200
+0  68.34342  79.296188  41.308215
+
+

The process can be automated by bypassing the GUI.

+
>>> import openhdemg.library as emg
+>>> emg_refsig = emg.askopenfile(filesource="OTB_REFSIG")
+>>> filteredrefsig  = emg.filter_refsig(
+...     emgfile=emg_refsig,
+...     order=4,
+...     cutoff=15,
+...     )
+>>> rfd = emg.compute_rfd(
+...     emgfile=filteredrefsig,
+...     ms=[50, 100, 200],
+...     startpoint=3568,
+...     )
+>>> rfd
+        50         100        200
+0  68.34342  79.296188  41.308215
+
+ +
+ +


+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Cite-Us/index.html b/Cite-Us/index.html new file mode 100644 index 0000000..2e6c39d --- /dev/null +++ b/Cite-Us/index.html @@ -0,0 +1,679 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Cite Us - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

Cite Us

+ +

If you use openhdemg for your reaserch, please cite the project as:

+

We are working to publish soon..

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Contacts/index.html b/Contacts/index.html new file mode 100644 index 0000000..abf3c8f --- /dev/null +++ b/Contacts/index.html @@ -0,0 +1,795 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Contacts - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

Contacts

+ +

Primary contact

+

  Giacomo Valli: giacomo.valli@phd.unipd.it

+

Discussion forum

+

  Read answers or ask questions in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

+

Follow us on Twitter

+

  https://twitter.com/openhdemg

+

Meet the developers

+

Giacomo Valli:

+
    +
  • +

    The creator of the project and the developer of the library.

    +
  • +
  • +

    Giacomo Valli obtained a master degree in Sports Science and a research fellowship in molecular biology of exercise at the University of Urbino (IT). He is currently a PhD student at the University of Padova (IT) in neuromuscular physiology. He is investigating the electrophysiological modifications happening during disuse, disease and aging and linking this information to the molecular alterations of the muscle.

    +
  • +
+

Paul Ritsche:

+
    +
  • +

    The developer of the GUI.

    +
  • +
  • +

    Paul Ritsche obtained a master degree in Sports Science at the University of Basel (CH). He is currently a research associate at the University of Basel (CH) focusing on muscle ultrasonography. He is investigating automatic ultrasonography image analysis methods to evaluate muscle morphological as well architectural parameters.

    +
  • +
+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/GUI_advanced/index.html b/GUI_advanced/index.html new file mode 100644 index 0000000..63c39ac --- /dev/null +++ b/GUI_advanced/index.html @@ -0,0 +1,889 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + advanced - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

Graphical Interface

+

This is the toturial for the Advanced Tools in the openhdemg GUI. Great that you made it this far! In the next few sections we will take a look at the more advanced functions implemented in the GUI. But first of all, you need to click the Advanced Toolsbutton in the main window of the GUI to get to the respective adavanced analysis. The Advanced Tools Window will open.

+

advanced_analysis

+

So far, we have included three advanced analyses in the openhdemg GUI.

+
    +
  • Motor Unit Tracking
  • +
  • Duplicate Removal
  • +
  • Conduction Velocity Calculation
  • +
+

For all of those, the specification of a Matrix Orientation and a Matrix Code is required. The Matrix Orientaion must match the one of your matrix during acquisition. You can find a reference image for the Orientation at the bottom in the right side of the Plot Window when using the Plot EMGfunction. The Matrix Orientation can be either 0 or 180 and must be chosen from the dropdown list. +The Matrix Code must be specified according to the one you used during acquisition. So far, the codes

+
    +
  • GR08MM1305
  • +
  • GR04MM1305
  • +
  • GR10MM0808
  • +
  • None
  • +
+

are implemented. You must choose one from the respective dropdown list. +In case you selected None, the entrybox Rows, Columns will appear. Please specify the number of rows and columns of your used matrix since you now bypass included matrix codes. In example, specifying

+

Rows, Columns: 13, 5
+
+means that your File has 65 channels. +Once you specified these parameter, you can click the Advaned Analysis button to start your analysis.

+
+

Motor Unit Tracking

+

When you want to track MUs across two different files, you need to select the Motor Unit Tracking options and specify the Matrix Code and Matrix Orentation in the Advanced Tools Window. Once you clicked the Advanced Analysis button, the MUs Tracking Window will pop-up.

+

mus_tracking

+
    +
  1. +

    You need to specify the Type of file you want to track MUs across in the respective dropdown. The available filetypes are:

    +
      +
    • OTB (.mat file exportable by OTBiolab+)
    • +
    • DEMUSE (.mat file used in DEMUSE)
    • +
    • OPENHDEMG (emgfile or reference signal stored in .json format)
    • +
    • CUSTOM (custom data from a .csv file)
    • +
    +

    Each filetype corresponds to a distinct datatype that should match the file you want to analyse. So, select the Type of file corresponding to the type of your file. In case you selected OTB specify the extension factor in the dropdown.

    +
  2. +
  3. +

    Load the files according to specified Type of fileusing the Load File 1 and Load File 2 buttons.

    +
  4. +
  5. +

    Select the minimum cross-correlation value to consider two MUs to be the same in the Threshold dropdown.

    +
  6. +
  7. +

    Specify the timewindow across which you want the spike triggered average to be computed in the Timewindow dropdown.

    +
  8. +
  9. +

    Select whether to exclude results with cross-correlation below specified Threshold by ticking the Exclude below threshold checkbox.

    +
  10. +
  11. +

    If you select the Filter checkbox, only the match with the highest cross-correlation is returned when the same MU has a match of cross-correlation > Threshold with multiple MUs.

    +
  12. +
  13. +

    The Show checkbox indicates whether to plot the spike triggered average of pairs of MUs with cross-correlation above Threshold.

    +
  14. +
  15. +

    By clicking the Track button, you can start the analysis. The tracking results will be displayed in the MUs Tracking Resul output in the right side of the MUs Tracking Window.

    +
  16. +
+

Duplicate Removal

+

When you want to remove MUs duplicates across different files, you need to select the Duplicate Removal options and specify the Matrix Code and Matrix Orentation in the Advanced Tools Window. Once you clicked the Advanced Analysis button, the Duplicate Removal Window will pop-up. Duplicate Removal requires similar input as Motor Unit Tracking, so please take a look at the Motor Unit Tracking section. However, you need to do two more things.

+

duplicate_removal

+
    +
  1. +

    You should specify How to remove the duplicated MUs in the Which dropdown. You can choose between

    +
      +
    • munumber: Duplicated MUs are removed from the file with more MUs.
    • +
    • PNR: The MU with the lowest PNR is removed.
    • +
    • SIL: The MU with the lowest SIL is removed.
    • +
    +
  2. +
  3. +

    By clicking the Remove Duplicates button, you start the removal process.

    +
  4. +
  5. +

    Specify a filename and location to save the file(s) with duplicates removed in a .json format.

    +
  6. +
+

Conduction Velocity

+

Prior to calculation of the Conduction Velocity you need to load a file in the main window of the GUI. Take a look at the intro section. Once you have done this, open the Advanced Tool Window using the Advanced Analaysis button.

+
    +
  1. +

    Select Conduction Velocity in the Analysis Tool dropdown, decide on the Matrix Orientation and Matrix Code as described above.

    +
  2. +
  3. +

    Click the Advanced Analysis button to start the calculation of the Conduction Velocity. The MUs cv estimation window will pop up.

    +

    cv_estimation

    +
  4. +
  5. +

    In the top left of the MUs cv estimation window select the MU for which you want to calculate the conduction velocity using the MU Number dropdown.

    +
  6. +
  7. +

    In the top middle of the window select the column for which you want to calculate the conduction velocity choosing from the Column dropdown.

    +
  8. +
  9. +

    In the top right of the window select the rows for which you want to calculate the conduction velocity using the From row and To row dropdown. For example, if you want to calculate the conduction velocity from row 3 to 7, select

    +
    From row: 3
    +To row: 7
    +
    +
  10. +
  11. +

    Click the Estimate button to start the calculation for the respective column and rows. The results will be displayed on the right side of the MUs cv estimation window.

    +
  12. +
  13. +

    You can copy the estimation results using the Copy Results button for futher analysis. The results are copied in the clipboard and can be pasted into any .csv (Excel).

    +
  14. +
+
+

We are now at the end of describing the advanced functions included in the openhdemg GUI. In case you need further clarification, don't hesitate to post a question in the Github discussion forum (LINK). Moreover, if you noticed an error that was not properly catched by the GUI, please file a bug report according to our guidelines (LINK). +If you want to take a look at more basic stuff, check out the basic.

+

More questions?

+

We hope that this tutorial was useful. If you need any additional information, do not hesitate to read the answers or ask a question in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/GUI_basics/index.html b/GUI_basics/index.html new file mode 100644 index 0000000..19327dc --- /dev/null +++ b/GUI_basics/index.html @@ -0,0 +1,1189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + basics - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + +

Graphical Interface

+

This is the basic introduction to the openhdemg GUI. In the next few sections, we will go through the basic analysis functions embedded in the GUI. For the advanced stuff, take a look at the advanced chapter. We will start with how to sort the motor units (MUs) included in your analysis file, go over force and MU property analysis, take a detour on plotting, and take a look at how to save and reset your analysis. Have fun!

+
+

Motor Unit Sorting

+

To sort the MUs included in your analysis file in order of their recruitement, we implemented a sorting algorithm. The MUs are sorted based on their recruitement order in an ascending manner.

+
    +
  1. +

    Load a file. Take a look at the intro section on how to do so.

    +
  2. +
  3. +

    Pay attention to view the MUs first, using the View MUs button (we explained this button in the intro chapter). The MUs will be sorted anyways, but without viewing them you won't see what is happening.

    +
  4. +
  5. +

    On the left hand side in the main window of the GUI, you can find the Sort MUs button. It is located in row three, column two. Once you press the button, the MUs will be sorted.

    +
  6. +
+

Remove Motor Units

+

To remove MUs included in your analysis file, you can click the Remove MUs button. The button is located on the left hand side in the main window of the GUI in column one of row four.

+

remove_mus

+
    +
  1. +

    View the MUs using the View MUs button prior to MU removal, you can directly see what is happening.

    +
  2. +
  3. +

    Click the Remove MUs button, and a file is loaded, a pop-up window will open.

    +
  4. +
  5. +

    Select the MU you want to delete from the analysis file from the Select MU:dropdown.

    +

    Select MU: 1
    +
    +will result in the second MU to be deleted (Python is base 0).

    +
  6. +
  7. +

    Click the Remove MU button to remove the MU.

    +
  8. +
+

Reference Signal Editing

+

The openhdemg GUI also allows you to edit and filter reference signals corresponding to your analysis file (this can be either a file containing both the MUs and the reference signal or a file containing only the reference signal).

+

reference_sig

+
    +
  1. +

    View the MUs using the View MUs button prior to reference signal editing, so you can see what is happening.

    +
  2. +
  3. +

    Click the RefSig Editing button located in row five and column one, a new pop-up window opens. In the Reference Signal Editing Window, you can low-pass filter the reference signal as well as remove any signal offset. Additionally, you can also convert your reference signal by a specific factor (amplification factor) or convert it from absolute to percentage (relative or normalised) values.

    +
  4. +
  5. +

    When you click the Filter RefSig button, the reference signal is low-pass filtered (Zero-lag, Butterworth) according to values specified in the Filter Order and Cutoff Freq textboxes. In example, specifiying

    +

    Filter Order: 4
    +Cutoff Freq: 15
    +
    +will allow only frequencies below 15 Hz to pass trough. The filter order of 4 indicates a fourth degree polynomial transfer function.

    +
  6. +
  7. +

    When you click the Remove Offset button, the reference signal's offset will be removed according to the values specified in the Offset Value and Automatic Offset textboxes. In example, specifying

    +

    Offset Value : 4
    +Automatic: 0
    +
    +will result in an offset correction by -4 in y-axis direction. Furthermore, specifying

    +

    Offset Value : 0
    +Automatic: != 0
    +
    +will result in automatic offset removal. In this case, the offset value is determined as the mean value of n samples at the beginning of the contraction (where n is equal to the value passed to Automatic). Moreover, specifying

    +

    Offset Value : 0
    +Automatic: 0
    +
    +will allow you to manually correct the offset in a new pop-up plot. You just need to follow the instructions on the plot.

    +
  8. +
  9. +

    When you click the Convert button, the reference signal will be multiplied or divided (depending on Operator) by the Factor. In example, specifying

    +

    Operator : "Multiply"
    +Factor: 2.5
    +
    +will amplify the reference signal 2.5 times.

    +
  10. +
  11. +

    When you click the To Percent button, the reference signal in absolute values is converted to percentage (relative or normalised) values based on the provided MVC Value. This step should be performed before any analysis, because openhdemg is designed to work with a normalised reference signal. In example, a file with a reference signal in absolute values ranging from 0 to 100 will be normalised from 0 to 20 if

    +
    MVC Value : 500
    +
    +
  12. +
+

Resize EMG File

+

Sometimes, resizing of your analysis file is unevitable. Luckily, openhdemg provides an easy solution. In row five and column two in the left side of the GUI, you can find the Resize File button.

+

resize_emg

+
    +
  1. +

    View the MUs using the View MUs button prior to file resizing, you can directly see what is happening.

    +
  2. +
  3. +

    Clicking the Resize File button will open a new pop-up plot of your analysis file.

    +
  4. +
  5. +

    Follow the instructions in the plot to resize the file. Simply click in the signal twice (once for start-point, once for end-point) to specify the resizing region and press enter to confirm your coice.

    +
  6. +
+

Analyse Force Signal

+

In order to analyse the force signal in your analysis file, you can press the Analyse Force button located in row six and column one in the left side of the GUI. A new pop-up window will open where you can analyse the maximum voluntary contraction (MVC) value as well as the rate of force development (RFD).

+

force_analysis

+

Maximum voluntary contraction

+
    +
  1. In order to get the MVC value, simply press the Get MVC button. A pop-up plot opens and you can select the area where you suspect the MVC to be.
  2. +
  3. Click once to specify the start-point and once to specify the end-point.
  4. +
  5. Press enter to confirm you choice. You will then see a Result Output appearing at the bottom of the main window of the GUI. There you can find the actual result of your MVC analysis.
  6. +
  7. You can edit or copy any value in the Result Output, however, you need to close the top-level Force Analysis Window first.
  8. +
+

Rate Of Force Development

+
    +
  1. To calculate the RFD values you can press the Get RFD button.
  2. +
  3. A pop-up plot appears and you need to specify the starting point of the rise in the force signal by clicking and subsequenlty pressing enter.
  4. +
  5. +

    The respective RFD values between the stated timepoint ranges (ms) in the RFD miliseconds textinput are displayed in the Result Output. In example, specifying

    +

    RFD miliseconds: 50,100,150,200
    +
    +will result in RFD value calculation between the intervals 0-50ms, 50-100ms, 100-150ms and 150-200ms. You can also specify less or more values in the RFD miliseconds textbox.

    +
  6. +
  7. +

    You can edit or copy any value in the Result Output, however, you need to close the top-level Force Analysis Window first.

    +
  8. +
+

Motor Unit Properties

+

When you press the MU Properties button in row six and column two, the Motor Unit Properties Window will pop up. In this window, you have the option to analyse several MUs propierties such as the MUs recruitement threshold or the MUs discharge rate.

+

mus_properties

+
    +
  1. +

    Specify your priorly calculated MVC in the Enter MVC [N]: textbox, like

    +
    Enter MVC [N]: 424
    +
    +
  2. +
+

Compute Motor Unit Threshold

+

Subsequently to specifying the MVC, you can compute the MUs recruitement threshold by specifying the respective event and type in the Event and Type dropdown list.

+
    +
  1. +

    Specify the Event dropdown and choose:

    +
    "rt_dert" : Both recruitment and derecruitment thresholds will be calculated.
    +"rt" : Only recruitment thresholds will be calculated.
    +"dert" : Only derecruitment thresholds will be calculated.
    +
    +
  2. +
  3. +

    Specify the Type dropdown and choose:

    +
    "abs_rel" : Both absolute and relative thresholds will be calculated.
    +"rel" : Only relative thresholds will be calculated.
    +"abs" : Only absolute thresholds will be calculated.
    +
    +
  4. +
  5. +

    Once you click the Compute threshold button, the recruitement threshold will be computed.

    +
  6. +
  7. The recruitement threshold for each inluded MU in the analysis file will be displayed in the Result Output of the GUI.
  8. +
  9. You can edit or copy any value in the Result Output, however, you need to close the top-level Motor Unit Properties Window first.
  10. +
+

Compute Motor Unit Discharge Rate

+

Subsequently to specifying the MVC, you can compute the MUs discharge rate by entering the respective firing rates and event.

+
    +
  1. Specify the number of firings at recruitment and derecruitment to consider for the calculation in the Firings at Rec textbox.
  2. +
  3. +

    Enter the number of firings over which to calculate the DR at the start and end of the steady-state phase in the Firings Start/End Steady textbox.

    +

    For example: +

    Firings at Rec: 4
    +Firings Start/End Steady: 10
    +

    +
  4. +
  5. +

    Lastly you need to specify the computation Event. From the Event dropdown list, you can choose:

    +
    "rec_derec_steady" : Discharge rate is calculated at recruitment, derecruitment and during the steady-state phase.
    +"rec" : Discharge rate is calculated at recruitment.
    +"derec" : Discharge rate is calculated at derecruitment.
    +"rec_derec" : Discharge rate is calculated at recruitment and derecruitment.
    +"steady" : Discharge rate is calculated during the steady-state phase.
    +
    +
  6. +
  7. +

    Once you press the Compute discharge rate button, the discharge rate will be calculated.

    +
  8. +
  9. The discharge rate for each inluded MU in the analysis file at the stated event as well a for all the contraction will be displayed in the Result Output of the GUI.
  10. +
  11. You can edit or copy any value in the Result Output, however, you need to close the top-level Motor Unit Properties Window first.
  12. +
+

Basic Motor Unit Properties

+

Subsequently to specifying the MVC, you can calculate a number of basic MUs properties with one click. These include

+
    +
  • The absolute/relative recruitment/derecruitment thresholds
  • +
  • The discharge rate at recruitment, derecruitment, during the steady-state phase and during the entire contraction
  • +
  • The coefficient of variation of interspike interval
  • +
  • The coefficient of variation of force signal
  • +
+

and are all displayed in the Result Output once the analysis in completed.

+
    +
  1. Specify the number of firings at recruitment and derecruitment to consider for the calculation in the Firings at Rec textbox.
  2. +
  3. +

    Enter the start and end point (in samples) of the steady-state phase in the Firings Start/End Steady textbox. For example,

    +
    Firings at Rec: 4
    +Firings Start/End Steady: 10
    +
    +
  4. +
  5. +

    The basic MUs properties will be displayed in the Result Output of the GUI.

    +
  6. +
  7. You can edit or copy any value in the Result Output, however, you need to close the top-level Motor Unit Properties Window first.
  8. +
+

Plot Motor Units

+

In openhdemg we have implemented options to plot your analysis file ... a lot of options! +Upon clicking the Plot MUs button, the Plot Window will pop up. In the top right corner of the window, you can find an information button forwarding you directly to some tutorials.

+

plot_mus

+

You can choose between the follwing plotting options:

+
    +
  • Plot the raw emg signal. Single or multiple channels. (Plot EMGSig)
  • +
  • Plot the reference signal. (Plot RefSig)
  • +
  • Plot all the MUs pulses (binary representation of the firings time). (Plot MUPulses)
  • +
  • Plot the decomposed source. (Plot Source)
  • +
  • Plot the instantaneous discharge rate (IDR). (Plot IDR)
  • +
  • Plot the differential derivation of the raw emg signal by matrix column. (Plot Derivation)
  • +
  • Plot motor unit action potentials (MUAPs) obtained from spike-triggered average from one or multiple MUs. (Plot MUAPs)
  • +
+

Prior to plotting you can optionally select a few options on the left side of the Plot Window.

+
    +
  1. When you want the reference signal to be displayed in the plots you can select the Reference Signal checkbox in row one and column two in the left side of the Plot Window.
  2. +
  3. You can specify wheter you want the x-axis of the plots to be scaled in seconds by selecting the Time in seconds checkbox in row two and column two in the left side of the Plot Window.
  4. +
  5. +

    You can change the size of the plot as well, by inputting your prefered height and width in the Figure in size in cm (h,w) textbox in row three and column two in the left side of the Plot Window. For example, if you want your plot to have a height of 6 and a width of 8, your input should look like this

    +
    Figure in size in cm (h,w): 6,8
    +
    +
  6. +
+

These three setting options are universally used in all plots. There are two more specification options on the right side of the Plot Window only relevant when using the Plot Derivation or Plot MUAP buttons.

+
    +
  1. +

    The Matrix Code must be specified in row one and column four in the right side of the Plot Window according to the one you used during acquisition. So far, implemented codes are:

    +
      +
    • GR08MM1305
    • +
    • GR04MM1305
    • +
    • GR10MM0808
    • +
    • None
    • +
    +

    In case you selected None, the entrybox Rows, Columns will appear. Please specify the number of rows and columns of your used matrix since you now bypass included matrix codes. In example, specifying +

    Rows, Columns: 13, 5
    +
    +means that your File has 65 channels.

    +
  2. +
  3. +

    You need to specify the Orientation in row two and column four in the left side of the Plot Window. The Orientaion must match the one of your matrix during acquisition. You can find a reference image for the Orientation at the bottom in the right side of the Plot Window.

    +
  4. +
+

Plot Raw EMG Signal

+
    +
  1. Click the Plot EMGsig button in row four and column one in the left side of the Plot Window, to plot the raw emg signal of your analysis file.
  2. +
  3. Enter or select a Channel Number in / from the dropdown list. For example, if you want to plot Channel Number one enter 0 in the dropdown. If you want to plot Channel Numbers one, two and three enter 0,1,2 in the dropdown.
  4. +
  5. Once you have clicked the Plot EMGsig button, a pop-up plot will appear.
  6. +
+

Plot Reference Signal

+
    +
  1. Click the Plot RefSig button in row five and column one in the left side of the Plot Window, to plot the reference signal.
  2. +
  3. Once you have clicked the Plot RefSig button, a pop-up plot will appear.
  4. +
+

Plot Motor Unit Pulses

+
    +
  1. Click the Plot MUpulses button in row six and column one in the left side of the Plot Window, to plot the single pulses of the MUs in your analysis file.
  2. +
  3. Enter/select a pulse Linewidth in/from the dropdown list. For example, if you want to use a Linewidth of one, enter 1 in the dropdown.
  4. +
  5. Once you have clicked the Plot MUpulses button, a pop-up plot will appear.
  6. +
+

Plot the Decomposed Source

+
    +
  1. Click the Plot Source button in row seven and column one in the left side of the Plot Window, to plot the Source of the decomposed MUs in your analysis file.
  2. +
  3. Enter/select a MU Number in/from the dropdown list. For example, if you want to plot the source for MU Number one enter 0 in the dropdown. If you want to plot the sources for MU Number one, two and three enter 0,1,2, in the dropdown. You can also set MU Number to "all" to plot the sources for all included MUs in the analysis file.
  4. +
  5. Once you have clicked the Plot Source button, a pop-up plot will appear.
  6. +
+

Plot Instanteous Discharge rate

+
    +
  1. Click the Plot IDR button in row eight and column one in the left side of the Plot Window, to plot the IDR of the MUs in your analysis file.
  2. +
  3. Enter/select a MU Number in/from the dropdown list. For example, if you want to plot the IDR of MU Number one enter 0 in the dropdown. If you want to plot the IDR of MU Number one, two and three enter 0,1,2 in the dropdown. You can also set MU Number to "all" to plot the IDR of all included MUs in the analysis file.
  4. +
  5. Once you have clicked the Plot IDR button, a pop-up plot will appear.
  6. +
+

Plot Differential Derivation

+
    +
  1. Click the Plot Derivation button in row four and column three in the right side of the Plot Window, to plot the differential derivation of the MUs in your analysis file.
  2. +
  3. Specify the Configuration for the calculation first. You can choose from:
      +
    • Single differential (Calculate single differential of raw signal on matrix rows)
    • +
    • Double differential(Calculate double differential of raw signal on matrix rows)
    • +
    +
  4. +
  5. Specify the respective Matrix Column you want to plot. You can choose one from the Matrix Column dropdown list.
  6. +
  7. Once you have clicked the Plot Derivation button, a new pop-up plot appears.
  8. +
+

Plot Motor Unit Action Potentials

+
    +
  1. Click the Plot MUAPs button in row five and column three in the right side of the Plot Window, you can plot the action potential of the MUs in your analysis file.
  2. +
  3. Specify the Configuration for calculation first. You can choose from:
      +
    • Monopolar
    • +
    • Single differential (Calculate single differential of raw signal on matrix rows)
    • +
    • Double differential(Calculate double differential of raw signal on matrix rows)
    • +
    +
  4. +
  5. Specify the respective MU Number you want to plot. You can choose one from the MU Number dropdown list.
  6. +
  7. Specify the Timewindow of the plots. You can choose from the Timewindow dropdown list or enter any integer.
  8. +
  9. Once you have clicked the Plot MUAPs button, a new pop-up plot appears.
  10. +
+

Saving Your Analysis File

+

Subsequently to analysing your emg-file in the openhdemg GUI, it is beneficial to save it. Otherwise, all changes will be lost when the GUI is closed.

+
    +
  1. Click the Save File button in row two and column two in the left side of the main window.
  2. +
  3. Specify a filename and a location and confirm! That's it!
  4. +
+

Saving Your Analysis Results

+

Some analyses included in the openhdemg GUI return values that are displayed in the Result Output of the GUI. Of course, you can simply copy-paste them, but it might be more convenient to directly save your analysis results. Additionally, all the values in the Results Output will be overwritten by new analyses or deleted in case of closing the GUI.

+
    +
  1. click the Save Results button in row two and column two in the left side of the main window.
  2. +
  3. Specify a location where to save the file and confirm. You can find the file there with the name of your analysis file.
  4. +
+

Resetting Your Analysis

+

We all make mistakes! But, most likely, we are also able to correct them. In case you have made a mistake in the analysis of you emg-file in the openhdemg GUI, we have implemented a reset button for you. Click the Reset Analysis button in row eight and column two in the lef side of the main window to reset any analysis you previously performed since opening the GUI and inputting an analysis file. Your analysis file is reset to the original file and all the changes are discarded. So, no need to be perfect!

+
+

We hope you had fun! We are now at the end of describing the basic functions included in the openhdemg GUI. In case you need further clarification, don't hesitate to post a question in the openhdemg discussion section. Moreover, if you noticed an error that was not properly catched by the GUI, please file a bug report according to our guidelines (LINK). +If you want to proceed to the advanced stuff now, take a look at the advanced tab on the left side of the webpage.

+

More questions?

+

We hope that this tutorial was useful. If you need any additional information, do not hesitate to read the answers or ask a question in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/GUI_intro/index.html b/GUI_intro/index.html new file mode 100644 index 0000000..61c9479 --- /dev/null +++ b/GUI_intro/index.html @@ -0,0 +1,797 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + intro - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

Graphical Interface

+

Welcome, to the openhdemg Graphical User Interface (GUI) introduction! +The openhdemg GUI incorporates all relevant high-level functions of the openhdemg library. The GUI allows you to successfully perform High-Density Electromyography (HD-EMG) data anlysis without any programming skills required. Moreover, there is no downside to using the GUI even if you are an experienced programmer.

+
+

Let us shortly walk you through the main window of the GUI. An image of the starting page of the GUI is displayed below.

+

gui_preview

+

This is your starting point for every analysis. On the left hand side you can find all the entryboxes and buttons relevant for the analyses you want to perform. In the middle you can see the plotting canvas where plots of the HD-EMG data analysis are displayed. On the right hand side you can find information buttons leading you directly to more information, tutorials, and more. And, with a little swoosh of magic, the results window appears at the bottom of the GUI once an analysis is finished.

+
+

Specifying an analysis file

+
    +
  1. +

    In order to load file into the GUI, you first need to select something in the Type of file dropdown box at the top left corner. The available filetypes are:

    +
      +
    • OTB (.mat file exportable by OTBiolab+)
    • +
    • DEMUSE (.mat file used in DEMUSE)
    • +
    • OTB_REFSIG (Reference signal in the .mat file exportable by OTBiolab+)
    • +
    • OPENHDEMG (emgfile or reference signal stored in .json format)
    • +
    • CUSTOM (custom data from a .csv file)
    • +
    +

    Each filetype corresponds to a distinct datatype that should match the file you want to analyse. So, select the Type of file corresponding to the type of your file.

    +
  2. +
  3. +

    To actually load the file, click the Load File button and select the file you want to analyse. In case of occurence, follow the error messages and repeat this and the previos step.

    +
  4. +
  5. +

    Once the file is successfully loaded, the specifications of the file you want to analyse will be displayed next to the Load File button.

    +
  6. +
+

Viewing an analysis file

+

It doesn't get any simpler than this! +Once a file is successfully loaded as described above, you can click the View MUs button to plot/view your file. In the middle section of the GUI, a plot containing your data should appear.

+
+

In the two sections above, we described the two most rudimental functions in the GUI. To learn more about basic and more advanced analysis features of the GUI, check out the basic and advanced chapters.

+

More questions?

+

We hope that this tutorial was useful. If you need any additional information, do not hesitate to read the answers or ask a question in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/Quick-Start/index.html b/Quick-Start/index.html new file mode 100644 index 0000000..36e5bd6 --- /dev/null +++ b/Quick-Start/index.html @@ -0,0 +1,1139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Quick Start - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + Skip to content + + +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + +

Quick Start

+ +

Let's implement together, step-by-step, a script to analyse all the relevant motor units' (MUs) properties.

+

In particular, we will go through:

+
    +
  1. Install opendemg
  2. +
  3. Load a file
  4. +
  5. Visualise the content of the file
  6. +
  7. Edit the reference signal
  8. +
  9. Remove unwanted MUs
  10. +
  11. Analyse fundamental MUs properties
  12. +
  13. Save the edited file and the results of the analysis
  14. +
+

1. Install

+

openhdemg can be easily installed using pip:

+
pip install openhdemg
+
+

or conda:

+
conda install -c conda-forge openhdemg
+
+

Once the installation of openhdemg is succesfull, you can install all the required packages from the reqirements.txt file.

+

2. Load a file

+

Before calling the functions contained in the openhdemg library, we need to import it. This can be done as:

+
import openhdemg.library as emg
+
+

Great, we are now ready to exploit all the functionalities of the library!

+


+

In this example, we will use the sample file provided with openhdemg.

+

This can be simply loaded calling the function emg_from_samplefile.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+

emgfile is organised as a Python dictionary and contains different elements (which are labelled by keys).

+

For a full list of keys contained in the emgfile refer to the openfiles documentation.

+

Each element in the emgfile can be accessed as emgfile["element"].

+

So, if we want to access, for example, the reference signal, we can use emgfile["REF_SIGNAL"].

+

3. Visualise the content of the file

+

Now that we loaded the emgfile, we can inspect its content.

+

As we said above, there are different elements in the emgfile and we can visualise both their type and their content with 2 lines of code:

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Print type
+print(type(emgfile["REF_SIGNAL"]))
+
+# Print content
+print(emgfile["REF_SIGNAL"])
+
+
+""" Output
+<class 'pandas.core.frame.DataFrame'>
+              0
+0     -0.159466
+1     -0.139630
+2     -0.099957
+3     -0.080121
+4     -0.060284
+...         ...
+66555 -0.337994
+66556 -0.318158
+66557 -0.298321
+66558 -0.318158
+66559 -0.318158
+"""
+
+

As you can see from the printed output, the reference signal is contained in a pandas DataFrame with 1 column (column 0).

+

This is an extremely important information if you want to manipulate the content of the emgfile although it is outside the scope of this Quick-Start tutorial.

+

Apart from accessing the numerical values, we can also plot them.

+

In this case we are interested in visualising the MUs firing times together with the reference signal. This can be done with the function plot_mupulses.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Plot MUs firing times and ref signal
+emg.plot_mupulses(emgfile=emgfile)
+
+

MUs_pulses_non_sorted

+

Looks good, but I would rather have the MUs ordered by recruitment order and also with thinner lines!

+

We can do that with the function sort_mus and changing the parameters in plot_mupulses.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Sort MUs based on recruitment order
+emgfile = emg.sort_mus(emgfile=emgfile)
+
+# Plot MUs firing times and ref signal
+emg.plot_mupulses(emgfile=emgfile, linewidths=0.4)
+
+

MUs_pulses_sorted

+


+

Are you curious about the dicharge rate of the MUs? You can view that with the function plot_idr.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Sort MUs based on recruitment order
+emgfile = emg.sort_mus(emgfile=emgfile)
+
+# Plot MUs instantaneous discharge rate
+emg.plot_idr(emgfile=emgfile)
+
+

MUs_pulses_sorted_idr

+

4. Edit the reference signal

+

The MUs look quite good; however, the reference signal is a bit noisy and the offset is not to 0.

+

The noise can be removed filtering the reference signal with the function filter_refsig that, by default, applies a 4th order, zero-lag, low-pass Butterworth filter with a cutoff frequency of 15 Hz.

+

Instead, the offset can be removed with the function remove_offset that automatically detects the offset based on a number of samples at the beginning of the recording.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Sort MUs based on recruitment order
+emgfile = emg.sort_mus(emgfile=emgfile)
+
+# Filter the ref signal
+emgfile = emg.filter_refsig(emgfile=emgfile)
+
+# Remove the offset based on the first 1024 samples (that corresponds to 0.5
+# seconds when sampling the signal at 2048 Hz).
+emgfile = emg.remove_offset(emgfile=emgfile, auto=1024)
+
+# Plot MUs instantaneous discharge rate
+emg.plot_idr(emgfile=emgfile)
+
+

MUs_pulses_sorted_idr_filteroffs

+

5. Remove unwanted MUs

+

There might be cases in which we need to remove one or more MUs from our emgfile.

+

From the visual inspection of our plots, we can see that the firings pattern of MU number 2 (remember, Python is in base 0!!!) is not really regular. We might therefore have doubts about its quality.

+

A way to assess the quality of the MUs is to look at the separation between the signal and the noise. This is efficiently measured by the silouette (SIL) score.

+

This score is automatically calculated while importing the emgfile and can be easily accessed as emgfile["SIL"].

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Print the SIL score
+print(emgfile["SIL"])
+
+"""Output
+          0
+0  0.899082
+1  0.919601
+2  0.879079
+3  0.917190
+4  0.955819
+"""
+
+

Our suspicion was right, MU number 2 has the lowest SIL score.

+

In order to remove this MU, we can use the function delete_mus.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Sort MUs based on recruitment order
+emgfile = emg.sort_mus(emgfile=emgfile)
+
+# Filter the ref signal
+emgfile = emg.filter_refsig(emgfile=emgfile)
+
+# Remove the offset based on the first 1024 samples (that corresponds to 0.5
+# seconds when sampling the signal at 2048 Hz).
+emgfile = emg.remove_offset(emgfile=emgfile, auto=1024)
+
+# Remove MU number 2
+emgfile = emg.delete_mus(emgfile=emgfile, munumber=2)
+
+# Plot MUs instantaneous discharge rate
+emg.plot_idr(emgfile=emgfile)
+
+

IDR_mu2removed

+

6. Analyse fundamental MUs properties

+

Now that we removed the unwanted MUs and adjusted the reference signal, we can proceed with the analysis of some fundamental MUs properties like the thresholds of recruitment and derecruitment and the discharge rate.

+

In the past, this used to require many lines of code, but thanks to openhdemg, we can now do that with 1 line of code using the function basic_mus_properties.

+

After calling the function basic_mus_properties, the user will be asked to select the start and the end of the steady-state phase. This can be done positioning the mouse on the desired point and then pressing a keybord key (such as 'a'). To remove points, right click with your mouse.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Sort MUs based on recruitment order
+emgfile = emg.sort_mus(emgfile=emgfile)
+
+# Filter the ref signal
+emgfile = emg.filter_refsig(emgfile=emgfile)
+
+# Remove the offset based on the first 1024 samples (that corresponds to 0.5
+# seconds when sampling the signal at 2048 Hz).
+emgfile = emg.remove_offset(emgfile=emgfile, auto=1024)
+
+# Remove MU number 2
+emgfile = emg.delete_mus(emgfile=emgfile, munumber=2)
+
+# Calculate all the basic MUs propertis.
+# Specify maximum voluntary contraction in Newtons.
+results = emg.basic_mus_properties(
+    emgfile=emgfile,
+    mvc=634,
+)
+
+print(results)
+
+"""
+     MVC  MU_number        PNR    avg_PNR       SIL   avg_SIL      abs_RT  \
+0  634.0          0  27.480307  29.877575  0.899082  0.922923   30.621759
+1    NaN          1  28.946493        NaN  0.919601       NaN   32.427026
+2    NaN          2  28.640680        NaN  0.917190       NaN   68.371911
+3    NaN          3  34.442821        NaN  0.955819       NaN  118.504004
+
+     abs_DERT     rel_RT   rel_DERT    DR_rec  DR_derec  DR_start_steady  \
+0   36.168135   4.829930   5.704753  7.548770  5.449581        11.788779
+1   31.167703   5.114673   4.916041  8.344515  5.333535        11.254445
+2   67.308703  10.784213  10.616515  5.699017  3.691367         9.007505
+3  102.761472  18.691483  16.208434  5.701081  4.662196         7.393645
+
+   DR_end_steady  DR_all_steady     DR_all  COVisi_steady  COVisi_all  \
+0      10.401857      11.154952  10.693076       6.833642   19.104306
+1       9.999033      10.751960  10.543011       8.364553   15.408739
+2       7.053079       8.168471   7.949294      10.097045   23.324503
+3       6.430807       6.908502   6.814687      11.211862   16.319474
+
+   COV_steady
+0    1.422424
+1         NaN
+2         NaN
+3         NaN
+"""
+
+

7. Save the results and the edited file

+

It looks like we got a lot of results, which makes it extremely inefficient to copy them manually.

+

Obviously, this can be automated using one attribute of the results object and we can conveniently save all the results in a .csv file.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Sort MUs based on recruitment order
+emgfile = emg.sort_mus(emgfile=emgfile)
+
+# Filter the ref signal
+emgfile = emg.filter_refsig(emgfile=emgfile)
+
+# Remove the offset based on the first 1024 samples (that corresponds to 0.5
+# seconds when sampling the signal at 2048 Hz).
+emgfile = emg.remove_offset(emgfile=emgfile, auto=1024)
+
+# Remove MU number 2
+emgfile = emg.delete_mus(emgfile=emgfile, munumber=2)
+
+# Calculate all the basic MUs propertis.
+# Specify maximum voluntary contraction in Newtons.
+results = emg.basic_mus_properties(
+    emgfile=emgfile,
+    mvc=634,
+)
+
+# Save the results to a .csv file.
+# Remember to change this path to a real path!
+results.to_csv("C:/Users/.../Desktop/Results.csv")
+
+

Our results are now safe but, additionally, we might want to save also the emgfile with all the changes that we made. This can be easily done with the function asksavefile that will save your emgfile in the open standard JSON file format which has a better integration with Python and has a very high cross-platform compatibility.

+
# Import the library with the short name 'emg'
+import openhdemg.library as emg
+
+# Load the sample file
+emgfile = emg.emg_from_samplefile()
+
+# Sort MUs based on recruitment order
+emgfile = emg.sort_mus(emgfile=emgfile)
+
+# Filter the ref signal
+emgfile = emg.filter_refsig(emgfile=emgfile)
+
+# Remove the offset based on the first 1024 samples (that corresponds to 0.5
+# seconds when sampling the signal at 2048 Hz).
+emgfile = emg.remove_offset(emgfile=emgfile, auto=1024)
+
+# Remove MU number 2
+emgfile = emg.delete_mus(emgfile=emgfile, munumber=2)
+
+# Calculate all the basic MUs propertis.
+# Specify maximum voluntary contraction in Newtons.
+results = emg.basic_mus_properties(
+    emgfile=emgfile,
+    mvc=634,
+)
+
+# Save the results to a .csv file.
+# Remember to change this path to a real path!
+results.to_csv("C:/Users/.../Desktop/Results.csv")
+
+# Save the edited emgfile
+emg.asksavefile(emgfile=emgfile)
+
+

8. Important notes

+

As you have seen, openhdemg makes it really easy to analyse MUs properties but please, don't think that what you saw in this tutorial is all you can do with this powerful framework.

+

We invite you to read the API reference section to understand how you can customise all the functions present in the library.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/What's-New/index.html b/What's-New/index.html new file mode 100644 index 0000000..efcfd05 --- /dev/null +++ b/What's-New/index.html @@ -0,0 +1,680 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + What's New - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

What's New

+ +

0.1.0-beta.1   June 2023

+

What's new? Well, everything. This is our firt release, if you are using it, congratulations, you are a pioneer!

+

Please note, this is a beta release, which means that a lot can change in this version and the library is not yet ready to be used without double-checking the results that you get.

+ + + + + + +
+
+ + +
+ +
+ + + +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/assets/_mkdocstrings.css b/assets/_mkdocstrings.css new file mode 100644 index 0000000..049a254 --- /dev/null +++ b/assets/_mkdocstrings.css @@ -0,0 +1,64 @@ + +/* Avoid breaking parameter names, etc. in table cells. */ +.doc-contents td code { + word-break: normal !important; +} + +/* No line break before first paragraph of descriptions. */ +.doc-md-description, +.doc-md-description>p:first-child { + display: inline; +} + +/* Max width for docstring sections tables. */ +.doc .md-typeset__table, +.doc .md-typeset__table table { + display: table !important; + width: 100%; +} + +.doc .md-typeset__table tr { + display: table-row; +} + +/* Defaults in Spacy table style. */ +.doc-param-default { + float: right; +} + +/* Keep headings consistent. */ +h1.doc-heading, +h2.doc-heading, +h3.doc-heading, +h4.doc-heading, +h5.doc-heading, +h6.doc-heading { + font-weight: 400; + line-height: 1.5; + color: inherit; + text-transform: none; +} + +h1.doc-heading { + font-size: 1.6rem; +} + +h2.doc-heading { + font-size: 1.2rem; +} + +h3.doc-heading { + font-size: 1.15rem; +} + +h4.doc-heading { + font-size: 1.10rem; +} + +h5.doc-heading { + font-size: 1.05rem; +} + +h6.doc-heading { + font-size: 1rem; +} \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 0000000..1cf13b9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.220ee61c.min.js b/assets/javascripts/bundle.220ee61c.min.js new file mode 100644 index 0000000..116072a --- /dev/null +++ b/assets/javascripts/bundle.220ee61c.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var Ci=Object.create;var gr=Object.defineProperty;var Ri=Object.getOwnPropertyDescriptor;var ki=Object.getOwnPropertyNames,Ht=Object.getOwnPropertySymbols,Hi=Object.getPrototypeOf,yr=Object.prototype.hasOwnProperty,nn=Object.prototype.propertyIsEnumerable;var rn=(e,t,r)=>t in e?gr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,P=(e,t)=>{for(var r in t||(t={}))yr.call(t,r)&&rn(e,r,t[r]);if(Ht)for(var r of Ht(t))nn.call(t,r)&&rn(e,r,t[r]);return e};var on=(e,t)=>{var r={};for(var n in e)yr.call(e,n)&&t.indexOf(n)<0&&(r[n]=e[n]);if(e!=null&&Ht)for(var n of Ht(e))t.indexOf(n)<0&&nn.call(e,n)&&(r[n]=e[n]);return r};var Pt=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Pi=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ki(t))!yr.call(e,o)&&o!==r&&gr(e,o,{get:()=>t[o],enumerable:!(n=Ri(t,o))||n.enumerable});return e};var yt=(e,t,r)=>(r=e!=null?Ci(Hi(e)):{},Pi(t||!e||!e.__esModule?gr(r,"default",{value:e,enumerable:!0}):r,e));var sn=Pt((xr,an)=>{(function(e,t){typeof xr=="object"&&typeof an!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var n=!0,o=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(O){return!!(O&&O!==document&&O.nodeName!=="HTML"&&O.nodeName!=="BODY"&&"classList"in O&&"contains"in O.classList)}function f(O){var Qe=O.type,De=O.tagName;return!!(De==="INPUT"&&s[Qe]&&!O.readOnly||De==="TEXTAREA"&&!O.readOnly||O.isContentEditable)}function c(O){O.classList.contains("focus-visible")||(O.classList.add("focus-visible"),O.setAttribute("data-focus-visible-added",""))}function u(O){O.hasAttribute("data-focus-visible-added")&&(O.classList.remove("focus-visible"),O.removeAttribute("data-focus-visible-added"))}function p(O){O.metaKey||O.altKey||O.ctrlKey||(a(r.activeElement)&&c(r.activeElement),n=!0)}function m(O){n=!1}function d(O){a(O.target)&&(n||f(O.target))&&c(O.target)}function h(O){a(O.target)&&(O.target.classList.contains("focus-visible")||O.target.hasAttribute("data-focus-visible-added"))&&(o=!0,window.clearTimeout(i),i=window.setTimeout(function(){o=!1},100),u(O.target))}function v(O){document.visibilityState==="hidden"&&(o&&(n=!0),Y())}function Y(){document.addEventListener("mousemove",N),document.addEventListener("mousedown",N),document.addEventListener("mouseup",N),document.addEventListener("pointermove",N),document.addEventListener("pointerdown",N),document.addEventListener("pointerup",N),document.addEventListener("touchmove",N),document.addEventListener("touchstart",N),document.addEventListener("touchend",N)}function B(){document.removeEventListener("mousemove",N),document.removeEventListener("mousedown",N),document.removeEventListener("mouseup",N),document.removeEventListener("pointermove",N),document.removeEventListener("pointerdown",N),document.removeEventListener("pointerup",N),document.removeEventListener("touchmove",N),document.removeEventListener("touchstart",N),document.removeEventListener("touchend",N)}function N(O){O.target.nodeName&&O.target.nodeName.toLowerCase()==="html"||(n=!1,B())}document.addEventListener("keydown",p,!0),document.addEventListener("mousedown",m,!0),document.addEventListener("pointerdown",m,!0),document.addEventListener("touchstart",m,!0),document.addEventListener("visibilitychange",v,!0),Y(),r.addEventListener("focus",d,!0),r.addEventListener("blur",h,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var cn=Pt(Er=>{(function(e){var t=function(){try{return!!Symbol.iterator}catch(c){return!1}},r=t(),n=function(c){var u={next:function(){var p=c.shift();return{done:p===void 0,value:p}}};return r&&(u[Symbol.iterator]=function(){return u}),u},o=function(c){return encodeURIComponent(c).replace(/%20/g,"+")},i=function(c){return decodeURIComponent(String(c).replace(/\+/g," "))},s=function(){var c=function(p){Object.defineProperty(this,"_entries",{writable:!0,value:{}});var m=typeof p;if(m!=="undefined")if(m==="string")p!==""&&this._fromString(p);else if(p instanceof c){var d=this;p.forEach(function(B,N){d.append(N,B)})}else if(p!==null&&m==="object")if(Object.prototype.toString.call(p)==="[object Array]")for(var h=0;hd[0]?1:0}),c._entries&&(c._entries={});for(var p=0;p1?i(d[1]):"")}})})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er);(function(e){var t=function(){try{var o=new e.URL("b","http://a");return o.pathname="c d",o.href==="http://a/c%20d"&&o.searchParams}catch(i){return!1}},r=function(){var o=e.URL,i=function(f,c){typeof f!="string"&&(f=String(f)),c&&typeof c!="string"&&(c=String(c));var u=document,p;if(c&&(e.location===void 0||c!==e.location.href)){c=c.toLowerCase(),u=document.implementation.createHTMLDocument(""),p=u.createElement("base"),p.href=c,u.head.appendChild(p);try{if(p.href.indexOf(c)!==0)throw new Error(p.href)}catch(O){throw new Error("URL unable to set base "+c+" due to "+O)}}var m=u.createElement("a");m.href=f,p&&(u.body.appendChild(m),m.href=m.href);var d=u.createElement("input");if(d.type="url",d.value=f,m.protocol===":"||!/:/.test(m.href)||!d.checkValidity()&&!c)throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:m});var h=new e.URLSearchParams(this.search),v=!0,Y=!0,B=this;["append","delete","set"].forEach(function(O){var Qe=h[O];h[O]=function(){Qe.apply(h,arguments),v&&(Y=!1,B.search=h.toString(),Y=!0)}}),Object.defineProperty(this,"searchParams",{value:h,enumerable:!0});var N=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==N&&(N=this.search,Y&&(v=!1,this.searchParams._fromString(this.search),v=!0))}})},s=i.prototype,a=function(f){Object.defineProperty(s,f,{get:function(){return this._anchorElement[f]},set:function(c){this._anchorElement[f]=c},enumerable:!0})};["hash","host","hostname","port","protocol"].forEach(function(f){a(f)}),Object.defineProperty(s,"search",{get:function(){return this._anchorElement.search},set:function(f){this._anchorElement.search=f,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(s,{toString:{get:function(){var f=this;return function(){return f.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(f){this._anchorElement.href=f,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(f){this._anchorElement.pathname=f},enumerable:!0},origin:{get:function(){var f={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],c=this._anchorElement.port!=f&&this._anchorElement.port!=="";return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(c?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(f){},enumerable:!0},username:{get:function(){return""},set:function(f){},enumerable:!0}}),i.createObjectURL=function(f){return o.createObjectURL.apply(o,arguments)},i.revokeObjectURL=function(f){return o.revokeObjectURL.apply(o,arguments)},e.URL=i};if(t()||r(),e.location!==void 0&&!("origin"in e.location)){var n=function(){return e.location.protocol+"//"+e.location.hostname+(e.location.port?":"+e.location.port:"")};try{Object.defineProperty(e.location,"origin",{get:n,enumerable:!0})}catch(o){setInterval(function(){e.location.origin=n()},100)}}})(typeof global!="undefined"?global:typeof window!="undefined"?window:typeof self!="undefined"?self:Er)});var qr=Pt((Mt,Nr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof Mt=="object"&&typeof Nr=="object"?Nr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof Mt=="object"?Mt.ClipboardJS=r():t.ClipboardJS=r()})(Mt,function(){return function(){var e={686:function(n,o,i){"use strict";i.d(o,{default:function(){return Ai}});var s=i(279),a=i.n(s),f=i(370),c=i.n(f),u=i(817),p=i.n(u);function m(j){try{return document.execCommand(j)}catch(T){return!1}}var d=function(T){var E=p()(T);return m("cut"),E},h=d;function v(j){var T=document.documentElement.getAttribute("dir")==="rtl",E=document.createElement("textarea");E.style.fontSize="12pt",E.style.border="0",E.style.padding="0",E.style.margin="0",E.style.position="absolute",E.style[T?"right":"left"]="-9999px";var H=window.pageYOffset||document.documentElement.scrollTop;return E.style.top="".concat(H,"px"),E.setAttribute("readonly",""),E.value=j,E}var Y=function(T,E){var H=v(T);E.container.appendChild(H);var I=p()(H);return m("copy"),H.remove(),I},B=function(T){var E=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},H="";return typeof T=="string"?H=Y(T,E):T instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(T==null?void 0:T.type)?H=Y(T.value,E):(H=p()(T),m("copy")),H},N=B;function O(j){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?O=function(E){return typeof E}:O=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},O(j)}var Qe=function(){var T=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},E=T.action,H=E===void 0?"copy":E,I=T.container,q=T.target,Me=T.text;if(H!=="copy"&&H!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(q!==void 0)if(q&&O(q)==="object"&&q.nodeType===1){if(H==="copy"&&q.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(H==="cut"&&(q.hasAttribute("readonly")||q.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Me)return N(Me,{container:I});if(q)return H==="cut"?h(q):N(q,{container:I})},De=Qe;function $e(j){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?$e=function(E){return typeof E}:$e=function(E){return E&&typeof Symbol=="function"&&E.constructor===Symbol&&E!==Symbol.prototype?"symbol":typeof E},$e(j)}function Ei(j,T){if(!(j instanceof T))throw new TypeError("Cannot call a class as a function")}function tn(j,T){for(var E=0;E0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof I.action=="function"?I.action:this.defaultAction,this.target=typeof I.target=="function"?I.target:this.defaultTarget,this.text=typeof I.text=="function"?I.text:this.defaultText,this.container=$e(I.container)==="object"?I.container:document.body}},{key:"listenClick",value:function(I){var q=this;this.listener=c()(I,"click",function(Me){return q.onClick(Me)})}},{key:"onClick",value:function(I){var q=I.delegateTarget||I.currentTarget,Me=this.action(q)||"copy",kt=De({action:Me,container:this.container,target:this.target(q),text:this.text(q)});this.emit(kt?"success":"error",{action:Me,text:kt,trigger:q,clearSelection:function(){q&&q.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(I){return vr("action",I)}},{key:"defaultTarget",value:function(I){var q=vr("target",I);if(q)return document.querySelector(q)}},{key:"defaultText",value:function(I){return vr("text",I)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(I){var q=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return N(I,q)}},{key:"cut",value:function(I){return h(I)}},{key:"isSupported",value:function(){var I=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],q=typeof I=="string"?[I]:I,Me=!!document.queryCommandSupported;return q.forEach(function(kt){Me=Me&&!!document.queryCommandSupported(kt)}),Me}}]),E}(a()),Ai=Li},828:function(n){var o=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,f){for(;a&&a.nodeType!==o;){if(typeof a.matches=="function"&&a.matches(f))return a;a=a.parentNode}}n.exports=s},438:function(n,o,i){var s=i(828);function a(u,p,m,d,h){var v=c.apply(this,arguments);return u.addEventListener(m,v,h),{destroy:function(){u.removeEventListener(m,v,h)}}}function f(u,p,m,d,h){return typeof u.addEventListener=="function"?a.apply(null,arguments):typeof m=="function"?a.bind(null,document).apply(null,arguments):(typeof u=="string"&&(u=document.querySelectorAll(u)),Array.prototype.map.call(u,function(v){return a(v,p,m,d,h)}))}function c(u,p,m,d){return function(h){h.delegateTarget=s(h.target,p),h.delegateTarget&&d.call(u,h)}}n.exports=f},879:function(n,o){o.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},o.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||o.node(i[0]))},o.string=function(i){return typeof i=="string"||i instanceof String},o.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(n,o,i){var s=i(879),a=i(438);function f(m,d,h){if(!m&&!d&&!h)throw new Error("Missing required arguments");if(!s.string(d))throw new TypeError("Second argument must be a String");if(!s.fn(h))throw new TypeError("Third argument must be a Function");if(s.node(m))return c(m,d,h);if(s.nodeList(m))return u(m,d,h);if(s.string(m))return p(m,d,h);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function c(m,d,h){return m.addEventListener(d,h),{destroy:function(){m.removeEventListener(d,h)}}}function u(m,d,h){return Array.prototype.forEach.call(m,function(v){v.addEventListener(d,h)}),{destroy:function(){Array.prototype.forEach.call(m,function(v){v.removeEventListener(d,h)})}}}function p(m,d,h){return a(document.body,m,d,h)}n.exports=f},817:function(n){function o(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var f=window.getSelection(),c=document.createRange();c.selectNodeContents(i),f.removeAllRanges(),f.addRange(c),s=f.toString()}return s}n.exports=o},279:function(n){function o(){}o.prototype={on:function(i,s,a){var f=this.e||(this.e={});return(f[i]||(f[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var f=this;function c(){f.off(i,c),s.apply(a,arguments)}return c._=s,this.on(i,c,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),f=0,c=a.length;for(f;f{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var rs=/["'&<>]/;Yo.exports=ns;function ns(e){var t=""+e,r=rs.exec(t);if(!r)return t;var n,o="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(c[0]===6||c[0]===2)){r=0;continue}if(c[0]===3&&(!i||c[1]>i[0]&&c[1]=e.length&&(e=void 0),{value:e&&e[n++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function W(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var n=r.call(e),o,i=[],s;try{for(;(t===void 0||t-- >0)&&!(o=n.next()).done;)i.push(o.value)}catch(a){s={error:a}}finally{try{o&&!o.done&&(r=n.return)&&r.call(n)}finally{if(s)throw s.error}}return i}function D(e,t,r){if(r||arguments.length===2)for(var n=0,o=t.length,i;n1||a(m,d)})})}function a(m,d){try{f(n[m](d))}catch(h){p(i[0][3],h)}}function f(m){m.value instanceof et?Promise.resolve(m.value.v).then(c,u):p(i[0][2],m)}function c(m){a("next",m)}function u(m){a("throw",m)}function p(m,d){m(d),i.shift(),i.length&&a(i[0][0],i[0][1])}}function pn(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof Ee=="function"?Ee(e):e[Symbol.iterator](),r={},n("next"),n("throw"),n("return"),r[Symbol.asyncIterator]=function(){return this},r);function n(i){r[i]=e[i]&&function(s){return new Promise(function(a,f){s=e[i](s),o(a,f,s.done,s.value)})}}function o(i,s,a,f){Promise.resolve(f).then(function(c){i({value:c,done:a})},s)}}function C(e){return typeof e=="function"}function at(e){var t=function(n){Error.call(n),n.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var It=at(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(n,o){return o+1+") "+n.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,n,o,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=Ee(s),f=a.next();!f.done;f=a.next()){var c=f.value;c.remove(this)}}catch(v){t={error:v}}finally{try{f&&!f.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var u=this.initialTeardown;if(C(u))try{u()}catch(v){i=v instanceof It?v.errors:[v]}var p=this._finalizers;if(p){this._finalizers=null;try{for(var m=Ee(p),d=m.next();!d.done;d=m.next()){var h=d.value;try{ln(h)}catch(v){i=i!=null?i:[],v instanceof It?i=D(D([],W(i)),W(v.errors)):i.push(v)}}}catch(v){n={error:v}}finally{try{d&&!d.done&&(o=m.return)&&o.call(m)}finally{if(n)throw n.error}}}if(i)throw new It(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)ln(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Sr=Ie.EMPTY;function jt(e){return e instanceof Ie||e&&"closed"in e&&C(e.remove)&&C(e.add)&&C(e.unsubscribe)}function ln(e){C(e)?e():e.unsubscribe()}var Le={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var st={setTimeout:function(e,t){for(var r=[],n=2;n0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var n=this,o=this,i=o.hasError,s=o.isStopped,a=o.observers;return i||s?Sr:(this.currentObservers=null,a.push(r),new Ie(function(){n.currentObservers=null,Ve(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var n=this,o=n.hasError,i=n.thrownError,s=n.isStopped;o?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new F;return r.source=this,r},t.create=function(r,n){return new xn(r,n)},t}(F);var xn=function(e){ie(t,e);function t(r,n){var o=e.call(this)||this;return o.destination=r,o.source=n,o}return t.prototype.next=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.next)===null||o===void 0||o.call(n,r)},t.prototype.error=function(r){var n,o;(o=(n=this.destination)===null||n===void 0?void 0:n.error)===null||o===void 0||o.call(n,r)},t.prototype.complete=function(){var r,n;(n=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||n===void 0||n.call(r)},t.prototype._subscribe=function(r){var n,o;return(o=(n=this.source)===null||n===void 0?void 0:n.subscribe(r))!==null&&o!==void 0?o:Sr},t}(x);var Et={now:function(){return(Et.delegate||Date).now()},delegate:void 0};var wt=function(e){ie(t,e);function t(r,n,o){r===void 0&&(r=1/0),n===void 0&&(n=1/0),o===void 0&&(o=Et);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=n,i._timestampProvider=o,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=n===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,n),i}return t.prototype.next=function(r){var n=this,o=n.isStopped,i=n._buffer,s=n._infiniteTimeWindow,a=n._timestampProvider,f=n._windowTime;o||(i.push(r),!s&&i.push(a.now()+f)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var n=this._innerSubscribe(r),o=this,i=o._infiniteTimeWindow,s=o._buffer,a=s.slice(),f=0;f0?e.prototype.requestAsyncId.call(this,r,n,o):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,n,o){var i;if(o===void 0&&(o=0),o!=null?o>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,n,o);var s=r.actions;n!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==n&&(ut.cancelAnimationFrame(n),r._scheduled=void 0)},t}(Wt);var Sn=function(e){ie(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var n=this._scheduled;this._scheduled=void 0;var o=this.actions,i;r=r||o.shift();do if(i=r.execute(r.state,r.delay))break;while((r=o[0])&&r.id===n&&o.shift());if(this._active=!1,i){for(;(r=o[0])&&r.id===n&&o.shift();)r.unsubscribe();throw i}},t}(Dt);var Oe=new Sn(wn);var M=new F(function(e){return e.complete()});function Vt(e){return e&&C(e.schedule)}function Cr(e){return e[e.length-1]}function Ye(e){return C(Cr(e))?e.pop():void 0}function Te(e){return Vt(Cr(e))?e.pop():void 0}function zt(e,t){return typeof Cr(e)=="number"?e.pop():t}var pt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Nt(e){return C(e==null?void 0:e.then)}function qt(e){return C(e[ft])}function Kt(e){return Symbol.asyncIterator&&C(e==null?void 0:e[Symbol.asyncIterator])}function Qt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function zi(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Yt=zi();function Gt(e){return C(e==null?void 0:e[Yt])}function Bt(e){return un(this,arguments,function(){var r,n,o,i;return $t(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,et(r.read())];case 3:return n=s.sent(),o=n.value,i=n.done,i?[4,et(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,et(o)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function Jt(e){return C(e==null?void 0:e.getReader)}function U(e){if(e instanceof F)return e;if(e!=null){if(qt(e))return Ni(e);if(pt(e))return qi(e);if(Nt(e))return Ki(e);if(Kt(e))return On(e);if(Gt(e))return Qi(e);if(Jt(e))return Yi(e)}throw Qt(e)}function Ni(e){return new F(function(t){var r=e[ft]();if(C(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function qi(e){return new F(function(t){for(var r=0;r=2;return function(n){return n.pipe(e?A(function(o,i){return e(o,i,n)}):de,ge(1),r?He(t):Dn(function(){return new Zt}))}}function Vn(){for(var e=[],t=0;t=2,!0))}function pe(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new x}:t,n=e.resetOnError,o=n===void 0?!0:n,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,f=a===void 0?!0:a;return function(c){var u,p,m,d=0,h=!1,v=!1,Y=function(){p==null||p.unsubscribe(),p=void 0},B=function(){Y(),u=m=void 0,h=v=!1},N=function(){var O=u;B(),O==null||O.unsubscribe()};return y(function(O,Qe){d++,!v&&!h&&Y();var De=m=m!=null?m:r();Qe.add(function(){d--,d===0&&!v&&!h&&(p=$r(N,f))}),De.subscribe(Qe),!u&&d>0&&(u=new rt({next:function($e){return De.next($e)},error:function($e){v=!0,Y(),p=$r(B,o,$e),De.error($e)},complete:function(){h=!0,Y(),p=$r(B,s),De.complete()}}),U(O).subscribe(u))})(c)}}function $r(e,t){for(var r=[],n=2;ne.next(document)),e}function K(e,t=document){return Array.from(t.querySelectorAll(e))}function z(e,t=document){let r=ce(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function ce(e,t=document){return t.querySelector(e)||void 0}function _e(){return document.activeElement instanceof HTMLElement&&document.activeElement||void 0}function tr(e){return L(b(document.body,"focusin"),b(document.body,"focusout")).pipe(ke(1),l(()=>{let t=_e();return typeof t!="undefined"?e.contains(t):!1}),V(e===_e()),J())}function Xe(e){return{x:e.offsetLeft,y:e.offsetTop}}function Kn(e){return L(b(window,"load"),b(window,"resize")).pipe(Ce(0,Oe),l(()=>Xe(e)),V(Xe(e)))}function rr(e){return{x:e.scrollLeft,y:e.scrollTop}}function dt(e){return L(b(e,"scroll"),b(window,"resize")).pipe(Ce(0,Oe),l(()=>rr(e)),V(rr(e)))}var Yn=function(){if(typeof Map!="undefined")return Map;function e(t,r){var n=-1;return t.some(function(o,i){return o[0]===r?(n=i,!0):!1}),n}return function(){function t(){this.__entries__=[]}return Object.defineProperty(t.prototype,"size",{get:function(){return this.__entries__.length},enumerable:!0,configurable:!0}),t.prototype.get=function(r){var n=e(this.__entries__,r),o=this.__entries__[n];return o&&o[1]},t.prototype.set=function(r,n){var o=e(this.__entries__,r);~o?this.__entries__[o][1]=n:this.__entries__.push([r,n])},t.prototype.delete=function(r){var n=this.__entries__,o=e(n,r);~o&&n.splice(o,1)},t.prototype.has=function(r){return!!~e(this.__entries__,r)},t.prototype.clear=function(){this.__entries__.splice(0)},t.prototype.forEach=function(r,n){n===void 0&&(n=null);for(var o=0,i=this.__entries__;o0},e.prototype.connect_=function(){!Wr||this.connected_||(document.addEventListener("transitionend",this.onTransitionEnd_),window.addEventListener("resize",this.refresh),va?(this.mutationsObserver_=new MutationObserver(this.refresh),this.mutationsObserver_.observe(document,{attributes:!0,childList:!0,characterData:!0,subtree:!0})):(document.addEventListener("DOMSubtreeModified",this.refresh),this.mutationEventsAdded_=!0),this.connected_=!0)},e.prototype.disconnect_=function(){!Wr||!this.connected_||(document.removeEventListener("transitionend",this.onTransitionEnd_),window.removeEventListener("resize",this.refresh),this.mutationsObserver_&&this.mutationsObserver_.disconnect(),this.mutationEventsAdded_&&document.removeEventListener("DOMSubtreeModified",this.refresh),this.mutationsObserver_=null,this.mutationEventsAdded_=!1,this.connected_=!1)},e.prototype.onTransitionEnd_=function(t){var r=t.propertyName,n=r===void 0?"":r,o=ba.some(function(i){return!!~n.indexOf(i)});o&&this.refresh()},e.getInstance=function(){return this.instance_||(this.instance_=new e),this.instance_},e.instance_=null,e}(),Gn=function(e,t){for(var r=0,n=Object.keys(t);r0},e}(),Jn=typeof WeakMap!="undefined"?new WeakMap:new Yn,Xn=function(){function e(t){if(!(this instanceof e))throw new TypeError("Cannot call a class as a function.");if(!arguments.length)throw new TypeError("1 argument required, but only 0 present.");var r=ga.getInstance(),n=new La(t,r,this);Jn.set(this,n)}return e}();["observe","unobserve","disconnect"].forEach(function(e){Xn.prototype[e]=function(){var t;return(t=Jn.get(this))[e].apply(t,arguments)}});var Aa=function(){return typeof nr.ResizeObserver!="undefined"?nr.ResizeObserver:Xn}(),Zn=Aa;var eo=new x,Ca=$(()=>k(new Zn(e=>{for(let t of e)eo.next(t)}))).pipe(g(e=>L(ze,k(e)).pipe(R(()=>e.disconnect()))),X(1));function he(e){return{width:e.offsetWidth,height:e.offsetHeight}}function ye(e){return Ca.pipe(S(t=>t.observe(e)),g(t=>eo.pipe(A(({target:r})=>r===e),R(()=>t.unobserve(e)),l(()=>he(e)))),V(he(e)))}function bt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function ar(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var to=new x,Ra=$(()=>k(new IntersectionObserver(e=>{for(let t of e)to.next(t)},{threshold:0}))).pipe(g(e=>L(ze,k(e)).pipe(R(()=>e.disconnect()))),X(1));function sr(e){return Ra.pipe(S(t=>t.observe(e)),g(t=>to.pipe(A(({target:r})=>r===e),R(()=>t.unobserve(e)),l(({isIntersecting:r})=>r))))}function ro(e,t=16){return dt(e).pipe(l(({y:r})=>{let n=he(e),o=bt(e);return r>=o.height-n.height-t}),J())}var cr={drawer:z("[data-md-toggle=drawer]"),search:z("[data-md-toggle=search]")};function no(e){return cr[e].checked}function Ke(e,t){cr[e].checked!==t&&cr[e].click()}function Ue(e){let t=cr[e];return b(t,"change").pipe(l(()=>t.checked),V(t.checked))}function ka(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function Ha(){return L(b(window,"compositionstart").pipe(l(()=>!0)),b(window,"compositionend").pipe(l(()=>!1))).pipe(V(!1))}function oo(){let e=b(window,"keydown").pipe(A(t=>!(t.metaKey||t.ctrlKey)),l(t=>({mode:no("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),A(({mode:t,type:r})=>{if(t==="global"){let n=_e();if(typeof n!="undefined")return!ka(n,r)}return!0}),pe());return Ha().pipe(g(t=>t?M:e))}function le(){return new URL(location.href)}function ot(e){location.href=e.href}function io(){return new x}function ao(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)ao(e,r)}function _(e,t,...r){let n=document.createElement(e);if(t)for(let o of Object.keys(t))typeof t[o]!="undefined"&&(typeof t[o]!="boolean"?n.setAttribute(o,t[o]):n.setAttribute(o,""));for(let o of r)ao(n,o);return n}function fr(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function so(){return location.hash.substring(1)}function Dr(e){let t=_("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function Pa(e){return L(b(window,"hashchange"),e).pipe(l(so),V(so()),A(t=>t.length>0),X(1))}function co(e){return Pa(e).pipe(l(t=>ce(`[id="${t}"]`)),A(t=>typeof t!="undefined"))}function Vr(e){let t=matchMedia(e);return er(r=>t.addListener(()=>r(t.matches))).pipe(V(t.matches))}function fo(){let e=matchMedia("print");return L(b(window,"beforeprint").pipe(l(()=>!0)),b(window,"afterprint").pipe(l(()=>!1))).pipe(V(e.matches))}function zr(e,t){return e.pipe(g(r=>r?t():M))}function ur(e,t={credentials:"same-origin"}){return ue(fetch(`${e}`,t)).pipe(fe(()=>M),g(r=>r.status!==200?Ot(()=>new Error(r.statusText)):k(r)))}function We(e,t){return ur(e,t).pipe(g(r=>r.json()),X(1))}function uo(e,t){let r=new DOMParser;return ur(e,t).pipe(g(n=>n.text()),l(n=>r.parseFromString(n,"text/xml")),X(1))}function pr(e){let t=_("script",{src:e});return $(()=>(document.head.appendChild(t),L(b(t,"load"),b(t,"error").pipe(g(()=>Ot(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(l(()=>{}),R(()=>document.head.removeChild(t)),ge(1))))}function po(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function lo(){return L(b(window,"scroll",{passive:!0}),b(window,"resize",{passive:!0})).pipe(l(po),V(po()))}function mo(){return{width:innerWidth,height:innerHeight}}function ho(){return b(window,"resize",{passive:!0}).pipe(l(mo),V(mo()))}function bo(){return G([lo(),ho()]).pipe(l(([e,t])=>({offset:e,size:t})),X(1))}function lr(e,{viewport$:t,header$:r}){let n=t.pipe(ee("size")),o=G([n,r]).pipe(l(()=>Xe(e)));return G([r,t,o]).pipe(l(([{height:i},{offset:s,size:a},{x:f,y:c}])=>({offset:{x:s.x-f,y:s.y-c+i},size:a})))}(()=>{function e(n,o){parent.postMessage(n,o||"*")}function t(...n){return n.reduce((o,i)=>o.then(()=>new Promise(s=>{let a=document.createElement("script");a.src=i,a.onload=s,document.body.appendChild(a)})),Promise.resolve())}var r=class extends EventTarget{constructor(n){super(),this.url=n,this.m=i=>{i.source===this.w&&(this.dispatchEvent(new MessageEvent("message",{data:i.data})),this.onmessage&&this.onmessage(i))},this.e=(i,s,a,f,c)=>{if(s===`${this.url}`){let u=new ErrorEvent("error",{message:i,filename:s,lineno:a,colno:f,error:c});this.dispatchEvent(u),this.onerror&&this.onerror(u)}};let o=document.createElement("iframe");o.hidden=!0,document.body.appendChild(this.iframe=o),this.w.document.open(),this.w.document.write(` + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+ + + + + + + +

Welcome to openhdemg

+


+

banner logo

+


+

Overview

+

openhdemg is a powerful toolbox for the analysis of HD-EMG recordings.

+

openhdemg is an open-source framework written in Python 3 with many functionalities specifically designed for the analysis of High-Density Electromyography (HD-EMG) recordings. Some of its main features are listed below, but there is much more to discover! For a full list of available functions, please refer to the API reference section.

+
    +
  1. Load decomposed HD-EMG files from various sources, such as .mat and .csv files. This allows to interface openhdemg with the commonly used softwares like OTBioLab+ or DEMUSE and potentially with any other software.
  2. +
  3. Visualise your EMG or force/reference signal, as well as the motor units' firing times and their action potentials shape.
  4. +
  5. Edit your file changing the reference signal offset, filtering noise, calculating differential derivations and removing unwanted motor units.
  6. +
  7. Analyse motor units' recruitment/derecruitment thresholds, discharge rate, conduction velocity, action potentials amplitude and more...
  8. +
  9. Remove duplicates between different files from the same recording session and analyse them together to increase the number of motor units'.
  10. +
  11. Track motor units' across different recording sessions.
  12. +
  13. Save the results of the analyses and the edited file.
  14. +
+

Start immediately

+

If you already know how to use Python, that's the way to go! Otherwise, have a look at the tutorial explaining how to Setup your Python environment.

+

openhdemg can be easily installed using pip:

+
pip install openhdemg
+
+

or conda:

+
conda install -c conda-forge openhdemg
+
+

If you want an overview of what you can do with the openhdemg library, have a look at the Quick Start section and then explore all the functions in the API reference.

+

Good to know

+

In addition to the rich set of modules and functions presented in the API reference, openhdemg offers also a practical graphical user interface (GUI) from which many tasks can be performed without writing a single line of code!

+

After installing the openhdemg package, the GUI can be simply accessed from the command line (check to be into the virtual environment) with:

+
python -m openhdemg.gui.openhdemg_gui
+
+

Once opened, it will look like this. It is cool, isn't it?

+

gui_preview

+

Why openhdemg

+

The openhdemg project was born in 2022 with the aim to provide the HD-EMG community with a free and open-source framework to analyse motor units' properties.

+

The field of EMG analysis in humans has always been characterized by a lack of available software for signal post-processing and analysis. This has forced users to code their own scripts, which can lead to problems when the scripts are not shared open-source. Why?

+
    +
  • If different users use different scripts, the results can differ.
  • +
  • Any code can contain errors, if the code is not shared, the errors will never be known and them will repeat in the following analyses.
  • +
  • There is a significant difference between the methods presented in research papers and the practical implementation of a script. Reproducing a script solely based on written instructions can be challenging, making the reproducibility of a study unrealistic.
  • +
  • Anyone who doesn't code, will not be able to analyse the recordings.
  • +
+

In order to overcome these problems, we developed a fully transparent framework for the analysis of motor units' properties.

+

This project is intended for the users that already know the Python language, for those willing to learn it and even for those not interested in coding, thanks to a friendly graphical user interface (GUI).

+

Both the openhdemg project and its contributors adhere to the Open Science Principles and especially to the idea of public release of data and other scientific resources necessary for conducting honest research.

+ + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/md_graphics/GUI/Advanced_analysis_window.png b/md_graphics/GUI/Advanced_analysis_window.png new file mode 100644 index 0000000..ed0dd98 Binary files /dev/null and b/md_graphics/GUI/Advanced_analysis_window.png differ diff --git a/md_graphics/GUI/CV_Estimation_window.png b/md_graphics/GUI/CV_Estimation_window.png new file mode 100644 index 0000000..0b46236 Binary files /dev/null and b/md_graphics/GUI/CV_Estimation_window.png differ diff --git a/md_graphics/GUI/Duplicate_Removal_window.png b/md_graphics/GUI/Duplicate_Removal_window.png new file mode 100644 index 0000000..4a1d13a Binary files /dev/null and b/md_graphics/GUI/Duplicate_Removal_window.png differ diff --git a/md_graphics/GUI/Force_Analysis_window.png b/md_graphics/GUI/Force_Analysis_window.png new file mode 100644 index 0000000..a2592b1 Binary files /dev/null and b/md_graphics/GUI/Force_Analysis_window.png differ diff --git a/md_graphics/GUI/MU_Tracking_window.png b/md_graphics/GUI/MU_Tracking_window.png new file mode 100644 index 0000000..01c7785 Binary files /dev/null and b/md_graphics/GUI/MU_Tracking_window.png differ diff --git a/md_graphics/GUI/MU_properties_window.png b/md_graphics/GUI/MU_properties_window.png new file mode 100644 index 0000000..fca8c80 Binary files /dev/null and b/md_graphics/GUI/MU_properties_window.png differ diff --git a/md_graphics/GUI/Plot_window.png b/md_graphics/GUI/Plot_window.png new file mode 100644 index 0000000..54f3a87 Binary files /dev/null and b/md_graphics/GUI/Plot_window.png differ diff --git a/md_graphics/GUI/Refsig_Filter_window.png b/md_graphics/GUI/Refsig_Filter_window.png new file mode 100644 index 0000000..370fdef Binary files /dev/null and b/md_graphics/GUI/Refsig_Filter_window.png differ diff --git a/md_graphics/GUI/Remove_MU_window.png b/md_graphics/GUI/Remove_MU_window.png new file mode 100644 index 0000000..1563149 Binary files /dev/null and b/md_graphics/GUI/Remove_MU_window.png differ diff --git a/md_graphics/GUI/Resize_window.png b/md_graphics/GUI/Resize_window.png new file mode 100644 index 0000000..4b48c11 Binary files /dev/null and b/md_graphics/GUI/Resize_window.png differ diff --git a/md_graphics/Index/Banner_Logo.png b/md_graphics/Index/Banner_Logo.png new file mode 100644 index 0000000..0f9de04 Binary files /dev/null and b/md_graphics/Index/Banner_Logo.png differ diff --git a/md_graphics/Index/GUI_Preview.png b/md_graphics/Index/GUI_Preview.png new file mode 100644 index 0000000..55c7826 Binary files /dev/null and b/md_graphics/Index/GUI_Preview.png differ diff --git a/md_graphics/Quick-Start/IDR_mu2removed.png b/md_graphics/Quick-Start/IDR_mu2removed.png new file mode 100644 index 0000000..0d8eefb Binary files /dev/null and b/md_graphics/Quick-Start/IDR_mu2removed.png differ diff --git a/md_graphics/Quick-Start/MUs_pulses_non_sorted.png b/md_graphics/Quick-Start/MUs_pulses_non_sorted.png new file mode 100644 index 0000000..72de647 Binary files /dev/null and b/md_graphics/Quick-Start/MUs_pulses_non_sorted.png differ diff --git a/md_graphics/Quick-Start/MUs_pulses_sorted.png b/md_graphics/Quick-Start/MUs_pulses_sorted.png new file mode 100644 index 0000000..9ca665b Binary files /dev/null and b/md_graphics/Quick-Start/MUs_pulses_sorted.png differ diff --git a/md_graphics/Quick-Start/MUs_pulses_sorted_idr.png b/md_graphics/Quick-Start/MUs_pulses_sorted_idr.png new file mode 100644 index 0000000..d048f81 Binary files /dev/null and b/md_graphics/Quick-Start/MUs_pulses_sorted_idr.png differ diff --git a/md_graphics/Quick-Start/MUs_pulses_sorted_idr_filteroffs.png b/md_graphics/Quick-Start/MUs_pulses_sorted_idr_filteroffs.png new file mode 100644 index 0000000..d76c307 Binary files /dev/null and b/md_graphics/Quick-Start/MUs_pulses_sorted_idr_filteroffs.png differ diff --git a/objects.inv b/objects.inv new file mode 100644 index 0000000..5c47334 Binary files /dev/null and b/objects.inv differ diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 0000000..5e08b11 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-,:!=\\[\\]()\"`/]+|\\.(?!\\d)|&[lg]t;|(?!\\b)(?=[A-Z][a-z])","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Welcome to openhdemg","text":""},{"location":"#overview","title":"Overview","text":"

openhdemg is a powerful toolbox for the analysis of HD-EMG recordings.

openhdemg is an open-source framework written in Python 3 with many functionalities specifically designed for the analysis of High-Density Electromyography (HD-EMG) recordings. Some of its main features are listed below, but there is much more to discover! For a full list of available functions, please refer to the API reference section.

  1. Load decomposed HD-EMG files from various sources, such as .mat and .csv files. This allows to interface openhdemg with the commonly used softwares like OTBioLab+ or DEMUSE and potentially with any other software.
  2. Visualise your EMG or force/reference signal, as well as the motor units' firing times and their action potentials shape.
  3. Edit your file changing the reference signal offset, filtering noise, calculating differential derivations and removing unwanted motor units.
  4. Analyse motor units' recruitment/derecruitment thresholds, discharge rate, conduction velocity, action potentials amplitude and more...
  5. Remove duplicates between different files from the same recording session and analyse them together to increase the number of motor units'.
  6. Track motor units' across different recording sessions.
  7. Save the results of the analyses and the edited file.
"},{"location":"#start-immediately","title":"Start immediately","text":"

If you already know how to use Python, that's the way to go! Otherwise, have a look at the tutorial explaining how to Setup your Python environment.

openhdemg can be easily installed using pip:

pip install openhdemg\n

or conda:

conda install -c conda-forge openhdemg\n

If you want an overview of what you can do with the openhdemg library, have a look at the Quick Start section and then explore all the functions in the API reference.

"},{"location":"#good-to-know","title":"Good to know","text":"

In addition to the rich set of modules and functions presented in the API reference, openhdemg offers also a practical graphical user interface (GUI) from which many tasks can be performed without writing a single line of code!

After installing the openhdemg package, the GUI can be simply accessed from the command line (check to be into the virtual environment) with:

python -m openhdemg.gui.openhdemg_gui\n

Once opened, it will look like this. It is cool, isn't it?

"},{"location":"#why-openhdemg","title":"Why openhdemg","text":"

The openhdemg project was born in 2022 with the aim to provide the HD-EMG community with a free and open-source framework to analyse motor units' properties.

The field of EMG analysis in humans has always been characterized by a lack of available software for signal post-processing and analysis. This has forced users to code their own scripts, which can lead to problems when the scripts are not shared open-source. Why?

  • If different users use different scripts, the results can differ.
  • Any code can contain errors, if the code is not shared, the errors will never be known and them will repeat in the following analyses.
  • There is a significant difference between the methods presented in research papers and the practical implementation of a script. Reproducing a script solely based on written instructions can be challenging, making the reproducibility of a study unrealistic.
  • Anyone who doesn't code, will not be able to analyse the recordings.

In order to overcome these problems, we developed a fully transparent framework for the analysis of motor units' properties.

This project is intended for the users that already know the Python language, for those willing to learn it and even for those not interested in coding, thanks to a friendly graphical user interface (GUI).

Both the openhdemg project and its contributors adhere to the Open Science Principles and especially to the idea of public release of data and other scientific resources necessary for conducting honest research.

"},{"location":"API_analysis/","title":"analysis","text":""},{"location":"API_analysis/#description","title":"Description","text":"

This module contains all the functions used to analyse the MUs properties when not involving the MUs action potential shape.

"},{"location":"API_analysis/#openhdemg.library.analysis.compute_thresholds","title":"compute_thresholds(emgfile, event_='rt_dert', type_='abs_rel', mvc=0)","text":"

Calculates recruitment/derecruitment thresholds.

Values are calculated both in absolute and relative therms.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

event_

When to calculate the thresholds.

rt_dert Both recruitment and derecruitment tresholds will be calculated. rt Only recruitment tresholds will be calculated. dert Only derecruitment tresholds will be calculated.

TYPE: str {\"rt_dert\", \"rt\", \"dert\"} DEFAULT: \"rt_dert\"

type_

The tipe of value to calculate.

abs_rel Both absolute and relative tresholds will be calculated. rel Only relative tresholds will be calculated. abs Only absolute tresholds will be calculated.

TYPE: str {\"abs_rel\", \"rel\", \"abs\"} DEFAULT: \"abs_rel\"

mvc

The maximum voluntary contraction (MVC). if mvc is 0, the user is asked to input MVC; otherwise, the value passed is used.

TYPE: float DEFAULT: 0

RETURNS DESCRIPTION mus_thresholds

A DataFrame containing the requested thresholds.

TYPE: pd.DataFrame

"},{"location":"API_analysis/#openhdemg.library.analysis.compute_thresholds--see-also","title":"See also","text":"
  • compute_dr : calculate the discharge rate.
  • basic_mus_properties : calculate basic MUs properties on a trapezoidal contraction.
  • compute_covisi : calculate the coefficient of variation of interspike interval.
  • compute_drvariability : claculate the DR variability.

Examples:

Load the EMG file and compute the thresholds.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> mus_thresholds = emg.compute_thresholds(\n...     emgfile=emgfile,\n...     event_=\"rt_dert\",\n... )\n>>> mus_thresholds\n       abs_RT    abs_DERT     rel_RT   rel_DERT\n0  160.148294  137.682351  18.665302  16.046894\n1   39.138554   49.860936   4.561603   5.811298\n2   88.155160   95.133218  10.274494  11.087788\n3   37.776982   41.010716   4.402912   4.779804\n

Type of output can be adjusted, e.g., to have only absolute values at recruitment.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> mus_thresholds = emg.compute_thresholds(\n...     emgfile=emgfile,\n...     event_=\"rt\",\n...     type_=\"abs\",\n... )\n>>> mus_thresholds\n       abs_RT\n0  160.148294\n1   39.138554\n2   88.155160\n3   37.776982\n
"},{"location":"API_analysis/#openhdemg.library.analysis.compute_dr","title":"compute_dr(emgfile, n_firings_RecDerec=4, n_firings_steady=10, start_steady=-1, end_steady=-1, event_='rec_derec_steady')","text":"

Calculate the discharge rate (DR).

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

n_firings_RecDerec

The number of firings at recruitment and derecruitment to consider for the calculation of the DR.

TYPE: int DEFAULT: 4

n_firings_steady

The number of firings to consider for the calculation of the DR at the start and at the end of the steady-state phase.

TYPE: int DEFAULT: 10

start_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

end_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

event_

When to calculate the DR.

rec_derec_steady DR is calculated at recruitment, derecruitment and during the steady-state phase. rec DR is calculated at recruitment. derec DR is calculated at derecruitment. rec_derec DR is calculated at recruitment and derecruitment. steady DR is calculated during the steady-state phase.

TYPE: str {\"rec_derec_steady\", \"rec\", \"derec\", \"rec_derec\", \"steady\"} DEFAULT: \"rec_derec_steady\"

RETURNS DESCRIPTION mus_dr

A pd.DataFrame containing the requested DR.

TYPE: pd.DataFrame

WARNS DESCRIPTION warning

When calculation of DR at rec/derec fails due to not enough firings.

"},{"location":"API_analysis/#openhdemg.library.analysis.compute_dr--see-also","title":"See also","text":"
  • compute_thresholds : calculates recruitment/derecruitment thresholds.
  • basic_mus_properties : calculate basic MUs properties on a trapezoidal contraction.
  • compute_covisi : calculate the coefficient of variation of interspike interval.
  • compute_drvariability : claculate the DR variability.
"},{"location":"API_analysis/#openhdemg.library.analysis.compute_dr--notes","title":"Notes","text":"

DR for all the contraction is automatically calculated and returned.

Examples:

Load the EMG file and compute the DR.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> mus_dr = emg.compute_dr(emgfile=emgfile)\n>>> mus_dr\n     DR_rec  DR_derec  DR_start_steady  DR_end_steady  DR_all_steady     DR_all\n0  5.701081  4.662196         7.321255       6.420720       6.907559   6.814342\n1  7.051127  6.752467        14.919066      10.245462      11.938671  11.683134\n2  6.101529  4.789000         7.948740       6.133345       7.695189   8.055731\n3  6.345692  5.333535        11.121785       9.265212      11.544140  11.109796\n

Type of output can be adjusted, e.g., to have only the DR at recruitment.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> mus_dr = emg.compute_dr(emgfile=emgfile, event_=\"rec\")\n>>> mus_dr\n     DR_rec     DR_all\n0  5.701081   6.814342\n1  7.051127  11.683134\n2  6.101529   8.055731\n3  6.345692  11.109796\n

The manual selection of the steady state phase can be bypassed if previously calculated with an automated method.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> mus_dr = emg.compute_dr(\n...     emgfile=emgfile,\n...     start_steady=20000,\n...     end_steady=50000,\n...     event_=\"steady\",\n... )\n>>> mus_dr\n   DR_start_steady  DR_end_steady  DR_all_steady     DR_all\n0         7.476697       6.271750       6.794170   6.814342\n1        14.440561      10.019572      11.822081  11.683134\n2         7.293547       5.846093       7.589531   8.055731\n3        13.289651       9.694317      11.613640  11.109796\n
"},{"location":"API_analysis/#openhdemg.library.analysis.basic_mus_properties","title":"basic_mus_properties(emgfile, n_firings_RecDerec=4, n_firings_steady=10, start_steady=-1, end_steady=-1, mvc=0)","text":"

Calculate basic MUs properties on a trapezoidal contraction.

The function is meant to be used on trapezoidal contractions and calculates: the absolute/relative recruitment/derecruitment thresholds, the discharge rate at recruitment, derecruitment, during the steady-state phase and during the entire contraction, the coefficient of variation of interspike interval, the coefficient of variation of force signal.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

n_firings_RecDerec

The number of firings at recruitment and derecruitment to consider for the calculation of the DR.

TYPE: int DEFAULT: 4

n_firings_steady

The number of firings to consider for the calculation of the DR at the start and at the end of the steady-state phase.

TYPE: int DEFAULT: 10

start_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

end_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

mvc

The maximum voluntary contraction (MVC). It is suggest to report MVC in Newton (N). If 0 (default), the user will be asked to imput it manually. Otherwise, the passed value will be used.

TYPE: float DEFAULT: 0

RETURNS DESCRIPTION exportable_df

A pd.DataFrame containing the results of the analysis.

TYPE: pd.DataFrame

"},{"location":"API_analysis/#openhdemg.library.analysis.basic_mus_properties--see-also","title":"See also","text":"
  • compute_thresholds : calculates recruitment/derecruitment thresholds.
  • compute_dr : calculate the discharge rate.
  • compute_covisi : calculate the coefficient of variation of interspike interval.
  • compute_drvariability : claculate the DR variability.

Examples:

Get full summary of all the MUs properties.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> df = emg.basic_mus_properties(emgfile=emgfile)\n>>> df\n     MVC  MU_number      abs_RT    abs_DERT     rel_RT   rel_DERT    DR_rec  DR_derec  DR_start_steady  DR_end_steady  DR_all_steady     DR_all  COVisi_steady  COVisi_all  COV_steady\n0  786.0          1  146.709276  126.128587  18.665302  16.046894  5.701081  4.662196         7.467810       6.242360       6.902616   6.814342      11.296316   16.309681    1.423286\n1    NaN          2   35.854200   45.676801   4.561603   5.811298  7.051127  6.752467        11.798908       9.977337      11.784061  11.683134      15.871254   21.233615         NaN\n2    NaN          3   80.757524   87.150011  10.274494  11.087788  6.101529  4.789000         7.940926       5.846093       7.671361   8.055731      35.755090   35.308650         NaN\n3    NaN          4   34.606886   37.569257   4.402912   4.779804  6.345692  5.333535        11.484875       9.636914      11.594712  11.109796      24.611246   29.372524         NaN\n

We can bypass manual prompting the MVC by pre-specifying it and/or bypass the manual selection of the steady state phase if previously calculated with an automated method.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> df = emg.basic_mus_properties(\n...     emgfile=emgfile,\n...     start_steady=20000,\n...     end_steady=50000,\n...     mvc=786,\n... )\n>>> df\n     MVC  MU_number      abs_RT    abs_DERT     rel_RT   rel_DERT    DR_rec  DR_derec  DR_start_steady  DR_end_steady  DR_all_steady     DR_all  COVisi_steady  COVisi_all  COV_steady\n0  786.0          1  146.709276  126.128587  18.665302  16.046894  5.701081  4.662196         7.476697       6.271750       6.794170   6.814342      11.066966   16.309681    1.431752\n1    NaN          2   35.854200   45.676801   4.561603   5.811298  7.051127  6.752467        14.440561      10.019572      11.822081  11.683134      15.076819   21.233615         NaN\n2    NaN          3   80.757524   87.150011  10.274494  11.087788  6.101529  4.789000         7.293547       5.846093       7.589531   8.055731      36.996894   35.308650         NaN\n3    NaN          4   34.606886   37.569257   4.402912   4.779804  6.345692  5.333535        13.289651       9.694317      11.613640  11.109796      26.028689   29.372524         NaN\n
"},{"location":"API_analysis/#openhdemg.library.analysis.compute_covisi","title":"compute_covisi(emgfile, n_firings_RecDerec=4, start_steady=-1, end_steady=-1, event_='rec_derec_steady', single_mu_number=-1)","text":"

Calculate theCOVisi.

This function calculates the coefficient of variation of interspike interval (COVisi).

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

n_firings_RecDerec

The number of firings at recruitment and derecruitment to consider for the calculation of the COVisi.

TYPE: int DEFAULT: 4

start_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

end_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

event_

When to calculate the COVisi.

rec_derec_steady covisi is calculated at recruitment, derecruitment and during the steady-state phase. rec covisi is calculated at recruitment. derec covisi is calculated at derecruitment. rec_derec covisi is calculated at recruitment and derecruitment. steady covisi is calculated during the steady-state phase.

TYPE: str {\"rec_derec_steady\", \"rec\", \"derec\", \"rec_derec\", \"steady\"} DEFAULT: \"rec_derec_steady\"

single_mu_number

Number of the specific MU to compute the COVisi. If single_mu_number >= 0, only the COVisi of the entire contraction will be returned. If -1 (default), COVisi will be calculated for all the MUs.

TYPE: int DEFAULT: -1

RETURNS DESCRIPTION covisi

A pd.DataFrame containing the requested COVisi.

TYPE: pd.DataFrame

"},{"location":"API_analysis/#openhdemg.library.analysis.compute_covisi--see-also","title":"See also","text":"
  • compute_thresholds : calculates recruitment/derecruitment thresholds.
  • compute_dr : calculate the discharge rate.
  • basic_mus_properties : calculate basic MUs properties on a trapezoidal contraction.
  • compute_drvariability : claculate the DR variability.
"},{"location":"API_analysis/#openhdemg.library.analysis.compute_covisi--notes","title":"Notes","text":"

COVisi for all the contraction is automatically calculated and returned.

Examples:

Compute covisi during the various parts of the trapezoidal contraction.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> df = emg.compute_covisi(emgfile=emgfile)\n>>> df\n   COVisi_rec  COVisi_derec  COVisi_steady  COVisi_all\n0    8.600651     24.007405      11.230602   16.309681\n1   46.874208     19.243432      16.657603   21.233615\n2   32.212757     18.642514      35.421124   35.308650\n3   62.995864     13.080768      24.966372   29.372524\n

If the steady-state phase has been pre-identified, the manual selection of the area can be bypassed.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> df = emg.compute_covisi(\n...     emgfile=emgfile,\n...     event_=\"rec_derec\",\n...     start_steady=20000,\n...     end_steady=50000,\n... )\n>>> df\n   COVisi_rec  COVisi_derec  COVisi_all\n0    8.600651     24.007405   16.309681\n1   46.874208     19.243432   21.233615\n2   32.212757     18.642514   35.308650\n3   62.995864     13.080768   29.372524\n

To access the covisi of the entire contraction of a single MU.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> df = emg.compute_covisi(emgfile=emgfile, single_mu_number=2)\n>>> df\n   COVisi_all\n0    35.30865\n
"},{"location":"API_analysis/#openhdemg.library.analysis.compute_drvariability","title":"compute_drvariability(emgfile, n_firings_RecDerec=4, start_steady=-1, end_steady=-1, event_='rec_derec_steady')","text":"

Claculate the DR variability.

This function calculates the variability (as the coefficient of variation) of the instantaneous discharge rate (DR) at recruitment, derecruitment, during the steady-state phase and during all the contraction.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

n_firings_RecDerec

The number of firings at recruitment and derecruitment to consider for the calculation of the DR variability.

TYPE: int DEFAULT: 4

start_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

end_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

event_

When to calculate the DR variability.

rec_derec_steady DR variability is calculated at recruitment, derecruitment and during the steady-state phase. rec DR variability is calculated at recruitment. derec DR variability is calculated at derecruitment. rec_derec DR variability is calculated at recruitment and derecruitment. steady DR variability is calculated during the steady-state phase.

TYPE: str {\"rec_derec_steady\", \"rec\", \"derec\", \"rec_derec\", \"steady\"} DEFAULT: \"rec_derec_steady\"

RETURNS DESCRIPTION drvariability

A pd.DataFrame containing the requested DR variability.

TYPE: pd.DataFrame

"},{"location":"API_analysis/#openhdemg.library.analysis.compute_drvariability--see-also","title":"See also","text":"
  • compute_thresholds : calculates recruitment/derecruitment thresholds.
  • compute_dr : calculate the discharge rate.
  • basic_mus_properties : calculate basic MUs properties on a trapezoidal contraction.
  • compute_covisi : calculate the coefficient of variation of interspike interval.
"},{"location":"API_analysis/#openhdemg.library.analysis.compute_drvariability--notes","title":"Notes","text":"

DR variability for all the contraction is automatically calculated and returned.

Examples:

Compute covisi during the various parts of the trapezoidal contraction.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> df = emg.compute_covisi(emgfile=emgfile)\n>>> df\n   DRvar_rec  DRvar_derec  DRvar_steady  DRvar_all\n0   8.560971    21.662783     11.051780  13.937779\n1  36.934213    17.714761     55.968609  52.726356\n2  28.943139    17.263000     49.375100  54.420703\n3  48.322396    12.873456     54.718482  48.019809\n

If the steady-state phase has been pre-identified, the manual selection of the area can be bypassed.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> df = emg.compute_covisi(\n...     emgfile=emgfile,\n...     event_=\"rec_derec\",\n...     start_steady=20000,\n...     end_steady=50000,\n... )\n>>> df\n   DRvar_rec  DRvar_derec  DRvar_all\n0   8.560971    21.662783  13.937779\n1  36.934213    17.714761  52.726356\n2  28.943139    17.263000  54.420703\n3  48.322396    12.873456  48.019809\n
"},{"location":"API_electrodes/","title":"electrodes","text":""},{"location":"API_electrodes/#description","title":"Description","text":"

This module contains informations about the electrodes commonly used for HD-EMG recordings. Functions to sort the electrode position are also included.

"},{"location":"API_electrodes/#notes","title":"Notes","text":"

The files saved from the DEMUSE software are supposed to be already sorted.

"},{"location":"API_electrodes/#openhdemg.library.electrodes.sort_rawemg","title":"sort_rawemg(emgfile, code='GR08MM1305', orientation=180, dividebycolumn=True, n_rows=None, n_cols=None)","text":"

Sort RAW_SIGNAL based on matrix type and orientation.

To date, built-in sorting functions have been implemented for the matrices: Code (Orientation) GR08MM1305 (0, 180), GR04MM1305 (0, 180), GR10MM0808 (0, 180).

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

code

The code of the matrix used. If \"None\", the electodes are not sorted but n_rows and n_cols must be specified when dividebycolumn == True.

TYPE: str {\"GR08MM1305\", \"GR04MM1305\", \"GR10MM0808\", \"None\"} DEFAULT: \"GR08MM1305\"

orientation

Orientation in degree of the matrix. E.g. 180 corresponds to the matrix connection toward the researcher or the ground (depending on the limb).

TYPE: int {0, 180} DEFAULT: 180

dividebycolumn

Whether to return the sorted channels classified by matrix column.

DEFAULT: True

n_rows

The number of rows and columns of the matrix. This parameter is used to divide the channels based on the matrix shape. These are normally inferred by the matrix code and must be specified only if code == None.

TYPE: None or int DEFAULT: None

n_cols

The number of rows and columns of the matrix. This parameter is used to divide the channels based on the matrix shape. These are normally inferred by the matrix code and must be specified only if code == None.

TYPE: None or int DEFAULT: None

RETURNS DESCRIPTION sorted_rawemg

If dividebycolumn == True a dict containing the sorted electrodes. Every key of the dictionary represents a different column of the matrix. Rows are stored in the dict as a pd.DataFrame. If dividebycolumn == False a pd.DataFrame containing the sorted electrodes. The matrix channels are stored in the pd.DataFrame columns.

TYPE: dict or pd.DataFrame

"},{"location":"API_electrodes/#openhdemg.library.electrodes.sort_rawemg--notes","title":"Notes","text":"

The returned file is called sorted_rawemg for convention.

Examples:

Sort emgfile RAW_SIGNAL and divide it by columns.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True,\n... )\n>>> sorted_rawemg[\"col0\"]\n        0          1          2 ...        10         11         12\n0     NaN -11.189778   3.560384 ... -2.034505  -3.051758  -0.508626\n1     NaN -12.715657   4.577637 ...  2.034505  -7.120768  -0.508626\n2     NaN   0.508626  21.870932 ... 17.801920   8.646647  16.276041\n3     NaN   6.103516  26.957193 ... 26.448568  19.327799  19.836426\n4     NaN  -5.594889  13.224284 ... 10.681152   2.034505   3.560384\n...    ..        ...        ... ...       ...        ...        ...\n63483 NaN -15.767415 -22.379557 ...-12.207031 -12.207031 -15.767415\n63484 NaN  -9.155273 -19.327799 ... -7.629395  -8.138021  -8.138021\n63485 NaN  -6.103516 -12.207031 ... -6.103516  -5.086263  -3.051758\n63486 NaN  -6.103516 -15.767415 ... -3.560384  -0.508626   2.543132\n63487 NaN  -8.138021 -18.819174 ... -2.034505  -1.525879   3.560384\n

Sort emgfile RAW_SIGNAL without dividing it by columns.

>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=False,\n... )\n>>> sorted_rawemg\n       0          1          2  ...        62         63         64\n0     NaN -11.189778   3.560384 ... -5.086263  -9.663899   2.034505\n1     NaN -12.715657   4.577637 ... -3.560384  -8.646647   1.017253\n2     NaN   0.508626  21.870932 ... 11.189778   6.612142  17.293295\n3     NaN   6.103516  26.957193 ... 22.888184  14.750163  21.362305\n4     NaN  -5.594889  13.224284 ...  9.663899   1.525879   6.612142\n...    ..        ...        ... ...       ...        ...        ...\n63483 NaN -15.767415 -22.379557 ... -8.646647 -20.345053 -15.258789\n63484 NaN  -9.155273 -19.327799 ... -7.120768 -19.327799 -13.732910\n63485 NaN  -6.103516 -12.207031 ... -3.051758 -10.681152  -6.103516\n63486 NaN  -6.103516 -15.767415 ...  2.543132  -7.120768  -4.069010\n63487 NaN  -8.138021 -18.819174 ...  2.034505  -3.051758  -0.508626\n

Avoid RAW_SIGNAL sorting but divide it by columns.

>>> emgfile = emg.askopenfile(filesource=\"CUSTOM\")\n>>> sorted_rawemg = emg.sort_rawemg(emgfile, code=\"None\", n_cols=5, n_rows=13)\n>>> sorted_rawemg[\"col0\"]\n             0         1         2  ...       10        11  12\n0      0.008138  0.001017  0.002035 ... 0.005595  0.008647 NaN\n1     -0.005595 -0.011190 -0.014750 ... 0.000000  0.005086 NaN\n2     -0.017293 -0.020854 -0.021871 ... 0.009664 -0.004578 NaN\n3     -0.003560 -0.012716 -0.009155 ... 0.004578  0.007121 NaN\n4      0.001526 -0.005595 -0.005595 ... 0.007121  0.010173 NaN\n...         ...       ...       ... ...      ...       ...  ..\n62459  0.011698  0.015259  0.004069 ... 0.000000  0.031026 NaN\n62460  0.007629  0.011698  0.002543 ... 0.002035  0.026449 NaN\n62461  0.001526  0.009664  0.000000 ... 0.001526  0.025940 NaN\n62462  0.033061  0.037130  0.027974 ... 0.022380  0.049845 NaN\n62463  0.020854  0.028992  0.017802 ... 0.013733  0.037638 NaN\n
"},{"location":"API_info/","title":"info","text":""},{"location":"API_info/#description","title":"Description","text":"

This module contains all the information regarding:

  • Data
    • Structures of data
    • How to access data
  • Abbreviations
  • AboutUs
  • Contacts
  • Links
  • CiteUs

"},{"location":"API_info/#openhdemg.library.info.info.data","title":"data(emgfile)","text":"

Print a description of the emgfile data structure.

Print a detailed description of the emgfile data structure and of how to access the contained elements.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

Examples:

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"DEMUSE\")\n>>> emg.info().data(emgfile)\nemgfile type is:\n<class 'dict'>\nemgfile keys are:\ndict_keys(['SOURCE', 'FILENAME', 'RAW_SIGNAL', 'REF_SIGNAL', 'PNR', 'SIL', 'IPTS', 'MUPULSES', 'FSAMP', 'IED', 'EMG_LENGTH', 'NUMBER_OF_MUS', 'BINARY_MUS_FIRING'])\nAny key can be acced as emgfile[key].\nemgfile['SOURCE'] is a <class 'str'> of value:\nDEMUSE\n.\n.\n.\n
"},{"location":"API_info/#openhdemg.library.info.info.abbreviations","title":"abbreviations()","text":"

Print common abbreviations.

Examples:

>>> import openhdemg.library as emg\n>>> emg.info().abbreviations()\n\"COV\": \"Coefficient of variation\",\n\"DERT\": \"DERecruitment threshold\",\n\"DD\": \"Double differential\",\n\"DR\": \"Discharge rate\",\n\"FSAMP\": \"Sampling frequency\",\n\"IDR\": \"Instantaneous discharge rate\",\n\"IED\": \"Inter electrode distance\",\n\"IPTS\": \"Impulse train (decomposed source)\",\n\"MU\": \"Motor units\",\n\"MUAP\": \"MUs action potential\",\n\"PNR\": \"Pulse to noise ratio\",\n\"RT\": \"Recruitment threshold\",\n\"SD\": \"Single differential\",\n\"SIL\": \"Silhouette score\",\n\"STA\": \"Spike-triggered average\",\n\"XCC\": \"Cross-correlation coefficient\"\n
"},{"location":"API_info/#openhdemg.library.info.info.aboutus","title":"aboutus()","text":"

Print informations about the library and the authors.

Examples:

>>> import openhdemg.library as emg\n>>> emg.info().aboutus()\nThe openhdemg project was born in 2022 with the aim to provide a\nfree and open-source framework to analyse HIGH-DENSITY EMG\nrecordings...\n
"},{"location":"API_info/#openhdemg.library.info.info.contacts","title":"contacts()","text":"

Print the contacts.

Examples:

>>> import openhdemg.library as emg\n>>> emg.info().contacts()\n\"Name\": \"Giacomo Valli\",\n\"Email\": \"giacomo.valli@phd.unipd.it\",\n\"Twitter\": \"@giacomo_valli\"\n
"},{"location":"API_info/#openhdemg.library.info.info.links","title":"links()","text":"

Print a collection of useful links.

"},{"location":"API_info/#openhdemg.library.info.info.citeus","title":"citeus()","text":"

Print how to cite the project.

"},{"location":"API_mathtools/","title":"mathtools","text":""},{"location":"API_mathtools/#description","title":"Description","text":"

This module contains all the mathematical functions that are necessary for the library.

"},{"location":"API_mathtools/#openhdemg.library.mathtools.min_max_scaling","title":"min_max_scaling(series_or_df)","text":"

Min-max scaling of pd.series or pd.dataframes.

Min-max feature scaling is often simply referred to as normalization, which rescales the dataset feature to a range of 0 - 1. It's calculated by subtracting the feature's minimum value from the value and then dividing it by the difference between the maximum and minimum value.

The formula looks like this: xnorm = x - xmin / xmax - xmin.

PARAMETER DESCRIPTION series_or_df

The min-max scaling is performed for the entire series, or for single columns in a pd.DataFrame.

TYPE: pd.Series or pd.DataFrame

RETURNS DESCRIPTION object

The normalised pd.Series or pd.DataFrame (normalised by column).

TYPE: pd.Series or pd.DataFrame

"},{"location":"API_mathtools/#openhdemg.library.mathtools.norm_xcorr","title":"norm_xcorr(sig1, sig2, out='both')","text":"

Normalized cross-correlation of 2 signals.

PARAMETER DESCRIPTION sig1

The two signals to correlate. These signals must be 1-dimensional and of same length.

TYPE: pd.Series or np.ndarray

sig2

The two signals to correlate. These signals must be 1-dimensional and of same length.

TYPE: pd.Series or np.ndarray

out

A string indicating the output value:

both The output is the greatest positive or negative cross-correlation value. max The output is the maximum cross-correlation value.

TYPE: str {\"both\", \"max\"} DEFAULT: \"both\"

RETURNS DESCRIPTION xcc

The cross-correlation value depending on \"out\".

TYPE: float

"},{"location":"API_mathtools/#openhdemg.library.mathtools.norm_xcorr--see-also","title":"See also","text":"
  • norm_twod_xcorr : Normalised 2-dimensional cross-correlation of STAs of two MUS.
"},{"location":"API_mathtools/#openhdemg.library.mathtools.norm_twod_xcorr","title":"norm_twod_xcorr(df1, df2, mode='full')","text":"

Normalised 2-dimensional cross-correlation of STAs of two MUS.

Any pre-processing of the RAW_SIGNAL (i.e., normal, differential or double differential) can be passed as long as the two inputs have same shape.

PARAMETER DESCRIPTION df1

A pd.DataFrame containing the STA of the first MU without np.nan column.

TYPE: pd.DataFrame

df2

A pd.DataFrame containing the STA of the second MU without np.nan column.

TYPE: pd.DataFrame

mode

A string indicating the size of the output:

full The output is the full discrete linear cross-correlation of the inputs. (Default) valid The output consists only of those elements that do not rely on the zero-padding. In 'valid' mode, either sta_mu1 or sta_mu2 must be at least as large as the other in every dimension. same The output is the same size as in1, centered with respect to the 'full' output.

TYPE: str {\"full\", \"valid\", \"same\"} DEFAULT: \"full\"

RETURNS DESCRIPTION normxcorr_df

The results of the normalised 2d cross-correlation.

TYPE: pd.DataFrame

normxcorr_max

The maximum value of the 2d cross-correlation.

TYPE: float

"},{"location":"API_mathtools/#openhdemg.library.mathtools.norm_twod_xcorr--see-also","title":"See also","text":"
  • align_by_xcorr : to align the two STAs before calling norm_twod_xcorr.
  • unpack_sta : for unpacking the sta dict in a pd.DataFrame before passing it to norm_twod_xcorr.
  • pack_sta : for packing the sta pd.DataFrame in a dict where each matrix column corresponds to a dict key.

Examples:

Full steps to pass two dataframes to norm_twod_xcorr from the same EMG file.

  1. Load the EMG file and band-pass filter the raw EMG signal
  2. Sort the matrix channels and compute the spike-triggered average
  3. Extract the STA of the MUs of interest from all the STAs
  4. Unpack the STAs of single MUs and remove np.nan to pas them to norm_twod_xcorr
  5. Compute 2dxcorr to identify a common lag/delay
>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emgfile = emg.filter_rawemg(emgfile, order=2, lowcut=20, highcut=500)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     )\n>>> sta = emg.sta(emgfile, sorted_rawemg, firings=[0, 50], timewindow=100)\n>>> mu0 = 0\n>>> mu1 = 1\n>>> sta_mu1 = sta[mu0]\n>>> sta_mu2 = sta[mu1]\n>>> df1 = emg.unpack_sta(sta_mu1)\n>>> no_nan_sta1 = df1.dropna(axis=1)\n>>> df2 = emg.unpack_sta(sta_mu2)\n>>> no_nan_sta2 = df2.dropna(axis=1)\n>>> normxcorr_df, normxcorr_max = emg.norm_twod_xcorr(\n...     no_nan_sta1,\n...     no_nan_sta2,\n...     )\n>>> normxcorr_max\n0.7241553627564273\n>>> normxcorr_df\n            0             1             2               125       126\n0   -0.000002 -1.467778e-05 -3.013564e-05 ... -1.052780e-06  0.000001\n1   -0.000004 -2.818055e-05 -6.024427e-05 ... -4.452469e-06  0.000001\n2   -0.000007 -4.192479e-05 -9.223725e-05 ... -1.549197e-05 -0.000002\n3   -0.000009 -5.071660e-05 -1.174545e-04 ... -3.078518e-05 -0.000007\n4   -0.000007 -4.841255e-05 -1.239106e-04 ... -4.232094e-05 -0.000012\n..        ...           ...           ... ...           ...       ...\n402  0.000005  1.641773e-05  3.994943e-05 ...  8.170792e-07 -0.000006\n403 -0.000001  4.535878e-06  1.858700e-05 ...  2.087135e-06 -0.000003\n404 -0.000004 -1.241530e-06  5.704194e-06 ...  1.027966e-05  0.000002\n405 -0.000004 -1.693078e-06  1.054646e-06 ...  1.811828e-05  0.000007\n406 -0.000002 -2.473282e-07  6.006046e-07 ...  1.605406e-05  0.000007\n
"},{"location":"API_mathtools/#openhdemg.library.mathtools.compute_sil","title":"compute_sil(ipts, mupulses)","text":"

Calculate the Silhouette score for a single MU.

The SIL is defined as the difference between the within-cluster sums of point-to-centroid distances and the same measure calculated between clusters. The output measure is normalised in a range between 0 and 1.

PARAMETER DESCRIPTION ipts

The decomposed source (or pulse train, IPTS[mu]) of the MU of interest.

TYPE: pd.Series

mupulses

The time of firing (MUPULSES[mu]) of the MU of interest.

TYPE: ndarray

RETURNS DESCRIPTION sil

The SIL score.

TYPE: float

"},{"location":"API_mathtools/#openhdemg.library.mathtools.compute_sil--see-also","title":"See also","text":"
  • compute_pnr : to calculate the Pulse to Noise ratio of a single MU.
"},{"location":"API_mathtools/#openhdemg.library.mathtools.compute_pnr","title":"compute_pnr(ipts, mupulses, fsamp, separate_paired_firings=True)","text":"

Calculate the pulse to noise ratio for a single MU.

PARAMETER DESCRIPTION ipts

The decomposed source (or pulse train, IPTS[mu]) of the MU of interest.

TYPE: pd.Series

mupulses

The time of firing (MUPULSES[mu]) of the MU of interest.

TYPE: ndarray

separate_paired_firings

Whether to treat differently paired and non-paired firings during the estimation of the signal/noise threshold. According to Holobar 2012, this is common in pathological tremor. The user is encouraged to use the default value (True) to increase the robustness of the estimation.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION pnr

The PNR in decibels.

TYPE: float

"},{"location":"API_mathtools/#openhdemg.library.mathtools.compute_pnr--see-also","title":"See also","text":"
  • compute_sil : to calculate the Silhouette score for a single MU.
"},{"location":"API_muap/","title":"muap","text":""},{"location":"API_muap/#description","title":"Description","text":"

This module contains functions to produce and analyse MUs anction potentials (MUAPs).

"},{"location":"API_muap/#openhdemg.library.muap.diff","title":"diff(sorted_rawemg)","text":"

Calculate single differential (SD) of RAW_SIGNAL on matrix rows.

PARAMETER DESCRIPTION sorted_rawemg

A dict containing the sorted electrodes. Every key of the dictionary represents a different column of the matrix. Rows are stored in the dict as a pd.DataFrame. Electrodes can be sorted with the function emg.sort_rawemg.

TYPE: dict

RETURNS DESCRIPTION sd

A dict containing the double differential signal. Every key of the dictionary represents a different column of the matrix. Rows are stored in the dict as a pd.DataFrame.

TYPE: dict

"},{"location":"API_muap/#openhdemg.library.muap.diff--see-also","title":"See also","text":"
  • double_diff : calculate double differential of RAW_SIGNAL on matrix rows.
"},{"location":"API_muap/#openhdemg.library.muap.diff--notes","title":"Notes","text":"

The returned sd will contain one less matrix row.

Examples:

Calculate single differential of a DEMUSE file with the channels already sorted.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"DEMUSE\")\n>>> sorted_rawemg = emg.sort_rawemg(\n>>>     emgfile,\n...     code=\"None\",\n...     orientation=180,\n...     dividebycolumn=True,\n...     n_rows=13,\n...     n_cols=5,\n... )\n>>> sd = emg.diff(sorted_rawemg)\n>>> sd[\"col0\"]\n             1         2         3  ...        10        11  12\n0     -0.003052  0.005086 -0.009155 ...  0.001526  0.016785 NaN\n1     -0.008647  0.008138 -0.010173 ... -0.001017 -0.015259 NaN\n2     -0.005595  0.005595 -0.013733 ...  0.003560  0.007629 NaN\n3     -0.010681  0.007121 -0.009664 ... -0.001526 -0.015259 NaN\n4     -0.005595  0.005086 -0.011190 ...  0.001017  0.017293 NaN\n...         ...       ...       ... ...       ...       ...  ..\n63483 -0.000509  0.007121 -0.007629 ... -0.006612  0.022380 NaN\n63484 -0.005086  0.005595 -0.004578 ... -0.005595 -0.045776 NaN\n63485 -0.004069  0.001017 -0.003560 ... -0.005086 -0.005086 NaN\n63486 -0.002035  0.006104 -0.010681 ... -0.007121  0.020345 NaN\n63487 -0.008647  0.000000 -0.010681 ... -0.011190 -0.027466 NaN\n

Calculate single differential of an OTB file where the channels need to be sorted.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n... )\n>>> sd = emg.diff(sorted_rawemg)\n
"},{"location":"API_muap/#openhdemg.library.muap.double_diff","title":"double_diff(sorted_rawemg)","text":"

Calculate double differential (DD) of RAW_SIGNAL on matrix rows.

PARAMETER DESCRIPTION sorted_rawemg

A dict containing the sorted electrodes. Every key of the dictionary represents a different column of the matrix. Rows are stored in the dict as a pd.DataFrame. Electrodes can be sorted with the function emg.sort_rawemg.

TYPE: dict

RETURNS DESCRIPTION dd

A dict containing the double differential signal. Every key of the dictionary represents a different column of the matrix. Rows are stored in the dict as a pd.DataFrame.

TYPE: dict

"},{"location":"API_muap/#openhdemg.library.muap.double_diff--see-also","title":"See also","text":"
  • diff : Calculate single differential of RAW_SIGNAL on matrix rows.
"},{"location":"API_muap/#openhdemg.library.muap.double_diff--notes","title":"Notes","text":"

The returned dd will contain two less matrix rows.

Examples:

Calculate double differential of a DEMUSE file with the channels already sorted.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"DEMUSE\")\n>>> sorted_rawemg = emg.sort_rawemg(\n>>>     emgfile,\n...     code=\"None\",\n...     orientation=180,\n...     dividebycolumn=True,\n...     n_rows=13,\n...     n_cols=5,\n... )\n>>> dd = emg.double_diff(sorted_rawemg)\n>>> dd[\"col0\"]\n             2         3         4  ...            10        11  12\n0      0.008138 -0.014242  0.012716 ...  4.577637e-03  0.015259 NaN\n1      0.016785 -0.018311  0.022380 ...  8.138018e-03 -0.014242 NaN\n2      0.011190 -0.019328  0.021362 ...  1.780192e-02  0.004069 NaN\n3      0.017802 -0.016785  0.014750 ...  1.118978e-02 -0.013733 NaN\n4      0.010681 -0.016276  0.017802 ...  4.577637e-03  0.016276 NaN\n...         ...       ...       ... ...           ...       ...  ..\n63483  0.007629 -0.014750  0.011698 ... -4.656613e-10  0.028992 NaN\n63484  0.010681 -0.010173  0.011698 ... -2.543131e-03 -0.040181 NaN\n63485  0.005086 -0.004578  0.004069 ... -6.612142e-03  0.000000 NaN\n63486  0.008138 -0.016785  0.013733 ... -1.068115e-02  0.027466 NaN\n63487  0.008647 -0.010681  0.019836 ... -1.068115e-02 -0.016276 NaN\n

Calculate single differential of an OTB file where the channels need to be sorted.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True,\n... )\n>>> dd = emg.double_diff(sorted_rawemg)\n
"},{"location":"API_muap/#openhdemg.library.muap.sta","title":"sta(emgfile, sorted_rawemg, firings=[0, 50], timewindow=50)","text":"

Computes the spike-triggered average (STA) of every MUs.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

sorted_rawemg

A dict containing the sorted electrodes. Every key of the dictionary represents a different column of the matrix. Rows are stored in the dict as a pd.DataFrame.

TYPE: dict

firings

The range of firnings to be used for the STA. If a MU has less firings than the range, the upper limit is adjusted accordingly. all The STA is calculated over all the firings.

TYPE: list or str {\"all\"} DEFAULT: [0, 50]

timewindow

Timewindow to compute STA in milliseconds.

TYPE: int DEFAULT: 50

RETURNS DESCRIPTION sta_dict

dict containing a dict of STA (pd.DataFrame) for every MUs.

TYPE: dict

"},{"location":"API_muap/#openhdemg.library.muap.sta--see-also","title":"See also","text":"
  • unpack_sta : build a common pd.DataFrame from the sta dict containing all the channels.
  • pack_sta : pack the pd.DataFrame containing STA to a dict.
  • st_muap : generate spike triggered MUs action potentials over the entire spike train of every MUs.
"},{"location":"API_muap/#openhdemg.library.muap.sta--notes","title":"Notes","text":"

The returned file is called sta_dict for convention.

Examples:

Calculate STA of all the MUs in the emgfile on the first 25 firings and in a 50 ms time-window. Access the STA of the column 0 of the first MU (number 0).

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n... )\n>>> sta = emg.sta(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     firings=[0,25],\n...     timewindow=50,\n... )\n>>> sta[0][\"col0\"]\n     0          1          2  ...        10         11         12\n0   NaN  -7.527668  -7.141111 ... -1.464846 -21.606445 -14.180500\n1   NaN -16.662600 -14.038087 ...  2.868650 -19.246420 -15.218098\n2   NaN -21.443687 -15.116375 ...  5.615236 -16.052244 -13.854978\n3   NaN -17.822264  -9.989420 ...  6.876628 -12.451175 -12.268069\n4   NaN -14.567060  -8.748373 ... -1.403812 -14.241538 -16.703283\n..   ..        ...        ... ...       ...        ...        ...\n97  NaN  19.388836  25.166826 ... 39.591473  23.681641  19.653318\n98  NaN   8.870444  16.337074 ... 28.706865  20.548504   8.422853\n99  NaN  -1.037601   7.446290 ... 18.086752  16.276041   0.040688\n100 NaN  -2.766926   5.371094 ... 11.006674  14.261881  -0.712078\n101 NaN   3.214517   9.562176 ...  4.475910  10.742184  -0.284828\n

Calculate STA of the differential signal on all the firings.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n... )\n>>> sd = emg.diff(sorted_rawemg=sorted_rawemg)\n>>> sta = emg.sta(\n...     emgfile=emgfile,\n...     sorted_rawemg=sd,\n...     firings=\"all\",\n...     timewindow=50,\n... )\n>>> sta[0][\"col0\"]\n     1         2          3  ...         10         11         12\n0   NaN -0.769545  11.807394 ...   3.388641  14.423187   1.420190\n1   NaN -1.496154  11.146843 ...   4.637086  12.312718   3.408456\n2   NaN -3.263135   9.660598 ...   6.258748   9.478946   5.974706\n3   NaN -4.125159   9.257659 ...   6.532877   5.558562   7.708665\n4   NaN -4.234151   9.379863 ...   6.034157   1.506064   8.722610\n..   ..       ...        ... ...        ...        ...        ...\n97  NaN -6.126635   1.225329 ... -10.050324   1.522576  -9.568117\n98  NaN -6.565903   0.571378 ...  -8.669765   4.643692 -10.714180\n99  NaN -6.153056  -0.105689 ...  -6.836730   7.272696 -12.623180\n100 NaN -5.452869  -0.587892 ...  -7.411412   8.504627 -14.727043\n101 NaN -4.587545  -0.855417 ... -10.549041   9.802613 -15.820260\n
"},{"location":"API_muap/#openhdemg.library.muap.st_muap","title":"st_muap(emgfile, sorted_rawemg, timewindow=50)","text":"

Generate spike triggered MUAPs of every MUs.

Generate single spike triggered (ST) MUs action potentials (MUAPs) over the entire spike train of every MUs.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

sorted_rawemg

A dict containing the sorted electrodes. Every key of the dictionary represents a different column of the matrix. Rows are stored in the dict as a pd.DataFrame.

TYPE: dict

timewindow

Timewindow to compute ST MUAPs in milliseconds.

TYPE: int DEFAULT: 50

RETURNS DESCRIPTION stmuap

dict containing a dict of ST MUAPs (pd.DataFrame) for every MUs. pd.DataFrames containing the ST MUAPs are organised based on matrix rows (dict) and matrix channel. For example, the ST MUAPs of the first MU (0), in the second electrode of the matrix can be accessed as stmuap0[1].

TYPE: dict

"},{"location":"API_muap/#openhdemg.library.muap.st_muap--see-also","title":"See also","text":"
  • sta : computes the STA of every MUs.
"},{"location":"API_muap/#openhdemg.library.muap.st_muap--notes","title":"Notes","text":"

The returned file is called stmuap for convention.

Examples:

Calculate the MUAPs of the differential signal. Access the MUAPs of the first MU (number 0), channel 15 that is contained in the second matrix column (\"col1\").

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n... )\n>>> sd = emg.diff(sorted_rawemg=sorted_rawemg)\n>>> stmuap = emg.st_muap(emgfile=emgfile, sorted_rawemg=sd, timewindow=50)\n>>> stmuap[0][\"col1\"][15]\n           0          1          2   ...        151         152         153\n0   -14.750162 -26.957193   6.103516 ...  23.905434    4.069008  150.553375\n1    -9.155273 -22.379557  12.715660 ...   8.138023    0.000000  133.260086\n2    -4.069010 -12.207031  17.293289 ...  -6.612144    6.612141   74.768066\n3     1.525879  -6.612143  22.379562 ... -25.939949   21.362305  -14.750168\n4     3.051758  -4.577637  24.414062 ... -35.603844   34.586590  -83.923347\n..         ...        ...        ... ...        ...         ...         ...\n97    9.155273 -24.922688  43.233238 ... -92.569984 -107.320145  -40.181477\n98   -2.543133 -14.241535  28.483074 ...-102.233887  -68.155922  -19.836430\n99  -23.905437 -13.732906  15.767414 ... -89.518234  -42.215984  -10.681152\n100 -52.388512 -20.853680  14.241537 ... -71.716309  -26.448566    0.000000\n101 -61.543785 -16.784668  21.362305 ... -52.388504   -3.560385    6.103516\n
"},{"location":"API_muap/#openhdemg.library.muap.unpack_sta","title":"unpack_sta(sta_mu)","text":"

Build a common pd.DataFrame from the sta_dict containing all the channels.

PARAMETER DESCRIPTION sta_mu

A dict containing the STA of a single MU.

TYPE: dict

RETURNS DESCRIPTION df1

A pd.DataFrame containing the STA of the MU (including the empty channel).

TYPE: pd.DataFrame

keys

The matrix columns (dict keys) of the unpacked sta.

TYPE: list

"},{"location":"API_muap/#openhdemg.library.muap.unpack_sta--see-also","title":"See also","text":"
  • sta : computes the STA of every MUs.
  • pack_sta : pack the pd.DataFrame containing STA to a dict.
"},{"location":"API_muap/#openhdemg.library.muap.pack_sta","title":"pack_sta(df_sta, keys)","text":"

Pack the pd.DataFrame containing STA to a dict.

PARAMETER DESCRIPTION df_sta

(including the empty channel).

TYPE: A pd.DataFrame containing the STA of a single MU

keys

The matrix columns (dict keys) by which to pack the sta.

TYPE: list

RETURNS DESCRIPTION packed_sta

dict containing STA of the input pd.DataFrame divided by matrix column. Dict columns are \"col0\", col1\", \"col2\", \"col3\", \"col4\".

TYPE: dict

"},{"location":"API_muap/#openhdemg.library.muap.pack_sta--see-also","title":"See also","text":"
  • sta : computes the STA of every MUs.
  • unpack_sta : build a common pd.DataFrame from the sta dict containing all the channels.
"},{"location":"API_muap/#openhdemg.library.muap.align_by_xcorr","title":"align_by_xcorr(sta_mu1, sta_mu2, finalduration=0.5)","text":"

Align the STA of 2 MUs by cross-correlation.

Any pre-processing of the RAW_SIGNAL (i.e., normal, differential or double differential) can be passed as long as the two inputs have same shape. Since the returned STA is cut based on finalduration, the input STA should account for this.

PARAMETER DESCRIPTION sta_mu1

A dictionary containing the STA of the first MU.

TYPE: dict

sta_mu2

A dictionary containing the STA of the second MU.

TYPE: dict

finalduration

Duration of the aligned STA compared to the original in percent. (e.g., 0.5 corresponds to 50%).

TYPE: float DEFAULT: 0.5

RETURNS DESCRIPTION aligned_sta1

A dictionary containing the aligned and STA of the first MU with the final expected timewindow (duration of sta_mu1 * finalduration).

TYPE: dict

aligned_sta2

A dictionary containing the aligned and STA of the second MU with the final expected timewindow (duration of sta_mu1 * finalduration).

TYPE: dict

"},{"location":"API_muap/#openhdemg.library.muap.align_by_xcorr--see-also","title":"See also","text":"
  • sta : computes the STA of every MUs.
  • norm_twod_xcorr : normalised 2-dimensional cross-correlation of STAs of two MUS.
"},{"location":"API_muap/#openhdemg.library.muap.align_by_xcorr--notes","title":"Notes","text":"

STAs are aligned by a common lag/delay for the entire matrix and not channel by channel because this might lead to misleading results.

Examples:

Align two MUs with a final duration of 50% the original one.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n... )\n>>> sta = emg.sta(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     timewindow=100,\n... )\n>>> aligned_sta1, aligned_sta2 = emg.align_by_xcorr(\n...     sta_mu1=sta[0], sta_mu2=sta[1], finalduration=0.5,\n... )\n>>> aligned_sta1[\"col0\"]\n     0          1          2  ...        10         11         12\n0   NaN -10.711670  -7.008868 ... 21.809900 -33.447262 -21.545408\n1   NaN  -5.584714  -2.380372 ... 22.664387 -33.081059 -18.931072\n2   NaN  -4.262290  -1.139323 ... 23.244226 -33.020020 -17.456057\n3   NaN  -4.638671  -1.078290 ... 23.111980 -34.118645 -18.147787\n4   NaN  -7.405599  -4.018145 ... 22.888189 -35.797115 -22.247314\n..   ..        ...        ... ...       ...        ...        ...\n97  NaN   6.764731  13.081865 ... 30.954998  39.672852  42.429604\n98  NaN   4.455567  10.467529 ... 31.311037  41.280106  44.403072\n99  NaN   0.356039   6.856283 ... 30.436195  43.701172  46.142574\n100 NaN  -2.960206   4.872639 ... 30.008953  44.342041  46.366371\n101 NaN  -7.008870   1.708984 ... 25.634764  40.100101  43.009445\n
"},{"location":"API_muap/#openhdemg.library.muap.tracking","title":"tracking(emgfile1, emgfile2, firings='all', derivation='sd', timewindow=50, threshold=0.8, matrixcode='GR08MM1305', orientation=180, n_rows=None, n_cols=None, exclude_belowthreshold=True, filter=True, show=False)","text":"

Track MUs across two different files.

PARAMETER DESCRIPTION emgfile1

The dictionary containing the first emgfile.

TYPE: dict

emgfile2

The dictionary containing the second emgfile.

TYPE: dict

firings

The range of firnings to be used for the STA. If a MU has less firings than the range, the upper limit is adjusted accordingly. all The STA is calculated over all the firings. A list can be passed as [start, stop] e.g., [0, 25] to compute the STA on the first 25 firings.

TYPE: list or str {\"all\"} DEFAULT: \"all\"

derivation

Whether to compute the sta on the monopolar signal, or on the single or double differential derivation.

TYPE: str {mono, sd, dd} DEFAULT: sd

timewindow

Timewindow to compute STA in milliseconds.

TYPE: int DEFAULT: 50

threshold

The 2-dimensional cross-correlation minimum value to consider two MUs to be the same. Ranges 0-1.

TYPE: float DEFAULT: 0.8

matrixcode

The code of the matrix used. This is necessary to sort the channels in the correct order. If matrixcode=\"None\", the electrodes are not sorted. In this case, n_rows and n_cols must be specified.

TYPE: str {\"GR08MM1305\", \"GR04MM1305\", \"GR10MM0808\", \"None\"} DEFAULT: \"GR08MM1305\"

orientation

Orientation in degree of the matrix (same as in OTBiolab). E.g. 180 corresponds to the matrix connection toward the user.

TYPE: int {0, 180} DEFAULT: 180

n_rows

The number of rows and columns of the matrix. This parameter is used to divide the channels based on the matrix shape. These are normally inferred by the matrix code and must be specified only if code == None.

TYPE: None or int DEFAULT: None

n_cols

The number of rows and columns of the matrix. This parameter is used to divide the channels based on the matrix shape. These are normally inferred by the matrix code and must be specified only if code == None.

TYPE: None or int DEFAULT: None

exclude_belowthreshold

Whether to exclude results with XCC below threshold.

TYPE: bool DEFAULT: True

filter

If true, when the same MU has a match of XCC > threshold with multiple MUs, only the match with the highest XCC is returned.

TYPE: bool DEFAULT: True

show

Whether to plot the STA of pairs of MUs with XCC above threshold.

TYPE: bool DEFAULT: False

RETURNS DESCRIPTION tracking_res

The results of the tracking including the MU from file 1, MU from file 2 and the normalised cross-correlation value (XCC).

TYPE: pd.DataFrame

WARNS DESCRIPTION UserWarning

If the number of plots to show exceeds that of available cores.

"},{"location":"API_muap/#openhdemg.library.muap.tracking--see-also","title":"See also","text":"
  • sta : computes the STA of every MUs.
  • norm_twod_xcorr : normalised 2-dimensional cross-correlation of STAs of two MUS.
  • remove_duplicates_between : remove duplicated MUs across two different files based on STA.
"},{"location":"API_muap/#openhdemg.library.muap.tracking--notes","title":"Notes","text":"

Parallel processing can improve performances by 5-10 times compared to serial processing. In this function, parallel processing has been implemented for the tasks involving 2-dimensional cross-correlation, sta and plotting.

Examples:

Track MUs between two OTB files and show the filtered results.

>>> import openhdemg.library as emg\n>>> emgfile1 = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emgfile2 = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> tracking_res = emg.tracking(\n...     emgfile1=emgfile1,\n...     emgfile2=emgfile2,\n...     firings=\"all\",\n...     derivation=\"mono\",\n...     timewindow=50,\n...     threshold=0.8,\n...     matrixcode=\"GR08MM1305\",\n...     orientation=180,\n...     n_rows=None,\n...     n_cols=None,\n...     exclude_belowthreshold=True,\n...     filter=True,\n...     show=False,\n... )\n    MU_file1  MU_file2       XCC\n0          0         3  0.820068\n1          2         4  0.860272\n2          4         8  0.857346\n3          5         0  0.878373\n4          6         9  0.877321\n5          7         1  0.823371\n6          9        13  0.873388\n7         11         5  0.862537\n8         19        10  0.802635\n9         21        14  0.896419\n10        22        16  0.836356\n
"},{"location":"API_muap/#openhdemg.library.muap.remove_duplicates_between","title":"remove_duplicates_between(emgfile1, emgfile2, firings='all', derivation='sd', timewindow=50, threshold=0.9, matrixcode='GR08MM1305', orientation=180, n_rows=None, n_cols=None, filter=True, show=False, which='munumber')","text":"

Remove duplicated MUs across two different files based on STA.

PARAMETER DESCRIPTION emgfile1

The dictionary containing the first emgfile.

TYPE: dict

emgfile2

The dictionary containing the second emgfile.

TYPE: dict

firings

The range of firnings to be used for the STA. If a MU has less firings than the range, the upper limit is adjusted accordingly. all The STA is calculated over all the firings. A list can be passed as [start, stop] e.g., [0, 25] to compute the STA on the first 25 firings.

TYPE: list or str {\"all\"} DEFAULT: \"all\"

derivation

Whether to compute the sta on the monopolar signal, or on the single or double differential derivation.

TYPE: str {mono, sd, dd} DEFAULT: sd

timewindow

Timewindow to compute STA in milliseconds.

TYPE: int DEFAULT: 50

threshold

The 2-dimensional cross-correlation minimum value to consider two MUs to be the same. Ranges 0-1.

TYPE: float DEFAULT: 0.9

matrixcode

The code of the matrix used. This is necessary to sort the channels in the correct order. If matrixcode=\"None\", the electrodes are not sorted. In this case, n_rows and n_cols must be specified.

TYPE: str {\"GR08MM1305\", \"GR04MM1305\", \"GR10MM0808\", \"None\"} DEFAULT: \"GR08MM1305\"

orientation

Orientation in degree of the matrix (same as in OTBiolab). E.g. 180 corresponds to the matrix connection toward the user.

TYPE: int {0, 180} DEFAULT: 180

n_rows

The number of rows and columns of the matrix. This parameter is used to divide the channels based on the matrix shape. These are normally inferred by the matrix code and must be specified only if code == None.

TYPE: None or int DEFAULT: None

n_cols

The number of rows and columns of the matrix. This parameter is used to divide the channels based on the matrix shape. These are normally inferred by the matrix code and must be specified only if code == None.

TYPE: None or int DEFAULT: None

filter

If true, when the same MU has a match of XCC > threshold with multiple MUs, only the match with the highest XCC is returned.

TYPE: bool DEFAULT: True

show

Whether to plot the STA of pairs of MUs with XCC above threshold.

TYPE: bool DEFAULT: False

which

How to remove the duplicated MUs.

munumber Duplicated MUs are removed from the file with more MUs. SIL The MU with the lowest SIL is removed. PNR The MU with the lowest PNR is removed.

TYPE: str {\"munumber\", \"PNR\", \"SIL\"} DEFAULT: 'munumber'

RETURNS DESCRIPTION emgfile1, emgfile2 : dict

The original emgfiles without the duplicated MUs.

tracking_res

The results of the tracking including the MU from file 1, MU from file 2 and the normalised cross-correlation value (XCC).

TYPE: pd.DataFrame

"},{"location":"API_muap/#openhdemg.library.muap.remove_duplicates_between--see-also","title":"See also","text":"
  • sta : computes the STA of every MUs.
  • norm_twod_xcorr : normalised 2-dimensional cross-correlation of STAs of two MUS.
  • tracking : track MUs across two different files.

Examples:

Remove duplicated MUs between two OTB files and save the emgfiles without duplicates. The duplicates are removed from the file with more MUs.

>>> emgfile1 = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emgfile2 = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emgfile1, emgfile2, tracking_res = emg.remove_duplicates_between(\n...     emgfile1,\n...     emgfile2,\n...     firings=\"all\",\n...     derivation=\"mono\",\n...     timewindow=50,\n...     threshold=0.9,\n...     matrixcode=\"GR08MM1305\",\n...     orientation=180,\n...     n_rows=None,\n...     n_cols=None,\n...     filter=True,\n...     show=False,\n...     which=\"munumber\",\n... )\n>>> emg.asksavefile(emgfile1)\n>>> emg.asksavefile(emgfile2)\n
"},{"location":"API_muap/#openhdemg.library.muap.xcc_sta","title":"xcc_sta(sta)","text":"

Cross-correlation between the STA of adjacent channels.

Calculate the normalised cross-correlation coefficient (XCC) between the MUs action potential shapes on adjacent channels. The XCC will be calculated for all the MUs and all the pairs of electrodes.

PARAMETER DESCRIPTION sta

The dict containing the spike-triggered average (STA) of all the MUs computed with the function sta().

TYPE: dict

RETURNS DESCRIPTION xcc_sta

A dict containing the XCC for all the pairs of channels and all the MUs. This dict is organised as the sta dict.

TYPE: dict

Examples:

Calculate the XCC of adjacent channels of the double differential derivation as done to calculate MUs conduction velocity.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True\n... )\n>>> dd = emg.double_diff(sorted_rawemg)\n>>> sta = emg.sta(\n...     emgfile=emgfile,\n...     sorted_rawemg=dd,\n...     firings=[0, 50],\n...     timewindow=50,\n... )\n>>> xcc_sta = emg.xcc_sta(sta)\n
"},{"location":"API_muap/#openhdemg.library.muap.MUcv_gui","title":"MUcv_gui(emgfile, sorted_rawemg, n_firings=[0, 50], muaps_timewindow=50)","text":"

Graphical user interface for the estimation of MUs conduction velocity.

GUI for the estimation of MUs conduction velocity (CV) and amplitude of the action potentials (root mean square - RMS).

PARAMETER DESCRIPTION emgfile

The dictionary containing the first emgfile.

TYPE: dict

sorted_rawemg

A dict containing the sorted electrodes. Every key of the dictionary represents a different column of the matrix. Rows are stored in the dict as a pd.DataFrame.

TYPE: dict

n_firings

The range of firnings to be used for the STA. If a MU has less firings than the range, the upper limit is adjusted accordingly. all The STA is calculated over all the firings.

TYPE: list or str {\"all\"} DEFAULT: [0, 50]

muaps_timewindow

Timewindow to compute ST MUAPs in milliseconds.

TYPE: int DEFAULT: 50

Examples:

Call the GUI.

>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True\n... )\n>>> gui = emg.MUcv_gui(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     n_firings=[0,50],\n...     muaps_timewindow=50\n... )\n
"},{"location":"API_openfiles/","title":"openfiles","text":""},{"location":"API_openfiles/#description","title":"Description","text":"

This module contains all the functions that are necessary to open or save MATLAB (.mat), JSON (.json) or custom (.csv) files. MATLAB files are used to store data from the DEMUSE and the OTBiolab+ software while JSON files are used to save and load files from this library. The choice of saving files in the open standard JSON file format was preferred over the MATLAB file format since it has a better integration with Python and has a very high cross-platform compatibility.

"},{"location":"API_openfiles/#functions-scope","title":"Function's scope","text":"
  • emg_from_samplefile: Used to load the sample file provided with the library.
  • emg_from_otb and emg_from_demuse: Used to load .mat files coming from the DEMUSE or the OTBiolab+ software. Demuse has a fixed file structure while the OTB file, in order to be compatible with this library should be exported with a strict structure as described in the function emg_from_otb. In both cases, the input file is a .mat file.
  • refsig_from_otb: Used to load files from the OTBiolab+ software that contain only the REF_SIGNAL.
  • emg_from_customcsv: Used to load custom file formats contained in .csv files.
  • save_json_emgfile, emg_from_json: Used to save the working file to a .json file or to load the .json file.
  • askopenfile, asksavefile: A quick GUI implementation that allows users to select the file to open or save.
"},{"location":"API_openfiles/#notes","title":"Notes","text":"

Once opened, the file is returned as a dictionary with keys:

\"SOURCE\" : source of the file (e.g., \"DEMUSE\", \"OTB\", \"custom\") \"RAW_SIGNAL\" : the raw EMG signal \"REF_SIGNAL\" : the reference signal \"PNR\" : pulse to noise ratio \"SIL\" : silouette score \"IPTS\" : pulse train (decomposed source) \"MUPULSES\" : instants of firing \"FSAMP\" : sampling frequency \"IED\" : interelectrode distance \"EMG_LENGTH\" : length of the emg file (in samples) \"NUMBER_OF_MUS\" : total number of MUs \"BINARY_MUS_FIRING\" : binary representation of MUs firings

The only exception is when OTB files are loaded with just the reference signal:

\"SOURCE\": source of the file (i.e., \"OTB_refsig\") \"FSAMP\": sampling frequency \"REF_SIGNAL\": the reference signal

Additional informations can be found in the info module and in the function's description.

"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_samplefile","title":"emg_from_samplefile()","text":"

Load the sample file. This file has been decomposed with the OTBiolab+ software and contains some reference MUs together with the force/reference signal.

This file contains only few MUs for storage reasons.

RETURNS DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_otb","title":"emg_from_otb(filepath, ext_factor=8, refsig=[True, 'fullsampled'], version='1.5.8.0')","text":"

Import the .mat file exportable by OTBiolab+.

This function is used to import the .mat file exportable by the OTBiolab+ software as a dictionary of Python objects (mainly pandas dataframes).

PARAMETER DESCRIPTION filepath

The directory and the name of the file to load (including file extension .mat). This can be a simple string, the use of Path is not necessary.

TYPE: str or Path

ext_factor

The extension factor used for the decomposition in OTbiolab+.

TYPE: int DEFAULT: 8

refsig

Whether to seacrh also for the REF_SIGNAL and whether to load the full or sub-sampled one. The list is composed as [bool, str]. str can be \"fullsampled\" or \"subsampled\". Please read notes section.

TYPE: list DEFAULT: [True, \"fullsampled\"]

version

Version of the OTBiolab+ software used (4 points). Tested versions are: \"1.5.3.0\", \"1.5.4.0\", \"1.5.5.0\", \"1.5.6.0\", \"1.5.7.2\", \"1.5.7.3\", \"1.5.8.0\", If your specific version is not available in the tested versions, trying with the closer one usually works, but please double check the results.

TYPE: str DEFAULT: \"1.5.8.0\"

RETURNS DESCRIPTION emgfile

A dictionary containing all the useful variables.

TYPE: dict

"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_otb--see-also","title":"See also","text":"
  • refsig_from_otb : import REF_SIGNAL in the .mat file exportable from OTBiolab+.
  • emg_from_demuse : import the .mat file used in DEMUSE.
  • emg_from_customcsv : Import custom data from a .csv file.
RAISES DESCRIPTION ValueError

When a wrong value is passed to version=.

"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_otb--notes","title":"Notes","text":"

The returned file is called emgfile for convention.

The input .mat file exported from the OTBiolab+ software should have a specific content: - refsig signal is optional but, if present, there should be the fullsampled or the subsampled version (in OTBioLab+ the \"performed path\" refers to the subsampled signal, the \"acquired data\" to the fullsampled signal), REF_SIGNAL is expected to be expressed as % of the MVC (but not compulsory). - Both the IPTS ('Source for decomposition...' in OTBioLab+) and the BINARY_MUS_FIRING ('Decomposition of...' in OTBioLab+) should be present. - The raw EMG signal should be present (it has no specific name in OTBioLab+) with all the channels. Don't exclude unwanted channels before exporting the .mat file. - NO OTHER ELEMENTS SHOULD BE PRESENT!

Structure of the returned emgfile: emgfile = { \"SOURCE\": SOURCE, \"FILENAME\": FILENAME, \"RAW_SIGNAL\": RAW_SIGNAL, \"REF_SIGNAL\": REF_SIGNAL, \"PNR\": PNR, \"SIL\": SIL, \"IPTS\": IPTS, \"MUPULSES\": MUPULSES, \"FSAMP\": FSAMP, \"IED\": IED, \"EMG_LENGTH\": EMG_LENGTH, \"NUMBER_OF_MUS\": NUMBER_OF_MUS, \"BINARY_MUS_FIRING\": BINARY_MUS_FIRING, }

Examples:

For an extended explanation of the imported emgfile use:

>>> import openhdemg.library as emg\n>>> emgfile = emg.emg_from_otb(filepath=\"path/filename.mat\")\n>>> info = emg.info()\n>>> info.data(emgfile)\n
"},{"location":"API_openfiles/#openhdemg.library.openfiles.refsig_from_otb","title":"refsig_from_otb(filepath, refsig='fullsampled', version='1.5.8.0')","text":"

Import REF_SIGNAL in the .mat file exportable by OTBiolab+.

This function is used to import the .mat file exportable by the OTBiolab+ software as a dictionary of Python objects (mainly pandas dataframes). Compared to the function emg_from_otb, this function only imports the REF_SIGNAL and, therefore, it can be used for special cases where only the REF_SIGNAL is necessary. This will allow a faster execution of the script and to avoid exceptions for missing data.

PARAMETER DESCRIPTION filepath

The directory and the name of the file to load (including file extension .mat). This can be a simple string, the use of Path is not necessary.

TYPE: str or Path

refsig

Whether to load the full or sub-sampled one. Please read notes section.

TYPE: str {\"fullsampled\", \"subsampled\"} DEFAULT: \"fullsampled\"

version

Version of the OTBiolab+ software used (4 points). Tested versions are: \"1.5.3.0\", \"1.5.4.0\", \"1.5.5.0\", \"1.5.6.0\", \"1.5.7.2\", \"1.5.7.3\", \"1.5.8.0\", If your specific version is not available in the tested versions, trying with the closer one usually works, but please double check the results.

TYPE: str DEFAULT: \"1.5.8.0\"

RETURNS DESCRIPTION emg_refsig

A dictionary containing all the useful variables.

TYPE: dict

"},{"location":"API_openfiles/#openhdemg.library.openfiles.refsig_from_otb--see-also","title":"See also","text":"
  • emg_from_otb : import the .mat file exportable by OTBiolab+.
  • emg_from_demuse : import the .mat file used in DEMUSE.
  • emg_from_customcsv : Import custom data from a .csv file.
"},{"location":"API_openfiles/#openhdemg.library.openfiles.refsig_from_otb--notes","title":"Notes","text":"

The returned file is called emg_refsig for convention.

The input .mat file exported from the OTBiolab+ software should contain: - refsig signal: there should be the fullsampled or the subsampled version (in OTBioLab+ the \"performed path\" refers to the subsampled signal, the \"acquired data\" to the fullsampled signal), REF_SIGNAL is expected to be expressed as % of the MVC (but not compulsory).

Structure of the returned emg_refsig: emg_refsig = { \"SOURCE\": SOURCE, \"FILENAME\": FILENAME, \"FSAMP\": FSAMP, \"REF_SIGNAL\": REF_SIGNAL, }

Examples:

For an extended explanation of the imported emgfile use:

>>> import openhdemg.library as emg\n>>> emgfile = emg.refsig_from_otb(filepath=\"path/filename.mat\")\n>>> info = emg.info()\n>>> info.data(emgfile)\n
"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_demuse","title":"emg_from_demuse(filepath)","text":"

Import the .mat file used in DEMUSE.

PARAMETER DESCRIPTION filepath

The directory and the name of the file to load (including file extension .mat). This can be a simple string, the use of Path is not necessary.

TYPE: str or Path

RETURNS DESCRIPTION emgfile

A dictionary containing all the useful variables.

TYPE: dict

"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_demuse--see-also","title":"See also","text":"
  • emg_from_otb : import the .mat file exportable by OTBiolab+.
  • refsig_from_otb : import REF_SIGNAL in the .mat file exportable by OTBiolab+.
  • emg_from_customcsv : Import custom data from a .csv file.
"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_demuse--notes","title":"Notes","text":"

The returned file is called emgfile for convention.

The demuse file contains 65 raw EMG channels (1 empty) instead of 64 (as for OTB matrix standards) in the case of a 64 electrodes matrix.

Structure of the emgfile: emgfile = { \"SOURCE\": SOURCE, \"FILENAME\": FILENAME, \"RAW_SIGNAL\": RAW_SIGNAL, \"REF_SIGNAL\": REF_SIGNAL, \"PNR\": PNR, \"SIL\": SIL \"IPTS\": IPTS, \"MUPULSES\": MUPULSES, \"FSAMP\": FSAMP, \"IED\": IED, \"EMG_LENGTH\": EMG_LENGTH, \"NUMBER_OF_MUS\": NUMBER_OF_MUS, \"BINARY_MUS_FIRING\": BINARY_MUS_FIRING, }

Examples:

For an extended explanation of the imported emgfile:

>>> import openhdemg.library as emg\n>>> emgfile = emg.emg_from_demuse(filepath=\"path/filename.mat\")\n>>> info = emg.info()\n>>> info.data(emgfile)\n
"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_customcsv","title":"emg_from_customcsv(filepath, ref_signal='REF_SIGNAL', raw_signal='RAW_SIGNAL', ipts='IPTS', mupulses='MUPULSES', binary_mus_firing='BINARY_MUS_FIRING', fsamp=2048, ied=8)","text":"

Import custom data from a .csv file.

The variables of interest should be contained in columns. The name of the columns containing each variable can be specified by the user if different from the default values.

This function detects the content of the .csv by parsing the .csv columns. For parsing, column labels should be provided. A label is a term common to all the columns containing the same information. For example, if the raw signal is contained in the columns 'RAW_SIGNAL_1', 'RAW_SIGNAL_2', ... , 'RAW_SIGNAL_n', the label of the columns should be 'RAW_SIGNAL'. If the parameters in input are not present in the .csv file, the user can simply leave the original inputs.

PARAMETER DESCRIPTION filepath

The directory and the name of the file to load (including file extension .mat). This can be a simple string, the use of Path is not necessary.

TYPE: str or Path

ref_signal

Label of the column(s) containing the reference signal.

TYPE: str DEFAULT: 'REF_SIGNAL'

raw_signal

Label of the column(s) containing the raw emg signal.

TYPE: str DEFAULT: 'RAW_SIGNAL'

ipts

Label of the column(s) containing the pulse train.

TYPE: str DEFAULT: 'IPTS'

mupulses

Label of the column(s) containing the times of firing.

TYPE: str DEFAULT: 'MUPULSES'

binary_mus_firing

Label of the column(s) containing the binary representation of the MUs firings.

TYPE: str DEFAULT: 'BINARY_MUS_FIRING'

fsamp

Tha sampling frequency.

TYPE: int DEFAULT: 2048

ied

The inter-electrode distance in mm.

TYPE: int DEFAULT: 8

RETURNS DESCRIPTION emgfile

A dictionary containing all the useful variables.

TYPE: dict

"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_customcsv--see-also","title":"See also","text":"
  • emg_from_demuse : import the .mat file used in DEMUSE.
  • emg_from_otb : import the .mat file exportable by OTBiolab+.
  • refsig_from_otb : import REF_SIGNAL in the .mat file exportable by OTBiolab+.
"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_customcsv--notes","title":"Notes","text":"

The returned file is called emgfile for convention.

Structure of the emgfile: emgfile = { \"SOURCE\": SOURCE, \"FILENAME\": FILENAME, \"RAW_SIGNAL\": RAW_SIGNAL, \"REF_SIGNAL\": REF_SIGNAL, \"PNR\": PNR, \"SIL\": SIL \"IPTS\": IPTS, \"MUPULSES\": MUPULSES, \"FSAMP\": FSAMP, \"IED\": IED, \"EMG_LENGTH\": EMG_LENGTH, \"NUMBER_OF_MUS\": NUMBER_OF_MUS, \"BINARY_MUS_FIRING\": BINARY_MUS_FIRING, }

Examples:

An example of the .csv file to load:

>>>\n    REF_SIGNAL  RAW_SIGNAL (1)  RAW_SIGNAL (2)  RAW_SIGNAL (3) ...  IPTS (1)  IPTS (2)  MUPULSES (1)  MUPULSES (2)  BINARY_MUS_FIRING (1)  BINARY_MUS_FIRING (2)\n0            1        0.100000        0.100000        0.100000 ...  0.010000  0.010000           2.0           1.0                      0                      0\n1            2        2.000000        2.000000        2.000000 ...  0.001000  0.001000           5.0           2.0                      0                      0\n2            3        0.500000        0.500000        0.500000 ...  0.020000  0.020000           8.0           9.0                      0                      0\n3            4        0.150000        0.150000        0.150000 ...  0.002000  0.002000           9.0          15.0                      0                      1\n4            5        0.350000        0.350000        0.350000 ... -0.100000 -0.100000          15.0          18.0                      1                      1\n5            6        0.215000        0.215000        0.215000 ...  0.200000  0.200000          16.0           NaN                      1                      0\n

For an extended explanation of the imported emgfile use:

>>> import openhdemg.library as emg\n>>> emgfile = emg_from_customcsv(filepath = \"mypath/file.csv\")\n>>> info = emg.info()\n>>> info.data(emgfile)\n
"},{"location":"API_openfiles/#openhdemg.library.openfiles.save_json_emgfile","title":"save_json_emgfile(emgfile, filepath)","text":"

Save the emgfile or emg_refsig as a JSON file.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

filepath

The directory and the name of the file to save (including file extension .json). This can be a simple string; The use of Path is not necessary.

TYPE: str or Path

"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_json","title":"emg_from_json(filepath)","text":"

Load the emgfile or emg_refsig stored in json format.

PARAMETER DESCRIPTION filepath

The directory and the name of the file to load (including file extension .json). This can be a simple string, the use of Path is not necessary.

TYPE: str or Path

RETURNS DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_json--see-also","title":"See also","text":"
  • emg_from_demuse : import the .mat file used in DEMUSE.
  • emg_from_otb : import the .mat file exportable by OTBiolab+.
  • refsig_from_otb : import REF_SIGNAL in the .mat file exportable by OTBiolab+.
  • emg_from_customcsv : import custom data from a .csv file.
"},{"location":"API_openfiles/#openhdemg.library.openfiles.emg_from_json--notes","title":"Notes","text":"

The returned file is called emgfile for convention (or emg_refsig if SOURCE = \"OTB_REFSIG\").

Examples:

For an extended explanation of the imported emgfile use:

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile()\n>>> info = emg.info()\n>>> info.data(emgfile)\n
"},{"location":"API_openfiles/#openhdemg.library.openfiles.askopenfile","title":"askopenfile(initialdir='/', filesource='OPENHDEMG', **kwargs)","text":"

Select and open files with a GUI.

PARAMETER DESCRIPTION initialdir

The directory of the file to load (excluding file name). This can be a simple string, the use of Path is not necessary.

TYPE: str or Path DEFAULT: \"/\"

filesource

See notes for how files should be exported from OTB.

DEMUSE File saved from DEMUSE (.mat). OTB File exported from OTB with decomposition and reference signal (.mat). OTB_REFSIG File exported from OTB with only the reference signal (.mat). CUSTOM Custom file format (.csv). OPENHDEMG File saved from openhdemg (.json).

TYPE: str {\"OPENHDEMG\", \"DEMUSE\", \"OTB\", \"OTB_REFSIG\", \"CUSTOM\"} DEFAULT: \"OPENHDEMG\"

otb_ext_factor

The extension factor used for the decomposition in the OTbiolab+ software. Ignore if loading other files.

TYPE: int DEFAULT: 8

otb_refsig_type

Whether to seacrh also for the REF_SIGNAL and whether to load the full or sub-sampled one. The list is composed as [bool, str]. str can be \"fullsampled\" or \"subsampled\". Ignore if loading other files.

TYPE: list DEFAULT: [True, \"fullsampled\"]

otb_version

Version of the OTBiolab+ software used (4 points). Tested versions are: \"1.5.3.0\", \"1.5.4.0\", \"1.5.5.0\", \"1.5.6.0\", \"1.5.7.2\", \"1.5.7.3\", \"1.5.8.0\", If your specific version is not available in the tested versions, trying with the closer one usually works, but please double check the results. Ignore if loading other files.

TYPE: str DEFAULT: \"1.5.8.0\"

custom_ref_signal

Label of the column(s) containing the reference signal of the custom file. This and the following arguments are needed only for custom files. Ignore if loading other files.

TYPE: str DEFAULT: 'REF_SIGNAL'

custom_raw_signal

Label of the column(s) containing the raw emg signal of the custom file. Ignore if loading other files.

TYPE: str DEFAULT: 'RAW_SIGNAL'

custom_ipts

Label of the column(s) containing the pulse train of the custom file. Ignore if loading other files.

TYPE: str DEFAULT: 'IPTS'

custom_mupulses

Label of the column(s) containing the times of firing of the custom file. Ignore if loading other files.

TYPE: str DEFAULT: 'MUPULSES'

custom_binary_mus_firing

Label of the column(s) containing the binary representation of the MUs firings of the custom file. Ignore if loading other files.

TYPE: str DEFAULT: 'BINARY_MUS_FIRING'

custom_fsamp

Tha sampling frequency of the custom file. Ignore if loading other files.

TYPE: int DEFAULT: 2048

custom_ied

The inter-electrode distance in mm of the custom file. Ignore if loading other files.

TYPE: int DEFAULT: 8

RETURNS DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

"},{"location":"API_openfiles/#openhdemg.library.openfiles.askopenfile--see-also","title":"See also","text":"
  • asksavefile : select where to save files with a GUI.
"},{"location":"API_openfiles/#openhdemg.library.openfiles.askopenfile--notes","title":"Notes","text":"

The returned file is called emgfile for convention (or emg_refsig if SOURCE = \"OTB_REFSIG\").

The input .mat file exported from the OTBiolab+ software should have a specific content: - refsig signal is optional but, if present, there should be both the fullsampled and the subsampled version (in OTBioLab+ the \"performed path\" refers to the subsampled signal, the \"acquired data\" to the fullsampled signal), REF_SIGNAL is expected to be expressed as % of the MViF (but not compulsory). - Both the IPTS ('Source for decomposition...' in OTBioLab+) and the BINARY_MUS_FIRING ('Decomposition of...' in OTBioLab+) should be present. - The raw EMG signal should be present (it has no specific name in OTBioLab+) with all the channels. Don't exclude unwanted channels before exporting the .mat file. - NO OTHER ELEMENTS SHOULD BE PRESENT!

For custom .csv files: The variables of interest should be contained in columns. The name of the columns containing each variable can be specified by the user if different from the default values. This function detects the content of the .csv by parsing the .csv columns. For parsing, column labels should be provided. A label is a term common to all the columns containing the same information. For example, if the raw signal is contained in the columns 'RAW_SIGNAL_1', 'RAW_SIGNAL_2', ... , 'RAW_SIGNAL_n', the label of the columns should be 'RAW_SIGNAL'. If the parameters in input are not present in the .csv file, the user can simply leave the original inputs. Please see the documentation of the function emg_from_customcsv for additional informations.

Structure of the returned emgfile: emgfile = { \"SOURCE\": SOURCE, \"FILENAME\": FILENAME, \"RAW_SIGNAL\": RAW_SIGNAL, \"REF_SIGNAL\": REF_SIGNAL, \"PNR\": PNR, \"SIL\": SIL, \"IPTS\": IPTS, \"MUPULSES\": MUPULSES, \"FSAMP\": FSAMP, \"IED\": IED, \"EMG_LENGTH\": EMG_LENGTH, \"NUMBER_OF_MUS\": NUMBER_OF_MUS, \"BINARY_MUS_FIRING\": BINARY_MUS_FIRING, }

Structure of the returned emg_refsig: emg_refsig = { \"SOURCE\": SOURCE, \"FILENAME\": FILENAME, \"FSAMP\": FSAMP, \"REF_SIGNAL\": REF_SIGNAL, }

Examples:

For an extended explanation of the imported emgfile use:

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile()\n>>> info = emg.info()\n>>> info.data(emgfile)\n
"},{"location":"API_openfiles/#openhdemg.library.openfiles.asksavefile","title":"asksavefile(emgfile)","text":"

Select where to save files with a GUI.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile to save.

TYPE: dict

"},{"location":"API_openfiles/#openhdemg.library.openfiles.asksavefile--see-also","title":"See also","text":"
  • askopenfile : select and open files with a GUI.
"},{"location":"API_plotemg/","title":"plotemg","text":""},{"location":"API_plotemg/#description","title":"Description","text":"

This module contains all the functions used to visualise the emg file, the MUs properties or to save figures.

"},{"location":"API_plotemg/#openhdemg.library.plotemg.showgoodlayout","title":"showgoodlayout(tight_layout=True, despined=False)","text":"

Despine and show plots with a good layout.

This function is called by the various plot functions contained in the library but can also be used by the user to quickly adjust the layout of custom plots.

PARAMETER DESCRIPTION tight_layout

If true (default), plt.tight_layout() is applied to the figure.

TYPE: bool DEFAULT: True

despined

False: left and bottom is not despined (standard plotting). True: all the sides are despined. 2yaxes Only the top is despined. This is used to show y axes both on the right and left side at the same time.

TYPE: bool or str {\"2yaxes\"} DEFAULT: False

"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_emgsig","title":"plot_emgsig(emgfile, channels, addrefsig=False, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True)","text":"

Plot the RAW_SIGNAL. Single or multiple channels.

Up to 12 channels (a common matrix row) can be easily observed togheter but more can be plotted.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

channels

The channel (int) or channels (list of int) to plot. The list can be passed as a manually-written list or with: channels=[*range(0, 13)]. We need the \" * \" operator to unpack the results of range into a list. channels is expected to be with base 0 (i.e., the first channel in the file is the number 0).

TYPE: int or list

addrefsig

If True, the REF_SIGNAL is plotted in front of the signal with a separated y-axes.

TYPE: bool DEFAULT: True

timeinseconds

Whether to show the time on the x-axes in seconds (True) or in samples (False).

TYPE: bool DEFAULT: True

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

tight_layout

If True (default), the plt.tight_layout() is called and the figure's layout is improved. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_emgsig--see-also","title":"See also","text":"
  • plot_differentials : plot the differential derivation of the RAW_SIGNAL by matrix column.

Examples:

Plot channels 0 to 12 and overlay the reference signal.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emg.plot_emgsig(\n...     emgfile=emgfile,\n...     channels=[*range(0,13)],\n...     addrefsig=True,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n... )\n
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_differentials","title":"plot_differentials(emgfile, differential, column='col0', addrefsig=False, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True)","text":"

Plot the differential derivation of the RAW_SIGNAL by matrix column.

Both the single and the double differencials can be plotted. This function is used to plot also the sorted RAW_SIGNAL.

PARAMETER DESCRIPTION emgfile

The dictionary containing the original emgfile.

TYPE: dict

differential

The dictionary containing the differential derivation of the RAW_SIGNAL.

TYPE: dict

column

The matrix column to plot. Options are usyally \"col0\", \"col1\", \"col2\", \"col3\", \"col4\". but might change based on the size of the matrix used.

TYPE: str {\"col0\", \"col1\", \"col2\", \"col3\", \"col4\", ...} DEFAULT: \"col0\"

addrefsig

If True, the REF_SIGNAL is plotted in front of the signal with a separated y-axes.

TYPE: bool DEFAULT: True

timeinseconds

Whether to show the time on the x-axes in seconds (True) or in samples (False).

TYPE: bool DEFAULT: True

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

tight_layout

If True (default), the plt.tight_layout() is called and the figure's layout is improved. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_differentials--see-also","title":"See also","text":"
  • diff : calculate single differential of RAW_SIGNAL on matrix rows.
  • double_diff : calculate double differential of RAW_SIGNAL on matrix rows.
  • plot_emgsig : pot the RAW_SIGNAL. Single or multiple channels.

Examples:

Plot the differential derivation of the first matrix column (col0).

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n>>>     emgfile=emgfile,\n>>>     code=\"GR08MM1305\",\n>>>     orientation=180,\n>>> )\n>>> sd=emg.diff(sorted_rawemg=sorted_rawemg)\n>>> emg.plot_differentials(\n...     emgfile=emgfile,\n...     differential=sd,\n...     column=\"col0\",\n...     addrefsig=False,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_refsig","title":"plot_refsig(emgfile, ylabel='MVC', timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True)","text":"

Plot the REF_SIGNAL.

The REF_SIGNAL is usually expressed as % MVC for submaximal contractions or as Kilograms (Kg) or Newtons (N) for maximal contractions, but any value can be plotted.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

ylabel

The unit of measure to show on the Y axis.

TYPE: str DEFAULT: \"MVC\"

timeinseconds

Whether to show the time on the x-axes in seconds (True) or in samples (False).

TYPE: bool DEFAULT: True

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

tight_layout

If True (default), the plt.tight_layout() is called and the figure's layout is improved. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

Examples:

Plot the reference signal.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emg.plot_refsig(emgfile=emgfile)\n

Change Y axis label and show time in samples.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emg.plot_refsig(\n>>>     emgfile=emgfile,\n>>>     ylabel=\"Custom unit e.g., N or kg\",\n>>>     timeinseconds=False,\n>>> )\n
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_mupulses","title":"plot_mupulses(emgfile, munumber='all', linewidths=0.5, addrefsig=True, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True)","text":"

Plot all the MUPULSES (binary representation of the firings time).

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

munumber

all IPTS of all the MUs is plotted.

Otherwise, a single MU (int) or multiple MUs (list of int) can be specified. The list can be passed as a manually-written list or with: munumber=[*range(0, 12)]. We need the \" * \" operator to unpack the results of range into a list. munumber is expected to be with base 0 (i.e., the first MU in the file is the number 0).

TYPE: str {\"all\"}, int or list DEFAULT: \"all\"

linewidths

The width of the vertical lines representing the MU firing.

TYPE: float DEFAULT: 0.5

addrefsig

If True, the REF_SIGNAL is plotted in front of the MUs pulses with a separated y-axes.

TYPE: bool DEFAULT: True

timeinseconds

Whether to show the time on the x-axes in seconds (True) or in samples (False).

TYPE: bool DEFAULT: True

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

tight_layout

If True (default), the plt.tight_layout() is called and the figure's layout is improved. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_mupulses--see-also","title":"See also","text":"
  • plot_ipts : plot the MUs impulse train per second (IPTS).
  • plot_idr : plot the instantaneous discharge rate.

Examples:

Plot MUs pulses based on recruitment order and overlay the reference signal.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emg.plot_mupulses(\n...     emgfile=emgfile,\n...     linewidths=0.5,\n...     order=True,\n...     addrefsig=True,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_ipts","title":"plot_ipts(emgfile, munumber='all', addrefsig=False, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True)","text":"

Plot the IPTS (decomposed source).

IPTS is the non-binary representation of the MUs firing times.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

munumber

all IPTS of all the MUs is plotted.

Otherwise, a single MU (int) or multiple MUs (list of int) can be specified. The list can be passed as a manually-written list or with: munumber=[*range(0, 12)]. We need the \" * \" operator to unpack the results of range into a list. munumber is expected to be with base 0 (i.e., the first MU in the file is the number 0).

TYPE: str {\"all\"}, int or list DEFAULT: \"all\"

timeinseconds

Whether to show the time on the x-axes in seconds (True) or in samples (False).

TYPE: bool DEFAULT: True

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

tight_layout

If True (default), the plt.tight_layout() is called and the figure's layout is improved. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_ipts--see-also","title":"See also","text":"
  • plot_mupulses : plot the binary representation of the firings.
  • plot_idr : plot the instantaneous discharge rate.
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_ipts--notes","title":"Notes","text":"

munumber = \"all\" corresponds to: munumber = [*range(0, emgfile[\"NUMBER_OF_MUS\"])]

Examples:

Plot IPTS of all the MUs and overlay the reference signal.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emg.plot_ipts(\n...     emgfile=emgfile,\n...     munumber=\"all\",\n...     addrefsig=True,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n

Plot IPTS of two MUs.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emg.plot_ipts(\n...     emgfile=emgfile,\n...     munumber=[1, 3],\n...     addrefsig=False,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_idr","title":"plot_idr(emgfile, munumber='all', addrefsig=True, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True)","text":"

Plot the instantaneous discharge rate (IDR).

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

munumber

``all\" IDR of all the MUs is plotted.

Otherwise, a single MU (int) or multiple MUs (list of int) can be specified. The list can be passed as a manually-written list or with: munumber=[*range(0, 12)]. We need the \" * \" operator to unpack the results of range into a list. munumber is expected to be with base 0 (i.e., the first MU in the file is the number 0).

TYPE: str, int or list DEFAULT: \"all\"

addrefsig

If True, the REF_SIGNAL is plotted in front of the MUs IDR with a separated y-axes.

TYPE: bool DEFAULT: True

timeinseconds

Whether to show the time on the x-axes in seconds (True) or in samples (False).

TYPE: bool DEFAULT: True

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

tight_layout

If True (default), the plt.tight_layout() is called and the figure's layout is improved. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_idr--see-also","title":"See also","text":"
  • plot_mupulses : plot the binary representation of the firings.
  • plot_ipts : plot the impulse train per second (IPTS).
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_idr--notes","title":"Notes","text":"

munumber = \"all\" corresponds to munumber = [*range(0, emgfile[\"NUMBER_OF_MUS\"])]

Examples:

Plot IDR of all the MUs and overlay the reference signal.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emg.plot_idr(\n...     emgfile=emgfile,\n...     munumber=\"all\",\n...     addrefsig=True,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n

Plot IDR of two MUs.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emg.plot_idr(\n...     emgfile=emgfile,\n...     munumber=[1, 3],\n...     addrefsig=False,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_muaps","title":"plot_muaps(sta_dict, title='MUAPs from STA', figsize=[20, 15], showimmediately=True)","text":"

Plot MUAPs obtained from STA from one or multiple MUs.

PARAMETER DESCRIPTION sta_dict

dict containing STA of the specified MU or a list of dicts containing STA of specified MUs. If a list is passed, different MUs are overlayed. This is useful for visualisation of MUAPs during tracking or duplicates removal.

TYPE: dict or list

title

Title of the plot.

TYPE: str DEFAULT: \"MUAPs from STA\"

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_muaps--see-also","title":"See also","text":"
  • sta : computes the spike-triggered average (STA) of every MUs.
  • plot_muap : for overplotting all the STAs and the average STA of a MU.
  • align_by_xcorr : for alignin the STAs of two different MUs.
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_muaps--notes","title":"Notes","text":"

There is no limit to the number of MUs and STA files that can be overplotted. Remember: the different STAs should be matched with same number of electrode, processing (i.e., differential) and computed on the same timewindow.

Examples:

Plot MUAPs of a single MU.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True,\n... )\n>>> sta = emg.sta(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     firings=\"all\",\n...     timewindow=50,\n... )\n>>> emg.plot_muaps(sta_dict=sta[1])\n

Plot single differential derivation MUAPs of a single MU.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True,\n... )\n>>> sorted_rawemg = emg.diff(sorted_rawemg=sorted_rawemg)\n>>> sta = emg.sta(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     firings=\"all\",\n...     timewindow=50,\n... )\n>>> emg.plot_muaps(sta_dict=sta[1])\n

Plot single differential derivation MUAPs of two MUs from the same file.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True,\n... )\n>>> sorted_rawemg = emg.diff(sorted_rawemg=sorted_rawemg)\n>>> sta = emg.sta(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     firings=\"all\",\n...     timewindow=50,\n... )\n>>> emg.plot_muaps(sta_dict=[sta[1], sta[2]])\n
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_muap","title":"plot_muap(emgfile, stmuap, munumber, column, channel, channelprog=False, average=True, timeinseconds=True, figsize=[20, 15], showimmediately=True, tight_layout=True)","text":"

Plot the MUAPs of a specific matrix channel.

Plot the MUs action potential (MUAPs) shapes with or without average.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

stmuap

dict containing a dict of ST MUAPs (pd.DataFrame) for every MUs.

TYPE: dict

munumber

The number of the MU to plot.

TYPE: int

column

The matrix columns. Options are usyally \"col0\", \"col1\", \"col2\", ..., last column.

TYPE: str

channel

The channel of the matrix to plot. This can be the real channel number if channelprog=False (default), or a progressive number (from 0 to the length of the matrix column) if channelprog=True.

TYPE: int

channelprog

Whether to use the real channel number or a progressive number (see channel).

TYPE: bool DEFAULT: False

average

Whether to plot also the MUAPs average obtained by spike triggered average.

TYPE: bool DEFAULT: True

timeinseconds

Whether to show the time on the x-axes in seconds (True) or in samples (False).

TYPE: bool DEFAULT: True

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

tight_layout

If True (default), the plt.tight_layout() is called and the figure's layout is improved. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_muap--see-also","title":"See also","text":"
  • plot_muaps : Plot MUAPs obtained from STA from one or multiple MUs.
  • st_muap : Generate spike triggered MUAPs of every MUs (as input to this function).

Examples:

Plot all the consecutive MUAPs of a single MU. In this case we are plotting the matrix channel 45 which is placed in column 4 (\"col3\") as Python numbering is base 0.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True,\n... )\n>>> stmuap = emg.st_muap(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     timewindow=50,\n... )\n>>> emg.plot_muap(\n...     emgfile=emgfile,\n...     stmuap=stmuap,\n...     munumber=1,\n...     column=\"col3\",\n...     channel=45,\n...     channelprog=False,\n...     average=False,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n

To avoid the problem of remebering which channel number is present in which matrix column, we can set channelprog=True and locate the channel with a value ranging from 0 to the length of each column.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True,\n... )\n>>> stmuap = emg.st_muap(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     timewindow=50,\n... )\n>>> emg.plot_muap(\n...     emgfile=emgfile,\n...     stmuap=stmuap,\n...     munumber=1,\n...     column=\"col3\",\n...     channel=5,\n...     channelprog=True,\n...     average=False,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n

It is also possible to visualise the spike triggered average of the MU with average=True. In this example the single differential derivation is used.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile=emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True,\n... )\n>>> sorted_rawemg = emg.diff(sorted_rawemg=sorted_rawemg)\n>>> stmuap = emg.st_muap(\n...     emgfile=emgfile,\n...     sorted_rawemg=sorted_rawemg,\n...     timewindow=50,\n... )\n>>> emg.plot_muap(\n...     emgfile=emgfile,\n...     stmuap=stmuap,\n...     munumber=1,\n...     column=\"col2\",\n...     channel=6,\n...     channelprog=True,\n...     average=True,\n...     timeinseconds=True,\n...     figsize=[20, 15],\n...     showimmediately=True,\n... )\n
"},{"location":"API_plotemg/#openhdemg.library.plotemg.plot_muaps_for_cv","title":"plot_muaps_for_cv(sta_dict, xcc_sta_dict, title='MUAPs for CV', figsize=[20, 15], showimmediately=True)","text":"

Visualise MUAPs on which to calculate MUs CV.

Plot MUAPs obtained from the STA of the double differential signal and their paired cross-correlation value.

PARAMETER DESCRIPTION sta_dict

dict containing the STA of the double-differential derivation of a specific MU.

TYPE: dict

xcc_sta_dict

dict containing the normalised cross-correlation coefficient of the double-differential derivation of a specific MU.

TYPE: dict

title

Title of the plot.

TYPE: str DEFAULT: \"MUAPs from STA\"

figsize

Size of the figure in centimeters [width, height].

TYPE: list DEFAULT: [20, 15]

showimmediately

If True (default), plt.show() is called and the figure showed to the user. It is useful to set it to False when calling the function from the GUI.

TYPE: bool DEFAULT: True

RETURNS DESCRIPTION fig

TYPE: pyplot `~.figure.Figure`

Examples:

Plot the double differential derivation and the XCC of adjacent channels for the first MU (0).

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> sorted_rawemg = emg.sort_rawemg(\n...     emgfile,\n...     code=\"GR08MM1305\",\n...     orientation=180,\n...     dividebycolumn=True\n... )\n>>> dd = emg.double_diff(sorted_rawemg)\n>>> sta = emg.sta(\n...     emgfile=emgfile,\n...     sorted_rawemg=dd,\n...     firings=[0, 50],\n...     timewindow=50,\n... )\n>>> xcc_sta = emg.xcc_sta(sta)\n>>> fig = emg.plot_muaps_for_cv(\n...     sta_dict=sta[0],\n...     xcc_sta_dict=xcc_sta[0],\n...     showimmediately=False,\n... )\n
"},{"location":"API_tools/","title":"tools","text":""},{"location":"API_tools/#description","title":"Description","text":"

This module contains the functions that don't properly apply to the plot or analysis category but that are necessary for the usability of the library. The functions contained in this module can be considered as \"tools\" or shortcuts necessary to operate with the HD-EMG recordings.

"},{"location":"API_tools/#openhdemg.library.tools.showselect","title":"showselect(emgfile, title='', titlesize=12, nclic=2)","text":"

Select a part of the recording.

The area can be selected (based on the REF_SIGNAL) with any letter or number in the keyboard, wrong points can be removed by pressing the right mouse button. Once finished, press enter to continue.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile and in particular the REF_SIGNAL (which is used for the selection).

TYPE: dict

title

The title of the plot. It is optional but strongly recommended. It should describe the task to do.

TYPE: str DEFAULT: ''

titlesize

The font size of the title.

TYPE: int DEFAULT: 12

nclic

The number of clics to be collected. If nclic < 1, all the clicks are collected.

DEFAULT: 2

RETURNS DESCRIPTION points

A list containing the selected points sorted in ascending order.

TYPE: list

RAISES DESCRIPTION ValueError

When the user clicked a wrong number of inputs in the GUI.

Examples:

Load the EMG file and select the points.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB_REFSIG\")\n>>> points = emg.showselect(\n...     emgfile,\n...     title=\"Select 2 points\",\n...     nclic=2,\n... )\n>>> points\n[16115, 40473]\n
"},{"location":"API_tools/#openhdemg.library.tools.create_binary_firings","title":"create_binary_firings(emg_length, number_of_mus, mupulses)","text":"

Create a binary representation of the MU firing.

Create a binary representation of the MU firing over time based on the times of firing of each MU.

PARAMETER DESCRIPTION emg_length

Number of samples (length) in the emg file.

TYPE: int

number_of_mus

Number of MUs in the emg file.

TYPE: int

mupulses

Each ndarray should contain the times of firing of each MU.

TYPE: list of ndarrays

RETURNS DESCRIPTION binary_MUs_firing

A pd.DataFrame containing the binary representation of MUs firing or np.nan if the variable was not found.

TYPE: pd.DataFrame

"},{"location":"API_tools/#openhdemg.library.tools.resize_emgfile","title":"resize_emgfile(emgfile, area=None)","text":"

Resize all the emgfile.

This function can be useful to compute the various parameters only in the area of interest.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile to resize.

TYPE: dict

area

The resizing area. If already known, it can be passed in samples, as a list (e.g., [120,2560]). If None, the user can select the area of interest manually.

TYPE: None or list DEFAULT: None

RETURNS DESCRIPTION rs_emgfile

the new (resized) emgfile.

TYPE: dict

start_, end_ : int

the start and end of the selection (can be used for code automation).

"},{"location":"API_tools/#openhdemg.library.tools.resize_emgfile--notes","title":"Notes","text":"

Suggested names for the returned objects: rs_emgfile, start_, end_.

PNR and SIL are computed again in the new resized area.

"},{"location":"API_tools/#openhdemg.library.tools.compute_idr","title":"compute_idr(emgfile)","text":"

Compute the IDR.

This function computes the instantaneous discharge rate (IDR) from the MUPULSES. The IDR is very useful for plotting and visualisation of the MUs behaviour.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

RETURNS DESCRIPTION idr

A dict containing a pd.DataFrame for each MU (keys are integers). Accessing the key, we have a pd.DataFrame containing: mupulses: firing sample. diff_mupulses: delta between consecutive firing samples. timesec: delta between consecutive firing samples in seconds. idr: instantaneous discharge rate.

TYPE: dict

Examples:

Load the EMG file, compute IDR and access the results for the first MU.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> idr = emg.compute_idr(emgfile=emgfile)\n>>> munumber = 0\n>>> idr[munumber]\n    mupulses  diff_mupulses    timesec       idr\n0        9221            NaN   4.502441       NaN\n1        9580          359.0   4.677734  5.704735\n2        9973          393.0   4.869629  5.211196\n3       10304          331.0   5.031250  6.187311\n4       10617          313.0   5.184082  6.543131\n..        ...            ...        ...       ...\n149     54521          395.0  26.621582  5.184810\n150     54838          317.0  26.776367  6.460568\n151     55417          579.0  27.059082  3.537133\n152     55830          413.0  27.260742  4.958838\n153     56203          373.0  27.442871  5.490617\n
"},{"location":"API_tools/#openhdemg.library.tools.delete_mus","title":"delete_mus(emgfile, munumber, if_single_mu='ignore')","text":"

Delete unwanted MUs.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

munumber

The MUs to remove. If a single MU has to be removed, this should be an int (number of the MU). If multiple MUs have to be removed, a list of int should be passed. An unpacked (*) range can also be passed as munumber=[*range(0, 5)]. munumber is expected to be with base 0 (i.e., the first MU in the file is the number 0).

TYPE: int, list of int

if_single_mu

A string indicating how to behave in case of a file with a single MU.

ignore Ignore the process and return the original emgfile. (Default) remove Remove the MU and return the emgfile without the MU. (Default) This should allow full compatibility with the use of this file in following processing (i.e., save/load and analyse).

TYPE: str {\"ignore\", \"remove\"} DEFAULT: \"ignore\"

RETURNS DESCRIPTION emgfile

The dictionary containing the emgfile without the unwanted MUs.

TYPE: dict

Examples:

Delete MUs 1,4,5 from the emgfile.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> emgfile = emg.delete_mus(emgfile=emgfile, munumber=[1,4,5])\n
"},{"location":"API_tools/#openhdemg.library.tools.sort_mus","title":"sort_mus(emgfile)","text":"

Sort the MUs in order of recruitment.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

RETURNS DESCRIPTION sorted_emgfile

The dictionary containing the sorted emgfile.

TYPE: dict

"},{"location":"API_tools/#openhdemg.library.tools.compute_covsteady","title":"compute_covsteady(emgfile, start_steady=-1, end_steady=-1)","text":"

Calculates the covsteady.

This function calculates the coefficient of variation of the steady-state phase (covsteady of the REF_SIGNAL).

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

start_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

end_steady

The start and end point (in samples) of the steady-state phase. If < 0 (default), the user will need to manually select the start and end of the steady-state phase.

TYPE: int DEFAULT: -1

RETURNS DESCRIPTION covsteady

The coefficient of variation of the steady-state phase in %.

TYPE: float

"},{"location":"API_tools/#openhdemg.library.tools.compute_covsteady--see-also","title":"See also","text":"
  • compute_idr : computes the instantaneous discharge rate.

Examples:

Load the EMG file, compute covsteady and access the result from GUI.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> covsteady = emg.compute_covsteady(emgfile=emgfile)\n>>> covsteady\n1.452806\n

The process can be automated by bypassing the GUI.

>>> import openhdemg.library as emg\n>>> emgfile = emg.askopenfile(filesource=\"OTB\", otb_ext_factor=8)\n>>> covsteady = emg.compute_covsteady(\n...     emgfile=emgfile,\n...     start_steady=3580,\n...     end_steady=15820,\n... )\n>>> covsteady\n35.611263\n
"},{"location":"API_tools/#openhdemg.library.tools.filter_rawemg","title":"filter_rawemg(emgfile, order=2, lowcut=20, highcut=500)","text":"

Band-pass filter the RAW_SIGNAL.

The filter is a Zero-lag band-pass Butterworth.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

order

The filter order.

TYPE: int DEFAULT: 2

lowcut

The lower cut-off frequency in Hz.

TYPE: int DEFAULT: 20

highcut

The higher cut-off frequency in Hz.

TYPE: int DEFAULT: 500

RETURNS DESCRIPTION filteredrawsig

The dictionary containing the emgfile with a filtered RAW_SIGNAL.

TYPE: dict

"},{"location":"API_tools/#openhdemg.library.tools.filter_rawemg--see-also","title":"See also","text":"
  • filter_refsig : low-pass filter the REF_SIGNAL.
"},{"location":"API_tools/#openhdemg.library.tools.filter_refsig","title":"filter_refsig(emgfile, order=4, cutoff=15)","text":"

Low-pass filter the REF_SIGNAL.

This function is used to low-pass filter the REF_SIGNAL and remove noise. The filter is a Zero-lag low-pass Butterworth.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

order

The filter order.

TYPE: int DEFAULT: 4

cutoff

The cut-off frequency in Hz.

TYPE: int DEFAULT: 15

RETURNS DESCRIPTION filteredrefsig

The dictionary containing the emgfile with a filtered REF_SIGNAL.

TYPE: dict

"},{"location":"API_tools/#openhdemg.library.tools.filter_refsig--see-also","title":"See also","text":"
  • remove_offset : remove the offset from the REF_SIGNAL.
  • filter_rawemg : band-pass filter the RAW_SIGNAL.
"},{"location":"API_tools/#openhdemg.library.tools.remove_offset","title":"remove_offset(emgfile, offsetval=0, auto=0)","text":"

Remove the offset from the REF_SIGNAL.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile.

TYPE: dict

offsetval

Value of the offset. If offsetval is 0 (default), the user will be asked to manually select an aerea to compute the offset value. Otherwise, the value passed to offsetval will be used. Negative offsetval can be passed.

TYPE: float DEFAULT: 0

auto

If auto > 0, the script automatically removes the offset based on the number of samples passed in input.

TYPE: int DEFAULT: 0

RETURNS DESCRIPTION offs_emgfile

The dictionary containing the emgfile with a corrected offset of the REF_SIGNAL.

TYPE: dict

"},{"location":"API_tools/#openhdemg.library.tools.remove_offset--see-also","title":"See also","text":"
  • filter_refsig : low-pass filter REF_SIGNAL.
"},{"location":"API_tools/#openhdemg.library.tools.get_mvc","title":"get_mvc(emgfile, how='showselect', conversion_val=0)","text":"

Measure the maximum voluntary contraction (MVC).

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile with the reference signal.

TYPE: dict

how

showselect Ask the user to select the area where to calculate the MVC with a GUI. all Calculate the MVC on the entire file.

TYPE: str {\"showselect\", \"all\"} DEFAULT: \"showselect\"

conversion_val

The conversion value to multiply the original reference signal. I.e., if the original reference signal is in kilogram (kg) and conversion_val=9.81, the output will be in Newton/Sec (N/Sec). If conversion_val=0 (default), the results will simply be Original measure unit. conversion_val can be any custom int or float.

TYPE: float or int DEFAULT: 0

RETURNS DESCRIPTION mvc

The MVC value in the original (or converted) unit of measurement.

TYPE: float

"},{"location":"API_tools/#openhdemg.library.tools.get_mvc--see-also","title":"See also","text":"
  • compute_rfd : calculate the RFD.
  • remove_offset : remove the offset from the REF_SIGNAL.
  • filter_refsig : low-pass filter REF_SIGNAL.

Examples:

Load the EMG file, remove reference signal offset and get MVC value.

>>> import openhdemg.library as emg\n>>> emg_refsig = emg.askopenfile(filesource=\"OTB_REFSIG\")\n>>> offs_refsig = emg.remove_offset(emgfile=emg_refsig)\n>>> mvc = emg.get_mvc(emgfile=offs_refsig )\n>>> mvc\n50.72\n

The process can be automated by bypassing the GUI and calculating the MVC of the entire file.

>>> import openhdemg.library as emg\n>>> emg_refsig = emg.askopenfile(filesource=\"OTB_REFSIG\")\n>>> mvc = emg.get_mvc(emgfile=emg_refsig, how=\"all\")\n>>> print(mvc)\n50.86\n
"},{"location":"API_tools/#openhdemg.library.tools.compute_rfd","title":"compute_rfd(emgfile, ms=[50, 100, 150, 200], startpoint=None, conversion_val=0)","text":"

Calculate the RFD.

Rate of force development (RFD) is reported as X/Sec where \"X\" is the unit of measurement based on conversion_val.

PARAMETER DESCRIPTION emgfile

The dictionary containing the emgfile with the reference signal.

TYPE: dict

ms

Milliseconds (ms). A list containing the ranges in ms to calculate the RFD.

TYPE: list DEFAULT: [50, 100, 150, 200]

startpoint

The starting point to calculate the RFD in samples, If None, the user will be requested to manually select the starting point.

TYPE: None or int DEFAULT: None

conversion_val

The conversion value to multiply the original reference signal. I.e., if the original reference signal is in kilogram (kg) and conversion_val=9.81, the output will be in Newton/Sec (N/Sec). If conversion_val=0 (default), the results will simply be Original measure unit/Sec. conversion_val can be any custom int or float.

TYPE: float or int DEFAULT: 0

RETURNS DESCRIPTION rfd

A pd.DataFrame containing the RFD at the different times.

TYPE: pd.DataFrame

"},{"location":"API_tools/#openhdemg.library.tools.compute_rfd--see-also","title":"See also","text":"
  • get_mvif : measure the MViF.
  • remove_offset : remove the offset from the REF_SIGNAL.
  • filter_refsig : low-pass filter REF_SIGNAL.

Examples:

Load the EMG file, low-pass filter the reference signal and compute RFD.

>>> import openhdemg.library as emg\n>>> emg_refsig = emg.askopenfile(filesource=\"OTB_REFSIG\")\n>>> filteredrefsig  = emg.filter_refsig(\n...     emgfile=emg_refsig,\n...     order=4,\n...     cutoff=15,\n... )\n>>> rfd = emg.compute_rfd(\n...     emgfile=filteredrefsig,\n...     ms=[50, 100, 200],\n...     conversion_val=9.81,\n...     )\n>>> rfd\n        50         100        200\n0  68.34342  79.296188  41.308215\n

The process can be automated by bypassing the GUI.

>>> import openhdemg.library as emg\n>>> emg_refsig = emg.askopenfile(filesource=\"OTB_REFSIG\")\n>>> filteredrefsig  = emg.filter_refsig(\n...     emgfile=emg_refsig,\n...     order=4,\n...     cutoff=15,\n...     )\n>>> rfd = emg.compute_rfd(\n...     emgfile=filteredrefsig,\n...     ms=[50, 100, 200],\n...     startpoint=3568,\n...     )\n>>> rfd\n        50         100        200\n0  68.34342  79.296188  41.308215\n
"},{"location":"Cite-Us/","title":"Cite Us","text":"

If you use openhdemg for your reaserch, please cite the project as:

We are working to publish soon..

"},{"location":"Contacts/","title":"Contacts","text":""},{"location":"Contacts/#primary-contact","title":"Primary contact","text":"

\u00a0 Giacomo Valli: giacomo.valli@phd.unipd.it

"},{"location":"Contacts/#discussion-forum","title":"Discussion forum","text":"

\u00a0 Read answers or ask questions in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

"},{"location":"Contacts/#follow-us-on-twitter","title":"Follow us on Twitter","text":"

https://twitter.com/openhdemg

"},{"location":"Contacts/#meet-the-developers","title":"Meet the developers","text":"

Giacomo Valli:

  • The creator of the project and the developer of the library.

  • Giacomo Valli obtained a master degree in Sports Science and a research fellowship in molecular biology of exercise at the University of Urbino (IT). He is currently a PhD student at the University of Padova (IT) in neuromuscular physiology. He is investigating the electrophysiological modifications happening during disuse, disease and aging and linking this information to the molecular alterations of the muscle.

Paul Ritsche:

  • The developer of the GUI.

  • Paul Ritsche obtained a master degree in Sports Science at the University of Basel (CH). He is currently a research associate at the University of Basel (CH) focusing on muscle ultrasonography. He is investigating automatic ultrasonography image analysis methods to evaluate muscle morphological as well architectural parameters.

"},{"location":"GUI_advanced/","title":"Graphical Interface","text":"

This is the toturial for the Advanced Tools in the openhdemg GUI. Great that you made it this far! In the next few sections we will take a look at the more advanced functions implemented in the GUI. But first of all, you need to click the Advanced Toolsbutton in the main window of the GUI to get to the respective adavanced analysis. The Advanced Tools Window will open.

So far, we have included three advanced analyses in the openhdemg GUI.

  • Motor Unit Tracking
  • Duplicate Removal
  • Conduction Velocity Calculation

For all of those, the specification of a Matrix Orientation and a Matrix Code is required. The Matrix Orientaion must match the one of your matrix during acquisition. You can find a reference image for the Orientation at the bottom in the right side of the Plot Window when using the Plot EMGfunction. The Matrix Orientation can be either 0 or 180 and must be chosen from the dropdown list. The Matrix Code must be specified according to the one you used during acquisition. So far, the codes

  • GR08MM1305
  • GR04MM1305
  • GR10MM0808
  • None

are implemented. You must choose one from the respective dropdown list. In case you selected None, the entrybox Rows, Columns will appear. Please specify the number of rows and columns of your used matrix since you now bypass included matrix codes. In example, specifying

Rows, Columns: 13, 5\n
means that your File has 65 channels. Once you specified these parameter, you can click the Advaned Analysis button to start your analysis.

"},{"location":"GUI_advanced/#motor-unit-tracking","title":"Motor Unit Tracking","text":"

When you want to track MUs across two different files, you need to select the Motor Unit Tracking options and specify the Matrix Code and Matrix Orentation in the Advanced Tools Window. Once you clicked the Advanced Analysis button, the MUs Tracking Window will pop-up.

  1. You need to specify the Type of file you want to track MUs across in the respective dropdown. The available filetypes are:

    • OTB (.mat file exportable by OTBiolab+)
    • DEMUSE (.mat file used in DEMUSE)
    • OPENHDEMG (emgfile or reference signal stored in .json format)
    • CUSTOM (custom data from a .csv file)

    Each filetype corresponds to a distinct datatype that should match the file you want to analyse. So, select the Type of file corresponding to the type of your file. In case you selected OTB specify the extension factor in the dropdown.

  2. Load the files according to specified Type of fileusing the Load File 1 and Load File 2 buttons.

  3. Select the minimum cross-correlation value to consider two MUs to be the same in the Threshold dropdown.

  4. Specify the timewindow across which you want the spike triggered average to be computed in the Timewindow dropdown.

  5. Select whether to exclude results with cross-correlation below specified Threshold by ticking the Exclude below threshold checkbox.

  6. If you select the Filter checkbox, only the match with the highest cross-correlation is returned when the same MU has a match of cross-correlation > Threshold with multiple MUs.

  7. The Show checkbox indicates whether to plot the spike triggered average of pairs of MUs with cross-correlation above Threshold.

  8. By clicking the Track button, you can start the analysis. The tracking results will be displayed in the MUs Tracking Resul output in the right side of the MUs Tracking Window.

"},{"location":"GUI_advanced/#duplicate-removal","title":"Duplicate Removal","text":"

When you want to remove MUs duplicates across different files, you need to select the Duplicate Removal options and specify the Matrix Code and Matrix Orentation in the Advanced Tools Window. Once you clicked the Advanced Analysis button, the Duplicate Removal Window will pop-up. Duplicate Removal requires similar input as Motor Unit Tracking, so please take a look at the Motor Unit Tracking section. However, you need to do two more things.

  1. You should specify How to remove the duplicated MUs in the Which dropdown. You can choose between

    • munumber: Duplicated MUs are removed from the file with more MUs.
    • PNR: The MU with the lowest PNR is removed.
    • SIL: The MU with the lowest SIL is removed.
  2. By clicking the Remove Duplicates button, you start the removal process.

  3. Specify a filename and location to save the file(s) with duplicates removed in a .json format.

"},{"location":"GUI_advanced/#conduction-velocity","title":"Conduction Velocity","text":"

Prior to calculation of the Conduction Velocity you need to load a file in the main window of the GUI. Take a look at the intro section. Once you have done this, open the Advanced Tool Window using the Advanced Analaysis button.

  1. Select Conduction Velocity in the Analysis Tool dropdown, decide on the Matrix Orientation and Matrix Code as described above.

  2. Click the Advanced Analysis button to start the calculation of the Conduction Velocity. The MUs cv estimation window will pop up.

  3. In the top left of the MUs cv estimation window select the MU for which you want to calculate the conduction velocity using the MU Number dropdown.

  4. In the top middle of the window select the column for which you want to calculate the conduction velocity choosing from the Column dropdown.

  5. In the top right of the window select the rows for which you want to calculate the conduction velocity using the From row and To row dropdown. For example, if you want to calculate the conduction velocity from row 3 to 7, select

    From row: 3\nTo row: 7\n
  6. Click the Estimate button to start the calculation for the respective column and rows. The results will be displayed on the right side of the MUs cv estimation window.

  7. You can copy the estimation results using the Copy Results button for futher analysis. The results are copied in the clipboard and can be pasted into any .csv (Excel).

We are now at the end of describing the advanced functions included in the openhdemg GUI. In case you need further clarification, don't hesitate to post a question in the Github discussion forum (LINK). Moreover, if you noticed an error that was not properly catched by the GUI, please file a bug report according to our guidelines (LINK). If you want to take a look at more basic stuff, check out the basic.

"},{"location":"GUI_advanced/#more-questions","title":"More questions?","text":"

We hope that this tutorial was useful. If you need any additional information, do not hesitate to read the answers or ask a question in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

"},{"location":"GUI_basics/","title":"Graphical Interface","text":"

This is the basic introduction to the openhdemg GUI. In the next few sections, we will go through the basic analysis functions embedded in the GUI. For the advanced stuff, take a look at the advanced chapter. We will start with how to sort the motor units (MUs) included in your analysis file, go over force and MU property analysis, take a detour on plotting, and take a look at how to save and reset your analysis. Have fun!

"},{"location":"GUI_basics/#motor-unit-sorting","title":"Motor Unit Sorting","text":"

To sort the MUs included in your analysis file in order of their recruitement, we implemented a sorting algorithm. The MUs are sorted based on their recruitement order in an ascending manner.

  1. Load a file. Take a look at the intro section on how to do so.

  2. Pay attention to view the MUs first, using the View MUs button (we explained this button in the intro chapter). The MUs will be sorted anyways, but without viewing them you won't see what is happening.

  3. On the left hand side in the main window of the GUI, you can find the Sort MUs button. It is located in row three, column two. Once you press the button, the MUs will be sorted.

"},{"location":"GUI_basics/#remove-motor-units","title":"Remove Motor Units","text":"

To remove MUs included in your analysis file, you can click the Remove MUs button. The button is located on the left hand side in the main window of the GUI in column one of row four.

  1. View the MUs using the View MUs button prior to MU removal, you can directly see what is happening.

  2. Click the Remove MUs button, and a file is loaded, a pop-up window will open.

  3. Select the MU you want to delete from the analysis file from the Select MU:dropdown.

    Select MU: 1\n
    will result in the second MU to be deleted (Python is base 0).

  4. Click the Remove MU button to remove the MU.

"},{"location":"GUI_basics/#reference-signal-editing","title":"Reference Signal Editing","text":"

The openhdemg GUI also allows you to edit and filter reference signals corresponding to your analysis file (this can be either a file containing both the MUs and the reference signal or a file containing only the reference signal).

  1. View the MUs using the View MUs button prior to reference signal editing, so you can see what is happening.

  2. Click the RefSig Editing button located in row five and column one, a new pop-up window opens. In the Reference Signal Editing Window, you can low-pass filter the reference signal as well as remove any signal offset. Additionally, you can also convert your reference signal by a specific factor (amplification factor) or convert it from absolute to percentage (relative or normalised) values.

  3. When you click the Filter RefSig button, the reference signal is low-pass filtered (Zero-lag, Butterworth) according to values specified in the Filter Order and Cutoff Freq textboxes. In example, specifiying

    Filter Order: 4\nCutoff Freq: 15\n
    will allow only frequencies below 15 Hz to pass trough. The filter order of 4 indicates a fourth degree polynomial transfer function.

  4. When you click the Remove Offset button, the reference signal's offset will be removed according to the values specified in the Offset Value and Automatic Offset textboxes. In example, specifying

    Offset Value : 4\nAutomatic: 0\n
    will result in an offset correction by -4 in y-axis direction. Furthermore, specifying

    Offset Value : 0\nAutomatic: != 0\n
    will result in automatic offset removal. In this case, the offset value is determined as the mean value of n samples at the beginning of the contraction (where n is equal to the value passed to Automatic). Moreover, specifying

    Offset Value : 0\nAutomatic: 0\n
    will allow you to manually correct the offset in a new pop-up plot. You just need to follow the instructions on the plot.

  5. When you click the Convert button, the reference signal will be multiplied or divided (depending on Operator) by the Factor. In example, specifying

    Operator : \"Multiply\"\nFactor: 2.5\n
    will amplify the reference signal 2.5 times.

  6. When you click the To Percent button, the reference signal in absolute values is converted to percentage (relative or normalised) values based on the provided MVC Value. This step should be performed before any analysis, because openhdemg is designed to work with a normalised reference signal. In example, a file with a reference signal in absolute values ranging from 0 to 100 will be normalised from 0 to 20 if

    MVC Value : 500\n
"},{"location":"GUI_basics/#resize-emg-file","title":"Resize EMG File","text":"

Sometimes, resizing of your analysis file is unevitable. Luckily, openhdemg provides an easy solution. In row five and column two in the left side of the GUI, you can find the Resize File button.

  1. View the MUs using the View MUs button prior to file resizing, you can directly see what is happening.

  2. Clicking the Resize File button will open a new pop-up plot of your analysis file.

  3. Follow the instructions in the plot to resize the file. Simply click in the signal twice (once for start-point, once for end-point) to specify the resizing region and press enter to confirm your coice.

"},{"location":"GUI_basics/#analyse-force-signal","title":"Analyse Force Signal","text":"

In order to analyse the force signal in your analysis file, you can press the Analyse Force button located in row six and column one in the left side of the GUI. A new pop-up window will open where you can analyse the maximum voluntary contraction (MVC) value as well as the rate of force development (RFD).

"},{"location":"GUI_basics/#maximum-voluntary-contraction","title":"Maximum voluntary contraction","text":"
  1. In order to get the MVC value, simply press the Get MVC button. A pop-up plot opens and you can select the area where you suspect the MVC to be.
  2. Click once to specify the start-point and once to specify the end-point.
  3. Press enter to confirm you choice. You will then see a Result Output appearing at the bottom of the main window of the GUI. There you can find the actual result of your MVC analysis.
  4. You can edit or copy any value in the Result Output, however, you need to close the top-level Force Analysis Window first.
"},{"location":"GUI_basics/#rate-of-force-development","title":"Rate Of Force Development","text":"
  1. To calculate the RFD values you can press the Get RFD button.
  2. A pop-up plot appears and you need to specify the starting point of the rise in the force signal by clicking and subsequenlty pressing enter.
  3. The respective RFD values between the stated timepoint ranges (ms) in the RFD miliseconds textinput are displayed in the Result Output. In example, specifying

    RFD miliseconds: 50,100,150,200\n
    will result in RFD value calculation between the intervals 0-50ms, 50-100ms, 100-150ms and 150-200ms. You can also specify less or more values in the RFD miliseconds textbox.

  4. You can edit or copy any value in the Result Output, however, you need to close the top-level Force Analysis Window first.

"},{"location":"GUI_basics/#motor-unit-properties","title":"Motor Unit Properties","text":"

When you press the MU Properties button in row six and column two, the Motor Unit Properties Window will pop up. In this window, you have the option to analyse several MUs propierties such as the MUs recruitement threshold or the MUs discharge rate.

  1. Specify your priorly calculated MVC in the Enter MVC [N]: textbox, like

    Enter MVC [N]: 424\n
"},{"location":"GUI_basics/#compute-motor-unit-threshold","title":"Compute Motor Unit Threshold","text":"

Subsequently to specifying the MVC, you can compute the MUs recruitement threshold by specifying the respective event and type in the Event and Type dropdown list.

  1. Specify the Event dropdown and choose:

    \"rt_dert\" : Both recruitment and derecruitment thresholds will be calculated.\n\"rt\" : Only recruitment thresholds will be calculated.\n\"dert\" : Only derecruitment thresholds will be calculated.\n
  2. Specify the Type dropdown and choose:

    \"abs_rel\" : Both absolute and relative thresholds will be calculated.\n\"rel\" : Only relative thresholds will be calculated.\n\"abs\" : Only absolute thresholds will be calculated.\n
  3. Once you click the Compute threshold button, the recruitement threshold will be computed.

  4. The recruitement threshold for each inluded MU in the analysis file will be displayed in the Result Output of the GUI.
  5. You can edit or copy any value in the Result Output, however, you need to close the top-level Motor Unit Properties Window first.
"},{"location":"GUI_basics/#compute-motor-unit-discharge-rate","title":"Compute Motor Unit Discharge Rate","text":"

Subsequently to specifying the MVC, you can compute the MUs discharge rate by entering the respective firing rates and event.

  1. Specify the number of firings at recruitment and derecruitment to consider for the calculation in the Firings at Rec textbox.
  2. Enter the number of firings over which to calculate the DR at the start and end of the steady-state phase in the Firings Start/End Steady textbox.

    For example:

    Firings at Rec: 4\nFirings Start/End Steady: 10\n

  3. Lastly you need to specify the computation Event. From the Event dropdown list, you can choose:

    \"rec_derec_steady\" : Discharge rate is calculated at recruitment, derecruitment and during the steady-state phase.\n\"rec\" : Discharge rate is calculated at recruitment.\n\"derec\" : Discharge rate is calculated at derecruitment.\n\"rec_derec\" : Discharge rate is calculated at recruitment and derecruitment.\n\"steady\" : Discharge rate is calculated during the steady-state phase.\n
  4. Once you press the Compute discharge rate button, the discharge rate will be calculated.

  5. The discharge rate for each inluded MU in the analysis file at the stated event as well a for all the contraction will be displayed in the Result Output of the GUI.
  6. You can edit or copy any value in the Result Output, however, you need to close the top-level Motor Unit Properties Window first.
"},{"location":"GUI_basics/#basic-motor-unit-properties","title":"Basic Motor Unit Properties","text":"

Subsequently to specifying the MVC, you can calculate a number of basic MUs properties with one click. These include

  • The absolute/relative recruitment/derecruitment thresholds
  • The discharge rate at recruitment, derecruitment, during the steady-state phase and during the entire contraction
  • The coefficient of variation of interspike interval
  • The coefficient of variation of force signal

and are all displayed in the Result Output once the analysis in completed.

  1. Specify the number of firings at recruitment and derecruitment to consider for the calculation in the Firings at Rec textbox.
  2. Enter the start and end point (in samples) of the steady-state phase in the Firings Start/End Steady textbox. For example,

    Firings at Rec: 4\nFirings Start/End Steady: 10\n
  3. The basic MUs properties will be displayed in the Result Output of the GUI.

  4. You can edit or copy any value in the Result Output, however, you need to close the top-level Motor Unit Properties Window first.
"},{"location":"GUI_basics/#plot-motor-units","title":"Plot Motor Units","text":"

In openhdemg we have implemented options to plot your analysis file ... a lot of options! Upon clicking the Plot MUs button, the Plot Window will pop up. In the top right corner of the window, you can find an information button forwarding you directly to some tutorials.

You can choose between the follwing plotting options:

  • Plot the raw emg signal. Single or multiple channels. (Plot EMGSig)
  • Plot the reference signal. (Plot RefSig)
  • Plot all the MUs pulses (binary representation of the firings time). (Plot MUPulses)
  • Plot the decomposed source. (Plot Source)
  • Plot the instantaneous discharge rate (IDR). (Plot IDR)
  • Plot the differential derivation of the raw emg signal by matrix column. (Plot Derivation)
  • Plot motor unit action potentials (MUAPs) obtained from spike-triggered average from one or multiple MUs. (Plot MUAPs)

Prior to plotting you can optionally select a few options on the left side of the Plot Window.

  1. When you want the reference signal to be displayed in the plots you can select the Reference Signal checkbox in row one and column two in the left side of the Plot Window.
  2. You can specify wheter you want the x-axis of the plots to be scaled in seconds by selecting the Time in seconds checkbox in row two and column two in the left side of the Plot Window.
  3. You can change the size of the plot as well, by inputting your prefered height and width in the Figure in size in cm (h,w) textbox in row three and column two in the left side of the Plot Window. For example, if you want your plot to have a height of 6 and a width of 8, your input should look like this

    Figure in size in cm (h,w): 6,8\n

These three setting options are universally used in all plots. There are two more specification options on the right side of the Plot Window only relevant when using the Plot Derivation or Plot MUAP buttons.

  1. The Matrix Code must be specified in row one and column four in the right side of the Plot Window according to the one you used during acquisition. So far, implemented codes are:

    • GR08MM1305
    • GR04MM1305
    • GR10MM0808
    • None

    In case you selected None, the entrybox Rows, Columns will appear. Please specify the number of rows and columns of your used matrix since you now bypass included matrix codes. In example, specifying

    Rows, Columns: 13, 5\n
    means that your File has 65 channels.

  2. You need to specify the Orientation in row two and column four in the left side of the Plot Window. The Orientaion must match the one of your matrix during acquisition. You can find a reference image for the Orientation at the bottom in the right side of the Plot Window.

"},{"location":"GUI_basics/#plot-raw-emg-signal","title":"Plot Raw EMG Signal","text":"
  1. Click the Plot EMGsig button in row four and column one in the left side of the Plot Window, to plot the raw emg signal of your analysis file.
  2. Enter or select a Channel Number in / from the dropdown list. For example, if you want to plot Channel Number one enter 0 in the dropdown. If you want to plot Channel Numbers one, two and three enter 0,1,2 in the dropdown.
  3. Once you have clicked the Plot EMGsig button, a pop-up plot will appear.
"},{"location":"GUI_basics/#plot-reference-signal","title":"Plot Reference Signal","text":"
  1. Click the Plot RefSig button in row five and column one in the left side of the Plot Window, to plot the reference signal.
  2. Once you have clicked the Plot RefSig button, a pop-up plot will appear.
"},{"location":"GUI_basics/#plot-motor-unit-pulses","title":"Plot Motor Unit Pulses","text":"
  1. Click the Plot MUpulses button in row six and column one in the left side of the Plot Window, to plot the single pulses of the MUs in your analysis file.
  2. Enter/select a pulse Linewidth in/from the dropdown list. For example, if you want to use a Linewidth of one, enter 1 in the dropdown.
  3. Once you have clicked the Plot MUpulses button, a pop-up plot will appear.
"},{"location":"GUI_basics/#plot-the-decomposed-source","title":"Plot the Decomposed Source","text":"
  1. Click the Plot Source button in row seven and column one in the left side of the Plot Window, to plot the Source of the decomposed MUs in your analysis file.
  2. Enter/select a MU Number in/from the dropdown list. For example, if you want to plot the source for MU Number one enter 0 in the dropdown. If you want to plot the sources for MU Number one, two and three enter 0,1,2, in the dropdown. You can also set MU Number to \"all\" to plot the sources for all included MUs in the analysis file.
  3. Once you have clicked the Plot Source button, a pop-up plot will appear.
"},{"location":"GUI_basics/#plot-instanteous-discharge-rate","title":"Plot Instanteous Discharge rate","text":"
  1. Click the Plot IDR button in row eight and column one in the left side of the Plot Window, to plot the IDR of the MUs in your analysis file.
  2. Enter/select a MU Number in/from the dropdown list. For example, if you want to plot the IDR of MU Number one enter 0 in the dropdown. If you want to plot the IDR of MU Number one, two and three enter 0,1,2 in the dropdown. You can also set MU Number to \"all\" to plot the IDR of all included MUs in the analysis file.
  3. Once you have clicked the Plot IDR button, a pop-up plot will appear.
"},{"location":"GUI_basics/#plot-differential-derivation","title":"Plot Differential Derivation","text":"
  1. Click the Plot Derivation button in row four and column three in the right side of the Plot Window, to plot the differential derivation of the MUs in your analysis file.
  2. Specify the Configuration for the calculation first. You can choose from:
    • Single differential (Calculate single differential of raw signal on matrix rows)
    • Double differential(Calculate double differential of raw signal on matrix rows)
  3. Specify the respective Matrix Column you want to plot. You can choose one from the Matrix Column dropdown list.
  4. Once you have clicked the Plot Derivation button, a new pop-up plot appears.
"},{"location":"GUI_basics/#plot-motor-unit-action-potentials","title":"Plot Motor Unit Action Potentials","text":"
  1. Click the Plot MUAPs button in row five and column three in the right side of the Plot Window, you can plot the action potential of the MUs in your analysis file.
  2. Specify the Configuration for calculation first. You can choose from:
    • Monopolar
    • Single differential (Calculate single differential of raw signal on matrix rows)
    • Double differential(Calculate double differential of raw signal on matrix rows)
  3. Specify the respective MU Number you want to plot. You can choose one from the MU Number dropdown list.
  4. Specify the Timewindow of the plots. You can choose from the Timewindow dropdown list or enter any integer.
  5. Once you have clicked the Plot MUAPs button, a new pop-up plot appears.
"},{"location":"GUI_basics/#saving-your-analysis-file","title":"Saving Your Analysis File","text":"

Subsequently to analysing your emg-file in the openhdemg GUI, it is beneficial to save it. Otherwise, all changes will be lost when the GUI is closed.

  1. Click the Save File button in row two and column two in the left side of the main window.
  2. Specify a filename and a location and confirm! That's it!
"},{"location":"GUI_basics/#saving-your-analysis-results","title":"Saving Your Analysis Results","text":"

Some analyses included in the openhdemg GUI return values that are displayed in the Result Output of the GUI. Of course, you can simply copy-paste them, but it might be more convenient to directly save your analysis results. Additionally, all the values in the Results Output will be overwritten by new analyses or deleted in case of closing the GUI.

  1. click the Save Results button in row two and column two in the left side of the main window.
  2. Specify a location where to save the file and confirm. You can find the file there with the name of your analysis file.
"},{"location":"GUI_basics/#resetting-your-analysis","title":"Resetting Your Analysis","text":"

We all make mistakes! But, most likely, we are also able to correct them. In case you have made a mistake in the analysis of you emg-file in the openhdemg GUI, we have implemented a reset button for you. Click the Reset Analysis button in row eight and column two in the lef side of the main window to reset any analysis you previously performed since opening the GUI and inputting an analysis file. Your analysis file is reset to the original file and all the changes are discarded. So, no need to be perfect!

We hope you had fun! We are now at the end of describing the basic functions included in the openhdemg GUI. In case you need further clarification, don't hesitate to post a question in the openhdemg discussion section. Moreover, if you noticed an error that was not properly catched by the GUI, please file a bug report according to our guidelines (LINK). If you want to proceed to the advanced stuff now, take a look at the advanced tab on the left side of the webpage.

"},{"location":"GUI_basics/#more-questions","title":"More questions?","text":"

We hope that this tutorial was useful. If you need any additional information, do not hesitate to read the answers or ask a question in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

"},{"location":"GUI_intro/","title":"Graphical Interface","text":"

Welcome, to the openhdemg Graphical User Interface (GUI) introduction! The openhdemg GUI incorporates all relevant high-level functions of the openhdemg library. The GUI allows you to successfully perform High-Density Electromyography (HD-EMG) data anlysis without any programming skills required. Moreover, there is no downside to using the GUI even if you are an experienced programmer.

Let us shortly walk you through the main window of the GUI. An image of the starting page of the GUI is displayed below.

This is your starting point for every analysis. On the left hand side you can find all the entryboxes and buttons relevant for the analyses you want to perform. In the middle you can see the plotting canvas where plots of the HD-EMG data analysis are displayed. On the right hand side you can find information buttons leading you directly to more information, tutorials, and more. And, with a little swoosh of magic, the results window appears at the bottom of the GUI once an analysis is finished.

"},{"location":"GUI_intro/#specifying-an-analysis-file","title":"Specifying an analysis file","text":"
  1. In order to load file into the GUI, you first need to select something in the Type of file dropdown box at the top left corner. The available filetypes are:

    • OTB (.mat file exportable by OTBiolab+)
    • DEMUSE (.mat file used in DEMUSE)
    • OTB_REFSIG (Reference signal in the .mat file exportable by OTBiolab+)
    • OPENHDEMG (emgfile or reference signal stored in .json format)
    • CUSTOM (custom data from a .csv file)

    Each filetype corresponds to a distinct datatype that should match the file you want to analyse. So, select the Type of file corresponding to the type of your file.

  2. To actually load the file, click the Load File button and select the file you want to analyse. In case of occurence, follow the error messages and repeat this and the previos step.

  3. Once the file is successfully loaded, the specifications of the file you want to analyse will be displayed next to the Load File button.

"},{"location":"GUI_intro/#viewing-an-analysis-file","title":"Viewing an analysis file","text":"

It doesn't get any simpler than this! Once a file is successfully loaded as described above, you can click the View MUs button to plot/view your file. In the middle section of the GUI, a plot containing your data should appear.

In the two sections above, we described the two most rudimental functions in the GUI. To learn more about basic and more advanced analysis features of the GUI, check out the basic and advanced chapters.

"},{"location":"GUI_intro/#more-questions","title":"More questions?","text":"

We hope that this tutorial was useful. If you need any additional information, do not hesitate to read the answers or ask a question in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

"},{"location":"Quick-Start/","title":"Quick Start","text":"

Let's implement together, step-by-step, a script to analyse all the relevant motor units' (MUs) properties.

In particular, we will go through:

  1. Install opendemg
  2. Load a file
  3. Visualise the content of the file
  4. Edit the reference signal
  5. Remove unwanted MUs
  6. Analyse fundamental MUs properties
  7. Save the edited file and the results of the analysis
"},{"location":"Quick-Start/#1-install","title":"1. Install","text":"

openhdemg can be easily installed using pip:

pip install openhdemg\n

or conda:

conda install -c conda-forge openhdemg\n

Once the installation of openhdemg is succesfull, you can install all the required packages from the reqirements.txt file.

"},{"location":"Quick-Start/#2-load-a-file","title":"2. Load a file","text":"

Before calling the functions contained in the openhdemg library, we need to import it. This can be done as:

import openhdemg.library as emg\n

Great, we are now ready to exploit all the functionalities of the library!

In this example, we will use the sample file provided with openhdemg.

This can be simply loaded calling the function emg_from_samplefile.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n

emgfile is organised as a Python dictionary and contains different elements (which are labelled by keys).

For a full list of keys contained in the emgfile refer to the openfiles documentation.

Each element in the emgfile can be accessed as emgfile[\"element\"].

So, if we want to access, for example, the reference signal, we can use emgfile[\"REF_SIGNAL\"].

"},{"location":"Quick-Start/#3-visualise-the-content-of-the-file","title":"3. Visualise the content of the file","text":"

Now that we loaded the emgfile, we can inspect its content.

As we said above, there are different elements in the emgfile and we can visualise both their type and their content with 2 lines of code:

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Print type\nprint(type(emgfile[\"REF_SIGNAL\"]))\n# Print content\nprint(emgfile[\"REF_SIGNAL\"])\n\"\"\" Output\n<class 'pandas.core.frame.DataFrame'>\n              0\n0     -0.159466\n1     -0.139630\n2     -0.099957\n3     -0.080121\n4     -0.060284\n...         ...\n66555 -0.337994\n66556 -0.318158\n66557 -0.298321\n66558 -0.318158\n66559 -0.318158\n\"\"\"\n

As you can see from the printed output, the reference signal is contained in a pandas DataFrame with 1 column (column 0).

This is an extremely important information if you want to manipulate the content of the emgfile although it is outside the scope of this Quick-Start tutorial.

Apart from accessing the numerical values, we can also plot them.

In this case we are interested in visualising the MUs firing times together with the reference signal. This can be done with the function plot_mupulses.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Plot MUs firing times and ref signal\nemg.plot_mupulses(emgfile=emgfile)\n

Looks good, but I would rather have the MUs ordered by recruitment order and also with thinner lines!

We can do that with the function sort_mus and changing the parameters in plot_mupulses.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Sort MUs based on recruitment order\nemgfile = emg.sort_mus(emgfile=emgfile)\n# Plot MUs firing times and ref signal\nemg.plot_mupulses(emgfile=emgfile, linewidths=0.4)\n

Are you curious about the dicharge rate of the MUs? You can view that with the function plot_idr.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Sort MUs based on recruitment order\nemgfile = emg.sort_mus(emgfile=emgfile)\n# Plot MUs instantaneous discharge rate\nemg.plot_idr(emgfile=emgfile)\n

"},{"location":"Quick-Start/#4-edit-the-reference-signal","title":"4. Edit the reference signal","text":"

The MUs look quite good; however, the reference signal is a bit noisy and the offset is not to 0.

The noise can be removed filtering the reference signal with the function filter_refsig that, by default, applies a 4th order, zero-lag, low-pass Butterworth filter with a cutoff frequency of 15 Hz.

Instead, the offset can be removed with the function remove_offset that automatically detects the offset based on a number of samples at the beginning of the recording.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Sort MUs based on recruitment order\nemgfile = emg.sort_mus(emgfile=emgfile)\n# Filter the ref signal\nemgfile = emg.filter_refsig(emgfile=emgfile)\n# Remove the offset based on the first 1024 samples (that corresponds to 0.5\n# seconds when sampling the signal at 2048 Hz).\nemgfile = emg.remove_offset(emgfile=emgfile, auto=1024)\n# Plot MUs instantaneous discharge rate\nemg.plot_idr(emgfile=emgfile)\n

"},{"location":"Quick-Start/#5-remove-unwanted-mus","title":"5. Remove unwanted MUs","text":"

There might be cases in which we need to remove one or more MUs from our emgfile.

From the visual inspection of our plots, we can see that the firings pattern of MU number 2 (remember, Python is in base 0!!!) is not really regular. We might therefore have doubts about its quality.

A way to assess the quality of the MUs is to look at the separation between the signal and the noise. This is efficiently measured by the silouette (SIL) score.

This score is automatically calculated while importing the emgfile and can be easily accessed as emgfile[\"SIL\"].

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Print the SIL score\nprint(emgfile[\"SIL\"])\n\"\"\"Output\n          0\n0  0.899082\n1  0.919601\n2  0.879079\n3  0.917190\n4  0.955819\n\"\"\"\n

Our suspicion was right, MU number 2 has the lowest SIL score.

In order to remove this MU, we can use the function delete_mus.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Sort MUs based on recruitment order\nemgfile = emg.sort_mus(emgfile=emgfile)\n# Filter the ref signal\nemgfile = emg.filter_refsig(emgfile=emgfile)\n# Remove the offset based on the first 1024 samples (that corresponds to 0.5\n# seconds when sampling the signal at 2048 Hz).\nemgfile = emg.remove_offset(emgfile=emgfile, auto=1024)\n# Remove MU number 2\nemgfile = emg.delete_mus(emgfile=emgfile, munumber=2)\n# Plot MUs instantaneous discharge rate\nemg.plot_idr(emgfile=emgfile)\n

"},{"location":"Quick-Start/#6-analyse-fundamental-mus-properties","title":"6. Analyse fundamental MUs properties","text":"

Now that we removed the unwanted MUs and adjusted the reference signal, we can proceed with the analysis of some fundamental MUs properties like the thresholds of recruitment and derecruitment and the discharge rate.

In the past, this used to require many lines of code, but thanks to openhdemg, we can now do that with 1 line of code using the function basic_mus_properties.

After calling the function basic_mus_properties, the user will be asked to select the start and the end of the steady-state phase. This can be done positioning the mouse on the desired point and then pressing a keybord key (such as 'a'). To remove points, right click with your mouse.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Sort MUs based on recruitment order\nemgfile = emg.sort_mus(emgfile=emgfile)\n# Filter the ref signal\nemgfile = emg.filter_refsig(emgfile=emgfile)\n# Remove the offset based on the first 1024 samples (that corresponds to 0.5\n# seconds when sampling the signal at 2048 Hz).\nemgfile = emg.remove_offset(emgfile=emgfile, auto=1024)\n# Remove MU number 2\nemgfile = emg.delete_mus(emgfile=emgfile, munumber=2)\n# Calculate all the basic MUs propertis.\n# Specify maximum voluntary contraction in Newtons.\nresults = emg.basic_mus_properties(\nemgfile=emgfile,\nmvc=634,\n)\nprint(results)\n\"\"\"\n     MVC  MU_number        PNR    avg_PNR       SIL   avg_SIL      abs_RT  \\\n0  634.0          0  27.480307  29.877575  0.899082  0.922923   30.621759\n1    NaN          1  28.946493        NaN  0.919601       NaN   32.427026\n2    NaN          2  28.640680        NaN  0.917190       NaN   68.371911\n3    NaN          3  34.442821        NaN  0.955819       NaN  118.504004\n     abs_DERT     rel_RT   rel_DERT    DR_rec  DR_derec  DR_start_steady  \\\n0   36.168135   4.829930   5.704753  7.548770  5.449581        11.788779\n1   31.167703   5.114673   4.916041  8.344515  5.333535        11.254445\n2   67.308703  10.784213  10.616515  5.699017  3.691367         9.007505\n3  102.761472  18.691483  16.208434  5.701081  4.662196         7.393645\n   DR_end_steady  DR_all_steady     DR_all  COVisi_steady  COVisi_all  \\\n0      10.401857      11.154952  10.693076       6.833642   19.104306\n1       9.999033      10.751960  10.543011       8.364553   15.408739\n2       7.053079       8.168471   7.949294      10.097045   23.324503\n3       6.430807       6.908502   6.814687      11.211862   16.319474\n   COV_steady\n0    1.422424\n1         NaN\n2         NaN\n3         NaN\n\"\"\"\n
"},{"location":"Quick-Start/#7-save-the-results-and-the-edited-file","title":"7. Save the results and the edited file","text":"

It looks like we got a lot of results, which makes it extremely inefficient to copy them manually.

Obviously, this can be automated using one attribute of the results object and we can conveniently save all the results in a .csv file.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Sort MUs based on recruitment order\nemgfile = emg.sort_mus(emgfile=emgfile)\n# Filter the ref signal\nemgfile = emg.filter_refsig(emgfile=emgfile)\n# Remove the offset based on the first 1024 samples (that corresponds to 0.5\n# seconds when sampling the signal at 2048 Hz).\nemgfile = emg.remove_offset(emgfile=emgfile, auto=1024)\n# Remove MU number 2\nemgfile = emg.delete_mus(emgfile=emgfile, munumber=2)\n# Calculate all the basic MUs propertis.\n# Specify maximum voluntary contraction in Newtons.\nresults = emg.basic_mus_properties(\nemgfile=emgfile,\nmvc=634,\n)\n# Save the results to a .csv file.\n# Remember to change this path to a real path!\nresults.to_csv(\"C:/Users/.../Desktop/Results.csv\")\n

Our results are now safe but, additionally, we might want to save also the emgfile with all the changes that we made. This can be easily done with the function asksavefile that will save your emgfile in the open standard JSON file format which has a better integration with Python and has a very high cross-platform compatibility.

# Import the library with the short name 'emg'\nimport openhdemg.library as emg\n# Load the sample file\nemgfile = emg.emg_from_samplefile()\n# Sort MUs based on recruitment order\nemgfile = emg.sort_mus(emgfile=emgfile)\n# Filter the ref signal\nemgfile = emg.filter_refsig(emgfile=emgfile)\n# Remove the offset based on the first 1024 samples (that corresponds to 0.5\n# seconds when sampling the signal at 2048 Hz).\nemgfile = emg.remove_offset(emgfile=emgfile, auto=1024)\n# Remove MU number 2\nemgfile = emg.delete_mus(emgfile=emgfile, munumber=2)\n# Calculate all the basic MUs propertis.\n# Specify maximum voluntary contraction in Newtons.\nresults = emg.basic_mus_properties(\nemgfile=emgfile,\nmvc=634,\n)\n# Save the results to a .csv file.\n# Remember to change this path to a real path!\nresults.to_csv(\"C:/Users/.../Desktop/Results.csv\")\n# Save the edited emgfile\nemg.asksavefile(emgfile=emgfile)\n
"},{"location":"Quick-Start/#8-important-notes","title":"8. Important notes","text":"

As you have seen, openhdemg makes it really easy to analyse MUs properties but please, don't think that what you saw in this tutorial is all you can do with this powerful framework.

We invite you to read the API reference section to understand how you can customise all the functions present in the library.

"},{"location":"What%27s-New/","title":"What's New","text":"

0.1.0-beta.1 \u00a0 June 2023

What's new? Well, everything. This is our firt release, if you are using it, congratulations, you are a pioneer!

Please note, this is a beta release, which means that a lot can change in this version and the library is not yet ready to be used without double-checking the results that you get.

"},{"location":"tutorials/Setup_working_env/","title":"Setup working environment","text":""},{"location":"tutorials/Setup_working_env/#introduction","title":"Introduction","text":"

Welcome to the tutorial on setting up your working environment.

This is the first step necessary to start using openhdemg, both if you want to use the library's functions and develop your scripts, or if you only want to use the graphical user interface (GUI).

The working environment refers to the set of resources necessary to carry out a particular task or job. In the context of this tutorial, we refer to the combination of a computer, a programming language, an integrated development environment and a set of algorithms.

In order to use openhdemg, we will install the following:

  • Programming language: Python 3
  • Integrated development environment: Visual Studio Code
  • Set of algorithms: openhdemg

Python 3 is a powerful and versatile programming language known for its simplicity, readability, and extensive library support. With a focus on code readability, Python allows developers to express concepts in fewer lines of code compared to other programming languages. It is widely used for web development, scientific computing, data analysis, artificial intelligence, and more.

The integrated development environment is a software that facilitates to write, test, and debug code. In this tutorial we will use Visual Studio Code (VS Code), a popular code editor that provides a seamless experience for Python programming.

By following the steps outlined in this tutorial, you will be able to install Python, set up VS Code, and configure your environment to write clean and efficient Python code.

"},{"location":"tutorials/Setup_working_env/#install-python-and-vs-code-on-windows","title":"Install Python and VS Code on Windows","text":"

To install Python 3 on Windows:

  1. Visit the official Python website: https://www.python.org/downloads/
  2. Click on the \"Downloads\" tab.
  3. Scroll down to the section titled \"Python Releases for Windows.\"
  4. Click on the \"Download\" button for the latest version of Python (e.g., Python 3.11.4).
  5. Run the downloaded installer.
  6. On the installer, make sure to check the box \"Add Python to PATH\" and then click \"Install Now.\"
  7. Python will be installed to your system (optionally, you can verify the installation by opening a command prompt and typing python --version).

To install VS Code on Windows:

  1. Visit the official Visual Studio Code website: https://code.visualstudio.com/
  2. Click on the \"Download for Windows\" button.
  3. Once the download is complete, run the installer.
  4. Follow the instructions on the installer to complete the installation.
  5. Visual Studio Code will be installed to your system.
"},{"location":"tutorials/Setup_working_env/#install-python-and-vs-code-on-mac","title":"Install Python and VS Code on Mac","text":"

To install Python 3 on Mac:

  1. Visit the official Python website: https://www.python.org/downloads/
  2. Click on the \"Downloads\" tab.
  3. Scroll down to the section titled \"Python Releases for macOS.\"
  4. Click on the \"Download\" button for the latest version of Python (e.g., Python 3.11.4).
  5. Run the downloaded installer package.
  6. Follow the instructions on the installer to complete the installation.
  7. Python will be installed to your system. (optionally, you can verify the installation by opening a terminal and typing python3 --version).

To install VS Code on Mac:

  1. Visit the official Visual Studio Code website: https://code.visualstudio.com/
  2. Click on the \"Download for Mac\" button.
  3. Once the download is complete, open the downloaded .dmg file.
  4. Drag and drop the Visual Studio Code application into the \"Applications\" folder.
  5. Visual Studio Code will be installed to your system.
"},{"location":"tutorials/Setup_working_env/#configure-vs-code-for-python","title":"Configure VS Code for Python:","text":"

Now that VS Code is installed, you need to set it up to code in Python and to install openhdemg:

  1. Open Visual Studio Code.
  2. Install the \"Python\" extension by Microsoft. To do so, click on the Extensions view on the left sidebar, search for \"Python\" in the search bar, and click the \"Install\" button next to the \"Python\" extension by Microsoft.

Once the extension is installed, you need to create a folder where you will palce all the scripts that you will write. You can create this folder with any name an in any location in your computer, but make it simple to find! In this tutorial the folder was placed in the Desktop and named Test_folder.

Once the folder is created:

  1. In VS Code click on 'File' and then on 'Add Folder to Workspace'.
  2. In VS Code click on 'Terminal' and then on 'New Terminal'.
  3. Select your folder in the window that pops up.

With your powershell terminal that is pointing to your folder path, you can now create a Virtual environment.

"},{"location":"tutorials/Setup_working_env/#create-a-virtual-environment","title":"Create a Virtual environment","text":"

The Virtual environments provide an isolated and controlled environment for your Python projects, allowing you to manage project-specific dependencies effectively.

In order to create a virtual environment type in your terminal:

For Windows users:

python -m venv myvenv\n

For Mac users:

python3 -m venv myvenv  

This command will create a Virtual environment named myvenv.

To activate myvenv type in the terminal:

For Windows users:

myvenv/Scripts/Activate   

For Mac users:

source myvenv/bin/activate  

If everything was successful, you should see the colourful name of your Virtual environment to the left of your folder path (as in the figure above).

Great! You are all set up to install and use openhdemg.

"},{"location":"tutorials/Setup_working_env/#install-and-use-openhdemg","title":"Install and use openhdemg","text":"

Now, installing openhdemg is super simple. Just type in the terminal:

pip install openhdemg 

openhdemg will be installed. Once the installation process is completed, you will see in the terminal the message Successfully installed openhdemg.

If you want to use the GUI, type in the terminal:

python -m openhdemg.gui.openhdemg_gui\n

And the GUI will start:

If you instead want to write your own script using the functions contained in openhdemg, follow these steps:

  1. click on the Explorer view on the left sidebar.
  2. Click on the icon to create a new file in your workspace folder (Test_folder in this case).
  3. Name the file as you wish but wit a .py extension.

Now you can open your .py file, write your code and execute it.

"},{"location":"tutorials/Setup_working_env/#troubleshooting","title":"Troubleshooting","text":""},{"location":"tutorials/Setup_working_env/#python-installation-issues","title":"Python Installation Issues","text":"

Windows:

  • Make sure you are running the installer with administrative privileges.
  • Verify that the downloaded Python installer matches the architecture of your Windows system (32-bit or 64-bit).
  • If the installation fails, try downloading a different version of Python from the official Python website.

macOS:

  • Ensure you have the necessary permissions to install software on your Mac.
  • If the installation fails, try using a package manager like Homebrew to install Python instead. Instructions for Homebrew installation can be found on the Homebrew website.
"},{"location":"tutorials/Setup_working_env/#issues-in-the-activation-of-the-virtual-environment","title":"Issues in the activation of the Virtual environment","text":"

Windows:

If trying to activate the Virtual environment you see this (or a similar) message in the terminal:

the execution of scripts is disabled on this system\n

the problem might be due to the Execution Policy Settings that are too restrictive and do not allow you to execute scripts. This problemm can be solved with the following steps:

  1. Go to the Windos search bar.
  2. Type PowerShell and open it as Administrator.
  3. In the new PowerShell type:
Set-ExecutionPolicy Unrestricted -Force\n

This should solve the issue and you should now be able to activate your Virtual environment. For additional information on this topic visit the stackoverflow thread.

"},{"location":"tutorials/Setup_working_env/#more-questions","title":"More questions?","text":"

We hope that this tutorial was useful. If you need any additional information, do not hesitate to read the answers or ask a question in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..0f8724e --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 0000000..fdf3334 Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/tutorials/Setup_working_env/activated_venv.png b/tutorials/Setup_working_env/activated_venv.png new file mode 100644 index 0000000..8678055 Binary files /dev/null and b/tutorials/Setup_working_env/activated_venv.png differ diff --git a/tutorials/Setup_working_env/add_folder_toworks.png b/tutorials/Setup_working_env/add_folder_toworks.png new file mode 100644 index 0000000..6870656 Binary files /dev/null and b/tutorials/Setup_working_env/add_folder_toworks.png differ diff --git a/tutorials/Setup_working_env/create_newfile.png b/tutorials/Setup_working_env/create_newfile.png new file mode 100644 index 0000000..46dff79 Binary files /dev/null and b/tutorials/Setup_working_env/create_newfile.png differ diff --git a/tutorials/Setup_working_env/first_script.png b/tutorials/Setup_working_env/first_script.png new file mode 100644 index 0000000..d5c5082 Binary files /dev/null and b/tutorials/Setup_working_env/first_script.png differ diff --git a/tutorials/Setup_working_env/index.html b/tutorials/Setup_working_env/index.html new file mode 100644 index 0000000..9ab1614 --- /dev/null +++ b/tutorials/Setup_working_env/index.html @@ -0,0 +1,967 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + Setup working environment - openhdemg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + +
+
+
+ + + + + + + +
+
+ + + + + + + +

Setup working environment

+ +

Introduction

+

Welcome to the tutorial on setting up your working environment.

+

This is the first step necessary to start using openhdemg, both if you want to use the library's functions and develop your scripts, or if you only want to use the graphical user interface (GUI).

+

The working environment refers to the set of resources necessary to carry out a particular task or job. In the context of this tutorial, we refer to the combination of a computer, a programming language, an integrated development environment and a set of algorithms.

+

In order to use openhdemg, we will install the following:

+
    +
  • Programming language: Python 3
  • +
  • Integrated development environment: Visual Studio Code
  • +
  • Set of algorithms: openhdemg
  • +
+

Python 3 is a powerful and versatile programming language known for its simplicity, readability, and extensive library support. With a focus on code readability, Python allows developers to express concepts in fewer lines of code compared to other programming languages. It is widely used for web development, scientific computing, data analysis, artificial intelligence, and more.

+

The integrated development environment is a software that facilitates to write, test, and debug code. In this tutorial we will use Visual Studio Code (VS Code), a popular code editor that provides a seamless experience for Python programming.

+

By following the steps outlined in this tutorial, you will be able to install Python, set up VS Code, and configure your environment to write clean and efficient Python code.

+

vscode_overview

+

Install Python and VS Code on Windows

+

To install Python 3 on Windows:

+
    +
  1. Visit the official Python website: https://www.python.org/downloads/
  2. +
  3. Click on the "Downloads" tab.
  4. +
  5. Scroll down to the section titled "Python Releases for Windows."
  6. +
  7. Click on the "Download" button for the latest version of Python (e.g., Python 3.11.4).
  8. +
  9. Run the downloaded installer.
  10. +
  11. On the installer, make sure to check the box "Add Python to PATH" and then click "Install Now."
  12. +
  13. Python will be installed to your system (optionally, you can verify the installation by opening a command prompt and typing python --version).
  14. +
+

To install VS Code on Windows:

+
    +
  1. Visit the official Visual Studio Code website: https://code.visualstudio.com/
  2. +
  3. Click on the "Download for Windows" button.
  4. +
  5. Once the download is complete, run the installer.
  6. +
  7. Follow the instructions on the installer to complete the installation.
  8. +
  9. Visual Studio Code will be installed to your system.
  10. +
+

Install Python and VS Code on Mac

+

To install Python 3 on Mac:

+
    +
  1. Visit the official Python website: https://www.python.org/downloads/
  2. +
  3. Click on the "Downloads" tab.
  4. +
  5. Scroll down to the section titled "Python Releases for macOS."
  6. +
  7. Click on the "Download" button for the latest version of Python (e.g., Python 3.11.4).
  8. +
  9. Run the downloaded installer package.
  10. +
  11. Follow the instructions on the installer to complete the installation.
  12. +
  13. Python will be installed to your system. (optionally, you can verify the installation by opening a terminal and typing python3 --version).
  14. +
+

To install VS Code on Mac:

+
    +
  1. Visit the official Visual Studio Code website: https://code.visualstudio.com/
  2. +
  3. Click on the "Download for Mac" button.
  4. +
  5. Once the download is complete, open the downloaded .dmg file.
  6. +
  7. Drag and drop the Visual Studio Code application into the "Applications" folder.
  8. +
  9. Visual Studio Code will be installed to your system.
  10. +
+

Configure VS Code for Python:

+

Now that VS Code is installed, you need to set it up to code in Python and to install openhdemg:

+
    +
  1. Open Visual Studio Code.
  2. +
  3. Install the "Python" extension by Microsoft. To do so, click on the Extensions view on the left sidebar, search for "Python" in the search bar, and click the "Install" button next to the "Python" extension by Microsoft.
  4. +
+

python_extension

+

Once the extension is installed, you need to create a folder where you will palce all the scripts that you will write. You can create this folder with any name an in any location in your computer, but make it simple to find! In this tutorial the folder was placed in the Desktop and named Test_folder.

+

Once the folder is created:

+
    +
  1. In VS Code click on 'File' and then on 'Add Folder to Workspace'.
  2. +
  3. In VS Code click on 'Terminal' and then on 'New Terminal'.
  4. +
  5. Select your folder in the window that pops up.
  6. +
+

add_folder_toworks

+

With your powershell terminal that is pointing to your folder path, you can now create a Virtual environment.

+

Create a Virtual environment

+

The Virtual environments provide an isolated and controlled environment for your Python projects, allowing you to manage project-specific dependencies effectively.

+

In order to create a virtual environment type in your terminal:

+

For Windows users: +

python -m venv myvenv
+

+

For Mac users: +

python3 -m venv myvenv  
+

+

venv_command

+

This command will create a Virtual environment named myvenv.

+

To activate myvenv type in the terminal:

+

For Windows users: +

myvenv/Scripts/Activate   
+

+

For Mac users: +

source myvenv/bin/activate  
+

+

activated_venv

+

If everything was successful, you should see the colourful name of your Virtual environment to the left of your folder path (as in the figure above).

+

Great! You are all set up to install and use openhdemg.

+

Install and use openhdemg

+

Now, installing openhdemg is super simple. Just type in the terminal:

+
pip install openhdemg 
+
+

openhdemg will be installed. Once the installation process is completed, you will see in the terminal the message Successfully installed openhdemg.

+

If you want to use the GUI, type in the terminal:

+
python -m openhdemg.gui.openhdemg_gui
+
+

And the GUI will start:

+

openhdemg GUI

+

If you instead want to write your own script using the functions contained in openhdemg, follow these steps:

+
    +
  1. click on the Explorer view on the left sidebar.
  2. +
  3. Click on the icon to create a new file in your workspace folder (Test_folder in this case).
  4. +
  5. Name the file as you wish but wit a .py extension.
  6. +
+

create_newfile

+

Now you can open your .py file, write your code and execute it.

+

first_script

+

Troubleshooting

+

Python Installation Issues

+

Windows:

+
    +
  • Make sure you are running the installer with administrative privileges.
  • +
  • Verify that the downloaded Python installer matches the architecture of your Windows system (32-bit or 64-bit).
  • +
  • If the installation fails, try downloading a different version of Python from the official Python website.
  • +
+

macOS:

+
    +
  • Ensure you have the necessary permissions to install software on your Mac.
  • +
  • If the installation fails, try using a package manager like Homebrew to install Python instead. Instructions for Homebrew installation can be found on the Homebrew website.
  • +
+

Issues in the activation of the Virtual environment

+

Windows:

+

If trying to activate the Virtual environment you see this (or a similar) message in the terminal:

+
the execution of scripts is disabled on this system
+
+

the problem might be due to the Execution Policy Settings that are too restrictive and do not allow you to execute scripts. This problemm can be solved with the following steps:

+
    +
  1. Go to the Windos search bar.
  2. +
  3. Type PowerShell and open it as Administrator.
  4. +
  5. In the new PowerShell type:
  6. +
+
Set-ExecutionPolicy Unrestricted -Force
+
+

This should solve the issue and you should now be able to activate your Virtual environment. For additional information on this topic visit the stackoverflow thread.

+

More questions?

+

We hope that this tutorial was useful. If you need any additional information, do not hesitate to read the answers or ask a question in the openhdemg discussion section. If you are not familiar with GitHub discussions, please read this post. This will allow the openhdemg community to answer your questions.

+ + + + + + +
+
+ + +
+ +
+ +
+ + +
+ +
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/tutorials/Setup_working_env/python_extension.png b/tutorials/Setup_working_env/python_extension.png new file mode 100644 index 0000000..9735362 Binary files /dev/null and b/tutorials/Setup_working_env/python_extension.png differ diff --git a/tutorials/Setup_working_env/venv_command.png b/tutorials/Setup_working_env/venv_command.png new file mode 100644 index 0000000..e1d3542 Binary files /dev/null and b/tutorials/Setup_working_env/venv_command.png differ diff --git a/tutorials/Setup_working_env/vscode_overview.png b/tutorials/Setup_working_env/vscode_overview.png new file mode 100644 index 0000000..0f10c4d Binary files /dev/null and b/tutorials/Setup_working_env/vscode_overview.png differ diff --git a/yml_graphics/Transp_Icon.png b/yml_graphics/Transp_Icon.png new file mode 100644 index 0000000..c1228cd Binary files /dev/null and b/yml_graphics/Transp_Icon.png differ