/*
Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
This file is part of CamCOPS.
CamCOPS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CamCOPS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
*/
#include "icd9cm.h"
#include <QDebug>
#include <QMap>
#include <QObject>
const QString Icd9cm::XSTRING_TASKNAME("icd9cm");
const QString RANGE_PREFIX("range"); // in string names
// ============================================================================
// Main functions
// ============================================================================
Icd9cm::Icd9cm(CamcopsApp& app, QObject* parent,
bool dummy_creation_no_xstrings) :
DiagnosticCodeSet(app, XSTRING_TASKNAME, "ICD-9-CM",
parent, dummy_creation_no_xstrings)
{
m_creation_stack.push(DepthItemPair(0, nullptr)); // root: depth 0, no parent
addIcd9cmCodes(BASE_CODES);
}
void Icd9cm::addIcd9cmCodes(const QStringList& codes)
{
// Conceptually: as for Icd10.
for (const QString& c : codes) {
const QString desc = xstring(c);
const bool show_code_in_full_name = !c.startsWith(RANGE_PREFIX);
addIndividualIcd9cmCode(c, desc, show_code_in_full_name);
// Any special sub-codes?
const int length = c.length();
if (length == 5 && c.startsWith("295.")) {
// Types of schizophrenia
addSchizophrenia(c, desc);
} else if (length == 5 && c.startsWith("296") && (c.endsWith('0') ||
c.endsWith('1') ||
c.endsWith('2') ||
c.endsWith('3') ||
c.endsWith('4') ||
c.endsWith('5') ||
c.endsWith('6'))) {
// Episodic affective disorders, 296.0 - 296.6
addEpisodicAffective(c, desc);
} else if (length == 5 && (c.startsWith("303") ||
c.startsWith("304") ||
c.startsWith("305"))) {
// Substance-induced disorders
// The sub-codes often have a different heading from the
// main stem, in which case we specify them separately with the
// strings having an "x" suffix.
QString subdescprefix;
if (c == "303.0" ||
c == "305.0" ||
c == "305.2" ||
c == "305.3" ||
c == "305.4" ||
c == "305.5" ||
c == "305.6" ||
c == "305.7" ||
c == "305.8" ||
c == "305.9") {
subdescprefix = xstring(c + "x");
} else {
subdescprefix = desc;
}
addSubstance(c, subdescprefix);
}
}
}
void Icd9cm::addIndividualIcd9cmCode(const QString& code, const QString& desc,
const bool show_code_in_full_name)
{
if (code.isEmpty()) {
qCritical() << Q_FUNC_INFO << "zero-length code! Ignoring";
return;
}
// Establish depth of new one
int depth = code.length();
// do any depth modifications here, if required:
if (code.startsWith(RANGE_PREFIX)) {
// longer description, but higher in the hierarchy
depth = 1;
}
while (depth <= m_creation_stack.top().first) {
m_creation_stack.pop();
}
DiagnosticCode* parent = m_creation_stack.top().second;
const bool selectable = (
(code.length() > 4 && !code.startsWith(RANGE_PREFIX)) ||
// plus some specific ones with no children:
code == "311" ||
code == "316" ||
code == "317" ||
code == "319"
);
DiagnosticCode* newchild = addCode(parent, code, desc, selectable,
show_code_in_full_name);
m_creation_stack.push(DepthItemPair(depth, newchild));
}
void Icd9cm::addSubcodes(const QString& basecode,
const QString& basedesc,
const QVector<CodeDescriptionPair>& level1)
{
for (const auto& extra1 : level1) {
const QString code = QString("%1%2").arg(basecode, extra1.first);
const QString desc = QString("%1, %2").arg(
basedesc, xstring(extra1.second));
addIndividualIcd9cmCode(code, desc);
}
}
// ============================================================================
// Episodic affective disorders
// ============================================================================
const QVector<Icd9cm::CodeDescriptionPair> Icd9cm::EPISODIC_AFFECTIVE_L1{
// The 296.x0 - 296.x6 codes
{"0", "affective_x0"},
{"1", "affective_x1"},
{"2", "affective_x2"},
{"3", "affective_x3"},
{"4", "affective_x4"},
{"5", "affective_x5"},
{"6", "affective_x6"},
};
void Icd9cm::addEpisodicAffective(const QString& basecode,
const QString& basedesc)
{
addSubcodes(basecode, basedesc, EPISODIC_AFFECTIVE_L1);
}
// ============================================================================
// Substance-induced
// ============================================================================
const QVector<Icd9cm::CodeDescriptionPair> Icd9cm::SUBSTANCE_L1{
// The 304.x0 - 304.x3 (and 305.x0 - 305.x3) codes
{"0", "substance_x0"},
{"1", "substance_x1"},
{"2", "substance_x2"},
{"3", "substance_x3"},
};
void Icd9cm::addSubstance(const QString& basecode, const QString& basedesc)
{
addSubcodes(basecode, basedesc, SUBSTANCE_L1);
}
// ============================================================================
// Schizophrenia
// ============================================================================
const QVector<Icd9cm::CodeDescriptionPair> Icd9cm::SCHIZOPHRENIA_L1{
// The 295.x0 - 295.x5 codes
{"0", "schizophrenia_x0"},
{"1", "schizophrenia_x1"},
{"2", "schizophrenia_x2"},
{"3", "schizophrenia_x3"},
{"4", "schizophrenia_x4"},
{"5", "schizophrenia_x5"},
};
void Icd9cm::addSchizophrenia(const QString& basecode, const QString& basedesc)
{
addSubcodes(basecode, basedesc, SCHIZOPHRENIA_L1);
}
// ============================================================================
// Main codes
// ============================================================================
const QStringList Icd9cm::BASE_CODES{
"range_290_294",
"290",
"290.0",
"290.1",
"290.10",
"290.11",
"290.12",
"290.13",
"290.2",
"290.20",
"290.21",
"290.3",
"290.4",
"290.40",
"290.41",
"290.42",
"290.43",
"290.8",
"290.9",
"291",
"291.0",
"291.1",
"291.2",
"291.3",
"291.4",
"291.5",
"291.8",
"291.81",
"291.82",
"291.89",
"291.9",
"292",
"292.0",
"292.1",
"292.11",
"292.12",
"292.2",
"292.8",
"292.81",
"292.82",
"292.83",
"292.84",
"292.85",
"292.89",
"292.9",
"293",
"293.0",
"293.1",
"293.8",
"293.81",
"293.82",
"293.83",
"293.84",
"293.89",
"293.9",
"294",
"294.0",
"294.1",
"294.10",
"294.11",
"294.2",
"294.20",
"294.21",
"294.8",
"294.9",
"range_295_299",
"295",
"295.0",
"295.1",
"295.2",
"295.3",
"295.4",
"295.5",
"295.6",
"295.7",
"295.8",
"295.9",
"296",
"296.0",
"296.1",
"296.2",
"296.3",
"296.4",
"296.5",
"296.6",
"296.7",
"296.8",
"296.80",
"296.81",
"296.82",
"296.89",
"296.9",
"296.90",
"296.99",
"297",
"297.0",
"297.1",
"297.2",
"297.3",
"297.8",
"297.9",
"298",
"298.0",
"298.1",
"298.2",
"298.3",
"298.4",
"298.8",
"298.9",
"299",
"299.0",
"299.00",
"299.01",
"299.1",
"299.10",
"299.11",
"299.8",
"299.80",
"299.81",
"299.9",
"299.90",
"299.91",
"range_300_316",
"300",
"300.0",
"300.00",
"300.01",
"300.02",
"300.09",
"300.1",
"300.10",
"300.11",
"300.12",
"300.13",
"300.14",
"300.15",
"300.16",
"300.19",
"300.2",
"300.20",
"300.21",
"300.22",
"300.23",
"300.29",
"300.3",
"300.4",
"300.5",
"300.6",
"300.7",
"300.8",
"300.81",
"300.82",
"300.89",
"300.9",
"301",
"301.0",
"301.1",
"301.10",
"301.11",
"301.12",
"301.13",
"301.2",
"301.20",
"301.21",
"301.22",
"301.3",
"301.4",
"301.5",
"301.50",
"301.51",
"301.59",
"301.6",
"301.7",
"301.8",
"301.81",
"301.82",
"301.83",
"301.84",
"301.89",
"301.9",
"302",
"302.0",
"302.1",
"302.2",
"302.3",
"302.4",
"302.5",
"302.50",
"302.51",
"302.52",
"302.53",
"302.6",
"302.7",
"302.70",
"302.71",
"302.72",
"302.73",
"302.74",
"302.75",
"302.76",
"302.79",
"302.8",
"302.81",
"302.82",
"302.83",
"302.84",
"302.85",
"302.89",
"302.9",
"303",
"303.0",
"303.0x",
"303.9",
"304",
"304.0",
"304.1",
"304.2",
"304.3",
"304.4",
"304.5",
"304.6",
"304.7",
"304.8",
"304.9",
"305",
"305.0",
"305.0x",
"305.1",
"305.2",
"305.2x",
"305.3",
"305.3x",
"305.4",
"305.4x",
"305.5",
"305.5x",
"305.6",
"305.6x",
"305.7",
"305.7x",
"305.8",
"305.8x",
"305.9",
"305.9x",
"306",
"306.0",
"306.1",
"306.2",
"306.3",
"306.4",
"306.50",
"306.51",
"306.52",
"306.53",
"306.59",
"306.6",
"306.7",
"306.8",
"306.9",
"307",
"307.0",
"307.1",
"307.2",
"307.20",
"307.21",
"307.22",
"307.23",
"307.3",
"307.4",
"307.40",
"307.41",
"307.42",
"307.43",
"307.44",
"307.45",
"307.46",
"307.47",
"307.48",
"307.49",
"307.5",
"307.50",
"307.51",
"307.52",
"307.53",
"307.54",
"307.59",
"307.6",
"307.7",
"307.8",
"307.80",
"307.81",
"307.89",
"307.9",
"308",
"308.0",
"308.1",
"308.2",
"308.3",
"308.4",
"308.9",
"309",
"309.0",
"309.1",
"309.2",
"309.21",
"309.22",
"309.23",
"309.24",
"309.28",
"309.29",
"309.3",
"309.4",
"309.8",
"309.81",
"309.82",
"309.83",
"309.89",
"309.9",
"310",
"310.0",
"310.1",
"310.2",
"310.8",
"310.81",
"310.89",
"310.9",
"311",
"312",
"312.0",
"312.00",
"312.01",
"312.02",
"312.03",
"312.1",
"312.10",
"312.11",
"312.12",
"312.13",
"312.2",
"312.20",
"312.21",
"312.22",
"312.23",
"312.3",
"312.30",
"312.31",
"312.32",
"312.33",
"312.34",
"312.35",
"312.39",
"312.4",
"312.8",
"312.81",
"312.82",
"312.89",
"312.9",
"313",
"313.0",
"313.1",
"313.2",
"313.21",
"313.22",
"313.23",
"313.3",
"313.8",
"313.81",
"313.82",
"313.83",
"313.89",
"313.9",
"314",
"314.0",
"314.00",
"314.01",
"314.1",
"314.2",
"314.8",
"314.9",
"315",
"315.0",
"315.00",
"315.01",
"315.02",
"315.09",
"315.1",
"315.2",
"315.3",
"315.31",
"315.32",
"315.34",
"315.35",
"315.39",
"315.4",
"315.5",
"315.8",
"315.9",
"316",
"range_317_319",
"317",
"318",
"318.0",
"318.1",
"318.2",
"319",
"range_V71_V82",
"V71.09",
};