cqframework/cql-execution

AgeInYearsAt

Closed this issue · 3 comments

I am running the age.cql example in the README. I am able to execute exec-age.js. When I run the code, the patientResults includes both John Smith and Sally Smith and the evaluatedPatients includes only Sally Smith. I tried modifying the example by changing the birthDate for John Smith to 8/2/2007 but doesn't seem to change the result. Is this expected?

Result from example as written:
joel@ubuntu:~/Documents/clinical_quality_language/Src/java$ node /home/joel/Documents/cql-execution/examples/node/exec-age.js
{
"patientResults": {
"1": {
"Patient": {
"json": {
"id": "1",
"recordType": "Patient",
"name": "John Smith",
"gender": "M",
"birthDate": "1999-02-17T06:15"
},
"id": "1",
"name": "John Smith",
"gender": "M",
"birthDate": "1999-02-17T06:15-08:00",
"records": {}
},
"InDemographic": true
},
"2": {
"Patient": {
"json": {
"id": "2",
"recordType": "Patient",
"name": "Sally Smith",
"gender": "F",
"birthDate": "2007-08-02T11:47"
},
"id": "2",
"name": "Sally Smith",
"gender": "F",
"birthDate": "2007-08-02T11:47-08:00",
"records": {}
},
"InDemographic": true
}
},
"unfilteredResults": {},
"localIdPatientResultsMap": {
"1": {
"AgeAtMP": {}
},
"2": {
"AgeAtMP": {}
}
},
"evaluatedRecords": [
{
"json": {
"id": "2",
"recordType": "Patient",
"name": "Sally Smith",
"gender": "F",
"birthDate": "2007-08-02T11:47"
},
"id": "2",
"name": "Sally Smith",
"gender": "F",
"birthDate": "2007-08-02T11:47-08:00",
"records": {}
}
]
}

Modified code for exec-age.js:
/* eslint-disable
no-console,
*/
const cql = require('../../src/cql');
const measure = require('./age.json');

const lib = new cql.Library(measure);
const executor = new cql.Executor(lib);
const psource = new cql.PatientSource([
{
id: '1',
recordType: 'Patient',
name: 'John Smith',
gender: 'M',
birthDate: '2007-08-02T11:47'
},
{
id: '2',
recordType: 'Patient',
name: 'Sally Smith',
gender: 'F',
birthDate: '2007-08-02T11:47'
}
]);

const result = executor.exec(psource);
console.log(JSON.stringify(result, undefined, 2));

Result after modifying example:
joel@ubuntu:~/Documents/clinical_quality_language/Src/java$ node /home/joel/Documents/cql-execution/examples/node/exec-age.js
{
"patientResults": {
"1": {
"Patient": {
"json": {
"id": "1",
"recordType": "Patient",
"name": "John Smith",
"gender": "M",
"birthDate": "2007-08-02T11:47"
},
"id": "1",
"name": "John Smith",
"gender": "M",
"birthDate": "2007-08-02T11:47-08:00",
"records": {}
},
"InDemographic": true
},
"2": {
"Patient": {
"json": {
"id": "2",
"recordType": "Patient",
"name": "Sally Smith",
"gender": "F",
"birthDate": "2007-08-02T11:47"
},
"id": "2",
"name": "Sally Smith",
"gender": "F",
"birthDate": "2007-08-02T11:47-08:00",
"records": {}
},
"InDemographic": true
}
},
"unfilteredResults": {},
"localIdPatientResultsMap": {
"1": {
"AgeAtMP": {}
},
"2": {
"AgeAtMP": {}
}
},
"evaluatedRecords": [
{
"json": {
"id": "2",
"recordType": "Patient",
"name": "Sally Smith",
"gender": "F",
"birthDate": "2007-08-02T11:47"
},
"id": "2",
"name": "Sally Smith",
"gender": "F",
"birthDate": "2007-08-02T11:47-08:00",
"records": {}
}
]
}

The evaluatedRecords is actually intended just to list which records were actually processed during execution. It seems like it should include John Smith too -- but regardless, that is not where you should expect to see results. The results are found in patientResults, which (luckily) has both John and Sally.

Here are your initial patientResults, pretty-printed:

{
  "1": {
    "Patient": {
      "json": {
        "id": "1",
        "recordType": "Patient",
        "name": "John Smith",
        "gender": "M",
        "birthDate": "1999-02-17T06:15"
      },
      "id": "1",
      "name": "John Smith",
      "gender": "M",
      "birthDate": "1999-02-17T06:15-08:00",
      "records": {}
    },
    "InDemographic": true
  },
  "2": {
    "Patient": {
      "json": {
        "id": "2",
        "recordType": "Patient",
        "name": "Sally Smith",
        "gender": "F",
        "birthDate": "2007-08-02T11:47"
      },
      "id": "2",
      "name": "Sally Smith",
      "gender": "F",
      "birthDate": "2007-08-02T11:47-08:00",
      "records": {}
    },
    "InDemographic": true
  }
}

The top-level keys ("1", "2") are the patient ids. Below them each key is a CQL expression name ("Patient" and "InDemographic"). In the Patient context, CQL automatically includes a Patient expression for the current patient (which is why you see it in the result). The InDemographic expression relates to this definition in the CQL:

define InDemographic:
    AgeInYearsAt(start of MeasurementPeriod) >= 2 and AgeInYearsAt(start of MeasurementPeriod) < 18

For each of the patient results, you'll see that they have "InDemographic": true. This makes sense because the MeasurementPeriod is the calendar year 2013, and both were between the ages of 2 and 18 on Jan 1, 2013. If you change one of their birthdays to be in the 1980s, for example, then I'd expect to see InDemographic change to false.

So, with the possible exception of a missing entry in evaluatedRecords (which I think is likely not relevant for you), it seems to be working correctly.

Sorry, I'm just starting to learn CQL. I didn't realize that defining the InDemographic expression would create a property in the resulting JSON object. This is very helpful. Thank you for the thorough explanation.

You're welcome. This isn't so much a detail of CQL as it is a detail of how cql-execution implements CQL. BTW, thank you for raising this anyway. I found the bug related to evaluatedRecords and am fixing it now.