All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.imsweb.algorithms.iarc.IarcUtils Maven / Gradle / Ivy

Go to download

Java implementation of cancer-related algorithms (NHIA, NAPIIA, Survival Time, etc...)

There is a newer version: 5.0
Show newest version
/*
 * Copyright (C) 2018 Information Management Services, Inc.
 */
package com.imsweb.algorithms.iarc;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang3.math.NumberUtils;

import com.imsweb.algorithms.internal.Utils;

/**
 * This class is used to calculate the International Primary indicator variable.
 * 

* See http://www.iacr.com.fr/images/doc/MPrules_july2004.pdf/. */ public final class IarcUtils { public static final String ALG_NAME = "IARC Multiple Primary Indicator"; public static final String VERSION = "ICD-O Third Edition released in 2004"; public static final Integer DUPLICATE = 0; public static final Integer PRIMARY = 1; public static final Integer INSITU = 9; private IarcUtils() { // utility class } public static List calculateIarcMp(List records) { //No records if (records == null || records.isEmpty()) return null; //If there is only one tumor if (records.size() == 1) { if (isInsitu(records.get(0))) records.get(0).setInternationalPrimaryIndicator(INSITU); else records.get(0).setInternationalPrimaryIndicator(PRIMARY); return records; } //Calculate the site group and hist group //let's also use a different list so we don't change the order of the original records List internalRecords = new ArrayList<>(); for (IarcMpInputRecordDto rec : records) { //Set IARC as primary by default rec.setInternationalPrimaryIndicator(PRIMARY); rec.setSiteGroup(calculateSiteGroup(rec.getSite())); rec.setHistGroup(calculateHistGroup(rec.getHistology())); internalRecords.add(new InternalRecDto(rec)); } Collections.sort(internalRecords); //Calculate IARC MP variable for (int i = 0; i < internalRecords.size(); i++) { IarcMpInputRecordDto r1 = internalRecords.get(i).getOriginalRecord(); if (DUPLICATE.equals(r1.getInternationalPrimaryIndicator()) || INSITU.equals(r1.getInternationalPrimaryIndicator())) continue; //Insitu cases are ignored except bladder if (isInsitu(r1)) { r1.setInternationalPrimaryIndicator(INSITU); continue; } for (int j = i + 1; j < internalRecords.size(); j++) { IarcMpInputRecordDto r2 = internalRecords.get(j).getOriginalRecord(); //Insitu cases are ignored except bladder if (isInsitu(r2)) { r2.setInternationalPrimaryIndicator(INSITU); continue; } if (r1.getHistGroup() != null && r2.getHistGroup() != null && r1.getSiteGroup() != null && r2.getSiteGroup() != null) { //Kaposi sarcoma or Hemato, no need to check the site if (isKaposiSarcoma(r1, r2) || isHemato(r1, r2) || (isSameSiteGroup(r1, r2) && (isSameHistGroup(r1, r2) || isNosVsSpecific(r1, r2)))) { r2.setInternationalPrimaryIndicator(DUPLICATE); if (needToUpdateHistology(r1, r2)) { r1.setHistology(r2.getHistology()); r1.setHistGroup(calculateHistGroup(r1.getHistology())); } } } } } return records; } private static String calculateSiteGroup(String site) { String siteGroup = site != null && site.length() >= 3 ? site.toUpperCase().substring(0, 3) : null; if (siteGroup != null) { if (Arrays.asList("C01", "C02").contains(siteGroup)) siteGroup = "C02"; else if (Arrays.asList("C00", "C03", "C04", "C05", "C06").contains(siteGroup)) siteGroup = "C06"; else if (Arrays.asList("C09", "C10", "C12", "C13", "C14").contains(siteGroup)) siteGroup = "C14"; else if (Arrays.asList("C19", "C20").contains(siteGroup)) siteGroup = "C20"; else if (Arrays.asList("C23", "C24").contains(siteGroup)) siteGroup = "C24"; else if (Arrays.asList("C33", "C34").contains(siteGroup)) siteGroup = "C34"; else if (Arrays.asList("C40", "C41").contains(siteGroup)) siteGroup = "C41"; else if (Arrays.asList("C65", "C66", "C67", "C68").contains(siteGroup)) siteGroup = "C68"; } return siteGroup; } private static Integer calculateHistGroup(String histology) { Integer histologyGroup = null; if (NumberUtils.isDigits(histology)) { int hist = NumberUtils.toInt(histology); if (Utils.isHistologyContained("8051-8084,8120-8131", hist)) histologyGroup = 1; else if (Utils.isHistologyContained("8090-8110", hist)) histologyGroup = 2; else if (Utils.isHistologyContained("8140-8149,8160-8162,8190-8221,8260-8337,8350-8551,8570-8576,8940-8941", hist)) histologyGroup = 3; else if (Utils.isHistologyContained("8030-8046,8150-8157,8170-8180,8230-8255,8340-8347,8560-8562,8580-8671", hist)) histologyGroup = 4; else if (Utils.isHistologyContained("8010-8015,8020-8022,8050", hist)) histologyGroup = 5; else if (Utils.isHistologyContained("8680-8713,8800-8921,8990-8991,9040-9044,9120-9125,9130-9136,9141-9252,9370-9373,9540-9582", hist)) histologyGroup = 6; else if (Utils.isHistologyContained("9050-9055", hist)) histologyGroup = 7; else if (Utils.isHistologyContained("9840,9861-9931,9945-9946,9950,9961-9964,9980-9987,9991-9992", hist)) histologyGroup = 8; else if (Utils.isHistologyContained("9597,9670-9699,9712,9728,9731-9738,9761-9767,9769,9811-9818,9823-9826,9833,9836,9940", hist)) histologyGroup = 9; else if (Utils.isHistologyContained("9700-9726,9729,9768,9827-9831,9834,9837,9948", hist)) histologyGroup = 10; else if (Utils.isHistologyContained("9650-9667", hist)) histologyGroup = 11; else if (Utils.isHistologyContained("9740-9742", hist)) histologyGroup = 12; else if (Utils.isHistologyContained("9750-9759", hist)) histologyGroup = 13; else if (Utils.isHistologyContained("9590-9591,9596,9727,9760,9800-9809,9820,9832,9835,9860,9960,9965-9975,9989", hist)) histologyGroup = 14; else if (hist == 9140) histologyGroup = 15; else if (Utils.isHistologyContained("8720-8790,8930-8936,8950-8983,9000-9030,9060-9110,9260-9365,9380-9539", hist)) histologyGroup = 16; else if (Utils.isHistologyContained("8000-8005", hist)) histologyGroup = 17; } return histologyGroup; } private static boolean isInsitu(IarcMpInputRecordDto rec) { return !"3".equals(rec.getBehavior()) && !(rec.getSite() != null && rec.getSite().toUpperCase().startsWith("C67")); } private static boolean isKaposiSarcoma(IarcMpInputRecordDto rec1, IarcMpInputRecordDto rec2) { return rec1.getHistGroup() == 15 && rec2.getHistGroup() == 15; } private static boolean isHemato(IarcMpInputRecordDto rec1, IarcMpInputRecordDto rec2) { return rec1.getHistGroup() >= 8 && rec1.getHistGroup() <= 14 && rec2.getHistGroup() >= 8 && rec2.getHistGroup() <= 14 && (rec1.getHistGroup() == 14 || rec2.getHistGroup() == 14 || rec1 .getHistGroup().equals(rec2.getHistGroup())); } private static boolean isSameSiteGroup(IarcMpInputRecordDto rec1, IarcMpInputRecordDto rec2) { return rec1.getSiteGroup().equals(rec2.getSiteGroup()); } private static boolean isSameHistGroup(IarcMpInputRecordDto rec1, IarcMpInputRecordDto rec2) { return rec1.getHistGroup().equals(rec2.getHistGroup()); } private static boolean isNosVsSpecific(IarcMpInputRecordDto rec1, IarcMpInputRecordDto rec2) { //17 is NOS for 1-7, 15 and 16 //14 is NOS for 8-13 //5 is NOS for 1-4 return (rec1.getHistGroup() == 17 && ((rec2.getHistGroup() >= 1 && rec2.getHistGroup() <= 7) || rec2.getHistGroup() == 15 || rec2.getHistGroup() == 16)) || (rec2.getHistGroup() == 17 && ((rec1.getHistGroup() >= 1 && rec1.getHistGroup() <= 7) || rec1.getHistGroup() == 15 || rec1.getHistGroup() == 16)) || (rec1.getHistGroup() == 14 && rec2.getHistGroup() >= 8 && rec2.getHistGroup() <= 13) || (rec2.getHistGroup() == 14 && rec1.getHistGroup() >= 8 && rec1.getHistGroup() <= 13) || (rec1.getHistGroup() == 5 && rec2.getHistGroup() >= 1 && rec2.getHistGroup() <= 4) || (rec2.getHistGroup() == 5 && rec1.getHistGroup() >= 1 && rec1.getHistGroup() <= 4); } private static boolean needToUpdateHistology(IarcMpInputRecordDto primaryRec, IarcMpInputRecordDto dupRecord) { return (primaryRec.getHistGroup() == 17 && ((dupRecord.getHistGroup() >= 1 && dupRecord.getHistGroup() <= 7) || dupRecord.getHistGroup() == 15 || dupRecord.getHistGroup() == 16)) || (primaryRec.getHistGroup() == 14 && dupRecord.getHistGroup() >= 8 && dupRecord.getHistGroup() <= 13) || (primaryRec.getHistGroup() == 5 && dupRecord.getHistGroup() >= 1 && dupRecord.getHistGroup() <= 4) || (primaryRec.getHistGroup().equals(dupRecord.getHistGroup()) && NumberUtils.toInt(primaryRec.getHistology()) < NumberUtils.toInt(dupRecord.getHistology())); } private static class InternalRecDto implements Comparable { IarcMpInputRecordDto _originalRecord; int _year; int _month; int _day; int _seqNum; public InternalRecDto(IarcMpInputRecordDto rec) { _originalRecord = rec; String yearStr = rec.getDateOfDiagnosisYear(); String monthStr = rec.getDateOfDiagnosisMonth(); String dayStr = rec.getDateOfDiagnosisDay(); _year = NumberUtils.isDigits(yearStr) ? Integer.parseInt(yearStr) : 9999; _month = NumberUtils.isDigits(monthStr) ? Integer.parseInt(monthStr) : 99; _day = NumberUtils.isDigits(dayStr) ? Integer.parseInt(dayStr) : 99; if (_month == 99) _day = 99; _seqNum = rec.getSequenceNumber() == null ? -1 : rec.getSequenceNumber(); // the sequence numbers might be used to determine the order; there are two families of sequences: federal (00-59, 98, 99) and non-federal (60-97); // sine the non-federal need to always be after the federal, let's add 100 to all the non-federal (making them 160-197) if (_seqNum >= 60 && _seqNum <= 97) _seqNum += 100; } public IarcMpInputRecordDto getOriginalRecord() { return _originalRecord; } @Override public int compareTo(InternalRecDto other) { if (_year == 9999 || other._year == 9999) return _seqNum - other._seqNum; else if (_year != other._year) return _year - other._year; else { if (_month == 99 || other._month == 99) return _seqNum - other._seqNum; else if (_month != other._month) return _month - other._month; else { if (_day == 99 || other._day == 99 || this._day == other._day) return _seqNum - other._seqNum; else return _day - other._day; } } } @Override @SuppressWarnings("SimplifiableIfStatement") public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; InternalRecDto other = (InternalRecDto)o; if (_year == 9999 || other._year == 9999) return _seqNum == other._seqNum; else if (_year != other._year) return false; else { if (_month == 99 || other._month == 99) return _seqNum == other._seqNum; else if (_month != other._month) return false; else { if (_day == 99 || other._day == 99 || this._day == other._day) return _seqNum == other._seqNum; else return false; } } } @Override public int hashCode() { int result = _year; result = 31 * result + _month; result = 31 * result + _day; result = 31 * result + _seqNum; return result; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy