Welcome to OpenREM’s documentation!¶
OpenREM is an opensource framework created for the purpose of radiation exposure monitoring. The software is capable of importing and displaying data from a wide variety of x-ray dose related sources, and then enables easy export of the data in a form that is suitable for further analysis by suitably qualified medical physics personnel.
Please see openrem.org for more details.
Contents:
Installation instructions¶
Quick setup¶
Note
Most path names are represented using the linux convention of a / separator. If you are installing in a Windows environment you will need to use the Windows \ separator.
Install python (might need to be 2.7)
Install setuptools and pip
- Install OpenREM
- pip install OpenREM-ver.tar.gz
- Configure OpenREM
Locate install location, typically something/lib/python2.7/site-packages/openrem
- There are two files that need renaming:
- openrem/openrem/settings.py.example to openrem/openrem/settings.py
- openrem/openrem/wsgi.py.example to openrem/openrem/wsgi.py
in the settings.py file, set the database details.
- For testing ONLY, use
'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': '/ENTER/PATH/WHERE/DB/FILE/CAN/GO'
- Windows example: 'NAME': 'C:\Documents\User\OpenREM\openrem.db'
- Linux example: 'NAME': '/var/openrem/openrem.db'
- Create the database
- python path/to/openrem/manage.py syncdb
- (optional when just testing) python path/to/openrem/manage.py convert_to_south remapp
- Start test web server
- python path/to/openrem/manage.py runserver
- If you are using a headless server and need to be able to see the web interface from another machine, use python path/to/openrem/manage.py runserver x.x.x.x:8000 replacing the ‘x’ with the IP address of the server and ‘8000’ with the port you wish to use.
Open the web addesss given, appending /openrem (http://localhost:8000/openrem)
- Add some data!
- openrem_rdsr.py rdsrfile.dcm
More in depth process¶
- Install virtualenv or maybe virtualenvwrapper
Recommended if the server is ever going to be used for more than one python application – virtualenv sets up an isolated python environment
- Install OpenREM
As per the Quick setup instructions above. Don’t configure OpenREM yet
- Install a production database
SQLite is great for getting things running quickly and testing if the setup works, but is really not recommended for production use on any scale. Therefore it is recommended to use a different database such as PostgreSQL or MySQL.
Here are the authors instructions for installing PostgreSQL on linux:
Installing PostgreSQL for OpenREM on Ubuntu linux¶
Install PostgreSQL and the python connector¶
- sudo apt-get install postgresql
- sudo apt-get build-dep python-psycopg2
The second command installed a lot of things, at least some of which are necessary for this to work!
If you are using a virtualenv, make sure you are in it and it is active (source bin/activate)
- pip install psycopg2
Create a user for the database¶
- sudo passwd postgres
- Enter password, twice
- sudo -u postgres createuser -P openrem_user
- Enter password, twice
- Superuser, No
- Create databases, No
- Create new roles, No
Optional: Specify the location for the database¶
You might like to do this if you want to put the database on an encrypted location
For this example, I’m going to assume all the OpenREM programs and data are in the folder /var/openrem/:
- sudo /etc/init.d/postgresql stop
- mkdir /var/openrem/database
- sudo cp -aRv /var/lib/postgresql/9.1/main /var/openrem/database/
- sudo nano /etc/postgresql/9.1/main/postgresql.conf
- Change the line
- data_directory = '/var/lib/postgresql/9.1/main' to
- data_directory = '/var/openrem/database/main'
- sudo /etc/init.d/postgresql start
Create the database¶
- su postgres
- psql template1
- CREATE DATABASE openrem_db OWNER openrem_user ENCODING 'UTF8';
- \q
- exit
Change the security configuration¶
The default security settings are too restrictive to allow access to the database.
sudo nano /etc/postgresql/9.1/main/pg_hba.conf
- Add the following line:
- local openrem_db openrem_user md5
sudo /etc/init.d/postgresql restart
Configure OpenREM to use the database¶
- Find and edit the settings file, eg
- nano local/lib/python2.7/site-packages/openrem/openrem/settings.py
- Set the following (changing name, user and password as appropriate):
- 'ENGINE': 'django.db.backends.postgresql_psycopg2',
- 'NAME': 'openrem_db',
- 'USER': 'openremuser',
- 'PASSWORD': 'openrem_pw',
Fire it up with OpenREM¶
- python path/to/openrem/manage.py syncdb
- python path/to/openrem/manage.py convert_to_south remapp
- Install and configure a production webserver
Unlike the database, the production webserver can be left till later and can be changed again at any time.
However, for performance it is recommended that a production webserver is used. Popular choices would be either Apache or you can do as the cool kids do and use Gunicorn with nginx.
- Configure OpenREM
Follow the ‘Configure OpenREM’ instuctions in the Quick setup section above, but this time with the production database details.
Configure the production webserver too.
- Create the database
- python path/to/openrem/manage.py syncdb
- Convert the database to use South
South is a django application to manage database migrations. Using South means that future changes to the database model can be calculated and executed automatically with simple commands when OpenREM is upgraded.
- python path/to/openrem/manage.py convert_to_south remapp
Importing data to OpenREM¶
Using the OpenREM interface and export function¶
Filtering for specific studies¶
This image shows the CT studies view, filtered by entering terms in the boxes on the right hand side to show just the studies where the modality model name includes the term ‘soma’:
The search fields can all be used on their own or together, and they are all case insensitive ‘contains’ searches. The exception is the date field, where both from and to have to be filled in (if either are), and the format must be yyyy-mm-dd. There currently isn’t any more complex filtering available, but it does exist as issue 17 for a future release.
The last box below the filtering search boxes is the ordering preference.
New in 0.3.8 Ordering by date now takes account of the time of the study (issue 37).
Viewing study details¶
By clicking on the study description link (in blue), you can see more details for an individual study:
Not all the details stored for any one study are displayed, just those thought to be most useful. If there are others you’d like to see, add an issue to the tracker.
The final field in the summary at the top is called ‘Test patient indicators?’ When studies are imported the ID and patient name fields are both ignored, but they are parsed to check if they have ‘phy’, ‘test’ or ‘qa’ in them to help exclude them from the data analysis. If they do, then this information is added to the field and is displayed both in the web interface as a Test patient indicator and in the Excel export. The name and ID themselves are not reproduced, simply the presence of one of the key words. Therefore a patient named ‘Phyliss’ would trigger this, but only ‘Phy’ would be reproduced in this field. Other fields will also help to confirm whether a study is for a real patient such as the lack of an Accession Number and an unusual patient age.
Exporting to csv and xlsx sheets¶
From any of the modality pages in the OpenREM interface, you can export the displayed studies to a csv spreadsheet by clicking on the link near the top. In the CT interface, you can also export to an enhanced XLSX spreadsheet.
For CT, the XLSX export has multiple sheets. The first sheet contains a summary of all the study descriptions, requested procedures and series protocol names contained in the export:
This information is useful for seeing what data is in the spreadsheet, and can also be used to prioritise which studies or protocols to analyse based on frequency.
The second sheet of the exported file lists all the studies, with each study taking one line and each series in the study displayed in the columns to the right.
The remainder of the file has one sheet per series protocol name. Each series is listed one per line. If a single study has more than one series with the same protocol name, then the same study will appear on more than one line.
Upgrade instructions¶
Upgrading from tar.gz package¶
Note
Make sure you have setup South before you upgrade – see 7. Convert the database to use South for details.
Code upgrade¶
- pip install OpenREM-version.tar.gz
Database migration¶
Always do a database migration using South after an upgrade in case any of the database models have changed. This will normally not be the case.
- python path/to/openrem/manage.py schemamigration --auto remapp
eg python lib/python2.7/site-packages/openrem/manage.py schemamigration --auto remapp
If response to the last command is ‘Nothing seems to have changed’, no migration is required. Else, follow the instructions to migrate.
Restart the web server¶
- Restart the web server to enable any changes that have been made to the web interface.
Documentation for the OpenREM code¶
Contents:
DICOM import modules¶
RDSR module¶
Ultimately this should be the only module required as it deals with all Radiation Dose Structured Reports. Currently this has only been tested on CT and fluoroscopy structured reports, but it also has the logic for mammography structured reports if they start to appear.
- remapp.extractors.rdsr.rdsr(rdsr_file)¶
Extract radiation dose related data from DICOM Radiation SR objects.
Parameters: filename (str.) – relative or absolute path to Radiation Dose Structured Report. - Tested with:
- CT: Siemens, Philips and GE RDSR, GE Enhanced SR.
- Fluoro: Siemens Artis Zee RDSR
Mammography module¶
Mammography is interesting in that all the information required for dose audit is contained in the image header, including patient ‘size’, ie thickness. However the disadvantage over an RSDR is the requirement to process each individual image rather than a single report for the study, which would also capture any rejected images.
- remapp.extractors.mam.mam(mg_file)¶
Extract radiation dose structured report related data from mammography images
Parameters: filename (str.) – relative or absolute path to mammography DICOM image file. - Tested with:
- GE Senographe DS software versions ADS_43.10.1 and ADS_53.10.10 only.
- Limited testing: GE Senographe Essential
- Limited testing: Hologic Selenia
- Limited testing: Siemens Inspiration
CT non-standard modules¶
Initially only Philips CT dose report images are catered for. These have all the information that could be derived from the images also held in the DICOM header information, making harvesting relatively easy.
- remapp.extractors.ct_philips.ct_philips(philips_file)¶
Extract radiation dose structured report related data from Philips CT dose report images
Parameters: filename (str.) – relative or absolute path to Philips CT dose report DICOM image file. - Tested with:
- Philips Gemini TF PET-CT v2.3.0
- Brilliance BigBore v3.5.4.17001.
Non-DICOM import modules¶
Patient height and weight csv import module¶
This module enables a csv file to be parsed and the height and weight information extracted and added to existing studies in the OpenREM database. An example may be a csv extract from a RIS or EPR system.
There needs to be a common unique identifier for the exam - currently this is limited to accession number or study instance UID.
- remapp.extractors.ptsizecsv2db.csv2db(*args, **kwargs)¶
Import patient height and weight data from csv RIS exports. Can be called from openrem_ptsizecsv.py script
Parameters: - –si-uid (bool) – Use Study Instance UID instead of Accession Number. Short form -s.
- csvfile (str) – relative or absolute path to csv file
- id (str) – Accession number column header or header if -u or –si-uid is set. Quote if necessary.
- height (str) – Patient height column header. Create if necessary, quote if necessary.
- weight (str) – Patient weight column header. Create if necessary, quote if necessary.
Example:
openrem_ptsizecsv.py -s MyRISExport.csv StudyInstanceUID HEIGHT weight
Export from database¶
Multi-sheet Microsoft Excel XLSX exports¶
This export has a summary sheet of all the requested and performed protocols and the series protocols. The next sheet has all studies on, one study per line, with the series stretching off to the right. The remaining sheets are specific to each series protocol, in alphabetical order, with one series per line. If one study has three series with the same protocol name, each one has a line of its own.
- remapp.exports.xlsx.ctxlsx(request)¶
Export filtered CT database data to multi-sheet Microsoft XSLX files.
Parameters: request (HTTP get) – Query parameters from the CT filtered page URL.
Single sheet CSV exports¶
- remapp.exports.exportcsv.exportFL2excel(request)¶
Export filtered fluoro database data to a single-sheet CSV file.
Parameters: request (HTTP get) – Query parameters from the fluoro filtered page URL.
- remapp.exports.exportcsv.exportCT2excel(request)¶
Export filtered CT database data to a single-sheet CSV file.
Parameters: request (HTTP get) – Query parameters from the CT filtered page URL.
- remapp.exports.exportcsv.exportMG2excel(request)¶
Export filtered mammography database data to a single-sheet CSV file.
Parameters: request (HTTP get) – Query parameters from the mammo filtered page URL.
Tools and helper modules¶
OpenREM settings¶
Administrative module to define the name of the project and to add it to the Python path
- remapp.extractors.openrem_settings.name_of_project()¶
Returns the name of the project. Default OpenREM
- remapp.extractors.openrem_settings.add_project_to_path()¶
Add project to path, assuming this file is within project
Get values¶
Tiny modules to reduce repetition in the main code when extracting information from DICOM headers using pydicom.
- remapp.tools.get_values.get_value_kw(tag, dataset)¶
Get DICOM value by keyword reference.
Parameters: - keyword (str.) – DICOM keyword, no spaces or plural as per dictionary.
- dataset (dataset) – The DICOM dataset containing the tag.
Returns: str. – value
- remapp.tools.get_values.get_value_num(tag, dataset)¶
Get DICOM value by tag group and element number.
Always use get_value_kw by preference for readability. This module can be required when reading private elements.
Parameters: - tag (hex) – DICOM group and element number as a single hexadecimal number (prefix 0x).
- dataset (dataset) – The DICOM dataset containing the tag.
Returns: str. – value
- remapp.tools.get_values.get_seq_code_value(sequence, dataset)¶
From a DICOM sequence, get the code value.
Parameters: - sequence (DICOM keyword, no spaces or plural as per dictionary.) – DICOM sequence name.
- dataset (DICOM dataset) – The DICOM dataset containing the sequence.
Returns: int. – code value
- remapp.tools.get_values.get_seq_code_meaning(sequence, dataset)¶
From a DICOM sequence, get the code meaning.
Parameters: - sequence (DICOM keyword, no spaces or plural as per dictionary.) – DICOM sequence name.
- dataset (DICOM dataset) – The DICOM dataset containing the sequence.
Returns: str. – code meaning
- remapp.tools.get_values.get_or_create_cid(codevalue, codemeaning)¶
Create a code_value code_meaning pair entry in the Content_item_descriptions table if it doesn’t already exist.
Parameters: - codevalue (int.) – Code value as defined in the DICOM standard part 16
- codemeaning – Code meaning as defined in the DICOM standard part 16
Returns: Content_item_descriptions entry for code value passed
Check if UID exists¶
Small module to check if UID already exists in the database.
- remapp.tools.check_uid.check_uid(uid, level='Study')¶
Check if UID already exists in database.
Parameters: uid (str.) – Study UID. Returns: 1 if it does exist, 0 otherwise
DICOM time and date values¶
Module to convert betweeen DICOM and Python dates and times.
- remapp.tools.dcmdatetime.get_date(tag, dataset)¶
Get DICOM date string and return Python date.
Parameters: - tag (str.) – DICOM keyword, no spaces or plural as per dictionary.
- dataset (dataset) – The DICOM dataset containing the tag.
Returns: Python date value
- remapp.tools.dcmdatetime.get_time(tag, dataset)¶
Get DICOM time string and return Python time.
Parameters: - tag (str.) – DICOM keyword, no spaces or plural as per dictionary.
- dataset (dataset) – The DICOM dataset containing the tag.
Returns: python time value
- remapp.tools.dcmdatetime.get_date_time(tag, dataset)¶
Get DICOM date time string and return Python date time.
Parameters: - tag (str.) – DICOM keyword, no spaces or plural as per dictionary.
- dataset (dataset) – The DICOM dataset containing the tag.
Returns: Python date time value
- remapp.tools.dcmdatetime.make_date(dicomdate)¶
Given a DICOM date, return a Python date.
Parameters: dicomdate (str.) – DICOM style date. Returns: Python date value
- remapp.tools.dcmdatetime.make_time(dicomtime)¶
Given a DICOM time, return a Python time.
Parameters: dicomdate (str.) – DICOM style time. Returns: Python time value
- remapp.tools.dcmdatetime.make_date_time(dicomdatetime)¶
Given a DICOM date time, return a Python date time.
Parameters: dicomdate (str.) – DICOM style date time. Returns: Python date time value
Test for QA or other non-patient related studies¶
- remapp.tools.not_patient_indicators.get_not_pt(dataset)¶
Looks for indications that a study might be a test or QA study.
Some values that might indicate a study was for QA or similar purposes are not recorded in the database, for example patient name. Therefore this module attempts to find such indications and creates an xml style string that can be recorded in the database.
Parameters: dataset (dataset) – The DICOM dataset. Returns: str. – xml style string if any trigger values are found.
Models¶
Filtering code¶
Indices and tables¶
Note
OpenREM does not currently include a DICOM Store SCP, ie you will need to install a DICOM store server in order to send RSDRs or other DICOM files from modalities.
If you have no preference, Conquest is recommended as a free, open source, scriptable DICOM server. Please note though that you will need to include the RSRD SOP in the dgatesop.lst file.