/*
* (C) Copyright 2013 The Board of Trustees of the University of Illinois
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of The Board of Trustees of the University of
* Illinois
*
* Contributors: HLN Consulting, LLC and other members of the
* SHARPS DS2 team, http://sharps.org/
*
*
*/
package org.sharps.ds2.predicate;
import java.io.IOException;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;
import org.sqlite.SQLiteConfig;
/**
* Loads and stores counts suitable for creating 2-way contingency tables
* between target conditions (e.g., HIV) and risk factors/correlated conditions
* (e.g., Kaposi Sarcoma).
*
* The data structures are: A pair of HashMaps to store YES and NO counts for
* the target conditions (e.g., 20,000 HIV YES in patient population; 4,000,000
* HIV NO); and a pair of HashMaps of HashMaps to store YES and NO counts for
* the target conditions limited by patients who have the risk factor conditions
* (e.g., 449 Kaposi Sarcoma patients are HIV YES; 71 Kaposi patients are HIV
* NO).
*
*/
public class Counts implements Serializable {
/**
* "Counts" requires a database with the following schema (plus indexes):
*
* <code>
*
* --
* -- CCS category table
* --
* -- Table Name: properties.getProperty("concept_table_name");
*
* CREATE TABLE "SHARPS_HIV2_DX_CATEGORY"
* (
* "CCS_ID" NUMBER NOT NULL,
* "NAME" VARCHAR2(512) NOT NULL
* );
*
*
* --
* -- Statistics table: contains targetConcent (outer) and
* -- risk factor concept (inner) counts
* --
* -- Table Name: properties.getProperty("bayes_statistics_table_name")
*
* CREATE TABLE BAYES_STATS
* (
* CCS_ID_OUTER NUMBER NOT NULL,
* CCS_ID_INNER NUMBER,
* COUNT_YES NUMBER NOT NULL,
* COUNT_NO NUMBER NOT NULL
* );
*
* </code>
*/
private static final String PROPERTIES_FILENAME = "/org/sharps/ds2/predicate/naivebayespredicate.properties";
HashMap<String, Long> targetConceptYesMap;
HashMap<String, Long> targetConceptNoMap;
HashMap<String, HashMap<String, Long>> riskFactorYesMap;
HashMap<String, HashMap<String, Long>> riskFactorNoMap;
ArrayList<Concept> conceptList;
HashMap<String, String> conceptMap;
public Counts() throws Exception {
targetConceptYesMap = new HashMap();
targetConceptNoMap = new HashMap();
riskFactorYesMap = new HashMap();
riskFactorNoMap = new HashMap();
HashMap<String, Long> thisRiskFactorYesMap = null;
HashMap<String, Long> thisRiskFactorNoMap = null;
conceptList = new ArrayList();
conceptMap = new HashMap();
Connection conn = null;
ResultSet rs;
PreparedStatement ps;
String dbfile;
String bayesStatisticsTableName;
String conceptTableName;
Properties properties = new Properties();
try {
properties.load(this.getClass().getResourceAsStream(PROPERTIES_FILENAME));
} catch (IOException e) {
throw e;
}
dbfile = properties.getProperty("dbfile");
bayesStatisticsTableName = properties.getProperty("bayes_statistics_table_name");
conceptTableName = properties.getProperty("concept_table_name");
Statement stmt = null;
/**
* connect to DB to get counts
*/
try {
Class.forName("org.sqlite.JDBC");
SQLiteConfig config = new SQLiteConfig();
config.setReadOnly(true);
config.setSharedCache(true);
config.setReadUncommited(true);
conn = DriverManager.getConnection("jdbc:sqlite:" + dbfile, config.toProperties());
ps = conn.prepareStatement("SELECT b.ccs_id_outer AS ccs_id_outer, "
+ "b.ccs_id_inner AS ccs_id_inner, "
+ "b.count_yes AS count_yes, "
+ "b.count_no AS count_no, "
+ "c.name AS ccs_name_outer "
+ "FROM " + bayesStatisticsTableName + " b, " + conceptTableName + " c "
+ "WHERE b.ccs_id_outer = c.ccs_id order by ccs_id_outer,ccs_id_inner");
rs = ps.executeQuery();
while (rs.next()) {
long countYes = rs.getLong("count_yes");
long countNo = rs.getLong("count_no");
String targetConcept = rs.getString("ccs_id_outer");
String targetConceptName = rs.getString("ccs_name_outer");
String riskFactor = rs.getString("ccs_id_inner");
if (rs.wasNull()) {
targetConceptYesMap.put(targetConcept, countYes);
targetConceptNoMap.put(targetConcept, countNo);
conceptList.add(new Concept(targetConcept, targetConceptName));
conceptMap.put(targetConcept, targetConceptName);
thisRiskFactorYesMap = new HashMap();
thisRiskFactorNoMap = new HashMap();
riskFactorYesMap.put(targetConcept, thisRiskFactorYesMap);
riskFactorNoMap.put(targetConcept, thisRiskFactorNoMap);
} else {
thisRiskFactorYesMap.put(riskFactor, countYes);
thisRiskFactorNoMap.put(riskFactor, countNo);
}
}
rs.close();
ps.close();
} catch (SQLException e) {
throw e;
} finally {
if (conn != null) {
conn.close();
}
}
}
public class Concept implements Serializable {
String concept;
String conceptName;
String conceptPrettyName;
String conceptPrettyNameIDAfter;
public Concept(String concept, String conceptName) {
this.concept = concept;
this.conceptName = conceptName;
this.conceptPrettyName = concept + ": " + conceptName;
this.conceptPrettyNameIDAfter = conceptName + " (" + concept + ")";
}
public Concept(String concept) {
this.concept = concept;
this.conceptName = null;
this.conceptPrettyName = concept;
this.conceptPrettyNameIDAfter = concept;
}
public String getConcept() {
return concept;
}
public void setConcept(String concept) {
this.concept = concept;
}
public String getConceptName() {
return conceptName;
}
public void setConceptName(String conceptName) {
this.conceptName = conceptName;
}
public String getConceptPrettyName() {
return conceptPrettyName;
}
public void setConceptPrettyName(String conceptPrettyName) {
this.conceptPrettyName = conceptPrettyName;
}
public String getConceptPrettyNameIDAfter() {
return conceptPrettyNameIDAfter;
}
public void setConceptPrettyNameIDAfter(String conceptPrettyNameIDAfter) {
this.conceptPrettyNameIDAfter = conceptPrettyNameIDAfter;
}
}
public ArrayList<Concept> getConceptList() {
return conceptList;
}
public HashMap<String, String> getConceptMap() {
return conceptMap;
}
public long getTargetConceptCountYes(String targetConcept) {
return targetConceptYesMap.get(targetConcept);
}
public long getTargetConceptCountNo(String targetConcept) {
return targetConceptNoMap.get(targetConcept);
}
public long getRiskFactorCountYes(String targetConcept, String riskFactor) {
return (riskFactorYesMap.get(targetConcept)).get(riskFactor);
}
public long getRiskFactorCountNo(String targetConcept, String riskFactor) {
return (riskFactorNoMap.get(targetConcept)).get(riskFactor);
}
}