Read about OpenEMR's Response to the COVID-19 Pandemic at

Has anyone worked on adding support for UCUM(Unified Code for Units of Measure) and its APIs?


Adding support for UCUM would be beneficial in terms of FHIR support(as many resources use it as a codeset) and a MAR(Medication Administration Record)

See FHIR resource for Medication Administration:

Take a look at this example:

It uses NDC(National Drug Code directory) to identify the drug, instead of RxNorm. NDC is managed by the FDA so it may be more US specific than RxNorm.
You can download a table, I believe updated daily, from this site here.
You can also download it here:

I got the ndc xls version, the text file might have been better. Not sure how it’s delineated. Once you unzip the file you see a package and product xls file.

If you go to the search the directory page here:

It points out that there’s a new API.

Here’s a list of currently supported searchable fields:

I think at least for now we should just need product_ndc

Let’s try building an API query and running it in our browser.

Let’s use the NDC code from the example FHIR .json file.
0206-8862-02 this should be piperacillin.

Putting together a super basic query we should get:“0206-8862-02”

Okay, that didn’t work because I had a typo in the above and replaced the / between drug and ndc with a .

After correcting the typo I got a new error:

I tried removing the hyphens and still got the same error.

Let’s try a different one:

Maybe it’s supposed to be the package_ndc but that didn’t work either.

When I look it up using this site it works.

Also apparently there are a number of openFDA apps available.

SNOMED-CT, Qualifier, Route of Administration Value

Okay, so for route the example uses the SNOMED-CT Route of Administration Subset.

Does that come with the version of snomed that is currently recommended to download and import?
Is this something you have to pay for?

Here’s another link:

That brings you to a page that appears to let you download the subset but only up to 2015.

Let’s go a ahead and log into our UMLS account.

Also does it matter if we get the US edition or international?

Looking at this site it seems that the route of administration has a concept ID 284009009

Go to classes->qualifier value -> Route of administration value.
This one seems more comprehensive than the below two.

Not sure if it’s worth mentioning but there’s also a dose form administration method, concept ID 736665006

Dose form intended site:
ID 736665006

Let’s see which of those options was used in our chosen FHIR example
“Intravenous route (qualifier value) (Details : {SNOMED CT code ‘47625008’ = ‘Intravenous route’, given as ‘Intravenous route (qualifier value)’})”

Googling that took me to this page:

Which tells me it has a parent concept of intravascular route

with children of these 3 types.

If you go to its parent page you see it has a parent relationship of route of administration value.

Which itself is in the Qualifier Value class


Okay, so first thing we should do is make a note of what unit preferences our instance administer has set.
In your instance go to administration ->globals->locale and look at the “units for visit forms field”

Now let’s figure out where this info is stored in the database. In the locale menu right click pretty much anywhere and select “view frame source.”

This will open a new tab. Look in the address bar. You see the code that is running this part of this page is in openemr/interface/super/edit_globals.php

Go ahead and find and open that file in your editor of choice and take a look around. The SQL statements I see being built go into a “globals table” let’s open phpMyAdmin and take a look in there.

So we have global names, gl_index and gl_value.

My first guess as to the one we’ll want to check is called “units of measurement” 0,1
I have my units set to the default option for visit forms.

If you go back to the html file that was opened when you inspected the frame, do a control+f search for units.

You’ll see the below:

  •  <div class='row form-group'><div class='col-sm-6 font-weight-bold'>Units for Visit Forms</div><div class='col-sm-6 oe-input' title='Applies to the Vitals form and Growth Chart'>
  •   <select class='form-control' name='form_50' id='form_50'>
  •    <option value='1' selected>Show both US and metric (main unit is US)</option>
  •    <option value='2'>Show both US and metric (main unit is metric)</option>
  •    <option value='3'>Show US only</option>
  •    <option value='4'>Show metric only</option>
  •   </select>

You can see that option 1, which I have currently selected is what you see in the gl_value field in the the globals table in the database.
To confirm I’m going to switch to option 4, show metric only, save, and validate that it changed in the database.

And now it’s set to 4.

Other gl_name fields relating to units:
display_units_in_billing 0, Null


So the key takeaway is that if when you run the query:
SELECT gl_value FROM globals WHERE gl_name = “units_of_measurement”

If the value is one you need to store the value in US units but also be able to display it along with metric.

If the value is two you need to store the value in metric units but also be able to display in US units.

For 3 I assume you store it as US units and 4 store as metric and you don’t need to display the other.

Okay, so let’s take these UCUM APIs out for a spin.

Although, for those who are not always connected to the internet we may want to actually go ahead and use the ucum-lhc javascript library.

Looks like it’s on npm. You can also clone it from github.

Anyways, let’s start with the validation and conversion api.

So there’s three services available at this time

Looks like it returns xml by default. But you can change it to json or plaintext by specifying in the query.

Also you have to do percent encoding. This changes things from square and curly brackets {}[] to a percent sign with numbers after it that tell you what special character it is.

There’s some pre-existing php code to do percent encoding. I talk about this in this thread looking into GUDID

In a nutshell, you take whatever text you need percent encoded, and use the below command
$UDI= urlencode($DI);

Here’s a few examples where the brackets are replaced with percent encoding.
2 inches -> centimeters[in_i]/to/cm

3 and a half feet to micrometers

I’m not sure how you know where to put the braces

You can also do conversions where it’s two units multiplied or divided.

It should be okay to use a / for division and . for multiplication since it automatically knows to grab everything after the from until the /before the to.

So if you’re not sure where to put the square braces or how to represent the units you’re converting from or to, it looks like you just have to trial and error using the validation service.


So there is a fair amount of overlap between UCUM and LOINC. So we may also want to make it so it can interpret/map to LOINC as well later on.

So say you got something like the below

and let’s pretend we don’t know it’s grams. Note that this is case sensitive. G is gauss.

This API will allow you to give a searchbar functionality by narrowing down the field as you type.
It returns a list of codes that start with g

To the maxList setting which is configurable but is set to 7 by default.

I think if you set it to 1 and if you’re sure it should be an exact match you should get just the one result you want.