Showing posts with label DAE inputs. Show all posts
Showing posts with label DAE inputs. Show all posts

Friday, August 2, 2019

Which Executables Work With Which Masks Files?

QUESTION:
Which Executables Work With Which Masks Files?

ANSWER:
Our code base is effectively split into the original branch which supports ICD9cm codes and the new branch which supports ICD10 codes.

The original branch has version numbers which begin with f (for "federal") while the new branch has version numbers which start with v. The original branch starts with f2 and ends with f32. The new branch starts with v33 and is currently up to v36.

In order to assign a DRG, you need both the logic (which we encode in the software) and the attributes or "masks" (which we encode in masks files).

The original branch is backwardly compatible: f32 has all the logic for some early version (f6, I believe) up and including f32. (The versions are internally designated with letters, so each executable can only support 26 versions. We have an executable and masks which support f2-f5 but that combination is a special order item).

The new branch is not backwardly compatible: v33 only supports v33, v34 only supports v34, etc. So v36 cannot use v34 masks because it does not have v34 logic in it.

We have a project on the books to combine all the logic into a backwardly compatible super-set, but currently this project is inactive.

Tuesday, December 5, 2017

How Indicate Exemption When Calling Our Software

QUESTION
Please, can you tell me which are the valid values for variable “Exempt” for version 34? I was not able to find anything in the grouper documentation.
 
ANSWER

When the Hospital Acquired Condition (HAC) rules were introduced, some organizations were exempt from them. This meant that our APIs to our DRG Assignment Engine (DAE) had to expanded to accommodate this concept.

As laid out in this post here, there are three different levels of exempt:
  1.  Organization (batch) level: put the exempt flag in the version and all the records will be assumed to be exempt.
  2. Record level: put the exempt flag in the record sent to the DAE and that particular record will be exempt.
  3. Diagnosis level: make the PoA flag for a given Dx code the "exempt" value and that particular Dx code will be exempt.
To send the exempt flag at the batch level, append a lowercase 'e' to the version number, eg '33e'.

To send the record level flag to any API which allows it, pass Exempt flag parameter as nothing (not exempt) or as X. To send the record level flag to DRGFilt, set the "exmp" flag to either X or 1.

To send the exempt flag at the code level, check out this post here.

Tuesday, October 20, 2015

POA Logic Indicator (Exempt Flag)

With the introduction of the Present On Admission concept came three distinct data elements:
  • POA Logic Indicator / Exempt flag: an official grouper parameter which is a record-level flag which tells the grouper whether  or not POA logic (including the Hospital Acquired Condition rules, or HAC);
  • POA Flag: an official grouper parameter which is a diagnosis-level flag which tells the group how to process this code against the HAC rules
  • Have POA Flag: a DRGGroupers software parameters which, when part of our API, tells our software whether or not to look for POA flags
(Since POA comes up in so many contexts, we prefer to call the "POA Logic Indicator" something else: "the exempt-from-HAC flag" or simply "the exempt flag." Be advised that this is not how CMS refers to this data element.)

There are only two legal values for this flag:


X - Exempt from POA reporting
Z - Requires POA reporting

Note that "2" seems to be used by the grouper folks to means "throw me an error if there is HAC rule processing to do."

Present On Admission (POA) Flags

Starting with version 33 and ICD10 support, diagnosis codes are supposed to have Present On Admission (POA) flags.

(Unless the institution or patient encounter is "exempt" which would be indicated by the POA Logic Indicator which we call "the exempt flag." The POA Logic Indicator gets its own post to keep confusion to a minimum.)

Here are the CMS definitions of the legal values for this single character flag:

 Flag Meaning
YYes, present at the time of inpatient admission
NNo, not present at the time of inpatient admission
UInsufficient documentation to determine if present on admission
WClinically unable to determine if present at time of admission
1Code is exempt from POA reporting (Used on 4010 form)
BlankCode is exempt from POA reporting (Used on 5010 form, effective 01/01/2011)

Many of our APIs have a "Have POA" flag which is something different: the "Have POA" flag is a record-level indication of whether or not there are POA flags in the submitted diagnosis data. The "Have POA" flag is either "y" for yes or "n" for no.

The POA flags are single-character fields at the individual diagnosis code level. There are up to 25 diagnosis codes accepted for DRG assignment and if you are using POA flags, every code should have one.

In their test data set,CMS passes the POA flag to its grouper as the last character of a fixed-width field. We support that methodology in our DRGFilt product's fixed-with mode and in our C-callable DLL as these are environments in which appending an indicator is relatively easy.

We also support passing in separate POA flag fields in our DRGFilt product's CSV mode and in our VB-callable DLL as there environments generally have better support for separate fields than for character manipulation.

Wednesday, October 7, 2015

DRGFilt10 New Control File Format, part 3

Today we validated group handling in our new DRGFilt Control File; the group name is given in square brackets and every configuration item until the next group is part of the current group.

DRGFilt10 now only processes the configuration information in the active group. The default active group is "drgfilt".  You can either specify an active group on the command line or let the default active group be used.

Therefore the new DRGFilt10 syntax is this:

drgfilt10 {ini-file-name} [group-name]

For example, we are validating with a control file called "v33.ini". That control file defines several jobs:
  • "fixed" defines the job to process the standard CMS test data set
  • "csv" defines the job to process the CSV we created from the CMS file
  • "csv-validate" defines the job which creates output for our validator
When we want to run the job to process the standard CMS test data set, we run this command:

drgfilt10 v33.ini fixed < TESTDB > output.fixed 

We choose to use the Unix-style filter feature of DRGFilt, but the new control file allows us to specify an input file, an output file, or both or neither.

Here is a sample DRGFilt control file which documents all the currently supported features:

; new format DRGFilt control file, with different groups for different purposes

;---------------
; this group is to process the standard fixed-width input file from CMS
;---------------
[fixed]
format = fixed          ; input file format
verbose = 0             ; no debugging information
blip = 1000             ; give progress report every 1,000 records
batchver = 33           ; assign version 33 DRGs to this batch
maskdir = .             ; directory in which to find drgmasks.v33

; fixed-width input variables: name = length@offset
age =   3@0
sex = 1@3
ds =  2@4
dxl=8           ; dx length does not require an offset
poa= 7
dx = 200@23
sgl=7@0         ; pr length, offset is optional & ignored
surg= 175@223
exmp = 1@6
; -----
; these are already present from the CMS grouper:
; you could overwrite the incoming values if you wanted to
; drg = 3@603
; mdc = 2@600

; rc = 2@598
; -----

; these are written out by DRGFilt
rc  = 2@1760
mdc = 2@1762
drg = 3@1764

;---------------
; this group is to validate date-handling of a CSV
;---------------
[csv-adt]
format = csv (,)        ; separator character is in parens
base = 0                ; field indices are zero-based, as opposed to 1-based, etc
headers = 1             ; 1=want column headers, 0=no headers
crlf = 0                ; type of end-of-line: 0=crlf (DOS), 1=lf (Unix)
blip = 1000             ; give progress report every 1,000 records
maskdir = .             ; directory in which to find drgmasks.v33
batchver = 33           ; the DRG version to apply to this entire batch
infile = adt.csv        ; input file name
outfile = x.csv         ; output file name
;outfile = blank file.csv
verbose = 1             ; give debugging output

; input variables: name = index
inid = 0
bdt =  1
sex = 2
exmp = 3
ds =  4
; these there keywords are allowed to have lists as parameters.
; lists can contain single entries, ranges, or both. for example
; 1,2,7-22,50
dx = 5-29
poa = 30-54
surg= 55-79
adt = 80
; calcver gives the index of a field to be used as the date from which
; we calculate the appropriate DRG version. If any record's calculated
; DRG version does not match the batchver, we skip that record
calcver = 80            ; NOTE: same index as "adt" because we are using the same field

; these are written out by DRGFilt
outid = 0               ; patient ID from input, whatever inid pointed to
rc  = 1
mdc = 2
drg = 3
desc = 4
weight = 5
morp = 6
outver = 7

;---------------
; this group is to process the CSV we created from the standard fixed-width input file from CMS

;---------------
[csv]
format = csv (,) ; separator character is in parens
base = 0 ; indices are zero-based
;base = 1 ; indices are one-based
headers = 1 ; 1=want column headers, 0=no headers
crlf = 0 ; type of end-of-line: either crlf or lf
blip = 1000
batchver = 33
maskdir = .
infile = testdbv33.csv
outfile = testdb.out.csv

; input variables: name = index
inid = 0
age =  1
sex = 2
exmp = 3
ds =  4
dx = 5-29
poa = 30-54
surg= 55-79

; these are written out by DRGFilt
outid = 0 ; patient ID from input
rc  = 1
mdc = 2
drg = 3
desc = 4
weight = 5
morp = 6
outver = 7

;---------------
; this group is to process the CSV we created from the standard fixed-width input file from CMS
;---------------
[csv-validate]
format = csv (,) ; separator character is in parens
base = 0 ; indices are zero-based
;base = 1 ; indices are one-based
headers = 0 ; 1=want column headers, 0=no headers
crlf = 0 ; type of end-of-line: either crlf or lf
blip = 1000
maskdir = .
batchver = 33
infile = testdbv33.csv
outfile = testdb.validate.csv
verbose = 1

; input variables: name = index
inid = 0
age =  1
sex = 2
exmp = 3
ds =  4
dx = 5-29
poa = 30-54
surg= 55-79

; these are written out by DRGFilt
outid = 0 ; patient ID from input
drg = 1

; eof

Thursday, August 21, 2014

Valid Discharge Status Values

We are often asked what the list of valid discharge status values is. Here is a link to a PDF from CMS which answers that question as of March 6th, 2014:

Discharge Status List

Monday, August 18, 2014

Data Needed To Assign a DRG

We are often asked what fields we need to assign a CMS (US Federal) DRG.


We need the following fields to assign a CMS DRG to an inpatient encounter:
  1. The list of diagnoses, with the Primary diagnosis as the first code.
  2. The list of procedures, if any.
  3. The patient's age-on-admission
  4. The patient's sex (Male, Female, Other, Unknown)
  5. The patient's discharge status (use zero for "Unknown" and 20 for expired)
    1. Home
    2. Other Hospital
    3. Skilled Nursing Facility (SNF)
    4. Intensive Care Facility (ICF)
    5. Other Institution (eg nursing home)
    6. Home Care (VNA, etc)
    7. Against Medical Advice (AMA)
And that is all that is needed.

Notes

  • Using age-on-discharge usually returns a valid DRG.
  • For our DRG Assignment Service...
    • we usually want an encounter ID against which to return the DRG.
    • We are happy to calculate the age-on-admission from a date of birth and an admission date.

Friday, January 25, 2013

ICD Codes & MS-Excel (Leading Zeroes)

Each year CMS publishes a data set to help users validate their DRG assignments for that year's DRG version.

We use the official CMS test data set to confirm that our DRG assignments are correct. The data set arrives as a text file which we use in a variety of ways:

  1. we use the text file as-is to validate DRGFilt
  2. we extract & pretty-print random cases to validate our interactive products
    1. CGI-DRG under Windows
    2. CGI-DRG under Linux
    3. Access-DRG under Windows
    4. C-callable DLL under Windows
    5. Linux DLL under Linux
    6. PHP shared object under Linux
    7. Perl shared object under Linux
    8. C shared object under Linux
  3. we reformat the text file as a CSV in order to validate Excel-DRG
(Many of these exercises are being done twice as we validate our ICD10-based code base.)

It is item 3 that gave us fits this for a long-standing reason: MS-Excel's CSV import insists on stripping leading zeroes for values it imports if those values are all-numeric. This wreaks havoc on ICD9 or ICD10 codes, either of which can start with one or more zeroes and be all digits for the rest of the code.

There are tricks for formatting the code so that it appears to have its leading zeroes, but that does not help, because the actual data remains the stripped version, which is just plain wrong.

We have painfully rediscovered the only way we know of to fix this (although we welcome suggestions of better ways to do this)
  1. give your CSV the ".txt" extension, eg "testdb.txt" and NOT "testdb.csv"
  2. use the Excel Data->Import->text file function
  3. choose your text file from the list of available files
  4. in the import dialogue, specify that the delimiter is comma
  5. at step three, highlight any ICD9 or ICD10 columns and specify that the format is "Text"
  6. import and confirm

TECHNIQUES WHICH DO NOT WORK

If you are trying to use the native Excel Import function on a file with the CSV extension, eg "testdb.csv", we tried the following ideas without success. Most of these ideas were found on the Internet, free and worth every penny.

  • Encasing the data in double-quotes, eg "0016071"
  • Using a single-quote at the start of the code, eg '0016071
  • Making the value into a formula, eg ="0016071"
  • Using a leading blank and double-quotes, eg " 0016071"

Thursday, January 5, 2012

Estimated CMI?

Your query to DRGGroupers.com:
My Boss wants an estimated CaseMixIndex  within 24 hours of admission.  I know that we have to default some fields, i.e. discharge status.  He wants me to compare the CMI using the 24 hours of data with the final CMI assigned after discharge.  Is this possible?  Does it even make sense for us to try?  Look forward to your response. 

Our reply:

Technologically, this is not hard. However it is not clear that the results would be meaningful, but that is your boss's call.

To assign a DRG, you need the following data elements:

(a) sex
(b) age
(c) diagnoses
(d) procedures
(e) discharge status

In the first 24 hours of an inpatient encounter, you would know the sex and age of the patient. You could assume that the discharge status will be "home" which will be very wrong sometimes. You could use the notoriously inaccurate admitting diagnosis and whatever procedures were performed immediately for the diagnoses and procedures.

Friday, September 9, 2011

How Many DX Codes?

QUESTION

Your documentation states that the groupers currently only utilize up to nine diagnosis codes. Are you planning on increasing that number to 25 in conjunction with the recent changes CMS has implemented?

ANSWER

Our ICD9-based DRG Assignment Engine supports up to 15 diagnosis codes. Our ICD10 prototype currently supports 30 diagnosis codes, but we only commit to supporting the expected 25.

Tuesday, May 26, 2009

How to Use POA

QUESTION

As yoyu know, DRG versions 25 and up require the use of the Present On Admission (POA) indicator associated with ICD9 diagnosis codes for the grouping of DRGs. Your grouper software does support versions 25 and 26, but no where in your documentation do I find any reference to POAs and how they should be fed into the data file, or defined in the control file.

We need this information asap in order to ensure that the grouper is working correctly. Please email or call me at your earliest convenience.

ANSWER

Please find attached our most recent documentation, which has a healthy entry in the Index under POA.

I am not sure which of our products you are using, but POA should be supported across the product line. To quote the docs on POA support in general:

Note: as of version 26, released in 2008, the DRG version can have either
a 'p' or an 'e' or both appeneded to it. If there is a trailing 'p', it
is assumed that the last character of every diagnosis code is a POA flag.
If the there is a trailing 'e', then the source institution is presumed
to be exempt from the HAC. Thus "26p" specifies POA support, while "26"
does not. "25p" does not make sense.

To quote the glossary on POA:
In order to avoid paying for medical mistakes, diagnoses are now
flagged as having been present on admission (POA).

The values for the POA flag are not, as one might expect, simply
Y or N; rather the following options are defined:

-Y for Yes
-N for No
-U for Unspecified
-W for clinically undetermined
-1 for unreported / not used / exempt from reporting
To quote from Chapter 5, on our DRGFilt product:
The keyword "poa " specifies where, in the diagnosis code, to find the
POA flag. If the diagnosis code length (specified by dlx) is 8, it is
typical to find the POA flag at offset 7, that is to say the last character
of every code.

The keyword "exmp" specifies that the institution from which these data
come is exempt from the HAC.

Note that if neither of these keywords is present, the software assumes that
POA is irrelevant and that the source institution is to be treated as exempt
from the HAC.

Wednesday, November 14, 2007

Common Data Formatting Issues

QUESTION

As a test I'm regrouping some claims from the Medicare Inpatient SAF (LDS), and about 10% of the time, the results from the grouper do not match CMS's results. (Specifically, for around 1.2M claims, out of about 10M).

Some details:
  • We're using the newest grouper executable.
  • Mask version: 21 
  • Claim Through Dates: 2003-Q4 through 2004-Q3
The return codes are almost always 0 but the results often do not match. Sometimes it's b/c we don't have exact ages (everyone under 65 is just listed as 65; we don't have better info than that in the LDS SAF).

The biggest example, for each quarters:
  • Your grouper's result: 518
  • CMS-assigned DRG: 527
We have checked & rechecked the input files, control files etc. Everything looks right. The grouper return codes are good, and totaling the PFLAGs and DFLAGs shows no inconsistencies.

ANSWER

We test against the CMS grouper all the time, so this is baffling.

To really see, we would need an example or two (scrubbed of identifiers, preferably). While it is possible that our grouper has a bug in it, we are pleased to report that this is exceedingly rare. Typically, the issues we see are data handling or trivial-seeming formatting issues:
  • stripping leading zeroes from ICD9 codes
  • leading whitespace on ICD9 codes
  • non-contiguous ICD9 codes 
  • discharge disposition coding
But why guess? Send us a few records--10? 100?--and we will see what we see.