Tuesday, October 23, 2012

New 32 Bit Windows Reference Platform (f30)

As part of fixing the v30 bug (see posts with "v30 bug" as a label) we tok the opportunity to change our 32 bit Windows reference platform. The previous platform was over a decade old, so we were probably due.

Our 32 bit Windows platform is now:

Microsoft Windows 7 Professional, version 6.1.7601

The new executables work on the old reference platform, and vice versa, so we are not expecting any compatibility issues to arise from this platform change.

New 32 bit Linux Reference Platform (f30)

As part of fixing the v30 bug (see posts with "v30 bug" as a label) we were forced to change our 32 bit Linux reference platform. The previous platform was over a decade old, so we were probably due.

Our 32 bit Linux platform is now:

Linux 2.6.32-42-generic-pae #96-Ubuntu SMP Wed Aug 15 19:12:17 UTC 2012 i686 GNU/Linux

Under 32 bit Linux, our shared Perl object is now built against v5.10.1 and our shared PHP object is now built against 5.3.2-1ubuntu4.18.

Note that this means that we no longer support ancient glibc installations, but we suspect that there are precious few such installations left. However, if you are a customer of ours and you cannot run the new 32 bit Linux executable, we will be able to provide the old 32 bit Linux executables for the remainder of v30's reign--ie until October 1st, 2013.

Sunday, October 14, 2012

V30 Bug Test Case

This post is intended to give users of our various products a test case to ensure the corrected version of our product is in use.

Use the "v30 bug" label to see all the posts about this issue.

TEST CASE
The basic test case is this, from our new testdb.txt (line 18,374): WRONG=DRG 194; CORRECT=DRG 178. Note the Present on Admission (POA) indicators at the end of the diagnosis codes.

----------INPUT REC 18374----------
 age@  0 for  3:018
 sex@  3 for  1:1
  ds@  4 for  2:51
  dx@ 23 for 96:4870   Y|85172  N|48284  Y|69556  Y|E8616  Y                                                        
surg@223 for 98:9503   |9946   |9904   |9144   |9231   |3372   |0016   |9971                                             
 drg@607 for  3:178
 mdc@610 for  2:04
  rc@612 for  2:00
dflg@614 for 15:101100000000000
sflg@629 for 15:000000000000000

TEST CASE IN C
Here is a C program which calls our mhdrg() function on the this test case:

/* tryit.c (c) 2002 M+H Consulting, LLC C-callable demo (BFH) */
/* Sun Oct 14 18:08:14 EDT 2012 BFH test case for v30 bug */
/* Sun Oct  3 11:57:46 EDT 2010 BFH support f28 */
/* 10/06/2008 made win32 and unix versions the same */
/* 10/11/2003 added bit-string of used dx's and used procedures */

#include 
#include 
#include 

#define DELIM "^"
#define RETURNED 10

#ifdef WIN32
/* DLL functions */
extern int mhicd();             /* mhicd.dll */
extern char * mhdrg();          /* mhdrg.dll */
extern char * mherrdesc();      /* mhdrg.dll */
#else
char * mhdrg();
extern char * errdesc();        /* mhdrg.dll */
#endif

int main() {
    char * retval;
    char * p;
    char * a[RETURNED];
    char * expected;
    int i;

    /* f30 test case: bug fix
----------INPUT REC 18374----------
 age@  0 for  3:018
 sex@  3 for  1:1
  ds@  4 for  2:51
  dx@ 23 for 96:4870   Y85172  N48284  Y69556  YE8616  Y                                                        
surg@223 for 98:9503   9946   9904   9144   9231   3372   0016   9971                                             
 drg@607 for  3:178
 mdc@610 for  2:04
  rc@612 for  2:00
dflg@614 for 15:101100000000000
sflg@629 for 15:000000000000000
     */
     expected = "RC: 0 MDC: 04 DRG: 178";

    /* call the grouper, store results in reval */
    retval = mhdrg(
        "f30p",                 /* which DRG version you want */
        "/drbd/mnh/src/SWIG",   /* path to masks files */
        "1",                    /* discharge status */
        "18",                   /* patient age on admission */
        "1",                    /* patient sex (1=male, 2=female) */
        /* ICD DX codes */
        "4870   Y85172  N48284  Y69556  YE8616  Y",
        /* ICD procedure codes */
        "9503   9946   9904   9144   9231   3372   0016   9971   ",
        8,                      /* length of each ICD DX code */
        7                       /* length of each ICD procedure code */
    );

    /* if there was an error, alert the user */
    if (retval == NULL) {
        printf("M+H grouper argument or environment error: %s\n", errdesc());
        exit(-1);
    }

    /* show the raw return value */
    printf("Raw return value from mhdrg:\n%s\n\n",retval);

    /* deconstruct return from mhdrg() */
    p = strtok(retval,DELIM);
    for (i = 0; i < RETURNED && p != NULL; i++) {
        a[i] = p;
        p = strtok(NULL,DELIM);
    }
    /* last two return values are bit-strings of which ICD codes were 
     * used in the grouping 
     */

    puts("Deconstructed return value from mhdrg:");
    printf("rc=%s, mdc=%s, drg=%s, ovn=%s, weight=",a[0],a[1],a[2],a[3]);
#ifdef OLD_WAY
    printf("%s, mean=%s, porm=%s\ndesc=%s\ndx flags:%ld, px flags: %ld\n",a[4],a[5],a[6],a[7],dxu,pxu);
#else
    printf("%s, mean=%s, porm=%s\ndesc=%s\ndx flags:%s, px flags: %s\n",a[4],a[5],a[6],a[7],a[8],a[9]);
#endif

    /* show what we should get */
    printf("\nExpected result: %s\n",expected);

    /* last two return values are bit-strings of which ICD codes were used in the grouping */
    puts("\nSignificant ICD codes:");
#ifdef OLD_WAY
    for (mask = 1L,i = 0; i < 32; i++, mask *= 2L) {
        if (mask & dxu) {
            printf(" * DX code %2d was used\n",(i+1));
        }
    }
    for (mask = 1L,i = 0; i < 32; i++, mask *= 2L) {
        if (mask & pxu) {
            printf(" * Proc code %2d was used\n",(i+1));
        }
    }
#else
    p = a[8];
    for (i = 0; i < 32 && p[i] != '\000'; i++) {
        if (p[i] == '1') {
            printf(" * DX code %2d was used\n",(i+1));
        }
    }
    p = a[9];
    for (i = 0; i < 32 && p[i] != '\000'; i++) {
        if (p[i] == '1') {
            printf(" * Proc code %2d was used\n",(i+1));
        }
    }
#endif
    exit(0);
}
/* eof */

TEST CASE IN CGI-DRG
Here is an example of how the DAE failure looked in our CGI-DRG product:

Before fix: incorrect DRG of 194

M+H CGI CMS (HCFA) DRG Grouper (3.0:f30)

Version:  POA:  Exempt:  Age:  Sex:  Discharge Status: 
	    Diagnoses 1-5: *     *   
	   Diagnoses 6-10:           
	  Diagnoses 11-15:           

	   Procedures 1-5:                
	  Procedures 6-10:                
	 Procedures 11-15:                

						

DRG: 194 SIMPLE PNEUMONIA & PLEURISY W CC                                      
MDC:  4  Weight: 0.9996 Mean LOS: 0.00 Version: f30

© 2002-2012 M+H Consulting LLC, all rights reserved

After fix: correct DRG of 178

M+H CGI CMS (HCFA) DRG Grouper (3.0:f30)

Version:  POA:  Exempt:  Age:  Sex:  Discharge Status: 
	    Diagnoses 1-5: *   * *   
	   Diagnoses 6-10:           
	  Diagnoses 11-15:           

	   Procedures 1-5:                
	  Procedures 6-10:                
	 Procedures 11-15:                

						

DRG: 178 RESPIRATORY INFECTIONS & INFLAMMATIONS W CC                           
MDC:  4  Weight: 1.4403 Mean LOS: 0.00 Version: f30

© 2002-2012 M+H Consulting LLC, all rights reserved

V30 Bug

This post is an overview of an issue with the v30 DRG Assignment Engine (DAE) and our response to it. Related posts will have the label "v30 bug" in order to make them easier to find. This post will be updated as the status changes.

Current status (Oct 24 2:27pm Eastern)
The issue in regression testing under 32 bit Linux was hard enough to resolve that we upgraded the 32 bit Linux reference platform instead (for details, go here). While we were upgrading reference platforms, we also upgraded the Windows reference platform (for details, go here).

We have finished the in-house rebuild and revalidation of our products. We are currently rebuilding the products built using  a porting lab, at which point we will be ready to update our web site and start sending out free updates to customers. We have already begun sending out free updates to customers with standing orders.

History of Bug Fix

On October 11 at about 10am
Customer Service received a bug report:

One of our customers asked about a change in V30 that maps a dx of 487.0 with one 1 of 11 secondary pneumonia dx's to DRGs 177-179. In previous versions this combo would map to DRGs 193-195. She claims this change is in the specs of the final release. Our grouper is mapping this combo to the old DRGs of 193-195.

October 11 at about 10:30am
Tech Support punted this issue to Development.

October 12 at about 6pm
Development delivers a fix to Tech Support:

The problem was in the CC exclusion logic, requiring a change to the DAE, so all DRG assigning products will have to be re-released.

When the DAE was delivered the first time, you noticed that the test file did not do a very good job of covering the DRGs, and we said we would look into finding the latest one with better cover. which we did. When we ran against the new test file, there were over 200 mismatches. These turned out to be cases with more than 15 diagnoses or procedures. So we upped our limit to 25 which required changes to DRGFilt and it control file, cntl.f30.

Note that drgmasks.f30 did NOT change so you only have to redeliver the DAE itself (drgfilt, dll, shared object, etc).

October 13, various
Tech Support drew up their roll-out plan:
  1. create this overview post
  2. document a test case or two so users can confirm DAE status
  3. revalidate product line with new DAE and new test DB
  4. update our manual's "What's New" to reflect this bug
  5. have Customer Service approve documentation changes
  6. update web site with new products
  7. send updates for standing orders
  8. send updates for orders from the web site
Plan approved; plan execution begins.

October 14, various
Tech Support  continues executing plan.

Thursday, October 4, 2012

V30 Open Issues

10/4/12 11:03 AM Eastern
We have completed our V30 release with two open issues:
  1. Our 64 Bit Linux Perl Shared Object is still built against Perl v5.8.8, which is on the old side of the pre-5.10 divide. We can (and do) build against 5.10, but still in a developmental mode: we have yet to add the 5.10+ product to our catalogue. We haven't figured out what to call it: any suggestions?
  2. We have a similar issue with our 64 Bit Linux PHP Shared Object: we still build against a rather old PHP and need to have our developers create a production environment in which to build a newer object. We also need to update our catalogue to reflect this.
If you are looking to run the newer version of either of this products in the near future, please buy the  older version and send email to techsupport@drggroupers.com so we can send you the newer version by hand.

10/23/12 3:12PM Eastern
As part of our f30 bug fix, we changed our 32 bit Linux platform, which changed the PHP and Perl versions against which our 32 Linux shared objects are created:

32 bit Linux Perl version: v5.10.1
32 bit Linux PHP version: 5.3.2-1ubuntu4.18

So even if you are running 64 bit Linux, you might want our 32 bit Linux shared object, because most 64 Linux systems can run 32 bit versions of software and these versions are across important divides from our 64 bit versions.

Wednesday, October 3, 2012

DRGFilt Control File Change for V30: dxc & sgc

The ancient and venerable DRGFilt control file syntax has changed slightly for v30, released in October of 2012. The change is the addition of two new keywords, "dxc" and "sgc" and they stand for "diagnosis count" and "surgery/procedure count" respectively.

The problem they solve are records with 15 dx or 15 procedures. Since drgfilt's cntl file mechanism only has a two-digit length, it cannot directly specify all 15 when they are spaced as on these test records.

When these values are present, they are multiplied in drgfilt by the dxl and/or sgl and override the lengths on the dx and sg cards.

For example, our internal control file to process the Federal test data now looks like this:

age  000 03
sex  003 01
ds   004 02
dxl  000 08
dxc  000 15
poa  000 07
dx   023 96
sgl  000 07
sgc  000 15
surg 223 98
#drg  603 03
#mdc  600 02
#rc   598 02
exmp 006 01
# these are written out by us
drg  607 03
mdc  610 02
rc   612 02
dflg 614 15
sflg 629 15

Monday, October 1, 2012

New in V30

The DRG definitions were finalized early this year, allowing us to ship products on September 28, 2012 instead of our usual target of the first week in October.

This is a quiet year for DRG version change. The only real DRG change we have to report is the addtion of two new HACs (see glossary), 13 and 14.

Probably also because of the impending switch from ICD9 to ICD10, there are no new or revised or deleted ICD-9-CM diagnosis codes for V30. There are also no revised or deleted ICD-9-CM procedure codes for V30 and only one new procedure code:

00.95    Injection or infusion of glucarpidase

For details, visit the CMS site:

https://www.cms.gov/Medicare/Coding/ICD9ProviderDiagnosticCodes/

Conversion from ICD9 codes for diagnoses and procedures to ICD10 codes is still coming, but it isn't here yet. We will continue to produce ICD10 versions of our products as an aid to cutting over.