diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index cc40b34..e54cd61 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,78 +1,74 @@ -Contributor Covenant Code of Conduct +# Contributor Covenant Code of Conduct -Our Pledge +## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, sex characteristics, gender identity and expression, -level of experience, education, socio-economic status, nationality, personal -appearance, race, religion, or sexual identity and orientation. +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. -Our Standards +## Our Standards Examples of behavior that contributes to creating a positive environment include: - * Using welcoming and inclusive language * Being respectful of differing viewpoints and experiences * Gracefully accepting constructive criticism * Focusing on what is best for the community * Showing empathy towards other community members - Examples of unacceptable behavior by participants include: - * The use of sexualized language or imagery and unwelcome sexual attention or advances * Trolling, insulting/derogatory comments, and personal or political attacks * Public or private harassment -* Publishing others’ private information, such as a physical or electronic -address, without explicit permission +* Publishing others' private information, such as a physical or electronic + address, without explicit permission * Other conduct which could reasonably be considered inappropriate in a -professional setting - + professional setting -Our Responsibilities +## Our Responsibilities Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. -Scope +## Scope -This Code of Conduct applies within all project spaces, and it also applies when -an individual is representing the project or its community in public spaces. -Examples of representing a project or community include using an official -project e-mail address, posting via an official social media account, or acting -as an appointed representative at an online or offline event. Representation of -a project may be further defined and clarified by project maintainers. +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. -Enforcement +## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at imr.framework2018@gmail.com. All +reported by contacting the team at . All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other -members of the project’s leadership. +members of the project's leadership. -Attribution +## Attribution -This Code of Conduct is adapted from the Contributor Covenant, version 1.4, -available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] -For answers to common questions about this code of conduct, see -https://www.contributor-covenant.org/faq +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bf0e44b..96acfc0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,23 +1,30 @@ # Contributing to `pypulseq` :thumbsup: :tada: Thanks for taking time to contribute! :thumbsup: :tada: Here are guidelines (not rules!) for contributing to `pypulseq`. Use your best judgment, and feel free to propose changes to this document in a pull request. ## Table of contents 1. [Code of Conduct](#code-of-conduct) 2. [PEP Style Guide for Python coding](#style-guide-for-python-code) ## Code of Conduct This project and everyone participating in it is governed by the -[`pypulseq` Code of Conduct](https://github.com/imr-framework/pypulseq/blob/master/CODE_OF_CONDUCT.md). +[`pypulseq` Code of Conduct](code_of_conduct). By participating, you are expected to uphold this code. Please report unacceptable behavior to -[imr.framework2018@github.com](mailto:imr.framework2018@github.com). +[imr.framework2018@gmail.com](email). -## Style Guide for Python Code -Read through the [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) and follow the coding -conventions. If you notice any code not adhering to PEP8, submit a pull request or open an issue. +## Pull requests +Follow the coding conventions laid out in the [Style Guide for Python Code](style_guide). Ensure source code is +documented as per the Numpy convention [[numpy1]], [[numpy2]]. If you notice any `pypulseq` code not adhering to +[PEP8](style-guide), submit a pull request or open an issue. -## Documenting source code -As per the Numpy convention: check [this](https://numpydoc.readthedocs.io/en/latest/format.html) link, or -[this](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html). \ No newline at end of file +## Issues +Please adhere to the appropriate templates when reporting bugs or requesting features. The templates are automatically +presented via Github's 'New Issue' feature. + +[email]: mailto:imr.framework2018@gmail.com +[code_of_conduct]: https://github.com/imr-framework/pypulseq/blob/master/CODE_OF_CONDUCT.md +[style_guide]: https://www.python.org/dev/peps/pep-0008/ +[numpy1]: https://numpydoc.readthedocs.io/en/latest/format.html +[numpy2]: https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html \ No newline at end of file diff --git a/README.md b/README.md index a791c61..270d86c 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,88 @@

+# pypulseq +Pulseq in Python + Pulse sequence design is a significant component of MRI research. However, multi-vendor studies require researchers to be acquainted with each hardware platform's programming environment. `pypulseq` enables vendor-neutral pulse sequence design in Python [[1]](#references). The pulse sequences can be -exported as a `.seq` file to be run on Siemens/[GE](https://toppemri.github.io)/ -[Bruker](https://github.com/pulseq/bruker_interpreter) hardware by leveraging their respective Pulseq interpreters. -This tool is targeted at MR pulse sequence designers, MRI researchers and other interested users. It is a translation -of the Pulseq framework originally written in Matlab [[2]](#references). +exported as a `.seq` file to be run on Siemens/[GE](toppe)/[Bruker](bruker) hardware by leveraging their respective +Pulseq interpreters. This tool is targeted at MRI pulse sequence designers, researchers, students and other interested +users. It is a translation of the Pulseq framework originally written in Matlab [[2]](#references). -It is strongly recommended to first read the [Pulseq specification](https://pulseq.github.io/specification.pdf) -before proceeding. The specification document defines the concepts required for pulse sequence design using `pypulseq`. Checkout the [`pypulseq-gpi`](https://github.com/imr-framework/pypulseq/tree/pypulseq-gpi) branch to design pulse sequences on a GUI. +It is strongly recommended to first read the [Pulseq specification](pulseq-spec) before proceeding. The specification +document defines the concepts required for pulse sequence design using `pypulseq`. ## 1 minute demo 1. Clone this repository. -2. Run any of the example scripts in your favourite IDE on Python 3.6 or above. +2. `cd` into this repository (or set as working directory in an IDE). +2. Run any of the example scripts on Python 3.6 or above. 3. Inspect plots! -4. Get in touch regarding running the `.seq` files on your Siemens/GE/Bruker scanner. +?. Get in touch regarding running the `.seq` files on your Siemens/GE/Bruker scanner. ## Custom pulse sequences Getting started with pulse sequence design using `pypulseq` is simple: -1. `pip install pypulseq` on Python 3.6 or above. +1. `pip install pypulseq` in your virtual environment (>=Python 3.6). 2. First, define system limits in `Opts` and then create a `Sequence` object with it: ```python from pypulseq.opts import Opts from pypulseq.Sequence.sequence import Sequence system = Opts(max_grad=32, grad_unit='mT/m', max_slew=130, slew_unit='mT/m/s') seq = Sequence(system=system) ``` 3. Then, design gradient, RF or ADC pulse sequence events: ```python from pypulseq.make_sinc_pulse import make_sinc_pulse Nx, Ny = 256, 256 # matrix size fov = 220e-3 # field of view delta_k = fov / Nx # RF sinc pulse with a 90 degree flip angle rf90, _, _ = make_sinc_pulse(flip_angle=90, system=system, slice_thickness=5e-3, apodization=0.5, time_bw_product=4) # Frequency encode, trapezoidal event gx = make_trapezoid(channel='x', flat_area=Nx * delta_k, flat_time=6.4e-3, system=system) # ADC readout adc = make_adc(num_samples=Nx, duration=gx.flat_time, delay=gx.rise_time, system=system) ``` -4. Add these pulse sequence events to the `Sequence` object from step 2. One or more events can be executed simultaneously, simply pass them all to the `add_block()` method. For example, the `gx` and `adc` pulse sequence events need to be executed simultaneously: +4. Add these pulse sequence events to the `Sequence` object from step 2. One or more events can be executed +simultaneously, simply pass them all to the `add_block()` method. For example, the `gx` and `adc` pulse sequence events +need to be executed simultaneously: ```python seq.add_block(rf90) seq.add_block(gx, adc) ``` 5. Visualize plots: ```python seq.plot() ``` 6. Generate a `.seq` file to be executed on a real MR scanner: ```python seq.write('demo.seq') ``` + +## Community guidelines +`pypulseq` adheres to a code of conduct adapted from the [Contributor Covenant](contrib-covenant) code of conduct. +Contributing guidelines can be found [here](contrib-guidelines). + --- ## References 1. Ravi, Keerthi Sravan, et al. "Pulseq-Graphical Programming Interface: Open source visual environment for prototyping pulse sequences and integrated magnetic resonance imaging algorithm development." Magnetic resonance imaging 52 (2018): 9-15. 2. Layton, Kelvin J., et al. "Pulseq: a rapid and hardware‐independent pulse sequence prototyping framework." Magnetic resonance in medicine 77.4 (2017): 1544-1552. + +[api-docs]: https://pypulseq.readthedocs.io/en/latest +[bruker]: https://github.com/pulseq/bruker_interpreter +[contrib-covenant]: http://contributor-covenant.org +[contrib-guidelines]: https://github.com/imr-framework/pypulseq/blob/master/CONTRIBUTING +[pulseq-gpi-branch]: https://github.com/imr-framework/pypulseq/tree/pypulseq-gpi +[pulseq-spec]: https://pulseq.github.io/specification.pdf +[toppe]: https://toppemri.github.io \ No newline at end of file diff --git a/paper.bib b/paper.bib new file mode 100644 index 0000000..6b8c8af --- /dev/null +++ b/paper.bib @@ -0,0 +1,60 @@ +@article{layton2017pulseq, + title={Pulseq: a rapid and hardware-independent pulse sequence prototyping framework}, + author={Layton, Kelvin J and Kroboth, Stefan and Jia, Feng and Littin, Sebastian and Yu, Huijun and Leupold, Jochen and Nielsen, Jon-Fredrik and St{\"o}cker, Tony and Zaitsev, Maxim}, + journal={Magnetic resonance in medicine}, + volume={77}, + number={4}, + pages={1544--1552}, + year={2017}, + publisher={Wiley Online Library} +} + +@inproceedings{ravi2018amri, + address = {Washington, D.C.}, + author = {Ravi, Keerthi Sravan and Geethanath, Sairam and Weber Jochen and Vaughan, John Thomas}, + booktitle = {ISMRM Workshop on Machine Learning Part II,}, + title = {MR Value driven Autonomous MRI using imr-framework}, + year = {2018} +} + +@inproceedings{ravi2018imrframework, + author = {Ravi, Keerthi Sravan and Geethanath, Sairam and Vaughan, John Thomas}, + booktitle = {i2i Workshop}, + title = {imr-framework for rapid design and deployment of non-Cartesian sequences}, + url = {cai2r.net/i2i}, + year = {2018} +} + +@article{ravi2018pulseq-gpi, + title={Pulseq-Graphical Programming Interface: Open source visual environment for prototyping pulse sequences and integrated magnetic resonance imaging algorithm development}, + author={Ravi, Keerthi Sravan and Potdar, Sneha and Poojar, Pavan and Reddy, Ashok Kumar and Kroboth, Stefan and Nielsen, Jon-Fredrik and Zaitsev, Maxim and Venkatesan, Ramesh and Geethanath, Sairam}, + journal={Magnetic resonance imaging}, + volume={52}, + pages={9--15}, + year={2018}, + publisher={Elsevier} +} + +@inproceedings{gehua2019ismrm, + address = {Montreal, Canada}, + author = {Tong, Gehua and Geethanath, Sairam and Qian, Enlin and Ravi, Keerthi Sravan and Jimeno Manso, Marina and Vaughan, John Thomas}, + booktitle = {ISMRM 27th Annual Meeting & Exhibition}, + title = {Virtual MR Scanner Software}, + year = {2019} +} + +@inproceedings{ravi2019accessible-amri, + address = {New Delhi, India}, + author = {Ravi, Keerthi Sravan and Geethanath, Sairam and Vaughan, John Thomas}, + booktitle = {ISMRM Workshop on Accessible MRI for the World}, + title = {Autonomous scanning using imr-framework to improve MR accessibility}, + year = {2019} +} + +@inproceedings{ravi2019selfadmin, + address = {Montreal, Canada}, + author = {Ravi, Keerthi Sravan and Geethanath, Sairam and Vaughan, John Thomas}, + booktitle = {ISMRM 27th Annual Meeting & Exhibition}, + title = {Self-administered exam using Autonomous Magnetic Resonance Imaging (AMRI)}, + year = {2019} +} diff --git a/paper.md b/paper.md index b0eaca8..3005c44 100644 --- a/paper.md +++ b/paper.md @@ -1,42 +1,102 @@ --- title: 'pypulseq' tags: - Python - MRI - pulse sequence design - vendor neutral authors: - name: Keerthi Sravan Ravi orcid: 0000-0001-6886-0101 affiliation: 1 + - name: Sairam Geethanath + orcid: 0000-0002-3776-4114 + affiliation: 1 + - name: John Thomas Vaughan Jr. + orcid: 0000-0002-6933-3757 + affiliation: 1 affiliations: - name: Columbia Magnetic Resonance Research Center, Columbia University in the City of New York, USA index: 1 -date: 17 July 2019 +date: 21 August 2019 bibliography: paper.bib --- # Summary +Magnetic Resonance Imaging (MRI) is a critical component of healthcare. MRI data is acquired by playing a series of +radio-frequency and magnetic field gradient pulses. Designing these pulse sequences requires knowledge of specific +programming environments depending on the vendor hardware (generations) and software (revisions) intended for +implementation. This impedes the pace of prototyping. Pulseq [@layton2017pulseq] introduced an open-source file +standard for Siemens/[GE](toppe)/[Bruker](bruker) platforms. In this work, we introduce `pypulseq`, which enables pulse sequence +programming in Python. Its advantages are zero licensing fees and easy integrability with deep learning methods +developed in Python. `pypulseq` is aimed at MR researchers, faculty, students, and other allied field researchers +such as those in neuroscience. We have leveraged this tool for several published research works. + +# Statement of need + Magnetic Resonance Imaging (MRI) is a non-invasive diagnostic imaging tool. It is a critical component of healthcare and has a significant impact on diagnosis and treatment assessment. Structural, functional and metabolic MRI generate -valuable information that aid in the accurate diagnosis of a wide range of pathologies. +valuable information that aid in the accurate diagnosis of a wide range of pathologies. These are aimed at achieving +faster scan times, improving tissue contrast and increasing Signal-to-Noise Ratio (SNR). However, designing pulse +sequences requires knowledge of specific programming environments depending on the vendor hardware (generations) and +software (revisions) intended for implementation. This typically involves considerable effort, impeding the pace of +prototyping and therefore research and development. + +Typically, MRl researchers program and simulate the pulse sequences on computers and execute them on MR scanners. +However, the programming language differs across vendors. This also hampers multi-site multi-vendor studies as it +requires researchers to be acquainted with each vendor's programming environment. Further, harmonizing acquisition +across vendors in MR is challenging given the sophisticated choices with respect to a particular hardware platform, +software and the application. This work introduces an open-source tool that enables pulse sequence programming for +Siemens/GE/Bruker platforms in Python. + +# Introduction to the Pulseq file format: .seq -A key aspect of MRI research is pulse sequence design. Pulse sequences directly impact the time required for the MRI -scan and the value of the information obtained. Medical researchers program the pulse sequences on computers and -execute them on MR scanners. However, the programming language differs across vendors. This hampers multi-site -multi-vendor studies as it requires researchers to be acquainted with each vendor's programming environment. +The `.seq` file format introduced in Pulseq [@layton2017pulseq] is a novel way to capture a pulse sequence as plain +text. The file format was designed keeping in mind design goals such as: human-readable, easily parsable, vendor +independent, compact and low-level [@layton2017pulseq]. A pulse sequence comprises of pulsed, magnetic field gradient, +delay or ADC readout *events*. A *block* comprises of one or more *events* occurring simultaneously. *Event* envelopes +are defined by *shapes*, which are run-length encoded and stored in the `.seq` file. In a `.seq` file, each *event* and +*shape* is identified uniquely by an integer. *Blocks* are constructed by assembling the uniquely referenced *events*. +Therefore, any custom pulse sequence can be synthesised by concatenating *blocks*. + +# About `pypulseq` The `pypulseq` package presented in this work is an open-source vendor-neutral MRI pulse sequence design tool. It enables researchers and users to program pulse sequences in Python and export as a `.seq` file. These `.seq` files can -be executed on Siemens/GE/Bruker MR hardware by leveraging vendor-specific interpreters. +be executed on the three MR vendors by leveraging vendor-specific interpreters. The MR methods have been reported +previously [@ravi2018pulseq]. The `pypulseq` package allows for both representing and deploying custom sequences. This +work focuses on the software aspect of the tool. `pypulseq` was entirely developed in Python, and this has multiple +advantages. First, it does not involve any licensing fees that are otherwise associated with other scientific research +platforms such as MATLAB. Second, there has been a proliferation of deep learning projects developed in Python in recent +years. This allows `pypulseq` to be integrated with deep learning techniques for acquisition (for example, intelligent +slice planning in [@ravi2018amri]), and related downstream reconstruction, etc. Also, the standard Python package +manager - PyPI - enables convenient installs on multiple OS platforms. These Python related benefits ensure that +`pypulseq` can reach a wider audience. We have leveraged the `pypulseq` library to implement acquisition oriented +components of the Autonomous MRI (AMRI) package [@ravi2018amri], [@ravi2019accessible-amri], [@ravi2019selfadmin], +Virtual Scanner [@gehua2019ismrm], and the non-Cartesian acquisition library [@ravi2018imrframework]. Also, +the [`pypulseq-gpi`](pypulseq-gpi-branch) branch integrates a previous version of `pypulseq` with [GPI](gpilab) to +enable GUI-based pulse sequence design. This work has been previously reported [@ravi2018pulseq-gpi] and is not within +the scope of this JOSS submission. `pypulseq` is a translation of Pulseq from MATLAB [@layton2017pulseq]. + +# Target audience + +`pypulseq` is aimed at MRI researchers focusing on pulse sequence design, image reconstruction, MR physics. We also +envisage pypulseq to be utilized for repeatability and reproducibility studies such as those for functional MRI +(multi-site, multi-vendor). The package could also serve as a hands-on teaching aid for MR faculty and students. +Beginners can get started with the bundled example pulse sequences. More familiar users can import the appropriate +packages to construct and deploy custom pulse sequences. + +# Reference -The `pypulseq-gpi` branch on the Github repository includes GPI 'Nodes' that enable GUI-based pulse sequence design. -This work has been previously reported [@pulseq-gpi] and is not within the scope of this JOSS submission. +[bruker]: https://github.com/pulseq/bruker_interpreter +[gpilab]: http://gpilab.com/ +[pypulseq-gpi-branch]: https://github.com/imr-framework/pypulseq/tree/pypulseq-gpi +[toppe]: https://toppemri.github.io # Acknowledgements -This study was funded (in part) by the Seed Grant Program for MR Studies of the Zuckerman Mind Brain Behavior Institute -at Columbia University (PI: Geethanath). +This study was funded (in part) by the MR Technology Development Grant and the Seed Grant Program for MR Studies of the +Zuckerman Mind Brain Behavior Institute at Columbia University (PI: Geethanath). -# References \ No newline at end of file +# References diff --git a/setup.py b/setup.py index 28d63e9..36c912b 100644 --- a/setup.py +++ b/setup.py @@ -1,23 +1,23 @@ import setuptools with open("README.md", "r") as fh: long_description = fh.read() setuptools.setup( name="pypulseq", - version="1.2.1", + version="1.2.2", author="Keerthi Sravan Ravi", author_email="sravan953@gmail.com", description="Pulseq in Python", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/imr-framework/pypulseq", packages=setuptools.find_packages(exclude=['pypulseq.utils', 'pypulseq.seq_examples*', 'pypulseq.recon_examples']), - install_requires=['numpy', 'matplotlib'], + install_requires=['numpy==1.16.3', 'matplotlib==3.0.3'], license='License :: OSI Approved :: GNU Affero General Public License v3', classifiers=[ "Programming Language :: Python :: 3.6", "License :: OSI Approved :: GNU Affero General Public License v3", "Operating System :: OS Independent", ], )