diff --git a/README.md b/README.md index 5d4ddb0..a5fada0 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ You should put the code in this `findoutlie` directory on your Python PATH. This README file has instructions on how to get, validate and process the data. -# Added this new line. +# Instructions ## Get the data diff --git a/data/group-00/hash_list.txt b/data/group-00/hash_list.txt deleted file mode 100644 index 9063f6e..0000000 --- a/data/group-00/hash_list.txt +++ /dev/null @@ -1,40 +0,0 @@ -5eaa2e01f05cee170e576f5b1e3d4661c75af764 group-00/sub-01/func/sub-01_task-taskzero_run-01_bold.nii.gz -7e39dbebcb9504b26dc90ab97da6925c7229ecdd group-00/sub-01/func/sub-01_task-taskzero_run-01_events.tsv -164738abad431b2e251d32ae5df39ac32d492662 group-00/sub-01/func/sub-01_task-taskzero_run-02_bold.nii.gz -ab264a6822196940f06044f2fcbb611fc5954441 group-00/sub-01/func/sub-01_task-taskzero_run-02_events.tsv -25a80c818325e9b94c604d0cb7ad02fc143eba64 group-00/sub-02/func/sub-02_task-taskzero_run-01_bold.nii.gz -60d3100d2f98cd467482bd0b0a86aab87f63250c group-00/sub-02/func/sub-02_task-taskzero_run-01_events.tsv -20708ce8c3fceb23b70818504103cb54dc11cd45 group-00/sub-02/func/sub-02_task-taskzero_run-02_bold.nii.gz -97c6e697ad5d2837bce14169eca4bf80ed074d70 group-00/sub-02/func/sub-02_task-taskzero_run-02_events.tsv -a5b57e14242e1333cdd5aaf7b0feb6d612d5bd52 group-00/sub-03/func/sub-03_task-taskzero_run-01_bold.nii.gz -13a9fcaefc9e2f3f8d0f962246f894ec3f4cd13c group-00/sub-03/func/sub-03_task-taskzero_run-01_events.tsv -bef1f787f29a6d76d4779d60da3a1d9ce69cdc22 group-00/sub-03/func/sub-03_task-taskzero_run-02_bold.nii.gz -2e432cde2492a32c98c85e393a387a8042cac39c group-00/sub-03/func/sub-03_task-taskzero_run-02_events.tsv -2b43b2821ea004ddbb172085ab7d52e7e679d07e group-00/sub-04/func/sub-04_task-taskzero_run-01_bold.nii.gz -ec65e4be6b734b11e6b7d78bbb6088a6f8b50b53 group-00/sub-04/func/sub-04_task-taskzero_run-01_events.tsv -e0fc9db87118f0765f2fb82c3b3915d72a7f50aa group-00/sub-04/func/sub-04_task-taskzero_run-02_bold.nii.gz -486096db175b3e5fd173fb05b91035a90ee63c9b group-00/sub-04/func/sub-04_task-taskzero_run-02_events.tsv -a04d0d79245e0dc301789ec02a03e98ce1b7a9b5 group-00/sub-05/func/sub-05_task-taskzero_run-01_bold.nii.gz -dc2ab8324999e0a7317e6551305c476d1c0160ae group-00/sub-05/func/sub-05_task-taskzero_run-01_events.tsv -69c697238d7930f07b2339b2afd4a7bf11a52f18 group-00/sub-05/func/sub-05_task-taskzero_run-02_bold.nii.gz -76692e6435353d8b7fd3885f69a10bc64614f55f group-00/sub-05/func/sub-05_task-taskzero_run-02_events.tsv -aaa411bb54454d39a9c245d5c4446899c17a495a group-00/sub-06/func/sub-06_task-taskzero_run-01_bold.nii.gz -fd5f7feed8ddd12ffe4467a4020cc5931cd49b26 group-00/sub-06/func/sub-06_task-taskzero_run-01_events.tsv -9a18f7addc6f9a13b1a4d06b631e67cc20380ea8 group-00/sub-06/func/sub-06_task-taskzero_run-02_bold.nii.gz -2fe32e9ca3338512db646eb3da8b54d3a918ed53 group-00/sub-06/func/sub-06_task-taskzero_run-02_events.tsv -86ecf9bdf2b834233c855569a64cc3ef0698522a group-00/sub-07/func/sub-07_task-taskzero_run-01_bold.nii.gz -e80fd4d390c5be3635a963c14fb5c0d59b740e13 group-00/sub-07/func/sub-07_task-taskzero_run-01_events.tsv -8c2f0d942a7c99c370f9544bc323714708b8e195 group-00/sub-07/func/sub-07_task-taskzero_run-02_bold.nii.gz -b7f85a9b85e834727cfefcf356b9f69cd6f1ad46 group-00/sub-07/func/sub-07_task-taskzero_run-02_events.tsv -dfce82fbf7b3e02d658918fa1341db093ab6e3c4 group-00/sub-08/func/sub-08_task-taskzero_run-01_bold.nii.gz -a4eb6744d5e50a6783d3f365bbd5398151a650f3 group-00/sub-08/func/sub-08_task-taskzero_run-01_events.tsv -4b416251f92ecb10f8c084878049001a224860e2 group-00/sub-08/func/sub-08_task-taskzero_run-02_bold.nii.gz -ce183e545542d7c82b885bb27cb4c4bdfdb1e4b6 group-00/sub-08/func/sub-08_task-taskzero_run-02_events.tsv -7df011856082ac011ac8b191f28e57d12f84bf67 group-00/sub-09/func/sub-09_task-taskzero_run-01_bold.nii.gz -d527ddaee0ea05fdcedb41ef54b2107b655b05d8 group-00/sub-09/func/sub-09_task-taskzero_run-01_events.tsv -36daa50dd2cbd064d652ad519457ad914f2fde12 group-00/sub-09/func/sub-09_task-taskzero_run-02_bold.nii.gz -0734244bb63b92c814fa348bff4eee177bd0ea80 group-00/sub-09/func/sub-09_task-taskzero_run-02_events.tsv -cdfa850cb3b626158bb28aa798803c11a5cd0049 group-00/sub-10/func/sub-10_task-taskzero_run-01_bold.nii.gz -2ef1140403852426ed68f5e93e8bf228cb975ff0 group-00/sub-10/func/sub-10_task-taskzero_run-01_events.tsv -b500a60b6ee1372317a93ebdfc5ae111082cb4fc group-00/sub-10/func/sub-10_task-taskzero_run-02_bold.nii.gz -ab58f5933ca0cb8234a8d6f3713d07692c689437 group-00/sub-10/func/sub-10_task-taskzero_run-02_events.tsv diff --git a/data/group-02/hash_list.txt b/data/group-02/hash_list.txt new file mode 100644 index 0000000..4782c9b --- /dev/null +++ b/data/group-02/hash_list.txt @@ -0,0 +1,40 @@ +08987f4b8332c21199e45497a9fa2c6857e5a8bc group-02/sub-01/func/sub-01_task-taskzero_run-01_bold.nii.gz +5c7fa277512e7e8d653b0ea70c90806f09176485 group-02/sub-01/func/sub-01_task-taskzero_run-01_events.tsv +b0d39329d2aaa89c75d43d942979b8ed6d496f98 group-02/sub-01/func/sub-01_task-taskzero_run-02_bold.nii.gz +c69427bea1a5029adf82c7cc340477aef3ac0066 group-02/sub-01/func/sub-01_task-taskzero_run-02_events.tsv +4cf4c45e348a1a7c23f19c411ba017b19cb07d84 group-02/sub-02/func/sub-02_task-taskzero_run-01_bold.nii.gz +fdb93d39f4011a0ab6076455d9216f3b336f411d group-02/sub-02/func/sub-02_task-taskzero_run-01_events.tsv +e2b6301873607a2a0a2caf72d3d6e2fe5630a0c8 group-02/sub-02/func/sub-02_task-taskzero_run-02_bold.nii.gz +441a8aaf4d18a7d0782e45f59672e1ea721e2691 group-02/sub-02/func/sub-02_task-taskzero_run-02_events.tsv +ee182e71d9dd56aa7b6a68cf81f1eaf51eaf88f0 group-02/sub-03/func/sub-03_task-taskzero_run-01_bold.nii.gz +e9d7ce1ee39f4d851cc76ac9d9f7b40cda698d1f group-02/sub-03/func/sub-03_task-taskzero_run-01_events.tsv +9ca6834e78d044d459aebc9cdda4c21928419ab9 group-02/sub-03/func/sub-03_task-taskzero_run-02_bold.nii.gz +613597b36a145f8621b7d9a49d46613afc35de45 group-02/sub-03/func/sub-03_task-taskzero_run-02_events.tsv +42cb10dd9691e3282a00d900988c6b367d8a32bc group-02/sub-04/func/sub-04_task-taskzero_run-01_bold.nii.gz +84135951864c7b73959b8f5a4f016195eb3842dc group-02/sub-04/func/sub-04_task-taskzero_run-01_events.tsv +3d2256f313dc6256d2f8ebd8c1b1154a59f6449c group-02/sub-04/func/sub-04_task-taskzero_run-02_bold.nii.gz +b636ec0c2ea45425656279085f34910c8a2fa550 group-02/sub-04/func/sub-04_task-taskzero_run-02_events.tsv +e5295642bc528d1c081ac3b84379263e8f35842d group-02/sub-05/func/sub-05_task-taskzero_run-01_bold.nii.gz +4744b8bf85e25df25b95d0e3537714c65b465556 group-02/sub-05/func/sub-05_task-taskzero_run-01_events.tsv +72e2b366f78c58b480518248f6e0cf8b3bcb7ae2 group-02/sub-05/func/sub-05_task-taskzero_run-02_bold.nii.gz +6864445fd0d5a400ffc0107da767651959747b91 group-02/sub-05/func/sub-05_task-taskzero_run-02_events.tsv +1907d02c1e271d1a9f952a5cf7cbf2dfa02df86f group-02/sub-06/func/sub-06_task-taskzero_run-01_bold.nii.gz +500191bbc5b64a75e93a2077a694aaf0ad1a4672 group-02/sub-06/func/sub-06_task-taskzero_run-01_events.tsv +52d9e1ccdba5545cc2f61cbe91e5fda83812043c group-02/sub-06/func/sub-06_task-taskzero_run-02_bold.nii.gz +2e9e990c9f26047ffaec5015d7bc85120a4decfd group-02/sub-06/func/sub-06_task-taskzero_run-02_events.tsv +f076705b6b80286a96f81f916743350ed6590d2b group-02/sub-07/func/sub-07_task-taskzero_run-01_bold.nii.gz +66ea8a008eafc46e88a06aaeeb491dc89060c2b1 group-02/sub-07/func/sub-07_task-taskzero_run-01_events.tsv +9650559e6c24c74159faa4fbc8908852133a530b group-02/sub-07/func/sub-07_task-taskzero_run-02_bold.nii.gz +931a08702e5b25a438dcd30be743b6ab9b31546e group-02/sub-07/func/sub-07_task-taskzero_run-02_events.tsv +9c89c33a013ea60a7770e28c35bd5cee900694c1 group-02/sub-08/func/sub-08_task-taskzero_run-01_bold.nii.gz +20faad141870c86e6a69aac9d6c7f414001db135 group-02/sub-08/func/sub-08_task-taskzero_run-01_events.tsv +6b999ac8af50c3e43e0a2b1cd0016dbb62f1e3fe group-02/sub-08/func/sub-08_task-taskzero_run-02_bold.nii.gz +ab7eb648799ee08717211da3862b25a371545ae4 group-02/sub-08/func/sub-08_task-taskzero_run-02_events.tsv +75470b95aed4f935f2319da6f310d32f7e1d259b group-02/sub-09/func/sub-09_task-taskzero_run-01_bold.nii.gz +065cc29a50942c54510c58c88e0f2c221e8fa584 group-02/sub-09/func/sub-09_task-taskzero_run-01_events.tsv +3e320f57894e56213d7ea4a5f7d19674d3b41bd8 group-02/sub-09/func/sub-09_task-taskzero_run-02_bold.nii.gz +bd135692cf2477793315c493528d79dba8d62936 group-02/sub-09/func/sub-09_task-taskzero_run-02_events.tsv +5b9872cafb1b8375f1b9de99140386f2f349e384 group-02/sub-10/func/sub-10_task-taskzero_run-01_bold.nii.gz +9e4e364f6cdbd5e0f797534fab618cbb49490001 group-02/sub-10/func/sub-10_task-taskzero_run-01_events.tsv +5941418f1b555902a8451aad5864cea03f0272c5 group-02/sub-10/func/sub-10_task-taskzero_run-02_bold.nii.gz +689773a733b9456b3016167262843c733edd7bd9 group-02/sub-10/func/sub-10_task-taskzero_run-02_events.tsv diff --git a/findoutlie/detectors.py b/findoutlie/detectors.py index 6723409..b3663f8 100644 --- a/findoutlie/detectors.py +++ b/findoutlie/detectors.py @@ -11,7 +11,7 @@ """ # Any imports you need -# +++your code here+++ +import numpy as np def iqr_detector(measures, iqr_proportion=1.5): @@ -45,9 +45,9 @@ def iqr_detector(measures, iqr_proportion=1.5): A boolean vector of same length as `measures`, where True means the corresponding value in `measures` is an outlier. """ - # Any imports you need - # Hints: - # * investigate np.percentile - # * You'll likely need np.logical_or - # https://textbook.nipraxis.org/numpy_logical.html - # +++your code here+++ + Q1, Q3 = np.percentile(measures, [25, 75]) + IQR = Q3 - Q1 + lower_lim = Q1 - IQR * iqr_proportion + upper_lim = Q3 + IQR * iqr_proportion + is_outlier = np.logical_or(measuresupper_lim) + return is_outlier diff --git a/findoutlie/metrics.py b/findoutlie/metrics.py index 08ba844..40273f4 100644 --- a/findoutlie/metrics.py +++ b/findoutlie/metrics.py @@ -1,8 +1,7 @@ """ Scan outlier metrics """ -# Any imports you need -# +++your code here+++ +import numpy as np def dvars(img): @@ -26,7 +25,8 @@ def dvars(img): # In [3]: np.mean(arr, axis=1) # Out[2]: array([3., 6.]) # - # You may be be able to solve this in four lines, without a loop. - # But solve it any way you can. - # This is a placeholder, replace it to write your solution. - raise NotImplementedError('Code up this function') + data = img.get_fdata() + vol_diff = np.diff(data, axis=3) # [x,y,z,t-1] + dvar_val = np.sqrt(np.mean(vol_diff ** 2, axis=(0,1,2))) + + return dvar_val diff --git a/scripts/validate_data.py b/scripts/validate_data.py index beb7922..9d48163 100644 --- a/scripts/validate_data.py +++ b/scripts/validate_data.py @@ -23,10 +23,11 @@ def file_hash(filename): SHA1 hexadecimal hash string for contents of `filename`. """ # Open the file, read contents as bytes. + pth = Path(filename) + file_bytes = pth.read_bytes() # Calculate, return SHA1 has on the bytes from the file. - # This is a placeholder, replace it to write your solution. - raise NotImplementedError( - 'This is just a template -- you are expected to code this.') + return hashlib.sha1(file_bytes).hexdigest() + def validate_data(data_directory): @@ -48,13 +49,17 @@ def validate_data(data_directory): ``data_hashes.txt`` file. """ # Read lines from ``data_hashes.txt`` file. - # Split into SHA1 hash and filename - # Calculate actual hash for given filename. - # If hash for filename is not the same as the one in the file, raise - # ValueError - # This is a placeholder, replace it to write your solution. - raise NotImplementedError( - 'This is just a template -- fill out the template with code.') + hash_path = Path(data_directory) / 'hash_list.txt' + with open(hash_path, 'r') as f: + for line in f.readlines(): + # Split into SHA1 hash and filename + read_hash, filename = line.strip().split() + # Calculate actual hash for given filename. + true_hash = file_hash(hash_path.parent.parent / filename) + # If hash for filename is not the same as the one in the file, raise + if true_hash != read_hash: + raise ValueError("Hash value not as recorded.") + def main():