diff --git a/.flake8 b/.flake8
deleted file mode 100644
index df2060b3..00000000
--- a/.flake8
+++ /dev/null
@@ -1,5 +0,0 @@
-[flake8]
-max-line-length=88
-per-file-ignores=__init__.py:F401
-extend-exclude = *brain_challenge*,*2020-08*
-extend-ignore = E203, E266, E501
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 033e6f11..1f373649 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -15,7 +15,7 @@ jobs:
       max-parallel: 4
       matrix:
         platform: [ubuntu-latest]
-        python-version: [3.7, 3.8]
+        python-version: [3.8]
 
     runs-on: ${{ matrix.platform }}
 
@@ -28,8 +28,9 @@ jobs:
       - name: Install
         run: |
           python -m pip install --upgrade pip
-          pip install --upgrade wheel
-          pip install -e .
+          pip install --upgrade wheel build setuptools
+          python -m build .
+          pip install dist/*.whl
       - name: Test Import
         run: |
           python -c 'import fastmri'
@@ -40,7 +41,7 @@ jobs:
       max-parallel: 4
       matrix:
         platform: [ubuntu-latest]
-        python-version: [3.7, 3.8]
+        python-version: [3.8]
 
     runs-on: ${{ matrix.platform }}
 
@@ -65,7 +66,7 @@ jobs:
         run: |
           python -m pip install --upgrade pip
           pip install --upgrade wheel
-          pip install -r dev-requirements.txt
+          pip install --editable ".[tests]"
       - name: Check Formatting and Lint
         run: |
           python --version
@@ -75,10 +76,8 @@ jobs:
           mypy fastmri
           flake8 --version
           flake8 fastmri_examples fastmri tests
-      - name: Install fastMRI
-        run: |
-          python setup.py bdist_wheel
-          pip install dist/*.whl
+          isort --version
+          isort --check-only fastmri tests fastmri_examples
       - name: Run pytest
         run: |
           echo -e "PyTorch \c" && pip show torch | grep Version 
diff --git a/.gitignore b/.gitignore
index c9cd8de5..db23769f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,3 +20,4 @@ lightning_logs/
 *.pt
 build/
 dist/
+fastmri/_version.py
diff --git a/README.md b/README.md
index 87bd23f7..d525d96a 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,8 @@ help(SliceDataset)
 
 **Note:** Contributions to the code are continuously tested via GitHub actions.
 If you encounter an issue, the best first thing to do is to try to match the
-test environments in `requirements.txt` and `dev-requirements.txt`.
+`tests` environment in `setup.cfg`, e.g., `pip install --editable ".[tests]"`
+when installing from source.
 
 **Note:** As documented in [Issue 215](https://github.com/facebookresearch/fastMRI/issues/215),
 there is currently a memory leak when using `h5py` installed from `pip` and
diff --git a/dev-requirements.txt b/dev-requirements.txt
deleted file mode 100644
index 35987872..00000000
--- a/dev-requirements.txt
+++ /dev/null
@@ -1,10 +0,0 @@
--r requirements.txt
-wheel
-pytest==6.2.4
-mypy==0.910
-black==21.9b0
-flake8==3.9.0
-types-pyyaml==5.4.10
-pandas-stubs==1.2.0.40
-types-requests==2.27.6
-types-urllib3==1.26.6
\ No newline at end of file
diff --git a/fastmri/__init__.py b/fastmri/__init__.py
index bdc97c6e..66f3aaa1 100644
--- a/fastmri/__init__.py
+++ b/fastmri/__init__.py
@@ -5,14 +5,16 @@
 LICENSE file in the root directory of this source tree.
 """
 
-__version__ = "0.1.2a20220121"
-__author__ = "Facebook/NYU fastMRI Team"
-__author_email__ = "fastmri@fb.com"
-__license__ = "MIT"
-__homepage__ = "https://fastmri.org/"
+from importlib.metadata import PackageNotFoundError, version
+
+try:
+    __version__ = version("fastmri")
+except PackageNotFoundError:
+    # package is not installed
+    import warnings
+
+    warnings.warn("Could not retrieve fastmri version!")
 
-import torch
-from packaging import version
 
 from .coil_combine import rss, rss_complex
 from .fftc import fft2c_new as fft2c
diff --git a/fastmri/coil_combine.py b/fastmri/coil_combine.py
index b29b9d21..5f4f8028 100644
--- a/fastmri/coil_combine.py
+++ b/fastmri/coil_combine.py
@@ -23,7 +23,7 @@ def rss(data: torch.Tensor, dim: int = 0) -> torch.Tensor:
     Returns:
         The RSS value.
     """
-    return torch.sqrt((data ** 2).sum(dim))
+    return torch.sqrt((data**2).sum(dim))
 
 
 def rss_complex(data: torch.Tensor, dim: int = 0) -> torch.Tensor:
diff --git a/fastmri/data/__init__.py b/fastmri/data/__init__.py
index b0f2a601..1dbd88ab 100644
--- a/fastmri/data/__init__.py
+++ b/fastmri/data/__init__.py
@@ -5,5 +5,5 @@
 LICENSE file in the root directory of this source tree.
 """
 
-from .mri_data import SliceDataset, CombinedSliceDataset
+from .mri_data import CombinedSliceDataset, SliceDataset
 from .volume_sampler import VolumeSampler
diff --git a/fastmri/data/mri_data.py b/fastmri/data/mri_data.py
index 582144dd..b2e28598 100644
--- a/fastmri/data/mri_data.py
+++ b/fastmri/data/mri_data.py
@@ -276,8 +276,8 @@ def __init__(
             if dataset_cache.get(root) is None and use_dataset_cache:
                 dataset_cache[root] = self.examples
                 logging.info(f"Saving dataset cache to {self.dataset_cache_file}.")
-                with open(self.dataset_cache_file, "wb") as f:
-                    pickle.dump(dataset_cache, f)
+                with open(self.dataset_cache_file, "wb") as cache_f:
+                    pickle.dump(dataset_cache, cache_f)
         else:
             logging.info(f"Using dataset cache from {self.dataset_cache_file}.")
             self.examples = dataset_cache[root]
diff --git a/fastmri/data/transforms.py b/fastmri/data/transforms.py
index abb3a932..b4552585 100644
--- a/fastmri/data/transforms.py
+++ b/fastmri/data/transforms.py
@@ -7,10 +7,11 @@
 
 from typing import Dict, NamedTuple, Optional, Sequence, Tuple, Union
 
-import fastmri
 import numpy as np
 import torch
 
+import fastmri
+
 from .subsample import MaskFunc
 
 
diff --git a/fastmri/data/volume_sampler.py b/fastmri/data/volume_sampler.py
index ac2c47e9..ac128bce 100644
--- a/fastmri/data/volume_sampler.py
+++ b/fastmri/data/volume_sampler.py
@@ -9,9 +9,10 @@
 
 import torch
 import torch.distributed as dist
-from fastmri.data.mri_data import CombinedSliceDataset, SliceDataset
 from torch.utils.data import Sampler
 
+from fastmri.data.mri_data import CombinedSliceDataset, SliceDataset
+
 
 class VolumeSampler(Sampler):
     """
diff --git a/fastmri/evaluate.py b/fastmri/evaluate.py
index 8a82525c..6fe562d0 100644
--- a/fastmri/evaluate.py
+++ b/fastmri/evaluate.py
@@ -25,7 +25,7 @@ def mse(gt: np.ndarray, pred: np.ndarray) -> np.ndarray:
 
 def nmse(gt: np.ndarray, pred: np.ndarray) -> np.ndarray:
     """Compute Normalized Mean Squared Error (NMSE)"""
-    return np.linalg.norm(gt - pred) ** 2 / np.linalg.norm(gt) ** 2
+    return np.array(np.linalg.norm(gt - pred) ** 2 / np.linalg.norm(gt) ** 2)
 
 
 def psnr(
diff --git a/fastmri/losses.py b/fastmri/losses.py
index d0133b91..cde43356 100644
--- a/fastmri/losses.py
+++ b/fastmri/losses.py
@@ -25,8 +25,8 @@ def __init__(self, win_size: int = 7, k1: float = 0.01, k2: float = 0.03):
         super().__init__()
         self.win_size = win_size
         self.k1, self.k2 = k1, k2
-        self.register_buffer("w", torch.ones(1, 1, win_size, win_size) / win_size ** 2)
-        NP = win_size ** 2
+        self.register_buffer("w", torch.ones(1, 1, win_size, win_size) / win_size**2)
+        NP = win_size**2
         self.cov_norm = NP / (NP - 1)
 
     def forward(
@@ -52,7 +52,7 @@ def forward(
         A1, A2, B1, B2 = (
             2 * ux * uy + C1,
             2 * vxy + C2,
-            ux ** 2 + uy ** 2 + C1,
+            ux**2 + uy**2 + C1,
             vx + vy + C2,
         )
         D = B1 * B2
diff --git a/fastmri/math.py b/fastmri/math.py
index 35106db7..758a8b5a 100644
--- a/fastmri/math.py
+++ b/fastmri/math.py
@@ -66,7 +66,7 @@ def complex_abs(data: torch.Tensor) -> torch.Tensor:
     if not data.shape[-1] == 2:
         raise ValueError("Tensor does not have separate complex dim.")
 
-    return (data ** 2).sum(dim=-1).sqrt()
+    return (data**2).sum(dim=-1).sqrt()
 
 
 def complex_abs_sq(data: torch.Tensor) -> torch.Tensor:
@@ -83,7 +83,7 @@ def complex_abs_sq(data: torch.Tensor) -> torch.Tensor:
     if not data.shape[-1] == 2:
         raise ValueError("Tensor does not have separate complex dim.")
 
-    return (data ** 2).sum(dim=-1)
+    return (data**2).sum(dim=-1)
 
 
 def tensor_to_complex_np(data: torch.Tensor) -> np.ndarray:
diff --git a/fastmri/models/policy.py b/fastmri/models/policy.py
index 7dae4396..e436453f 100644
--- a/fastmri/models/policy.py
+++ b/fastmri/models/policy.py
@@ -7,8 +7,7 @@
 
 import functools
 import operator
-from typing import List
-from typing import Tuple
+from typing import List, Tuple
 
 import torch
 import torch.nn as nn
@@ -64,14 +63,10 @@ def forward(self, mask: torch.Tensor, kspace: torch.Tensor):
         if self.use_softplus:
             # Softplus to make positive
             prob_mask = F.softplus(sampler_out, beta=self.slope)
-            prob_mask = (
-                prob_mask
-                / torch.max(
-                    (1 - mask.reshape(prob_mask.shape[0], prob_mask.shape[1]))
-                    * prob_mask,
-                    dim=1,
-                )[0].reshape(-1, 1)
-            )
+            prob_mask = prob_mask / torch.max(
+                (1 - mask.reshape(prob_mask.shape[0], prob_mask.shape[1])) * prob_mask,
+                dim=1,
+            )[0].reshape(-1, 1)
         else:
             # Sigmoid to make positive
             prob_mask = torch.sigmoid(self.slope * sampler_out)
@@ -419,7 +414,7 @@ def __init__(
         self.down_sample_layers = nn.ModuleList(
             [
                 SingleConvBlock(
-                    chans * 2 ** i,
+                    chans * 2**i,
                     chans * 2 ** (i + 1),
                     drop_prob,
                     pool_size=self.pool_size,
diff --git a/fastmri/models/varnet.py b/fastmri/models/varnet.py
index 0f533d80..92e0b045 100644
--- a/fastmri/models/varnet.py
+++ b/fastmri/models/varnet.py
@@ -6,12 +6,13 @@
 """
 
 import math
-from typing import List, Tuple, Optional
+from typing import List, Optional, Tuple
 
-import fastmri
 import torch
 import torch.nn as nn
 import torch.nn.functional as F
+
+import fastmri
 from fastmri.data import transforms
 
 from .unet import Unet
diff --git a/fastmri/pl_modules/__init__.py b/fastmri/pl_modules/__init__.py
index 43cb6e47..fc9e255b 100644
--- a/fastmri/pl_modules/__init__.py
+++ b/fastmri/pl_modules/__init__.py
@@ -5,7 +5,7 @@
 LICENSE file in the root directory of this source tree.
 """
 
+from .data_module import FastMriDataModule
 from .mri_module import MriModule
 from .unet_module import UnetModule
 from .varnet_module import VarNetModule
-from .data_module import FastMriDataModule
diff --git a/fastmri/pl_modules/data_module.py b/fastmri/pl_modules/data_module.py
index bde1d6cf..f68489a3 100644
--- a/fastmri/pl_modules/data_module.py
+++ b/fastmri/pl_modules/data_module.py
@@ -9,9 +9,10 @@
 from pathlib import Path
 from typing import Callable, Optional, Union
 
-import fastmri
 import pytorch_lightning as pl
 import torch
+
+import fastmri
 from fastmri.data import CombinedSliceDataset, SliceDataset
 
 
@@ -52,13 +53,13 @@ def worker_init_fn(worker_id):
                         + worker_info.id * len(data.datasets)
                         + i
                     )
-                dataset.transform.mask_func.rng.seed(seed_i % (2 ** 32 - 1))
+                dataset.transform.mask_func.rng.seed(seed_i % (2**32 - 1))
     elif data.transform.mask_func is not None:
         if is_ddp:  # DDP training: unique seed is determined by worker and device
             seed = base_seed + torch.distributed.get_rank() * worker_info.num_workers
         else:
             seed = base_seed
-        data.transform.mask_func.rng.seed(seed % (2 ** 32 - 1))
+        data.transform.mask_func.rng.seed(seed % (2**32 - 1))
 
 
 def _check_both_not_none(val1, val2):
diff --git a/fastmri/pl_modules/mri_module.py b/fastmri/pl_modules/mri_module.py
index 83cd30a2..11299fbe 100644
--- a/fastmri/pl_modules/mri_module.py
+++ b/fastmri/pl_modules/mri_module.py
@@ -9,13 +9,14 @@
 from argparse import ArgumentParser
 from collections import defaultdict
 
-import fastmri
 import numpy as np
 import pytorch_lightning as pl
 import torch
-from fastmri import evaluate
 from torchmetrics.metric import Metric
 
+import fastmri
+from fastmri import evaluate
+
 
 class DistributedMetricSum(Metric):
     def __init__(self, dist_sync_on_step=True):
diff --git a/fastmri/pl_modules/unet_module.py b/fastmri/pl_modules/unet_module.py
index c7307f5d..3f261271 100644
--- a/fastmri/pl_modules/unet_module.py
+++ b/fastmri/pl_modules/unet_module.py
@@ -8,9 +8,10 @@
 from argparse import ArgumentParser
 
 import torch
-from fastmri.models import Unet
 from torch.nn import functional as F
 
+from fastmri.models import Unet
+
 from .mri_module import MriModule
 
 
diff --git a/fastmri/pl_modules/varnet_module.py b/fastmri/pl_modules/varnet_module.py
index 74a1ad89..3f101a66 100644
--- a/fastmri/pl_modules/varnet_module.py
+++ b/fastmri/pl_modules/varnet_module.py
@@ -7,8 +7,9 @@
 
 from argparse import ArgumentParser
 
-import fastmri
 import torch
+
+import fastmri
 from fastmri.data import transforms
 from fastmri.models import VarNet
 
diff --git a/fastmri_examples/adaptive_varnet/eval_pretrained_adaptive_varnet.py b/fastmri_examples/adaptive_varnet/eval_pretrained_adaptive_varnet.py
index 11198f87..9b6e6d5a 100644
--- a/fastmri_examples/adaptive_varnet/eval_pretrained_adaptive_varnet.py
+++ b/fastmri_examples/adaptive_varnet/eval_pretrained_adaptive_varnet.py
@@ -4,14 +4,14 @@
 import numpy as np
 import pytorch_lightning as pl
 import torch
+from pl_modules import AdaptiveVarNetModule, VarNetModule
+from subsample import create_mask_for_mask_type
+
 from fastmri import evaluate
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.transforms import MiniCoilTransform
 from fastmri.pl_modules import FastMriDataModule
 
-from pl_modules import AdaptiveVarNetModule, VarNetModule
-from subsample import create_mask_for_mask_type
-
 
 def str2bool(v):
     if isinstance(v, bool):
diff --git a/fastmri_examples/adaptive_varnet/pl_modules/adaptive_varnet_module.py b/fastmri_examples/adaptive_varnet/pl_modules/adaptive_varnet_module.py
index 8fddc6a5..60ac1d3b 100644
--- a/fastmri_examples/adaptive_varnet/pl_modules/adaptive_varnet_module.py
+++ b/fastmri_examples/adaptive_varnet/pl_modules/adaptive_varnet_module.py
@@ -9,9 +9,10 @@
 from collections import defaultdict
 from typing import Tuple
 
-import fastmri
 import numpy as np
 import torch
+
+import fastmri
 from fastmri import evaluate
 from fastmri.data import transforms
 from fastmri.models import AdaptiveVarNet
diff --git a/fastmri_examples/adaptive_varnet/pl_modules/varnet_module.py b/fastmri_examples/adaptive_varnet/pl_modules/varnet_module.py
index f033e632..349218ac 100644
--- a/fastmri_examples/adaptive_varnet/pl_modules/varnet_module.py
+++ b/fastmri_examples/adaptive_varnet/pl_modules/varnet_module.py
@@ -9,10 +9,11 @@
 from collections import defaultdict
 from typing import Optional
 
-import fastmri
 import numpy as np
 import torch
 import torch.nn as nn
+
+import fastmri
 from fastmri import evaluate
 from fastmri.data import transforms
 from fastmri.data.transforms import VarNetSample
@@ -20,7 +21,7 @@
 from fastmri.models.varnet import NormUnet
 from fastmri.pl_modules.mri_module import MriModule
 
-from .metrics import DistributedMetricSum, DistributedArraySum
+from .metrics import DistributedArraySum, DistributedMetricSum
 
 
 class VarNet(nn.Module):
diff --git a/fastmri_examples/adaptive_varnet/subsample.py b/fastmri_examples/adaptive_varnet/subsample.py
index d2f5947e..89257835 100644
--- a/fastmri_examples/adaptive_varnet/subsample.py
+++ b/fastmri_examples/adaptive_varnet/subsample.py
@@ -8,6 +8,7 @@
 from typing import Optional, Sequence
 
 import numpy as np
+
 from fastmri.data.subsample import MaskFunc, RandomMaskFunc
 
 
diff --git a/fastmri_examples/adaptive_varnet/train_adaptive_varnet_demo.py b/fastmri_examples/adaptive_varnet/train_adaptive_varnet_demo.py
index 90c175b0..5ec600bf 100644
--- a/fastmri_examples/adaptive_varnet/train_adaptive_varnet_demo.py
+++ b/fastmri_examples/adaptive_varnet/train_adaptive_varnet_demo.py
@@ -15,13 +15,13 @@
 import pytorch_lightning as pl
 import torch
 import wandb
+from pl_modules import AdaptiveVarNetModule, VarNetModule
+from pytorch_lightning.callbacks import Callback
+from subsample import create_mask_for_mask_type
+
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.transforms import MiniCoilTransform
 from fastmri.pl_modules import FastMriDataModule
-from pytorch_lightning.callbacks import Callback
-
-from pl_modules import AdaptiveVarNetModule, VarNetModule
-from subsample import create_mask_for_mask_type
 
 
 def count_parameters(model):
diff --git a/fastmri_examples/adaptive_varnet/util.py b/fastmri_examples/adaptive_varnet/util.py
index f8808895..564f3265 100644
--- a/fastmri_examples/adaptive_varnet/util.py
+++ b/fastmri_examples/adaptive_varnet/util.py
@@ -1,6 +1,6 @@
-import tempfile
 import pathlib
 import shutil
+import tempfile
 from typing import Tuple
 
 
diff --git a/fastmri_examples/cs/run_bart.py b/fastmri_examples/cs/run_bart.py
index 128015d2..4b93f87d 100644
--- a/fastmri_examples/cs/run_bart.py
+++ b/fastmri_examples/cs/run_bart.py
@@ -13,10 +13,11 @@
 from collections import defaultdict
 
 import bart
-import fastmri
 import numpy as np
 import torch
 import yaml
+
+import fastmri
 from fastmri import tensor_to_complex_np
 from fastmri.data import SliceDataset
 from fastmri.data import transforms as T
diff --git a/fastmri_examples/unet/run_pretrained_unet_inference.py b/fastmri_examples/unet/run_pretrained_unet_inference.py
index 26e69151..cdafd625 100644
--- a/fastmri_examples/unet/run_pretrained_unet_inference.py
+++ b/fastmri_examples/unet/run_pretrained_unet_inference.py
@@ -10,14 +10,15 @@
 from collections import defaultdict
 from pathlib import Path
 
-import fastmri
-import fastmri.data.transforms as T
 import numpy as np
 import requests
 import torch
+from tqdm import tqdm
+
+import fastmri
+import fastmri.data.transforms as T
 from fastmri.data import SliceDataset
 from fastmri.models import Unet
-from tqdm import tqdm
 
 UNET_FOLDER = "https://dl.fbaipublicfiles.com/fastMRI/trained_models/unet/"
 MODEL_FNAMES = {
diff --git a/fastmri_examples/unet/train_unet_demo.py b/fastmri_examples/unet/train_unet_demo.py
index 6e17f8ba..321ff158 100644
--- a/fastmri_examples/unet/train_unet_demo.py
+++ b/fastmri_examples/unet/train_unet_demo.py
@@ -10,6 +10,7 @@
 from argparse import ArgumentParser
 
 import pytorch_lightning as pl
+
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.subsample import create_mask_for_mask_type
 from fastmri.data.transforms import UnetDataTransform
@@ -144,7 +145,7 @@ def build_args():
     parser.set_defaults(
         gpus=num_gpus,  # number of gpus to use
         replace_sampler_ddp=False,  # this is necessary for volume dispatch during val
-        accelerator=backend,  # what distributed version to use
+        strategy=backend,  # what distributed version to use
         seed=42,  # random seed
         deterministic=True,  # makes things slower, but deterministic
         default_root_dir=default_root_dir,  # directory for logs and checkpoints
diff --git a/fastmri_examples/unet/unet_reproduce_20201111.py/unet_brain_leaderboard.py b/fastmri_examples/unet/unet_reproduce_20201111.py/unet_brain_leaderboard.py
index abc4fb7c..1f857fb4 100644
--- a/fastmri_examples/unet/unet_reproduce_20201111.py/unet_brain_leaderboard.py
+++ b/fastmri_examples/unet/unet_reproduce_20201111.py/unet_brain_leaderboard.py
@@ -10,6 +10,7 @@
 from argparse import ArgumentParser
 
 import pytorch_lightning as pl
+
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.subsample import create_mask_for_mask_type
 from fastmri.data.transforms import UnetDataTransform
diff --git a/fastmri_examples/unet/unet_reproduce_20201111.py/unet_knee_mc_leaderboard.py b/fastmri_examples/unet/unet_reproduce_20201111.py/unet_knee_mc_leaderboard.py
index 946d611e..2605294e 100644
--- a/fastmri_examples/unet/unet_reproduce_20201111.py/unet_knee_mc_leaderboard.py
+++ b/fastmri_examples/unet/unet_reproduce_20201111.py/unet_knee_mc_leaderboard.py
@@ -10,6 +10,7 @@
 from argparse import ArgumentParser
 
 import pytorch_lightning as pl
+
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.subsample import create_mask_for_mask_type
 from fastmri.data.transforms import UnetDataTransform
diff --git a/fastmri_examples/unet/unet_reproduce_20201111.py/unet_knee_sc_leaderboard.py b/fastmri_examples/unet/unet_reproduce_20201111.py/unet_knee_sc_leaderboard.py
index 767b9b7c..931a0749 100644
--- a/fastmri_examples/unet/unet_reproduce_20201111.py/unet_knee_sc_leaderboard.py
+++ b/fastmri_examples/unet/unet_reproduce_20201111.py/unet_knee_sc_leaderboard.py
@@ -10,6 +10,7 @@
 from argparse import ArgumentParser
 
 import pytorch_lightning as pl
+
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.subsample import create_mask_for_mask_type
 from fastmri.data.transforms import UnetDataTransform
diff --git a/fastmri_examples/varnet/run_pretrained_varnet_inference.py b/fastmri_examples/varnet/run_pretrained_varnet_inference.py
index 34dc0f89..63091352 100644
--- a/fastmri_examples/varnet/run_pretrained_varnet_inference.py
+++ b/fastmri_examples/varnet/run_pretrained_varnet_inference.py
@@ -10,14 +10,15 @@
 from collections import defaultdict
 from pathlib import Path
 
-import fastmri
-import fastmri.data.transforms as T
 import numpy as np
 import requests
 import torch
+from tqdm import tqdm
+
+import fastmri
+import fastmri.data.transforms as T
 from fastmri.data import SliceDataset
 from fastmri.models import VarNet
-from tqdm import tqdm
 
 VARNET_FOLDER = "https://dl.fbaipublicfiles.com/fastMRI/trained_models/varnet/"
 MODEL_FNAMES = {
diff --git a/fastmri_examples/varnet/train_varnet_demo.py b/fastmri_examples/varnet/train_varnet_demo.py
index 3b795d38..34f0e7ab 100644
--- a/fastmri_examples/varnet/train_varnet_demo.py
+++ b/fastmri_examples/varnet/train_varnet_demo.py
@@ -10,6 +10,7 @@
 from argparse import ArgumentParser
 
 import pytorch_lightning as pl
+
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.subsample import create_mask_for_mask_type
 from fastmri.data.transforms import VarNetDataTransform
@@ -150,7 +151,7 @@ def build_args():
     parser.set_defaults(
         gpus=num_gpus,  # number of gpus to use
         replace_sampler_ddp=False,  # this is necessary for volume dispatch during val
-        accelerator=backend,  # what distributed version to use
+        strategy=backend,  # what distributed version to use
         seed=42,  # random seed
         deterministic=True,  # makes things slower, but deterministic
         default_root_dir=default_root_dir,  # directory for logs and checkpoints
diff --git a/fastmri_examples/varnet/varnet_reproduce_20201111/varnet_brain_leaderboard.py b/fastmri_examples/varnet/varnet_reproduce_20201111/varnet_brain_leaderboard.py
index 317b6257..8d75bd4a 100644
--- a/fastmri_examples/varnet/varnet_reproduce_20201111/varnet_brain_leaderboard.py
+++ b/fastmri_examples/varnet/varnet_reproduce_20201111/varnet_brain_leaderboard.py
@@ -10,6 +10,7 @@
 from argparse import ArgumentParser
 
 import pytorch_lightning as pl
+
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.subsample import create_mask_for_mask_type
 from fastmri.data.transforms import VarNetDataTransform
diff --git a/fastmri_examples/varnet/varnet_reproduce_20201111/varnet_knee_leaderboard.py b/fastmri_examples/varnet/varnet_reproduce_20201111/varnet_knee_leaderboard.py
index 17bbdbbb..c0bbdda3 100644
--- a/fastmri_examples/varnet/varnet_reproduce_20201111/varnet_knee_leaderboard.py
+++ b/fastmri_examples/varnet/varnet_reproduce_20201111/varnet_knee_leaderboard.py
@@ -10,6 +10,7 @@
 from argparse import ArgumentParser
 
 import pytorch_lightning as pl
+
 from fastmri.data.mri_data import fetch_dir
 from fastmri.data.subsample import create_mask_for_mask_type
 from fastmri.data.transforms import VarNetDataTransform
diff --git a/fastmri_examples/zero_filled/run_zero_filled.py b/fastmri_examples/zero_filled/run_zero_filled.py
index 7bdd65db..4b9309b5 100644
--- a/fastmri_examples/zero_filled/run_zero_filled.py
+++ b/fastmri_examples/zero_filled/run_zero_filled.py
@@ -9,11 +9,12 @@
 from argparse import ArgumentParser
 from pathlib import Path
 
-import fastmri
 import h5py
+from tqdm import tqdm
+
+import fastmri
 from fastmri.data import transforms
 from fastmri.data.mri_data import et_query
-from tqdm import tqdm
 
 
 def save_zero_filled(data_dir, out_dir, which_challenge):
diff --git a/mypy.ini b/mypy.ini
deleted file mode 100644
index 21ea37ac..00000000
--- a/mypy.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[mypy]
-
-# modules that don't play well with mypy
-[mypy-numpy.*,h5py.*,runstats.*,skimage.metrics.*,setuptools.*,bart.*,torchvision.*,tqdm.*]
-ignore_missing_imports=True
-
-# directories we're not tracking
-[mypy-tests.*,models.*,data.*,common.*,banding_removal.*]
-ignore_missing_imports=True
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 00000000..97fd1439
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,10 @@
+[build-system]
+build-backend = "setuptools.build_meta"
+requires = [
+    "setuptools-scm>=6.3.2",
+    "setuptools>=59.5.0",
+    "wheel>=0.37.0",
+]
+
+[tool.setuptools_scm]
+write_to = "fastmri/_version.py"
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index fae147fe..00000000
--- a/requirements.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-numpy==1.21.0
-scikit_image==0.16.2
-torchvision==0.10.0
-torch==1.9.0
-runstats==2.0.0
-pytorch_lightning==1.4.7
-h5py==2.10.0
-PyYAML==5.4.1
-torchmetrics==0.5.1
-click==8.0.4
-pandas==1.3.4
-protobuf==3.20
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 00000000..cd62edbe
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,97 @@
+[flake8]
+max-line-length=88
+per-file-ignores=__init__.py:F401
+extend-exclude = *brain_challenge*,*2020-08*
+extend-ignore = E203, E266, E501
+
+[isort]
+profile = black
+
+[metadata]
+author = Meta/NYU fastMRI Team
+author_email = fastmri@fb.com
+classifiers =
+    Programming Language :: Python :: 3
+    Programming Language :: Python :: 3.8
+    License :: OSI Approved :: MIT License
+    Operating System :: OS Independent
+    Development Status :: 3 - Alpha
+    Intended Audience :: Developers
+    Topic :: Scientific/Engineering :: Artificial Intelligence
+    Topic :: Scientific/Engineering :: Image Processing
+    Topic :: Scientific/Engineering :: Medical Science Apps.
+    Topic :: Scientific/Engineering :: Physics
+description = A large-scale dataset of both raw MRI measurements and clinical MRI images.
+license = MIT
+license_files = LICENSE.md
+long_description = file: README.md
+long_description_content_type = text/markdown
+name = fastmri
+project_urls =
+    Homepage = https://fastmri.org/
+    Source = https://github.com/facebookresearch/fastMRI
+
+[mypy]
+
+[mypy-h5py.*]
+ignore_missing_imports = True
+
+[mypy-runstats.*]
+ignore_missing_imports = True
+
+[mypy-skimage.metrics.*]
+ignore_missing_imports = True
+
+[mypy-tqdm.*]
+ignore_missing_imports = True
+
+[options]
+install_requires =
+    numpy>=1.18.5
+    scikit_image>=0.16.2
+    torchvision>=0.8.1
+    torch>=1.8.0
+    runstats>=1.8.0
+    pytorch_lightning>=1.4
+    h5py>=2.10.0
+    PyYAML>=5.3.1
+    torchmetrics>=0.5.1
+    pandas>=1.3.4
+packages = find:
+python_requires = >=3.8
+
+[options.extras_require]
+dev =
+    black==22.3.0
+    flake8==4.0.1
+    mypy==0.961
+    pytest==7.1.2
+    types-pyyaml==5.4.10
+    types-requests==2.27.6
+    types-urllib3==1.26.6
+tests =
+    black==22.3.0
+    flake8==4.0.1
+    h5py==3.7.0
+    isort==5.10.1
+    mypy==0.961
+    numpy==1.22.3
+    pandas==1.4.2
+    pandas-stubs==1.2.0.61
+    pytest==7.1.2
+    pytorch_lightning==1.6.4
+    PyYAML==6.0
+    runstats==2.0.0
+    scikit_image==0.19.3
+    torchmetrics==0.9.1
+    torchvision==0.12.0
+    torch==1.11.0
+    types-pyyaml==5.4.10
+    types-requests==2.27.6
+    types-urllib3==1.26.6
+
+[options.packages.find]
+exclude = 
+    banding_removal*
+    fastmri_examples*
+    tests*
\ No newline at end of file
diff --git a/setup.py b/setup.py
index c6b1dcdd..6973f6b6 100644
--- a/setup.py
+++ b/setup.py
@@ -5,69 +5,6 @@
 LICENSE file in the root directory of this source tree.
 """
 
-import os
-import re
+from setuptools import setup
 
-from setuptools import find_packages, setup
-
-# from https://github.com/facebookresearch/ClassyVision/blob/master/setup.py
-# get version string from module
-with open(os.path.join(os.path.dirname(__file__), "fastmri/__init__.py"), "r") as f:
-    readval = re.search(r"__version__ = ['\"]([^'\"]*)['\"]", f.read(), re.M)
-    if readval is None:
-        raise RuntimeError("Version not found.")
-    version = readval.group(1)
-    print("-- Building version " + version)
-
-with open("README.md", encoding="utf8") as f:
-    readme = f.read()
-
-install_requires = [
-    "numpy>=1.18.5",
-    "scikit_image>=0.16.2",
-    "torchvision>=0.8.1",
-    "torch>=1.8.0",
-    "runstats>=1.8.0",
-    "pytorch_lightning>=1.4",
-    "h5py>=2.10.0",
-    "PyYAML>=5.3.1",
-    "torchmetrics>=0.5.1",
-    "pandas>=1.3.4",
-]
-
-setup(
-    name="fastmri",
-    author="Facebook/NYU fastMRI Team",
-    author_email="fastmri@fb.com",
-    version=version,
-    license="MIT",
-    description="A large-scale dataset of both raw MRI measurements and clinical MRI images.",
-    long_description_content_type="text/markdown",
-    long_description=readme,
-    project_urls={
-        "Homepage": "https://fastmri.org/",
-        "Source": "https://github.com/facebookresearch/fastMRI",
-    },
-    python_requires=">=3.6",
-    packages=find_packages(
-        exclude=[
-            "tests",
-            "fastmri_examples*",
-            "banding_removal",
-        ]
-    ),
-    setup_requires=["wheel"],
-    install_requires=install_requires,
-    classifiers=[
-        "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.6",
-        "License :: OSI Approved :: MIT License",
-        "Operating System :: OS Independent",
-        "Development Status :: 3 - Alpha",
-        "Intended Audience :: Developers",
-        "Topic :: Scientific/Engineering :: Artificial Intelligence",
-        "Topic :: Scientific/Engineering :: Image Processing",
-        "Topic :: Scientific/Engineering :: Medical Science Apps.",
-        "Topic :: Scientific/Engineering :: Physics",
-    ],
-)
+setup()
diff --git a/tests/conftest.py b/tests/conftest.py
index 1e5c634f..28e5d16a 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -8,7 +8,8 @@
 import numpy as np
 import pytest
 import torch
-from .create_temp_data import create_temp_data, create_temp_annotation
+
+from .create_temp_data import create_temp_annotation, create_temp_data
 
 # these are really slow - skip by default
 SKIP_INTEGRATIONS = True
diff --git a/tests/test_data.py b/tests/test_data.py
index d54646bc..9c949646 100644
--- a/tests/test_data.py
+++ b/tests/test_data.py
@@ -6,9 +6,9 @@
 """
 
 from fastmri.data.mri_data import (
-    SliceDataset,
-    CombinedSliceDataset,
     AnnotatedSliceDataset,
+    CombinedSliceDataset,
+    SliceDataset,
 )
 
 
diff --git a/tests/test_integrations.py b/tests/test_integrations.py
index 3aba0847..4ad8d95a 100644
--- a/tests/test_integrations.py
+++ b/tests/test_integrations.py
@@ -6,6 +6,7 @@
 """
 
 import pytest
+
 from fastmri.data.mri_data import CombinedSliceDataset, SliceDataset, fetch_dir
 
 
diff --git a/tests/test_math.py b/tests/test_math.py
index 6a00e28c..cb8debfd 100644
--- a/tests/test_math.py
+++ b/tests/test_math.py
@@ -5,10 +5,11 @@
 LICENSE file in the root directory of this source tree.
 """
 
-import fastmri
 import numpy as np
 import pytest
 import torch
+
+import fastmri
 from fastmri.data import transforms
 
 from .conftest import create_input
diff --git a/tests/test_models.py b/tests/test_models.py
index d9d147a2..565e0b77 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -7,6 +7,7 @@
 
 import pytest
 import torch
+
 from fastmri.data import transforms
 from fastmri.data.subsample import RandomMaskFunc
 from fastmri.models import Unet, VarNet
diff --git a/tests/test_modules.py b/tests/test_modules.py
index 9421fef2..e1433a91 100644
--- a/tests/test_modules.py
+++ b/tests/test_modules.py
@@ -8,11 +8,12 @@
 from argparse import ArgumentParser
 
 import pytest
+from pytorch_lightning import Trainer
+
 from fastmri.data import SliceDataset
 from fastmri.data.subsample import create_mask_for_mask_type
 from fastmri.data.transforms import UnetDataTransform, VarNetDataTransform
 from fastmri.pl_modules import FastMriDataModule, UnetModule, VarNetModule
-from pytorch_lightning import Trainer
 
 
 def build_unet_args(data_path, logdir, backend):
diff --git a/tests/test_transforms.py b/tests/test_transforms.py
index fbe9efac..8b07f079 100644
--- a/tests/test_transforms.py
+++ b/tests/test_transforms.py
@@ -7,6 +7,7 @@
 
 import numpy as np
 import pytest
+
 from fastmri.data import transforms
 from fastmri.data.subsample import MaskFunc, RandomMaskFunc, create_mask_for_mask_type