Coder Social home page Coder Social logo

physiopy / phys2denoise Goto Github PK

View Code? Open in Web Editor NEW
9.0 4.0 19.0 215 KB

A collection of scripts to prepare physiology data for fMRI denoise

Home Page: https://phys2denoise.readthedocs.io/

License: Apache License 2.0

Python 99.55% Makefile 0.45%
hacktoberfest closember

phys2denoise's Introduction

physiopy

Requirements Status

Metapackage for physiopy repository

phys2denoise's People

Contributors

cesarcaballerogaudes avatar eril892 avatar erwinschrodinger1 avatar ineschh avatar kristinazvolanek avatar maestroque avatar me-pic avatar pre-commit-ci[bot] avatar raystick avatar rzlim08 avatar smoia avatar tomaslenc avatar tsalo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

phys2denoise's Issues

Design strategy

In our monthly developers call, we discussed how we'd like phys2denoise to be structured (along with the other packages). Here are the minutes for anyone who's interested.

There were a few ideas that were discussed. Some of these ideas have broad implications for the whole suite, and, if we decide to go with one of those, then we can figure out how to synchronize package-specific discussions within the suite.

  1. phys2denoise operates on a shared object with peakdet. This class would represent physio data from a single frequency, and could end up being restricted to a single channel.
    • Pros:
      1. Classes group attributes (e.g., the time series and the sampling rate) together.
      2. peakdet will need its own class to track changes to the data. While we don't need that same functionality in phys2denoise, it's helpful to have the same design philosophy across packages.
    • Cons:
      1. We would need to either (1) duplicate our class definition across peakdet and phys2denoise or (2) define the class in one package and then manage changes to the class across both.
      2. For "higher level" users, who want to use the individual functions, having to initialize or operate on a new object for their data (instead of a common one like a numpy array or a pandas DataFrame) will make it harder for them to start using the package.
      3. Mocking up package-specific objects for tests is hard and those objects can add overhead to your CI.
  2. phys2denoise's object is moved all the way up to physutils. Same pros and cons as the above, but with additional difficulties in synchronizing the class definition across packages.
  3. A purely functional approach. All functions in phys2denoise would operate on arrays or possibly DataFrames, with no package-specific classes defined.
    • Pros:
      1. This makes the individual functions easier to work with.
      2. Most users will only interact with the main workflow function/CLI, so the internal structure of the function is not important (i.e., classes are not necessary).
      3. Functions are easier to test.
    • Cons:
      1. Devs who get used to OOP in peakdet and phys2bids might be confused by phys2denoise, although the opposite is more likely, since functional programming is more intuitive.

If anyone has other ideas, please comment and I can update this issue summary.

Logo for phys2denoise

At the moment phys2denoise uses the general physiopy logo.
However, we can have a tailored one, like phys2bids does!
It would be nice if it's based on the general logo though.

Tagging @danalclop since he already worked on the other logos.

Possible Implementation

Take the general physiopy logo here and experiment with new ideas! There are examples and other versions here

Add BIDS support to the main workflow

Our current plan for the workflow is to make it non-BIDS-specific (i.e., generic inputs and outputs), but we do want to support BIDS as an option.

Detailed Description

We will want to (1) add a --bids flag to the workflow, (2) add functions to ingest BIDS data and metadata, and (3) add the ability to generate BIDS-compatible derivatives. Thankfully, all three elements should be pretty straightforward, as confound timeseries are well established in fMRIPrep.

Context / Motivation

This will make it easier to apply phys2denoise in conjunction with other BIDS Apps. We can even make it easier to merge our outputs with fMRIPrep outputs so users don't need to do any additional work to get physio confounds.

Possible Implementation

Script metric call in workflow

Long story short:

  • we have a bunch of metrics to call in the main workflow (see #4 and #7 for examples)
  • we are going to ask the user to state which metric they want to compute using non-argument flags (see #14 for implementation)
  • we could make a long list of if metric_list contains metric then metric(args) to call each metric
  • HOWEVER, such list might grow exponentially (who knows how much)
  • a much tidier approach is to do something pythonic: for metric in metric_list do metric(args)
  • HOWEVER, each metric has different arguments in input
  • HOWEVER, we can add **kwarg to all the metric calls so that we always pass all arguments without thinking about it too much, and those arguments that are not used will just be ignored (see example below)

What do you think @eurunuela @tsalo @62442katieb @CesarCaballeroGaudes @ineschh?

In [1]: def hello(you='meh', age='42', **kwargs):                                                                                               
   ...:     print(f'Hi {you}, of age {age}')                                                                                                    
   ...: 
                                                                                                                                                
In [2]: hello(you='Arthur')                                                                                                                     
Hi Arthur, of age 42                                                                                                                            

In [3]: hello(you='Rick', age='46')                                                                                                             
Hi Rick, of age 46                                                                                                                              

In [4]: hello(you='Rick', age='46', blubba='bla')                                                                                               
Hi Rick, of age 46   

Requested metric: cardiac pulsatility model

The cardiac pulsatility model (CPM) is a set of denoising regressors derived from PPG data and proposed in Kassinopoulos and Mitsis (2020).

Detailed Description

This metric is an adapted version of the RETROICOR regressors and MATLAB code can be found in mkassinopoulos/Noise_modeling_based_on_PPG.

Context / Motivation

I haven't dug into the code or preprint in too much detail, but according to the abstract the CPM model outperforms RETROICOR, so it could be useful.

Possible Implementation

We can probably translate the MATLAB code directly, as long as we integrate the original repo's license info (which we will probably need to request).

Requested metric: respiratory variance

Respiratory variance (RV) is, like RVT, used to measure variability of the respiratory trace. This regressor, especially when convolved with a respiratory response function (RRF), can be used to denoise fMRI data.

Per Power et al. (2018) (appendix):

Second, the RV (respiratory variance) measure was created from the standard deviation of the respiratory trace within a 6-second window (following (7)), and this trace was lagged back 3 seconds and forward 3 seconds to create 3 regressors, and each of these regressors was convolved with the RRF defined above for a total of 6 respiratory regressors.

Improved RVT calculation with Hilbert transform

Harrison et al. (2020) proposes a new filtering approach when calculating respiration-based metrics (especially respiratory volume per unit time [RVT]) that is supposedly better able to capture atypical breathing (e.g., deep breaths). While it's just a preprint, I think it's worth looking into this method to see if it's worth supporting in phys2denoise.

Here are the details of the algorithm, taken from the manuscript:

  1. PhysIO preprocessing: Remove low frequency drifts (less than 0.01 Hz) from the breathing signal, and remove high-frequency noise above 2.0 Hz. This version of the breathing signal is used for both RETROICOR and the peak-based RVT estimate in the physiological pipelines used in the Results section. This is the raw trace shown in Panel (a) of Figure 3.
  2. Lowpass filter the data again to more aggressively remove high-frequency noise above 0.75 Hz. This is the raw trace shown in Figure 1.
  3. Decompose the signal into magnitude and phase components via the Hilbert transform.
  4. Linearly interpolate any periods where the phase time course decreases, using the procedure in Figure 2, to remove any artefactual negative frequencies. Reconstruct the oscillatory portion of the signal, cos(๐œ™(๐‘ก)), and lowpass filter at 0.75 Hz to remove any resulting artefacts. This procedure is repeated 10 times, with the new phase timecourse re- estimated from the filtered oscillatory signal.
  5. Calculate RV and low-pass filter the signal magnitude at 0.2 Hz to remove within-cycle fluctuations. Instantaneous breathing frequency is the numerical derivative of the phase timecourse, filtered as above. Finally, estimates are thresholded to remove physiologically implausible values.

Add general, report, and reference loggers

Per GatherTown convo, we want to take tedana's approach to loggers and use it here.

Detailed Description

We want three loggers: (1) a general one that prints to the console, (2) a report logger for building a copy/pastable methods section, and (3) a references logger that collects the bibliography for the report logger. The latter two get merged together and outputted in both the interactive report (if we make one) and a report file at the end of the workflow.

Context / Motivation

The report/references logging will build a citable workflow description for users to add directly to their manuscripts.

Possible Implementation

Let's just steal tedana's approach.

phys2denoise 1.0

@physiopy/all , I'm opening this issue so that we can start tracking the development of phys2denoise, but especially so that we can decide what do we expect from it before promoting it out of testing stages.

Please feel free to add ideas and start a discussion!

Implement Loguru for better logging

So far we're adopting basic logging - 95% of the time that's ok, but for instance the logs are not catching errors, which is annoying for bugfixes.

Loguru might offer a solution, at a very small dependency cost - especially if not on Windows (otherwise two small dependencies more to deal with their terminal).

I think it'd be neat to implement it!

Typo: requirements.txt

I was preparing for GSOC 2024. To get idea of the codebase I was trying to run a source code and solve the issue #48. But while installing the requirements file using
pip install -r .\requirements.txt
I got
image
this issue.
It is a simple typo. The space highlighted is causing the error.
image

Possible solution

It can be solved by just removing that highligted space in line 2 of requirements.txt

Travis config file in repo

Summary

I see we still have a configuration file for Travis in the repo. We have to remove it if we're going to use Circle CI.

  • Open a PR that removes the config file.

phys2denoise noncompetitive code sprint

This is a reminder for the code sprint we discussed during the last community meeting, taking place on the 25th and 26th of February from 9AM EST / 15.00 CET to 13AM EST / 19.00 CET.

We'll meet in GatherTown, here. The password to enter the space will be provided via Brainhack mattermost (~physiopy channel).

Build citable report as part of main workflow

The main workflow for phys2denoise should (I believe) run a set of functions on a physio object, and should output the associated confounds in a BIDS Derivatives-compatible format. We can also build a citable report as those functions are run, just like tedana.

OHBM 2021 abstract submission

This is related to physiopy/phys2bids#380.

OHBM abstract submission deadline is close, and if we submit two abstracts, one would be for phys2denoise.
However, that means pulling together and closing all these PRs we have open. I was thinking we could meet and do a sort of code sprint of one day before the 1st of February? Who would be in for that, @physiopy/all?

I'd be happy to take care of writing this abstract (also possible to do multiple authors)!

Requested metric: respiratory-volume-per-time

Respiratory-volume-per-time (RVT) is a "breath-to-breath metric of respiratory variation," and can be used to generate a regressor for denoising fMRI data.

Per Chang and Glover (2009):

First, peak detection was used to determine the maximum and minimum for each breath. The time series of maxima and minima (max(t) and min(t)) were then interpolated to the imaging TR. A time series of the breathing period (T(t)) was determined by taking the time difference between successive maxima, assigning the resulting value to the midpoint between the successive maxima, and interpolating the resulting time series to the imaging TR. The final RVT time series was then computed as RVT(t) = (max(t) โˆ’ min(t))/T(t).

A relevant metric is RPV convolved with a respiratory response function:

In addition, RVT(t) was convolved with the RRF (Birn et al., 2008), forming a separate waveform (RVT*RRF(t)).

RVT*RRF is also often lagged when used to denoise fMRI data.

Allow YAML-based config file with input arguments from/for workflow

We want to add the ability to ingest and write out YAML-based config files when running the workflow.

Stems from #17 (comment) and GatherTown convo.

Detailed Description

Running the workflow will automatically write out a YAML file to the output directory with all arguments used in the original call. Users will also be able to feed in a --config-file argument that will take parameters from a YAML file and use them in the workflow call. Any manually specified arguments will override ones in the YAML file (perhaps with a warning?).

Context / Motivation

This will make it easier to re-run the workflow, as well as to run the workflow on many participants with limited variable hard-coding.

Possible Implementation

Support negative lags in RV calculation

Detailed Description

Currently, only positive lags are supported in RV calculation:

delays = [abs(int(lag * samplerate)) for lag in lags]

However, apply_lags() supports negative lags just fine.

Context / Motivation

I require this for an analysis, and there is no real cost. In fact, as it is implemented, it could be confusing for users.

Possible Implementation

I think it's pretty straightforward to fix:

    delays = [int(lag * samplerate) for lag in lags] 

Requested metric: respiratory pattern variability

Respiratory pattern variability (RPV) is a run-level metric created by in Power et al. (2018). The metric can also be calculated as a time series using a window, which in Power et al. (2019) is referred to as ENV.

Per Power et al. (2018):

To capture the variability of the respiratory patterns, the respiratory belt waveforms (which are in arbitrary units) were z-scored, the envelope of the resulting waveform was calculated, and the SD of this envelope was then calculated.

From Power et al. (2019):

These include respiration variation (RV), which is the standard deviation of the belt trace within a (6-s) window (Chang et al., 2009), the envelope of the respiratory trace (over a 10-s window, ENV) (Power et al., 2018), and the change in belt magnitude over a breath cycle (respiratory volume per time, RVT) (Birn et al., 2006).

Add visualisation of regressors

Detailed Description

Add a plot of each regressor computed by phys2denoise before the export.

Context / Motivation

Visualising the regressors is something important!

Possible Implementation

Using phys2bids.viz as an inspiration, output a plot with each regressor as subplot.
The first subplot should be the input.
Separating RETROICOR from everything else would be nice.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.