GSoC 2017 – Operation Theater Module Workflow Enhancements

This post originally appeared in OpenMRS Talk as my final presentation.

Operation Theater Module Workflow Enhancements

Mentors: Akshika Wijesundara & Harsha Kumara

Code contribution Summary: GitHub

There’s a certain pleasure in seeing people make use of your work. That’s one of the main driving forces behind the open source philosophy. It’s deeply satisfying to know that your lines of code makes someone’s life easier, even if by just a little bit.
But what about not just making lives easier, but helping to save entire lives? That’s some next level thing. Enter OpenMRS.
This summer I had the opportunity to contribute with code to save lives, and this is my final note about the experience.

My project was to work with the operation theater module which can be used to manage theater activities in hospitals. It had been made as a previous GSoC project, but not updated with the rest of OpenMRS.
So I had two primary targets:

  1. Migrate the module to work with the latest OpenMRS platform.
  2. Perform workflow enhancements to make it more useful.

And migrate and enhance we did.

Migrating the Operation Theater module

The OT module was written for platform 1.9.7, in the age of Java 7. Fast forward to 2017, and we’re having platform 2.7 in beta.
So as my first task, I set out to migrate the module to the latest stable OpenMRS platform – 2.6. This involved a number of things, mostly related to replacing outdated components in the module code base.

Replacing Joda Time library

The module solves a constraint satisfaction problem – scheduling surgeries to available operation theaters. It uses the Optaplanner library for this task. This involves coding the available times of operation theaters, the surgery durations, avoiding surgery overlaps and making maximum use of the available times.

The original implementation modeled the problem with programmatic concepts and implementations of time available in 2014. It used the Joda Time library for things like intervals, durations and timeline management. This library was deprecated and became obsolete with the introduction of the Time package in Java 8.

What’s more, the use of the Joda Time library raised many dependency issues as the same library’s different versions were being used across different modules in OpenMRS. We had a nightmare with class loader constraint violations.

After discussions with my mentors, I replaced the Joda Time library with the Java standard library’s Time package, and the ThreeTen-Extra package. Together, these two packages provide the essential features such as intervals and durations required as part of the CSP solution.
Elsewhere, OpenMRS had moved on from Hibernate 3.x, while the OT module still used the older version. We did the needful to move to newer Hibernate versions.

Thus went down the primary target. Here are some views from the module.

Next I started on performing workflow enhancements.

Workflow Enhancements

Workflow enhancement mostly focused on the data collection throughout a surgery’s life cycle. During the initial planning period, we had identified a set of data that would be useful for theater activities. These encompassed pre-theater, post and in-theater activities.

As for pre-theater data, our initial plan was to collect the following.

  1. Past surgeries
  2. Pre-theater prescriptions
  3. Allergies
  4. Fitness for surgery / physical condition

My first thought was to collect these data as free text. Let someone type them as notes for the surgical team. But it was later pointed out that we should ideally collect the data with concepts and observation groups. This made more sense, as it organized the collection of data and provided a way to query the information more readily via OpenMRS. In the long run, this would allow users to generate reports on theater activities.

I was warned that implementing data collection with obs groups may be tougher and would take longer. After discussing with my primary mentor, we decided to implement as much of the data collection as we can using concepts and obs groups.

In choosing the concepts for obs groups, @ball provided guidance and advised to use concepts already available, as this would make the code adhere to established standards, allowing collected data to be analyzed beyond just OpenMRS. She pointed me to CIEL, where past procedure data collection could be done with the following concepts:

  • Procedure History (Grouping concept)
    • Procedure performed.
    • Procedure date/time
    • Procedure comment.

The next problem was to ensure that these concepts would be available in the work environments where the module was deployed. Again, @ball provided examples of how this has been done in other implementations, and I added the concepts to the module activator.

The module activator checks if a deployment environment already has the procedure history concepts from CIEL, and adds them if not. Along with that, I added a new concept group for gathering surgery data across its workflow as below.

  • Procedure information (Grand-parent grouping concept)
    • Pre-theater drugs (parent grouping concept)
    • In-theater drugs
    • Post-theater drugs
    • Procedure History (same as before)

All three drug concepts are parent groups that facilitate adding drug prescriptions as observations of the surgery. So we’ve achieved collection of data with concepts and obs groups, thereby standardizing the data collection.
The point here is that this allows the data to be identified across systems, rather than being confined to OpenMRS. It’s better to use an international convention so that more people can make sense of the data without going through the hassle of another concept dictionary.

Here are some views that portray the data collection within the module. Oh and I’m not the most knowledgeable person on drug-related terms. Please do excuse if I’ve mixed up pills and tablets, or given a drug where you never do. :smile:

Pre-theater data:

Post-theater data

As for in-theater data, I felt that it’s best to add them to the post-operative form.

GSoC 2017 With OpenMRS – Operation Theater Module Workflow Enhancements

It’s a little hard to think 12 weeks have passed already. But as they say, all good things must come to an end. So goes Google Summer of Code 2017 with OpenMRS.

This summer, I worked on the Operation Theater module to bring it up to speed with 2017. The project had 2 main targets.

  1. Migrate the module to work with the current OpenMRS platform.
  2. Add workflow enhancements pertaining to pre, post and in-theater stages.

To remind what the operation theater module does, it basically helps us to schedule surgeries in the operation theaters within a hospital. We can add operation theater locations, save available procedures, schedule surgeries for patients and have a scheduling engine come up with the best schedule for current surgeries.

We can also add a team of surgeons and other people who will be taking part in the surgery. But after making the module, it was somehow left behind and wasn’t updated along with the core of OpenMRS & other modules. It just went beep for 3 years.

So my first task was to get it up and running. For this I had to first check what had changed between those 3 years and update the module codebase. I learned much about how the concept of time is handled in the programming world. I learned about Optaplanner, and constraint satisfaction problems in general (shout out to Charith sir for the Intelligent Systems lectures!). And bloody hell, I replaced an entire time library with two other libraries.

Along with that, there were database changes. OpenMRS had migrated from Hibernate 3.x to 4.x, so the Operation theater module needed some changes on that front. There I learned a bit of Hibernate, the ORM (Object-relational mapping. It’s a database thing). So the first month was spent on updating the module codebase and dependencies.

And we revved up the module.

After adding an operation theater location from settings, we can access the scheduling page and start scheduling. But wait, you need to add some procedures first. Otherwise, what surgery are you going to schedule?

And we’re good. So, first task, done!

Next, we started doing workflow enhancements. The main focus here was on the collection of data throughout the surgery. Before starting a surgery, it’s important to know the history of the patient. What procedures have they done before? Are there any drugs we need to give before the surgery? Is the guy even fit to go into surgery? Curiosity to save a life. Or two, counting the surgeon’s.

I initially planned to collect data as notes – free text. But the community suggested that we do it with concepts and observations, the preferred method of collecting data into OpenMRS. This way, we can use the collected data to generate reports and perform analytics. You can probably guess how hard that would be with free text.

I was halfway through doing it with free text when I got the suggestion. After that, I rewrote the code with appropriate concepts. So now, we’re adhering to standards and working neater overall.

We record past surgery data, allergies, physical condition and drug prescriptions during the pre-theater data collection.

We do the same for in-theater and post-theater data. As for in-theater data, we decided to capture it in the post-operative form as it’s not practical to enter the data during the surgery.

And that’s target number two, down. We’re all good with the primary tasks 😀

After that, I started documenting the code and the module. I’ve written some tests to cover the code and tried to clean it up.

I’ve learned a lot in these past few months, specially how a real project handles collection of data in a flexible manner. This is especially useful for some of my personal projects as well.

As next steps, I’d much rather fully rewrite the scheduling engine myself. Then I know the module inside out from its core, and can help other people to get involved in maintaining it. Another possible extension is generating reports from the data we collect. It’s just a matter of presenting the data in suitable formats.

And that’s it for this time, people. We’ll wrap it up after the final evaluations in one more post.

Until then, take care.

GSoC 2017 – Week 11

Over the 11th week, I tried to refactor the code to use as many concepts as possible for data collection. I have added required concepts to be loaded via the module activator at module startup. Then I tested adding data to the system with the saved concepts.

We’re now properly using concepts to store theater workflow data with observation groups where necessary. This is a major milestone as this means we’ve effectively standardized the data collection over the long term, enabling people to make use of the gathered data. My mentors provided feedback on the module and discussed the possibility of shipping the module with the next release of the Reference Application 😀

That’s a big deal, but I feel we’re short of that yet.  I’d personally rewrite the scheduling engine completely, as at the moment it’s a mess of one guy’s solution and another guy’s attempt at bringing it to 2017. It works, but with a few quirks here and there – like sometimes it schedules surgeries after the theater open hours. But with the time constraints, this’ll be a task for after the GSoC deadline.

On unit testing side, I wrote test cases for checking availability of initial concepts, adding data with concepts and retrieving them. I plan to document a guide on using the module over the next week. We will also make a video about our work as the final presentation of the project.

GSoC 2017 – Week 10

We’re nearly done with all development now. This week I went through CIEL and identified existing concepts that I can use for data collection.

It turns out that the whole set of data collected for past surgery history are available in CIEL. Instead of past procedures, they call it procedure history. There’s a set of concepts to record past surgery details as below.

160714 – Procedure history (Grouping concept)
1651       – Procedure performed
160715 – Procedure date/time
160716 – Procedure comment
160721 – Procedure outcome
163049 – Procedure site

During this week I refactored my code to use these concepts for past surgery data collection. I also added them to the module activator to ensure that they are available in any deployment environment.

Apart from that, I spent some time looking into how unit tests are written for OpenMRS modules. We have less than two weeks left of the coding period, so I plan to finish off development with feedback from the community this week.

GSoC 2017 – Week 9

In-theater workflow enhancements includes collecting various data during the surgery is being performed.  My original plan was to have a simple page that would show a timer and allow users to add various data as the surgery continues.

But later I realized that it’s not practical to have someone typing at a computer during a surgery. Silly me. The better approach, I think, is to let the data be recorded after the surgery is performed – add it to the post-operative data.

This is the case with one of the existing implementations that I saw. They have a post-ops form with fields to enter fluids administered during the procedure, specimens collected and such.

I made a similar form for our use case. Since OpenMRS has concepts for most drugs and observations, those are used within the form to store the collected data within an obs group called In-theater drugs.

Towards the latter part of the week, I learned that I should ideally use existing concepts for storing data. There are various standard collections of concepts that define medical concepts internationally. One of them is CIEL – Columbia International eHealth Lab Concept dictionary.

The point here is that this allows the data to be identified across systems, rather than being confined to OpenMRS. It’s better to use an international convention so that more people can make sense of the data without going through the hassle of another concept dictionary. So I’m changing the current concept definitions to match those in CIEL concept dictionary.

Another thing I wanted to know last week was how to add these concept definitions to a startup script of the module. When the module is deployed in a new instance of OpenMRS, we need to make sure that it has the basic set of concept definitions to continue its work. This is best done in some sort of initializer.

I asked the community about this and they suggested 2 methods – either to have a metadata module that sets up the relevant data, or to have it all in a file called the module activator. I decided that it’s better to have the code in one place rather than having a separate metadata module, as the amount of metadata is low at this point.

And we had our second evaluations. We made a small video about our current progress and posted in the community for feedback.

GSoC 2017 – Week 8

Wow, two months gone just like that. This week, my focus was on implementing the pre-theater data collection as per our discussions over the previous weeks. If you followed along,  you’d remember that we decided to use concepts and obs groups to  record the collected data.

The first thing I did was getting the patient’s allergies and showing them alongside the surgery data. Documentation is scarce on this but I remembered that the new Reference Application contained Allergy module by default. So when I view a patient, his or her allergies are listed on the profile itself. Now I just had to see the corresponding code.

Well, that didn’t work out too well. I couldn’t find how the patient profile view was coded. Fret not, let’s explore the OpenMRS core. Rummaging through the core API, I came across the PatientService class and there I found a method to get all the allergies of a patient.

Then I wanted to see the source code of the Allergies, Allergy and Allergen classes (seriously, they’re modeled like that for reasons unknown to me). But GitHub doesn’t support Ctrl-click to view source (it should. It’s 2017!) so I downloaded it, revved up an IntelliJ instance and loaded it up. Ctrl-clicked away to my heart’s content. Ah.

The Allergies class allows us to manipulate allergy data as a whole. The Allergy class drills it down to a specific allergy. Allergens are what cause the allergy, and have a particular set of reactions for it. AllergyReaction class, you see where we’re going with this.

Anyway, so I needed to use all 4 classes to display the allergies of a particular patient. Maybe we should document that somewhere in the wiki. Huh…

Another thing I did was rearranging the Surgery page. Right now I’m using the Surgery Edit view to display its summary (reuse, reuse!) so it needed a bit of moving things around to accommodate the new stuff I was adding to it.

And we really need to have a standard guide with examples on UI development. Nobody knows how the existing fragments in the UI Commons library look or work. You have to go through the code and figure things out by trial and error to get it working. And adding icons is another mess. Maybe I missed an existing guide somewhere… I doubt it though.

That’s all for this week. In-theater data collection is the next step.

GSoC 2017 – Week 7

During the 7th week, I got feedback on the mock-ups for pre-theater data collection. Just as I suspected, letting the user simply note data as free text was not the best idea.

Although a simple note might be useful in communicating the patient history, it’s not usable for analytical purposes. I mean, a text paragraph is not granular enough to analyze trends in patient history and can’t be used to generate reports. We need to organize the data collection such that they can be analyzed in the future. This means breaking it down into contextual chunks. Then structuring the DB to store them allowing easy querying.

My first idea about implementing  this was a little complex. I thought about making 3 tables – tags, surgeries and surgery_tags. The tags table would denote the past surgeries. Surgeries would store the master entity. The surgery_tags table would add multiple entries with past surgery data before doing a new surgery.

But then I was directed towards Obs Groups and the OpenMRS Concepts Dictionary. Those two blew my mind. Literally.

Let’s start with the concepts dictionary. It defines the medical concepts that are used within a particular implementation of OpenMRS. As many institutions use OpenMRS around the world, they add the concepts they use into their instance. To quote the docs,

the concept is the basic element of flexibility in OpenMRS. Concepts are the individual data points collected from a population of patients. Concepts include both questions and answers.

For example, blood type data is collected for a patient.  The question is “What is the blood type for the patient?”, with a set of discrete answers of “A, B, AB or O”.  To implement this in OpenMRS with concepts, the question is a concept (“blood type“) and each response (“A“, “B“, “AB” and “O“) is also a concept.  For this one question, a total of 5 concepts are required.

Here are the docs, it’s an interesting approach that allows future modifications to the data collected within the server. This works in tandem with Obs, or observations.

An observation is anything that is actively measured or observed during an encounter (-> a patient’s interaction with the doctor). This could be the white blood cell count of a patient. Or the mode of transportation to the hospital.

Logical groupings of observations are called Obs Groups. For example, there may be an obs group called “TRAVEL TO CLINIC”, which may include the member observations “MODE_OF_TRANSPORTATION”, “DISTANCE_TRAVELED”, “TIME_SPENT_TRAVELING” and such. You can read the docs here to get a better idea about it.

So in our particular case, we’d need to register an obs group called past surgeries, as this would be an observation made during an encounter before scheduling the surgery. Then, the date of the past surgery, its name and diagnosis would be member observations. These would be recorded as concept entries within the DB.

This will take some time to implement, and we’re supposed to be done with the pre-theater workflow enhancements in a week. I discussed with my mentor and we’ll implement as much as we can during the available time.

Another thing I noticed is that we can’t view the details of a surgery once we finish entering its details the first time. There’s no way to view a single surgery and info about it. We get a summary page of the surgery when we finish creating it, but you can never get back to it once you exit from there. So I connected that page to the overall surgeries page so that we can click on a particular surgery and view details of it at a later point. Such a simple thing, I’m not sure how this was not discovered before.

And that’s all for this week, folks. I’m sorry that I’m late to post this (hell, I got asked why I’m late). Work, you know how it is during the intern period.

Until later, then. Ciao.


GSoC 2017 – Week 6

It’s the end of the 6th week and I’m happy to bring some UI to the mix. Up until now we’ve been working with the stuff that was made before. But now it’s time for new enhancements. The first part of it is enhancing the pre-theater workflow.

Along that line, we discussed what data need to be collected before a procedure, last week. I asked the community what they considered necessary, while making my own suggestions. Just as expected, there are already some implementations of data collection of a surgery.

One example was a post-op form used by a Partners In Health member. She provided screenshots of the form which they used to collect data about the procedure after it took place. It included fields to record the surgical team involved, the location of the procedure, anesthetics, complications etc. They were not collecting any data before the procedure, so they used the same form to record pre-operative diagnoses as well.

The PIH lady was kind enough to provide advice on implementing the forms as well. She gave a rough idea on how I might want to configure the provider types with metadata, and may consider adding a separate role such as surgery scheduler to assign the tasks related to theater activities.

Going by the screenshots she provided, and the data I originally proposed to collect, I came up with the following page for pre-theater data collection.


These are more like preliminary sketches, to get the feedback of the community. I’ll finalize them and connect the database next.

GSoC 2017 – Week 5

Another week passes and we’re done with the first round of development. In this round we worked to migrate the Operation Theater module to the current platform, and the last week focused on modifying the theater scheduler.

We’ve finished modifying it, and the results are mind-boggling. No, seriously, it’s messed up. Right now it schedules activities one after the other on the same day, without looking at the open hours of the theaters. So not what we want.

It’s got something to do with the timelines used when running the scheduler. The start and end times of a theater, and those of a procedure seem to be having an error in the way they get time zones. I need to take a deeper look at that.

Our main goal of migrating the module is complete. Correcting some errors is what’s left of it.

The second round of development focuses on pre-theater data collection. This is the first part of the workflow of any procedure. We need to collect data about the patient’s condition, medications and things that need to be done before the procedure. I’ve listed some of the data I’ve identified as important below.

  • Evaluating patient medical history
    • Past surgeries
    • Diseases that may affect the surgery
    • Current medications – may cause complications
    • Allergies – for chemicals, drugs or anything else used in surgery
  • Fitness for surgery
    • Checking the body condition of the patient for signs that the surgery may not be viable
  • Prescriptions to be taken before the surgery
    • Dyes
    • Anesthetics, antibiotics, antifungals, analgesics, IV fluids, Electrolytes, anticoagulants, diuretics, barbiturates
  • Fasting periods
    • NBM periods for the surgery
  • Legal requirements (where applicable)
    • Documents requiring legal consent of the patient for the surgery

With this data, I’ve outlined the data model for storing them in the database. I’ll post a diagram here soon.

So the next week, we’re going to start implementing the pre-theater data collection. Forms, Spring and Hibernate.

GSoC 2017 – Week 4

It’s the fourth week, and we’re nearly done with the first round of developments. My main objective for the first round was migrating the Operation Theater module to the latest platform, and I’ve completed about 80% of it. There’s just one more thing to finish – to get the scheduler working.

The OT module uses a tool named Optaplanner for scheduling theater activities. It’s an open source constraint satisfaction solver written in Java. We can model the theater planning activity as a constraint satisfaction problem (CSP) and use Optaplanner to get a somewhat optimal solution in a given amount of time. As you might know, CSPs are  considered to be either NP-complete or harder.

Let’s start with a few definitions before we get to the nitty-gritty.

Constraint satisfaction problem – a problem with a limited set of resources, and constraints on possible paths to a solution. A solution needs to satisfy the given constraints and employ available resources.
NP-completeness – the abbreviation NP means Nondeterministic Polynomial time. We’ll need to go way out of our topic to describe what each of those terms mean exactly, so let’s get a high-level idea. Simply put, NP-complete means the following;

  • It’s easy to verify a given solution of such a problem, in a reasonable amount of time.
  • We don’t know an efficient method to get such a solution.

The best-known characteristic of NP-complete problems is that we don’t have a fast way to solve them. All current methods grow exponentially more complex as the size of the problem grows. 😐

You already know that theater scheduling is a CSP. What else are CSPs? Well, think about creating timetables in a university. Or scheduling nurses in a hospital. Planning car assembly lines. Investment portfolio optimization. Cutting steel sheets in an optimal manner. All of these are constraint satisfaction problems. Aaand planning problems. They have goals that they wish to optimize and limited resources under constraints. You can refer the documentation of Optaplanner for a good description of them[1].

Anyway, the OT module has an implementation of Optaplanner based off of version 6.0.0. That one isn’t working nicely with the shiny new other libraries that we’re using, so I need to migrate it to version 7.0.0.

There are two ways I can do this.

  1. Make the changes that happened in Optaplanner through versions 6.0.0 to 7.0.0.
  2. Write a new solution in the latest version, using the earlier implementation as a guide.

I thought a little on this and realized that while I could write a new solution, then I’d need to check how the current implementation communicates with the Optaplanner engine and write matching API endpoints to ensure proper functionality. Given the limited amount of time I have with all the work of the internship, I thought it’s best to first try to migrate the existing solution.

So right now, I’m working on making necessary changes to the solution so that I can get it running asap. Let’s see how optimal we can get.