Welcome to QATrack+’s documentation!¶
About QATrack+ v3.1.1¶
QATrack+ is a fully configurable, free, and open source (MIT License) web application for managing QC data for radiation therapy and medical imaging equipment. QATrack+ is used in many hospitals and clinics around the world!
QATrack+ is a replacement for error prone spreadsheets and other in-house databases. It brings structure and organization to your QA program while retaining much of the flexibility of spreadsheets. Built in scheduling, reports, notifications, and charts make keeping on top of your machine QA program a breeze!
The main features include:
Record & review your QC data via a user friendly web application.
Fully customized QC tests. You configure QATrack+ to record the data that is important to you. QATrack+ comes with a number of test types including:
- numerical
- text
- file upload & analysis using Python scripts (arbitrary file types including DICOM, JPG, TIFF etc)
- yes/no
- multiple choice
- calculations using Python snippets
- date & times
- and more!
Schedule your QC on a daily, weekly, monthly, semi-annual, annual or define your own custom scheduling recurrence rules.
Configure notifications to alert you when:
- Scheduled QC tests are due or overdue
- QC tests are completed
- Service events are created
- more!
Built in data charts for trending numerical test results. Data can be filtered by unit, date, or frequency, and can also be exported for external analysis.
PDF & Excel reports that can be generated on the fly, or delivered to you via email on a schedule of your choosing.
Support for multiple user groups (e.g. Administrators, Physicists, Assistants, Therapists, etc) with user & group-specific privileges and test lists, as well as a configurable user authentication system.
Easily integrate test procedures into data entry forms via embedded html or links to external documentation.
Save incomplete work and complete it a later date.
Perform manual review & approval of QC data or use Auto Review Rules to cut down your QC Review workload.
Integrated Service Log for tracking service events and machine downtime
Parts tracker for tracking spare parts on hand, part costs and vendors
The flexibility to host on an intranet or www, requiring minimal resources from IT departments. Can optionally be managed within a physics department if permitted by local institution policies.
Screenshots¶
For some example screenshots, please see the Screenshots page.
Installation & Deployment¶
QATrack+ is deployable on most operating system/server/database platform combinations. It was developed in the popular Python programming language using the Django web framework so that QC data may be entered, reviewed, and analyzed using a web browser.
Documentation for QATrack+ v0.2.7-v0.2.9¶
As of version 0.3.0 QATrack+ documentation is hosted at http://docs.qatrackplus.com. For versions prior to v0.3.0, please see the QATrack+ Wiki on BitBucket.
Problems, Questions or Suggestions?¶
Bugs or Feature Requests¶
If you have a bug to report or a feature to request please use the GitHub Issues page.
Mailing List, General Questions, Discussions or Support?¶
If you have general questions, want to have an initial discussion about features or the way things work (basically anything that isn’t a specific bug report or feature request) please use the Google QATrack+ Group Forum.
This forum is also a mailing list and it is highly recommended that you subscribe to email updates from the forum to get all the announcements about QATrack+ releases and discussions.
Commercial Support and Hosting Services¶
Commercial support and cloud hosting services for QATrack+ are now available from Multi Leaf Consulting.
Email¶
Want to discuss something directly with the QATrack+ team? Please feel free to email directly:
- Randy Taylor (QATrack+ lead developer): randy@multileaf.ca
- Crystal Angers (TOHCC QATrack+ lead): cangers@toh.ca
- Ryan Bottema (TOHCC QATrack+ developer): rbottema@toh.ca
Glossary¶
- Admin Site
- This is the section of your QATrack+ site used for configuring Tests, Test Lists, Auto Review Rules etc. See the Admin Site documentation.
- API
- The API (Application Programming Interface) is a method you can use to access and upload data to your QATrack+ programmaticaly. See the API documentation.
- Auth Token
- The API uses Auth tokens for authenticating API requests.
- Auto Review
- In QATrack+ you can set up Auto Review Rules to automatically assign Test Instance Statuss to your Test instances so that no manual review is required.
- Auto Review Rule
- See Auto Review.
- Category
- Categories define the type of test users are performing. Test Lists can be filtered by Test Category when performing QC. See Categories.
- Contacts
- Contacts are phone numbers that can be displayed to users when performing QC in case they run into any issues and need to call for help. See Contacts.
- Frequency
- Frequency is the time schedule with which a test list is to be performed (e.g. Daily, Monthly, Annual etc). See Frequency.
- Groups
- Groups are used to User s with common roles within the clinic. Groups are useful for managing Permissions for similar users. See Groups.
- Group Linkers
- Group linkers are used to specifiy individual Groups members involved in a Service Event. This information is displayed on the Service Event page in the Involved Parties and Durations frame and may be used to specifiy the various individuals involved in the Service Event (beyond those doing the actual service work). See Service Log.
- Location
- Parts storage Rooms may have one or more locations (e.g. a shelf, closet, cabinet etc) associated with them.
- Modality
- Treatment & diagnostic units may have multiple modalities assigned (for example 6MV photon & 15MeV electron). In future, it may be possible to assign Test List’s to specific Unit modalities rather than an entire Unit.
- Notification Subscriptions
- Notification subscriptions allow QATrack+ to send email alerts to different groups when a Test List is submitted with one or more Tests which are outside of Tolerance or Action levels. See Email notifications.
- Parts
- As of QATrack+ v0.3.0 there is now a Parts application which can be used for tracking spare parts inventory. See Parts.
- Parts Categories
- Parts categories allow you to categorize parts by their function (e.g. Linac, Table, Laser etc).
- Permissions
- The permissions assigned to Groups and Users control what functionality they have access to on the QCTrack+ site. See Permissions.
- QC Session
- See Test List Instance.
- Reference
- The value which Test Instance are compared to when performing QC to determine whether they are within tolerance and action levels. See References & Tolerances.
- Rooms
- Rooms are used in the Parts app for keeping track of where spare parts are located.
- Return To Service QC
- Test Lists that must be performed after a Service Event before a Unit can be released for clinical service.
- RTS
- See Return To Service QC
- RTS QC
- See Return To Service QC
- Service Area
Service Area’s are different sub systems of a treatment unit & bunker. For example:
- Treatment Table
- Lasers
- XVI
- iView
- Service Event
- A machine service event like preventative maintenance, unplanned outage etc. See Service Log.
- Service Event Status
- The status of a Service Event. Service Event Status’s indicate whether review of the Service Event is required and whether Return To Service QC must be reviewed. Example Service Event Status’s include: - Service Pending - Service In Progress - Service Complete - Approved - Test Data - Rejected
- Service Type
The type of a Service Event. For example: - Preventative Maintenance - Minor Repairs / Corrective Maintenance - Extensive Repairs - Safety Systems
See Service Log.
- Site
- For clinics with multiple sites, you can indicate which site a Unit is located at.
- Staff User
- A Staff user is any user who can access the admin section. See Users.
- Status
- See Test Instance Status
- Sublist
- To ease configuration of Test Lists, you can include other Test Lists in addition to Tests. See Sublists.
- Superuser
- A User who has Superuser status has all Permissions granted to them implicitly. See Users.
- Suppliers
- Suppliers are companies/vendors who supply your clinic with parts. See Parts.
- Test
- A Test is any individual measurement to be entered into QATrack+. Tests may be a numerical value to be entered, a true or false checkmark, text entry etc.
- Test List
- A Test List is a grouping of Test’s to be performed at the same time. For example a Test List might be “Monthly 6MV Output” and be made up of tests for temperature, air pressure, ion chamber calibration factors and ion chamber readings.
- Test List Cycle
- A Test List Cycle allows you to group multiple Test Lists into a single repeating cycle that can be assigned to a unit. See Test Lists.
- Test Instance
- A Test Instance is a single completed value of any given Test. Each Test Instance is assigned a Test Instance Status.
- Test List Instance
- A Test List Instance is a single completed value of any given Test List. Also called a QC Session.
- Test Instance Status
- A Test Instance Status is assigned to each Test Instance which indicates whether a Test Instance is reviewed/approved/rejected. See Statuses.
- Test Pack
- A file of Tests, Test Lists, Test List Cycles, and Test Categories to enable sharing configurations between different clinics. See Test Packs.
- Third Parties
- Third parties are service people, associated with a Vendor from outside the clinic who work on/repair units. See Service Log.
- Tolerance
- Tolerances, in combination with References, determine whether a Test Instance value is within tolerance or action levels. See References & Tolerances.
- Unit
- A piece of equipment e.g. a linac, brachy suite, tomotherapy unit etc. You may also want to define e.g.
- Unit Class
- Unit class is the category of Unit e.g. Linac, Tomotherapy, CT, MRI etc.
- Unit Type
- The model of a unit e.g. Elekta Synergy, Varian TrueBeam.
- Unit Service Area Memberships
- Unit Service Area Memberships are how Service Areas are associated with a Unit and are configured via the Unit admin.
- Unit Test Collection
- Unit Test Collections are how Test Lists and Frequency are associated with a Unit.
- Unreviewed Queue
- The set of Test List Instance’s that require manual review.
- User
- Any person who has the ability to login to your QATrack+ site. See User.
- Vendor
- Major equipment vendors e.g. Accuray, Elekta, Varian etc.
Release Notes¶
QATrack+ v3.1.1 Release Notes¶
This is a follow up release to address a few issues that were found in v3.1.0. The following issues have been addressed:
QA¶
- Added basic multiple choice plotting support
- Fixed a Test admin bug with the display of “Test item visible in charts”
- A message warning you about being logged out or your server not being reachable will be shown after 3 consecutive unauthenticated or failed pings. In order to disable this check set PING_INTERVAL_S = 0 in your local_settings.py file.
- The maximum frequency of autosaves has been reduced to once per 4s. This an attempt to work around occasional deadlocks with SQL Server.
- Pylinac has been updated:
- An issue with CatPhan modules CNR calculations return NaN due to the modules not having background ROIs defined has been fixed
- A bug with DMLC VMAT tests with valleys in their profiles that fell below 50% of Dmax has been fixed.
- A regression in QC3 image detection introduced in the QATrack fork of Pylinac has been remedied.
Faults¶
- Fault ID column size has been reduced.
- Fault review users are now shown as full names instead of usernames where possible
- The ability to create new fault types on the fly when entering faults is now restricted to users with the “Can Add Fault Type” permission
- Fault type matches are now case insensitive and surrounding whitespace will be stripped
Parts¶
Parts tables now allow you to sort/filter by room
API¶
- Fixed a file upload API bug where QATrack+ would try to base64 decode a null value
- The UnitTestCollection API end point should no longer return duplicated results.
- The AutoReviewRuleSetFilter API end point has been fixed.
- Fixed the fault_types field of the API’s FaultSerializer
- The API schema view will no longer throw a 500 error.
Miscellaneous¶
- A few documentation typo fixes
- Reports now respect the active/inactive status of units as well as the active/inactive status of test list assignments.
- Fixed a permissions check for deleting faults
- Reviewing faults now use the term “Acknowledge” instead of “Approve”
QATrack+ v3.1.0.1 Release Notes¶
- Attempt to fix an issue with Django Q not being able to find report types on Windows
QATrack+ v3.1.0 Release Notes¶
Acknowledgements¶
Thank you to the many people who suggested new features, contributed bug reports, and helped out testing this release. Thank you also to all of you who waited patiently and provided words of encouragement in the 2 years since the last major QATrack+ release!
Details of the v3.1.0 release¶
New version numbering¶
Given that QATrack+ is now a mature and featureful application, we are eliminating the 0. from the version number and moving from v0.3.0 to v3.1.0.
Moving to GitHub¶
QATrack+ is migrating from BitBucket to [GitHub](https://github.com/qatrackplus/qatrackplus/). As part of your update process you will be instructed to update your origin url (git remote set-url origin https://github.com/qatrackplus/qatrackplus.git).
Deprecations & Discontinuations¶
- Python 3.4 & 3.5, 3.6: Python 3.4 & 3.5 are no longer receiving updates and therefore QATrack+ will no longer be supporting those Python versions. It is also recommended that Python 3.7-3.10 be used on Windows as it simplifies the install process.
- The settings AD_DEBUG & AD_DEBUG_FILE are no longer used. Instead, information is now logged to an ‘auth.log’ file.
A new Reports tool has been added for generating and scheduling PDF & Excel reports. As part of this move the following features have now been moved to a report rather than a standalone page:
- Paper Backup Forms
A new Query Tool has been added for advanced query and reporting. (You must set USE_SQL_REPORTS = True in your local_settings.py file to use this feature).
- Notifications have been expanded & improved.
- You can now send notifications on test lists being completed.
- You can now specify to send notifications to individual users as well as groups.
- You can now specify that a given notifications will only be sent for specific units or test lists.
- New QC Scheduling & Unreviewed QC Notices.
- Service event creation & update notices.
- Parts low inventory notices.
- Machine faults
A new Autosave feature has been implemented to automatically save test list instance data temporarily to prevent data loss when a user mistakenly navigates away from the page while entering QC data.
A new Users & Groups Page has been added to simplify the management of Group membership and group permissions.
A new Fault log feature for recording machine faults.
You can now create Service Event Templates and schedule them in a similar manner to scheduling QC work.
- Composite Tests will now raise an error if they return anything other than a numerical value, None, or an empty string (“”). Previously it was possible to return e.g. a string which would have resulted in the test being skipped. If you were relying on this behaviour, you need to switch to using a String Composite/JSON test type instead.
- The day key is now required when performing a Test List Cycle via the API
- Upload tests can not have reference/tolerance values set. Allowing this originally was an implementation oversight.
- EMAIL_NOTIFICATION_SENDER must be set to a valid email address, not just a name.
New test types including:
- Date and Date & Time test types to allow users to select dates/times with a calendar widget. These test results will be available in calculation contexts as Python date, and datetime values respectively.
- Wraparound test type have been added. This test type allows you to define a test that “wraps around” at a minimum and maximum value. This type of test is useful for example if you have a collimator/gantry readout test and want to consider 359.9 deg a 0.1 deg difference from a 0 deg reference.
A new “Display Name” field has been added to tests. This is an optional field where you can add text describing how a test should be displayed when performing or reviewing. Having a separate name & display name allows you to create tests with descriptive names that are easy to find in the admin area, but use a more succinct name when performing a Test List. If left blank, the test name will be used.
A new “Require Comment” option has been added to force users to enter a comment before submitting a test.
It is now possible to perform a test and not have the due date advanced by de-selecting the “Include for Scheduling” option.
Calculation procedures are now syntax checked, and automatically formatted using Black.
Numerical tests now have an optional Formatting field to control how their results are displayed. For example a test with a formatting of “%.2E” will use scientific notation with 2 decimal places (3 sig figures).
Non-calculated test types (e.g. simple numerical, multiple choice, string, etc) may now use the calculation_procedure to set default initial values.
Added UTILS.set_skip and UTILS.get_skip functions for setting/getting skip status of tests.
Using UTILS.set_comment in a calculation will now open the comment box on the front end.
Setting the Warning message field to blank on a TestList will now prevent a warning message/banner from being shown when tests are at action level.
Calculated tests are now included in Paper Backup Forms (now a Report) by default
Frequency dropdown lists when choosing a unit to perform QC on will now only show Ad Hoc if that unit has ad hoc test lists assigned
There are new Tree Views available (under the Perform QC menu) for viewing/selecting QC assigned to units.
There is a new MAX_TESTS_PER_TESTLIST setting (default is 250 tests per test list)
- Test.auto_review has been replaced by new AutoReviewRuleSet’s that allow you to apply different AutoReviewRules to different tests. For more information see the Auto Review page.
- A new Bulk Review feature has been added to allow setting review & approval status for multiple test list instances at the same time.
- New management commands review_all_unreviewed and clear_in_progress have been added. review_all_unreviewed updates the status of all unreviewed test list instances, while clear_in_progress will delete all in progress test lists.
- A new Collapse option has been added to the Unit Type model to allow collapsing less frequency used unit types in user interface.
- Unit modalities are now labeled as Treatment or Imaging Modality
QA -> QC: In most places in the UI the initials QA have been replaced by QC. This change was made to reflect that while QATrack+ is a tool for managing the QA program of radiation therapy programs, the data collected in QATrack+ is QC data.
Improved the ordering and organization of unit, frequency, and test lists fields when assigning a test list to a unit. Also improve UnitType dropdown for Unit Admin.
The Unit admin page now has “Save as New” as an option to make it easier to create new units using an existing unit as a template. You can also now leave the unit number blank to have it assigned automatically.
Staff Status has been renamed to Admin Status to reflect the fact that almost all QATrack+ users are “Staff”!
Test Instance points with comments associated with them are now highlighed in charts
Clicking on a chart link beside a tests history will now set the date range for the chart to the larger of a span of 1 year, or span between the first and last history items. This results in a chart of say the last 5 years of data for an annual QA item rather than just the single point from the most recent year.
Keyboard entry of dates is now permitted for Work Started & Work Completed dates when performing QC
New dropdown on Unit selection buttons to allow selecting QC to perform based on Test categories.
A calculation status icon has been added (spins when calculations are being performed).
Add test type css class to test rows. Allows you to target different test types in site.css like:
.qa-boolean, .qa-numerical { background-color: rgba(0, 0, 0, 0.05); }
The In Progress label will now only display the count of in progress test lists visible to the users rather than the total count.
History & Unreviewed listing pages will now show a paperclip icon if the test list instance has at least one attachment.
ID attributes have been added to many elements on the pages for performing/editing test lists to make them easier to target with JavaScript.
For installations with Units assigned to multiple ‘Sites’, a new ‘Site’ column has been added to many of the views used for selecting TestList assignments and TestListInstances.
- Inline links to edit and delete foreign key choices have been disabled in all QATrack+ admin models. Editing or deleting a foreign key object here has always been a poor workflow that lead to confusion for users.
- Setting multiple references & tolerances now allows removing tolerances.
- Setting multiple references & tolerances will now include an entry in that UnitTestInfo’s change log
- A number of bug in the API have been fixed including:
- a bug which was causing extra information to be returned for list views has
been fixed. This may require you to adjust scripts if you were relying on:
- permissions or user_set data present in the Groups list view
- first_name, last_name, date_joined, permissions in the User List view
- Fields other than name, number, or site in the Unit list
- Bugs with filtering for exact matches of search strings have been resolved.
- First Name & Last Name have been added to the user-list api view
- When dependencies of a composite test are skipped and the composite test itself is not skipped, an error letting the user know to skip the composite test explicitly is now shown.
- a bug which was causing extra information to be returned for list views has
been fixed. This may require you to adjust scripts if you were relying on:
- The UnitTestCollection API results now include “next_day” and “next_test_list” parameters to make it simple to determine which test list is to be performed next in a test list cycle.
- The TestList API results now includes a field “test_lists” which is a list of all the sublist test lists for that TestList.
- The banner at the top of the browsable API now says “QATrack+ API” rather than Django Rest Framework and now the link directs to the main site rather than DRFs site.
- It is now possible to perform a test and not have the due date advanced by setting “include_for_scheduling”: False, in your API post data.
- The day key is now required when performing a Test List Cycle via the API
- The USE_SERVICE_LOG and USE_PARTS settings have been removed. Permissions are suitable for hiding the UI elements if you don’t want to use service log or parts, but having these settings can complicate some views and testing.
- Added option to Group Linkers to make a given Group Linker required when submitting a ServiceEvent.
- There is a new New or Used field on Parts to allow you to track new and used inventories of the same part separately.
- A new setting SL_ALLOW_BLANK_SERVICE_AREA has been added to optionally allow users to submit ServiceEvents without a ServiceArea set explicitly.
- A new setting SL_ALLOW_BLANK_SERVICE_TYPE has been added to optionally allow users to submit ServiceEvents without a ServiceType set explicitly.
- Parts Supplier details have been expanded to include phone numbers, website, address and contact information
- Part supplier details pages have been added to show what parts are available from each supplier as well as company & contact details.
- You may now add attachments & images to Parts. Images will be shown inline in the parts listing table and parts detail pages.
- Service Log Status now have an order field to allow you
- You can now create Service Event Templates and schedule them in a similar manner to scheduling QC work.
- There is now an app for logging machine faults.
The default authentication backend setting is now:
AUTHENTICATION_BACKENDS = ( 'qatrack.accounts.backends.QATrackAccountBackend', )
the QATrackAccountBackend is a simple wrapper around the Django ModelBackend to allow usernames to be transformed prior to authentication. The transform is controlled by the ACCOUNTS_CLEAN_USERNAME settings.
A new ACCOUNTS_SELF_REGISTER setting has been added to control whether users are allowed to register their own accounts.
A new ACCOUNTS_PASSWORD_RESET setting has been added to control whether users are allowed to reset or change their own passwords.
Users can now automatically be added to QATrack+ groups based on their AD group memberships using . Active Directory Groups to QATrack+ Group Map’s
The AD_MEMBERSHIP_REQ was previously not functional and has now been replaced by Qualifying Groups’s
When a user logs in through the AD backend, their email address, first name, and lastname will be updated to match the values found in Active Directory.
The DEFAULT_GROUP_NAMES setting has been removed. Instead, QATrack+ groups now have a default group flag. Anytime a user logs into QATrack+, they will automatically be added to any group with this flag set.
- Fixed bug with control charts and null valued / skipped tests. #506
- Fixed bug with selecting Test List Cycle days from sidebar menu
- QATrack+ by default will now use the database for caching rather than the filesystem. This should have comparable or better performance and eliminate the occassional 500 errors generated on Windows servers due to file permissions & access issues.
- Some python packages have been updated
- pydicom updated to 2.1.2
- numpy updated to 1.20.0
- matplotlib updated to 3.3.4
- scipy updated to 1.5.4
What didn’t make it into this release?¶
- Translations Unfortunately there is still quite a bit of work to be done in order to get QATrack+ translated into other languages. Translations are currently low on the developers priority list so without outside contributions it is hard to say when this will be completed. However, incremental progress is being made in this direction and templates and strings are gradually getting marked for translation.
QATrack+ v0.3.0.18 Release Notes¶
- Fixed the UnitTestCollection queryset in the API
- Updated requirements to work with Python 3.7 & new versions of pip
QATrack+ v0.3.0.18 Release Notes¶
- Fixed a bug where Test Lists from Test List Cycles with Ad-Hoc frequency would not show up when charting
QATrack+ v0.3.0.16 Release Notes¶
- Allow disabling warning message by setting TestList.warning_message blank
- Add test type to html class for qa-valuerows so they can more easily be targeted in JavaScript code.
QATrack+ v0.3.0.15 Release Notes¶
- The Active Unit Test Info filter was fixed
- Fixed minimum width of Category display when performing QC tests
- Added new setting CATEGORY_FIRST_OF_GROUP_ONLY. When True, if there is a group of sequential tests with the same category, only the top most category name will be shown to allow better visual separation of groups of categories. Currently this defaults to False to maintain current behaviour but this will default to True for the v3.1.0 release.
Upgrading to v0.3.0.15 from v0.3.0¶
If you haven’t upgraded to v0.3.0 yet see instructions for v0.3.0 below. If you’ve already upgraded to v0.3.0 then to upgrade to v0.3.0.15:
Open shell and activate your Python 3 virtual environment then:
git fetch origin git checkout v0.3.0.15 python manage.py collectstatic python manage.py clearcache
On Linux sudo service apache2 restart on Windows, restart QATrack3 CherryPy Service
QATrack+ v0.3.0.14 Release Notes¶
A patch was made to fix a security flaw in LDAP/Active Directory Authentication. This patch is only required if you use LDAP/Active Directory for authenticating your users.
To patch your system, please follow the following instructions for your version:
v0.3.0.x:
Windows. Open a Powershell Window then:
cd C:\deploy .\venvs\qatrack3\Script\Activate.ps1 cd qatrackplus git fetch origin git checkout v0.3.0.14 python manage.py shell -c "from qatrack.accounts.utils import fix_ldap_passwords; fix_ldap_passwords()" python manage.py collectstatic
then restart the CherryPy service
Linux. Open a terminal:
cd ~/web/qatrackplus source ~/venvs/qatrack3/bin/activate git fetch origin git checkout v0.3.0.14 python manage.py shell -c "from qatrack.accounts.utils import fix_ldap_passwords; fix_ldap_passwords()" python manage.py collectstatic sudo service apache2 restart
v0.2.9.x:
Windows. Open a Powershell Window then:
cd C:\deploy .\venvs\qatrack\Script\Activate.ps1 cd qatrackplus git fetch origin git checkout v0.2.9.2 python manage.py shell >>> from qatrack.accounts.utils import fix_ldap_passwords; fix_ldap_passwords() >>> exit() python manage.py collectstatic
then restart the CherryPy service
Linux. Open a terminal:
cd ~/web/qatrackplus source ~/venvs/qatrack3/bin/activate git fetch origin git checkout v0.2.9.2 python manage.py shell >>> from qatrack.accounts.utils import fix_ldap_passwords; fix_ldap_passwords() >>> exit() python manage.py collectstatic sudo service apache2 restart
v0.2.8.x:
Windows. Open a Powershell Window then:
cd C:\deploy .\venvs\qatrack\Script\Activate.ps1 cd qatrackplus git fetch origin git checkout v0.2.8.1 python manage.py shell >>> from qatrack.accounts.utils import fix_ldap_passwords; fix_ldap_passwords() >>> exit() python manage.py collectstatic
then restart the CherryPy service
Linux. Open a terminal:
cd ~/web/qatrackplus source ~/venvs/qatrack3/bin/activate git fetch origin git checkout v0.2.8.1 python manage.py shell >>> from qatrack.accounts.utils import fix_ldap_passwords; fix_ldap_passwords() >>> exit() python manage.py collectstatic sudo service apache2 restart
QATrack+ v0.3.0.13 Release Notes¶
For full details of v0.3.0 see the v0.3.0 release notes below. v0.3.013 is a patch to v0.3.0 that fixes a few minor issues.
- Service Events have been added to the admin so they can now be hard deleted.
- A few bugs with testpacks has been fixed including where Sublist tests were not created correctly when creating test packs.
- A number of bugs with the API have been fixed.
- A bug with the initial v0.3.0 migration has been fixed for those who have SITE_ID ~= 1 in their settings file.
- skipped tests are now excluded by default from UTILS.previous_test_instance.
- Bug where the Test List Members drop down would not be populated correctly due to conflicting jQuery versions has been resolved.
Upgrading to v0.3.0.13 from v0.3.0¶
If you haven’t upgraded to v0.3.0 yet see instructions for v0.3.0 below. If you’ve already upgraded to v0.3.0 then to upgrade to v0.3.0.13:
Open shell and activate your Python 3 virtual environment then:
git fetch origin git checkout v0.3.0.13 python manage.py collectstatic python manage.py clearcache
On Linux sudo service apache2 restart on Windows, restart QATrack3 CherryPy Service
QATrack+ v0.3.0 Release Notes¶
It’s been two years since the release of QATrack+ v0.2.9 and this release marks the largest update to QATrack+ since the initial release in 2012. Details of QATrack+ v0.3.0 are included below.
Acknowledgements¶
Many thanks to Ryan Bottema & Crystal Angers at The Ottawa Hospital for all their work on the development and implementation of the new Service Log app (with guidance and QA from the rest of the Ottawa QATrack+ team!).
Thank you to Simon Biggs for all his work on the new experimental Docker deployment method as well as ideas and discussions on many other features.
Thanks to all of you who provided databases for testing the data model migration from 0.2.9 to 0.3.0. This helped catch a few DBMS specific migration issues. There were also a number of people who tested the migration / update procedure before this releae which is hugely appreciated!
A big thanks also goes out to the Canadian Nuclear Safety Commission! QATrack+ was one of the recipients of the 2017 CSNC’s Innovation Grant which provided financial support for this release.
Last but certainly not least, thank you to those of you who have submitted bug reports, made feature requests, and contributed to the many discussions on the mailing list.
Details of the v0.3.0 release¶
- A new Service Log application for tracking machine service events, machine down time, return to service, and more!
- A new Parts application for tracking spare parts, where they’re located, how many are in inventory, and their vendors.
- Sublists have been updated and improved and can now have their order rearranged within the parent test list as well as optional visual emphasis when performing a test list.
- The user interface has been updated to be a bit more modern while hopefully remaining familiar to existing QATrack+ users.
- Pylinac is now installed by default. Images can be uploaded, analyzed, and displayed inline within test lists.
- Experimental support for importing/exporting Testpacks for exchanging test configurations with other QATrack+ installations.
- An Application Programming Interface (API) has been added for allowing external applications and scripts to access and upload data to your QATrack+ server.
- When reviewing data by Due Status you can now filter by unit.
- After creating a Unit Test Collection, it is no longer possible to change the test list (cycle) assigned to it. This is in order to prevent unintended data loss.
- You can now assign a tolerance to boolean tests.
- The ability to save test lists is now an assignable user permission.
- Entire units can now be marked as inactive to make it easy to hide units when they are decomissioned.
- Hidden tests can now be autoreviewed.
- When choosing a unit to peform QA on, rather than showing all defined frequencies, the drop down lists for test frequencies are now limited to frequencies of test lists assigned to that unit.
- A new “experimental” method of deploying QATrack+ using Docker is available. This method makes it very easy to get a complete QATrack+ installation up and running. Currently marked as experimental as it has not been deployed in production anywhere. Thank you very much to Simon Biggs for putting this idea forward and then getting it all implemented in a sensible way!
- When a reference or tolerance for a test is updated, the history of the users who made the change, when the changes was made, the previous reference and tolerance, and an optional comment are now stored.
- It’s now possible to set (or read) the comment for a test instance from the tests calculation procedure.
- Default email notifications are now sent as html emails with a link to the relevant test list instance
- Notification emails are no longer sent to inactives users.
- When performing a test list, the number of existing in-progress sessions for the same test list is now shown in the UI. The total number of test lists in progress is also now shown in the main drop down menus.
- Comments can now be added when reviewing test list instances and comments on test list instances now <record the username and timestamp of the comment.
- If a composite test or upload test generates a “Server Error”, the error can now be seen by hovering your mouse over the Status column for the test.
- The UX for deleting a test list has been improved.
- Upload tests now have two context variables available FILE and BIN_FILE, the latter being a file instances opened in binary rather than text mode. Any existing upload tests that you have which assume a binary file type will need to be updated to use BIN_FILE. More details are available in the v0.3.0 installation docs.
- Mainstream support for Python 2 is ending in 2020 and as such QATrack+ has been updated to use Python 3.4-3.6.
- The complete list of bugs/features can be found on BitBucket
Upgrading to v0.3.0¶
For instructions on upgrading to QATrack+ 0.3.0 please see the installation docs for your platform.
QATrack+ v0.2.9 Release Notes¶
There have been many bug fixes and improvements to QATrack+ made since the version 0.2.8. For the complete details you can check out the issue tracker for issues tagged 0.2.9.
Special thanks for this release to Zacharias Chalampalakis for contributing a patch to make the warning message shown when a test is at action level configurable.
Also, big thanks to Ryan Bottema in Ottawa who has taken over my previous role at the Ottawa Hospital and has made many contributions to this release and been crucial in finally getting it out the door.
As always Crystal Angers has been a big help in testing and critical analysis of new features.
Details of 0.2.9 below:
- Multiple choices tests now store their results as the test value rather than the index of the choice. It is important that you update any composite tests that rely on multiple choice test results after this upgrade (see Upgrade Instructions below)
- Unit modalities are now free text fields instead of forcing you to select particle/energy.
- If you attempt to access a QATrack+ page but are logged out, you will be redirected to that page after logging in
- You can now add REVIEW_DIFF_COL = True to your local_settings.py file to enable an extra column showing the difference from reference when reviewing tests list
- Users sessions will be renewed anytime they are active on the QATrack+ site rather than just when they perform QA (prevents being logged out automatically)
- Changing a Test’s type is now limited to only allow changes to similar test types (e.g. numerical -> composite is allowed but numerical -> string is not)
- By default inactive test lists are no longer shown in the default review list
- Bulk deletion of UnitTestInfo objects in the admin has been disabled to prevent possible data loss
- Only active UnitTestInfo objects will be shown in the admin by default
- You can now view test list comments in a pop over by hovering your mouse over the comment icon
- You can now filter Test objects in the admin by whether or not they belong to any active TestList’s or not
- If a comment is included when performing a test list than manual review will be required regardless of auto-review settings
- Inactive tests can now be filtered on the charts page
- There are many new filters available in the admin section
- Permissions for reviewing and viewing the program overview have been split
- Individual tests can now be configured to always allow skipping without a comment (regardless of the users permissions)
- You can now set a custom label for the “Choose Day” drop down label when performing a test list from a cycle.
- You can now sort test lists by due date
- You can now customize the test status display (default remains Act/Tol/OK)
- Test value input fields should now be more mobile device friendly
- pydicom is now available in the default calculation context (along with numpy & scipy)
- You can now filter test lists to review by which groups the test lists are visible to
A more complete list of bugs fixed and features added can be found in the issues tracker!
Deprecation Notices¶
As QATrack+, Python & Django and the web continue to evolve, occassionally we need to deprecate some of the versions of Python & web browsers we support. The next major release of QATrack+ will no longer officially support the following items:
- Python 2.6 (Python 2.7 & 3.4+ only): In order to provide support for Python 3 we will be dropping support for Python 2.6
- IE7-IE10 (IE 11+ Only): IE7-IE10 are no longer supported by Microsoft and we will no longer be testing these platforms.
Upgrade Instructions¶
For instructions on how to upgrade from v0.2.8 please see the wiki
QATrack+ v0.2.8 Release Notes¶
This release introduces some database schema changes. The database migrations have been tested on SQLServer, PostgreSQL, MySQL & SQLite but it is important that you:
BACK UP YOUR DATABASE BEFORE ATTEMPTING THIS UPGRADE
There are lots of minor enhancements & a number of new features in this release of QATrack+.
Special thanks for this release go to Wenze van Klink from VU Medisch Centrum Amsterdam. Wenze contributed a couple of great features to QATrack+ for this release including:
- The ability to easily copy references & tolerance from one Unit to another. A nice time saver!
- The ability to set references and tolerances for multiple tests at the same time. Want to set 20 tests to have a reference value of 100? Now you can do it with just a few clicks.
- Display uploaded images (jpg, png, gif) on the test list page.
- a number of other bug fixes & minor features.
Great work Wenze…your contributions are greatly appreciated!
Also of note, Gaspar Sánchez Merino has produced a Spanish translation of the QATrack+ documentation. Thanks a lot Gaspar! You can find the translation on Gaspar’s BitBucket page.
Here’s a list of some of the changes in this release:
- The documentation has been split into different versions (corresponding to QATrack+ releases) to accomodate users who are not running the latest version of QATrack+.
- You can now embed uploaded images right on the test list page
- You can now choose to hide tests from the list of tests to plot. Handy to limit the chart test selection lists to only those tests you are interested in plotting.
- There is now an “Auto Review” feature that can be configured so that only test which are at tolerance or action levels will be placed in the review queue.
- Page load speeds for the charting page have been greatly improved for large databases
- You can now configure your site to use icons in addition to colors to indicate pass/fail & due/overdue. This should help with usability for color blind users. Thanks to Eric Reynard for the great suggestion! Examples of the icons can be seen on BitBucket
- Python code snippets and html test/test list descriptions are now syntax highlighted on modern browsers
- Composite & constant tests no longer need to be skipped manually
- When charting you can now combine data for the same test from different test lists (thanks to Eric Reynard for the suggestion)
- Data can now be plotted relative to its reference value (thanks to Balazs Nyiri for the suggestion)
- CSV export files should now work on IE8 & 9
- A new permission has been added to control who can review their own test results
- It’s now possible to easily copy references and tolerances between units
- Easily set references & tolerances for multiple tests at the same time
- You can now tweak the look of your QATrack+ site with css using a site specific css file
- You can now configure your site to order the Units on the “Choose Unit” page by number or name.
- QATrack+ now is using a file based cache to decrease page load times. By default the cache data is located at qatrack/cache/cache_data/ but this can be changed if required.
- You can now assign multiple choice tolerances to string/string composite test types (thanks to Elizabeth McKenzie for the suggestion).
- You can now access reference and tolerance values for tests in your calculated tests (thanks to Andrew Alexander from Saskatoon for the suggestion)
- a number of other bug fixes and performance enhancements
Upgrading to v0.2.8¶
Note: If any of these steps results in an error, *stop* and figure out why before carrying on to the next step!
From the git bash command shell (with your QATrack+ virtual env activated!):
- git pull origin master
- pip install -r requirements/base.txt
- python manage.py syncdb
- python manage.py migrate
- python manage.py collectstatic
- restart the QATrack+ app (i.e. the CherryPy service or Apache or gunicorn or…)
QATrack+ v0.2.7 Release Notes¶
Note: this release introduces some database schema changes. It is a good idea to BACK UP YOUR DATABASE BEFORE ATTEMPTING THIS UPGRADE
Version 0.2.7 has a quite a few improvements to the code base behind the scenes, some new features and a number of bug fixes. Please see the guide to upgrading to version 0.2.7 below.
A note on QATrack+ and security is now available on the wiki.
Special thanks for this release go to Eric Reynard of Prince Edward Island. Eric has contributed a new authentication backend and tutorial on running QATrack+ with IIS, FastCGI and Windows Integrated Authentication. Thanks Eric!
New Features & Bugs Fixed¶
Three new test types have been added:
- File upload: Allows you to upload and process arbitrary files as part of a test list
- String: Allows you to save short text snippets as test results
- String Composite: A composite test for text rather than numerical values
Composite tests no longer need to assign to a result variable. Instead you can just assign the result to the composite test macro name (e.g. my_test = 42 is now a valid calculation procedure). This is now the recommended way to write calculation macros.
Tests with calculated values now have a ‘META’ variable available in the calculation context that includes some useful information about the test list being performed.
Easy export of historical test results to CSV files
New tool for creating basic paper backup QA forms to be used in the event of a server outage. See the paper backup wiki page for more information. This feature is currently quite primitive and suggestions on how to improve it are welcome!
TestListCycle’s can now contain the same TestList multiple times. Thanks to Darcy Mason for reporting this bug.
Unit’s that have no active TestList’s will no longer appear on the Unit selection page
- Changes to Reference & Tolerances:
- Tolerances no longer require all 4 of the tolerance/action levels (Act Low, Tol Low, Act High, Tol High) to be set making it possible to create pass/fail only, pass/tolerance only and one-sided tolerances. See the Tolerances wiki page for more information.
- Duplicate tolerances can no longer be created (there is no use for duplicate tolerances)
- Tolerances can no longer be named by the user and are now automatically given a descriptive name based on their tolerance and action levels. This is to help emphasize the fact that Tolerance values are not test specific.
- As part of the 0.2.7 database update, all duplicate tolerance & reference objects in the database are going to be deleted and any test value currently pointing at these tolerance & reference values will be updated to point at the correct non-duplicated tolerance/reference. At TOHCC this resulted in reducing the size of references database table by about 90% (from ~2700 rows to ~200 rows).
A new authentication backend using Windows Integrated Authentication has been added. Thanks to Eric Reynard for contributing this!
New user account pages for viewing permissions and updating/resetting passwords.
Page permissions have been improved slightly and two new permisions have been added:
- qa | test instance | Can chart test history (Allows users to access charts page)
- qa | test list instance | Can view previously completed instances (Allows users to view but not edit or review (change the status) of historical results. Please see the wiki for more information.
Page load time reduced by using more efficient unreviewed count query
Charts page now allows plotting of data for tests which are no longer active
- Test data is now grouped by TestList when generating charts (i.e. multiple lines are
produced if the same Test exists in multiple TestList’s)
Upgrading to v0.2.7¶
_Note: If any of these steps results in an error, stop and figure out why before carrying on to the next step!_
From the git bash command shell (with your QATrack+ virtual env activated!):
git pull origin master
pip install -r requirements/base.txt
python manage.py syncdb
python manage.py migrate
python manage.py collectstatic
restart the QATrack+ app (i.e. the CherryPy service or Apache or gunicorn …)
In the Admin –> Auth –> Groups section of the website grant the new permissions
- qa | test instance | Can chart test history
- qa | test list instance | Can view previously completed instances
to any groups that require this functionality. See the Managing Users & Groups page for more information on permissions. 1. In order to use the new file upload test type, you must configure your server to serve all requests for http(s)://YOURSERVER/media/* to files in qatrack/uploads/ directory. More information about this is available on the deployment wiki pages. If you need help with this part please post in the QATrack+ Google group. If you don’t plan on using the file upload test type, this step is not required.
QATrack+ v0.2.6 Release Notes¶
Note: this release introduces some database schema changes. BACK UP YOUR DATABASE BEFORE ATTEMPTING THIS UPGRADE
v0.2.6 includes a number of bug fixes
Thank you to Eric Reynard and Darcy Mason for their bug reports.
New Features¶
- You can now manually override the due date for a Test List on a Unit
- You can turn off the auto scheduling of due dates for Test Lists on Units
- Test Lists no longer need to have a Frequency associated with them when assigned to a Unit (allows for ad-hoc Tests)
- new management command auto_schedule (see wiki)
- Selecting a different day in a Test List Cycle no longer requires you to click Go
- When references aren’t visible, Users will only be shown ‘OK’ or ‘FAIL’ instead of ‘OK’, ‘TOL’ or ‘ACT’
- Minor improvements to the charts page layout
- Reference values are now included in data displayed on chart page
- Test List description can now be displayed on the page when performing or reviewing QA
- Improved performance when saving data from test lists with lots of tests.
- New permission Can skip without comment added to allow some users/groups to skip tests without adding a comment
- Comment counts are now displayed in Test List history listings
- Now only Units which have Test Lists visible to the user will be displayed.
- The first page of all listings is now pre-rendered for faster page load times
- Input lag when performing QA using IE has now been reduced (although it is still highly recommended that you use Chrome or Firefox!)
- Deploying QATrack+ under a sub directory of your server should now be handled a little better (requires setting FORCE_SCRIPT_NAME in your local_settings.py file)
- There is now a View on Site button that will allow you to go directly to the Perform QA page from a UnitTestCollection (Assign Test List to Unit) page in the admin
- Some other minor cosmetic enhancements
- majority of code now conforms with pep8
Bug Fixes¶
- Unique Char fields limited to a length of 255 to fix issue with MySQL
- Fixed formatting of due date displays
- Increased the precision with which data is displayed in chart tool tips
- Fixed “Absolute value” wording mixup when defining tolerances
- Fixed errors when adding new tests to a sublist
- Plotting data with one of the chart buttons will now only select the relevant Test Lists
- Chart reference lines are now plotted in the same colour as the actual plot line
- Fixed issue when navigating between inputs on filtered lists
- Fixed issue with missing history values for Test List cycles
- Added missing filter for “Assigned To” column on Test List listings
- The value 0 should no longer be shown in scientific notation
- Fixed issue with non linearly spaced graph data
- various other issues
To upgrade from v0.2.5¶
Note: this release introduces some database shema changes. BACK UP YOUR DATABASE BEFORE ATTEMPTING THIS UPGRADE
From the git bash shell in the root directory of your QATrack+ project
1. git pull origin master 1. python manage syncdb 1. python manage.py migrate 1. python manage.py collectstatic
QATrack+ v0.2.5 Release Notes¶
This release fixes some issues with control charts and makes test list pages orderable and filterable.
There are no database schema changes in this release so updating should just be a matter of pulling the latest release from git.
Changes in this release include:
- A number of improvments to the control chart functionality have been made
- Test lists and completed sessions are now sortable & filterable without a page refresh.
- On the overview page, you cannow collapse/expand the Units so that you can review one Unit at a time.
- Scientific notation is now used to display composite test results for large & small values.
- The behaviour when determining whether a value exactly on a pass/tolerance or tolerance/fail border has been improved (see issue 207.
- numpy & scipy are now available in the composite calculation context
- All test variable names (whether they have values entered for them or not) are now included in the composite calculation context.
- Crash in admin when “saving as new” with missing tests has been fixed.
- default work completed date is now an hour later than default work started.
- Fixed display of work completed date for last session details (time zone issue)
- Some other bug fixes and cleanup
QATrack+ v0.2.4 Release Notes¶
This release introduces South for managing database schema migrations. In order to update an existing database, you need to do the following:
- pip install south
- checkout version 0.2.4 code (e.g. git pull origin master)
- python manage.py syncdb
- python manage.py migrate qa 0001 –fake
- python manage.py migrate units 0001 –fake
- python manage.py migrate qa
New Features¶
- added South migrations
- added description field to TestInstance Status models (displayed in tooltips when reviewing qa)
- Added new review page for displaying Test Lists by due date
- Added new review page for displaying overall QA Program status
Bug Fixes and Clean Up¶
- removed salmonella urls from urls.py
QATrack+ v0.2.3 Release Notes¶
This release has a number of small features and bug fixes included.
New Features¶
- Greatly improved permissions system. Group/user specific permissions are no longer only controlled by the is_staff flag
- TestListCycle’s now display the last day done
- You can now delete TestListInstances from the admin interface or when reviewing (redirects to admin)
- Cleaned up interface for choosing a unit a bit.
Bug Fixes¶
- Fixed js null bug when charting (see issue #189)
- Fixed expiring cookie issue that could potentially cause QA data to be lost when submitted.
- Deleting a UnitTestCollection no longer causes a server fault.
- more
Installation and Deployment Options¶
Selecting a platform for QATrack+¶
Currently there are two “officially” supported platforms for deploying QATrack+ on: 1) Ubuntu Linux (18.04+) with PostgreSql (or MySQL) and 2) Windows Server 2017+ with SQL Server.
The platform you choose will generally depend on what type of system you or your clinic has the most expertise in and / or your budget (Microsoft tools can be expensive!).
New Installation of QATrack+ v3.1.1 on Ubuntu Linux¶
Note
This guide assumes you have at least a basic level of familiarity with Linux and the command line.
This guide is going to walk you through installing everything required to run QATrack+ on an Ubuntu 20.04 LTS (Focal Fossa) server with Python 3.8, Apache 2.4 as the web server and PostgreSQL 12 (MySQL 8.0) as the database. The instructions have also been tested on Ubuntu 18.04 and installation instructions should be similar on other Ubuntu systems. Similar steps will also likely work on other Linux distributions but those distributions are not officially supported or tested.
If you are upgrading an existing QATrack+ installation, please see one of the following pages:
- Upgrading an existing v0.3.0 installation to v3.1.1.
- Upgrading an existing v0.2.X installation to v3.1.1.
The steps we will be undertaking are:
- Prerequisites
- Installing and configuring Git and checking out the QATrack+ Source Code
- Installing a Database System
- Setting up our Python environment (including virtualenv)
- Making sure everything is working up to this point
- Configuration of QATrack+
- Setting up Django Q
- Installing Apache web server and mod_wsgi
- Next Steps
- Last Word
If you hit an error along the way, stop and figure out why the error is occuring before proceeding with the next step! You can seek help on the on the mailing list.
Prerequisites¶
These install steps should be done using a regular user account. They will not work if you are currently logged in as ‘root’. If you have don’t have a regular user account you should set one up before continuing.
Make sure your existing packages are up to date:
sudo apt update
sudo apt upgrade
You will need to have the make command and a few other packages available for this deployment. Install install them as follows:
sudo apt install make build-essential python3-dev python3-tk python3-venv
You will also need the Chrome browser installed for generating PDF reports:
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
Installing and configuring Git and checking out the QATrack+ Source Code¶
QATrack+ uses the git version controls system. Ensure you have git installed with the following command:
sudo apt install git
and then configure git (substituting your name and email address!)
git config --global user.name "randlet"
git config --global user.email randy@multileaf.ca
Now that we have git installed we can proceed to grab the latest version of QATrack+. To checkout the code enter the following commands:
mkdir -p ~/web
cd web
git clone https://github.com/qatrackplus/qatrackplus.git
cd qatrackplus
git checkout v3.1.1
Installing a Database System¶
It is highly recommended that you choose PostgreSQL for your database, however it is possible to use MySQL/MariaDB if you need to.
If you do not have an existing database server, you will need to install PostgreSQL locally. Run the following commands:
sudo apt-get install postgresql libpq-dev postgresql-client postgresql-client-common
After that completes, we can create a new database and Postgres user (db name/user/pwd = qatrackplus31/qatrack/qatrackpass) as follows:
cd ~/web/qatrackplus
sudo -u postgres psql < deploy/postgres/create_db_and_role.sql
And then create a readonly user for the SQL query tool:
sudo -u postgres psql < deploy/postgres/create_ro_role.sql
Now edit /etc/postgresql/12/main/pg_hba.conf (use your favourite editor, e.g. sudo nano /etc/postgresql/12/main/pg_hba.conf (note, if you have a different version of Postgres installed, then you would need to change the 12 in that path e.g. /etc/postgresql/9.3/main/pg_hba.conf) and scroll down to the bottom and change peer to md5 for the local all all entry so it looks like:
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all md5
host replication all 127.0.0.1/32 md5
host replication all ::1/128 md5
and restart the pg server:
sudo service postgresql restart
sudo apt-get install mysql-server libmysqlclient-dev
Note
You should use the InnoDB storage engine for MySQL. If you are using MySQL >= 5.5.5 then it uses InnoDB by default, otherwise if you are using MySQL < 5.5.5 you need to set the default storage engine to InnoDB: https://dev.mysql.com/doc/refman/5.5/en/storage-engine-setting.html
Now we can create and configure a user (db name/user/pwd = qatrackplus31/qatrack/qatrackpass) and database for QATrack+:
# if you set a password during mysql install
sudo mysql -u root -p < deploy/mysql/create_db_and_role.sql
# if you didn't
sudo mysql < deploy/mysql/create_db_and_role.sql
And then create a readonly user for the SQL query tool:
# if you set a password during mysql install
sudo mysql -u root -p < deploy/mysql/create_ro_role.sql
# if you didn't
sudo mysql < deploy/mysql/create_ro_role.sql
Setting up our Python environment (including virtualenv)¶
Version 3.1.1, runs on Python 3.6, 3.7, 3.8, & 3.9 Check your version of python3 with the command:
python3 -V
Which should show the result Python 3.6.8 or similar. In order to keep QATrack+’s Python environment isolated from the system Python, we will run QATrack+ inside a Python Virtual Environment. To create the virtual environment run the following commands:
mkdir -p ~/venvs
python3 -m venv ~/venvs/qatrack31
Anytime you open a new terminal/shell to work with your QATrack+ installation you will want to activate your virtual environment. Do so now like this:
source ~/venvs/qatrack31/bin/activate
Your command prompt should now be prefixed with (qatrack31).
It’s also a good idea to upgrade pip the Python package installer:
pip install --upgrade pip
We will now install all the libraries required for QATrack+ with PostgresSQL (be patient, this can take a few minutes!):
cd ~/web/qatrackplus
pip install -r requirements/postgres.txt
or for MySQL:
cd ~/web/qatrackplus
pip install -r requirements/mysql.txt
Making sure everything is working up to this point¶
At this point you can run the QATrack+ test suite to ensure your environment is set up correctly:
cd ~/web/qatrackplus
touch qatrack/local_settings.py
make test_simple
This should take a few minutes to run and should exit with output that looks similar to the following:
Results (88.45s):
975 passed
5 skipped
32 deselected
Configuration of QATrack+¶
Next we need to tell QATrack+ how to connect to our database and (optionally) set some configuration options for your installation.
Create your local_settings.py file by copying the example from deploy/{postgres|mysql}/local_settings.py:
# postgres
cp deploy/postgres/local_settings.py qatrack/local_settings.py
# mysql
cp deploy/mysql/local_settings.py qatrack/local_settings.py
then open the file in a text editor. There are many available settings and they are documented within the example file and more completely on the settings page. Directions for setting up email are also included on that page.
However, the two most important settings are DATABASES and ALLOWED_HOSTS: which should be set like the following (switch the ENGINE to mysql if required):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'qatrackplus31',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': '',
'PORT': '',
},
'readonly': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'qatrackplus31',
'USER': 'qatrack_reports',
'PASSWORD': 'qatrackpass',
'HOST': '',
'PORT': '',
}
}
# Change XX.XXX.XXX.XX to your servers IP address and/or host name e.g. ALLOWED_HOSTS = ['54.123.45.1', 'yourhostname']
ALLOWED_HOSTS = ['XX.XXX.XXX.XX']
Once you have got those settings done, we can now test our database connection:
python manage.py showmigrations accounts
which should show output like:
accounts
[ ] 0001_initial
[ ] 0002_activedirectorygroupmap_defaultgroup
[ ] 0003_auto_20210207_1027
If you were able to connect to your database, we can now create the tables in our database and install the default data:
python manage.py migrate
python manage.py loaddata fixtures/defaults/*/*
After that completes, we can grant privileges to our readonly database user as follows:
# PostgreSQL
sudo -u postgres psql < deploy/postgres/grant_ro_rights.sql
# or MySQL if you set a password during install
sudo mysql -u root -p -N -B -e "$(cat deploy/mysql/generate_ro_privileges.sql)" > grant_ro_privileges.sql
sudo mysql -u root -p --database qatrackplus31 < grant_ro_privileges.sql
# or MySQL if you did not set a password during install
sudo mysql -N -B -e "$(cat deploy/mysql/generate_ro_privileges.sql)" > grant_ro_privileges.sql
sudo mysql --database qatrackplus31 < grant_ro_privileges.sql
You also need to create a super user so you can login and begin configuring your Test Lists:
python manage.py createsuperuser
and to create a cachetable in the database:
python manage.py createcachetable
and finally we need to collect all our static media files in one location for Apache to serve:
python manage.py collectstatic
Setting up Django Q¶
As of version 3.1.0, some features in QATrack+ rely on a separate long running process which looks after periodic and background tasks like sending out scheduled notices and reports. We are going to use Supervisor to look after running this process on startup and ensuring it gets restarted if it fails for some reason.
Install supervisor:
sudo apt install supervisor
and then set up the Django Q configuration:
make supervisor.conf
Lastly, confirm django-q is now running:
sudo supervisorctl status
which should result in output like:
django-q RUNNING pid 15860, uptime 0:00:05
If supervisor does not show RUNNING you can check the error log which is located at /var/log/supervisor-django-q.err.log
You can also check on the status of your task cluster at any time like this:
source ~/venvs/qatrack31/bin/activate
cd ~/web/qatrackplus/
python manage.py qmonitor
Installing Apache web server and mod_wsgi¶
The next step to take is to install and configure the Apache web server. Apache and mod_wsgi can be installed with the following commands:
sudo apt-get install apache2 apache2-dev libapache2-mod-wsgi-py3 python3-dev
Next, lets make sure Apache can write to our logs and media directories:
sudo usermod -a -G www-data $USER
exec sg www-data newgrp `id -gn` # this refreshes users group memberships without needing to log off/on
mkdir -p logs
touch logs/{migrate,debug,django-q,auth}.log
sudo chown -R www-data:www-data logs
sudo chown -R www-data:www-data qatrack/media
sudo chmod ug+rwxs logs
sudo chmod ug+rwxs qatrack/media
Now we can remove the default Apache config file and copy over the QATrack+ config file:
Danger
If you already have other sites running using the default config file you will want to edit it to include the directives relevant to QATrack+ rather than deleting it. Seek help if you’re unsure!
make qatrack_daemon.conf
sudo rm /etc/apache2/sites-enabled/000-default.conf
and finally restart Apache:
sudo service apache2 restart
You should now be able to log into your server at http://yourserver/!
Next Steps¶
- Check the the settings page for any available customizations you want to add to your QATrack+ installation (don’t forget to restart Apache after changing any settings!)
- Automate the backup of your QATrack+ installation.
- Read the Administration Guide, User Guide, and Tutorials.
Last Word¶
There are a lot of steps getting everything set up so don’t be discouraged if everything doesn’t go completely smoothly! If you run into trouble, please get in touch on the mailing list.
Upgrading an existing Linux v0.3.0 installation to v3.1.1¶
Note
This guide assumes you have at least a basic level of familiarity with Linux and the command line.
This guide will walk you through upgrading your existing v0.3.0 installation to v3.1.1. If you currently have a 0.2.x version of QATrack+, you first need to follow the instructions to upgrade to 0.3.0, before carrying out these instructions.
If you hit an error along the way, stop and figure out why the error is occuring before proceeding with the next step! You can seek help on the on the mailing list.
Prerequisites¶
If your QATrack+ server exists on a virtual machine, now would be a great time to take a snapshot of your VM in case you need to restore it later! Consult with your IT department on how to do this.
It is extremely important you back up your database before attempting to upgrade. Generate a backup file for your database
# postgres
sudo -u postgres pg_dump -d qatrackplus > backup-0.3.0-$(date -I).sql
# or for MySQL
mysqldump --user qatrack --password=qatrackpass qatrackplus > backup-0.3.0-$(date -I).sql
In order to make reverting to your prior configuration simpler, it is recommended to clone your existing database by creating a new database, restoring your backup and then perform the upgrade on it instead. This will also confirm your backup step above worked.
sudo -u postgres psql -c "CREATE DATABASE qatrackplus31;"
# postgres (# it's ok if you see an error "role "qatrack" already exists here)
sudo -u postgres psql -c "CREATE USER qatrack with PASSWORD 'qatrackpass';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE qatrackplus31 to qatrack;"
sudo -u postgres psql -d qatrackplus31 < backup-0.3.0-$(date -I).sql
# or for MySQL (omit the -p if your mysql installation doesn't require a password for root)
sudo mysql -p -e "CREATE DATABASE qatrackplus31;"
sudo mysql -p --database=qatrackplus31 < backup-0.3.0-$(date -I).sql
sudo mysql -p -e "GRANT ALL ON qatrackplus31.* TO 'qatrack'@'localhost';"
sudo mysql -p -e "CREATE USER 'qatrack_reports'@'localhost' IDENTIFIED BY 'qatrackpass';"
Now confirm your restore worked:
# postgres: Should show Count=1234 or similar
PGPASSWORD=qatrackpass psql -U qatrack -d qatrackplus31 -c "SELECT COUNT(*) from qa_testlistinstance;"
# mysql: Should show Count=1234 or similar
sudo mysql --password=qatrackpass --database qatrackplus31 -e "SELECT COUNT(*) from qa_testlistinstance;"
Version 3.1.1, runs on Python 3.6, 3.7, 3.8, & 3.9. Check your version of Python 3 with the command:
python3 -V
if that shows a version of Python lower than 3.6 then you will need to install a more up to date version of Python before proceeding.
sudo apt update
sudo apt upgrade
You will also need the Chrome browser installed for generating PDF reports:
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install ./google-chrome-stable_current_amd64.deb
Check out the latest version of QATrack+¶
We can now grab the latest version of QATrack+. To checkout the code enter the following commands:
cd ~/web/qatrackplus
git remote set-url origin https://github.com/qatrackplus/qatrackplus.git
git fetch origin
git checkout v3.1.1
Setting up our Python environment (including virtualenv)¶
We will create a new Virtual Environment in order to make it simpler to revert to your old environment if required. To create the virtual environment run the following commands:
python3 -m venv ~/venvs/qatrack31
Anytime you open a new terminal/shell to work with your QATrack+ installation you will want to activate your virtual environment. Do so now like this:
source ~/venvs/qatrack31/bin/activate
Your command prompt should now be prefixed with (qatrack31).
It’s also a good idea to upgrade pip the Python package installer:
pip install --upgrade pip
We will now install all the libraries required for QATrack+ with PostgresSQL (be patient, this can take a few minutes!):
cd ~/web/qatrackplus
pip install -r requirements/postgres.txt
or for MySQL:
cd ~/web/qatrackplus
pip install -r requirements/mysql.txt
Next we need to tell QATrack+ how to connect to our newly restored database.
Edit your qatrack/local_settings.py and adjust your DATABASE setting so it looks similar to this:
# for postgres
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'qatrackplus31',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
},
'readonly': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'qatrackplus31',
'USER': 'qatrack_reports',
'PASSWORD': 'qatrackpass',
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
# for mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'qatrackplus31',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
},
'readonly': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'qatrackplus31',
'USER': 'qatrack_reports',
'PASSWORD': 'qatrackpass',
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
}
}
Once you have got those settings done, we can now test our database connection:
python manage.py showmigrations accounts
which should show output like:
accounts
[ ] 0001_initial
[ ] 0002_activedirectorygroupmap_defaultgroup
[ ] 0003_auto_20210207_1027
If you were able to connect to your database, we can now migrate the tables in our database.
python manage.py migrate
After that completes, we can create & grant privileges to our readonly database user as follows:
# PostgreSQL
sudo -u postgres psql < deploy/postgres/create_ro_role.sql
sudo -u postgres psql < deploy/postgres/grant_ro_rights.sql
# or MySQL if you set a password during install
sudo mysql -u root -p -N -B -e "$(cat deploy/mysql/generate_ro_privileges.sql)" > grant_ro_privileges.sql
sudo mysql -u root -p --database qatrackplus31 < grant_ro_privileges.sql
# or MySQL if you did not set a password during install
sudo mysql -N -B -e "$(cat deploy/mysql/generate_ro_privileges.sql)" > grant_ro_privileges.sql
sudo mysql --database qatrackplus31 < grant_ro_privileges.sql
You also need to create a cachetable in the database:
python manage.py createcachetable
and finally we need to collect all our static media files in one location for Apache to serve:
python manage.py collectstatic
As of version 3.1.0, some features in QATrack+ rely on a separate long running process which looks after periodic and background tasks like sending out scheduled notices and reports. We are going to use Supervisor to look after running this process on startup and ensuring it gets restarted if it fails for some reason.
Install supervisor:
sudo apt install supervisor
and then set up the Django Q configuration:
make supervisor.conf
Lastly, confirm django-q is now running:
sudo supervisorctl status
which should result in output like:
django-q RUNNING pid 15860, uptime 0:00:05
If supervisor does not show RUNNING you can check the error log which is located at /var/log/supervisor-django-q.err.log
You can also check on the status of your task cluster at any time like this:
source ~/virtualenvs/qatrack31/bin/activate
cd ~/web/qatrackplus/
python manage.py qmonitor
Setting File Permissions for Apache¶
Next, lets make sure Apache can write to our logs and media directories:
sudo usermod -a -G www-data $USER
exec sg www-data newgrp `id -gn` # this refreshes users group memberships without needing to log off/on
mkdir -p logs
touch logs/{migrate,debug,django-q,auth}.log
sudo chown -R www-data:www-data logs
sudo chown -R www-data:www-data qatrack/media
sudo chmod ug+rwxs logs
sudo chmod ug+rwxs qatrack/media
Now we can update our default Apache config file so that it points to the correct virtualenv. Edit /etc/apache2/sites-available/qatrack.conf and find the WSGIDaemonProcess line and update the python-home variable so that it points to /venvs/qatrack31.
WSGIDaemonProcess qatrackplus python-home=/home/YOURUSERNAMEHERE/venvs/qatrack31 python-path=/home/YOURUSERNAMEHERE/web/qatrackplus
You should also ensure the WSGIScriptAlias line and includes the application-group directive.
WSGIScriptAlias / /home/YOURUSERNAMEHERE/web/qatrackplus/qatrack/wsgi.py process-group=qatrackplus application-group=%{GLOBAL}
and finally restart Apache:
sudo service apache2 restart
You should now be able to log into your server at http://yourserver/!
What Next¶
- Make sure you have read the release notes for version 3.1.0 carefully. There are some new settings you may want to adjust.
- Since the numpy, scipy, pylinac, pydicom, & matplotlib libraries have been updated, some of your calculation procedures may need to be adjusted to restore functionality.
- Adjust your backup script so that it is now backing up the qatrackplus31 database instead of the version 0.3.0 database!
Last Word¶
There are a lot of steps getting everything set up so don’t be discouraged if everything doesn’t go completely smoothly! If you run into trouble, please get in touch on the mailing list.
Upgrading an existing Linux v0.2.X installation to v3.1.1¶
Note
This guide assumes you have at least a basic level of familiarity with Linux and the command line.
This document will walk you through migrating an existing v0.2.X version of QATrack+ to a new Ubuntu 18.04 or Ubuntu 20.04 server. Although it may be possible, upgrading an Ubuntu 14.04 or Ubuntu 16.04 installation in place is not recommended. This guide assumes you are moving to a new server. If you need advice please get in touch on the mailing list.
On your old server¶
The first step to migrating your existing QATrack+ installation is to generate the backup files to move everything to your new server.
The process to generate and restore a database dump may vary depending on how you have things configured, your operating system version, or the version of database software you are using. The steps below can be used as a guide, but they may need to be tweaked for your particular installation.
Note
We will assume you are currently using a database named ‘qatrackplus’ but if not (check the DATABASE settings in qatrack/local_settings.py) replace ‘qatrackplus’ in the instructions below with your database name (e.g. qatrackdb).
# postgres
sudo -u postgres pg_dump -d qatrackplus > backup-0.2.X.sql
# or for MySQL
mysqldump --user qatrack --password=qatrackpass qatrackplus > backup-0.2.X.sql
and create an archive of your uploads directory:
tar czf qatrack-uploads.tgz qatrack/media/uploads/
On your new server¶
Copy the backup-0.2.X.sql and qatrack-uploads.tgz to your new server, these will be needed below.
Prerequisites¶
Make sure your existing packages are up to date:
sudo apt update
sudo apt upgrade
You will need to have the make command and a few other packages available for this deployment. Install install them as follows:
sudo apt install make build-essential python-dev python3-dev python3-tk python3-venv
If you were using Postgres before, then install it again. Likewise, if your previous server was using a MySQL database, then install MySQL/MariaDB
If you do not have an existing database server, you will need to install PostgreSQL locally. Run the following commands:
sudo apt-get install postgresql libpq-dev postgresql-client postgresql-client-common
Now edit /etc/postgresql/12/main/pg_hba.conf (use your favourite editor, e.g. sudo nano /etc/postgresql/12/main/pg_hba.conf (note, if you have a different version of Postgres installed, then you would need to change the 12 in that path e.g. /etc/postgresql/9.3/main/pg_hba.conf) and scroll down to the bottom and change the instances of peer to md5 so it looks like:
# Database administrative login by Unix domain socket
local all postgres peer
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all md5
# IPv4 local connections:
host all all 127.0.0.1/32 md5
# IPv6 local connections:
host all all ::1/128 md5
# Allow replication connections from localhost, by a user with the
# replication privilege.
local replication all md5
host replication all 127.0.0.1/32 md5
host replication all ::1/128 md5
and restart the pg server:
sudo service postgresql restart
sudo apt-get install mysql-server libmysqlclient-dev
We can now restore your previous database:
sudo -u postgres psql -c "CREATE DATABASE qatrackplus;"
sudo -u postgres psql -d qatrackplus < backup-0.2.X.sql
sudo -u postgres psql -c "CREATE USER qatrack with PASSWORD 'qatrackpass';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE qatrackplus to qatrack;"
# or for MySQL (omit the -p if your mysql installation doesn't require a password for root)
sudo mysql -p -e "CREATE DATABASE qatrackplus;"
sudo mysql -p --database=qatrackplus < backup-0.2.X.sql
sudo mysql -p -e "GRANT ALL ON qatrackplus.* TO 'qatrack'@'localhost';"
Now confirm your restore worked:
# postgres: Should show Count=1234 or similar
PGPASSWORD=qatrackpass psql -U qatrack -d qatrackplus -c "SELECT COUNT(*) from qa_testlistinstance;"
# mysql: Should show Count=1234 or similar
sudo mysql --password=qatrackpass --database qatrackplus -e "SELECT COUNT(*) from qa_testlistinstance;"
Assuming your database restoration was successful, you may now proceed with upgrading the database to v0.3.0.
Installing and configuring Git and checking out the QATrack+ Source Code¶
Ensure you have git installed with the following command:
sudo apt install git
and then configure git (substituting your name and email address!)
git config --global user.name "randlet"
git config --global user.email randy@multileaf.ca
Now that we have git installed we can proceed to grab the latest version of QATrack+. To checkout the code enter the following commands:
mkdir -p ~/web
cd web
git clone https://github.com/qatrackplus/qatrackplus.git
cd qatrackplus
git checkout v0.2.9.2
Assuming you are on a new server and have an uploads file that you want to restore you should do so now:
# assuming your qatrack-uploads.tgz is in your home directory
cd ~/web/qatrackplus
mv ~/qatrack-uploads.tgz .
sudo tar xzf qatrack-uploads.tgz
Use your favourite text editor to create a local_settings.py file in ~/web/qatrackplus/qatrack/ with the following contents:
# for postgres
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'qatrackplus',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
},
}
# or for mysql
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'qatrackplus',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used with sqlite3.
},
}
If you have a v0.2.9 database, you will only need a Python 3 installation, however if you have an older QATrack+ installation, you will also require Python 2.7. If you have a v0.2.9 database, you can skip this next section.
First install virtualenv, then create and activate a new Python 2 environment:
cd ~/web/qatrackplus
sudo apt install python-virtualenv
mkdir -p ~/venvs
virtualenv -p python2 ~/venvs/qatrack2
source ~/venvs/qatrack2/bin/activate
pip install --upgrade pip
Now install the required Python packages:
pip install -r requirements/base.txt
# for postgres
pip install psycopg2-binary
# for mysql
pip install mysqlclient
Now migrate your database to v0.2.9
python manage.py syncdb
python manage.py migrate
and deactivate the virtualenv
deactivate
Migrating 0.2.9 to 0.3.0¶
In order to upgrade our 0.2.9 installation to 0.3.0, first we need to checkout the QATrack+ v0.3.0 source code:
cd ~/web/qatrackplus
git checkout v0.3.0.19
Create and activate a new Python 3 virtual environment:
mkdir -p ~/venvs
python3 -m venv ~/venvs/qatrack3
source ~/venvs/qatrack3/bin/activate
pip install --upgrade pip
We will now install all the libraries required for QATrack+ with PostgresSQL (be patient, this can take a few minutes!):
# for postgres
pip install -r requirements/postgres.txt
# or for MySQL:
pip install -r requirements/mysql.txt
We are now ready to migrate our 0.2.9 database to v0.3.0:
python manage.py migrate --fake-initial
Installing Apache web server and mod_wsgi¶
The next step to take is to install and configure the Apache web server. Apache and mod_wsgi can be installed with the following commands:
sudo apt-get install apache2 apache2-dev libapache2-mod-wsgi-py3 python3-dev
Now we can remove the default Apache config file and copy over the QATrack+ config file:
Danger
If you already have other sites running using the default config file you will want to edit it to include the directives relevant to QATrack+ rather than deleting it. Seek help if you’re unsure!
make qatrack_daemon.conf
sudo rm /etc/apache2/sites-enabled/000-default.conf
and finally restart Apache:
sudo service apache2 restart
Next Steps¶
Now that you have upgraded to 0.3.0, you should proceed directly to upgrading to v3.1.1 from v0.3.0;
Installing and Deploying QATrack+ on Windows Server¶
Note
This guide assumes you have at least a basic level of familiarity with Windows Server, SQL Server Management Studio, and the command line.
New Installation¶
This guide is going to walk you through installing QATrack+ on a Windows Server 2016-2019 server with IIS serving static assets (images, javascript and stylesheets) and acting as a reverse proxy for a CherryPy web server which serves our Django application (QATrack+). The instructions have been tested with SQL Server 2016 & 2019 database
If you are upgrading an existing QATrack+ installation, please see one of the following pages:
- Upgrading an existing v0.3.0 installation to v3.1.1.
- Upgrading an existing v0.2.X installation to v3.1.1.
Note
This guide assumes you have SQL Server Management Studio (SSMS) and Internet Information Services (IIS) installed/enabled
The steps we will be undertaking are:
Install Google Chrome¶
If you want to be able to generate or schedule PDF reports, you need to have Google Chrome installed. Download and install Chrome here: https://www.google.com/chrome/index.html
Installing Python 3¶
Go to http://www.python.org/downloads/ and download the latest Python 3.9.X (3.9.1 at the time of writing) 64 bit version (e.g. the “Windows installer (64-bit)” link). Run the installer and on the first page, make sure both “Install launcher for all users” and “Add Python 3.9 to PATH” are checked and then click the “Customize Installation” button.
On the second page of the installer, leave the defaults and click “Next”.
On the third page, make sure you have “Install for all users” selected (this is important!) before clicking “Install”.
Installing git and checking out the QATrack+ Source Code¶
Go to http://git-scm.com and download the latest version of git (msysgit) for Windows (Git-2.30.0 at the time of writing). Run the installer. I just leave all the settings on the defaults but you are free to modify them if you like.
Open a Windows PowerShell terminal and then create a directory for QATrack+ and check out the source code, use the following commands:
mkdir C:\deploy
cd C:\deploy
git clone https://github.com/qatrackplus/qatrackplus.git
Setting up our Python environment¶
Ensure you have python3 installed correctly and on your PATH by running:
python --version
# should print e.g. Python 3.9.1 or similar
We’re now ready to install all the libraries QATrack+ depends on.
mkdir venvs
python -m pip install --upgrade pip
python -m venv venvs\qatrack31
.\venvs\qatrack31\Scripts\Activate.ps1
python -m pip install --upgrade pip
cd qatrackplus
git checkout v3.1.1
pip install -r requirements\win.txt
Warning
If you are going to be using Active Directory for authenticating your users, you need to install pyldap. There are binaries available on this page: https://www.lfd.uci.edu/~gohlke/pythonlibs/#python-ldap. Download the binary relavant to your distribution (e.g. python_ldap‑3.3.1‑cp39‑cp39‑win_amd64.whl) and then pip install it:
pip install C:\path\to\python_ldap‑3.3.1‑cp39‑cp39‑win_amd64.whl
Creating a database with SQL Server¶
In order for QATrack+ to connect to your database, you need to have the ODBC Driver 17 installed. Visit https://www.microsoft.com/en-us/download/details.aspx?id=56567 and download and install the driver (64 bit).
Open SQL Server Management Studio and connect to ‘localhost’ or another database server.
In the Object Explorer frame right click on the server you are connected to and click Properties. In the dialog that opens click on Security, ensure SQL Server and Windows Authentication mode is selected and then click OK. Now right click on your server again and click Restart.
In the Object Explorer frame, right click the Databases folder and select “New Database…”.
Enter ‘qatrackplus31’ as the database name and click OK.
Back in the Object Explorer frame, right click on the main Server Security folder and click New Login… Set the login name to ‘qatrack’, select SQL Server Authentication. Enter ‘qatrackpass’ (or whatever you like) for the password fields and uncheck Enforce Password Policy. Click OK.
Again in the Object Explorer frame, right click on the main Security folder and click New Login… Set the login name to ‘qatrack_reports’, select SQL Server Authentication. Enter ‘qatrackpass’ (or whatever you like) for the password fields and uncheck Enforce Password Policy. Click OK.
Back in the Object Explorer frame, expand the qatrackplus31 database, right click on Security and select New->User.
Enter ‘qatrack’ as the User name and Login name and then in the Database Role Membership region select ‘db_ddladmin’, ‘db_datawriter’, ‘db_datareader’ and ‘db_owner’. Click OK.
Now add the readonly database user for the query tool. In the Object Explorer frame, expand the qatrackplus31 database, right click on Security and select New->User.
Enter ‘qatrack_reports’ as the User name and Login name and then in the Database Role Membership region select ‘db_datareader’. Click OK.
Copy the example local_settings file:
cp deploy\win\local_settings.py qatrack\local_settings.py
and then edit it so that the NAME, USER, and PASSWORD settings match the way you set up your database above.
DEBUG = False
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'qatrackplus31',
'USER': 'qatrack', # USER/PWD can usually be left blank if SQL server is running on the same server as QATrack+
'PASSWORD': 'qatrackpass',
'HOST': '', # leave blank unless using remote server or SQLExpress (use 127.0.0.1\\SQLExpress or COMPUTERNAME\\SQLExpress)
'PORT': '', # Set to empty string for default. Not used with sqlite3.
'OPTIONS': {
'driver': 'ODBC Driver 17 for SQL Server'
},
},
'readonly': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'qatrackplus31',
'USER': 'qatrack_reports',
'PASSWORD': 'qatrackpass',
'HOST': '',
'PORT': '',
'OPTIONS': {
'driver': 'ODBC Driver 17 for SQL Server'
},
}
}
ALLOWED_HOSTS = ['127.0.0.1', 'localhost'] # See local settings docs
Confirm you can connect to your database by running the showmigrations command:
python manage.py showmigrations accounts
which should show output like:
accounts
[ ] 0001_initial
[ ] 0002_activedirectorygroupmap_defaultgroup
[ ] 0003_auto_20210207_1027
We will now create the database tables and load some configuration data into our new database from the command prompt:
python manage.py migrate
python manage.py createsuperuser
python manage.py createcachetable
python manage.py collectstatic
Get-ChildItem .\fixtures\defaults\*\*json | foreach {python manage.py loaddata $_.FullName}
Configuring CherryPy to Serve QATrack+¶
In order to have QATack+ start when you reboot your server, or restart after a crash, we will run QATrack+ with a CherryPy server installed as a Windows service (running on port 8080, see note below if you need to change the port).
Open a new PowerShell window with Administrator privileges (right click on PowerShell and click “Run as Administrator”) and run the following commands:
cd C:\deploy
.\venvs\qatrack31\Scripts\Activate.ps1
cd qatrackplus
cp deploy\win\QATrack31CherryPyService.py .
python C:\deploy\venvs\qatrack31\Scripts\pywin32_postinstall.py -install
python QATrack31CherryPyService.py --startup=auto install
python QATrack31CherryPyService.py start
Open the Windows Services dialog and confirm the QATrack 31 CherryPy Service is installed and has a status of Running. Next open a browser on the server and navigate to http://localhost:8080/ and ensure you see a plain login form there (it won’t look like this once we’re finished!). If not, check the logscherry_py_err.log file for any errors.
Your QATrack+ installation is now installed as a Windows Service running on port 8080 (see note below). You may also wish to configure the service to email you in the event of a crash (see the Recovery tab of the QATrackCherryPyService configuration dialogue).
Note
If you need to run QATrack+ on a different port, edit C:\deploy\qatrackplus\QATrack3CherryPyService.py and set the PORT variable to a different port (e.g. 8008)
Setting up IIS¶
To start open up the Internet Information Services (IIS) application. We are going to use IIS for two purposes: first, it is going to serve all of our static media (css, js and images) and second it is going to act as a reverse proxy to forward the QATrack+ specific requests to CherryPy.
Before starting please make sure you have both URL Rewrite 2.1 and Application Request Routing 3.0 IIS modules installed. These can be installed by clicking on the “Get New Web Platform Components” link in the right hand side bar of IIS (you may need to install the Web Platform Installer first).
After installing these modules, you will need to close & re-open IIS.
Application Request Routing needs to have the proxy setting enabled. To do this, click on the top level server in the left side panel, and then double click the Application Request Routing icon. In the Actions panel click the Server Proxy Settings and then check Enable proxy at the top. Leave all the other settings the same and click Apply and then Back to ARR Cache.
IIS is not always set up to serve static content. To enable this, open the Server Manager software, click Manage, then Add Roles and Features then Next, Next. In the Roles widget, select Web Server(IIS)->Web Server->Common HTTP Features and make sure Static Content is selected. If it isn’t, enable that role.
Once you have Applicationn Request Routing installed and proxies enabled, in the left panel of IIS under Sites, select the default Web Site and click Stop on the right hand side.

Stop default website
Now right click on Sites and click Add Web Site

Add a new web site
Enter QATrack Static for the Site Name and “C:\deploy\qatrackplus\qatrack" for the Physical Path then click OK and answer Yes to the warning.
To test that setup worked correctly open a browser on your server and enter the address http://localhost/static/qa/img/tux.png You should see a picture of the Linux penguin.
Next, select the top level server in the Connections pane and then double click URL Rewrite:

URL Rewrite
In the top right click Add Rule and select Blank Rule.
Give it a name of QATrack Static and enter ^(static|media)/.* for the Pattern field, and select None for the Action type. Make sure Stop processing of subsequent rules is checked.

Static URL Rewrite Rule
When finished click Apply, then Back To Rules and then add another blank rule. Give it a name of QATrack Reverse Proxy, enter ^(.*) for the Pattern and http://localhost:8080/{R:1} for the Rewrite URL. In the Server Variables section add a new Server Variable with the Name=HTTP_X_FORWARDED_HOST and the Value=yourservername.com (replace yourservername with whatever your domain is!). Finally, make sure both Append query string and Stop processing of subsequent rules are checked.

URL Rewrite Reverse Proxy
Your URL rewrites should look like the following (order is important!)

URL Rewrite rules
You should now be able to visit http://localhost/ in a browser on your server and see the QATrack+ login page. Congratulations, you now have a functional QATrack+ setup on your Windows Server!
If you see a “403.14 Forbidden” error, double check you added the URL rewrite rules to the top level server, and not the QATrack Static site.
If you see a “502.3 Bad Gateway” error, double check that your QATrack CherryPy service was installed correctly and is running.
Note
There are many different ways to configure IIS. The method I’ve used above is simple and works well when QATrack+ is the only web service running on a server.
Setting up Django Q¶
As of version 3.1.0, some features in QATrack+ rely on a separate long running process which looks after periodic and background tasks like sending out scheduled notices and reports. We are going to use Windows Task Scheduler to run the Django Q task processing cluster.
Open the Windows Task Scheduler application and click Create Task. Give the task a name of “QATrack+ Django Q Cluster”. Click the Change User or Group… button and in the Enter the object name to select box put SYSTEM, then click Check Names and OK.

QCluster Task
On the Triggers tab, click New… and in the Begin the task: dropdown select At startup and then click OK.

QCluster Trigger
Now go to the Actions tab and click New…. In the Program/script: box enter C:\deploy\venvs\qatrack31\Scripts\python.exe. In the Add arguments (optional): field enter manage.py qcluster, and in the Start in (optional): field put C:\deploy\qatrackplus (no trailing slash!).

QCluster Action
Click OK, then right click on the task and select Run. Go back to your PowerShell window (or open a new one) and confirm your task cluster is running with python manage.py qmonitor which should show something like:
Host Id State Pool TQ RQ RC Up
YOUR-SERVER e0474f3f Idle 2 0 0 0 0:05:53
ORM default Queued 0 Success 48 Failures 0
[Press q to quit]
If the line between Host and ORM default is blank then there is a problem with the Windows Task you created.
What Next¶
- Check the the settings page for any available customizations you want to add to your QATrack+ installation (don’t forget to restart both your QATrack CherryPy Service, and Django Q cluster via the task scheduler after changing any settings!)
- Automate the backup of your QATrack+ installation.
- Read the Administration Guide, User Guide, and Tutorials.
Wrap Up¶
This guide shows only one of many possible method of deploying QATrack+ on Windows. It is very similar to what is used at The Ottawa Hospital Cancer Centre and it has proven to be a very solid setup. If you’re stuck with a Windows stack it will likely work for you too. Please post on the QATrack+ Google Group if you get stuck!
Upgrading an existing Windows v0.3.0 installation to v3.1.1¶
This guide will walk you through upgrading your existing v0.3.0 installation to v3.1.1. If you currently have a 0.2.x version of QATrack+, you first need to follow the instructions to upgrade to 0.3.0, before carrying out these instructions.
These instructions assume you are using Windows Server 2016-2019 and SQL Server 2016-2019. No testing is done on earlier versions of Windows or SQL Server and it is recommended that if you are running on Windows Server < 2016 you migrate your QATrack+ installation to a more recent database/OS version when you upgrade QATrack+.
Prerequisites¶
If your QATrack+ server exists on a virtual machine, now would be a great time to take a snapshot of your VM in case you need to restore it later! Consult with your IT department on how to do this.
In order for QATrack+ to connect to your database, you need to have the ODBC Driver 17 installed. Visit https://www.microsoft.com/en-us/download/details.aspx?id=56567 and download and install the driver (64 bit).
Install Google Chrome¶
If you want to be able to generate or schedule PDF reports, you need to have Google Chrome installed. Download and install Chrome here: https://www.google.com/chrome/index.html
Stop your CherryPy Service to Serve QATrack+¶
If you have an existing CherryPy service running for QATrack+, open the windows services dialog, find the QATrack3CherryPyService, right click on it and select Stop. Then right click on it again, select Properties and set the Startup type to disbled before clicking OK.
It is extremely important you back up your database before attempting to upgrade. In order to generate a backup open SQL Server Management Studio (SSMS), right click on your database then select Tasks -> Back Up..

Backup Menu Item
Select Copy-only backup and make sure the Backup component is set to Database. Take note of where the backup is being stored and then click OK:

Backup Dialog
In order to make reverting to your prior configuration simpler, it is recommended to clone your existing database then perform the upgrade on it instead.
In the Object Explorer panel, right click on your database and select Tasks->Restore Database

Restore database menu
In the Source section leave your existing database as the source in the Database section selected.
In the Destination section edit the Database field to qatrackplus31. This will ensure you are not overwriting your old database.

Set database destination
Next select the Files page from the left hand sidebar and select the Relocate all files to folder option:

relocate data files
Lastly select the Options page from the left hand sidebar and deselect the Take tail-log backup before restore.

Disable tail log
Then click OK. Be patient while the database restores.
Your existing QATrack+ database user should still be present on your new database, however, you should ensure they have the correct rights. In the Object Explorer from expand the qatrackplus31 database, then expand the Security and Users folders, then right click on the qatrack user and select Properties. Under the Database Role Membership region select db_ddladmin, db_datawriter, db_datareader and db_owner. Click OK.
We also need to add a readonly database for this version of QATrack+. In the Object Explorer frame, right click on the main Security folder and click New Login… Set the login name to ‘qatrack_reports’, select SQL Server Authentication. Enter ‘qatrackpass’ (or whatever you like) for the password fields and uncheck Enforce Password Policy. Click OK.
Back in the Object Explorer frame, expand the qatrackplus31 database, right click on Security and select New->User.
Enter ‘qatrack_reports’ as the User name and Login name and then in the Database Role Membership page select ‘db_datareader’. Click OK.
Version 3.1.1, runs best on Python 3.7, 3.8, & 3.9 (3.6 works ok but installing dependencies is more complicated). Check your version of Python 3 by opening a PowerShell prompt and entering:
python -V
if that shows a version of Python lower than 3.7 then you will need to install a more up to date version of Python before proceeding (see https://python.org). You will need to re-open your PowerShell Window after installing Pyton.
First we must check out the code for version 3.1.1 in a PowerShell window:
cd C:\deploy\qatrackplus
git remote set-url origin https://github.com/qatrackplus/qatrackplus.git
git fetch origin
git checkout v3.1.1
Setting up our Python environment (including virtualenv)¶
We will create a new Virtual Environment in order to make it simpler to revert to your old environment if required. To create the virtual environment run the following commands:
python -m venv C:\deploy\venvs\qatrack31
Anytime you open a new terminal/shell to work with your QATrack+ installation you will want to activate your virtual environment. Do so now like this:
cd C:\deploy
.\venvs\qatrack31\Scripts\Activate.ps1
Your command prompt should now be prefixed with (qatrack31).
It’s also a good idea to upgrade pip the Python package installer:
pip install --upgrade pip
We will now install all the libraries required for QATrack+ (be patient, this can take a few minutes!):
cd C:\deploy\qatrackplus
pip install -r requirements\win.txt
Next we need to tell QATrack+ how to connect to our newly restored database.
Edit your qatrack\local_settings.py and adjust your DATABASE setting so it looks similar to this:
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'qatrackplus31',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': '', # leave blank unless using remote server or SQLExpress (use 127.0.0.1\\SQLExpress or COMPUTERNAME\\SQLExpress)
'PORT': '', # Set to empty string for default. Not used with sqlite3.
'OPTIONS': {
'driver': 'ODBC Driver 17 for SQL Server'
},
},
'readonly': {
'ENGINE': 'sql_server.pyodbc',
'NAME': 'qatrackplus31',
'USER': 'qatrack_reports',
'PASSWORD': 'qatrackpass',
'HOST': '', # leave blank unless using remote server or SQLExpress (use 127.0.0.1\\SQLExpress or COMPUTERNAME\\SQLExpress)
'PORT': '', # Set to empty string for default. Not used with sqlite3.
'OPTIONS': {
'driver': 'ODBC Driver 17 for SQL Server'
},
}
}
Once you have got those settings done, we can now test our database connection:
python manage.py showmigrations accounts
which should show output like:
accounts
[ ] 0001_initial
[ ] 0002_activedirectorygroupmap_defaultgroup
[ ] 0003_auto_20210207_1027
If you were able to connect to your database, we can now migrate the tables in our database.
python manage.py migrate
You also need to create a cachetable in the database:
python manage.py createcachetable
and finally we need to collect all our static media files in one location for Apache to serve:
python manage.py collectstatic
Update your CherryPy Service to Serve QATrack+¶
Open a new PowerShell window with Administrator privileges (right click on PowerShell and click “Run as Administrator”) and run the following commands:
cd C:\deploy
.\venvs\qatrack31\Scripts\Activate.ps1
cd qatrackplus
python C:\deploy\venvs\qatrack31\Scripts\pywin32_postinstall.py -install
cp deploy\win\QATrack31CherryPyService.py .
python QATrack31CherryPyService.py --startup=auto install
python QATrack31CherryPyService.py start
Open the Windows Services dialog and confirm the QATrack 31 CherryPy Service is installed and has a status of Running.
Your QATrack+ 3.1.1 installation is now installed as a Windows Service running on port 8080 (see note below). You may also wish to configure the service to email you in the event of a crash (see the Recovery tab of the QATrackCherryPyService configuration dialogue).
Note
If you need to run QATrack+ on a different port, edit C:\deploy\qatrackplus\QATrack3CherryPyService.py and set the PORT variable to a different port (e.g. 8008)
Setting up Django Q¶
As of version 3.1.0, some features in QATrack+ rely on a separate long running process which looks after periodic and background tasks like sending out scheduled notices and reports. We are going to use Windows Task Scheduler to run the Django Q task processing cluster.
Open the Windows Task Scheduler application and click Create Task. Give the task a name of “QATrack+ Django Q Cluster”. Click the Change User or Group… button and in the Enter the object name to select box put SYSTEM, then click Check Names and OK.

QCluster Task
On the Triggers tab, click New… and in the Begin the task: dropdown select At startup and then click OK.

QCluster Trigger
Now go to the Actions tab and click New…. In the Program/script: box enter C:\deploy\venvs\qatrack31\Scripts\python.exe. In the Add arguments (optional): field enter manage.py qcluster, and in the Start in (optional): field put C:\deploy\qatrackplus (no trailing slash!).

QCluster Action
Click OK, then right click on the task and select Run. Go back to your PowerShell window (or open a new one) and confirm your task cluster is running with python manage.py qmonitor which should show something like:
Host Id State Pool TQ RQ RC Up
YOUR-SERVER e0474f3f Idle 2 0 0 0 0:05:53
ORM default Queued 0 Success 48 Failures 0
[Press q to quit]
If the line between Host and ORM default is blank then there is a problem with the Windows Task you created.
What Next¶
- Make sure you have read the release notes for version 3.1.0 carefully. There are some new settings you may want to adjust.
- Since the numpy, scipy, pylinac, pydicom, & matplotlib libraries have been updated, some of your calculation procedures may need to be adjusted to restore functionality.
- Adjust your backup script so that it is now backing up the qatrackplus31 database instead of the version 0.3.0 database!
Last Word¶
There are a lot of steps getting everything set up so don’t be discouraged if everything doesn’t go completely smoothly! If you run into trouble, please get in touch on the mailing list.
Upgrading an existing Windows v0.2.X installation to v3.1.1¶
This document will walk you through migrating an existing v0.2.X version of QATrack+ to a new Windows server. Although it may be possible, upgrading a QATrack+ 0.2.x installation in place is not recommended. This guide assumes you are moving to a new server. If you need advice please get in touch on the mailing list.
On your old server¶
The first step to migrating your existing QATrack+ installation is to generate the backup files to move everything to your new server.
Note
We will assume you are currently using a database named ‘qatrackplus’ but if not (check the DATABASE settings in qatrack/local_settings.py) replace ‘qatrackplus’ in the instructions below with your database name (e.g. qatrackdb).
In order to generate a backup open SQL Server Management Studio (SSMS), right click on your database then select Tasks -> Back Up..

Backup Menu Item
Select Copy-only backup and make sure the Backup component is set to Database. Take note of where the backup is being stored and then click OK:

Backup Dialog
and create a zip archive of your uploads directory:

Create zip archive of uploads
On your new server¶
Copy the qatrackplus.bak and uploads.zip to your new server, these will be needed below. The qatrackplus.bak file should go in your SQL Server backup directory which is located at e.g. C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\Backup (the MSSQL13.MSSQLSERVER might have a different version number in it depending on what version of SQL Server you are using).
Visit https://www.python.org/downloads/windows/ and download the latest (64 bit) Python 2.7 release. Select Install for all users but do not add python.exe to Path when given the option.
Installing Python 3 (required for all)¶
Go to http://www.python.org/downloads/ and download the latest Python 3.9.X (3.9.1 at the time of writing) 64 bit version (e.g. the “Windows installer (64-bit)” link). Run the installer and on the first page, make sure both “Install launcher for all users” and “Add Python 3.9 to PATH” are checked and then click the “Customize Installation” button.
On the second page of the installer, leave the defaults and click “Next”.
On the third page, make sure you have “Install for all users” selected (this is important!) before clicking “Install”.
Open SQL Server Management Studio and connect to ‘localhost’ or another database server.
In the Object Explorer frame right click on the server you are connected to and click Properties. In the dialog that opens click on Security, ensure SQL Server and Windows Authentication mode is selected and then click OK. Now right click on your server again and click Restart.
We can now restore your previous database. On your new server, open SQL Server Management Studio (SSMS) and in the Object Explorer panel, right click the Databases item and select Restore Database…

Restore database menu
In the General page, select Device and then click the … button, and then the Add button. Navigate to whereever you copied the SQL Server .bak file from your old server, select it and click OK and then OK again.

Selecting the database restore file
Assuming you don’t already have a database called qatrackplus on this server, set the Destination database to qatrackplus and then click OK.
Back in the Object Explorer frame, right click on the main Server Security folder and click New Login… Set the login name to ‘qatrack’, select SQL Server Authentication. Enter ‘qatrackpass’ (or whatever you like) for the password fields and uncheck Enforce Password Policy. Click OK.
Back in the Object Explorer frame, expand the qatrackplus31 database, right click on Security and select New->User.
Enter ‘qatrack’ as the User name and Login name and then in the Database Role Membership region select ‘db_ddladmin’, ‘db_datawriter’, ‘db_datareader’ and ‘db_owner’. Click OK.
Assuming your database restoration was successful, you may now proceed with upgrading the database to v0.3.0.
Installing git and checking out the QATrack+ Source Code¶
Go to http://git-scm.com and download the latest version of git (msysgit) for Windows (Git-2.30.0 at the time of writing). Run the installer. I just leave all the settings on the defaults but you are free to modify them if you like.
Open a Windows PowerShell terminal and then create a directory for QATrack+ and check out the source code, use the following commands:
mkdir C:\deploy
cd C:\deploy
git clone https://github.com/qatrackplus/qatrackplus.git
Assuming you are on a new server and have an uploads file that you want to restore you should do so now.
Open an Explorer window and navigate to where ever you copied your uploads.zip file to. Right click on it and select Extract All…. In the window that opens, set the destination for the files to C:\deploy\qatrackplus\qatrack\media and then click OK:

Extracting your uploads file
If you have a v0.2.9 database, you will only need a Python 3 installation, however if you have an older QATrack+ installation, you will also require Python 2.7. If you have a v0.2.9 database, you can skip this next section.
Use your favourite text editor to create a local_settings.py file with the following contents:
DATABASES = {
'default': {
'ENGINE': 'sqlserver_ado', # use this for upgrading to 0.2.9
'NAME': 'qatrackplus',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': '', # leave blank unless using remote server or SQLExpress (use 127.0.0.1\\SQLExpress or COMPUTERNAME\\SQLExpress)
'PORT': '', # Set to empty string for default. Not used with sqlite3.
'OPTIONS': {
'provider': 'SQLOLEDB'
},
},
}
Open a new PowerShell Window and create and activate a new Python 2 environment:
cd C:\deploy
mkdir venvs
C:\Python27\python.exe -m pip install --upgrade pip
C:\Python27\python.exe -m pip install virtualenv
C:\Python27\Scripts\virtualenv.exe venvs\qatrack2
.\venvs\qatrack2\Scripts\Activate.ps1
Now checkout v0.2.9 and install the required Python packages:
cd C:\deploy\qatrackplus
git checkout v0.2.9.2
pip install -r requirements\base.txt
pip install -r requirements\win.txt
Now migrate your database to v0.2.9
python manage.py syncdb
python manage.py migrate
and deactivate the virtualenv
deactivate
Migrating 0.2.9 to 0.3.0¶
In order to upgrade our 0.2.9 installation to 0.3.0, first we need to checkout the QATrack+ v0.3.0 source code:
cd ~/web/qatrackplus
git checkout v0.3.0.20
Now use your favourite text editor to create a local_settings.py file (or edit your existing one if you created one for updating to 0.2.9) with the following contents:
DATABASES = {
'default': {
'ENGINE': 'sql_server.pyodbc', # use this for upgrading 0.2.9 to 0.3.0
'NAME': 'qatrackplus',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': '', # leave blank unless using remote server or SQLExpress (use 127.0.0.1\\SQLExpress or COMPUTERNAME\\SQLExpress)
'PORT': '', # Set to empty string for default. Not used with sqlite3.
'OPTIONS': {
'driver': 'ODBC Driver 17 for SQL Server'
},
},
}
Ensure you have python3 installed correctly and on your PATH by running:
python --version
# should print e.g. Python 3.9.1 or similar
Create and activate a new Python 3 virtual environment:
cd C:\deploy
mkdir venvs # only if you haven't already created it
python -m venv venvs\qatrack3
.\venvs\qatrack3\Scripts\Activate.ps1
pip install --upgrade pip
We will now install all the libraries required for QATrack+:
cd C:\deploy\qatrackplus
pip install -r requirements\win.txt
We are now ready to migrate our 0.2.9 database to v0.3.0:
python manage.py migrate --fake-initial
Setting up IIS¶
Open up the Internet Information Services (IIS) application. We are going to use IIS for two purposes: first, it is going to serve all of our static media (css, js and images) and second it is going to act as a reverse proxy to forward the QATrack+ specific requests to CherryPy.
Before starting please make sure you have both URL Rewrite 2.1 and Application Request Routing 3.0 IIS modules installed. These can be installed by clicking on the “Get New Web Platform Components” link in the right hand side bar of IIS (you may need to install the Web Platform Installer first).
After installing these modules, you will need to close & re-open IIS.
Application Request Routing needs to have the proxy setting enabled. To do this, click on the top level server in the left side panel, and then double click the Application Request Routing icon. In the Actions panel click the Server Proxy Settings and then check Enable proxy at the top. Leave all the other settings the same and click Apply and then Back to ARR Cache.
IIS is not always set up to serve static content. To enable this, open the Server Manager software, click Manage, then Add Roles and Features then Next, Next. In the Roles widget, select Web Server(IIS)->Web Server->Common HTTP Features and make sure Static Content is selected. If it isn’t, enable that role.
Once you have Applicationn Request Routing installed and proxies enabled, in the left panel of IIS under Sites, select the default Web Site and click Stop on the right hand side.

Stop default website
Now right click on Sites and click Add Web Site

Add a new web site
Enter QATrack Static for the Site Name and “C:\deploy\qatrackplus\qatrack" for the Physical Path then click OK and answer Yes to the warning.
To test that setup worked correctly open a browser on your server and enter the address http://localhost/static/qa/img/tux.png You should see a picture of the Linux penguin.
Next, select the top level server in the Connections pane and then double click URL Rewrite:

URL Rewrite
In the top right click Add Rule and select Blank Rule.
Give it a name of QATrack Static and enter ^(static|media)/.* for the Pattern field, and select None for the Action type. Make sure Stop processing of subsequent rules is checked.

Static URL Rewrite Rule
When finished click Apply, then Back To Rules and then add another blank rule. Give it a name of QATrack Reverse Proxy, enter ^(.*) for the Pattern and http://localhost:8080/{R:1} for the Rewrite URL. In the Server Variables section add a new Server Variable with the Name=HTTP_X_FORWARDED_HOST and the Value=yourservername.com (replace yourservername with whatever your domain is!). Finally, make sure both Append query string and Stop processing of subsequent rules are checked.

URL Rewrite Reverse Proxy
Your URL rewrites should look like the following (order is important!)

URL Rewrite rules
Next Steps¶
Now that you have upgraded to 0.3.0, you should proceed directly to upgrading to v3.1.1 from v0.3.0;
Note there is no official support for the platforms listed below. That doesn’t necessarily mean they are unreliable, just that you may be on your own if you run into any issues. Of course you can always look for help on the mailing list.
Installing & Deploying QATrack+ with Docker¶
Warning
This is a developmental install method. It is quite simple to get up and running but has not been battle tested in production yet!
Warning
This install method has not yet been updated for version 3.1.X
Prerequisites by OS¶
This has been tested under two setups, Ubuntu 18.04, or Windows 10. Depending on which system you are using there are different ways to install the required dependencies. Follow the section that applies to your specific machine.
The aim of this setup is to have a complete installation of QATrack+ on a Windows 10 Professional or Enterprise machine with the backups being scheduled to be periodically copied to a OneDrive directory.
This setup uses Hyper-V. To use Hyper-V you need Windows 10 Professional or Enterprise with virtualisation enabled. To verify that virtualisation is enabled open the task manager, select More details, click on the Performance tab and verify that in the bottom right it states Virtualisation: Enabled as in the following screenshot:

Virtualisation enabled
If this says disabled then this will need to be enabled within your machines BIOS before continuing.
See https://docs.docker.com/docker-for-windows/troubleshoot/#virtualization for further troubleshooting if required.
To simplify this guide all installation will be done via the chocolatey package manager. To install chocoletey run the following in a command prompt with administrative privileges.
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
For more information on chocolatey see https://chocolatey.org/
To install Docker for Windows, Docker Compose and Git run the following within and administrative command prompt:
choco install git docker-for-windows -y
Reboot your machine.
Run the newly created Docker for Windows icon that has appeared on the desktop. If prompted to approve the request to enable Hyper-V. Thise will once again reboot your computer. Depending on your user priveledges you may need to add your user account to docker-users (https://github.com/docker/for-win/issues/868#issuecomment-352279510) at this point.
You should not need to click this icon again.
After multiple reboots Docker will begin downloading and setting up its virtual machine. This will take some time and you may notice the PC running slow while it is working on this.
Specifically you are waiting until the following popup is displayed:

Docker Welcome
On my machine this docker initialisation process took a little over 15 minutes.
To test that docker is working as expected run the following in a command prompt:
docker run hello-world
If your PC is running Ubuntu 18.04 follow these steps to install the required prerequisites.
To run this installation method you will need both docker-ce and docker-compose on your system. When running Ubuntu 18.04 do this by running the following commands:
sudo apt update
sudo apt upgrade
sudo snap install docker
sudo apt install python3-venv
python3 -m venv ~/.docker-compose
source ~/.docker-compose/bin/activate
pip install --upgrade pip
pip install docker-compose
Each time before using the docker-compose command you will need to repeat the above command of source ~/.docker-compose/bin/activate.
On other systems you can follow the instructions found at the following locations:
You will also need to implement the following to be able to run docker without sudo:
After completing these post install tasks please reset your computer.
Before continuing please verify that you can run docker run hello-world in a terminal.
To retrieve files from github you will need git installed by running the following:
sudo apt install git
On other systems follow the instructions at https://www.atlassian.com/git/tutorials/install-git.
Installing QATrack+¶
This part is OS independent. The language used will be tuned for a Windows 10 user, but equivalent steps can be followed on Ubuntu.
Open a command prompt with just user priveledges and change your directory to the directory where all of the QATrack+ server files will be stored.
Lets say, for example, all our files are going to be located within the D: drive at D:QATrack+ then we would want to do the following:
D:
cd QATrack+
At this point QATrack plus files need to be pulled from the git repository. Do the following:
git clone https://github.com/qatrackplus/qatrackplus.git
cd qatrackplus
To run any docker-compose commands you need to be within the qatrackplus\deploy\docker directory. So lets change to there now:
cd deploy\docker
To build and start the server run the following:
docker-compose build
docker-compose up
On initial run this will take quite some time to load.
Wait until you see something like the following within your terminal:
qatrack-django_1 | [2018-07-07 15:31:44 +0000] [509] [INFO] Starting gunicorn 19.3.0
qatrack-django_1 | [2018-07-07 15:31:44 +0000] [509] [INFO] Listening at: http://0.0.0.0:8000 (509)
qatrack-django_1 | [2018-07-07 15:31:44 +0000] [509] [INFO] Using worker: sync
qatrack-django_1 | [2018-07-07 15:31:44 +0000] [512] [INFO] Booting worker with pid: 512
qatrack-django_1 | [2018-07-07 15:31:44 +0000] [514] [INFO] Booting worker with pid: 514
Once the Listening at: http://0.0.0.0:8000 line is visible go to http://localhost in your computer’s browser to see the server.
If you go to the website too early you will see the following error. This is not an issue, it just means that the QATrack+ server has not yet finished initialising. The first time QATrack+ starts up initialisation can take about 10 minutes depending on your internet connection.

Default login is username admin, password admin. Once you have logged in as admin go to http://localhost/admin/auth/user/2/password/ to change the admin password to something more secure.
Create the following bat file:
NET USE V: "\\pdc\OneDrive$\QATrack+"
xcopy D:\QATrack+\qatrackplus\deploy\docker\user-data\backup-management\backups V:\backups /E /G /H /D /Y
Then using Windows Task scheduler to set that bat file to run daily.
Advanced usage tips¶
If you need to access the Django shell run the following in another terminal:
docker exec -ti docker_qatrack-django_1 /bin/bash
source deploy/docker/user-data/python-virtualenv/bin/activate
python manage.py shell
This requires that the containers are already running.
To have QATrack+ start on boot run the following command:
docker-compose up -d
To set up SSL I highly recommending using CloudFlare’s free ‘one-click ssl’ which will set up SSL security between your users and CloudFlare: https://www.cloudflare.com/ssl/
To also secure the path between CloudFlare and your server you will need to follow the following steps: https://support.cloudflare.com/hc/en-us/articles/217471977
The nginx.conf file referred to by that guide is contained within this directory. Place the certificate files within user-data/ssl then they will be available at /root/ssl/your_certificate.pem and /root/ssl/your_key.key on the server.
To reset the server and use your updated nginx.conf file run:
docker-compose stop
docker-compose up
The first number of the ports item within docker-compose.yml can be changed to use a port that is different to port 80. For example, if 80:80 was changed to 8080:80 then you would need to type http://localhost:8080 within your browser to see QATrack+. After editing docker-compose.yml you need to rerun docker-compose up.
To shutdown the server run:
docker-compose stop
You can also single press Ctrl + C within the server terminal that you ran docker-compose up to gracefully shutdown the server.
To update the server from github run:
docker-compose stop
git pull
Once any files have changed in the qatrackplus directory you need to run the following:
docker-compose build
docker-compose up
Everytime docker-compose up is run a timestamped backup zip file of the database, uploaded files, and your site specific css is created. These backups are stored within qatrackplus/deploy/docker/user-data/backup-management/backups. To restore a backup zip file copy it to the restore directory found at qatrackplus/deploy/docker/user-data/backup-management/restore. The restoration will occur next time docker-compose up is called. After successful restoration the zip file within the restore directory is deleted.
This restore method will also successfully restore backup files created on a different machine. However it will only successfully restore a like for like QATrack+ version. This cannot be used when upgrading between versions.
If for some reason you need it, the following command will delete all docker data from all docker projects (WARNING, IRREVERSABLE):
docker stop $(docker ps -a -q) && docker rm $(docker ps -a -q)
And this will delete all of the cache:
echo 'y' | docker volume prune
To just delete all postgres database data do the following:
docker stop docker_qatrack-postgres_1 && docker rm docker_qatrack-postgres_1 && docker volume rm docker_qatrack-postgres-volume
Configuring your QATrack+ Instance¶
After installing QATrack+ you will likely want to customize some of the settings for QATrack+. All of the available settings and how to set them is described here:
Configuring a QATrack+ Installation¶
QATrack+ Local Settings¶
Local settings allow you to override the default QATrack+ settings to better meet your clinics needs. The most important settings are explained below.
These settings should be defined in a local_settings.py file in the main directory (same directory as settings.py)
Any time you change a setting in local_settings.py, you need to restart the QATrack+ application either by restarting Apache or restarting the CherryPy Windows Service and you also need to restart Django Q.
sudo service apache2 restart
sudo supervisorctl reread
sudo supervisorctl update
Open a PowerShell Window and enter the following commands:
cd C:\deploy
.\venvs\qatrack31\Scripts\Activate.ps1
cd qatrackplus
python manage.py QATrack3CherryPyService.py restart
Stop-ScheduledTask -TaskName "QATrack+ Django Q Cluster"
Start-ScheduledTask -TaskName "QATrack+ Django Q Cluster"
When deploying your site for clinical use, you should set:
DEBUG = False
however, when you are experiencing issues getting your site deployed, setting:
DEBUG = True
will show you a detailed error traceback which can be used to diagnose any issues.
Danger
It is important to not use DEBUG = True during normal service as it may affect site performance and security.
On Linux, set allowed hosts either to your server name or IP address (e.g. for Apache):
ALLOWED_HOSTS = ['52.123.4.9']
On Windows using CherryPy/IIS (or if you are running QATrack+ behind a reverse proxy on Linux):
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
In order for urls to use the correct protocol for links, set HTTP_OR_HTTPS to the appropriate protocol.
HTTP_OR_HTTPS = 'http' # when using http for your site (default)
# -or -
HTTP_OR_HTTPS = 'https' # when using https/ssl for your site
The database setting is covered in more detail in the Django documentation as well as the QATrack+ deployment documentation.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'qatrackplus',
'USER': 'qatrack',
'PASSWORD': 'qatrackpass',
'HOST': 'localhost',
'PORT': '5432',
},
'readonly': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'qatrackplus',
'USER': 'qatrack_reports',
'PASSWORD': 'qatrackpass',
'HOST': 'localhost',
'PORT': '5432',
}
}
If you are using SQL Server and the SQL Reports feature, you may also need to set AUTOCOMMIT = False for your readonly configuration (see the USE_SQL_REPORTS setting below).
By default QATrack+ stores cached pages and values on disk in the directory qatrack/cache/cache_data/ but this can be changed by copying the Python dictionary below into your local_settings.py file:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/path/to/your/desired/cache/data/location/',
'TIMEOUT': 24*60*60, # cache timeout of 24hours
}
}
Generally you shouldn’t need to change this unless you have concerns about disk usage.
By default QATrack+ is configured to use North American Eastern Standard Time so you will need to adjust this to reflect your local time zone.
In your local_settings.py file add a line like the following:
TIME_ZONE = 'America/Toronto'
where ‘America/Toronto’ is replaced with your local timezone (e.g. TIME_ZONE = ‘Australia/Sydney’. If you are unsure, you can find a list of valid timezones on Wikipedia.
By default QATrack+ will show icons to indicate the pass/fail or due/overdue/not due status of tests and test lists.
Examples of the icons can be seen on BitBucket
To override the default settings, copy the following Python dictionary to your local_settings.py file and change the relevant setting to True/False.
ICON_SETTINGS = {
'SHOW_STATUS_ICONS_PERFORM': True,
'SHOW_STATUS_ICONS_LISTING': True,
'SHOW_STATUS_ICONS_REVIEW': True,
'SHOW_STATUS_ICONS_HISTORY': False,
'SHOW_REVIEW_ICONS': True,
'SHOW_DUE_ICONS': True,
}
- SHOW_STATUS_ICONS_PERFORM controls whether the icons are shown when a user is performing a test list.
- SHOW_STATUS_ICONS_LISTING controls whether icons are shown on listings pages which show the results of the last QC session. (Default True)
- SHOW STATUS_ICONS_REVIEW controls whether the icons are shown when a user is reviewing a test list. (Default True)
- SHOW STATUS_ICONS_HISTORY controls whether the icons are shown for historical results when a user is performing or reviewing a test list. (Default False)
- SHOW_REVIEW_ICONS control whether to show warning icon for unreviewed test lists. (Default True)
- SHOW_DUE_ICONS control whether to show icons for the due status of test lists. (Default True)
By changing the following settings you can alter the phrasing that QATrack+ uses for indicating whether a test is passing/failing. The TEST_STATUS_DISPLAY_SHORT settings are used when performing a test list and the TEST_STATUS_DISPLAY settings are used in notifications and when displaying historical results.
TEST_STATUS_DISPLAY = {
'action': "Action",
'fail': "Fail",
'not_done': "Not Done",
'done': "Done",
'ok': "OK",
'tolerance': "Tolerance",
'no_tol': "No Tol Set",
}
TEST_STATUS_DISPLAY_SHORT = {
'action': "ACT",
'fail': "Fail",
'not_done': "Not Done",
'done': "Done",
'ok': "OK",
'tolerance': "TOL",
'no_tol': "NO TOL",
}
The meaning of the individual keys is as follows:
- action: Test is failing or at action level (shown to users with permission to view Refs/Tols)
- fail: Test is failing or at action level (shown to users without permission to view Refs/Tols)
- not_done: Test was not completed
- done: Test was completed
- ok: Test is passing / within tolerance
- tolerance: The test is at tolerance (shown to users with permission to view Refs/Tols)
- no_tol: No tolerances set for this test
When ACCOUNTS_PASSWORD_RESET = True users will be able to reset or change their passwords on their own. This only applies to the normal QATrack+ authentication backend, and not the LDAP or ADFS backends. Default is True.
When ACCOUNTS_SELF_REGISTER = True anonymous users are able to register themselves for accounts. Default is False.
When ACCOUNTS_CLEAN_USERNAME is set to callable it will be used to transform any username that is to be authenticated. The most common scenario for this setting it is for example to set def ACCOUNTS_CLEAN_USERNAME(username): return username.lower() which makes all logins lowercase. Note in this case, the user can enter SoMeUsErName and it will be authenticated as someusername. Default is ACCOUNTS_CLEAN_USERNAME = False.
Set AUTOSAVE_DAYS_TO_KEEP to control the maximum number of days that auto-saved QC data will be kept for. The default settings is 30 days.
Set CHROME_PATH to the Chrome/Chromium executable for generating PDF reports. For example
CHROME_PATH = '/usr/bin/chromium-browser' # default
# - or -
CHROME_PATH = 'C:/path/to/chromium.exe' # on Windows
When CATEGORY_FIRST_OF_GROUP_ONLY = True, then the category will only be shown for the first test of a consecutive group of tests sharing the same category, otherwise the category will be shown next to each test line when performing QC.
When COMPOSITE_AUTO_FORMAT = True (default) calculation procedures will be auto formatted with Black . This leaves everyones code in a consistent format making stylistic differences when reading code a non-issue. Set to False to tell QATrack+ to leave your code alone!
Set the CONSTANT_PRECISION setting to adjust the precision for which Constant test type values are displayed. (default 8)
Default formatting string to be used for Composite & Constant number formatting (can be overridden on a test by test basis). Set to a Python style string format for displaying numerical results. Use e.g. %.2F to display as fixed precision with 2 decimal places, or %.3E to show as scientific format with 3 significant figures, or %.4G to use ‘general’ formatting with up to 4 significant figures. (Note this does not affect the way other values are calculated, only the way composite and constant test values are displayed. For example a constant test with a value of 1.2345 and a format of %.1f will be displayed as 1.2, but the full 1.2345 will be used for calculations). Note you may also use “new style” Python string formatting: see https://pyformat.info/ for examples.
DEFAULT_NUMBER_FORMAT = "%.3f" # 3 decimal place fixed precision using "Old" style formatting
DEFAULT_NUMBER_FORMAT = "{:.3f}" # 3 decimal place fixed precision using "New" style formatting
DEFAULT_NUMBER_FORMAT = "{:.4E}" # 5 sig fig scientific notation using "New" style formatting
Set DEFAULT_WARNING_MESSAGE = “Your custom message” to change the default warning message that will be shown when a performed test is at action level. If DEFAULT_WARNING_MESSAGE = “” then the default will be to not show any warning message when a test is at action level.
If you deploy QATrack+ at a non root url (e.g. http://5.5.5.5/qatrack/) then you need to set these settings as follows:
FORCE_SCRIPT_NAME = '/qatrack'
LOGIN_REDIRECT_URL = 'qatrack/'
LOGIN_URL = "/qatrack/accounts/login/"
If you’ve also changed the directory IIS is serving static media from, you may need to adjust the static and media urls as well:
# just an example, change according to how you have configured IIS
MEDIA_URL = '/qatrack_media/'
UPLOADS_URL = MEDIA_URL + 'uploads/'
STATIC_URL = '/qatrack_static/'
Sets the maximum number of tests per test list. Default is MAX_TESTS_PER_TESTLIST = 200
Adjusts the number of historical test results to show when reviewing/performing QC. Default is NHIST = 5.
Set ORDER_UNITS_BY = ‘name’ in your local_settings.py file in order to order units by name rather than number
Controls how often (in seconds) the server is “pinged” when performing QC or entering service log data. Set to PING_INTERVAL_S = 0 to disable the ping check. Default is PING_INTERVAL_S = 5
Set REVIEW_DIFF_COL = True to include a difference column when reviewing test list results. This column shows the difference between a test value and its reference value.
Set REVIEW_BULK = False to disable the Bulk Review feature which allows users to update the review and approval status of multiple test list instances at the same time.
Set SL_ALLOW_BLANK_SERVICE_AREA = True to allow users to create a ServiceEvent with a blank ServiceArea set. When a Service Event is saved without a ServiceArea explicitly set, the ServiceArea will be set to “Not Specified”.
Set SL_ALLOW_BLANK_SERVICE_TYPE = True to allow users to create a ServiceEvent with a blank ServiceType set. When a Service Event is saved without a ServiceType explicitly set, the ServiceType will be set to “Not Specified”.
Change the number of elapsed seconds before exporting a TestPack will time out. Default is 30.
Set USE_SQL_REPORTS to True in order to enable the SQL Query tool. Note if you are using SQL Server for your database, you may also need to set AUTOCOMMIT = False for your readonly database user:
DATABASES = {
'default': {
# default connection settings...
},
'readonly': {
'ENGINE': 'sql_server.pyodbc',
'AUTOCOMMIT': False,
# rest of db settings
}
}
Set USE_X_FORWARDED_HOST = True when running QATrack+ behind a reverse proxy and set to False for whenever you are not running behind a reverse proxy e.g. Set to True for CherryPy/IIS and False for Apache/mod_wsgi or development work.
These settings control how quickly users are automatically logged out of an active browser session. SESSION_COOKIE_AGE specifies how long (in seconds) a user can use a browser session without having to log in again (default 2 weeks). However, if SESSION_SAVE_EVERY_REQUEST is True the session age will be reset every time a user is active and hence allows them to stay logged in indefinitely.
SESSION_COOKIE_AGE = 14 * 24 * 60 * 60
SESSION_SAVE_EVERY_REQUEST = True
Configuring Email for QATrack+¶
QATrack+ email settings
QATrack+ has the ability to send emails email notifications when tests are at action or tolerance levels. In order for this to function you need access to an SMTP server that can send the emails for you.
In order to override the default settings, in your local_settings.py file you should set the following variables appropriately.
Who should be emailed when internal QATrack+ errors occur:
ADMINS = (
('Admin Name', 'admin.email@yourplace.com'),
)
MANAGERS = ADMINS
- EMAIL_HOST should be set to the SMTP host you are using (e.g. ‘smtp.gmail.com’ or ‘smtp.mail.your.hospital’)
- EMAIL_HOST_USER this is the default email address of the account to access the SMTP server
- EMAIL_HOST_PASSWORD this is the default account of the account to access the SMTP server
- EMAIL_USE_TLS set to True to use secure connection when connecting to the server
- EMAIL_PORT set to the port number to connect to the smtp server on (25 if EMAIL_USE_TLS is False, 587 if True)
- EMAIL_FAIL_SILENTLY set to False to see error tracebacks when sending an email fails. (should only be used for debugging)
Note that EMAIL_HOST_USER and EMAIL_HOST_PASSWORD can be set to None or “” if no authentication is required.
An example of these settings for a secure connection is shown here (for gmail):
EMAIL_HOST = "smtp.gmail.com"
EMAIL_HOST_USER = 'randle.taylor@gmail.com'
EMAIL_HOST_PASSWORD = 'my_very_secure_password'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
and for an unsecured connection:
EMAIL_HOST = "MYHOSPITALSMTPSERVER"
EMAIL_HOST_USER = None
EMAIL_HOST_PASSWORD = None
EMAIL_USE_TLS = False
EMAIL_PORT = 25
These settings allow you to override the default notification settings in your local_settings.py file:
- EMAIL_NOTIFICATION_SENDER email address to use in QATrack+ emails “From” address
- EMAIL_NOTIFICATION_SUBJECT_TEMPLATE allows you to override the default template to use for rendering the email subject line (see below)
- EMAIL_NOTIFICATION_TEMPLATE allows you to override the default template to use for rendering the email body (see below)
- (deprecated) EMAIL_NOTIFICATION_USER allows you to use a diferent user from the default set above (set to None to use EMAIL_HOST_USER). This setting is no longer used, set EMAIL_HOST_USER instead.
- (deprecated) EMAIL_NOTIFICATION_PWD password to go along with EMAIL_NOTIFICATION_USER. This setting is no longer used, set EMAIL_HOST_PASSWORD instead.
An example of these settings is shown here:
#-----------------------------------------------------------------------------
# Email and notification settings
EMAIL_NOTIFICATION_USER = None
EMAIL_NOTIFICATION_PWD = None
EMAIL_NOTIFICATION_SENDER = "Your Custom Name Here"
EMAIL_NOTIFICATION_SUBJECT_TEMPLATE = "my_custom_subject_template.txt"
EMAIL_NOTIFICATION_TEMPLATE = "my_custom_html_email.html"
Emails are generated using the Django template language with the following context available:
- test_list_instance The TestListInstance object containing information about the test list and unit where the tests were being performed.
- failing_tests a queryset of all tests that failed.
- tolerance_tests a queryset of all tests that are at tolerance level.
To create your own templates, use the examples below as a starting point and save them in the qatrack/notifications/templates/ directory and set the filenames for the TEMPLATE settings above.
An example subject template is shown below
{{test_list_instance.work_completed|date:"DATE_FORMAT"}} - {{test_list_instance.unit_test_collection.unit.name }}, {{test_list_instance.test_list.name}} - {% if failing_tests %} Tests at Action: {{failing_tests.count}} {% endif %} {% if tolerance_tests %} Tests at Tolerance: {{tolerance_tests.count}} {% endif %}
The default HTML email template is shown here:
{% load comments %}
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Notifications for {{test_list_instance.test_list.name}}</title>
<style>
/* -------------------------------------
GLOBAL RESETS
------------------------------------- */
img {
border: none;
-ms-interpolation-mode: bicubic;
max-width: 100%; }
body {
background-color: #f6f6f6;
font-family: sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 14px;
line-height: 1.4;
margin: 0;
padding: 0;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%; }
table {
border-collapse: separate;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
width: 100%; }
table td {
font-family: sans-serif;
font-size: 14px;
vertical-align: top; }
th.header {
text-align: right;
margin-right: 10px;
vertical-align: text-top;
}
table.test-table {
text-align: left;
}
table.test-table thead tr th.action {
text-align: center;
font-size: 1.1em;
background: #dd4b39;
color: white;
}
table.test-table thead tr th.tolerance{
text-align: center;
font-size: 1.1em;
background: #f39c12;
color: white;
}
table.test-table td.value,
table.test-table th.value{
text-align: right;
}
table.test-table td.comment {
text-align: left;
font-style: italic;
}
table.test-table td.test,
table.test-table th.test{
text-align: left;
}
/* -------------------------------------
BODY & CONTAINER
------------------------------------- */
.body {
background-color: #f6f6f6;
width: 100%; }
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
.container {
display: block;
Margin: 0 auto !important;
/* makes it centered */
max-width: 580px;
padding: 10px;
width: 580px; }
/* This should also be a block element, so that it will fill 100% of the .container */
.content {
box-sizing: border-box;
display: block;
Margin: 0 auto;
max-width: 580px;
padding: 10px; }
/* -------------------------------------
HEADER, FOOTER, MAIN
------------------------------------- */
.main {
background: #ffffff;
border-radius: 3px;
width: 100%; }
.wrapper {
box-sizing: border-box;
padding: 20px; }
.content-block {
padding-bottom: 10px;
padding-top: 10px;
}
.footer {
clear: both;
Margin-top: 10px;
text-align: center;
width: 100%; }
.footer td,
.footer p,
.footer span,
.footer a {
color: #999999;
font-size: 12px;
text-align: center; }
/* -------------------------------------
TYPOGRAPHY
------------------------------------- */
h1,
h2,
h3,
h4 {
color: #000000;
font-family: sans-serif;
font-weight: 400;
line-height: 1.4;
margin: 0;
Margin-bottom: 30px; }
h1 {
font-size: 35px;
font-weight: 300;
text-align: center;
text-transform: capitalize; }
p,
ul,
ol {
font-family: sans-serif;
font-size: 14px;
font-weight: normal;
margin: 0;
Margin-bottom: 15px; }
p li,
ul li,
ol li {
list-style-position: inside;
margin-left: 5px; }
a {
color: #3498db;
text-decoration: underline; }
/* -------------------------------------
BUTTONS
------------------------------------- */
.btn {
box-sizing: border-box;
width: 100%; }
.btn > tbody > tr > td {
padding-bottom: 15px; }
.btn table {
width: auto; }
.btn table td {
background-color: #ffffff;
border-radius: 5px;
text-align: center; }
.btn a {
background-color: #ffffff;
border: solid 1px #3498db;
border-radius: 5px;
box-sizing: border-box;
color: #3498db;
cursor: pointer;
display: inline-block;
font-size: 14px;
font-weight: bold;
margin: 0;
padding: 12px 25px;
text-decoration: none;
text-transform: capitalize; }
.btn-primary table td {
background-color: #3498db; }
.btn-primary a {
background-color: #3498db;
border-color: #3498db;
color: #ffffff; }
/* -------------------------------------
OTHER STYLES THAT MIGHT BE USEFUL
------------------------------------- */
.last {
margin-bottom: 0; }
.first {
margin-top: 0; }
.align-center {
text-align: center; }
.align-right {
text-align: right; }
.align-left {
text-align: left; }
.clear {
clear: both; }
.mt0 {
margin-top: 0; }
.mb0 {
margin-bottom: 0; }
.preheader {
color: transparent;
display: none;
height: 0;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
mso-hide: all;
visibility: hidden;
width: 0; }
.powered-by a {
text-decoration: none; }
hr {
border: 0;
border-bottom: 1px solid #f6f6f6;
Margin: 20px 0; }
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important; }
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 16px !important; }
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important; }
table[class=body] .content {
padding: 0 !important; }
table[class=body] .container {
padding: 0 !important;
width: 100% !important; }
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important; }
table[class=body] .btn table {
width: 100% !important; }
table[class=body] .btn a {
width: 100% !important; }
table[class=body] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important; }}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%; }
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%; }
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important; }
.btn-primary table td:hover {
background-color: #34495e !important; }
.btn-primary a:hover {
background-color: #34495e !important;
border-color: #34495e !important; } }
</style>
</head>
<body class="">
<table border="0" cellpadding="0" cellspacing="0" class="body">
<tr>
<td> </td>
<td class="container">
<div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader">Notifications for {{test_list_instance.test_list.name}}</span>
<table class="main">
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<p>Hello</p>
<p>
You are receiving this notice because one or more tests were at tolerance or action levels
for the following test list instance:
</p>
<table>
<tr>
<th class="header">
Test List:
</th>
<td>
{{test_list_instance.test_list.name}}
</td>
</tr>
<tr>
<th class="header">
Unit:
</th>
<td>
{{test_list_instance.unit_test_collection.unit.name}}
</td>
</tr>
<tr>
<th class="header">
Date:
</th>
<td>
{{ test_list_instance.work_completed }}
</td>
</tr>
<tr>
<th class="header">
Link:
</th>
<td>
<a href="{% if 'http' not in domain %}http://{% endif %}{{ domain }}{{ test_list_instance.get_absolute_url }}"
title="Click to view on the site"
>
{% if 'http' not in domain %}http://{% endif %}{{ domain }}{{ test_list_instance.get_absolute_url }}
</a>
</td>
</tr>
{% if test_list_instance.comments.exists %}
<tr>
<th class="header">Comments:</th>
<td>
{% render_comment_list for test_list_instance %}
</td>
</tr>
{% endif %}
</table>
<table class="test-table">
<thead>
<tr>
<th class="action" colspan="4">
Failing Tests
</th>
</tr>
<tr>
<th class="test">Test</th>
<th class="value">Value</th>
<th class="value">Reference</th>
<th class="value">Tolerance</th>
</tr>
</thead>
<tbody>
{% for test_instance in failing_tests %}
<tr>
<td class="test">{{test_instance.unit_test_info.test.name}}</td>
<td class="value">{{test_instance.value_display}}</td>
<td class="value">{{test_instance.reference}}</td>
<td class="value">{{test_instance.tolerance}}</td>
</tr>
{% if test_instance.comment %}
<tr>
<td class="comment" colspan="4">
{{ test_instance.comment }}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
<table class="test-table">
<thead>
<tr>
<th class="tolerance" colspan="4">
Tests at Tolerance
</th>
</tr>
<tr>
<th class="test">Test</th>
<th class="value">Value</th>
<th class="value">Reference</th>
<th class="value">Tolerance</th>
</tr>
</thead>
<tbody>
{% for test_instance in tolerance_tests %}
<tr>
<td class="test">{{test_instance.unit_test_info.test.name}}</td>
<td class="value">{{test_instance.value_display}}</td>
<td class="value">{{test_instance.reference}}</td>
<td class="value">{{test_instance.tolerance}}</td>
</tr>
{% if test_instance.comment %}
<tr>
<td class="comment" colspan="4">
{{ test_instance.comment }}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</td>
</tr>
</table>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- START FOOTER -->
<div class="footer">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="content-block">
<span class="apple-link"></span>
</td>
</tr>
<tr>
<td class="content-block powered-by">
Sent by QATrack+
</td>
</tr>
</table>
</div>
<!-- END FOOTER -->
<!-- END CENTERED WHITE CONTAINER -->
</div>
</td>
<td> </td>
</tr>
</table>
</body>
</html>
An example plain text email template is shown below
=== Notifications for {{test_list_instance.test_list.name}} ===
Test List : {{test_list_instance.test_list.name}}
Unit : {{test_list_instance.unit_test_collection.unit.name}}
Date : {{test_list_instance.work_completed }}
{% if failing_tests %}
Failing Tests
=============
{% for test_instance in failing_tests %}
Test : {{test_instance.unit_test_info.test.name}}
Value : {{test_instance.value_display}}
Ref. : {{test_instance.reference}}
Tol. : {{test_instance.tolerance}}
{% endfor %}
{% endif %}
{% if tolerance_tests %}
Tests at Tolerance
==================
{% for test_instance in tolerance_tests %}
Test : {{test_instance.unit_test_info.test.name}}
Value : {{test_instance.value_display}}
Ref. : {{test_instance.reference}}
Tol. : {{test_instance.tolerance}}
{% endfor %}
{% endif %}
QATrack+ allows you to use an Active Directory (AD) server for User authentication. In order to use Active Directory you need to set up the following settings:
In order to use one of the Active Directory backends, you need to copy the AUTHENTICATION BACKENDS setting to your local_settings.py and uncomment the backend you want to use e.g.:
AUTHENTICATION_BACKENDS = [
'qatrack.accounts.backends.QATrackAccountBackend',
'qatrack.accounts.backends.ActiveDirectoryGroupMembershipSSLBackend',
# 'qatrack.accounts.backends.WindowsIntegratedAuthenticationBackend',
# 'qatrack.accounts.backends.QATrackAdfsAuthCodeBackend',
]
AD_DNS_NAME = 'ad.subdomain.maindomain.on.ca' # DNS Name
AD_LU_ACCOUNT_NAME = "sAMAccountName" # AD Lookup account name property
AD_LU_MAIL = "mail" # AD Lookup account email property
AD_LU_SURNAME = "sn" # AD Lookup account surname property
AD_LU_GIVEN_NAME = "givenName" # AD Lookup account given name property
AD_LU_MEMBER_OF = "memberOf" # AD Lookup group membership property
AD_SEARCH_DN = "" # eg "dc=ottawahospital,dc=on,dc=ca"
AD_NT4_DOMAIN = "" # Network domain that AD server is part of
AD_CERT_FILE = '/path/to/your/cert.txt'
AD_CLEAN_USERNAME_STRING = '' # if your AD usernames are returned as e.g. "foo/jsmith" then
# setting `AD_CLEAN_USERNAME_STRING = 'foo/'` will strip the `foo/` prefix
# off the username, so the QATrack+ username will just be 'jsmith'
AD_CLEAN_USERNAME = None # define a function called AD_CLEAN_USERNAME in local_settings.py if you
# wish to clean usernames before sending to ldap server e.g.
# def AD_CLEAN_USERNAME(username): return username.lower()
If using a non-SSL connection use these
AD_LDAP_PORT = 389
AD_LDAP_URL = 'ldap://%s:%s' % (AD_DNS_NAME, AD_LDAP_PORT)
AD_LDAP_USER = ''
AD_LDAP_PW = ''
If using SSL use these:
AD_LDAP_PORT = 636
AD_LDAP_URL = 'ldaps://%s:%s' % (AD_DNS_NAME,AD_LDAP_PORT)
AD_LDAP_USER = ''
AD_LDAP_PW = ''
More information on Active Directory is available here: Active Directory.
Authentication Backends¶
QATrack+ has a few different methods of authenticating users:
- The built in Django backend. No additional configuration is required but users and their group memberships need to be managed manually.
- Active Directory. Use your hospitals AD system for managing users and groups.
- Active Directory Federiation Services. Use your hospitals AD FS system for managing users and groups.
Active Directory¶
Using an existing Active Directory server to do your user authentication is a great way to simply the management of users for your QATrack+ system. It’s especially convenient for your users that they don’t have to remember “yet another password” and can simply use their network logon. QATrack+ comes with an Active Directory backend and it’s configuration will be described below.
If you happen to be on a Windows system with Visual Studio installed, you should just be able to do pip install python-ldap and have the latest version of the pyldap package installed. Otherwise, there are binaries available on this page: https://www.lfd.uci.edu/~gohlke/pythonlibs/#python-ldap. Download the binary relevant to your Python 3 installation (e.g. python_ldap‑3.3.1‑cp36‑cp36m‑win_amd64.whl) and then pip install it:
pip install C:\path\to\python_ldap‑3.3.1‑cp36‑cp36m‑win_amd64.whl
To confirm your installation is working, activate your virtual env
cd C:\deploy
.\venvs\qatrack3\scripts\activate
python -c "import ldap; print(ldap.__version__)"
If that commands prints the ldap version then ldap is installed correctly.
There are some pre-requisistes that need to be installed before python-ldap.
At the time of writing on Ubuntu this looks like:
sudo apt-get install build-essential python3-dev python2.7-dev \
libldap2-dev libsasl2-dev slapd ldap-utils
source ~/venvs/qatrack3/bin/activate
pip install python-ldap
See https://www.python-ldap.org/en/latest/installing.html for more details.
Copy the following lines to your local_settings.py file:
#-----------------------------------------------------------------------------
# Authentication backend settings
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'qatrack.accounts.backends.ActiveDirectoryGroupMembershipSSLBackend',
)
# active directory settings (not required if only using ModelBackend
AD_DNS_NAME = 'your.ad.server.yourhospital.com'
# If using non-SSL use these
AD_LDAP_PORT = 389
AD_LDAP_URL = 'ldap://%s:%s' % (AD_DNS_NAME, AD_LDAP_PORT)
# If using SSL use these:
# AD_LDAP_PORT=636
# AD_LDAP_URL='ldaps://%s:%s' % (AD_DNS_NAME,AD_LDAP_PORT)
AD_CERT_FILE = None # AD_CERT_FILE='/path/to/your/cert.txt'
AD_SEARCH_DN = "dc=yourdomain,dc=yourhospital,dc=com"
AD_NT4_DOMAIN = "YOURDOMAIN" # Network domain that AD server is part of
AD_SEARCH_FIELDS = ['mail', 'givenName', 'sn', 'sAMAccountName', 'memberOf']
AD_DEBUG_FILE = "C:/deploy/qatrackplus/logs/ad_log.txt"
AD_DEBUG = False # set to True and restart QATrack+ CherryPy Service if you need to debug AD Connection
You will also obviously have to modify AD_DNS_NAME1, `AD_SEARCH_DN and AD_NT4_DOMAIN to suit your own Active Directory setup. The complete set of Active Directory settings are described here: Active Directory Settings.
After you have saved that file, you will need to restart your application server (or for example your CherryPy service).
Active Directory Federation Services (ADFS)¶
As of version 3.1.0 comes with an ADFS backend for Single Sign On (SSO). This can provide a convenient way for your users to log into QATrack+ using their hospital network login.
There are two backends you can potentially use for using ADFS for SSO. There is the raw django_adfs.backends.AdfsAuthCodeBackend which you can read more about at https://django-auth-adfs.readthedocs.io/en/latest/settings_ref.html and there is the qatrack.accounts.backends.QATrackAdfsAuthCodeBackend which is a wrapper around the AdfsAuthCodeBackend with some QATrack+ specific functionality added. In order to enable one of these backends you need to set your AUTHENTICATION_BACKENDS setting like:
AUTHENTICATION_BACKENDS = [
'qatrack.accounts.backends.QATrackAccountBackend',
'qatrack.accounts.backends.QATrackAdfsAuthCodeBackend',
# or comment above and uncomment below
# 'django_adfs.backends.AdfsAuthCodeBackend'
]
Please see the following guides to configure your ADFS Server to allow access for QATrack+:
The following will give a step by step on how to configure QATrack+ as a client application in Active Directory Federation Services 2016 (AD FS 2016).
First, launch AD FS Management, which can be located in the Start Menu under Windows Administrative Tools:

AD FS Management Link in Start Menu
In the left hand panel expand the ‘AD FS’ folder and click on ‘Application Groups’ then click on ‘Add Application Group…’.

Adding an Application Group
In the Add Application Group Wizard set the Name to QATrack+ (or something else if you prefer). In the Template area select Web browser accessing a web application and then click Next >.

Add Application Group Wizard
On the next page set the Client Identifier to qatrackplus; this is what you will set the CLIENT_ID field to in your AUTH_ADFS settings. Set the Redirect URI to the url of your QATrack+ server with a path of accounts/oauth2/callback (no trailing slash) and then click Add. For example if your QATrack+ server is located at https://qatrack.yourhospital.com then you would set the Redirect URI to https://qatrack.yourhospital.com/accounts/oauth2/callback.

Native Application Page
On the next page leave the Policy as Permit everyone and click Next.

Access Control settings
On the Summary page confirm your settings are correct and click Next then Close.

Settings Summary
You will now have a QATrack+ Application Group showing. Select it and then click Properties in the right hand pane.

App group properties
In the QATrack+ Properties Dialog, select the QATrack+ - Web application item in the Web application section and then click Edit…

QATrack+ App group properties
Click on the Issuance Transform Rules tab at the top of the properties dialog and click Add Rule

Issuance Transform Rules
Set the Claim rule template to Send LDAP Attributes as Claims and click Next.

Select claim rule template
On the next page set the Claim rule name to LDAP Attributes and set the Attribute store to Active Directory. In the Mapping of LDAP attributes to outgoing claim types field set the following attributes:
LDAP Attribute | Outgoing Claim Type |
---|---|
E-Mail-Addresses | E-Mail Address |
Given-Name | Given Name |
Surname | Surname |
Token-Groups - Unqualified Names | Group |
SAM-Account-Name | Windows account name |
then click Finish:

Setting up the claims
and OK:

Issuance rules set
You can now proceed to configure your QATrack+ application to use AD FS. The settings you will need are:
SERVER: The HostName of your ADFS server. For example adfs.yourhospital.com. You can retrieve this setting by opening a PowerShell window and entering:
Get-AdfsProperties | select HostName | Format-List
CLIENT_ID: Use qatrackplus or whatever you set the Client Identifier to above.
To double check this setting open a PowerShell window and enter:
Get-AdfsNativeClientApplication -Name "QATrack+ - Native application"
and look for the Identifier field.
RELYING_PARTY_ID: The Relying Party Identifier will be the same as the CLIENT_ID setting e.g. qatrackplus double check this setting open a PowerShell window and enter:
Get-AdfsWebApiApplication | select Identifier | Format-List
AUDIENCE: Use the RELYING_PARTY_ID setting but prefixed with microsoft:identityserver: e.g. microsoft:identityserver:qatrackplus
The following will give a step by step on how to configure QATrack+ as a client application in Active Directory Federation Services 3.0 (AD FS 2016).
First, launch AD FS Management, which can be located in the Start Menu under Windows Administrative Tools:

AD FS Management Link in Start Menu
In the left hand panel expand the ‘AD FS’ folder and click on ‘Trust Relationships’ then click on ‘Add Relying Party Trust…’.

Adding a Relying Party Trust
In the Add Relying Party Trust Wizard click ‘Enter data about the relying party manually’ and then click Next

Choose to enter the data about the reyling party manually
set the Display Name to QATrack+ and click Next.

Setting the display name
On the next page keep the Profile selection as AD FS profile

Select the AD FS profile option
On the next page Leave the Certificate blank and click Next

Leave the certificate blank
Likewise on the Configure URL page leave both options unchecked and click Next

WS-Federation Passive and SAML2.0 WebSSO protocols unchecked
On the Configure Identifiers page set the Relying party trust identifier to qatrackplus (this is what you will set the CLIENT_ID field to in your AUTH_ADFS settings) and click Add.

Set the relying party trust identifier to qatrackplus
On the Configure Multi-factor Authentication Now page leave the I do not want to configure multi-factor authentication settings for this relying party trust at this time option selected and click Next.

Do not configure MFA at this time
On the Choose Issuance Authorization Rules page select Permit all users to access this relying party and click Next.

Permit All Users
On the Ready to Add Trust page click Next and then on the final page select Open the Edit Claim Rules dialog for this relying party trust when the wizard close and click Close

Open claims rules
In the Edit Claim Rules for QATrack+ dialog, on the Issuance Transform Rules click Add Rule:

Add a rule
Ensure Send LDAP Attributes as Claims is selected and click Next:

Send LDAP Attributes as Claims
On the next page set the Claim rule name to LDAP Attributes and set the Attribute store to Active Directory. In the Mapping of LDAP attributes to outgoing claim types field set the following attributes:
LDAP Attribute | Outgoing Claim Type |
---|---|
E-Mail-Addresses | E-Mail Address |
Given-Name | Given Name |
Surname | Surname |
Token-Groups - Unqualified Names | Group |
SAM-Account-Name | Windows account name |
then click Finish and then OK:

LDAP Attributes Map
and then click OK.
Now open a PowerShell Window and enter the following command making sure to set the RedirectUri to the url of your QATrack+ server with a path of accounts/oauth2/callback (no trailing slash). For example if your QATrack+ server is located at https://qatrack.yourhospital.com then you would set the Redirect URI to https://qatrack.yourhospital.com/accounts/oauth2/callback.
Add-ADFSClient -Name "QATrack+ OAuth2 Client" `
-ClientId "qatrackplus" `
-RedirectUri "https://qatrack.yourhospital.com/accounts/oauth2/callback"

Adding the QATrack+ client
You can now proceed to configure your QATrack+ application to use AD FS. The settings you will need are:
SERVER: The HostName of your ADFS server. For example adfs.yourhospital.com. You can retrieve this setting by opening a PowerShell window and entering:
Get-AdfsProperties | select HostName | Format-List
CLIENT_ID: Use qatrackplus or whatever you set the Client Identifier to above. To double check this setting open a PowerShell window and enter:
Get-ADFSClient -Name "QATrack+ OAuth2 Client"
RELYING_PARTY_ID: Use the Relying Party Identifier you set above e.g. qatrackplus. To double check this setting open a PowerShell window and enter:
Get-AdfsRelyingPartyTrust -Name "QATrack+" | Select Identifier
AUDIENCE: Use the RELYING_PARTY_ID setting but prefixed with microsoft:identityserver: e.g. microsoft:identityserver:qatrackplus
Copy the following lines to your local_settings.py file:
AUTHENTICATION_BACKENDS = [
'qatrack.accounts.backends.QATrackAccountBackend',
'qatrack.accounts.backends.QATrackAdfsAuthCodeBackend',
]
# AD FS settings.
AUTH_ADFS = {
"SERVER": "some.adfs.server.com",
"CLIENT_ID": "qatrackplus",
"RELYING_PARTY_ID": "https://your.qatrackserver.com",
"AUDIENCE": "https://your.qatrackserver.com",
"CLAIM_MAPPING": {
"first_name": "given_name",
"last_name": "family_name",
"email": "email"
},
"USERNAME_CLAIM": "winaccountname",
"GROUPS_CLAIM": "group",
}
If you require a different configuration for some reason, more options and settings are described in https://django-auth-adfs.readthedocs.io/en/latest/settings_ref.html
Mapping Active Directory Groups to QATrack+ Groups¶
You can have your users automatically added to one or more QATrack+ groups based on their Active Directory Group memberships. For more information on configuring this see Active Directory Group to QATrack+ Groups Map.
Backing up QATrack+¶
Note
Note, please speak with your server administrator to see if you already have a backup plan in place for both databases and files. If you already do then great, you can ignore this page! If not then please read on.
It is highly recommended you put an automated backup solution in place for your QATrack+ installation. It is also highly recommended that your backups not reside on the QATrack+ server itself. That is to say, you should favour having your backups stored on a remote system (e.g. a network or shared drive) so that if your server loses its primary hard drive you will still have access to your backups. Example backup scripts for Linux (to be run by cronjob) and Windows (run by Task Scheduler) are included below. These scripts back up nightly, and retain daily backups for a week, weekly backups for 5 weeks and monthly backups for ~1 year (these values are configurable).
Danger
The scripts included below can be used as is, or modified to suit your needs, but ultimately it is up to you to ensure your QATrack+ installation is backed up correctly.
Backing up QATrack+ on Linux¶
To use one of the example backup scripts on a Linux install, copy the appropriate script for your database to the main QATrack+ directory:
cp deploy/postgres/backup.sh .
# - or - #
cp deploy/mysql/backup.sh
Now edit the backup.sh file and set the various options in the configuration section. Add the backup.sh script to your crontab:
# make the script executable by everyone so cron can run it
chmod 755 backup.sh
# add the crontab entry to run every night at 3am
(crontab -l && echo "0 3 * * * $PWD/backup.sh") | crontab -
# -or edit your crontab manually and append a line like "0 3 * * * /home/randlet/web/qatrackplus/backup.sh"
crontab -e
Backing up QATrack+ on Windows¶
First copy the script deploy/backup/win/backup.ps1 to the main qatrackplus directory:
cd C:\deploy\qatrackplus
cp deploy\win\backup.ps1 .
Then edit the backup.ps1 file and set the configuration variables appropriately.
Next open the Task Scheduler and select Create Task in the Action menu.
On the General tab set the Name field to QATrack+ Backup (or similar). Check the Run whether user is logged on or not checkbox.
On the Triggers tab click New and select Daily and choose the Start date and Time (e.g. 3am) and Recur every to 1 then click OK.
Now go to the Actions tab and click New then enter PowerShell.exe in the Program/Script field and -ExecutionPolicy Bypass C:\deploy\qatrackplus\backup.ps1 in the Add Arguments field.
Now save your scheduled task and run it and manually to confirm it worked correctly.
Using Django to Dump The Database To JSON¶
In some cases you may want to move your database from one type of SQL database to another, say from Postgres to SQLite. In this case, one way to do this is to dump your database to a JSON file and then load it in your other database.
Open a terminal, and activate your virtual environment and then:
python manage.py dumpdata > qatrack-dump.json
The qatrack-dump.json file can now be used to populate a fresh database.
Danger
This will completely erase all of the data in your database. Only do this if you are sure you are dealing with a fresh database
You must load your previously dumped database into the same version of QATrack+. First you need to create a new database, and then configure QATrack+ to access it. Then migrate your database and clean out the autopopulated data:
python manage.py migrate
python manage.py shell -c "from qatrack.qa.models import *; TestListInstance.objects.all().delete(); UnitTestCollection.objects.all().delete(); ContentType.objects.all().delete()"
Then you can load in your new data:
python manage.py loaddata qatrack-dump.json
Administrators Guide¶
Introduction¶
The admin guide is intended for use by anyone who will be responsible for configuring tests and test lists, modifying references & tolerances or managing users and user permissions. Typically this would be limited to a small group of users within the clinic.
Accessing the admin site¶
To access the admin site, log into QATrack+ and then choose the Admin option from the dropdown at the top right hand corner of the page (where your username is displayed).
A walk through tutorial (with screenshots) on going from a blank QATrack+ install to a fully configured, performable test list is available on the Tutorials page. Reading through this tutorial is a great way to familiarize yourself with QATrack+ configuration.
Initial Configuration¶
Before you start defining tests and test lists for the first time it is a good idea to begin by doing some initial configuration.
Admin Guide Contents¶
Changing The Site Name Displayed at the Top of Pages¶
To change the name of your site from example.com:
- Go to the Admin area of the website
- In the Websites section click on the “Websites” or “Change” link.
- Click on the example.com site
- Set the Domain name field to your server domain and root of your QATrack installation (e.g. yourcomputer/qatrack or 123.456.1.1/qatrack) and the Display name to what you want shown in the top left hand corner of your site.
- Click Save

Changing the default Site from example.com
Managing Users and Groups¶
Access to various QATrack+ features for users is defined based on which groups a user belongs to and which permissions have been assigned to their groups, or to their user account specifically.
The text below discusses how to manage users and groups from within the QATrack+ admin area. As of version 3.1.0 there is also now a more convient Groups & Permissions page for managing group memberships and common permissions.
User Groups¶
User groups are useful for managing the permissions of many users at once. For example, you may have groups for Administrators, Physicists, Physics Technologists and Therapists (A user may belong to one or more groups) each with different permissions and different parts of QATrack+ accessible to them.
To define a new user group click on the Groups link from the main admin page and then click Add group on the top right hand corner of the next page. Give your group a name and then choose the permissions available to that group (permissions are described in more detail below).
Select the Default Group checkbox if you want all users to be added to this group. The users groups will be checked every time they log in and if they are not part of a default group, they will automatically be added to it.
Once you are finished, click Save.

Creating a new group
Active Directory Group to QATrack+ Groups Map¶
As of version 3.1.0 QATrack+ now has a method of automatically assigning users to QATrack+ groups based on the Active Directory (AD) groups they belong to. This mapping of AD groups to QATrack+ groups is done in the Authentication and Authorization Backend Settings -> Active Directory Group to QATrack+ Group Map section of the admin.
Lets say for example that you wanted any user which belongs to the Your Hospital - Medical Physics Active Directory group to automatically be added to the Physics, Electrons, and Cyberknife QATrack+ groups. Then you would set up an Active Directory Group to QATrack+ Group Map with the following settings:
- Active Directory Group: Your Hospital - Medical Physics
- QATrack+ Groups: Cyberknife, Electronics, Physics

Creating a group mapping from Active Directory Groups to QATrack+ Groups
The Group Map’s have an additional Account Qualifying Group flag which can be set. If one or more Group Map objects have the Account Qualifying Group flag set then any user who tries to log into QATrack+ must belong to at least one of those Active Directory groups in order to be permitted to login to QATrack+. For example, in the screenshot below, a user would have to belong to either the Your Hospital - Physics AD group, or the Your Hospital - Therapy groups in order to be permitted to log into QATrack+.

Active Directory Qualifying Groups
Users¶
If you are using Active Directory or Active Directory Federation Services for user authentication then new users will be automatically created the first time they log in. Otherwise if you are using the built in authentication system you will need to create users manually.
From the main admin page click on the Users link under the Auth section and then click Add user. On the next page fill out the username and password fields. (The user will be able to change their password to something different on their own later). Click Save when you are finished.

Creating a new user
On the next page you can fill out more details about the users including proper names and which groups the user belongs to. You may also add permissions specific to that person (i.e. that are not already covered by the groups they are members of) although it is highly recommended that you stick to using groups for managing all permissions.

Creating a new user and setting permissions
Any user that has Admin Status (formerly Staff Status) checked on their user profile page will have access to the admin site.
A user with Superuser status checked will have all permissions granted to them without needing to explicitly specified.
Permissions¶
The easiest method of managing permissions is to grant specific permissions to a group and then make users part of that group. The user will inherit all the permissions of their groups and as such do not need to have them explicitly granted to them on their user profile page. It is recommended that you only use groups for managing permissions and don’t assign permissions to users directly (that is, you can leave the Chosen user permissions box blank on most users profile page).
You will likely want to tweak the set of permissions your user groups are granted but example permission sets are given below to help you get started.
The most important permissions are described here and typical permission sets for groups are given below:.
- auth | group | Can change group Allows a user to change group membership and permissions.
- qa | test instance | Can view test history Allows a user to view historical data alongside a test when performing a test list.
- qa | test instance | Can view charts of test history Allows a user to plot charts of historical data
- qa | test instance | Can review tests Allow a user to perform review & approval functions
- qa | test instance | Can review & approve self-performed tests Allow a user to review their own test results (requires review permission as well)
- qa | test instance | Can review non visible test list instances Allow a user to review test list instances that are not visible to any of their groups
- qa | test instance | Can skip without comment Allows a user to skip tests without adding a comment
- qa | test list instance | Can add test list instance Required for all users who will be performing QC
- qa | test list instance | Can perform subset of tests Allows a user to perform only a subset of test categories when performing a test list
- qa | test list instance | Can save in progress Allows a user to save test lists with the “In Progress” flag set
- qa | test list instance | Can view previously completed instances Allows a user to view (but not edit) previously completed test lists
- qa | test list instance | Can change test list instance Allows a user to edit previously completed test results
- qa | frequency | Choose QC by Frequency Allows a user to access different frequencies of QC to perform
- qa | test list instance | Can override date Enables a user to override the default date and time for a test list instance
- qa | unit test info | Can view Refs and Tols Enables the display of reference and tolerance values when a user is performing a test list
- qa | unit test collection | Can view program overview Allows a user to view the program overview page
- qa | unit test collection | Can view TLI and UTC not visible to user’s groups Allows a user to view all Test Lists regardless of their groups
- reports | saved reports | Can Create SQL Data Reports Gives user the ability to create and run raw SQL queries on your data
- reports | saved reports | Can Run SQL Data Reports allows a user to run previously defined SQL queries
- reports | saved reports | Can Create Reports Gives user the ability to create and run reports on your data
- reports | saved reports | Can Run Reports allows a user to run previously defined reports
- service_log | hours | Can have hours Allow tracking of users hours when involved with a Service Event
- service_log | return to service qa | Can perform return to service qa Allow user to perform qa linked to service events
- service_log | return to service qa | Can view existing return to service qa Allow user to view qa linked to service events
- service_log | service event | Can create service events Allows user to create new service events
- service_log | service event | Can view service events Allows user to view existing service events
- service_log | service event | Can review service events Allows user to change status of service events to statuses with ‘is review required = false’.
- parts | part | Can add part Allows a user to enter new parts
- parts | part | Can view parts Allows a user to view existing parts
- faults | fault | Can add fault Allows a user to log a machine fault
- faults | fault | Can change fault Allows a user to edit an existing fault
- faults | fault | Can delete fault Allows a user to delete an existing fault
- faults | fault | Can review faults Allows a user to review faults
A fairly minimal set of permissions for performing QC (e.g. for a therapist) is:
- qa | test list instance | Can add test list instance
- qa | test list instance | Can perform subset of tests (optional)
- qa | test list instance | Can view previously completed instances (optional)
- faults | fault | Can add fault

Minimal set of permissions
This set of permissions will allow a user to access and perform daily & weekly QC and optionally view previously comleted test lists.
For users who will be performing lots of QC but will not be reviewing and approving data or configuring new tests and test lists (e.g. a Physics Technologist), the list of permissions might look like the following:
- qa | frequency | Choose QC by Frequency
- qa | test instance | Can chart test history
- qa | test instance | Can view test history
- qa | test list instance | Can add test list instance
- qa | test list instance | Can override date
- qa | test list instance | Can perform subset of tests
- qa | test list instance | Can view previously completed instances
- qa | test list instance | Can change test list instance
- qa | unit test info | Can view Refs and Tols
- faults | fault | Can add fault

Physics Techs Permissions
For a user who will be performing QC, reviewing and approving data and configuring new tests and test lists and groups (e.g. a Physicist), a typical permission set might look like the following:
- auth | group | Can add group
- auth | group | Can change group
- auth | permission | Can add permission
- auth | permission | Can change permission
- auth | user | Can add user
- auth | user | Can change user
- contacts | contact | Can add contact
- contacts | contact | Can change contact
- contacts | contact | Can delete contact
- qa | category | Can add category
- qa | category | Can change category
- qa | frequency | Can add frequency
- qa | frequency | Choose QC by Frequency
- qa | frequency | Can change frequency
- qa | reference | Can add reference
- qa | reference | Can change reference
- qa | test | Can add test
- qa | test | Can change test
- qa | test instance | Can add test instance
- qa | test instance | Can review tests
- qa | test instance | Can chart test history
- qa | test instance | Can view test history
- qa | test instance | Can change test instance
- qa | test instance | Can delete test instance
- qa | test instance | Can skip without comment
- qa | test instance status | Can add test instance status
- qa | test instance status | Can change test instance status
- qa | test list | Can add test list
- qa | test list | Can change test list
- qa | test list cycle | Can add test list cycle
- qa | test list cycle | Can change test list cycle
- qa | test list cycle membership | Can add test list cycle membership
- qa | test list cycle membership | Can change test list cycle membership
- qa | test list cycle membership | Can delete test list cycle membership
- qa | test list instance | Can add test list instance
- qa | test list instance | Can override date
- qa | test list instance | Can perform subset of tests
- qa | test list instance | Can view previously completed instances
- qa | test list instance | Can change test list instance
- qa | test list instance | Can delete test list instance
- qa | test list membership | Can add test list membership
- qa | test list membership | Can change test list membership
- qa | test list membership | Can delete test list membership
- qa | tolerance | Can add tolerance
- qa | tolerance | Can change tolerance
- qa | unit test collection | Can add unit test collection
- qa | unit test collection | Can change unit test collection
- qa | unit test info | Can add unit test info
- qa | unit test info | Can view Refs and Tols
- qa | unit test info | Can change unit test info
- reports | saved reports | Can Create SQL Data Reports
- reports | saved reports | Can Run SQL Data Reports
- reports | saved reports | Can Create Reports
- reports | saved reports | Can Run Reports
- service_log | hours | Can have hours
- service_log | return to service qa | Can perform return to service qa
- service_log | return to service qa | Can view existing return to service qa
- service_log | service event | Can create service events
- service_log | service event | Can view service events
- service_log | service event | Can review service events
- parts | part | Can add part
- parts | part | Can view parts
- faults | fault | Can add fault
- faults | fault | Can change fault
- faults | fault | Can delete fault
- faults | fault | Can review faults
Email Notifications¶
QATrack+ comes with a number of built in email notification types that can be triggered by actions taken on the site or scheduled to be delivered at a specific time. Currently the availble notification types are:
- QC Completed Notices
- QC Review Notices
- QC Scheduling Notices
- Service Event Notices
- Service Event Scheduling Notices
- Part Notices
- Fault Logged Notices
- Fault Review Notices
Configuring Notifications¶
Through the use of Recipient Groups, Unit Groups, Test List Groups, and Part Category Groups notifications can be configured so that they are only apply to certain Units & Test Lists and are only sent to specific users. Configuring these notification groups is done in the admin area under the Notifications header:

The Notification admin section
These notifications groups can either be configured on the fly when creating/editing new notifications, or defined ahead of time.
QATrack+ allows you to target notifications to specific users/email addresses using Recipient Groups. A Recipient Group is made up of User Groups, Users, or individual email addresses. To create a new Recipient Group click through the Recipient groups link in the Notifications section of the admin area and then on the next page click Add Recipient Group and then fill out the fields:
- Name (required)
- Give the recipient group a relavant name
- Groups (optional)
- All users included in these Group will receive the notifications.
- Users (optional)
- Include any individual Users you want to receive the notifications.
- Extra recipient emails (optional)
- Include any emails which are not associated with a QATrack+ User

Filling out the fields for a recipient group.
and finally click Save. This Recipient Group can now be associated with Notifications.
A Unit Group is made up of one or more Units and allows you to target notifications to specific Units using Unit Groups. To create a new Unit Group click through the Unit Group section of the admin and then on the next page click Add Unit Group and then fill out the fields:
- Name (required)
- Give the Units Group a relevant name
- Units (required)
- Select the Units to include in this group.

Filling out the fields for a Unit group.
and finally click Save. This Unit Group can now be associated with Notifications.
A Test List Group is made up of one or more Test Lists and allows you to target notifications to specific Test Lists using Test List Groups. To create a new Test List Group click through the Test List Group section of the admin and then on the next page click Add Test List Group and then fill out the fields:
- Name (required)
- Give the Test List Group a relevant name
- Test Lists (required)
- Select the Test Lists to include in this group.

Filling out the fields for a Test List group.
and finally click Save. This Test List Group can now be associated with Notifications.
A Part Category Groups is made up of one or more Part Categories and allows you to target Part notifications to specific Part Categories using Part Category Groups. To create a new Part Category Group click through the Part Category Group section of the admin and then on the next page click Add Part Category Group and then fill out the fields:
- Name (required)
- Give the Units Group a relevant name
- Part Categories (required)
- Select the Part Categories to include in this group.
and finally click Save. This Part Category Group can now be associated with Notifications.
QC Completed Notices¶
These notifications are triggered after a user submits a Test List. There are 4 subtypes of QC Completed Notices:
- Notify when Test List Completed: This type of notice is triggered any time a user submits a completed Test List.
- Notify on Test at Tolerance or Action: This type of notice is triggered when a user submits a Test List that has Test Instances which are at tolerance or action level.
- Notify on Test at Action level only: This is the same type of notice as Notify on Test at Tolerance or Action but is only sent for Test Instances which are outside of Action level.
- Follow up notification: This notification type allows you to have an email notice sent a certain number of days after a Test List is submitted.
To create a new QC Completed Notice click through the QC Completed Notices section of the Notification admin section and then on the next page click Add QC Completed Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Follow up days (Follow up notifiation Only):
- Set the number of days after a test list being completed that you want a follow up email sent.
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Unit Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
- Test List Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
Click Save once you have configured the notification the way you want.

Filling out the fields for a QC Completed notice.
QC Review Notices¶
There is currently only one subtype of QC Review Notice:
- Notify about test list instances awaiting review: This is a scheduled notification that can be sent to remind staff that there is completed QC awaiting review.
To create a new QC Review Notice click through the QC Review Notices section of the Notification admin section and then on the next page click Add QC Review Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Send Empty (required):
- Should this notice be sent even if there is no QC to currently notify about?
- Recurrences (required):
- Create a recurrence rule to define the days you want this notice sent.
- Time of day (required):
- Select the time of day you want the notice sent.
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Unit Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
- Test List Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
Click Save once you have configured the notification the way you want.

Filling out the fields for a QC Review notice to be sent at 9am Mon Wed Fri.
QC Scheduling Notices¶
These scheduled notices are available to help you keep on top of what QC is due and when. There are four sub types of notifications that can be configured:
- Notify about all Test Lists Due Dates This notification will send an email that contains all of the currently scheduled QC and when it is due.
- Notify about Test Lists currently Due & Overdue This notification will send a notice about Test Lists that are currently Due or Overdue.
- Notify About Test Lists Currently Due & Overdue, and Upcoming Due Dates This notification allows you to select a future time period (e.g. 7 days) and sends an email about which QC is currently Due, Overdue, or will become Due in that time period.
- Notify About Test Lists Upcoming Due Dates Only This notification allows you to select a future time period (e.g. 7 days) and sends an email about which QC will become Due in that time period.
To create a new QC Scheduling Notice click through the QC Scheduling Notices section of the Notification admin section and then on the next page click Add QC Scheduling Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Send Empty (required):
- Should this notice be sent even if there is no QC to currently notify about?
- Recurrences (required):
- Create a recurrence rule to define the days you want this notice sent.
- Time of day (required):
- Select the time of day you want the notice sent.
- Future Days:
- Select the number of days for which you want to include upcoming due dates for QC. For example, to get a notification containing QC coming due in the next week, set future days to 7.
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Unit Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
- Test List Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
Click Save once you have configured the notification the way you want.

Filling out the fields for a QC Scheduling notice to be sent on the first of the month.
Service Event Notices¶
Service Event notices allows users to be alerted when a service event is created or modified. There are currently seven Service Event Notification subtypes:
- Notify when a Service Event is created or modified Use these alerts to get an email whenever a Service Event is created or modified any way.
- Notify when a Service Event is created Use these alerts to get an email whenever a Service Event is created.
- Notify when a Service Event is modified in any way Use these alerts to get an email when a Service Event is modified in any way.
- Notify when a Service Event Status is changed Use these alerts to get an email when the Status of Service Event is modified.
- Notify when Return To Service QC is changed Use these alerts to get an email when Return to Service QC for a Service Event is added or changed.
- Notify when Return To Service QC is performed Use these alerts to get an email when Return to Service QC for a Service Event is performed.
- Notify when Return To Service QC is approved Use these alerts to get an email when Return to Service QC has its status updated to an approved status.
To create a new Service Event Notice click through the Service Event Notices section of the Notification admin section and then on the next page click Add Service Event Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Unit Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
Click Save once you have configured the notification the way you want.

Filling out the fields for a Service Event notice.
Service Event Scheduling Notices¶
These scheduled notices are available to help you keep on top of which Service Event Schedules are due and when. There are four sub types of notifications that can be configured:
- Notify About All Service Event Schedule Due Dates This notification will send an email that contains all of the currently scheduled service events and when they are due.
- Notify about Scheduled Service Events Currently Due & Overdue This notification will send a notice about scheduled service events that are currently Due or Overdue.
- Notify About Scheduled Service Events Currently Due & Overdue, and Upcoming Due Dates This notification allows you to select a future time period (e.g. 7 days) and sends an email about which scheduled service events are currently Due, Overdue, or will become Due in that time period.
- Notify About Scheduled Service Events Upcoming Due Dates Only This notification allows you to select a future time period (e.g. 7 days) and sends an email about which scheduled service events will become Due in that time period.
To create a new Service Event Scheduling Notice click through the Service Event Scheduling Notices section of the Notification admin section and then on the next page click Add Service Event Scheduling Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Send Empty (required):
- Should this notice be sent even if there is no QC to currently notify about?
- Recurrences (required):
- Create a recurrence rule to define the days you want this notice sent.
- Time of day (required):
- Select the time of day you want the notice sent.
- Future Days:
- Select the number of days for which you want to include upcoming due dates for QC. For example, to get a notification containing QC coming due in the next week, set future days to 7.
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Unit Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
Click Save once you have configured the notification the way you want.
Service Event Review Notices¶
Service Event Review notices allow users to be alerted when Service Events are awaiting review. There is currently one Service Event Review Notification subtypes:
- Notify about Service Events awaiting review This is a scheduled notification that can be sent to remind staff that there are Service Events awaiting review.
To create a new Service Event Review Notice click through the Service Event Review Notices section of the Notification admin section and then on the next page click Add Service Event Review Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Send Empty (required):
- Should this notice be sent even if there are no Service Events to currently notify about?
- Recurrences (required):
- Create a recurrence rule to define the days you want this notice sent.
- Time of day (required):
- Select the time of day you want the notice sent.
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Unit Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
Click Save once you have configured the notification the way you want.

Filling out the fields for a Service Event Review notice.
Part Notices¶
There is currently one Part notice type:
- Notify when inventory for a part falls below it’s Low Inventory threshold Use these alerts to get an email whenever the number of parts fall below its low inventory threshold.
To create a new Part Notice click through the Part Notices section of the Notification admin section and then on the next page click Add Part Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Part Category Group filter (optional):
- If you want this notification to only pertain to specific part categories, select a Part Category Group filter.
Click Save once you have configured the notification the way you want.
Fault Logged Notices¶
There is currently one Fault Logged notice type:
- Notify when fault logged Use these alerts to get an email whenever a user logs a fault.
To create a new Fault Logged Notice click through the Fault Logged Notices section of the Notification admin section and then on the next page click Add Fault Logged Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Unit Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
Click Save once you have configured the notification the way you want.
Fault Review Notices¶
There is currently only one subtype of Fault Review Notice:
- Notify about Faults awaiting review: This is a scheduled notification that can be sent to remind staff that there are currently logged Faults awaiting review.
To create a new Fault Review Notice click through the Fault Review Notices section of the Notification admin section and then on the next page click Add Fault Review Notice and then fill out the fields:
- Notification Type (required):
- Select the notification type you want to create
- Send Empty (required):
- Should this notice be sent even if there are no Faults to currently notify about?
- Recurrences (required):
- Create a recurrence rule to define the days you want this notice sent.
- Time of day (required):
- Select the time of day you want the notice sent.
- Recipients (required):
- Select the recipient group you want this notification sent to.
- Unit Group filter (optional):
- If you want this notification to only pertain to specific units, select a Unit Group filter.
Click Save once you have configured the notification the way you want.
Editing a Notification¶
In order to edit any notification, locate it in the admin section:

Find the notification you want to edit.
click through the link, make the changes you want and then click Save
Deleting a Notification¶
In order to delete any notification, locate it in the admin section (as shown above in Editing a Notification), click through the link, click Delete:

Notification delete button
and then click Yes, I’m Sure:

Notification delete confirmation button
Units¶
Creating A New Unit¶
Before you can create a new unit you have to define some treatment and imaging modalities and unit types. This can either be done beforehand or “inline” when defining a new unit. The former is described below.
Defining a treatment or imaging modality¶
Modalities can be used to define what beam energies, and treatment or imaging techniques are available on a unit. Examples of modalities might be “6X”, “6FFF”, “6E”, “9E”, “CBCT” and so on.
From the main administrators page click the Modalities link from the Units section.

Units admin section
This page lists all the existing (if any) modalities. To add a new modality click the Add modality button at the top right.

Add Modality
From here just enter the name of the modality type you want to define. The definition of a 6MV photon beam is illustrated below.

Defining a 6MV Photon Modality
Click Save when you are finished.
Defining a new unit class¶
From the main administrators page click the Unit classes link from the Units section and then on the next page click the Add unit class link in the top right hand corner.
Add the name of the unit class (e.g. Linac, Tomotherapy, Cyberknife, CT, MRI etc).

Defining a new unit class
Defining a new unit type¶
From the main administrators page click the Unit Types link from the Units section and then on the next page click the Add unit type link in the top right hand corner.
Fill in the Name, Vendor, and optionally Unit class*, **Model, and Collapse fields and click Save when you are finished.
Checking the Collapse option will hide units of this unit type by default on pages where you select units (e.g. the Choose Unit to Perform QC On page).

Defining a new unit type
Defining a Site¶
For clinics with multiple sites, or satellite clinics, you can define separate Sites to assign Units to.
From the main administrators page click the Sites link in the Units section and then click the Add Site button. Give your site a name (e.g. Main Site, Satellite Site) and click Save. Repeat for other Sites as required.

Defining new Sites
Defining a new unit¶
From the main administrators page click the Units link from the Units section and then on the next page click the Add unit link in the top right hand corner.
On the Add Unit page you will need to fill in all the relevant fields, some of which are described below:
- Number - A uniquely identifying integer number for this unit. The unit Number will effect the order that treatment units are displayed on certain pages.
- Acceptance Date - Date that the unit was approved for treatment
- Active - Uncheck this field when a unit is decomissioned. This will hide the unit from many parts of the user interface to reduce clutter and confusion
- Unit Type - Select the type of unit this is
- Is serviceable - Set to true to make this unit selectable in Service Events
- Site - If you have multiple sites configured, choose the site this unit is located at
- Modalities - Select any treatment and imaging modalities that are currently available on this machine. These are used in conjunction with the fault log functionality
- Service Areas - Select all the service areas available for this unit (e.g. Linac, kv Imaging, MV Imaging etc)
- Available Time on date of acceptance - The number of clinical hours that the unit is available on a day to day basis
- Unit Schedule - Set the number of hours this unit is available and the effective date. See below for an example
Example input for an Elekta Synergy unit is shown below.

Defining a new unit type
Example Unit Schedule showing a unit that is being restricted completely for a week (from June 24-30th) for service, after which it returns to it’s normal schedule on July 1st:

Defining a unit schedule
Tests and Other QC¶
Test Categories¶
It can be useful to separate tests into different categories. For example, if you have a Test List for morning QC on a machine that consists of both dosimetry and safety tests, and occasionally wish to perform only the dosimetry tests, having the tests in separate categories allows you to easily perform a subset of the tests from a test list.
New categories are straightforward to define: from the main admin page, click on the Categories link, then click Add category, fill out the fields and Save.

Creating a new test category
Frequencies & Scheduling¶
When a test list is assigned to a unit you give it a frequency or schedule with which it should be performed. This frequency determines when a test list is show as being due/overdue on a unit.
Frequencies can be configured from the main admin page by clicking on the Frequencis link in the QC section.
Prior to version 3.1.0, QATrack+ used an “offset” system for deciding whether a test list is not due, due or overdue. Anytime a test list was performed, its due date was set a certain number of days (the Due Interval) from todays date. While this method of scheduling is still possible, v3.1.0 introduced a more flexible scheduling system based on recurrence rules (RFC 5545) similar to what you would find in other calendar applications. Recurrence rules allow you to specify schedules like “Every Mon, Wed, Fri”, “The First Monday of Every Month”, or like in prior versions “28 days after today”.
Since, QC data is not always collected on the exact day it is scheduled, QATrack+ uses the concept of a “QC Window” where a QC Window is defined as some number of days before the due date of a test list (the Start Interval), up until the date when a test list should be marked as overdue (the End Interval). If a Test List is performed within its QC Window (or indeed after the QC Window expires) then the due date will be set forward until the next instance of the recurrence rule. If a Test List is performed prior to its QC Window, the due date will not be moved forward (this is the primary difference between the previous scheduling system). The following diagram may be helpful in understanding this system:

QC window scheduling model of QATrack+
Lets look at a couple of examples to demonstrate this system:
- A test list is scheduled with a recurrence rule of “The 1st of every month” with a Start Interval of 7 days and an End Interval also set to 7 days. The due date is currently set to Dec 1st. If the test list is performed any time before Nov 24th, the due date will stay as Dec 1st since the QC was performed prior to the QC window start.
- Same schedule as above, except the test list is now performed on Nov 27th, prior to the due date, but within the QC Window. In this case the due date will be set to Jan 1st since the QC was performed within the QC window.
- Same schedule as above but the unit has an extended down time and the test list is not performed until Jan 10th over a month after its due date. In this case, since the test list is past due, its due date will be set to the next occuring instance of the recurrance rule, Feb 1st.
- A test list is scheduled with a recurrence rule of “Every 28 days” with a null Start Interval and an End Interval of 7 days. The due date is currently set to Dec 1st. A user performs the test list on Nov 14th. In this case, since no Start Interval is defined, the due date will be set forward 28 days to to Dec 12th. This is analogous to the offset system used in versions prior to v3.1.0.
If a Test List has not reached its next due date, the due date will be shown in green.

Test list that is not yet due
When a test list reaches its due date it will be shown in yellow.

Test list that is now due
Finally if a test list has not been completed within the QC window (window_end days after the due date) it will be shown in red.

Test list that is now over due
Hovering over any due date will show the test lists current QC window:

Hovering over a due date status to reveal the QC window
A weekly every Wednesday frequency, which also demonstrates the viewing of the recurrence rules on a calendar.

Every Wednesday frequency configuration
A “classic” daily frequency that sets the due date to tomorrow, no matter what day it is performed on:

Daily frequency configuration
A frequency for tests that must be performed at least once a week (Mon - Fri). Nominal due date is set to Wed with a window of 2 days on either side. :

Once a week frequency configuration
A frequency for tests that must be performed the first Monday of every other month.

First monday of every other month configuration
Test Statuses¶
Every test instance that is created has a status assigned to it (and hence there must be at least one status defined before doing QC).
These statuses allow you to flag tests for review, indicate whether a test result is valid or not and whether or not a test result should be included in charts by default.
An example status definition is shown here with the various fields explained below.

Status overview
- The status Name is what will be displayed on pages where this status is used, the Slug is a url safe version of the name and the Description should be a brief description of when a test should be given this status.
- If Is default is checked for a status then all new test instances created when a user performs a test list will be given this status unless explicitly overridden by the user.
- If a test instance has a status with Requires review checked its parent test list instance will appear in the **Unreviewed** queue.
- Export by default indicates whether test instances with this status should be included by default in data plots. In the figure below the Rejected status does not have Export by default checked and therefore must be specifically checked off if they want to include Rejected data in the plots.

Export by default statuses
- Valid indicates whether tests with this status are “good” data or not (i.e. if the test was carried out correctly).
Tests¶
To access existing tests or to configure a new test, click on the Tests link in the QC section on the the main admin page.
Create a new test by clicking the Add Test link in the top right hand page of the Tests admin page. The individual fields for configuring a tests are described below.
A unique name that describes what the test is (e.g. something like Temperature (deg C) or 0 deg Gantry - Field Size 10.0x10.0cm - X1 (cm)).
Text describing how a test should be displayed when performing or reviewing. Having a separate name & display name allows you to create tests with descriptive names that are easy to find in the admin, but use a more succinct name when performing a Test List. If left blank, the test name will be used.
Macro name tl;dr: give your test a short variable name like ion_chamber_reading or temperature.
Every test must be given a macro name which will be used to refer to this test in composite tests. The macro name must be a [valid Python variable name](http://en.wikibooks.org/wiki/Think_Python/Variables,_expressions_and_statements#Variable_names_and_keywords) (that is it must consist of only letters a-z, letters A-Z, numbers and underscores) and must not be one of the following reserved words:
False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield
Python programmers generally use lower case only variable names with words separated by underscores (_). That is to say a macro name like ion_chamber_reading is preferable to ionChamberReading, IonChamberReading, or Ion_Chamber_Reading. Note that this is by convention only and you are free to choose whichever names you like.
It is also highly advised that you use use a descriptive name like ion_chamber_reading instead of something like icr. That way when other people are reading your code it is obvious what your variable represents.
The description field is the text that is shown when a user clicks on the test name while performing QC. This description can be made up of plain text or html. An example showing an html description is shown below along with the way it looks when displayed on the test list page.

Test description definition

Test description display
The procedure allows you to insert a URL to a more detailed procedure available elsewhere. A link to that URL will be shown when the user clicks on the test name while performing QC as shown below.

Detailed procedure link
Choose the Test Category that this test belongs to.
QATrack+ currently supports 11 different test types as outlined below.
Simple Numerical A test with a single numerical result (e.g. Temperature)
Wraparound A test that accepts values in a predefined range (Wrap low to Wrap high) and has values that “wrap” from the high to low value and vice versa. This type of test is useful for example if you have a collimator/gantry readout test and want to consider 359.9 deg a 0.1 deg difference from a 0 deg reference.
Only absolute tolerances with reference values between Wrap low and Wrap high are supported.
Boolean A test with a Yes or No answer (e.g. Door Interlock Functional)
Constant A non-user editablenumerical constant to be used in composite tests (e.g. an N_DW calibration factor). When you choose Constant for the Type field a Constant Value text box will appear for you to enter your numerical constant in.
Multiple Choice A test where the user selects from a predefined list of choices. When you choose Multiple Choice for the Type field, a Choices text box will appear where you must enter a comma separated list of choices for the test.
Composite A value calculated based on other test values (e.g. a temperature pressure correction, or a calculated dose). Composite tests are easy to define but allow users to do define complex calculations with the Python programming language. Please see the Composite Test section for more information on defining this type of test.
String Allows the user to enter a short piece of text (e.g. a user ID)
String Composite/JSON A Composite test that stores a string (text) rather than a numerical value. You may also use this type of field to store a JSON data structure. Please see the Composite Test section for more information on defining this type of test.
Date Allows the user to use a date picker to select a calendar date. Test values will be coerced to Python datetime.date objects in compsite calculations contexts.
Date & Time Allow the user to use a date picker to select a calendar date and time Test values will be coerced to Python datetime.datetime objects in compsite calculations contexts.
Upload A test that allows you to upload an arbitrary file and process it with a Python snippet. Please see the Composite Test section for more information on defining this type of test.
Field to enter a comma separated list of your test choices.
Field to enter the value your constant test.
Check this option if you want an image uploaded to QATrack+ to be displayed on the test list page (supported images depend on browser version but generally jpg, png & gif work well).
Uncheck this option to hide the test from the charting page. This can help keep your charting page clean and limited to the tests you really care about.
Indicate whether this test should be auto-reviewable. Select the AutoReviewRuleSet you would like to use for this, or leave blank, to disable Auto Review for this test. For more information about this option see the Auto Review page.
Check this option if you want users to be able to skip this test without being forced to add a comment (regardless of their commenting permissions).
Check this option if you want users to be forced to enter a comment when submitting this test.
This field is used for calculating either test results (for composite, string composite, & file upload test types) or default initial (user overrideable) values for other test types (simple numerical, string, date/time, multiple choice).
Python style string format for displaying numerical results. Leave blank for the QATrack+ default, select one of the predefined options, or enter your own formatting string. Use e.g. %.2F to display as fixed precision with 2 decimal places, or %.3E to show as scientific format with 3 significant figures, or %.4G to use ‘general’ formatting with up to 4 significant figures. (Note this does not affect the way other values are calculated, only the way composite and constant test values are displayed. For example a constant test with a value of 1.2345 and a format of %.1f will be displayed as 1.2, but the full 1.2345 will be used for calculations). Note you may also use “new style” Python string formatting: see https://pyformat.info/ for examples.
To set a default value for numerical formatting see the DEFAULT_NUMBER_FORMAT setting.
You can attach arbitrary documents to your test which will be presented to the user for viewing when performing tests lists.
There are currently three test types that allow you to calculate test results using snippets of Python code. These tests include Composite, String Composite/JSON & Upload.
Composite tests allow you to do calculations to produce a numerical test result based on other test values ( e.g. to calculate a dose based on a raw electrometer reading and temperature & pressure ). When you select Composite for the test Type field, a Calculation Procedure box will be displayed.
In this box you must enter a snippet of Python code where you must set the value of this tests macro name. Two examples are shown below, first, a one liner to calculate a temperature-pressure correction factor:
Note that in QATrack+ versions prior to 0.2.7 the last line of code had to be a line that set a``result`` variable to the final calculated result. This is no longer the recommended way to use composite tests although it is still supported for backwards compatability.

Temperature Pressure Correction Calculation
and second a slightly more complicated multi-line snippet that collects a group of readings and calculates the average value of them.

Average Reading Procedure
Note that in both the previous examples the snippets depend on the
values of other tests. In the first, temp_solid_water
,
raw_pressure
and temp_corr
are the macro names corresponding
to Temperature, Pressure and Pressure Correction tests. Likewise
in the second snippet, the average reading result depends on ten other
tests (Readings 1 through 10 with macro names r1, r2...r10
).
While the previous two examples are fairly simple, all the control structures of the Python programming language are available including loops, if-else statements, list comprehensions etc.
When your script (calculation procedure) is executed, it has access to
the current value of all the tests in the current test list being performed
A number of Python modules including the Python math module, along with NumPy, SciPy, matplotlib and, pydicom.
Note: Other Python modules can be imported the same as any other Python script
REFS & TOLS variables which are dictionaries of reference and tolerance values for all of the tests.
- REFS is a dictionary of form {macro_name: ref_value’} e.g.
REFS = { 'mytest': 100, 'someothertest': 1.234, }
- TOLS is a dictionary of form {macro_name: tolerances} where tolerances itself is a dictionary of form:
{ 'act_low': act_low_val, 'tol_low': tol_low_val, 'tol_high': tol_high_val, 'act_high': act_high_val, 'mc_pass_choices': passing_vals, 'mc_tol_choices': tolerance_vals, 'type': tolerance_type }
e.g.
TOLS = { 'mytest': { 'type': "absolute" # or 'act_low': -3, 'tol_low': -2, 'tol_high': 2, 'act_high': 3, }, 'someothertest': { 'type': "multchoice" # or 'mc_pass_choices': "pass_val_1,pass_val_2", 'mc_tol_choices': "tol_val_1,tol_val_2", }, }
A META object which is a dictionary of some potentially useful information about the test list currently being performed including:
- test_list_id - ID of current test list
- test_list_name - Name of current test list
- unit_test_collection_id - ID of current Unit Test Collection (Unit Test List/Cycle Assignment)
- unit_number - Unit number
- cycle_day - Current cycle day being performed (Always 1 for non-cycle test lists)
- work_completed - Python datetime object with current work_completed value
- work_started - Python datetime object with current work_started value
- username - Username of person performing test
A UTILS object which is a collection of utility methods currently consisting of:
UTILS.get_comment( macro_name ) gets the user set comment for the input
UTILS.set_comment( “your comment here” ) sets the comment for the current test
UTILS.set_skip( macro_name , True|False ) set skip status of a test. Please note that if a user alters the skip state of the same test before the composite calculation is complete, their selection will be overridden by the results of the composite test.
UTILS.get_skip( macro_name ) returns boolean indicating whether or not a given test is currently skipped.
UTILS.write_file(file_name, object) attaches a file to the current test (see below for an example). If you have Display Image checked for this test, and the object you pass to write file is “image like” (matplotlib axis, matplotlib figure, numpy array etc) then the object will be saved as an image file and displayed to the user.
UTILS.previous_test_list_instance(include_in_progress=False) retrieves the most recent Test List Instance for the Test List currently being performed on this Unit. If include_in_progress=True than Test List Instances which are marked as In Progress will be included, otherwise they will be excluded. If no previous Test Instance is found, None will be returned.
UTILS.previous_test_instance(test, same_list_only=True, include_in_progress=False, exclude_skipped=True) retrieves the most recent Test Instance performed on this unit for the input test. If same_list_only=True then only Test Instances’s which were created as part of the current Test List being performed will be included, otherwise, any Test Instance for this Test & Unit will be returned. If include_in_progress=True than Test List Instances which are marked as In Progress will be included, otherwise they will be excluded. If exclude_skipped=False, then skipped results will be included, otherwise only non-skipped results will be searched. If no previous Test Instance is found, None will be returned.
UTILS.get_figure() will get you a matplotlib Figure instance suitable for creating and displaying plots e.g.:
fig = UTILS.get_figure() axes = fig.gca() axes.plot(range(10), range(10)) UTILS.write_file("line.png", fig)
The snippet below shows a composite calculation which takes advantage of the SciPy stats library to perform a linear regression and return the intercept as the result.

Example procedure using Scipy
NumPy and SciPy provide access to a huge number of robust and fast mathematical functions and it is highly recommended you look through their documentation to see what is available.
An example calculation procedure using the META variable:
unit_number = META["unit_number"]
user = META["username"]
if user == 'bob' and unit_number == 42:
do_something()
An example calculation using the REFS variable:
diff = 100*(my_test_name - REFS["my_test_name"])/REFS["my_test_name"]
An example calculation using the TOLS variable:
if diff > TOLS["my_test_macro"]["act_high"]:
some_other_value = 1
else:
some_other_value = 2
An example setting the comment for the current test:
foo = 1234*678
comment = "The value is %s" % foo
UTILS.set_comment(comment)
An example showing how to use write_file to create a matplotlib plot:
import matplotlib.pyplot as plt
xs = range(10)
ys = range(10)
plt.plot(xs, ys)
figure = plt.gcf()
UTILS.write_file("a_line.png", figure)
An example showing how to use get_last_test_instance to calculate the percent change in a test value since the last time it was performed:
last_ti = UTILS.previous_test_instance("some_test")
if last_ti is None:
diff = 0
else:
diff = 100*(some_test - last_ti.value) / last_ti.value
QATrack+ has a primitive dependency resolution system and it is therefore safe to create composite values that depend on other composite values as they will be calculated in the correct order.
Since v0.3.0, QATrack+ uses Python 3.4+ which no longer uses integer division by default. The calculationn a = 1/2 will result in a = 0.5 rather than a = 0 like in Python 2.x. If you need integer division, make sure you use the // operator like a = 1//2 # a == 0.
The String Composite test type are the same as the Composite test type described above with the exception that the calculated value should be a string rather than a number. An example Composite String test is shown below.
As of v3.1.0 you may now also return a JSON serializable Python dictionary. This allows you to e.g. pre-calculate values for other composite tests, or store more complex datatypes in the database.

Example String Composite procedure
Upload test types allow the user to attach arbitrary files (text, images, spreadsheets etc) which can then be analyzed with a Python snippet similar to the composite tests above.
If the file you uploaded is a binary file type (image, dicom etc) then you can access the uploaded file object (more information on file objects is available in the Python documentation) using the BIN_FILE context variable. Likewise, if you upload a file with a text format you can access the file object through the FILE context variable.
The upload test calculation procedure can return any JSON serializable object (number, string, list, dict etc) and then (optionally) other composite tests can make use of the returned results. An example of this is given below.
Imagine we have a text file with the following contents:
01/01/2013, 25.1
01/02/2013, 23.2
01/03/2013, 25.2
01/04/2013, 24.0
01/05/2013, 24.0
01/06/2013, 25.5
Where the first column is some dates and the second column is temperature. For our test list we want to upload this file and calculate and save the average (Average Temperature) , max (Maximum Temperature) and min temperatures (Minimum Temperature).
First we define our upload test and procedure for analyzing the file. We
will call our Upload test Temperatures
and give it a macro name of
temp_stats
.
The calculation procedure we will use is:
temperatures = []
for line in FILE:
line = line.strip()
if line.find(',')>=0: # ignore any line without temperature data
date, temp = line.split(',') # split up the line into date and temperature columns
temp = float(temp.strip()) # strip whitespace and convert to float
temperatures.append(temp) # add temp to our list
# set our macro_name to a dictionary containing the values
# we are interested in
temp_stats = {
"max": max(temperatures),
"min": min(temperatures),
"avg": sum(temperatures)/len(temperatures),
}

Example upload test type
We can then define three composite tests to store our calculated
results. The calculation procedure required for Average Temp is simply
avg_temp = temp_stats['avg']
and the complete test definition is
shown below:

Average temperature test
An example test list made of these 4 tests is shown below as it is being performed:

Example upload test in action
Here’s how you would write a procedure to access some data from an uploaded DICOM file:
import pydicom
f = pydicom.read_file(BIN_FILE)
mean_value = f.pixel_array.mean()
Warning
Defaults are currently only applied for Test Lists performed via the web user interface and not through the API.
Similar to calculated tests, as of version 3.1.0, you can now use the calculation procedure field to set an initial default value for a test that can be overridden by the user.
For example, to set an initial value for a Simple Numerical test you could use a simple calculation procedure like:
your_simple_test = 22
To set an initial value for a Multiple Choice test with choices “A,B,C” you could use a simple calculation procedure like:
your_mult_choice_test = "B"
To set an initial value for a Boolean (Yes/No) test you would use:
your_bool_test = True # or False
To set an initial value for a String test you would use:
your_string_test = "Some string"
To set an initial value for a Date test you could use something like this:
from django.utils import timezone
your_date_test = timezone.now().date() # or some other datetime.date instance
To set an initial value for a Datetime test you could use someting like this:
from django.utils import timezone
your_date_test = timezone.now() # or some other datetime.datetime instance
Configuring Test Lists¶
To edit existing test lists or create new test lists click on the Test Lists in the QC section on the main admin page.
Create a new test list by clicking the Add Test List link on the Test Lists admin page. The fields for defining a new test list are described below.
A descriptive name that will be displayed in listings of test-lists.
A slug is a URL friendly short label for a test list. It should consist of only letters, numbers, underscores and hyphens.
Use this field to define the message shown when a test within this test is at Action level. If the message is left blank, a warning message will not be shown for out of tolerance tests.
You can enter arbitrary Javascript snippets here, and they will be injected into the page when performing the test list.

Javascript Injection
Test lists comprise Tests and/or other Test Lists, called Sublists. In order to add a test to your test list, click the magnifying glass beside the first text box under the Test header.

Search for a test
This will bring up a dialogue box that you can use to search for the test you want to add (or create a new one).

Search results
Once you’ve found the test you want to add, clicking on its name will close the dialogue box and add the test to your test list.

Test added to list
Likewise, you can select another Test List to include by using the Sublist entry field:

Adding a Sublist to a Test List
If you need to add more Tests or Sublists, then click the Add another Test List Membership or Add another Sublist links.
You can choose to have Sublists distinguished visually by checking the corresponding Show Outline Around Sublist checkbox.
If you now click the Save and continue editing button at the bottom of the page, you will see the name of your test next to its id number.

Test added and saved
Continue to add tests in this fashion (you can add many tests without saving in between) until you have added all the required tests.
When you are finished click Save and continue editing and confirm that all your tests are present. See the section below for instructions on how to reorder the tests if required.
Tests and Sublist’s can easily be reordered by dragging and dropping a tests row into a new position in the list. After you have finished reordering click Save and continue editing and ensure all your tests are now in the correct order.

Reorder Tests & Sublists
You can add arbitrary attachments to a Test List (e.g. a PDF procedure for performing the Test List) by uploading them using the Attachments section at the bottom of the Test List configuration page.

Adding attachments to Test Lists
Configuring Test List Cycles¶
A test list cycle allows you to group multiple Test Lists into a single repeating cycle that can be assigned to a unit.
For example, at our clinic, on a number of units, the therapists daily QC is on a repeating 2 or 4 day cycle where the actual tests they perform vary slightly by day. A test list cycle allows us to handle this situation without the therapists having to keep track of which day was done last.
For a 4 day cycle, you would create 4 separate test lists (e.g. Morning Outputs Day 1, Morning Outputs Day 2, Morning Outputs Day 3, Morning Outputs Day 4) and then create a Test List Cycle made up of those 4 Test Lists. You would then assign that Test List Cycle to the unit with a daily frequency, rather than assigning each of the 4 test lists individually.
When a user performs a Test List Cycle, it checks which test list in the cycle was performed last and automatically presents them with the tests in the next days test list. So if Day 2 was performed yesterday, they will be presented with the Day 3 tests today. You can also manually override which day you want to perform.
Defining a test list cycle is described below.
From the main admin page select the Test list cycles page and click the Add test list cycle button in the top right corner of the page. The fields for defining a test list cycle are described below.
A descriptive name that will be displayed in listings of test-lists.
A slug is a URL friendly short label for a test list. It should consist of only letters, numbers, underscores and hyphens.
Set the text of the label of the drop down input used for choosing a one of the test list members of this cycle. The default is “Choose Day”.
Choose whether to use the test list day number (i.e. Day 1, Day 2, …) or the test list name for display in the dropdown used for chossing one of the test list members.
To add a test list to your cycle click the magnifying glass beside the first text box uder the Test list cycle memberships section. (Note prior to version 0.2.6 you first need to click the Add another Test List Cycle Membership link to create a new row in the Test list cycle memberships list.)

Search for test list
This will bring up a dialogue box where you can search or navigate to the test list that you want to add to your cycle.

Test List Cycle Search Results
Clicking on the name of the test list you want to add will close the dialogue and add the test list to your cycle. Repeat these steps until you have added all the required test lists to your cycle.

Test List Cycle ID’s
Once you have added all your test lists, click the Save and continue editing button and confirm all your test lists are present and in the correct order.

Test List Cycle after save
If you need to reorder the test lists you can do so by dragging and dropping the test list rows into a different order and then saving the changes.
To remove a test list from a cycle, click the checkbox under the Delete column of the Test list cycle memberships listing and then save the cycle.

Removing a test list from a cycle
You can add arbitrary attachments to a Test List Cycle (e.g. a PDF procedure for performing the Test Lists which make up the Cycle) by uploading them using the Attachments section at the bottom of the Test List Cycle configuration page.
Assigning A Test List Or Test List Cycle To A Unit¶
Once you have created a Unit and a Test List (or Test List Cycle) you need to create an association between the two before the test list can actually be performed. To do this click on the Assign Test Lists to Units link from the main admin page and then click Add unit test collection button in the top right hand corner.
The fields required for assigning a test list to a unit are described below.
The unit you want to assign the test list to.
The Frequency with which you want the test list (cycle) to be performed (e.g. Daily, Monthly, Yearly etc).
Optionally, you can leave the frequency blank and the test list will be assigned to be performed on an ad-hoc basis.
Here you can manually set the initial due date/time for a test list on a unit. You can also leave this blank if you like and the test list will show up as being Not Due.
If you leave Auto Schedule checked, the due date will automatically be updated according to the assigned frequency after the test list is completed on a unit.
The group of users that is generally responsible for performing the lists. Note that the Assigned To property is used for display only and users not part of the Assigned To group will still be able to see and perform the test list.
Choose the groups you want this test list on this unit to be visible to by moving the groups from the Available visible to to the Chosen visible to box.
If this checkbox is unchecked, the test list will not appear in any listings on the main site. This should be used to disable test lists that are no longer performed on a unit (deleting the unit test collection would cause a loss of historical data).
Choose whether you are assigning a Test List or a Test List Cycle <qa_test_list_cycles> to this unit. After choosing the type of test collection you are adding, the Object id dropdown will be populated with the appropriate items.
Choose the test collection (test list or test list cycle) that you want to assign to this unit.
The below screen shot shows a test list being assigned to a unit on a daily basis.

Assigning a test list to a unit
And this is the way it would look in a listing on the main site:

Test list assigned to a unit on main site
Test Tolerances¶
Test tolerances (along with Reference values are used to determine whether a test is passing, at tolerance or failing. Configuring the different kinds of tolerance values are described below while the procedure for setting reference and tolerance values for a given test on a unit is described elsewhere.
To create a new tolerance click the Tolerances link under the QC section on the main admin page and then click the Add tolerance button at the top right hand corner. Choose the Tolerance type you want to create and fill in the appropriate values (described below).
Danger
A tolerance object should very rarely need to be edited and should only be done if you understand the implications of doing so.
When test values are stored, it keeps a reference to the tolerance that was set at the time the test was performed. If this tolerance object is later edited it will appear that the tolerance level for those test instances was different than it actually was at the time the test was performed.
The tolerance/action levels of a test act as a window around the reference value. For example if a certain test on a unit has reference value of 50 and a tolerance/action level of +/- 2%/3% (i.e. lower action = -3%, lower tolerance = -2%, upper tolerance = 2%, upper action = 3%) then values between 49 and 51 will be considered within tolerance, values between 48.5 & 49 or 51 & 51.5 will be considered at tolerance and values less than 48.5 or greater than 51.5 will be considered failing.

Note that you are free to leave one or more of the tolerance and action levels empty. This allows you to create tolerances which are pass/fail only (Tol Low & Tol High are both left blank), pass/tolerance only (Act Low & Act High are both left blank) or one sided tolerances (e.g. Act Low & Tol Low are left blank).
Numerical tolerances can either be specified as absolute
or
percentage
. An example of a percentage based tolerance is given in
the previous paragraph. Absolute tolerances differ from percentage
tolerances only in the way the window around the reference value is
calculated. For example if a certain test on a unit has reference value
of 80 and an absolute tolerance/action level of +/- 1/2 (i.e. lower
action = -2, lower tolerance = -1, upper tolerance = 1, upper action =
2) then values between 79 and 81 will be considered within tolerance,
values between 78 & 79 or 81 & 82 will be considered at tolerance and
values less than 78 or greater than 82 will be considered failing.


Multiple choice, String, & String Composite tests can be subjected to pass/tolerance/fail criteria by using the Multiple Choice tolerance type. First choose the Multiple Choice option for the Type field and then enter a comma separated list of choices which are to be considered passing and a comma separated list of choices which are to be considered tolerance values.
For example if your multiple choice test had choices like below:

and you wanted Choice A
to be passing, Choice B
to be failing
and Choice C
to be failing then you would set up your tolerance like
the following:

if you wanted Choice A
and Choice B
to be passing and
Choice C
to be failing then you would set up your tolerance like the
following (leaving the tolerance values field blank):

Setting Reference & Tolerance Values¶
When you assign a test list to a unit each of the tests from that list are assigned a record of the reference value and tolerance/action levels on that unit. Reference values and tolerance/action levels are unit specific so you must set these values for every unit a test is assigned to. Initially the reference value and tolerance/action levels are set to null so you will need to update them if you want to subject your tests to pass/fail criteria when performing a test list.
To set the reference and tolerance values click on the Set References and Tolerances link from the main admin page. From here you will see a list of all the test/unit pairs for any test list which has been assigned to a unit. To set the reference value for a given test on a unit you can either browse through the list or use the search box at the top of the page to find the test you are looking for. Note, you may also use the filters at the side of the page to narrow your search. The image below shows a search for a test which has been assigned to two units.

Searching for a test on a unit
Once you have located the test/unit pair you want to set the reference for, click on its name. From here you will see information about the current reference value and tolerance/action levels including when these values were last changed and who changed them.

Reference and tolerance example
If the test you are setting reference values for is numerical (e.g. simple numerical or composite test types) you can choose a tolerance/action level from the Tolerances: drop down and set the reference value in the text box below that.
The tolerance/action levels of a test act as a window around the reference value. For example if a certain test on a unit has reference value of 50 and a tolerance/action level of +/- 2%/3% (i.e. lower action = -3%, lower tolerance = -2 %, upper tolerance = 2%, upper action = 3%) then values between 49 and 51 will be considered within tolerance, values between 48.5 & 49 or 51 & 51.5 will be considered at tolerance and values less than 48.5 or greater than 51.5 will be considered failing.
For boolean tests you choose whether the reference value is Yes or No and whether a mismatch between the reference value and the users selection should result in a warning or a failure.

Reference and tolerance example for boolean test
Multiple choice tests have no reference value. For information about multiple choice tolerances, please see the tolerances page.
As of version 0.3.0 users may add a comment when updating references and tolerances and this comment will be shown with the history of changes for the reference and tolerance.

Reference and tolerance history
Setting multiple References & Tolerances at the same time¶
To set a group of tests to the same reference/tolerance value, go to the
Set References & Tolerances
page and select all the tests you want
to set:

Setting multiple references & Tolerance
then select Set multiple references and tolerances
from the
Actions
dropdown list at the top and click Go
.
On the next page set the desired reference & tolerance value then click
Set tolerances and references
.

Setting multiple references & Tolerance
Copying References & Tolerances between units¶
It is possible to copy references and tolerances from one unit to another. This is quite handy when you have the same test list assigned to multiple units with the same reference values set.
From the main admin page click on the Copy References & Tolerances
link in the QC section.

Copy ref tols link
On the next page, choose the source unit and test list (cycle) and the
destination unit and click Copy references and tolerances
.

Copy ref tols select
Finally, you will be asked to review and confirm before the new references are set.

Copy ref tols confirm
Adding Contacts¶
When performing a test list, in the left hand sidebar menu there is a contact numbers button that can be used to toggle a list of useful phone numbers in case the person performing QC needs assistance. At The Ottawa Hospital Clinic this feature would often be used by Therapists to call a Physicist for assistance.
To create a new contact number click on the Contacts link on the main admin page and then Add contact at the top right hand corner.
On the next page fill out the display name, phone number and a short description of what this number is used for. The description will be displayed when a users hovers the mouse over the number when performing QC.
Here are three defined contact numbers in the admin:

Contact numbers in the admin
and the way they look on the main site:

Contact numbers displayed on site
Auto Review¶
To configure Auto Review rules visit the Admin section of your QATrack+
site and select the Auto review rules
link under the QC section.
Auto review rules allow you to automatically assign a Test Status based on whether the test is passing, at tolerance or failing (action). This can be useful if you only want to require review for tests that are at tolerance or action.
For example, you may wish to set up an Auto Review rule to automatically assign passing tests (OK) to an Approved status.

Auto review rule
In order for a test to be Auto Reviewed, it must have an “Auto Review Rules Set” option selected.
Auto Review Rule Sets¶
Auto Review Rule Sets allow you to apply different sets of Auto Review Rules to different tests.
In the figure below two Auto Review Rule Sets are shown, a default rule set that will set skipped tests to Unreviewed, and a second rule set that will set skipped tests to “Approved”.

Auto review rule sets
To choose an Auto Review Rule Set for a Test, use the “Auto Review Rules” field on the Test configuration page:

Auto review rule set selection for a test
Email notifications¶
QATrack+ can be configured so that when a test list is performed and has tests which are at tolerance or failing an email can be sent to specific groups. This requires that your website administrator has configured the email settings correctly.

To create a new notification, choose the Notification subscriptions option under the Notifications section on the main admin page and then click on Add notification subscription in the top right hand corner of the page.
Choose the group who you want to receive emails and choose whether the emails should be sent only when tests are failing or both when tests are at tolerance or failing. Click Save when you are finished.

Creating a new notification
Configuring Auto-Schedule for all currently assigned test lists¶
As of version 0.2.6 of QATrack+ there is a Django management command
auto_schedule
that allows you to enable or disable auto-scheduling for all test lists currently assigned to a unit. It will
also allow you to update the due dates for all tests lists assigned to a unit
based on their last performed date and assigned frequency. This is usually not
necessary but might be useful if you have manually overriden many due dates and
want to “reset” all of them.
All of these commands must be run from the git bash shell from the root of your QATrack+ directory (with your virtualenv activated).
The following command will disable the ``auto_schedule`` flag for all test list assignments:
#! bash
python manage.py auto_schedule disable-all
The following command will enable the ``auto_schedule`` flag for all test list assignments:
#! bash
python manage.py auto_schedule enable-all
The following command will update the scheduled due date for all test list assignments based on the date they were last completed and their assigned frequency:
#! bash
python manage.py auto_schedule schedule-all
The following command will “unset” the due date for all test list assignments (i.e. they will all show as Not Due):
#! bash
python manage.py auto_schedule unschedule-all
Test Packs (Experimental feature)¶
In order to facilitate the sharing of test lists between different QATrack+ installations (e.g. to allow separate clinics to share test list configurations) QATrack+ allows users to export/import “Test Packs” which include complete definitions of Tests, TestLists, and/or TestListCycles.
Note
This is currently an experimental feature and will be expanded and improved in future versions of QATrack+. A site for publicly sharing test pack configurations is planned so that centres around the world can share some or all of their test configurations.
In order to export a test pack, go to the main admin site and click on Export Test Pack (or visit /qa/admin/export_testpack/ directly).
On the next screen, you can select all of the TestLists, TestListCycles, and extra Tests that you want to include in your TestPack. Note, selecting a TestList will automatically include all the relevant Tests and SubLists required for the TestList.

After you have selected the items you want to include, enter a name (the name must consist only of letters, numbers, underscores and hyphens) and brief description on the right hand side of the page and click Download.

You can now share this TestPack file with colleagues and they can import the test configuration to their own system.
If you have a Test Pack file you want to import, go to the main admin site and click on Import Test Pack (or visit /qa/admin/import_testpack/ directly).
On the next screen, click the “Choose File…” button on the right hand side of the page and select your Test Pack file. Use the tables to select the Test Lists, Test List Cycles, or individual tests you want to import and then click the Import button on the right.

Note if there is a naming conflict between an existing test name (or test list/test list cycle slug), and a test being imported, QATrack+ will append a numeral to the name so that existings tests (test lists/test list cylces) will not be overwritten.
Initial Configuration¶
Before you start defining tests and test lists for the first time it is a good idea to begin by doing some initial configuration.
After that is complete, you can move on to:
- Add Tests
- Add Test Lists
- Add Test List Cycles (optional)
- Assign Test Lists to Units
- Set Test References and Tolerances
A step-by-step tutorial to walk you through the process of configuring a new test list and assigning it to a unit available on our Tutorials Page.
Admin Tutorials¶
For a list of tutorials avaialable please visit our Tutorials Page.
The Service Log and Parts apps are used for tracking service events, machine downtime, and spare parts inventory. Details on configuring the Service Log & Parts apps are linked below, and for instructions on how to use the Service Log app, see the Service Log User Guide.
Service Log & Parts¶
Group Linkers¶
When creating or editing a new Service Event users have the opportunity to list who is involved in the Service Event. This is accomplished via Group Linkers.
For example, if therapists perform morning QC in your clinic and runs into an issue where a Service Event is initiated, you may want to create Group linkers for Therapist who reported issue and Physicist reported to. Then when initiating a Service Event the user would be presented with dropdowns to choose users from the Therapy & Physics groups who are involved:

Group linkers showing during service event initiation
To add Group Linkers go to the Admin section and click the Group linkers link in the Service Log section and then click the Add Group Linker button. Fill in the required fields and then click Save to create your Group Linker. Configurations for the two Group Linkers discussed above are shown below:

Physics group linker configuration

Therapist group linker configuration
Service Areas¶
Service Areas can be considered sub-systems within a single treatment “system” made up of e.g. linac, treatment couch, lasers, TPS etc. You will be required to select a Service Area when initiating a new Service Event.
To create Service Areas go to the Admin section and click the Service Areas link in the Service Log section and then click the Add Service Area button. Fill in the Name field and then click Save.

Defining a new Service Area
Repeat to create as many Service Area’s as you think you will need (you can always create more at a later date!).
Once you have some Service Area’s defined, you need to associate Units with their related Service Areas. There are two possible ways to accomplish this.
You can visit the Admin page for a given Unit and select the related Service Areas:
Adding Service Areas via the Unit admin
You can use the Unit Service Area Memberships area of the admin (in the Service Log admin section) to create associations between Units and Service Areas. This method allows you to add notes about the Service Area association:
Adding Service Areas via the Unit Service Area Membership admin
Service Event Statuses¶
Similar to Test Instance Status’s, Service Events have a status associated with them. These Service Event Status help manage the flow of a Service Event from initiation to completion.
To create Service Event Statuses go to the Admin section and click the Service Event Statuses link in the Service Log section and then click the Add Service Event Status button. Fill in the fields as follows:
- Name A short descriptive name for the status
- Is default Check off whether this should be considered the default Service Event Status when initiating a Service Event.
- Is review required Do service events with this status require review?
- RTS qa review required Service events with Return To Service (RTS) QC that has not been reviewed can not have this status selected if set to true. For example, you may have an Approved Service Event Status that requires one or more Test Lists to be performed and approved before the Service Event can have its status set to Approved.
- Description A description of this status
- Color Service Event Statuses can have different colours associated with them.
- Order You may set an explit order for each Service Event Status. When the user selects a status from a dropdown menu in the UI, the statuses will be displayed according to their order.
By default the following Service Event Statuses are configured:
Status Name | Is Review Required | Is Default | RTS QC Must be reviewed |
---|---|---|---|
Service Pending | Yes | No | No |
Service In Progress | Yes | Yes | No |
Service Complete | Yes | No | No |
Approved | No | No | Yes |
Test Data | No | No | No |
Rejected | No | No | No |
Service Types¶
Every Service Event initiated needs to have a Service Type associated with it.
To create Service Types go to the Admin section and click the Service Types link in the Service Log section and then click the Add Service Type button. Fill in the fields as follows:
- Name A short descriptive name for the Service Type.
- Is review required This flag controls whether the “Is Review Required” checkbox is enabled when entering/editing service events. If this flag is not checked, then users will have the option of not requiring a new Service Event to be reviewed. If this flag is checked, then all Service Events of this type will be required to undergo review. For example, you may wish to leave this flag unchecked for minor service types and allow the person entering the service event details to determine whether it needs to be reviewed or not. Conversely you may want to check this flag for extensive, or safety systems service types.
- Is active Unchecking this will hide the Service Type from drop down menus
- Description A brief description of this service type
By default the following Service Types are defined:
Service Type | Requires Approval | Definition |
---|---|---|
Preventive (Regular) Maintenance | No | Anything that is recommended by the manufacturer for routine (e.g. daily, weekly, monthly, quarterly and annual) maintenance and is on a schedule. |
Minor Repairs / Corrective Maintenance | No | Anything that is not part of a routine schedule and requires intervention without parts replacement. |
Extensive Repairs | No | Any repair that is not part of a routine schedule and involves the replacement of parts. In addition, any action that involves changes to ANY operating parameter (i.e. steering coils, gun current, readout calibration, etc.). |
Safety Systems | Yes | Any repair that involves a CNSC regulated safety system. Examples are in-room monitors, room interlocks, prim alert, etc |
Service Event Templates & Schedules¶
In order to simplify the process of creating Service Events, QATrack+ allows you to define Service Event Templates that can be used to autopopulate many of the fields in the Service Event form including:
- Service Type
- Service Area
- Problem Description
- Work Description
- Is Review Required?
- Return To Service Tests / Test List Cycles
This allows you to create say a “Annual PM” service event template which predefines the work done and return to service work required after the PM.
To create a new Service Event Template, go to the admin area and select the Service Event Templates link in the Service Log section then click the Add Service Event Template button.
On the Add service event template page give your template a name (e.g. Annual PM) and then fill out the fields below to indicate how the Service Event fields should be populated when a user selects this template.
All of the fields are optional, however special attention should be payed to the Service Area and Return to Service Test Lists (Cycles) fields. A Service Event Template may only be applied to a unit when that unit has a matching service area and the selected return to service test lists/cycles assigned to it. If you need to create a more generic template that can be applied to a variety of unit types you may want to leave those fields blank.
Once you have filled out the fields, click Save.

Adding a new Service Event Template
For information on using a Service Event Template see the Service Log Users Guide.
Similar to the concept of assigning Test Lists to Units, QATrack+ allows you to assign Service Event Templates (described above) to Units to be performed with a given frequency.
To assign a Service Event Template to a Unit, go to the admin area and select the Assign Service Event Templates to Units link in the Service Log section then click the Add Service Event Schedule button.
On the Add service event schedule page, select the Unit Service Area you want to assign your template to (this will autopopulate the Unit field).
The Unit Service Area that you want to assign the test list to.
The Frequency with which you want the template to be performed (e.g. Daily, Monthly, Yearly etc).
Optionally, you can leave the frequency blank and the template will be assigned to be performed on an ad-hoc basis.
Here you can manually set the initial due date/time for a test list on a unit. You can also leave this blank if you like and the test list will show up as being Not Due.
If you leave Auto Schedule checked, the due date will automatically be updated according to the assigned frequency after the test list is completed on a unit.
The group of users that is generally responsible for performing the service. Note that the Assigned To property is used for display only and users not part of the Assigned To group will still be able to see and perform the template.
Select which user groups this service event template should be visible to by moving groups from the Chosen visible to to the Available visible to box.
If this checkbox is unchecked, the template will not appear in any listings on the main site. This should be used to disable templates are no longer performed on a unit.

Adding a new Service Event Schedule
For more information on performing Service Event Schedules, see the Service Log Users Guide.
Configuring the Parts App¶
As part of the Service Log App app, QATrack+ has the ability to track your inventory of spare parts and where they are located. Before you can use the Part’s app, you need to configure a few things.
In order to categorize your spare parts, you need to create some Part categories. To create new Part Categories go to the Admin section and click the Part Categories link in the Parts section and then click the Add Part Category button.
Give the Part Category a name and then click Save. Repeat for as many different categories as you want.

Parts categories
The Parts app is the ability to track the location of where parts are located. To do this, you need to create some storage Locations, which belong to Rooms. To create new Rooms go to the Admin section and click the Rooms link in the Parts section and then click the Add Room button.
If you have configured Sites then select the Site that this Room is located in.and then give the room a name (e.g. A234). In the Storage section add some locations and descriptions of places parts are stored within the Room (e.g. Filing Cabinet, Shelf #1 etc). Repeat for as many different Room`s as you want.

Adding a new parts room
Parts Suppliers allow you to keep track of one ore more vendors who can supply individual parts. To create new Suppliers go to the Admin section and click the Suppliers link in the Parts section and then click the Add Supplier button.
Set the name of the supplier and any relevant notes then click Save:

Adding a new parts supplier
While it is possible to add Parts via the Admin section, it is recommended you use the main parts user interface for managing parts and inventory levels.
Initial Configuration¶
Fault Log Administration¶
The Fault Log app is used for tracking faults that occur on your units. There is no initial configuration required for the fault log app.
Fault Types¶
Fault types can be created on the fly as users log new faults so it is not necessary to configure fault types. However, if you want to manually add fault types, or add a description to existing fault types it can be done in the Fault types section of the admin.

Faults admin section
On the Fault types listing page, you can add a new fault type by clicking the Add Fault Type button at the top right hand of the page, or edit an existing fault type by clicking the link in the Code column of the table.
The Fault Type fields are as follows:
- Code The fault type code or fault type number.
- Description A description that will be shown alongside the fault type when viewing fault details.
Faults¶
Typically you would edit faults using the Fault Log application, however, you may also edit or delete faults from the admin interface if you prefer.
Fault Review Groups¶
By adding one or more Fault Review Groups, the person logging the fault/interlock can select the people who were informed of the fault at the time the fault is logged. A fault logged with one or more reviewers selected will be considered reviewed and will not appear in the unreviewed fault list. Selecting a review user for a Fault Review Groups can either be required or optional.
For example if you add two Fault Review Groups, one for an Electronics group, and one for a Physics group:

Fault Review Group Admin
then when a user is logging a new fault, the form will include a reviewers section at the bottom:

Logging a fault with reviewers
Users Guide¶
Note
For documentation on configuring tests, users and other administrative tasks, please see the Administrators Guide.
Managing Users and Groups¶
For the most common tasks of creating new groups, updating group members, and managing group permissions, you may find the Groups & Permissions page more convenient than the admin area for managing users, groups, and permissions. This feature requires you have the “Change Group” permission.
Accessing the Groups & Permissions Page¶
To access the Groups & Permissions page, hover over your username in the top right hand corner and select the Groups & Permissions link.

Accessing the Groups & Permissions page
Adding a new group¶
To add a new group first click the Add Group button, enter a new group name, then select the users you want included in your group.

Adding a new group
Once you’re finished click Close.
Editing Group Name and Members¶
To edit an existing group, select the group you want to edit in the Group select box, then click the Edit Group button. Update the members or group name as required in the modal dialogue that opens. Click Save Group when you are done or Close to cancel.
Changing Group Permissions¶
When you select a group using the Group select, the group permissions will be shown on the page below, with a green checkmark indicating the group has a permission, and a red x indicating that the group does not have that permission. In order to toggle any permission for that group, click on the relevant checkmark or x. Changes will take place immediately upon toggling.

Editing a groups permissions
Please note this page only covers the most common permissions required for groups in QATrack+. If you need finer grained controls, you will need to use the admin authorization area.
Performing and reviewing QC¶
Performing a Test List¶
Selecting a test list¶
To perform a test list, first login to QATrack+ and then select the Choose Unit option from the Perform QC dropdown menu.

Choose Unit Menu Option
On the following page, clicking on the main button for a unit will take you to a page that lists all the test lists assigned to that unit.

Select unit button
You can pre-filter the list by its assigned frequency by using the dropdown menu attached to the select unit button.

Select unit dropdown button
On the next page, all the test lists with the chosen frequency will be displayed along with relevant information about the last time that test list was performed and when the test list is next due on this unit.
Click on the Perform QC button next to the list that you would like to complete.

Choose a test list to perform
In addition to the Choose Unit method for selecting a test list, QATrack+ has two “Tree Views” that present the QC available to perform in a tree structure grouped either by Unit & Frequency, or by Unit, Frequency, and Category. These views are found in the Perform QC menu:

The menu options for selecting a tree view
An example of the Unit, Frequency, and Category view is shown here:

An example of a Unit, Frequency, Category tree view
Performing a test list¶
An example test list is shown below. Details about all the features will given below but briefly, you can see all the tests completed and ready to be submitted. The shaded input boxes for the last two tests indicate that they are composite tests i.e. they are test values calculated based on the other 4 input values. Passing, tolerance and failing tests are displayed with a green, yellow or red status, respectively. Tests which have no reference or tolerance set for them are shown in blue.

Example test list
Clicking on the test name will display instructions or information about performing the test.

Embedded test procedure
You may add either test specific comments by clicking on the speech bubble beside the test or you can add a general comment for the whole test list by entering the comment in the text box below the Submit QC Results button.
Adding comments to a test list

Adding comments to test lists
Occasionally it may be required to skip a test when performing a test list. To accomplish this, check off the skip checkbox next to the test and add a comment (required unless the user has the Can skip without comment permission) explaining why you are skipping the test.

Skipping a single test
Some test lists may have tests from more than one category type. To selectively perform the tests from one or more categories, use the select box from the left hand drawer menu to choose the test categories you want to perform. Tests from categories that are not selected, will be hidden and marked as skipped with a comment explaining why.

Performing a subset (Dosimetry & AQA) of tests within a test list
When performing QC, you may attach arbitrary documents to the test list before submitting (e.g. a PDF report from some external software).
In order to do this, simply click the Browse button and select the files you want to attach.

Attaching files to a test list instance
These files will be saved and available for review later.
There are currently a limited number of keyboard shortcuts available when performing a test list:
- Use the up/down arrow keys to navigate between test input fields
- Hit Enter or Tab to cycle through the test input fields
More keyboard shortcuts will be made available in the future.
If for some reason you need to finish a test list at a later time, you can click the Mark this list as still in progress checkbox next to the Submit QC Results button. When this box is checked, the test list will not be considered complete and will not be marked for review.

Save a test list to complete later
When you are ready to complete the test list, you can find it by selecting the In Progress menu option

In progress menu
and then clicking Continue on your saved result.

Continue an in progress test list
When performing a test list, the left hand drawer menu will also show any In Progress QC sessions for the current test list.

Continue an in progress test list from the sidebar
As of version 3.1.0, QATrack+ now auto-saves your data in the background every time you enter a new test result. This helps prevent data loss in the case that a user mistakenly navigates away from a test list page without submiting the data, or due to a browser crash, power failure, etc.
You can see the last auto-save time in the top right hand portion of the form for entering QC data.

Autosave status showing last saved time
When performing a test list with autosaved data available, the left hand drawer menu will also show any autosaved sessions which you can click to load and continue.

Continue an autosaved test list instance
Autosaved sessions will be automatically deleted either:
- When the QC session is submitted succesfully -or-
- After 30 days has passed since the auto-saved session was last modified. (To change the 30 day interval, you may change the AUTOSAVE_DAYS_TO_KEEP setting).
Test List Cycles¶
QATrack+ allows you to set up groups of Test Lists, called Test List Cycles, which are performed in a cycle. For example, you may perform different safety tests on different days of the week. When a user chooses to perform a Test List Cycle the next Test List scheduled to be performed is automatically loaded for the user.
Manually Choosing A Test List From A Test List Cycle¶
Occasionally you may want to perform a specific day from a Test List Cycle out of order. This is easily accomplished on the test list page by selecting the desired day from the dropdown list in the left hand drawer menu.

Overriding the default test list cycle day
Note
You could also change the requested day in the url from next to the day of
your choosing. For example you could change the url from
http://qatrack/qa/utc/perform/27/?day=next
to
http://qatrack/qa/utc/perform/27/?day=3
but this method is not guaranteed
to work in the future.
Viewing The History Of A Test List¶
The easiest method of viewing the hsitory for a test list is to visit the Your Test Lists By Unit page from the Review Data dropdown at the top of the page.

Choose a unit to review
On the following page you can select the unit you wish to review and from there, you will see a list of all tests lists assigned to that unit.

Review Test List Listings
Click the History button of the test list you want to review data for and then click the Review button for the specific instance you want to review.

History listing
Editing Previously Entered Data¶
If your user group has the required permissions, you may edit previously completed data. To edit a specific test list instance, first navigate to the history of the test list of the test list and click on the Edit button of the session that you want to revise.

Test list history page
You can then edit the previous results and save as usual. Note that when you edit a Test List Instance, the default behaviour is to reset the status for all the tests to the default test status. For example, if a qa session had already been reviewed but was later edited and saved, it will show up in your Unreviewed list again (assuming your default status is one which requires review).
Review and Approval of Test List Instances¶
After a Test List is submitted, every Test Instance in QATrack+ is assigned a Status that indicates what type of data the test is and whether or not it requires further review. If any Test Instance within a Test List Instance is assigned a Status which requires review, then the Test List Instance is placed in an Unreviewed Queue so that periodically a physicist may manually review and approve the QC data being generated. (It is also possible to skip the Unreviewed Queue and manual review step using Auto Review Rules).
Details on how to review QC data and/or update the status of a set of tests are given below.
Reviewing QC Data¶
The number of test lists with unreviewed tests is displayed at the top of every QATrack+ page (provided you have the permissions required to review data).

Unreviewed count is displayed at the top of every page
To review data, choose the Unreviewed option from the Review Data dropdown menu at the top of the page.

Unreviewed menu option
You will then be presented with a list of QC sessions awaiting review. This list can be filtered/sorted by unit, frequency, date or user.
Click on the Review button of the QC session that you want to review and you can then change the status of the tests as described below.

Unreviewed listing
Repeat those steps for all the QC sessions that you would like to review.
Changing the status of test data¶
On the following page select the status you would like to apply to the tests from the dropdown menu at the top. Click the checkmark next to the dropdown to apply that status to all the tests in the list (Test statuses can also be set individually.) Click the Update Test Statuses to save your changes to the database.

Updating test instance statuses
If all the Test Instances were assigned a Status that does not require review, than the Test List Instance will be removed from the Unreviewed Queue.
Bulk Review of Test List Instances¶
If your administrator has enabled the REVIEW_BULK setting, your Unreviewed Test List Instances queue will have an extra column on the right hand side that behaves similar to the Review page described above. This page allows you to set the review and approval status for all test instances included in any test list instances which have a Review & Approval status selected.
First set the Review Status of all Test List Instances you want to update, and then click Update Review Statuses and then review and confirm before submitting.

Updating test list instance review statuses in bulk

Confirm that you want to update the test list instance review statuses in bulk
Deleting A QC Session (Test List Instance)¶
Warning Deleted items are irretrievable! If you are unsure of what you are doing please ask someone for assistance.
Navigate to the review page of the QC session you would like to delete and at the bottom left of the page click the red Delete button (if the button is deactivated, you don’t have the required permissions to delete items).

Delete button location
Clicking that button will take you to an admin page where you will be presented with a list of all objects in the database that will be deleted as a result of this action.

List of things to be deleted
Carefully review this list! Once you click Delete the items listed will be deleted permanently. You should see details (test list/date/time/user) of the session you are about to delete, along with all of its associated test results.
If you are sure you want to permanently delete these items click Delete.
Overseeing The State Of Your QC Program¶
There are currently two main ways of viewing the overall status of your QC program. You can see which tests lists are overdue or coming due soon on the Review By Due Status page, or you can view a snapshot of your whole QC program on the Overview page.

Review Test Lists By Due Status
Viewing Test Lists Which are Coming Due Soon¶
From the Review Data dropdown menu at the top chose the By Due Status option. This will take you to page that summarizes any test lists that are coming due soon.

Summary of upcoming QC required
Overview of All Units¶
From the Review Data dropdown menu at the top chose the Overview - All Units option. This will take you to page that lists all the defined Unit s and their respective Test Lists, grouped by frequency. This allows you to get a quick overview of what the current status of QC is on all of your units.

Overview snapshot
Clicking on the names of any of the test lists will take you directly to the history of that test list.
Plotting your data¶
There are currently two ways of plotting your data 1) basic time series plots and 2) statistical process control charts (SPC) (see Statistical process control for radiotherapy quality assurance).
Note
Anywhere you see a little chart icon ( ) next to a
test you can click on it to automatically be taken to a chart of that
data
To access the chart interface choose the Charts menu item from the Review Data dropdown menu at the top of any page.

Charts option of the Trends and Analysis menu
The basic functionality of the charts page should be fairly self explanatory. First select the units you are interested in, and then select the test lists/tests you would like to plot data for.

Choose tests to plot
There are a number of chart options which you can change:
- Combine test data for unit: Combine results for the same test from different test lists into a single series
- Plot relative to reference values If selected, the absolute difference is plotted for tests with absolute tolerances set or with reference values of zero, otherwise the percent difference is plotted.
- Show Service Events If checked, then charts will show markers along the x-axis for Service Events that occured on a Unit.
- Service Types Select the types of Service Events you want to show on the chart.
To create an SPC choose the Control Chart option from the Chart Options - Type: dropdown.
Once you are happy with the options, click the Generate Chart button.

Time Series Plot

Time Series Plot showing a Service Event marker
The foo time series plots are interactive and you can pan/zoom the data using the sliders at the bottom of the chart.
In order to save a time series chart to an image, click the Save Chart button and a PNG image of the graph will be created.

Save Chart
You can also use the URL located in the link text box under the chart to share the chart with other users.

Control Chart
To save a control chart, right click and select Save Image As.
Notes on Control Charts¶
Note
For details on the terminology & definitions of control charts please see the paper by Pawlicki et al (2005): https://aapm.onlinelibrary.wiley.com/doi/abs/10.1118/1.2001209
To specify where your baseline data comes from you can use the Date Filters under the Generate Chart button. For example if there was a reference change on 5 Nov 2012 then you would set the From: date filter to 5 Nov 2012 and the baseline points will be taken starting on that date.
Service Log and Parts Apps¶
As of version 0.3.0, QATrack+ includes Service Log and Parts applications for recording major equipment service events, machine down time, and parts inventories. For more information on using these applications, refer to the documents linked below.
Using Service Log¶
Service Events¶
A Service Event is any event where some sort of scheduled or unscheduled maintenance or intervention that occurs for a Unit. Examples of Service Events include:
- Electron gun change
- xray tube change
- MLC calibration
- Laser adjustments
- Routine preventative maintenance (PM)
Recording this information in QATrack+ will help you keep track of the history of your units, correlate machine performance with service events and more.
There are three ways to create a new Service Event record.
The first method for initiating a Service Event is to simply access the Enter New Service Event menu from the Service Log menu in the top bar:

Service Log menu
on the next page you will be presented with a number of forms used to generate Service Event records.
On the main form, fill in the following fields:
- Service Status The current status of the Service Event. If you are scheduling a Service Event for later this will likely be a status like Service Pending or similar. If you are performing the Service Event now, this may be e.g. Service in Progress.
- Date and time The date and time the service is being performed.
- Unit The Unit the service event is occuring on.
- Service Area The Service Area of the Unit that the service is being performed on (e.g. Treatment Table).
- Service Type Select whether this is preventative maintenance, minor fix etc.
- Related Service Events After you select a Unit, the Related Service Events input will become active and you can search and select one or more related service events.
- Initiated By If this service event is occuring as a result of a QC Session (e.g. a failing test) you can create a link between this Service Event and that QC Session. After you select a Unit, the Initiated By dropdown will be activated and show you a list of Test Lists associated with the selected unit. After selecting the Test List you will be shown a popup window to select the related Test List Instance.
- Review Required Does this Service Event require Review after it is performed?
- Problem Description A description of why this service was performed.
- Work Description A description of the how and what this Service Event entailed.
- Safety precautions (optional) Any safety precautions taken during this Service Event.

Initiating a new Service Event
Next move to the Involved Parties and Durations form in which you can specify who was involved in performing this Service Event and how long it took.
- Service Event Durations - Service Time The time taken to perform the actual Service Event.
- Service Event Durations - Lost time How much clinical time was lost due to this Service Event?
- Group Members Involved If your QATrack+ administrator has configured Group Linkers then you may select users from different groups who are involved in this Service Event.
- User and Third Party Work Durations

Durations and personnel
The next form allows you to specify what Return To Service QC (RTS QC) needs to be performed before the Unit can be released for clinical use again.
- Test List Select one or more Test Lists that must be performed as RTS QC. Once you have select the Test List, you can click the Performed button to select a completed Test List Instance service as RTS QC, or more likely, if it has not been performed, yet, this can be selected later.
- Comments Add any relevant comments about RTS QC here.

Return to service QC
Lastly there are two forms you can use to a) Specify the Parts used in the Service Event and where they came from and b) attach arbitrary documents to this Service Event.

Attachments and parts
Once all the fields are filled out you can click Save and you will be returned to the Service Log Dashboard.
It is also possible to initiate a Service event when performing a Test List by selecting the Initiate Service Event checkbox (if you have the required permissions):

Initiating a Service Event from a Test List
after submitting the QC you will be taken to the Create Service Event page described above with the Initiated By field auto populated with the Test List Instance you just performed.

Service Event Initialized by a Test List Instance
is also possible to initiate a Service event when reviewing a Test List Instance by clicking the Initiate Service Event button (if you have the required permissions):

Initiating a Service Event from a Test List Instance review
which will take you to the Create Service Event page described above with the Initiated By field auto populated with the Test List Instance you were just reviewing.
If your administrator has configured service event templates then when you select the Unit you want to enter a Service Event for, the Template input will be activated and you can select one of the templates available to perform on that unit.

Selecting a service event template
This will auto populate any fields that have been configured in the template including the Return To Service QC.
Scheduled Service Events can be accessed throught the Service Log -> Service Event Schedules menu:

Navigating to the Scheduled Service Event Lists
On the next page, select the Service Event Template you want to perform. Clicking the Perform button will take you the form for entering a new Service Event with the appropriate Service Event Template field and the other template fields pre-populated for you.
If you are performing this Service Event Template outside of your normally scheduled time, you can deselect the Include for Scheduling field and the due date for this scheduled template will not be updated when you submit it.
The Service Log Dashboard provides you with an overview of the current status of all Service Events, including which events need review, which events have Return To Service QC incomplete or unreviewed and a list of recent activities.

Service Log Dashboard
Return To Service QC¶
Integral to the Service Log app is the concept of Return to Service QC (RTS QC) which is to say, Test Lists that must be performed before the Unit can be released for clinical use after a Service Event. To view which RTS QC is pending, select the View All Incomplete Return To Service menu item from the Service Log menu, or click on the Incomplete button on the Service Log dashboard.

Return To Service Menu

Return To Service Button
This will take you to a listing of incomplete RTS QC.

Return To Service List
To perform an RTS QC Test List, click the Perform button and perform the Test List. After performing the Test List, the resulting Test List Instance will be placed in the Unreviewed Return To Service queue which you can view using the Unreviewed Return To Service menu item in the Service Log menu.

Return To Service RTS QC Review Menu
Selecting that menu will take you the listing of all unreviewed return to service QC from where you can review the data using the usual routine.
Reviewing Service Events¶
After all required RTS QC has been performed, you will want to review your Service Event. Select the Service Events Needing Review menu item from the Service Log menu:

Return To Service Review Menu
From there click on the Edit button of the Service Event you want to review:

Unreviewed Service Event List
and select the appropriate Service Event Status:

Approving a Service Event
and click Save. This will remove the Service Event from the Unreviewed queue.
Service and Lost Time Report¶
In order to view a report about Unit uptime, select the Service and Lost Time menu item from the Trends and Analysis menu:

Service and Lost Time Menu
On the next page you will see a listing of all Service Events and their associated Service Time and Lost Time. Use the various filters to select the Unit’s and date ranges of interest:

Service log uptime summary
and then click the Download Up Time Summary which will generate a CSV file with a unit by unit uptime report (this uptime report is based on the Available Time property of the Units):

Service Log uptime report
Using the Parts App¶
As of version 0.3.0 QATrack+ comes with a Service Log which inclues a Parts app for managing spare parts inventory.
When users are managing Service Events they may choose to include which parts from their inventory were used and they will automatically be removed from the available inventory.
Adding Parts To Your Inventory¶
To add a new part to the inventory select the Enter New Part menu item from the Service Log menu in the top menu bar:

Enter new part menu item
On the next page you will be presented with a form for adding your new part:

Creating a new part
The fields are as follows:
- Name Name describing what this part is.
- Part Number The manufacturers identification number for this part.
- Alteranate Part Number Alternate manufactures part number.
- Cost Last known cost for this part.
- Part Category (optional) Which category does this part belong to.
- Low Inventory Count When the part inventory count falls below this number, a message will be shown to the user and the part will show up in the Low Inventory Report.
- Notes (optional) Any additional comments about this part type?
- Suppliers (optional) List any known suppliers and optionally the supplier specific part number.
- Storage (optional) List the Rooms and Locations where the part is located and how many are available in that location.
- Attachments (optional) Add attachments such as pdfs or images relevant to this part. Images will be shown inline in the parts listing pages and on the parts details page.
Once you have entered the fields click Add Part and enter Another to save this part and continue entering other parts, or just click Add Part and you will be returned to the list of all parts.
Editing Existing Parts¶
To view all existing parts select the View All Parts menu item from the Service Log menu in the top bar.

View all available parts
from there you can click Edit or Details to edit the part item (adjust inventory numbers, part name etc) or view the details of the part:

View part details
Low Inventory Report¶
To view a report about which parts are low in inventory, select the View Low Inventory Parts from the Service Log menu in the top bar.

View low inventory parts
A Complete Service Log Example¶
In this tutorial we will walk through a complete example of using Service Log to record an output adjustment that is made after morning QC revealed that the output was too high.
Scenario¶
The output on a unit has been trending upwards for a little while and one morning the morning output check indicates that the machine output is outside of action levels and treatment can not begin:

Output is outside of action levels
The therapist measuring output uses the QATrack+ contacts information to call the on on-call physcist and informs them of the issue:

Contacts displayed while performing QC
The physicist must now restrict the machine and perform an output adjustment working alongside the field service engineer (FSE).
Resolution¶
The physicist opens QATrack+ and visits the Enter new Service Event page:

The New Service Event Menu
The physicist then enters the basic information about this service event:

Basic information about the Service Event
and then, since this SE was related to a specific Test List Instance, they choose the related Test List, and specific Test List Instance from the Initiated By drop down menu and popup:

Selecting Initiated By Test List

Selecting Initiated By Test List Instance

Selected Initiated By Test List Instance
Since the service will be performed, now, the physicist changes the Service Status to Service In Progress:

Service In Progress status
Next the physicist selects the Return To Service QC that will be required before the Unit can be released for clinical duty:

Return To Service QC Selected
The physicist now clicks Save and the are ready to make the output adjustment. Note that the Service Log Dashboard will now show 1 incomplete Return To Service QC and 1 Service Event needing review.

Service log dashboard
After The Adjustment¶
The physicist and FSE have now made the adjustment and will now, perform the Return to Service QC. The physicist clicks the Incomplete Return To Service QC button (shown above) and then clicks Perform next to the RTS QC list item:

Return To Service QC Listing
After the RTSQC is performed the physicist returns to Edit the Service Event so they can complete the entry of how much time it took and who was involved:

Edit Service Event Button
The Work description, Service Event Durations, Group Members Involved and User and Third Party Work Durations fields can now all be filled out (If any parts were used in the Service Event, this would also be the time to enter them):

Fields filled out after Service Event is completed
The Service Event Status can now be set to Service Complete:

Service completed status
and Save’d again.
The Dashboard will now show that there is one Return To Service QC, and 1 Service Event awaiting review:

Dashboard after Return To Service QC
The physicist now goes back to the Edit page for the Service Event. Note that an attempt to save the Service Event with the Service Event Status to Approved before the RTSQC has been approved will result in an error!

Can’t approve a Service Event without reviewing the RTS QC first
Instead, the physicist first clicks through the Review link for the RTSQC and reviews the QC:

Review RTSQC Link
after the RTSQC Test List Instance is reviewed, the physicist is directed back to the Edit page for the Service Event where you can see the updated Review Status of the RTSQC:

All RTS QC reviewed
The Service Event Status can now be set to Approved and this Service Event is now complete!

Service Event Approved

Dashboard after Service Event reviewed and approved
Machine Fault Log¶
In order to help you keep track of any machine issues, QATrack+ allows you to record machine faults using the fault log introduced in version 3.1.0. Faults can either be logged directly on the page when performing QC work, or using the standalone page for entering faults.
Entering a new fault¶
Note
Only units with the “Is Serviceable” flag set will be shown in the Unit’s drop down.
In order to enter a new machine fault, select the Enter a new fault option from the Fault Log menu at the top of the page.

Location of the faults menu
Next, fill out the form on the New Fault Page:

Entering a new fault
- Date & Time fault occurred Enter approximately when the fault took place
- Unit, Modality* When you select the Unit the fault occurred on, the Treatment or Imaging Modality drop downs will be populated with any treatment or imaging modality options configured for your unit. The Modality field is optional.
- Fault Type After typing the first two characters of the Fault type, the drop down will be populated with any matching Fault Type codes already in the Fault type database. If the fault code does not already exist in the database, you should enter (and select) the full fault code. This Fault Type will be added to the database when you submit your fault.
- Related Service Events In this field you may optionally select one or more related service events by entering their service event IDs.
- Comment Add any comments you think might be useful for anyone reviewing the fault.
- Reviewers If your administrator has configured Fault Review Groups you will be able to select the users who were notified of this fault.
Click Log Fault once you’ve finished entering the data.
Entering a new fault while performing QC¶
In addition to the above method of logging a new fault, you can log a new fault directly on the page when performing QC. In order to do this click the Log Fault item from the left sidebar.

Location of Log Fault link when performing QC
This will bring up a modal dialogue that allows you to enter the fault details. The unit, date, and time will already be populated for you.

Dialogue for logging fault when performing QC
Complete the other details then click Log Fault. The dialogue will automatically close after the fault is logged successfully.
Reviewing Faults¶
Note
In order to review faults after they are logged, the user will need to belong to a group with the Can review faults permission.
If your administrator has not configured Fault Review Groups then after submitting a fault, it will be in an unreviewed state. In order to mark faults as reviewed select the Unreviewed menu item from the Faults menu.

Location of the unreviewed faults menu
On the next page you can click the Review button (if you don’t have fault review permissions this button will say Details) for the fault you want to review.

Select the fault you want to review
On the details page you can click the Acknowledge This Fault button to mark this fault as reviewed, click the Edit button to edit the fault, click the Delete button to delete the fault, or view other occurrences of the same type of fault at the bottom of the page.

Reviewing fault details
Fault Notifications¶
There are two types of notifications you can set up for faults:
- Fault Logged Notices: to notifiy people when a fault is first logged.
- Fault Review Notices: to periodically notify people when there are unreviewed faults.
Units¶
Setting Unit Available Time¶
Your site administrator should have set up the nominal available time when configuring units but there are often exceptions to available time due to holidays or other events. To ensure your uptime/downtime is tracked accurately, you need to record these exceptions in QATrack+. To do this, navigate to the Unit Available Times menu option in the right hand drawer menu (hover pointer over your username in the top right).

Unit available time menu
On the left hand side of the page, select all the Units that you want to change the available time for. Next you can modify available times one of two ways:
1. Modifying available times for specific days¶
In order to modify the available time for specific days, select the days on the calendar that you want to make the modification for. In the image below, two Mondays (Sept 10th & 17th) are selected for three units:

Selecting days on the calendar
to reduce the available hours to say 4 hours for those two dates, click the Edit Available Time button on the left hand side and enter the modified number of hours:

Modifying the time available for units
and then click Update Available Times. The calendar will then reflect the modified hours on those days:

Modified available time
2. Modify available times for all days after a specfic day¶
Let’s say your clinic was extending the treatment day to 12 hours on Monday & Tues for one unit in the month of September in order to treat a backlog of patients. To track this in QATrack+, select the units you want to modify then click on the Monday that you want this to start. Then click on the Edit Schedule button on the left hand sidebar and set the avaialable times:

Changing available time after date
then click Update Schedule. Your changes will then be reflected in the calendar:

Changed schedule
To return the Unit to it’s regular schedule in October, Select the first Monday in October, click Edit Schedule and set the hours back to 8:00.

Reset calendar
Deleting a schedule modification¶
If you make a mistake, you can remove schedule modifications: select the Unit and Date you want to delete and then click the Delete Changes button on the left sidebar:

Deleting a schedule modification
Clicking Delete will remove any selected schedule modifications.
Reporting & SQL Queries¶
QATrack+ currently has two different methods of generating reports. There is a set of predefined reports in the Reports App and also a method of writing and saving SQL queries, generating charts & pivot tables, and exporting CSV data using the Query Tool.
Reports¶
As of version 3.1.0 QATrack+ has a tool for generating and scheduling reports in PDF/Excel/CSV formats. To access the tool, select the Reports option from the Trends & Analysis menu.
Permissions Required¶
Generating reports requires a user to have the “Can Run Reports” or “Can Create Reports” permission set on their account.
Available Report Types¶
The report types currently available in QATrack+ are:
QC:
- QC Assignment Summary This report lists all test lists (cycles) currently assigned for the selected sites, units, frequencies and groups.
- QC Assignment Details This report includes details for all test lists (cycles) currently assigned for the selected sites, units, frequencies and groups. Details include tests, & current references, and tolerances.
- Test List Instance Summary: This report lists all Test List Instances from a given time period for selected sites, units, frequencies, and groups.
- Test List Instance Details: This report includes details for all Test List Instances from a given time period for a given Unit Test List (Cycle) assignment.
- Test Instance Details: This report shows QC test values for select tests/units.
QC Backup Forms:
- QC Paper Backup Forms This report generates a PDF containing paper backup forms that can be used to record QC values in the case that your QATrack+ installation is unavailable.
Scheduling:
- Next Due Dates for QC: This report shows QC tests whose next due date fall in the selected time period.
- Due and Overdue QC: This report shows QC tests which are currently due or overdue
Service Log:
- Service Event Summary: This report summarizes the Service Events logged for selected Sites & Units in a given time period.
- Service Event Details: This report provides details for the Service Events logged for selected Sites & Units in a given time period.
- Service Event Personnel Summary: This report summarizes the people involved in Service Events logged for selected Sites & Units over a given time period.
- Service Event Personnel Summary: This report summarizes the service time, lost time, and uptime percentages for selected Sites & Units over a given time period.
- Scheduled Service Event Assignment Summary This report lists all service event templates assigned to the selected sites, units, frequencies and groups.
Service Event Scheduling:
- Next Due Dates for Scheduled Service Events: This report shows scheduled service events whose next due date fall in the selected time period.
- Due and Overdue Scheduled Service Events: This report shows scheduled service events which are currently due or overdue
If there are other reports you would like to see please file an issue For custom reporting please submit an issue on GitHub.
Creating a New Report¶
On the left hand side of the page you will find the Report Configuration area:

Configuration options for a new report.
The fields in this are as follows:
- Currently editing / Clear Report / Delete Report:
This field will display New Report when creating a new report, or the name of the saved report currently being edited.
In order to clear the current report, click the X button to the right of the Currently editing field.
In order to delete the current report, click the trash can button to the right of the Currently editing field. A popup will be displayed asking you to confirm the deletion.
- Title
- Give your report a descripitive title
- Report Type
- Select the Report Type you wish to generate.
- Report Format
- Select the format you would like your report to be generated as. Most reports are available as PDF, CSV, or Excel however, some may only be available in a subset of these formats (e.g. the Test Instance Values is only available in CSV/Excel formats.
- Visible To
- When you save a report, you can optionally choose to have that report visible to others. Select the groups you want to share your report with in this field, or leave blank to keep the report private.
- Signature
- If you check this option, there will be a placeholder for a signature and the current date included at the end of PDF reports.
Report Filters¶
Most of the reports have either optional or required filters which you can apply before generating a preview or downloading your report. Please see the individual report descriptions for explanations about what filters are available on each report.
Adding Notes to Reports¶
Users can add include zero or more custom notes in their reports by clicking the ‘Add Note’ button.

Buttons for adding notes to reports
Once a note is added you must specify a heading for the note, and you can optionally add some content to the note. If you leave the note content blank a space will be left in the report so that users can add notes later using external PDF tools. Notes are added at the bottom of the report.

Example report with notes included
Previewing, Saving, or Downloading a Report¶
Underneath the Report Filters section are buttons for saving, downloading, and previewing your report.

Buttons for dowloading, saving, or previewing a report.
Once you have set up the filters required for your report, you can generate an online preview (only available for reports which have a PDF Report format option.). You can generate an online preview of your report by clicking the Preview button. The report will be generated on the QATrack+ server and then displayed for you in the Report Preview area.
Clicking the Download button will allow you to download the report in your desired format, while clicking the Save button will add this report to your saved reports which are available for future use in the Saved & Scheduled Reports section on the right hand side of the Reports page.
Loading a Saved Report¶
On the right hand side of the screen on the Reports page you will find the Saved & Scheduled Reports section which contains a table of all your previously saved reports:

Saved & Scheduled Reports area
To load a previously saved report, click on the title link of the report in the Report column of the table. The report will then be loaded and you can preview it, download it, or edit its configuration and save it again.
Scheduling a Report¶
In order to schedule a report for delivery you first need to Save it. Then, in the Saved & Scheduled Reports area, click the calendar icon beside the report you want to schedule:

Click the calendar icon to schedule your report.
This will bring up a dialogue with a scheduling form for you to fill out. The fields in this form are as follows:
- Schedule (required)
- Set a recurrence rule for the days that you would like your report sent.
- Time of Day (required)
- Set the time of day you would like the report emailed.
- Groups (optional)
- If you want the report delivered to one or more user groups, select those here.
- Users (optional)
- To have the report delivered to individual users, select them here
- Extra recipient emails (optional)
- Add any additional emails you would like this report sent to.
Once you have set the schedule and recipients, click the Update Schedule button and then click Close.

Setting the schedule and recipients for a report.
To edit or clear the schedule for a report, click on the Edit Calendar icon next to your report.

Click the edit calendar icon to schedule your report.
You can then adjust the recipients and/or schedule for your report and click Update Schedule and then Close.
To clear the schedule for a report open the scheduling dialogue and click the Clear Schedule button and then click Close.
Deleting a Saved Report¶
In order to delete a saved report, first load the report then click the trash can icon next to the Currently Editing field:

Click the trash can icon to delete your report.
Report Type Descriptions & Options¶

An example QC Assignment Summary report
This report lists all test lists (cycles) currently assigned for the selected sites, units, frequencies and groups.
The filters available for this report are:
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Frequency (optional)
- Filter your results to those scheduled with a specific frequency (e.g. Monthly).
- Assigned To (optional)
- Filter your results to those assigned to a specific group.
- Active (optional)
- Select whether you want to include assignments which are active, inactive or both.

An example QC Assignment Details report
This report includes details for all test lists (cycles) currently assigned for the selected sites, units, frequencies and groups. Details include tests, & current references, and tolerances.
The filters available for this report are:
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Frequency (optional)
- Filter your results to those scheduled with a specific frequency (e.g. Monthly).
- Assigned To (optional)
- Filter your results to those assigned to a specific group.
- Active (optional)
- Select whether you want to include assignments which are active, inactive or both.

An example QC Summary report
This report tabulates all completed Test List Instances from a given time period for selected sites, units, frequencies, and groups.
The filters available for this report are:
- Work Completed (required)
- Select the period you want to include Test List Instances from.
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Frequency (optional)
- Filter your results to those scheduled with a specific frequency (e.g. Monthly).
- Assigned To (optional)
- Filter your results to those assigned to a specific group.

An example Test List Instance Details report
This report includes details for all Test List Instances from a given time period for a given Unit Test List (Cycle) assignment.
The filters available for this report are:
- Work Completed (required)
- Select the period you want to include Test List Instances from.
- Test List (Cycle) Assignment (required)
- Select the Test List Unit Assignments that you want to include in this report.

An example Test Instance Details report
This report shows QC test values for selected tests/units.
The filters available for this report are:
- Work Completed (required)
- Select the period you want to include Test values from
- Test (required)
- Select the test you want to generate a report for
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Organization (required)
Select how you want your results organized.
- One Test Instance Per Row: Only include a single value per row in the spreadsheet
- Group rows by tests that are performed on the same unit, on the same date.

An example QC Paper Backup Forms Report
This report generates a PDF containing paper backup forms that can be used to record QC values in the case that your QATrack+ installation is unavailable.
The filters available for this report are:
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Frequency (optional)
- Filter your results to those scheduled with a specific frequency (e.g. Monthly).
- Assigned To (optional)
- Filter your results to those assigned to a specific group.
- Active (optional)
- Select whether you want to include assignments which are active, inactive or both.

An example Next Due Dates report
This report shows QC tests whose next due date fall in the selected (future) time period.
The filters available for this report are:

An example Due & Overdue report
This report shows QC tests which are currently due and overdue.
The filters available for this report are:

An example Service Event Summary report
This report summarizes the Service Events logged for selected Sites & Units in a given time period.
The filters available for this report are:
- Service Date (required)
- Select the period you want to include Service Events from.
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Service Type (optional)
- Filter your results to one or more Service Types’s.
- Service Area (optional)
- Filter your results to one or more Service Areas’s.

An example Service Event Details report
This report provides details for the Service Events logged for selected Sites & Units in a given time period.
The filters available for this report are:
- Service Date (required)
- Select the period you want to include Service Events from.
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Service Type (optional)
- Filter your results to one or more Service Types’s.
- Service Area (optional)
- Filter your results to one or more Service Areas’s.

An example Service Event Personnel report
This report summarizes the people involved in Service Events logged for selected Sites & Units over a given time period.
The filters available for this report are:
- Service Date (required)
- Select the period you want to include Service Events from.
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Service Type (optional)
- Filter your results to one or more Service Types’s.
- Service Area (optional)
- Filter your results to one or more Service Areas’s.
This report lists all scheduled service event templates currently assigned for the selected sites, units, frequencies and groups.
The filters available for this report are:
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Frequency (optional)
- Filter your results to those scheduled with a specific frequency (e.g. Monthly).
- Assigned To (optional)
- Filter your results to those assigned to a specific group.
- Active (optional)
- Select whether you want to include assignments which are active, inactive or both.

An example Service Event Times report
This report summarizes the service time, lost time, and uptime percentages for selected Sites & Units over a given time period.
The filters available for this report are:
- Service Date (required)
- Select the period you want to include Service Events from.
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Service Type (optional)
- Filter your results to one or more Service Types’s. (Note if you filter by Service Type, overall uptime percentages can not be calculated)
- Service Area (optional)
- Filter your results to one or more Service Areas’s. (Note if you filter by Service Areas, overall uptime percentages can not be calculated)
This report shows QC tests whose next due date fall in the selected (future) time period.
The filters available for this report are:
- Time Period (required)
- Select the period you want to include due dates for.
- Assigned To (optional)
- Filter your results to those assigned to a specific group.
- Site (optional)
- Filter your results to one or more Site’s.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Frequency (optional)
- Filter your results to those scheduled with a specific frequency (e.g. Monthly).
- Active (optional)
- Select whether you want to include assignments which are active, inactive or both.
This report shows Scheduled Service Events which are currently due and overdue.
The filters available for this report are:
- Site (optional)
- Filter your results to one or more Site’s. select them here.
- Unit (optional)
- Filter your results to one or more Unit’s.
- Service Area (optional):
- Filter your results to one or more Service Areas’s.
- Assigned To (optional)
- Filter your results to those assigned to a specific group.
- Active (optional)
- Select whether you want to include assignments which are active, inactive or both.
Query Tool¶
Warning
In order to use SQL Reports, your site administrator must have set up a read-only database user, and configured QATrack+ to use this read-only user in it’s DATABASES setting.
You must also set USE_SQL_REPORTS = True in your local_settings.py file. If you are using SQL Server your readonly database options may also need to set AUTOCOMMIT = False.
As of version 3.1.0 QATrack+ has a tool for creating, running, and storing SQL database queries/reports. To access the tool, select the Query Tool option from the Trends & Analysis menu.
From this main query tool page, you can select an existing query to run, or create a new one using the New Query or Playground links in the sidebar.
Permissions Required¶
Currently, to access this tool a user must have the “Can Run SQL Reports” or “Can Create SQL Reports” permission set on their account.
Creating a new Query¶
Note
If you want to run ad-hoc queries or develop a new query, you can use the Playground area to run queries without saving them to the database for later use.
Give your query a title and description and then write your query in the SQL text area:

Creating a new database query
Once you have written your query you can click Save & Run to generate your query. This will save the query for later use and run it now placing the results at the bottom of the page:

Results from running a DB query
To add a configurable parameter to use in the query add a symbol like $$your_param_name$$ to your query. For each parameter an input box will be added to configure the query. You can use $$your_param_name:default_value$$ to have a default value filled in:

Adding query parameters
Exporting the query¶
If you would like to download your data, simply use the drop down on the Save & Run button to export your data to CSV, Excel, or JSON format.

Download results from a database query
Viewing the DB Schema¶
You can view the database tables and columns available by clicking on the Show Schema button. A full database diagram is also available in the developer documents: Database Schema.
Pivot Tables¶
After running a query you can click on the Pivot link at the top of the results table to generate a pivot table for aggregating and summarizing the data. Note the link at the top right can be shared with others to link directly to this pivot table.

Pivot table results from a database query
Deleting a Query¶
In order to delete a query, navigate to the Saved Queries page and click the trash can icon next to the query.

Deleting a saved query
Using the QATrack+ API¶
As of version 0.3.0 QATrack+ now includes a JSON API for accessing or uploading data using external scripts/programs. The primary intent of this API is to allow users to write their own applications for automating the completion of test lists. For example, you may want to write a script that runs every day (via a cron job or Windows Task Scheduler) which retrieves data from a hardware device used for daily output measurements and then uploads that data to QATrack+.
You are free to use any language which is capable of parsing/serializing JSON and making requests via http(s) but the examples below will use Python 3.x and the requests library.
Getting an API Token¶
Every application/script that accesses the API requires an authentication token which is connected to a QATrack+ user. You can either set up a new user in QATrack+ specifically for API access, or use an existing username/password.
To retrieve an API token you need to make a request similar to the following:
import requests
root = "http://yourservernamehere/api"
token_url = root + "/get-token/"
resp = requests.post(token_url, {'username': 'user', 'password': 'password'})
token = resp.json()['token']
Once you have retrieved the API token you must include it with every API request as an HTTP Authorization header with the value Token your-token-here. For example:
headers = {"Authorization": "Token %s" % token}
resp = requests.get(api, headers=headers)
Note, you can also create an API token in the QATrack+ admin section by going to /admin/authtoken/token and clicking Add Token:

and then selecting the user you want to create the token for and clicking Save:

Viewing the API online¶
In addition to the JSON API, the QATrack+ is browsable via a web browser by visiting /api:

The API schema including all endpoints is also available at the /api/schema/ endpoint:
resp = requests.get(root + '/schema', headers=headers)
print(resp.json())
Retrieving Data¶
In order to retrieve data from the API you need to make a request to the relevant API endpoint which is demonstrated for a number of cases below:
Getting a list of available units¶
resp = requests.get(root + '/units/units', headers=headers)
print(resp.json())
# results in data like:
{
'count': 18,
'next': None,
'previous': None,
'results': [
{
'active': True,
'date_acceptance': '2018-01-01',
'install_date': None,
'is_serviceable': False,
'location': '',
'modalities': [
'http://127.0.0.1:8081/api/units/modalities/1/',
'http://127.0.0.1:8081/api/units/modalities/2/'
],
'name': 'Unit 1',
'number': 1,
'restricted': False,
'serial_number': '',
'site': None,
'type': 'http://127.0.0.1:8081/api/units/unittypes/7/',
'url': 'http://127.0.0.1:8081/api/units/units/5/'
},
{...}
]
}
Getting a specific units details¶
resp = requests.get(root + '/units/units/1', headers=headers)
print(resp.json())
# results in data like:
{
'active': True,
'date_acceptance': '2018-01-01',
'install_date': None,
'is_serviceable': False,
'location': 'TBCC',
'modalities': ['http://127.0.0.1:8081/api/units/modalities/1/'],
'name': 'Unit 3',
'number': 3,
'restricted': False,
'serial_number': '799',
'site': None,
'type': 'http://127.0.0.1:8081/api/units/unittypes/7/',
'url': 'http://127.0.0.1:8081/api/units/units/1/'
}
Getting a list of Test Lists¶
resp = requests.get(root + '/qa/testlists', headers=headers)
print(resp.json())
# results in data like:
{
'count': 145,
'next': 'http://127.0.0.1:8081/api/qa/testlists/?limit=100&offset=100',
'previous': None,
'results': [
{
'created': '2014-05-30T16:11:05-04:00',
'created_by': 'http://127.0.0.1:8081/api/auth/users/9/',
'description': '',
'javascript': None,
'modified': '2014-07-24T13:59:43-04:00',
'modified_by': 'http://127.0.0.1:8081/api/auth/users/9/',
'name': 'Accessory inspection',
'slug': 'accessory-inspection',
'tests': ['http://127.0.0.1:8081/api/qa/tests/104/',
'http://127.0.0.1:8081/api/qa/tests/105/'],
'url': 'http://127.0.0.1:8081/api/qa/testlists/6/',
'warning_message': 'Do not treat'
},
{...}
]
}
Getting a specific test lists details¶
resp = requests.get(root + '/qa/testlists/1', headers=headers)
print(resp.json())
# results in data like:
{
'created': '2014-05-30T16:11:05-04:00',
'created_by': 'http://127.0.0.1:8081/api/auth/users/9/',
'description': '',
'javascript': None,
'modified': '2014-07-24T13:59:43-04:00',
'modified_by': 'http://127.0.0.1:8081/api/auth/users/9/',
'name': 'Accessory inspection',
'slug': 'accessory-inspection',
'tests': ['http://127.0.0.1:8081/api/qa/tests/104/',
'http://127.0.0.1:8081/api/qa/tests/105/'],
'url': 'http://127.0.0.1:8081/api/qa/testlists/6/',
'warning_message': 'Do not treat'
}
Pagination of data¶
When requesting data from the API, by default you will get up to 100 results per request. You can change the page and page size by using the limit/offset query parameters. For example to retrieve the first two pages of data with 10 results per page:
page1 = requests.get(root + '/qa/testlists/?limit=10&offset=0', headers=headers)
page2 = requests.get(root + '/qa/testlists/?limit=10&offset=10', headers=headers)
# or alternatively
page2 = requests.get(page1.json()['next'], headers=headers)
page3 = requests.get(page2.json()['next'], headers=headers)
To process results in a loop:
page = requests.get(root + '/qa/testlists/?limit=10&offset=0', headers=headers)
while page.json()['next']:
page = requests.get(page.json()['next'], headers=headers)
# do something with page data
Filtering and Ordering data¶
Data retrieved from the API can also be filtered so that only a subset of available results are included. For example, to retrieve all tests lists whose name contains the phrase “Sim”:
resp = requests.get(root + '/qa/testlists/?name__contains=Sim', headers=headers)
The filtering can also cross foreign key references. As an example, to find all UnitTestCollections whose Unit name is “Unit 1”:
resp = requests.get(root + '/qa/unittestcollections/?unit__name__icontains=Unit 1', headers=headers)
Here’s an example of getting Test Instance data for a specific Test and Unit:
url = root + '/qa/testinstances/'
params = {
"unit_test_info__unit__name__icontains": "Unit Name",
"unit_test_info__test__name__icontains": "Test Name",
"ordering": "-work_completed",
}
resp = requests.get(url, params, headers=headers)
payload = resp.json()
data = [(x['work_completed'], x['value']) for x in payload['results']]
Note the use of a dictionary of GET parameters here rather than placing them in the url directly. Both methods are more or less equivalent. This example also demonstrates how to order the data from your request using the ordering key.
QATrack+ uses Django-Rest-Framework-Filters for it’s filtering so more information about the filtering tools available an be found in DRFF’s documentation.
Uploading Data¶
The real power of the API is the ability to complete TestLists programatically. In order to demonstrate the API, we will submit two number entries via the API to perform a test list that adds two numbers together shown here:

A script that will find the above test list, and submit the data is shown here:
import requests
root = "http://yourservernamehere/api"
token_url = root + "/get-token/"
resp = requests.post(token_url, {'username': 'user', 'password': 'password'})
token = resp.json()['token']
headers = {"Authorization": "Token %s" % token}
# first find the UnitTestCollection we want to perform
resp = requests.get(root + '/qa/unittestcollections/?unit__name__icontains=Unit 1&test_list__name__icontains=Simple API Example', headers=headers)
utc_url = resp.json()['results'][0]['url']
# prepare the data to submit to the API. Notice you don't need to submit a value for
# sum_of_two since it is calculated from number_1 and number_2
data = {
'unit_test_collection': utc_url,
'day': 0, # optional day=0, for TestLists, required for Test List Cycles (where 0 <= day < # of test lists in cycle)
'in_progress': False, # optional, default is False
'include_for_scheduling': True,
'work_started': "2018-07-6 10:00",
'work_completed': "2018-07-6 11:00", # optional
'user_key': "12345", # optional, allows you ensure uniqueness of results
'comment': "test list comment", # optional
'tests': {
'number_1': {'value': 1, 'comment': "hello number 1"}, # comment is optional
'number_2': {'value': 2, 'skipped': False}, # value is mandatory, skipped is optional
},
'attachments': [] # optional
}
resp = requests.post(root + "/qa/testlistinstances/", json=data, headers=headers)
print(resp.json())
# data returned from the API
{
'all_reviewed': False, [11/8824]
'created_by': 'http://127.0.0.1:8081/api/auth/users/65/',
'day': 0,
'due_date': None,
'in_progress': False,
'include_for_scheduling': True,
'reviewed': None,
'reviewed_by': None,
'site_url': 'http://127.0.0.1:8081/qa/session/details/2991/',
'test_list': 'http://127.0.0.1:8081/api/qa/testlists/206/',
'unit_test_collection': 'http://127.0.0.1:8081/api/qa/unittestcollections/327/',
'url': 'http://127.0.0.1:8081/api/qa/testlistinstances/2991/',
'work_completed': '2018-07-06T11:00:00-04:00',
'work_started': '2018-07-06T10:00:00-04:00'
'tests': {
'number_1': {
'attachments': [],
'comment': 'hello number 1',
'diff_display': '',
'pass_fail': ['no_tol', 'No Tol Set'],
'reference': None,
'skipped': False,
'status': '/api/qa/testinstancestatus/1/',
'string_value': '',
'tolerance': None,
'url': '/api/qa/testinstances/19317/',
'value': 1.0,
'value_display': '1'
},
'number_2': {
'attachments': [],
'comment': '',
'diff_display': '',
'pass_fail': ['no_tol', 'No Tol Set'],
'reference': None,
'skipped': False,
'status': '/api/qa/testinstancestatus/1/',
'string_value': '',
'tolerance': None,
'url': '/api/qa/testinstances/19318/',
'value': 2.0,
'value_display': '2'
},
'sum_of_two': {
'attachments': [],
'comment': '',
'diff_display': '',
'pass_fail': ['no_tol', 'No Tol Set'],
'reference': None,
'skipped': False,
'status': '/api/qa/testinstancestatus/1/',
'string_value': '',
'tolerance': None,
'url': '/api/qa/testinstances/19319/',
'value': 3.0,
'value_display': '3'
}
},
}
A few things to note:
Some fields like comment, in_progress, include_for_scheduling, and attachments are optional
The tests key is a dictionary of the form (skipped and comment keys are optional):
{ 'macro_name_1': {'value': <value>, 'skipped': True|False, 'comment': 'comment'}, 'macro_name_2': {...} }
You don’t need to submit data for sum_of_two since it is a composite test and calculated automatically.
The url key contains the hyperlink where you can view the completed TestListInstance online.
Performing A Test List Cycle¶
In order to perform a Test List Cycle you must include a day key in your upload data. The day key is a 0-indexed integer indicating which day of the test list cycle you want to perform (e.g. if you want to perform day 1, you would use ‘day’: 0, and if you want to perform day 2, you would use ‘day’: 1).
Example data to perform day 2 of a test list cycle would look something like:
data = {
'unit_test_collection': utc_url,
'day': 1, # note 0-indexed days so we use 1 for day 2
'work_started': "2018-07-6 10:00",
'work_completed': "2018-07-6 11:00", # optional
'tests': {
...
},
}
Upload test types¶
In order to perform a test list that includes a File Upload test type, your test values should be a dictionary of the form {‘filename’: ‘some-file.name’, ‘value’: ‘file contents’, ‘encoding’: ‘text’|’base64’}. For example:
data = {
...
'tests': {
...
'upload_text_test': {
'filename': 'test.txt',
'value': 'hello text', # or e.g. open("text_file.txt", "r").read()
'encoding': 'text'
},
'upload_binary_test': {
'filename': 'image.png',
'value': base64.b64encode(open("path/to/image.png", 'rb').read()).decode(),
'encoding': 'base64'
},
}
}
Note that binary files must be base64 encoded!
Attachments¶
Similar to File Upload test types, you can add arbitrary attachments to your TestListInstance in the following way:
data = {
...
'tests': {
...
}
"attachments": [
{
'filename': 'some_report.pdf',
'value': base64.b64encode(open("/path/to/some_report.pdf", 'rb').read()).decode(),
'encoding': 'base64'
},
],
}
Preventing Duplicate Entries with the user_key field¶
When uploading data in an automated fashion via the API, you may want to ensure that your script or program is not uploading the same data twice. To facilitate this, the TestListInstance API allows you to specify a unique “User Key”. The User Key has a uniqueness constraint enforced at the database level and posting data with a duplicated user_key will result in an HTTP 400 error code with a message “test list instance with this user key already exists”. To set the user_key for a test list instance include a unique identifier with your json data.
data = {
'unit_test_collection': utc_url,
...
'user_key': "some unique identifier", # optional, allows you ensure uniqueness of results
'tests': {
...
},
}
How you choose the user_key is up to you but it is stored as a text field with a maximum length of 255 characters. Examples of user_key’s might be:
A Test List Name and Database Row ID: “Test List Name: 1234”
A Test List Name, Unit Name, and Timestamp: “SomeTestListName:Unit 123:2021-03-16 12:34”
An MD5 hash of a file:
import hashlib user_key = hashlib.md5(open("some-file.dcm", "rb").read()).hexdigest()
FAQ¶
Q: My site is using https and Apache. Why is token authentication not working?: You need to add
# this can go in either server config, virtual host, directory or .htaccess WSGIPassAuthorization On
to your Apache config. See: http://www.django-rest-framework.org/api-guide/authentication/#apache-mod_wsgi-specific-configuration for more details.
Q: Why is the API returning status 403 with {‘detail’: ‘You do not have permission to perform this action’}?: The user you are submitting your data with does not have permission to perform QA. Add the user to a group with the required permissions.
Q: Why is the API returning status 401 with {‘detail’: ‘Authentication credentials not provided’}?: You forgot to include the authorization token http header with your request.
Q: Why is the API returning status 401 with {‘detail’: ‘Invalid token’}?: You included an invalid authorization token http header with your request. Check to ensure your auth token is set correctly.
API Tutorial Example¶
There is a tutorial on uploading image data for analysis via pylinac available here: Image Analysis Using pylinac and the QATrack+ API.
Developers Guide¶
QATrack+ v0.3.0 Database Schema¶
Below you will find a database schema diagram for v0.3.0 of QATrack+.
The QATrack+ v0.3.0 schema (click to view full size or right click and view in new tab to view full size)
Generating the schema diagram¶
Ubuntu¶
On Ubuntu (tested on 18.04) you need to install a few dependencies before generating the schema diagram:
sudo apt install python-dev graphviz libgraphviz-dev pkg-config
pip install pygraphviz
and then you can generate your schema with:
make schema
which will output the schema to docs/developer/images/qatrack_schema_$(VERSION).svg
Windows¶
It is also possible to generate a schema diagram on Windows using Sql Server Management Studio. See https://dataedo.com/kb/tools/ssms/create-database-diagram for instructions on making a diagram with SSMS.
Schema for Older Versions¶
Database diagrams for older versions of QATrack+ are available on BitBucket: Schema diagrams.
Installing QATrack+ For Development¶
Due to the huge volume of tutorials already written on developing software using Python, Django, and git, only a brief high level overview of getting started developing for the QATrack+ project will be given here. That said, there are lots of steps involved which can be intimidating to newcomers (especially git!). Try not to get discouraged and if you get stuck on anything or have questions about using git or contributing code then please post to the mailing list so we can help you out!
In order to develop for QATrack+ you first need to make sure you have a few requirements installed.
Python 3.6+¶
QATrack+ is developed using Python 3 (Python 3.6-3.9). Depending on your operating system, Python 3 may already be installed but if not you can find instructions for installing the proper version on https://python.org.
Git¶
QATrack+ uses the git version control system. While it is possible to download and modify QATrack+ without git, if you want to contribute code back to the QATrack+ project, or keep track of your changes, you will need to learn about git.
You can download and install git from https://git-scm.com. After you have git installed it is recommended you go through a git tutorial to learn about git branches, commiting code and pull requests. There are many tutorials available online including a tutorial by the Django team as well as a tutorial on and GitHub.
GitHub¶
The QATrack+ project currently uses GitHub for hosting its source code repository. In general, to contribute code to QATrack+ you will need to create a fork of QATrack+ on GitHub, make your changes, then make a pull request to the main QATrack+ project.
Creating a fork of QATrack+¶
Creating a fork of QATrack+ is explained in the GitHub documentation.
Cloning your fork to your local system¶
Once you have created a fork of QATrack+ on GitHub, you will want to download your fork to your local system to work on. This can either be done using the command line or one of the graphical git apps that are available. This page assumes you are using bash on linux or the Git Bash shell on Windows.
Setting up your development environment¶
In order to keep your QATrack+ development environment separate from your system Python installation, you will want to set up a virtual environment to install QATrack+’s Python dependencies in it. Using the command line change to the directory where you installed QATrack+, create a new virtual environment, and activate the virtual environment:
cd /path/to/qatrackplus
python3 -m venv env
source env/bin/activate
Then install the development libraries:
pip install -r requirements/dev.txt
Creating your development database¶
Rather than using a full blown database server for development work, You can use Sqlite3 which is included with Python.
Once you have the requirements installed, copy the debug local_settings.py file from the deploy subdirectory and then create your database:
cp deploy/local_settings.dev.py qatrack/local_settings.py
mkdir db
python manage.py migrate
this will put a database called default.db in the db subdirectory.
Running the development server¶
After the database is created, create a super user so you can log into QATrack+:
python manage.py createsuperuser
and then run the development server:
python manage.py runserver
Once the development server is running you should be able to visit http://127.0.0.1/ in your browser and log into QATrack+.
Next Steps¶
Now that you have the development server running, you are ready to begin modifying the code! If you have never used Django before it is highly recommended that you go through the official Django tutorial which is an excellent introduction to writing Django applications.
Once you are happy with your modifications, commit them to your source code repository, push your changes back to your online repository and make a pull request! If those terms mean nothing to you…read a git tutorial!
QATrack+ Development Guidelines¶
The following lists some guidelines to keep in mind when developing for QATrack+.
Internationalization & Translation¶
Please mark all strings and templates in QATrack+ for translation. This will allow for QATrack+ to be made avaialable in multiple languages. For discussion of how to mark templates and strings for translation please read the Django docs on translation.
Tool Tips And User Hints¶
Where possible all links, buttons and other “actionable” items should have a tooltip (via a title attribute or using one of the bootstrap tool tip libraries) which provides a concise description of what clicking the item will do. For example:
<a class="..."
title="Click this link to perform XYZ"
href="..."
>
Foo
</a>
Other areas where tooltips are very useful is e.g. badges and labels where wording is abbreviated for display. For example:
<i class="fa fa-badge" title="There are 7 widgets for review">7<i>
<span title="This X has Y and Z for T">Foo baz qux</span>
Formatting & Style Guide¶
General formatting¶
In general, any code you write should be PEP 8 compatible with a few exceptions. It is highly recommended that you use flake8 to check your code for pep8 violations. A QATrack+ flake8 config file is included with QATrack+, to view any flake8 violations run:
make flake8
# or
flake8 .
You may also want to use yapf which can automatically format your code to conform with QATrack+’s style guide. A yapf configuration sections is included in the setup.cfg file. To run yapf:
make yapf
Import Order¶
Imports in your Python code should be split in three sections:
- Standard library imports
- Third party imports
- QATrack+ specific imports
and each section should be in alphabetical order. For example:
import math
import re
import sys
from django.apps import apps
from django.conf import settings
from django.contrib.auth.models import Group, User
from django.contrib.contenttypes.fields import (
GenericForeignKey,
GenericRelation,
)
from django_comments.models import Comment
import matplotlib
from matplotlib.backends.backend_agg import FigureCanvasAgg
import numpy
import scipy
from qatrack.qa import utils
from qatrack.units.models import Unit
isort is a simple tool for automatically ordering your imports and an isort configuration is included in the setup.cfg file.
Indentation¶
Python code for QATrack+ use 4 spaces for indentation. Django templates (and other html files) should use 2 spaces for indentation. Javascript code should use 4 spaces for indentation.
Running The Test Suite¶
Once you have QATrack+ and its dependencies installed you can run the test suite from the root QATrack+ directory using the py.test command:
./qatrackplus> py.test
Test session starts (platform: linux, Python 3.6.5, pytest 3.5.0, pytest-sugar 0.9.1)
Django settings: qatrack.settings (from ini file)
rootdir: /home/randlet/projects/qatrack/qatrackplus, inifile: pytest.ini
plugins: sugar-0.9.1, django-3.1.2, cov-2.5.1
qatrack/accounts/tests.py ✓✓✓
For more information on using py.test, refer to the py.test documentation.
Important
All new code you write should have tests written for it. Any non trivial code you wish to contribute back to QATrack+ will require you to write tests for the code providing as high a code coverage as possible. You can measure code coverage in the following way:
make cover
Writing Documentation¶
As well as writing tests for your new code, it will be extremely helpful for you to include documenation for the features you have built. The documentation for QATrack+ is located in the docs/ folder and is seperated into the following sections:
- User guide: Documentation for normal users of the QATrack+ installation.
- Admin guide: Documentation for users of QATrack+ who are responsible for configuring and maintaining Test Lists, Units etc.
- Tutorials: Complete examples of how to make use of QATrack+ features.
- Install: Documentation for the people responsible for installing, upgrading, and otherwise maintaining the QATrack+ server.
- Developers guide: You are reading it :)
Please browse through the docs and decide where is the most appropriate place to document your new feature.
While writing documentation, you can view the documentation locally in your web browser (at http://127.0.0.1:8008) by running one of the following commands:
make docs-autobuild
# -or-
sphinx-autobuild docs docs/_build/html -p 8008
Copyright & Licensing¶
The author of the code (or potentially their employer) retains the copyright of their work even when contributing code to QATrack+. However, unless specified otherwies, by submitting code to the QATrack+ project you agree to have it distributed using the same MIT license as QATrack+ uses.
I’m not a developer, how can I help out?¶
Not everyone has development experience or the desire to contribute code to QATrack+ but still wants to help the project out. Here are a couple of ways that you can contribute to the QATrack+ project without doing any software development:
- Translations: Starting in QATrack+ v3.1.0 (sorry this didn’t happen yet), QATrack+ will have the infrastructure in place to support languages other than English. We will be making translation files available so that the community can create translation files for their native languages. Please get in touch with randy@multileaf.ca if you are able to help out with this task!
- Tutorials: Tutorials are a great way for newcomers to learn their way around QATrack+. If you have an idea for a tutorial, we would love to include it in our tutorials section!
- Mailing List: QATrack+ has a mailing list which QATrack+ users and administrators may find useful for getting support and discussing bugs and/or features. Join the list and chime in!
- Spread the word: The QATrack+ community has grown primarily through word of mouth. Please let others know about QATrack+ when discussing QA/QC software :)
- Other: Have any ideas for acquiring development funding for the QATrack+ project? We’d love to hear them!
Tutorials¶
Setting up, performing, and reviewing your first test list step-by-step¶
This guide will take you through:
- Logging in and accessing the admin interface
- Changing the name displayed at the top of your QATrack+ website
- Creating a new Unit
- Creating different user groups
- Configuring test statuses
- Setting up a test list for performing a linac output measurement,
- Assigning the test list to a unit
- Setting references and tolerances for your tests.
- Setting references and tolerances for your tests.
- Performing the Test List
- Reviewing the Test List Instance
This tutorial assumes your website administrator has QATrack+ configured and running on a server somewhere and has assigned you a username/password with superuser status.
Logging in and accessing the admin interface¶
Access the url for QATrack+ (your website adminstrator should have provided you with a URL) in your favourite web browser. QATrack+ looks and works best with Chrome or Firefox but Internet Explorer versions 11 and up are also supported.
If you are not already logged in, you will be taken to the login page:

The QATrack+ login screen
enter your username and password and click the Log In button.
After logging in, you should see a screen similar to the one below:

QATrack+ home screen
Click the little dropdown arrow next to your name in the top right hand corner, and then select the Admin option from the dropdown menu.

Accessing the QATrack+ admin section
This wll take you to the main admin page where you will be doing all of your QATrack+ configuration.
Setting up the name of your QATrack+ website¶
As you may have noticed in earlier screen shots, the words “example.com” are displayed at the top of your website. Let’s change that to “Your Hospital Name”.
From the main admin page find the Websites section and click on the Websites link.

Sites section of the admin
Click on the example.com entry under the Domain name column header.

The example.com site object
and then set the relevant fields (ask your admin if you’re not sure of the domain name to use) and click Save when you’re finished.

Setting the website name
If you now return to the main site (at any time you can click the QATrack+ administration header at the top of the admin pages to return to the main QATrack+ site) you should see your site now says Your Hospital Name+ at the top rather than example.com.

Changed site name
In the next step of this tutorial we will configure a new Unit.
Creating a new Unit¶
In order to prevent duplicating information here, please follow the instructions in the Units administration docs to create a new Unit before continuing.
Creating a New User Group¶
After you’ve created your Unit, return to the main admin page and click on the Groups link under the Auth section and then click the Add group button in the top right.
Set the Name field to Physics and choose the following set of permissions:
- attachments | attachment | Can add attachment
- qa | frequency | Choose QC by Frequency
- qa | test instance | Can review & approve tests
- qa | test instance | Can review & approve self-performed tests
- qa | test instance | Can skip tests without comment
- qa | test instance | Can view charts of test history
- qa | test instance | Can see test history when performing QC
- qa | test list instance | Can add test list instance
- qa | test list instance | Can override date
- qa | test list instance | Can perform subset of tests
- qa | test list instance | Can save test lists as ‘In Progress’
- qa | test list instance | Can view previously completed instances
- qa | test list instance | Can change test list instance
- qa | unit test collection | Can view tli and utc not visible to user’s groups
- qa | unit test collection | Can view program overview
- qa | unit test info | Can view Refs and Tols
- service_log | return to service qa | Can add return to service qa
- service_log | return to service qa | Can perform return to service qa
- service_log | return to service qa | Can view return to service qa
- service_log | service event | Can add service event
- service_log | service event | Can review service event
- service_log | service event | Can view service event
- units | unit available time | Can change unit available time
- units | unit available time edit | Can add unit available time edit
- units | unit available time edit | Can change unit available time edit
Your group should look like the following:

Defining a physics group
Click Save and you will now see your new group in the listings page.

Group listings
The last step for this section is to add yourself to the Physics group. Visit your user profile by going to the Users section under the Auth section and clicking on your username.

Choose a user to edit
On the next page find the Groups field and add Physics to the Chosen Groups list.

selecting a group
Click on Save to finalize the addition of yourself to the Physics group.
Creating Test Statuses¶
We are next going to create two test statuses; first an Unreviewed status which will be the default Test Instance Status given to test data when they are performed and second an Approved status that can be applied to the tests after they have been reviewed.
From the main admin page click on the Statuses link under the QC section and click the Add test instance status button in the top right.
Give the status a Name of Unreviewed, a Slug of unreviewed and a description of Default status for tests which have just been completed.. Next, check off the Is default checkbox and then click Save and add another.

Unreviewed status
Create an Approved status similar to the Unreviewed status but this time leave the Is default box unchecked and also uncheck the Requires review checkbox. You should also select a new colour for the status (e.g. green for Approved). Click Save when you’re finished.

Approved status
And finally create a Rejected status similar to the Unreviewed status but this time leave the Is default box unchecked and also uncheck the Requires review and Is Valid checkboxex. You should also select a new colour for the status (e.g. red for Rejected). Click Save when you’re finished.

Rejected status
You should now see your three statuses in the listing.

Test status listings
Now that we have done the initial configuration we can begin to cover test and test list configuration.
Creating a new Test List¶
Creating the required Tests¶
In this part of the tutorial we will create the tests required to calculate a dose. This will demonstrate a number of different test types including composite calculations.
In order to calculate dose we need to create 6 tests (k_Q and Other corrections such as P_pol, P_ion etc are ignored for simplicity):
- Temperature (numerical test)
- Pressure (numerical test)
- Temperature-pressure correction (Ftp - a composite calculation)
- Ion chamber reading (numerical test)
- Ndw for converting our ion chamber reading to dose (constant value)
- Dose (the final result we are interested in - a composite calculation)
To create the tests, visit the Tests link under the QC section from the main admin page and then click on Add test in the top right hand corner.
Give our first test the name Temperature °C and the macro name of temperature. We will leave the description blank for now.
Since we haven’t created any [categories](../categories.md) yet we will do so now. Click the green cross next to the Category: drop down and create a Dosimetry category.

creating a dosimetry category
For the Type field choose Simple Numerical, indicating that this test will require the user to enter a number. You may also check the Allow auto review of this test? checkbox if you intend to use auto review.

Full temperature test
Click Save and add another when you are done.
Follow the same procedure define 1) a Pressure (mmHg) test ensuring that you use the macro name pressure (You can use the Dosimetry category we created earlier for the pressure and all of the remaining tests), and 2) an Ion Chamber Reading (nC) test using the macro name reading.
Next we will create our first composite test for our temperature pressure correction. Give this test a name of Temperature-Pressure Correction and a macro name of p_tp. From the Type: dropdown select Composite and you will notice that a new Calculation Procedure text box will appear below. In that text box enter the following Python snippet:
p_tp = (temperature + 273.15)/295.15*760/pressure
Note here that we used the macro names temperature and pressure from our previously defined tests to define how our Temperature Pressure Correction test result will be calculated.

P_TP calculation
When you are finished, click Save and add another. Define a test called N_DW with the macro name n_dw. This time choose a Type of Constant and enter a value of 0.05 in the Constant value field that appears.

N_DW
Once that is finished we will add our final test for calculating dose. Create a composite test with the name Dose, the macro name dose and a calculation procedure defined as:
corrected_reading = reading*p_tp dose = n_dw*corrected_reading

dose test
Note
Note that the dose calculation is a composite test based on a previous composite result (p_tp). QATrack+ has a dependency resolution system to allow this sort of composite-of-composite type calculations.
Once that is complete click on Save which will take you back to the test listings. If all the steps have been completed correctly you should see 6 tests listed:

Test listings for dose calculations
In the next step of the tutorial we will group these tests into a test list.
Creating the Test List¶
To create the test list, visit the Test Lists link under the QC section from the main admin page and then click on Add test list in the top right hand corner.
Give the test list the name Machine Output and slug machine-output. We will ignore the description fields for now.
Under the Test List Members section click on green cross / Add another Test list membership link at the bottom to make a 6th Test text box appear (you can ignore the Sublist text box, it allows you to include other Test Lists within a parent Test List). Now click the first magnifying glass and click on the Temperature test in the window that pops up:

Selecting a test
Repeat this step for the other 5 tests we defined at which point the Test list memberships section should look like:

Test list memberships
Now click Save and that’s it! Now that we’ve created our tests and test list we can assign it to the unit we created earlier. This is covered in the next step of this tutorial.
Assigning the test list¶
In this part of the tutorial we will assign our test list to a unit and ensure that it is functioning correctly on the main site.
To assign the test list to a unit, visit the Assign Test Lists to Units link under the QC section from the main admin page and then click on Add unit test collection in the top right hand corner.
Select the Test Unit from the Unit: dropdown, and then create a new [frequency](../frequencies) by clicking on the green cross next to the Frequency dropdown. Give the frequency the name Monthly, slug monthly and enter 28, 28, 35 for Nominal interval, Due Interval and for Overdue interval, respectively.

creating a new frequency
Select the Physics option from the Assigned to: dropdown and add the Physics group to the Visible to section.
Next select test list from the Test List or Test List Cycle dropdown. After selecting test list you will be able to select Machine Output from the Tests collection dropdown.

Assigning to a unit
When you’re finished click Save. We can now set a reference and tolerance value for the dose calculated by our Test List.
To assign the test list to a unit, visit the Set References and Tolerances link under the QC section from the main admin page and then click on the Dose link for the Test Unit.
Create a new Tolerance by clicking the green cross beside the Tolerance field. Select Percentage for the Type and set Action Low = -3, Tolerance Low = -2, Tolerance High = 2, and Action High = 3 and then click Save. This will create a Tolerance which signals the user if a test is outside of tolerance (2%) or action (3%) levels relative to the reference value.

Creating a new tolerance
Set the New reference value to 1 and then click Save. We are now ready to perform the test list.
Performing the Test List¶
Visit the main site (you can click the QATrack+ administration header at the top of the admin page) and select the Choose Unit link from the Perform QC dropdown at the top of the page. On the next page choose the Monthly option from the Test Unit drop down.

Choosing Monthly
On the next page click Perform beside the Machine Output test list.

Monthly test listings
You should now see the test list you defined:

Final test list
Fill in sample values of :
- Temperature = 24
- Pressure = 760
- Ion Chamber Reading = 20.2
And you should see the Temperature-Pressure Correction and Dose values calculated as 1.007 and 1.017 respectively. The Status column next to Dose should indicate the Test is within tolerance.

Calculated results
Notice that the Status for all the other tests all show No Tol Set. This is because we haven’t set reference values and tolerance/action levels for these tests. For more information on Reference & Tolerance values see here.
You may now click Submit QC Results and you will be returned to the previous page. You should notice at the top of the page that there is now an indication that there is 1 unreviewed Test List Instance:

Visual indicators of review queue
Reviewing the Data¶
Periodically whoever is responsible for ensuring QC has been completed satisfactorily should go through all unreviewed Test List Instances and update their status to either Approved or Rejected (note rejected is to be used if a Test was performed incorrectly, not if it was performed correctly but failing).
Select the Unreviewed - All Groups menu item from the Review Data menu and then click Review beside the Test List Instance we just performed:

Unreviewed Test Lists
On the next page you will see details of the Test List Instance. Select the Approved status from the Status drop down to change the status from Unreviewed. Add a comment at the bottom of the page if desired and then click Update Test Statuses.

Reviewing a test list
That Test List instance will now be removed from the Unreviewed queue. Note that it is also possible to automate review and approval.
Wrapping Up¶
We have now gone through the basics of taking QATrack+ from a blank installation all the way to performing and reviewing our first Test List! Check out the admin guide (for configuration) and users guide (for end user instructions) for more information.
Visualizing Data with Composite Tests¶
In this tutorial we’ll set up a test list that uses an uploaded text file to fit a line to some data, and plot the data as well as the best fit line.
The csv file we’ll be using looks like this:
0.0000,0.1821
1.0000,1.5899
2.0000,3.1447
3.0000,4.3780
4.0000,6.0144
5.0000,7.4758
6.0000,9.0759
7.0000,10.6360
8.0000,11.8331
9.0000,13.2787
10.0000,14.8097
and our goal is to upload this file, fit a line, and record the slope and intercept of the line. Save the data file for later.
To accomplish this, we need to set up a test list with three tests:
- An Upload test that will parse the data from the file, fit the line, and generate the plot using matplotlib.
- A Composite test to record the slope of the line.
- A Composite test to record the intercept of the line.
Configuring the Tests¶
Navigate to the admin section of the site and click on the Tests item in the QC section.

Tests admin link
Now click on the Add Test button at the top right of the next page:

Add test button
Then fill out the Test fields as follows:
Name: Data upload
Macro name: data_upload
Category: (pick any available category, or add a new one)
Type: File Upload
Display image: Make sure this is checked so that our plot will be visible
Calculation procedure:
import matplotlib import matplotlib.figure import matplotlib.style import numpy as np matplotlib.style.use("seaborn") # read the data and put the x, y values in xs, ys xs = [] ys = [] for line in FILE: x, y = map(float, line.strip().split(",")) xs.append(x) ys.append(y) # polyfit of degree 1 can be used to fit line slope, intercept = np.polyfit(xs, ys, 1) # calculate some datapoints of the line of best fit for display fit_ys = [slope*x + intercept for x in xs] # plot the data fig = UTILS.get_figure() axes = fig.gca() # gca == get_current_axes axes.plot(xs, ys, 'o', label="Raw data") axes.plot(xs, fit_ys, label="Best fit line") # use QATrack+ UTILS to save the plot as an image UTILS.write_file("fit_line.png", axes) # set the final result which can be used by other composite tests data_upload = {'slope': slope, 'intercept': intercept}
This should look similar to:

Upload data test config
Once you have that complete click Save and add another and create another Test:
Name: Slope
Macro name: slope
Category: (pick any available category, or add a new one)
Type: Composite
Calculation procedure:
slope = data_upload['slope']
And again click Save and add another and create the final Test:
Name: Intercept
Macro name: intercept
Category: (pick any available category, or add a new one)
Type: Composite
Calculation procedure:
intercept = data_upload['intercept']
Then click Save
Settting up the Test List¶
Navigate back to the Home or QC page of the Admin area and then create a new Test List by clicking the Test List link in the QC section and then clicking the Add Test List button.
Give your test list the name Line fit example or similar, then in the Test List Members section, click on the magnifying class next to the first Test box:

Find a Test for your Test List
and then select the Upload Data test:

Select a Test for your Test List
Do the same for the Slope and Intercept tests:

All tests selected
Then click Save.
Assigning the Test List to a Unit¶
Navigate back to the Home or QC page of the Admin area and then assign the Test List by clicking the Assign Test Lists to Units link in the QC section and then click the Add Unit Test Collection button at the top right.
Fill out the required fields:
- Select a Unit from the Unit drop down
- Select a Group from the Assigned To drop down
- Choose one or more Groups (your user must be part of one of the groups) in the Visible to control
- Select test list in the Test List or Test List Cycle drop down
- Finally select the Line fit (or whatever you called it!) Test List in the Tests collection field.

Assign Test List to Unit
Now click Save and Continue Editing which will bring you back to the same page. You can then click View on site to perform the Test List

View on Site
Image Analysis Using pylinac and the QATrack+ API¶
As of version 0.3.0, QATrack+ includes pylinac which for image and log file analysis. This tutorial will cover setting up a Picket Fence imaging test and then performing the test both via the web interface and the QATrack+ API.
Setting up the Test List¶
Log into QATrack+ and navigate to the admin section. Create the following tests (if you haven’t created a Test List before, go through the step-by-step test list tutorial before attempting this tutorial):
- Name:
Picket Fence upload & analysis
- Macro name:
pf_upload_analysis
- Category:
Choose existing Category or create an Image Analysis category.
- Type:
File Upload
- Display image:
Ensure this field is checked off
Calculation procedure:
import io import pylinac # run the picket fence analysis using pylinac # note the use of `BIN_FILE` rather than `FILE` since we are dealing with an image pf = pylinac.PicketFence(BIN_FILE.path) pf.analyze() # our dictionary of results to return pf_upload_analysis = { 'percent passing': pf.percent_passing, 'max error': pf.max_error, 'number of pickets': pf.num_pickets, 'orientation': pf.orientation, } # create a pylinac PDF and create an attachment with it data = io.BytesIO() pf.publish_pdf(data) UTILS.write_file('testingpfpdf.pdf', data) # convert the image to a png file so it can be displayed when performing the test list UTILS.write_file('pf-image.png', pf.image)
- Name:
PF orientation (Left-Right, Up-down)
- Macro name:
pf_orientation
- Category:
Choose existing Category
- Type:
String Composite
Calculation procedure:
pf_orientation = pf_upload_analysis['orientation']
- Name:
PF pickets found (#)
- Macro name:
pf_num_pickets
- Category:
Choose existing Category
- Type:
Composite
Calculation procedure:
pf_num_pickets = pf_upload_analysis['number of pickets']
- Name:
PF maximum leaf error (mm)
- Macro name:
pf_maximum_error
- Category:
Choose existing Category
- Type:
Composite
Calculation procedure:
pf_maximum_error = pf_upload_analysis['max error']
- Name:
PF leaves % passing
- Macro name:
pf_leaves_pct_passing
- Category:
Choose existing Category
- Type:
Composite
Calculation procedure:
pf_leaves_pct_passing = pf_upload_analysis['percent passing']
After you have created the Tests, create a Test List called Picket Fence that consists of the 5 Tests we just created:

The Picket Fence Test List Definition
Next assign this test list to one or more Units:

Assigning Picket Fence Test List to Unit
and set References and Tolerances on the Maximum Leaf Error (mm) and PF leaves % passing as shown below:

References and Tolerances for Picket Fence test
The Test List is now ready to perform!
Performing the Test List via the web UI¶
Navigate to the Test List selection for this Unit and click Perform next to the Picket Fence Test List:

Selecting the Picket Fence Test List
on the Test List page, click the Upload button and select your picket fence dicom (or other image format file). After the file is uploaded you will see your other test values automatically populated as well as the image shown:

Test list values after file upload
Click Submit QC Results and you are done!
Performing the Test List via the API¶
As of version 0.3.0, QATrack+ includes an API which can be used for automating the entry of Test List data. An example of using the API via a Python script is shown here, although the process should be similar in most other programming languages!
Obtain an API token¶
Before you can access the API, you need to have an API token which can either be created through the Admin section or retrieved programmaticaly:
import requests
root = "http://yourservernamehere/api"
token_url = root + "/get-token/"
resp = requests.post(token_url, {'username': 'user', 'password': 'password'})
token = resp.json()['token']
This token must be included with every request to the API.
Find the Unit Test Collection we want to perform¶
First we will use the API to retrieve the URL of the Unit Test Collection we want to perform:
import base64
import requests
# the request headers must include the API token
api_token = "YOUR API TOKEN HERE"
headers = {"Authorization": "Token %s" % api_token}
root = "http://yourservernamehere/api"
unit_name = "TB1"
test_list_name = "Picket Fence"
url = root + '/qa/unittestcollections/?unit__name__icontains=%s&test_list__name__icontains=%s' % (unit_name, test_list_name)
# find the UnitTestCollection we want to perform
resp = requests.get(url, headers=headers)
utc_url = resp.json()['results'][0]['url']
# prepare the data to submit to the API. Binary files need to be base64 encoded before posting!
data = {
'unit_test_collection': utc_url,
'work_started': "2018-09-19 10:00",
'work_completed': "2018-09-19 10:30",
'comment': "Performed via the API!", # optional
'tests': {
'pf_upload_analysis': { # pf_upload_analysis is the name of our upload test
'filename': 'picket.dcm', # path to file
'value': base64.b64encode(open("/home/randlet/Downloads/picket.dcm", 'rb').read()).decode(),
'encoding': 'base64'
},
},
'attachments': [] # optional
}
# send our data to the server
resp = requests.post(root + "/qa/testlistinstances/", json=data, headers=headers)
if resp.status_code == requests.codes.CREATED: # http code 201
completed_url = resp.json()['site_url']
print("Test List performed successfully! View your Test List Instance at %s" % completed_url)
else:
print("Your request failed with error %s (%s)" (resp.status_code, resp.reason))
Running the script should show:
Test List performed successfully! View your Test List Instance at http://yourservername/qa/session/details/60/
and then viewing that link your browser:

Viewing Test List Details after posting image via API
Acknowledgements¶
This Test List was originally created with assistance from James Kerns, author of pylinac.
Screenshots¶
Note
To view images in full size, right click and then open image in a new tab.

Example interface for performing QC. Shown are numerical tests, boolean tests, and composite tests.

Picket fence analysis using QATrack+ and pylinac

A listing of all the test lists awaiting review

A test list instance being reviewed

Demonstration of QATrack+’s plotting capabilities.

Demonstration of QATrack+’s reporting capabilities.

Screenshot of the QC Program Overview

Screenshot of the QC Program Overview by Due Status

Entering a new Service Event in QATrack+

The Service Log Dashboard

Overview of a users permissions

Admin interface for defining a test list