Repository: PennLINC/CuBIDS (language: python)

Issue:
Do slides + present to Yarik's lab



Discussion / hints:

Fix patch:
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 000000000..472f0115c
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,26 @@
+name: Linters
+
+on:
+  - push
+  - pull_request
+
+jobs:
+  lint:
+    runs-on: ubuntu-latest
+
+    steps:
+    - name: Set up environment
+      uses: actions/checkout@v3
+      with:  # no need for the history
+        fetch-depth: 1
+    - name: Set up Python
+      uses: actions/setup-python@v4
+      with:
+        python-version: '3.7'
+    - name: Install dependencies
+      run: |
+        python -m pip install --upgrade pip
+        python -m pip install --upgrade tox
+    - name: Run linters
+      run: |
+        tox -e codespell
diff --git a/docs/example.rst b/docs/example.rst
index fdf1c94a9..09f0c9c62 100644
--- a/docs/example.rst
+++ b/docs/example.rst
@@ -173,7 +173,7 @@ to detect potential curation errors using ``cubids-validate``.
 
     $ cubids-validate BIDS_Dataset_DataLad v0 --sequential
 
-.. note::  The use of the ``--sequential`` flag forces the validator to treat each participant as its own BIDS dataset. This can be helpful for identifying heterogenous elements, but can be slowed down by extremely large datasets.
+.. note::  The use of the ``--sequential`` flag forces the validator to treat each participant as its own BIDS dataset. This can be helpful for identifying heterogeneous elements, but can be slowed down by extremely large datasets.
 
 This command produces the following tsv: 
 
diff --git a/docs/usage.rst b/docs/usage.rst
index 852c52c74..1dd1a029f 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -116,7 +116,7 @@ Use ``cubids-group`` to generate your dataset's Key Groups and Parameter Groups:
 This will output four files, including the summary and files tsvs described above, 
 prefixed by the second argument ``v0``.
 
-Appplying changes 
+Applying changes 
 ------------------
 
 The ``cubids-apply`` program provides an easy way for users to manipulate their datasets. 
@@ -136,7 +136,7 @@ Groups—e.g., every Parameter Group except the Dominant one. Specifically, CuBI
 all non-dominant Parameter Group to include VARIANT* in their acquisition field where * is the reason 
 the Parameter Group varies from the Dominant Group. For example, when CuBIDS encounters a Parameter 
 Group with a repetition time that varies from the one present in the Dominant Group, it will automatically 
-suggest renaming all scans in that Variant Group to include ``acquisition-VARIANTRepetitionTime`` in thier 
+suggest renaming all scans in that Variant Group to include ``acquisition-VARIANTRepetitionTime`` in their 
 filenames. When the user runs ``cubids-apply``, filenames will get renamed according to the auto-generated 
 names in the “Rename Key Group” column in the summary.tsv
 
@@ -146,7 +146,7 @@ Deleting a mistake
 To remove files in a Parameter Group from your BIDS data, you simply set the ``MergeInto`` value
 to ``0``. We see in our data that there is a strange scan that has a ``RepetitionTime`` of 12.3
 seconds and is also variant with respect to EffectiveEchoSpacing and EchoTime. We elect to remove this scan from 
-our dataset becasuse we do not want these parameters to affect our analyses.
+our dataset because we do not want these parameters to affect our analyses.
 To remove these files from your BIDS data, add a ``0`` to ``MergeInto`` and save the new tsv as ``v0_edited_summary.tsv``
 
 .. csv-table:: Pre Apply Groupings with Deletion Requested
diff --git a/group_PNC.e6131615 b/group_PNC.e6131615
deleted file mode 100644
index c079f0bef..000000000
--- a/group_PNC.e6131615
+++ /dev/null
@@ -1,3 +0,0 @@
-Can't locate local/lib.pm:   /root/perl5/lib/perl5/local/lib.pm: Permission denied.
-BEGIN failed--compilation aborted.
-  0%|          | 0/1513 [00:00<?, ?it/s]  2%|▏         | 28/1513 [00:00<00:05, 275.62it/s]  4%|▍         | 64/1513 [00:00<00:04, 294.90it/s]  7%|▋         | 100/1513 [00:00<00:04, 310.35it/s]  9%|▉         | 136/1513 [00:00<00:04, 322.93it/s] 11%|█▏        | 172/1513 [00:00<00:04, 331.42it/s] 14%|█▎        | 208/1513 [00:00<00:03, 337.29it/s] 16%|█▌        | 244/1513 [00:00<00:03, 341.66it/s] 19%|█▊        | 280/1513 [00:00<00:03, 345.28it/s] 21%|██        | 316/1513 [00:00<00:03, 348.34it/s] 23%|██▎       | 352/1513 [00:01<00:03, 349.40it/s] 26%|██▌       | 388/1513 [00:01<00:03, 350.46it/s] 28%|██▊       | 423/1513 [00:01<00:03, 349.93it/s] 30%|███       | 460/1513 [00:01<00:02, 352.96it/s] 33%|███▎      | 496/1513 [00:01<00:02, 353.68it/s] 35%|███▌      | 532/1513 [00:01<00:02, 354.46it/s] 38%|███▊      | 568/1513 [00:01<00:02, 354.97it/s] 40%|███▉      | 604/1513 [00:01<00:02, 355.09it/s] 42%|████▏     | 640/1513 [00:01<00:02, 355.93it/s] 45%|████▍     | 676/1513 [00:01<00:02, 356.28it/s] 47%|████▋     | 712/1513 [00:02<00:02, 356.94it/s] 49%|████▉     | 748/1513 [00:02<00:02, 357.62it/s] 52%|█████▏    | 784/1513 [00:02<00:02, 356.32it/s] 54%|█████▍    | 820/1513 [00:02<00:01, 356.88it/s] 57%|█████▋    | 857/1513 [00:02<00:01, 358.66it/s] 59%|█████▉    | 893/1513 [00:02<00:01, 358.49it/s] 61%|██████▏   | 929/1513 [00:03<00:07, 74.64it/s]  64%|██████▎   | 964/1513 [00:04<00:05, 97.62it/s] 66%|██████▌   | 998/1513 [00:04<00:04, 123.96it/s] 68%|██████▊   | 1032/1513 [00:04<00:03, 152.76it/s] 70%|███████   | 1066/1513 [00:04<00:02, 182.34it/s] 73%|███████▎  | 1101/1513 [00:04<00:01, 212.36it/s] 75%|███████▌  | 1137/1513 [00:04<00:01, 241.83it/s] 78%|███████▊  | 1173/1513 [00:04<00:01, 268.02it/s] 80%|███████▉  | 1209/1513 [00:04<00:01, 289.84it/s] 82%|████████▏ | 1245/1513 [00:04<00:00, 307.60it/s] 85%|████████▍ | 1281/1513 [00:04<00:00, 320.84it/s] 87%|████████▋ | 1317/1513 [00:05<00:00, 330.69it/s] 89%|████████▉ | 1353/1513 [00:05<00:00, 337.68it/s] 92%|█████████▏| 1389/1513 [00:05<00:00, 342.46it/s] 94%|█████████▍| 1425/1513 [00:05<00:00, 345.71it/s] 97%|█████████▋| 1461/1513 [00:05<00:00, 175.87it/s] 99%|█████████▉| 1497/1513 [00:05<00:00, 206.86it/s]100%|██████████| 1513/1513 [00:05<00:00, 255.91it/s]
diff --git a/group_PNC.o6131615 b/group_PNC.o6131615
deleted file mode 100644
index dc8f78248..000000000
--- a/group_PNC.o6131615
+++ /dev/null
@@ -1,1 +0,0 @@
-Agent pid 201613
diff --git a/notebooks/Fieldmaps.ipynb b/notebooks/Fieldmaps.ipynb
index 04c18bd7e..0c14d5289 100644
--- a/notebooks/Fieldmaps.ipynb
+++ b/notebooks/Fieldmaps.ipynb
@@ -38,7 +38,7 @@
     "\n",
     "from pkg_resources import resource_filename as pkgrf \n",
     "\n",
-    "# returns stirng path to testdata\n",
+    "# returns string path to testdata\n",
     "TEST_DATA = pkgrf(\"cubids\", \"testdata\")\n",
     "\n",
     "# should give you the full path \n",
diff --git a/notebooks/HTML_param_groups.ipynb b/notebooks/HTML_param_groups.ipynb
index 72ec9aff6..f04a82b10 100644
--- a/notebooks/HTML_param_groups.ipynb
+++ b/notebooks/HTML_param_groups.ipynb
@@ -37,7 +37,7 @@
     "from cubids import CuBIDS\n",
     "from pkg_resources import resource_filename as pkgrf \n",
     "\n",
-    "# returns stirng path to testdata\n",
+    "# returns string path to testdata\n",
     "TEST_DATA = pkgrf(\"cubids\", \"testdata\")\n",
     "\n",
     "# should give you the full path \n",
@@ -411,7 +411,7 @@
     "import pathlib \n",
     "\n",
     "# @Params\n",
-    "# - path: a string contianing the path to the bids directory inside which we want to change files \n",
+    "# - path: a string containing the path to the bids directory inside which we want to change files \n",
     "# @Returns\n",
     "# - HTML report of acquisitions and their parameter groups \n",
     "\n",
diff --git a/notebooks/JSON_PoC_read_write.ipynb b/notebooks/JSON_PoC_read_write.ipynb
index eff761e4a..6e57b6c4b 100644
--- a/notebooks/JSON_PoC_read_write.ipynb
+++ b/notebooks/JSON_PoC_read_write.ipynb
@@ -143,7 +143,7 @@
     "sample_data.keys()\n",
     "sample_data.get('SliceTiming')\n",
     "SliceTime = sample_data.get('SliceTiming') #the way you can snatch things out of a dictionary \n",
-    "#if dict doens't have the key it will return none vs. error\n",
+    "#if dict doesn't have the key it will return none vs. error\n",
     "\n",
     "if SliceTime: \n",
     "    sample_data.update({\"SliceTime%03d\"%SliceNum : time for SliceNum, time in enumerate(SliceTime)})\n",
@@ -166,7 +166,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "the next one might not have slice timing but you concatonate the next row -- if the file doesn't have slice timing it fills with NaN and if it doesn't then google! \n",
+    "the next one might not have slice timing but you concatenate the next row -- if the file doesn't have slice timing it fills with NaN and if it doesn't then google! \n",
     "\n",
     "rglob to get all the files in the bids tree then load it with json.load "
    ]
@@ -228,7 +228,7 @@
    "source": [
     "3. Checking that the sidecare will write valid JSON files \n",
     "\n",
-    "In order to do this, we use the json.dumps function as it will turn the python object into a JSON string, and therefore, will wirte a valid JSON file always. \n",
+    "In order to do this, we use the json.dumps function as it will turn the python object into a JSON string, and therefore, will write a valid JSON file always. \n",
     "\n",
     "Note: same as the previous chunk of code, this was written for a single .json file and therefore is commentend out "
    ]
@@ -349,7 +349,7 @@
     "    #print(s_path)\n",
     "    file_tree = open(s_path)\n",
     "    example_data = json.load(file_tree)\n",
-    "    SliceTime = example_data.get('SliceTiming') #the way you can snatch things out of a dictionary #if dict doens't have the key it will return none vs. error\n",
+    "    SliceTime = example_data.get('SliceTiming') #the way you can snatch things out of a dictionary #if dict doesn't have the key it will return none vs. error\n",
     "    if SliceTime: \n",
     "        example_data.update({\"SliceTime%03d\"%SliceNum : time for SliceNum, time in enumerate(SliceTime)})\n",
     "        del example_data['SliceTiming']\n",
diff --git a/notebooks/PofC_Key_Values2.ipynb b/notebooks/PofC_Key_Values2.ipynb
index a43fb2da4..0e17595f2 100644
--- a/notebooks/PofC_Key_Values2.ipynb
+++ b/notebooks/PofC_Key_Values2.ipynb
@@ -133,7 +133,7 @@
     "#initialize list\n",
     "\n",
     "for file in all_files:\n",
-    "#for each file in the list, parse the information into a dictionary and add it to the list we just initalized\n",
+    "#for each file in the list, parse the information into a dictionary and add it to the list we just initialized\n",
     "    result = parse_file_entities(file) \n",
     "    \n",
     "    entities.append(result)\n",
@@ -158,7 +158,7 @@
     "\n",
     "# loop through files to create a bigger dictionary of discrete keys, adding each value to a list \n",
     "dictionary = {}\n",
-    "# initalize a new dictionary\n",
+    "# initialize a new dictionary\n",
     "for e in entities:\n",
     "# for each dictionary in the list we created above   \n",
     "    for k,v in e.items():\n",
@@ -228,7 +228,7 @@
     }
    ],
    "source": [
-    "#make a new dictionary with KEYS: BIDS entities (ie: subject, session, etc) and VALUES: dicionaries of ID's and instances\n",
+    "#make a new dictionary with KEYS: BIDS entities (ie: subject, session, etc) and VALUES: dictionaries of ID's and instances\n",
     "\n",
     "new_dictionary = {}\n",
     "counter = 0 \n",
diff --git a/notebooks/metadata_image_param.ipynb b/notebooks/metadata_image_param.ipynb
index cdef0bdbb..b8732d970 100644
--- a/notebooks/metadata_image_param.ipynb
+++ b/notebooks/metadata_image_param.ipynb
@@ -143,7 +143,7 @@
     "sample_data.keys()\n",
     "sample_data.get('SliceTiming')\n",
     "SliceTime = sample_data.get('SliceTiming') #the way you can snatch things out of a dictionary \n",
-    "#if dict doens't have the key it will return none vs. error\n",
+    "#if dict doesn't have the key it will return none vs. error\n",
     "\n",
     "if SliceTime: \n",
     "    sample_data.update({\"SliceTime%03d\"%SliceNum : time for SliceNum, time in enumerate(SliceTime)})\n",
@@ -166,7 +166,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "the next one might not have slice timing but you concatonate the next row -- if the file doesn't have slice timing it fills with NaN and if it doesn't then google! \n",
+    "the next one might not have slice timing but you concatenate the next row -- if the file doesn't have slice timing it fills with NaN and if it doesn't then google! \n",
     "\n",
     "rglob to get all the files in the bids tree then load it with json.load "
    ]
@@ -228,7 +228,7 @@
    "source": [
     "3. Checking that the sidecare will write valid JSON files \n",
     "\n",
-    "In order to do this, we use the json.dumps function as it will turn the python object into a JSON string, and therefore, will wirte a valid JSON file always. \n",
+    "In order to do this, we use the json.dumps function as it will turn the python object into a JSON string, and therefore, will write a valid JSON file always. \n",
     "\n",
     "Note: same as the previous chunk of code, this was written for a single .json file and therefore is commentend out "
    ]
@@ -452,7 +452,7 @@
     "    example_data = json.load(file_tree)\n",
     "    wanted_keys = example_data.keys() & IMAGING_PARAMS\n",
     "    example_data = {key: example_data[key] for key in wanted_keys} \n",
-    "    SliceTime = example_data.get('SliceTiming') #the way you can snatch things out of a dictionary #if dict doens't have the key it will return none vs. error\n",
+    "    SliceTime = example_data.get('SliceTiming') #the way you can snatch things out of a dictionary #if dict doesn't have the key it will return none vs. error\n",
     "    if SliceTime: \n",
     "        example_data.update({\"SliceTime%03d\"%SliceNum : [time] for SliceNum, time in enumerate(SliceTime)})\n",
     "        del example_data['SliceTiming']\n",
@@ -467,7 +467,7 @@
     "\n",
     "\n",
     "#create dataframe of unique rows \n",
-    "#bids entities filter in the cubids class to fileter through the files \n",
+    "#bids entities filter in the cubids class to filter through the files \n",
     "#loop over , get metadata, and put into the dataframe \n",
     "\n",
     "\n",
diff --git a/notebooks/rename_files_work.ipynb b/notebooks/rename_files_work.ipynb
index dde81b9e3..eaff64144 100644
--- a/notebooks/rename_files_work.ipynb
+++ b/notebooks/rename_files_work.ipynb
@@ -56,7 +56,7 @@
     "\n",
     "from pkg_resources import resource_filename as pkgrf \n",
     "\n",
-    "# returns stirng path to testdata\n",
+    "# returns string path to testdata\n",
     "TEST_DATA = pkgrf(\"cubids\", \"testdata\")\n",
     "\n",
     "# should give you the full path \n",
@@ -262,7 +262,7 @@
    "outputs": [],
    "source": [
     "# @Params\n",
-    "# - path: a string contianing the path to the directory inside which we want to change files \n",
+    "# - path: a string containing the path to the directory inside which we want to change files \n",
     "# - pattern: the substring of the file we would like to replace\n",
     "# - replacement: the substring that will replace \"pattern\"\n",
     "# @Returns\n",
@@ -296,7 +296,7 @@
     "import pathlib \n",
     "\n",
     "# @Params\n",
-    "# - path: a string contianing the path to the directory inside which we want to change files \n",
+    "# - path: a string containing the path to the directory inside which we want to change files \n",
     "# - pattern: the substring of the file we would like to replace\n",
     "# - replacement: the substring that will replace \"pattern\"\n",
     "# @Returns\n",
@@ -320,7 +320,7 @@
     "import pathlib \n",
     "\n",
     "# @Params\n",
-    "# - path: a string contianing the path to the bids directory inside which we want to change files \n",
+    "# - path: a string containing the path to the bids directory inside which we want to change files \n",
     "# - pattern: the substring of the file we would like to replace\n",
     "# - replacement: the substring that will replace \"pattern\"\n",
     "# @Returns\n",
@@ -2321,8 +2321,8 @@
     "# in BIDS, want to replace everything up to the BIDS root \n",
     "# don't want to replace all filenames up to the BIDS root \n",
     "\n",
-    "# could have a rename subject funciton and a rename session function\n",
-    "# also have a rename files funciton \n",
+    "# could have a rename subject function and a rename session function\n",
+    "# also have a rename files function \n",
     "\n",
     "# wants a single function that lets you replace any part of the string \n",
     "\n",
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 000000000..7a89eb01e
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,9 @@
+[tox]
+envlist = codespell
+
+[testenv:codespell]
+skip_install = true
+deps =
+    codespell~=2.0
+commands =
+    codespell -D- --skip "_version.py,*.pem,*.json" {posargs} cubds docs notebooks tests


Test patch:
diff --git a/tests/test_bond.py b/tests/test_bond.py
index fff3e5c6c..033e1bae0 100644
--- a/tests/test_bond.py
+++ b/tests/test_bond.py
@@ -817,7 +817,7 @@ def _add_ext_files(img_path):
 
 
 def _edit_a_json(json_file):
-    """Open a json file, write somthing to it and save it to the same name."""
+    """Open a json file, write something to it and save it to the same name."""
     with open(json_file, "r") as metadatar:
         metadata = json.load(metadatar)