{"id":26766088,"url":"https://github.com/ucl/stir-exercises","last_synced_at":"2025-04-15T12:36:00.147Z","repository":{"id":81377446,"uuid":"69784562","full_name":"UCL/STIR-exercises","owner":"UCL","description":"Exercises for STIR","archived":false,"fork":false,"pushed_at":"2024-07-29T12:50:35.000Z","size":11616,"stargazers_count":17,"open_issues_count":6,"forks_count":12,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-28T20:18:58.724Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/UCL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-02T07:25:06.000Z","updated_at":"2025-01-17T18:27:46.000Z","dependencies_parsed_at":null,"dependency_job_id":"cb8ae660-b023-4b82-bfde-5844493b4415","html_url":"https://github.com/UCL/STIR-exercises","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UCL%2FSTIR-exercises","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UCL%2FSTIR-exercises/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UCL%2FSTIR-exercises/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/UCL%2FSTIR-exercises/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/UCL","download_url":"https://codeload.github.com/UCL/STIR-exercises/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249072823,"owners_count":21208253,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-28T20:19:04.979Z","updated_at":"2025-04-15T12:36:00.120Z","avatar_url":"https://github.com/UCL.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Exercises for STIR.\n\nThis material is intended for practical demonstrations using \n[STIR](http://stir.sourceforge.net) on PET and SPECT Image Reconstruction.\n\nThis repository contains exercises to get you going\nwith STIR. Please check [INSTALL.md](INSTALL.md) first (unless\nyou have a Virtual Machine with the exercises\npre-installed).\n\nThe current version of the exercises need at least STIR 4.0.\n\nAuthors:\n- Kris Thielemans\n- Charalampos Tsoumpas (initial scatter and motion exercises)\n- The instructions below were completed with help from Elisabetta Grecchi and Irene Polycarpou\n\nThis software is distributed under an open source license, see [LICENSE.txt](LICENSE.txt)\nfor details.\n\n\nIntroduction\n============\n\nThese exercises introduce you to forward project, image reconstruction, scatter\netc in PET and SPECT. \nSimulated data will be prepared during the exercises. These are based on 2 sets of images:\n\n-   Thorax phantom data are obtained from the open access article: \n    *Tsoumpas et al 2013 Phys Med Biol*.\n    We use two respiratory gated positions of a thorax FDG PET phantom \n\talong with the corresponding CTAC image.\n\n-   Brain data are obtained from [BrainWeb](http://www.bic.mni.mcgill.ca/brainweb/).\n    We use a segmented brain-map.\n\nYou will probably only want to run either the brain or the thorax data (except for the motion \ncorrection exercise which is currently only for the thorax).\n\nThe input data are stored in the folders called `EX_*`, but you will need to\n**run the scripts from the \"main\" STIR-exercises folders** (open a terminal, \n`cd` to where you extracted the exercises, and always `cd` back after every exercise).\n\nWe are using Python for the exercises. Python is an open-source interactive language, \na bit like MATLAB. We provide Python scripts for the evaluation, so you should be fine.\nIt would be best to read a Python tutorial first, see the [Appendices](#appendices). We currently have two alternatives for using the Python scripts:\n- [Spyder](https://pythonhosted.org/spyder) is an IDE for Python. This is\n  recommended for using the \"normal\" Python files (`python/*.py`).\n- [Jupyter notebooks](http://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/what_is_jupyter.html)\n   provide a browser-based interface which keeps track of your work and results. They use\n   Python as well.\n   The notebooks are located in the folder `notebooks` (surprisingly).\n\n\nAs an alternative to Python, we also provide instructions (in the sections \n\"command line evaluation\")\nfor loading sinograms and images in a display program. However, this is really not\nrecommended as the Python scripts are much more convenient. \n***If you are attending a course, only the Jupyter notebooks will be used.***\nNote that in the text below we’re using [AMIDE](http://amide.sf.net/) for\ndisplay. ImageJ would work as well (see the end of the document).\n\nSee the appendices at the end of this document for some information to get started.\n***Please read this before the course.***\n\nStart of exercises\n==================\n\nOpen a terminal and type\n```\nexport STIR_exercises_PATH=~/devel/STIR-exercises\ncd $STIR_exercises_PATH\n```\nOf course, use the path where the STIR-exercises were installed. Note that on the VM,\nthe first line is not necessary as it is incorporated into the start-up script.\n\nNow use either\n```\njupyter notebook\u0026\n```\nor\n```\nspyder\u0026\n```\n\nYou will then alternate between the terminal (to run shell scripts that execute STIR commands)\nand the spyder/jupyter window (to run Python scripts that read in data and make plots).\nOr you could run the scripts from in the notebook or iPython session (see [#iPython]).\n\n**Note:**\n\nThe shell scripts `*.sh` should all write `DONE` or `Done` at the end. If they didn’t,\nsomething went wrong. Check the log files (`*.log`) in the output directory\n(`working_folder/...`) for the script that failed.\n\n**Note:**\n\nSome of the reconstruction scripts might take a while depending on your machine. You could\nalso run all the scripts that generate data beforehand, and run the evaluation scripts afterwards.\n```\ncd $STIR_exercises_PATH\n./run_all.sh\n```\n\nExercise 1: Brain Data Simulation\n=================================\n\n(Always run scripts from the STIR-exercises directory)\n\nThis is a simple simulation of a brain phantom. PSF is incorporated. Scatter is set to\nzero. Randoms are constant.\n\nThe aim of the exercise is get familiar with the scripts and evaluation environment, and\nto look at projection data in different ways (sinograms, by view etc)\n\nRead and run script:\n```\n./run_simulation_brain.sh\n```\nPython evaluation\n-----------------\n\nOpen the file `~/devel/STIR-exercises/evaluate_simulation_brain.py` in Spyder (obviously adjust\nthe path if you installed the exercises elsewhere). You can do this via its menus, or by\ntyping in the terminal:\n```\nspyder python/evaluate_simulation_brain.py\u0026\n```\nJupyter notebook evaluation\n---------------------------\nIn the jupyter interface, navigate to `notebooks` and open `evaluate_simulation_brain.ipynb`.\n\nCommand line evaluation\n-----------------------\nYou will need to extract the sinograms in an \"image\" Interfile to be able to load them in AMIDE\n```\ncd working_folder/brain\nextract_segments my_prompts.hs\nExtract as SegmentByView (0) or BySinogram (1)?[0,1 D:0]: 1\namide my_promptsseg0_by_sino.hv\u0026\n```\nCheck the central sinogram plane to see if it looks as expected.\n\nGo back to main directory\n```\ncd ../..\n```\nWe can also extract profiles through the sinogram to display these in Excel or GNUmeric\nor similar. An example of this is given in the script\n```\nold_evaluation_scripts/evaluate_simulation_brain.sh\n```\nwhich will extract the segments and create profile text files for you. Output files will be\n\n`working_folder/brain/profile_prompts.txt` and\n`working_folder/brain/profile_randoms.txt`\n\nExercise 2: Data Simulation Thorax with PET\n===========================================\n\n(Always run scripts from the `STIR-exercises` directory)\n\nThis is a simple simulation of a thorax phantom (2 gates). PSF is not incorporated. \ncatter is simulated using STIR. Randoms are constant.\n\nThe aim of the exercise is first to do the same things as for the brain, to see differences\nin sinograms etc, get a first view on scatter, but then to move on to seeing the effect of motion.\n\nRead and run script:\n```\n./run_simulations_thorax.sh\n```\n\nJupyter notebook evaluation\n---------------------------\nIn the jupyter interface, navigate to `notebooks` and open `evaluate_simulation_thorax.ipynb'.\n\nPython evaluation\n-----------------\n\nStart spyder with the evaluation script\n```\nspyder python/evaluate_simulation_thorax.py\u0026\n```\nor if Spyder is running, just open the file.\n\n\nCommand line evaluation\n-----------------------\n\nYou will need to extract the sinograms in an \"image\" Interfile to be able to load them in AMIDE\n```\ncd working_folder/GATE1/\nextract_segments my_prompts_g1.hs\nExtract as SegmentByView (0) or BySinogram (1)?[0,1 D:0]: 1\ncd ../GATE2/\nextract_segments my_prompts_g2.hs\nExtract as SegmentByView (0) or BySinogram (1)?[0,1 D:0]: 1\ncd ..\n```\nImport the extracted sinogram (e.g. `my_prompts_g1seg0_by_sino.hv`) using **AMIDE**.\n\nSelect and export the central sinogram plane and upload them online.\n\nSubtract the two sinograms. This can be done in AMIDE or on the command line\n```\nstir_subtract -s diff.hs GATE1/my_prompts_g1.hs GATE2/my_prompts_g2.hs\nextract_segments diff.hs\nExtract as SegmentByView (0) or BySinogram (1)?[0,1 D:0]: 1\n```\nHow does the difference look like in sinogram space?\n\nGo back to main directory\n```\ncd ..\n```\nWe can also extract profiles through the sinogram to display these in Excel or similar. You could run\n```\nold_evaluation_scripts/evaluate_simulation_thorax.sh\n```\nto extract the segments and create profiles for you.\n\n\nExercise 3: Data Simulation Thorax with SPECT\n=============================================\n\n(Always run scripts from the `STIR-exercises` directory)\n\nThis is a simple simulation of single slice of a thorax phantom for SPECT.\nPSF is incorporated. Scatter is set to zero.\n\nThe aim of the exercise is first to see how SPECT sinograms differ from PET.\n\nRead and run script:\n```\n./run_simulation_SPECT.sh\n```\nOutput is in `working_folder/single_slice_SPECT`.\n\nPython evaluation\n-----------------\n\nStart spyder with the evaluation script\n```\nspyder python/evaluate_simulation_SPECT.py\u0026\n```\nor if spyder is running, just open the file.\n\nJupyter notebook evaluation\n---------------------------\nIn the jupyter interface, navigate to `notebooks` and open `evaluate_simulation_SPECT.ipynb'.\n\n\nOptional exercise 1: Simulation in Python\n=========================================\nAs opposed to using scripts and parameter files, you can use STIR\nclasses directly in Python as well of course. This exercise shows you\nhow to use forward and backprojection, construct simple images etc.\n\nTo open in Spyder, type\n```\nspyder python/projection_demo.py\u0026\n```\nor open the `notebooks/projection_demo.ipynb` notebook.\n\nExercise 4: Preparation for Image reconstruction exercise\n=========================================================\n\nFor the thorax reconstruction exercise, we first need to generate a new simulation data set.\nThis time just a single slice to speed things up. Scatter is also set to zero for simplicity here.\n```\n./run_simulation_single_slice.sh\n```\nOutput is in `working_folder/single_slice`. There is no real need to look at the generated results\nas they are a single sinogram of the thorax simulation (but without scatter and with PSF).\n\n\n*Jupyter notebook evaluation* instructions will not be given below, as they're\nstraightforward almost-copies of the *Python evaluation* instructions.\n\nExercise 5: Image reconstruction part 1: EMML and OSEM\n======================================================\n\n(Always run scripts from the `STIR-exercises` directory)\n\nYou will need to have run the corresponding simulation script from the previous section. \nOutput is in `working_folder/single_slice` or `working_folder/brain` or\n`working_folder/single_slice_SPECT`.\n\nWe will now look at EMML and OSEM. A sample script is provided to generate results\n```\n./run_reconstruction_thorax.sh\n```\nOr\n```\n./run_reconstruction_brain.sh\n```\nOr\n```\n./run_reconstruction_SPECT.sh\n```\nThis will first run FBP, EMML (also known as MLEM) for 240 iterations, then OSEM (with 8 subsets)\nfor 240 sub-iterations. For both of these, the images obtained after every 24 updates will be saved.\nIt will also continue EMML and OSEM from 240 sub-iterations and continue for 8 more, writing images\nat every subiterations. In addition, the EMML and OSEM images at 240 iterations are also post-filtered\nwith a Gaussian filter.\n\nOutput is in `working_folder/single_slice` or `working_folder/brain` or\n`working_folder/single_slice_SPECT` *resp*.\n\nThe script runs the reconstruction on the noiseless simulations. See the next exercise for adding noise.\n\nSample questions to address:\n\n-   Is it worth running EMML? Why not simply use OSEM?\n-   At late iterations, is there a difference between OSEM and MLEM convergence behaviour?\n\nPython evaluation\n-----------------\n\nStart spyder with the evaluation script\n```\nspyder python/evaluate_reconstruction_brain.py\u0026\n```\nor if spyder is running, just open the file. If you have run the thorax or SPECT simulation, \njust adjust the path in Line 23 (or there abouts)\n```\nos.chdir('working_folder/brain')\n```\nto the appropriate location.\n\nCommand line evaluation\n-----------------------\n\nRun\n```\nold_evaluation_scripts/evaluate_reconstruction_brain.sh\n```\n(or choose `evaluate_reconstruction_thorax.sh` or `evaluate_reconstruction_SPECT.sh`).\n\nThe script generates some differences images and launches AMIDE. You can of course modify\nthe script for yourself or type commands on the command line.\n\nOptional exercise 2: Reconstruction with a smaller voxel size  \n=============================================================\nThe aim of this exercise is to see how the values of the reconstructed images \ndepend the number of voxels. \n\n(Always run scripts from the `STIR-exercises` directory)\n\nYou will need to have run the corresponding reconstruction script from the previous section. \nOutput is in `working_folder/single_slice`.\n\nThen, Run\n```\nrun_reconstruction_single_slice_thorax_with_zoom.sh\n```\n\nThe script generates three sets of images. \nThe first image is at standard pixel size, \nthe second image is at half pixel size in the two directions, \nbut double number of pixels in total, \nand the third image is also at half pixel size but in addition it uses 10 rays for ray tracing. \n \n\nPython evaluation\n-----------------\n\nStart spyder with the evaluation script\n```\nspyder python/evaluate_reconstruction_single_slice_zoom.py\u0026\n```\nor if spyder is running, just open the file. \n\nIf you wish, you can rerun the script and the evaluation \nafter noise has been included in the data to see the impact of the \naforementioned parameters in noisy datasets.\n\n\n\n\nOptional exercise 3: Reconstruction in Python\n=========================================\nThis exercise shows you how to use reconstruction directly in Python.\n```\nspyder python/reconstruction_demo.py\u0026\n```\nor open the `notebooks/reconstruction_demo.ipynb` notebook.\n\n\nExercise 6: Image reconstruction part 2: adding Poisson noise\n=============================================================\n\n(You will have to run the simulation and reconstruction scripts first.)\n\nWe can make the simulation more realistic by adding noise to the data. In STIR, this\ncan be done with the `poisson_noise` executable.\n\nRun `poisson_noise` in the terminal to understand what its arguments mean.\n```\npoisson_noise\n```\nWe will do this by replacing the noiseless data with a Poisson noise realisation\n(after saving the noiseless data elsewhere), such that we can re-run reconstructions etc without\nediting files (at the expense if possibly creating some confusion though...).\n\nFor your convenience, we provide scripts that do this for you with a\nspecified scaling factor (a smaller scaling factor means higher noise). For example: \n```\n./run_generate_Poisson_thorax.sh 0.5\n```\n*Warning*: in these scripts we have used the `-p` option to `poisson_noise`\nsuch that data and hence reconstructed images have the same scale. See [below\nfor more information](#footnotepreservemean).\n\nThis script does something like this\n```\ncd working_folder/single_slice\n# save noiseless data results in a subfolder\nmkdir noiseless\ncp *.* noiseless\n# Generate Poisson noise (after scaling the data with a factor 0.5)\npoisson_noise -p my_prompts.hs noiseless/my_prompts.hs 0.5 1\n# Copy the new data to a separate folder for later.\nmkdir noise_0.5\ncp my_prompts.* noise_0.5\ncd ../..\n```\n\n\nAs mentioned above, as we overwrite the data, we can just\nuse the same reconstruction and\nevaluation scripts as before (Exercise 5). An alternative would be to let\n`poisson_noise` create a new output file, adjust the reconstruction\nparameter files to use your new noisy data (input) and change the\nfilename used for the output, and change your evaluation scripts.\n\nIf you want to \"reset\" to the noiseless case, you can of course copy the data\nin `noiseless` back:\n```\ncd working_folder/single_slice\ncp noiseless/* .\ncd ../..\n```\n*Note:* If you have used the `run_all.sh` scripts, it already ran\nall reconstructions for a few different noise levels. The results are stored\nin sub-directories `noise_0.5`, `noise_1` etc. You could either run the evaluation\nin the sub-directory (e.g. by editing the `os.chdir` line at the start), or\ncopy the data one level up as illustrated above.\n\n*Note:* If you want to try different noise levels, you have to make sure you\nare adding Poisson noise to the noiseless data, not to noisy data that you’ve\ncreated in a previous step. This will be automatic if you follow the above\nprocedure.\n\nSample questions to address:\n\n-   Try different noise levels. Do the images change as you expected?\n-   Are the answers to the questions in Exercise 5 the same now that we added noise?\n\n\n*\u003ca name=\"footnotepreservemean\"\u003eNote on using the `-p` option of `poisson_noise`\u003c/a\u003e:*\n\nPoisson noise is count dependent. To generate noisier data, you have to scale the\ndata with a factor less than 1. This is somewhat inconvenient as it means that\nreconstructed images will have a different scale factor. When using the `-p`\noption, `poisson_noise` will first apply the scale factor, then generate a Poisson\nnoise realisation, and then scale that data back to the original mean. This is\nsomewhat dangerous, but it so happens that the Poisson log-likelihood just\nchanges with an additive constant with this procedure, and therefore the\nreconstruction will still use the appropriate noise model. If this makes your\nhead hurt, forget about it initially :wink:.\n\n\nExercise 7: Image reconstruction part 3: MAP\n============================================\n\nThis exercise needs results from the previous step (as the MAP reconstruction\nstarts from an OSEM image in this exercise). Output is in `working_folder/single_slice`\nor `working_folder/brain` or `working_folder/single_slice_SPECT` *resp.*\n\nWe will now look at OSL and OSSPS with a Quadratic Prior. A sample script\nis provided to generate results\n```\n./run_reconstruction_thorax_MAP.sh\n```\nor\n```\n./run_reconstruction_brain_MAP.sh\n```\nor\n```\n./run_reconstruction_SPECT_MAP.sh\n```\nThis will run OSL and OSSPS (continuing from a previous OSEM image after 24 subiterations).\n\n**Warning**:\n\nIf you added noise to the data (exercise 6), the MAP reconstructions will also use\nthe noisy data of course. However, because of the initialization with OSEM, you\nwant to run the normal reconstruction script (Exercise 5) first whenever you\nchange the noise level.\n\nYou could for instance first run this exercise with the noisy data, then move\nthe noiseless data back in place, then re-run the reconstruction script for\nthe current exercise.\n\nSample questions to address:\n\n-   Do OSL and OSSPS generate the same results?\n-   Does this depend on the penalty factor? Noise level? Iteration number?\n    Initialisation (try to remove the initial estimate for instance).\n\nStart spyder with the evaluation script\n```\nspyder python/evaluate_reconstruction_brain_MAP.py\u0026\n```\nor if spyder is running, just open the file. If you have run the thorax or \nSPECT simulation, just adjust the path in Line 23 (or there-abouts)\n```\nos.chdir('working_folder/brain')\n```\nto the appropriate location.\n\nExercise 8: Random estimation\n=============================\n\nThis exercise uses Maximum Likelihood estimation to find singles from a\nsinogram of ‘delayed coincidences’. These estimated singles are then\nused to construct the randoms estimate.\n\nOutput is in `working_folder/randoms*.*`\n\nFirst run\n```\n./run_randoms.sh\n```\nThis will construct a noiseless randoms sinogram (by using ground-truth\nsingles), add noise, and run the Maximum Likelihood estimation.\n\nSample questions to address:\n\n-   How do the estimated singles differ from the fansums? In which situations\ndoes this matter?\n\n-   Is there still noise in the estimated random sinogram? (You could do this\nby changing the seed for the Poisson noise generator and re-running the script).\n\nStart spyder with the evaluation script to help you\n```\nspyder python/evaluate_randoms.py\u0026\n```\nor if spyder is running, just open the file.\n\nExercise 9: Scatter Correction\n==============================\n\n(Always run scripts from the `STIR-exercises` directory)\n\nThere are 4 example scatter estimation scripts which can be used to investigate\ndifferent questions about scatter.\n\n**Run 0**\n\nIdeal (i.e. correct attenuation map, scatter simulation matches with how the data\nwas generated) scatter correction (using 3 scatter correction loops)\n\n***This script and its evaluation notebooks is superseded by the\n[`PET_scatter_estimation` notebook](notebooks/PET_scatter_estimation.ipynb).\n\n**Run 1**\n\nCalculate scatter by using a smaller energy window than that simulated. This will\ndemonstrate if the scaling technique works. We have selected 425keV for the lower\nenergy window (original is 350keV).\n\n~~**Run 2**~~ (this is currently not available)\n\n~~Scatter correction using the scatter estimation from the first gate for both gates.\nThis will demonstrate how sensitive is scatter in choosing different but adjacent gates.~~\n\n**Run 3**\n\nPerform reconstruction \u0026 attenuation correction by using wrong attenuation map. In the\nparticular exercise we have assigned bone attenuation value to lung attenuation value\nfor the first gate. Then we use this wrong attenuation map located at the first gate\nto correct for attenuation and scatter for each gates.\n\nYou will first need to simulate the thorax data\n```\n./run_simulations_thorax.sh\n```\nYou should run the scripts as folllows (you can try reading it but these scripts are\nrelatively complicated):\n```\n./run_scatter_0.sh\n```\nThe scripts make the following files in `working_folder/GATE1` (and similar in \n`working_folder/GATE2`)\n\n-   `input_g1.hs`: \"measured\" sinogram after randoms correction\n\n-   `my_scatter.hs`: sinogram output of the simulation (i.e. ground truth)\n\n-   `scatter_estimate_run0.hs` etc: sinogram output of the iterative scatter estimation\n\n-   `FDG_g1.hv`: input of the simulation (i.e. ground truth image)\n\n-   `FBP_recon_with_scatter_correction_run0.hv`: FBP reconstruction of the scatter\ncorrected data\n\nExample questions to answer:\n\n-   How close is the scatter estimate in the ideal case of a simulation and how does\nthis affect the image reconstruction? (run0)\n\n-   How different is the scatter (and its estimate) between gate 1 and gate 2? (run0)\n\n-   How different is the scatter (and its estimate) if you have a wrong estimate of\nthe energy dependence of the detection efficiency? (run1)\n\n-   What happens to the scatter estimate and the reconstructed image if you use the\nwrong attenuation image? (run3)\n\nPython evaluation\n-----------------\n\n2 Python scripts are provided as a starting point for investigating the results.\n\n- `evaluate_scatter_run0.py` which reads results from `run_scatter0.sh` and\ndisplays them comparing with the truth (i.e. simulation input and simulation scatter output) for GATE1\n\n- `evaluate_scatter_run3.py` reads results from run0 and run3 and displays them (also for GATE1).\nYou should be able to use this script with small modifications to look at results from run 2.\n(make a copy, don’t overwrite the existing one).\n\nEvaluation using AMIDE\n----------------------\n\nUse **AMIDE** to visualize your FBP_recon_with_scatter_correction_run0.hv for each\ngate and the original simulated image. Use maximum display value 25.\n\nCan you display the subtraction (e.g. using stir_subtract) between the two gates?\n\nHow much motion do you see in the reconstructed images?\n\nExtract sinograms for display with AMIDE for each of the two gates, e.g.:\n```\ncd working_folder\nextract_segments GATE2/scatter_estimate_run0.hs\nextract_segments GATE2/my_scatter_g2.hs\n```\nCan you display the difference of the two sinograms e.g. using `stir_subtract –s`?\nCan you see motion in the original sinograms? Scatter sinograms?\n\nExercise 10: Motion Correction \n===============================\n\n(Always run scripts from the `STIR-exercises` directory. This exercise depends on the\noutput of `run_simulations_thorax.sh`)\n\nThere are 2 scripts for Part I (MCIR vs noMC):\n- `run_MCIR_0.sh`\n    - Correct for motion using valid motion vectors and the previously calculated scatter background.\n    - output folder: `working_folder/MCIR`\n\n- `run_MCIR_1.sh`\n    - Do not correct for motion\n    - output folder: `working_folder/noMC`\n\nand 2 scripts for Part II (mismatched AC):\n\n- `run_MCIR_2.sh`\n    - Correct for motion using valid motion vectors for emission and the previously calculated\n      scatter background but use the same average attenuation map for both gates\n    - output folder: `working_folder/MCIR/avAC`\n\n- `run_MCIR_3.sh`\n    - Correct for motion using valid motion vectors for emission and the previously calculated\n      scatter background but use the same attenuation map\n      (based on CTAC_g1) for both gates\n    - output folder: `working_folder/MCIR/g1AC`\n\nRun the scripts, e.g.:\n```\n./run_MCIR_0.sh\n./run_MCIR_1.sh\n```\nIt takes about 30seconds to complete each reconstruction. If there are problems, you\ncan confirm the scripts ran OK:\n```\nless working_folder/MCIR/MCIR.log\nless working_folder/noMC/noMC.log\n```\n(quit `less` by pressing `q`)\n\nTo save some time, you can run Part II in the terminal while already evaluating Part I.\n\nTwo Python scripts are provided as a starting point for investigating the results: \n`evaluate_MCIR_Part_I.py` and `evaluate_MCIR_Part_II.py`.\n\nPart I compares motion correction with no motion correction result and shows\nthe forward motion \u0026 backward motion vector images.\n\nPart II compares motion correction using the three different attenuation correction\nfiles (one for each gate, the one obtained from the average, the one obtained from gate 1)\n\nExample questions to answer:\n\n-   How close is motion correction in the ideal case of a simulation and how does this\naffect image reconstruction? (Part I)\n\n- What type of motion is simulated? (Part I)\n\n- How important is the use of the correct attenuation map? (Part II)\n\n- Any comment on scatter correction? (Part II)\n\nExercise 11: Image reconstruction part 4: PSF and MAP\n=====================================================\nWe will now look at OSEM and OSSPS (with a Quadratic Prior) when PSF modelling is\nincluded in the reconstruction.\nWe recommend to do this for SPECT as at present,\nSTIR PSF modelling is PET is hard to modify. (Scripts are provided to run the\nPSF reconstructions for you for the brain and thorax PET case as well.\nIf you are brave, you can check the `.par` files and modify the image-based PSF\nmodelling as well).\n\nThis exercise needs results from exercises 5 and 7. So, you should already have done\nthe following steps:\n```\n./run_simulation_SPECT.sh\n# optionally add noise as in Exercise 6\n./run_reconstruction_SPECT.sh\n./run_reconstruction_SPECT_MAP.sh\n```\n\nA script is provided to generate results\n```\n./run_reconstruction_SPECT_PSF.sh\n```\nThis will run OSEM and OSSPS (continuing from a previous OSEM image after 24\nsubiterations) with PSF model (check e.g. `OSEMPSF.par`).\n\nOutput is in `working_folder/single_slice_SPECT` (or `brain` or `single_slice` of course).\n\n**Warning**:\n\nIf you added noise to the data (exercise 6), the reconstructions will also use\nthe noisy data of course. See the MAP exercise for more info.\n\nSample questions to address:\n\n-   Does PSF-modelling increase resolution?\n\n-   Do you see edge-effects or overshoots in the reconstructed images? For both\nOSEM and OSSPS or only OSEM? Why?\n\n-   What happens to the noise \"texture\" of the images if you reconstruct with\nnoisy data. Are overshoots worse?\n\n-   Extension: you could try to underestimate the PSF (edit `OSEMPSF.par`\nand change the collimator modelling and re-run the reconstruction script).\n\nStart spyder with the evaluation script\n```\nspyder python/evaluate_reconstruction_SPECT_PSF.py\u0026\n```\nor if spyder is running, just open the file.\n\nExercise 12: Image reconstruction part 5: PSF and anatomical prior\n==================================================================\nWe will now look at results with the Parallel Level Sets (PLS) prior.\nWe will do this without and with PSF modelling included in the reconstruction.\n\nThis exercise needs results from exercises 5 and 11. So, you should already have done\nthe following steps (for instance for the brain, but the other cases works as well):\n```\n./run_simulation_brain.sh\n# optionally add noise as in Exercise 6 (recommended)\n./run_reconstruction_brain.sh\n./run_reconstruction_brain_PSF.sh\n```\n\nA script is provided to generate results\n```\n./run_reconstruction_brain_PLS.sh\n```\nThis will run OSMAPOSL (continuing from a previous OSEM image after 24\nsubiterations) with the PLS prior, with and without PSF model (check e.g.\n`OSMAPOSLPSF_PLS.par`).\n\nOutput is in `working_folder/brain` (or in the `single_slice*` folders).\n\nWhen using the brain simulation, the anatomical image for PLS is a (brainweb simulated)\nT1 MRI. For the thorax and SPECT simulations, we use the \"CTAC\", as an MRI would\nusually not be available. You can of course change the brain case to the CTAC as well.\n\n**Warning**:\n\nIf you added noise to the data (exercise 6), the reconstructions will also use\nthe noisy data of course. See the MAP exercise for more info.\n\nSample questions to address:\n\n**Warning**\nThe settings for the prior work reasonably well for the brain simulation. You will\nneed to adjust the penalty factor (as in the MAP exercise).\n\nSample questions to address:\n\n-   Is it a good idea to use anatomical priors if you don't do PSF-modelling?\n\n-   Are any overshoots that you've seen with OSEMPSF reduced when using PLS?\n\n-   What is the effect of the alpha/eta parameters?\n\nExtension:\n-   PLS reduces to (smoothed) TV if the anatomical image is uniform. You could therefore\nuse the same scripts to compare with (smoothed) TV.\n\nStart spyder with the evaluation script\n```\nspyder python/evaluate_reconstruction_brain_PLS.py\u0026\n```\nor if spyder is running, just open the file.\n\n\nAppendices\n==========\n\n\nFile extensions\n---------------\n\n- `.hv`: Interfile header for an image (volume)\n- `.ahv`: (ignore) old-style Interfile header for an image\n- `.v`: raw data of an image (in floats)\n- `.hs`: Interfile header for projection data (sinograms)\n- `.s`: raw data of projection data (in floats)\n- `.par`: STIR parameter file\n- `.sh`: Shell script (sequence of commands)\n- `.bat`: Windows batch file\n- `.log`: log file (used to record output of a command)\n- `.py`: Python file\n\nA note on keyboard short-cuts inside a VirtualBox VM\n----------------------------------------------------\n\nOn Windows and Linux, VirtualBox sets the \"host-key\" by default to `Right-CTRL`, so\nunless you change this, you have to use `Left-CTRL` to \"send\" the `CTRL`-keystroke\nto the Virtual Machine. So, below we will always type `Left-CTRL`.\n\nLinux Terminal\n--------------\n\nIf you have never used a Linux/Unix terminal before, have a look at \n[a tutorial](https://help.ubuntu.com/community/UsingTheTerminal).\n\nYou can use `UPARROW` to go to previous commands, and use copy-paste shortcuts \n`Left-CTRL-SHIFT-C` and `Left-CTRL-SHIFT-V`.\n\n\nPython\n------\nHere is some suggested material on Python (ordered from easy to quite time-consuming).\n\n-   The official Python tutorial. Just read Section 1, 3, a bit of 4 and a tiny bit of 6.\n    \u003chttps://docs.python.org/2/tutorial/\u003e\n\n-   Examples for matplotlib, the python module that allows you to make plots almost like in MATLAB\n    \u003chttps://github.com/patvarilly/dihub-python-for-data-scientists-2015/blob/master/notebooks/02_Matplotlib.ipynb\u003e\n\n-   You could read bits and pieces of Python the Hard Way\n    \u003chttp://learnpythonthehardway.org/book/index.html\u003e\n\n-   Google has an online class on Python for those who know some programming.\n    This goes quite in depth and covers 2 days.\n    \u003chttps://developers.google.com/edu/python/?csw=1\u003e\n\nOne thing which might surprise you that in Python *indentation is important*. You would write for instance\n```python\nfor z in range(0,image.shape[0]):\n   plt.figure()\n   plt.imshow(image[z,:,:])\n# now do something else\n```\n\nJupyter notebooks\n-----------------\nIf you are trying this on your own and have never used Jupyter notebooks,\nyou could [read the official documentation](https://jupyter-notebook.readthedocs.io/en/stable/notebook.html).\nA useful introduction to the notebook interface [can be found here](http://jupyter-notebook.readthedocs.io/en/stable/examples/Notebook/Notebook%20Basics.html).\n\nIn a nut-shell, you need to start the server\n```bash\n   cd /wherever/it/is/STIR-exercises\n   jupyter notebook\n```\n\nThis will open a web-page that looks like a file browser\n(the *Jupyter Notebook dashboard*).\nClick on `notebooks`, and find a file with the extension `.ipynb`\nthat looks of interest, and click on that. This should open a new tab in your\nweb browser with the notebook open, all ready to run.\n\nYou will normally work by executing each *cell*\nbit by bit, and then editing it to do some more work. Useful \nshortcuts:\n\n-   `LEFT-CTRL + \u003cRETURN\u003e` executes the current cell.\n-   `SHIFT + \u003cRETURN\u003e` executes the current cell and advances the cursor to the next\n     cell.\n-   `TAB` tries to complete the word/command you have just typed.\n\nJupyter notebooks (normally) run iPython, [see the section below](#iPython) for some useful commands.\n\nCheck the [jupyter doc on closing a notebook](https://jupyter-notebook-beginner-guide.readthedocs.io/en/latest/execute.html#close-a-notebook-kernel-shut-down).\n\nSpyder\n------\nWe use Spyder as a nice Integrated Development Environment (IDE) for Python\n(or iPython which is a slightly friendlier version of Python). You need only\nminimal knowledge of Python for this course, but it would be good to read-up a bit (see below).\n\nYou will normally work by loading an example script in Spyder in the editor, executing it\nbit by bit, and then editing it to do some more work. Useful \n[shortcuts for in the editor](http://www.southampton.ac.uk/~fangohr/blog/spyder-the-python-ide.html)\n(these are in Windows-style, including the usual copy-paste shortcuts `Left-CTRL-C`\nand `Left-CTRL-V`):\n\n-   `F9` executes the currently highlighted code.\n-   `LEFT-CTRL + \u003cRETURN\u003e` executes the current cell (menu entry `Run -\u003e Run cell`).\n     A cell is defined as the code between two lines which start with the agreed tag `#%%`.\n-   `SHIFT + \u003cRETURN\u003e` executes the current cell and advances the cursor to the next\n     cell (menu entry `Run -\u003e Run cell and advance`).\n-   `TAB` tries to complete the word/command you have just typed.\n\nThe [Spyder Integrated Development Environment](https://pythonhosted.org/spyder/) \n(IDE) has of course lots of parameters which you can tune to your liking. The main\nsetting that you might want to change is if the graphics are generated \"inline\" in\nthe iPython console, or as separate windows. Go to `Tools` \u003e `Preferences` \u003e `Console`\u003e\n`Graphics` \u003e `Graphics backend`. Change from \"inline\" to \"automatic\" if you prefer the separate windows.\n\niPython\n-------\nYou might be able to convince spyder to run iPython.\nAnd here are some useful iPython \"magic\" commands that you can use in the iPython\nconsole on the right (but not in the scripts). Most of these are identical\nto what you would use in the terminal. (*Note*: these commands do not work in a Python console.)\n\n- change how figures appear\n    - separate figures\n    ```\n    %matplotlib\n    ```\n\n    - inline with other output\n    ```     \n    %matplotlib inline\n    ```\n\n    - inline in the jupyter notebook but with extra options for the figures\n      (required for animations)\n    ```     \n     %matplotlib notebook\n    ```\n\n-   change to a new directory\n```python\n    cd some_dir/another_subdir\n```\n-   change back 2 levels up\n```python\n    cd ../..\n```\n-   print current working directory\n```python\n    pwd\n```\n-   edit a file\n```python\n    edit FBP.par\n```\n-   list files in current directory\n```python\n    ls *.hs\n```\n-   Running system commands from the iPython prompt can be done via an exclamation mark\n```python\n    !FBP2D FBP.par\n```\n-   Get rid of everything in memory\n```python\n    %reset\n```\n\nGetting help within Python\n==========================\nMost classes/function will have some documentation. You can access this\nvia normal Python mechanisms.\n\n```python\n# use the class name\nhelp(stir.Scanner)\n# or you can use an object\nscanner=stir.Scanner(...)\nhelp(scanner)\n# help for a single method\nhelp(scanner.get_max_num_views)\n```\nWhen using ipython, you can also get the main class documentation (without\nmethods) by using\n```python\n? stir.Scanner\n```\n\nFinally, many STIR classes have a `parameter_info` method that returns a\nstring with all parameters. This is useful to get an overview, but\nthis can also be saved to file to serve as a parameter file later on.\n```python\nprint(scanner.parameter_info())\n```\n\n***Note***: The inline documentation is directly derived from the doxygen\ndocumentation of the C++ code. You will therefore see some references to C++\nand .h files that really don't make much sense for Python.\nThis is due to a limitation of the tools we are currently using. Apologies.\n\nImage display without Python\n----------------------------\n\nSeveral display programs can be used. AMIDE reads the interfile volumes directly. ImageJ and others can use\nimport of raw floats (i.e. the `.v` file). Settings are for instance.\n```\nImage type: 32-bit Real\nWidth ?\nHeight: ?\nOffset: 0\nNumber of images ?\nGap between images: 0\nWhite is 0: Ticked\nLittle endian: Ticked\n```\nYou will have to find the data sizes from the header (the `.hv` file), or by using the `list_image_info`\nSTIR command.\n\nSTIR commands for evaluation\n----------------------------\n\nThese are a few STIR commands that can be used on the command prompt (not Python).\nYou normally don’t need to if you use the Python scripts though.\n\nFor nearly all of these, you can just type the command name without arguments for a usage message.\n\n### Basic information about geometry\n```\nlist_projdata_info projdata.hs\nlist_image_info image.hv\n```\n### Image reconstruction\n```\nOSMAPOSL someParameterFile.par\nFBP2D somePparameterFile.par\nOSSPS someParameterFile.par\n```\nThese are the STIR executables used for reconstruction. In the text above, they are\ncalled by the shells scripts.\n\n### Profile extraction\n```\nlist_image_values prof.txt input_image \\\n  min_plane max_plane min_row max_row min_col max_col\n```\n(note: the backslash `\\` is used in shell scripts for \"line continuation\", i.e. when \neverything does not fit on one line. You can of course type it on one line instead.)\n\n`list_image_values`writes values to a text file (for import in Excel et al).\n\nIndices need to be in the STIR convention (plane starts from 0, col,row are\ncentred around 0). Use `list_image_info` to find ranges.\n\nNote: there is currently a bug in `list_image_values` that row (*x*) and column (*y*)\nhave to be given in that order (i.e. it's *z,x,y* while should have been *z,y,x*)\n\n### Conversion of projection data to an image for display\n```\nextract_segments projdata.hs\n```\nConverts projection data into an (Interfile) image (in fact a 3D volume) e.g.\nfor display via AMIDE (as no standard display program reads in sinogram data).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fucl%2Fstir-exercises","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fucl%2Fstir-exercises","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fucl%2Fstir-exercises/lists"}