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 3

This week I was mostly working in checking the functionality of the system, looking at UI elements, following method calls related to surgery CRUD operations etc.

I found a few cases where a surgery validation failed when trying to enter a  emergency procedure. The problem was that the surgery associated with the emergency procedure was not properly initialized, which caused it to fail validation. A few breakpoints with IntelliJ IDEA helped to solve that. Special thanks to Gayan Weerakutti for helping me to setup debugging.

Then there were some UI elements that didn’t appear properly. Checked through files and came across a set of JSON files that were apparently used for configuring the UI, but I couldn’t understand exactly how they interacted with the other files. They aren’t imported anywhere. I’m guessing the OpenMRS classloader is specially configured to look at the path they exist and read them if they’re there.

I’ll update this post with more info in a bit.

GSoC 2017 – Week 2

I’m gonna keep this one short, at least for now. You know the reason.

Last week, we decided to replace the Joda Time library with java.time and ThreeTen-Extra library. And that’s exactly what I did this week.

The Migration

There were 3 steps to what I did.

  1. Identifying the replacement classes.
  2. Understanding the class structure to start the migration from the base classes.
  3. Figuring out the best match for a given instance of replacement.

It might not look like much, but there was quite a bit of work once I got into it. I had already started off the replacement without much thought in the previous week. But as I later realized, it’s better to first look exactly where and how the base classes are used later.

Identifying the Replacement classes

The first step was figuring out which class of Joda Time maps to which of java.time or ThreeTen-Extra (henceforth known as TTX). Some of the classes like DateTime could be replaced with ZonedDateTime from the built-in library, while others like Interval needed the help of TTX.

There were some concepts like Hours, Minutes etc. that were replaced with Duration and Period. These were used in some calculations of the scheduling algorithm.

Understanding the class structure

It’s so much easier to start from the base classes and replace the library from inside out. This is because of our lovely IDEs that continuously parse the classes and perform semantic analysis to see if we’re using methods correctly. This is quite useful as then we can clearly see if and when we’re using a method wrong somewhere, use the IDE to suggest replacements and continue our work happily.

More importantly, it helps to understand why a particular type was used in the first place. Then I can make an informed decision for the next step.

Figuring out the best match

You can’t just blindly start replacing Joda Time with whatever fits. You need to look into the context. What’s the best way to replace DateTime used in an instance where it’s used to record the available times of an operation theater? I could go with a ZonedDateTime, or use a LocalDateTime that dropped the timezone. Heck, I could record them in Instants.

For recording the available times, I went with LocalDateTime. That’s because the available times are mostly for the scheduling work done locally. I could just add a timezone later if someone from Brazil wants to see when an operation theater in Rwanda operates.

What else? Oh yeah, we talked more about moving to an official repo under OMRS. It was agreed that it’s best to move at the end of the summer, when we have a concrete, ready-to-deploy module that others can also work on. So how could I show the world that I was working, making a contribution to the open source world, with those all-important green boxes on my GitHub profile?

I could make my fork into a standalone project! Just had to contact GitHub Support center. A kind lady there resolved the issue in hours. 👌

That’s it for last week. I hope you’ll excuse the brevity, at least for now. Do check out the repo and comment on my choices. Please, I may have made mistakes. You get the joy of pointing out mistakes, I get some of dat free code inspection.

Until next time, peace!