GithubHelp home page GithubHelp logo

blue-button / bluebutton.js Goto Github PK

View Code? Open in Web Editor NEW
152.0 152.0 103.0 2.15 MB

The Blue Button JavaScript Library

Home Page: blue-button.github.io/bluebutton.js

License: Other

JavaScript 69.37% HTML 30.63%

bluebutton.js's People

Contributors

anmolagar avatar blacktm avatar jmandel avatar marks avatar robdodson avatar sankarravi avatar thetylerhayes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bluebutton.js's Issues

Consider providing API for document metadata

In addition to the core groups we have so far, it would be very useful to have access to metadata associated with the provided document.

This might include:

  • Date produced (effective date?)
  • Provider/organization creating the document
  • Document timespan (earliest item, latest item)
  • Other things?

Medication doseQuantity is a PQ (value + unit)

When you see XML like:

              <doseQuantity value="1"/>

It's effectively shorthand for

              <doseQuantity value="1" unit="1"/>

The important thing is that a doseQuantity has a unit (not always implied). So the above may mean "1 pill," or "one inhalation" or whatever is appropriate. But you may also sometimes see:

              <doseQuantity value="100" unit="mg"/>

So it's important to capture this fact in the JSON rendering (again, for consistent queryability) rather than just rendering it as the string "1" or "100".

Problem list is missing... problems

Each problem has an observation whose value defines the actual problem. E.g.

 <code code="409586006" codeSystem="2.16.840.1.113883.6.96" displayName="Complaint"/>
 <value xsi:type="CD" code="233604007" codeSystem="2.16.840.1.113883.6.96" displayName="Pneumonia"/>

Right now bb.js is extracting

    "name": "Complaint",
    "status": "Active",
    "age": 57,
    "code": "409586006",
    "code_system": "2.16.840.1.113883.6.96"

... but this should be "name: pneumonia, code: 233604007..."

null vs. empty

I'm curious, why return null fields instead of empty fields? Is there a specific reason?

Otherwise it seems like it'd be good to stick with most Web APIs' convention of returning empty as opposed to null fields. Generally this convention pertains mostly to text fields, which is why it seems all the more pertinent here — all we're dealing with are text fields.

FWIW it's not the end of the world if bb.js is sticking to its story of null rather than empty because at least there's still only one way to have an empty string: null (as opposed to null and ""). Again, just curious.

Coming from a Django-heavy background. Naturally.

Free-floating "translation" elements don't make sense

Translations are translations of codes, so they should be attached to codes. The following free-floating translation attached to your encounter example doesn't make sense to me:

{
    "date": "2000-05-07T05:00:00.000Z",
    "name": "Office consultation - 15 minutes",
    "code": "99241",
    "code_system": "2.16.840.1.113883.6.12",
    "code_system_name": "CPT",
    "code_system_version": "4",
    "finding": {
      "name": "Bronchitis",
      "code": "32398004",
      "code_system": "2.16.840.1.113883.6.96"
    },
    "translation": {
      "name": "Ambulatory",
      "code": "AMB",
      "code_system": "2.16.840.1.113883.5.4",
      "code_system_name": "HL7 ActEncounterCode"
    }, 
...

This should probably read:

 {
    "date": "2000-05-07T05:00:00.000Z",
    "encounter_type": {
        "name": "Office consultation - 15 minutes",
        "code": "99241",
        "code_system": "2.16.840.1.113883.6.12",
        "code_system_name": "CPT",
        "code_system_version": "4",
        "translations": [{
            "name": "Ambulatory",
            "code": "AMB",
            "code_system": "2.16.840.1.113883.5.4",
            "code_system_name": "HL7 ActEncounterCode"
        }],

Also note that translations are multiple cardinality.

Date parser returns null when effectiveTime only contains year

E.g.,

<effectiveTime>
    <low value="195001"/>
</effectiveTime>

will return a nice date in bb.js. But

<effectiveTime>
    <low value="1950"/>
</effectiveTime>

will not. It will return null for the date.

Feel free to close if this is expected functionality.

Don't use parseInt for floats.

Just noticed in labs that values are converted from strings with parseInt but that turns "13.2" into 13.

Should use parseFloat instead.

CDA XML > JSON is inaccurate may be returning incorrect information

I'm working with the demo of the parser at http://blue-button.github.io/blue-button-for-developers/docs/js/demo.html#document-section

I'm trying to do a little eyeball QA on the before and after and running into some challenges.

The CCDA XML lists a weight measurement of 195 lbs on 3/30/12 and 162 lbs on 1/24/13.

The JSON lists a vital of 195 lbs on 10/25/11, 4/30/12, 2/24/13. It lists vitals for 162 lbs also on 10/25/11, 4/30/12, 2/24/13.

Determine testing strategy with sample patient data

This is an open question of how we test BlueButton.js (or really any dev tool) with sample patient data given that no reference implementation of the CCDA exists, and samples contributed by vendors are often low quality or incomplete.

Since many vendors/providers will be implementing the CCDA standard to comply with Meaningful Use Stage 2, ONC has created the SITE group to help actually implement these standards (it's not easy folks). Their EMERGE project will serve to be an authoritative source of high-quality sample CCDAs. @nayanjain and I are working closely with them to get this sample data in the hands of developers. (For the time being, they have the tool behind a login – I'll try to get some demo accounts.)

I think we should leverage the work being done by SITE and use sample data from their EMERGE project, the same resource EMR vendors, the VA, and others (?) will be using to implement their CCDAs. The benefit of this approach is that if/when we find difficulties using/parsing the CCDA, feedback can be sent back to SITE, and ultimately back to the standards committee if need be.

Thoughts?

Other resources:
HL7 implementation guide
@jmandel's sample_ccdas

Organization of labs output

What is the grouping of the labs output?

The only sample file I have that seems to parse correctly groups three results under a PLT object, but one of those objects is PLT as well. Is it supposed to be a panel?

Should this panel have a date associated with it? Is there a reference to when the lab/panel/whatever was ordered?

Add support for IE8 and below?

BB.js currently supports all browsers with DOMParser (non-IE and IE9+). Should we attempt to add support for IE8 and below? This would require using ActiveX or some other hackety hack.

Release notes/versioning

Ever considered release notes for bb.js?

I just pulled latest master in a while and am having to smoke test bb.js to try and figure out what breaking changes I may need to account for.

For example, labs no longer include code_system and code_system_name (introduced in 0233333). This isn't breaking anything for us but I could see it breaking frontends where systems rely on data once bb.js starts passing it through, and potentially backends that don't code around attributes not always existing/being made available.

Capture missing data

  • NPI numbers, look for <id root="2.16.840.1.113883.4.6"/>
  • URLs for code systems, see #5
  • Date document was produced (effective date?)
  • Creator of the document (provider, organization)
  • Document timespan (earliest item, latest item)
  • Encounters need a start and end date (especially inpatient encounters)
  • Allergy and Immunization "given", "not given" status. See #14 and #7
  • Review sample CCDAs from EMERGE for other missing data: http://onc-emerge.org/

Explodes in IE

Does not work in IE. Investigating XML parsing behavior cross-broswer (IE 6-9 does not have window.DOMParser and must use ActiveXObject).

Update 1:
Now works in IE10 using the native window.DOMParser. Still busted using IE 6-9's ActiveXObject.
(Apparently parentElement is a non-standard property but still returns undefined in IE, adding to hours of deep bug hunting fun. FML. Changed to parentNode.)

Update 2:
Looks like it should work in all browsers using window.DOMParser, this includes IE 9+. Now working on IE 6-8 using ActiveXObject.

Add allergy indication whether given, withheld, or refused

Josh:

  • "And conversely, we should only include allergies in the array where the C-CDA didn't have a negationIndicator=true, or a nullFlavor set."
  • "Need an approach for high-level statements like 'no known drug allergies.' In C-CDA this is represented as an allergy, where the substance is "substance" and the negationIndicator is true. But BB.js should make this simple an explicit."

Refactor and consolidate parsing pathway

Original implementation included completely separate pathways for parsing different document types (CCDA, C32). The new implementation should diverge at the point of parsing and data extraction, then join before constructing the final data object. This will reduce redundancy and make it generally easier to test and maintain.

Allergies need dates

Probably already on your TODO list, but right now allergy dates are being initialized to null and never set.

Render consistent dates across resources

Right now dates are sometimes points, sometimes ranges, and sometimes a combination. When a range is represented, different words are used in different places for the boundaries.

It's reasonable to use a date range for some resources (meds, problems, encounters), and a single point for others (lab result, vital sign). But I'd use different property names in these to cases, or else just always use a JS object (rather than object in some cases and Date/string in others).


    "effective_time": {
      "low": "2011-04-01T06:00:00.000Z",
      "high": "2012-04-01T06:00:00.000Z"
    },


  "date": {
      "value": null,
      "low": null,
      "high": null
    },
    "observation_date": {
      "low": null
    },

 "date": "2000-05-07T05:00:00.000Z",

"date": {
      "from": "1998-03-31T06:00:00.000Z",
      "to": "2011-02-03T06:00:00.000Z"
    },

Treat codes consistently across resources

For example in Labs, rather than repeating:

      var name = el.attr('displayName'),
          code = el.attr('code'),
          code_system = el.attr('codeSystem'),
          code_system_name = el.attr('codeSystemName');

You should parse the code in a consistent way (including translations if present), and abstract out that logic. Then you can given the code a property name to attach it to the lab

(For example in SMART we use semantic labels like "labName", so we'd have an individual result and say result.labName.code, or result.labName.label).

Don't rely on displayName as the sole source of *meaning*

When representing a code, it may be fine to include the displayName as extra (helpful) info in the JSON payload. But in cases where you're trying to avoid using a code altogether, it's not a safe approach to simply use the displayName value from the underlying document.

Two reasons:

  1. displayName is optional (and may sometimes be missing)
  2. It's perfectly legal to include whatever displayName you want for a given code, so documents may have different names for the same code -- and app developers won't know what to expect.

Simplest example: you're extracting a text description for race to make JSON snippets like:

  "race": "White",

Great! But don't just copy patient.tag("raceCode").attr("displayName") into this field. Rather, use patient.tag("raceCode").attr("code"), and map it explicitly to a display name that you want to associate with "White." This way apps that do clinical decision support based on race won't fail to match terms because of differences in spelling, diction, language, or even capitalization...

Parse passed-in source, rather than xml variable

I think this is just a typo that's happened to work out in your particular environment, but lines 488-490 prepare an incoming 'source' blob, but then parse the contents of the 'xml' variable.

source = source.replace(/^\s+|\s+$/g, "");
  if(source.substr(0, 5) == "<?xml") {
    xmlDOM = Core.parseXML(xml);

should probably become:

source = source.replace(/^\s+|\s+$/g, "");
  if(source.substr(0, 5) == "<?xml") {
    xmlDOM = Core.parseXML(source);

"TypeError: Arguments to path.resolve must be strings" on require

I added bluebutton to my package.json like this:

"bluebutton": "git://github.com/blue-button/bluebutton.js.git"

Just npm installed and tried to require("bluebutton") and I get this:

> bb = require("bluebutton");
TypeError: Arguments to path.resolve must be strings
    at Object.exports.resolve (path.js:313:15)
    at tryPackage (module.js:127:23)
    at Function.Module._findPath (module.js:190:18)
    at Function.Module._resolveFilename (module.js:336:25)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at repl:1:6
    at REPLServer.self.eval (repl.js:110:21)
    at repl.js:249:20

Requiring the full path works fine:

> bb = require("./node_modules/bluebutton/build/bluebutton.js");
[Function]

Is this a known issue? I'm I doing something stupid? Any ideas?
Upgraded my npm {1.2.18 -> 1.2.32} and node {v0.10.5 -> 0.10.12} and had the same error.

Need to look for multiple templateIds when "entries optional" are allowed

For example with vitals, you could find entries in one of two places:

    el = xmlDOM.template('2.16.840.1.113883.10.20.22.2.4.1');                             
    entries = el.elsByTag('entry');                                                       

    if (!entries.length) {                                                                
      el = xmlDOM.template('2.16.840.1.113883.10.20.22.2.4');                             
      entries = el.elsByTag('entry');                                                     
    }              

The former is preferred, but I've seen the latter in production systems.

Phone objects return different types

There's a little inconsistency in this right now.

For example, bb.demographics()[0].phone.home returns a list, even if there's only one number listed. On the other hand, bb.demographics()[0].guardian.phone.home returns a string.

I prefer the former, just because it's easy to know that you'll always have to iterate through a list, rather than having to check to see whether it's a list or a string.

Different results from bb.js vs. demo site

I'm running the same data using bb.js vs. the demo site and getting inconsistent results between the two. What's stranger is that it's only happening with certain CCDA files.

        var xml = fs.readFileSync(xmlfilepath, 'utf8', function(err, data) {
                if (err) {
                    console.log(err);
                }
            });

        var bb = BlueButton(xml);
        console.log(bb.demographics().json());

EXAMPLE 1: When I run this code against one of the files from the Direct Transport Sandbox — CCDA_CCD_b1_AllPerfsAddAPtoP3.xml — I get no data back (again this is just bb.demographics().json()):

Error: date is not a string
{
  "name": {
    "prefix": null,
    "given": [],
    "family": null
  },
  "dob": null,
  "gender": null,
  "marital_status": null,
  "address": {
    "street": [],
    "city": null,
    "state": null,
    "zip": null,
    "country": null
  },
...

Whereas the demo site shows the proper demographics data from the XML:
image

EXAMPLE 2: When I run bb.js against a copy of the "Blue Button Reference CCDA" XML from the demo site I get a nice response (again, this is bb.demographics().json():

Error: date is not a string
{
  "name": {
    "prefix": null,
    "given": [
      "Adam"
    ],
    "family": "Everyman"
  },
  "dob": "1962-10-22T00:00:00.000Z",
  "gender": "Male",
  "marital_status": "Never Married",
  "address": {
    "street": [
      "17 Daws Rd.",
      "Apt 27"
    ],
    "city": "Blue Bell",
    "state": "MA",
    "zip": "02368",
...

And of course the Reference CCDA works just fine at the demo site.

NB: I'm running bb.js via Node.js, not in a browser. I can't think of any reasons that would be the culprit but please point it out if you think it is. Another possible local culprit could be using fs.readFileSync, not sure if there's a better way to be reading in this XML...

allergy.code should not be represented in BB.js

Because according to C-CDA spec, this code is fixed as:

2.16.840.1.113883.5.4
(ActCode) = ASSERTION

(
The example file you're using appears to have a mistake where the code is:

<code code="416098002" displayName="drug allergy" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED CT"/>

)

Lab value showing up 2x in rendered JSON

In the example C-CDA at: http://bluebutton.blacktm.com/json

It looks like the code for PLT (platelets, a component of a complete blood count) is being pulled up in the header for the whole lab panel (which should be binding to the "CBC WO DIFFERENTIAL" code)

[
  {
    "name": "PLT",   // <------- this should be "CBC WO DIFFERENTIAL"
    "code": "26515-7",  <------ this should be "43789009"
    "code_system": "2.16.840.1.113883.6.1",  <------- this should be "2.16.840.1.113883.6.96"
    "code_system_name": "LOINC",
    "results": [
...


        "date": "2000-04-23T07:00:00.000Z",
        "name": "PLT",
        "value": "123",
        "unit": "10+3/ul",
        "code": "26515-7",

bb.demographics() returns a list

(just putting this here for documentation purposes)

demographics() should return a bare object, rather than a list of objects.

Even if the record targets more than one person, we should just not support that for now. It would be too confusing for folks to know what to do with two sets of demographics, and I'd think the use cases for multi-person records are relatively few.

Convert Line Endings to LF

Per #60

It seems like jsdom will freak out if you're using CRLF line endings and putting new lines between your attributes. I'm not sure if it's possible for us to convert all line endings to LF before parsing a doc but we should look into it. Note that this only affects the node.js parser.

Unable to load library

I'm new to node.js. Is this the proper way to load the library?

> require('./bluebutton.js');
    ReferenceError: window is not defined
        at Object.<anonymous> (/Users/neil/Desktop/bluebutton/bluebutton.js:2235:1)
        at Module._compile (module.js:456:26)
        at Object.Module._extensions..js (module.js:474:10)
        at Module.load (module.js:356:32)
        at Function.Module._load (module.js:312:12)
        at Module.require (module.js:364:17)
        at require (module.js:380:17)
        at repl:1:1
        at REPLServer.self.eval (repl.js:110:21)
        at repl.js:249:20

Some CDA files return null response

(Copying from https://groups.google.com/forum/#!topic/bluebuttondev/zGjyb4MF_1E)

Some files we're parsing are falling down; they return null for all values. When eyeballing the files they look to be properly-formatted; they're definitely CDA files. So I'm assuming there's some nuance here I'm unaware of.

One hypothesis based on a cursory analysis: maybe some templateIds are supported vs. others are not? E.g., does it sound right that bb.js would return null for all values if we're parsing Continuity of Care documents, even though the document itself is properly CDA-formatted? (I'm still a bit hazy as to what bb.js expects in terms of a file it accepts for parsing. Is it any CCDA file?[1])

For example, I just added

<templateId root="2.16.840.1.113883.10.20.22.1.1"/> [2]

after the opening

<typeId ...>

line in a CDA file that was returning null for everything via bluebutton.js and now all of a sudden bb.demographics() returns the actual demographics data from the file (i.e., non-null values).

Anyone got some wisdom here?
Any insight best practices for debugging issues like this?

[1] I know bb.js is also still under heavy development and AFAICT is still looking to support a wider array of files, etc. If there's a preferred channel for giving more secure feedback to widen that array please let me know.
[2] For posterity I got that templateId from https://github.com/blue-button/bluebutton.js/blob/master/lib/ccda/demographics.js#L26.

Not all of a procedures's participants are "device"s.

For example the following is silly:

    "device": {
      "name": "General Acute Care Hospital",
      "code": "GACH",
      "code_system": "2.16.840.1.113883.5.111"
    }

The hospital isn't listed as a device; it's listed as Service Delivery Location (templateId = 2.16.840.1.113883.10.20.22.4.32). You'll want to identify devices by [@templateId = '2.16.840.1.113883.10.20.22.4.37']/../playingDevice/code...

(This appears to stem from the use of getElementsByTag at https://github.com/blue-button/bluebutton.js/blob/master/src/core.js#L45, which recurses and finds nested elements, not just direct-children -- which can make the convenience wrappers fail in surprising ways when it doesn't find what it expects at the top of the hierarchy.)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.