diff --git a/.classpath b/.classpath
new file mode 100644
index 00000000..d8923924
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..5e56e040
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/bin
diff --git a/.project b/.project
new file mode 100644
index 00000000..ebaa3b16
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+
+
+ WhiteRabbit
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/.settings/com.wdev91.eclipse.copyright.xml b/.settings/com.wdev91.eclipse.copyright.xml
new file mode 100644
index 00000000..83008237
--- /dev/null
+++ b/.settings/com.wdev91.eclipse.copyright.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/jarDesc/WhiteRabbit.MF b/jarDesc/WhiteRabbit.MF
new file mode 100644
index 00000000..ea937919
--- /dev/null
+++ b/jarDesc/WhiteRabbit.MF
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Class-Path: . WhiteRabbit_lib/jtds-1.3.0.jar WhiteRabbit_lib/ojdbc5.ja
+ r WhiteRabbit_lib/ojdbc6.jar WhiteRabbit_lib/postgresql-9.3-1101.jdbc
+ 41.jar WhiteRabbit_lib/sqljdbc4.jar WhiteRabbit_lib/mysql-connector-j
+ ava-5.1.30-bin.jar WhiteRabbit_lib/dom4j-1.6.1.jar WhiteRabbit_lib/po
+ i-3.9-20121203.jar WhiteRabbit_lib/poi-excelant-3.9-20121203.jar Whit
+ eRabbit_lib/poi-ooxml-3.9-20121203.jar WhiteRabbit_lib/poi-ooxml-sche
+ mas-3.9-20121203.jar WhiteRabbit_lib/stax-api-1.0.1.jar WhiteRabbit_l
+ ib/xmlbeans-2.3.0.jar
+Main-Class: org.ohdsi.whiteRabbit.interactiveMapping.RabbitInAHat
+
diff --git a/jarDesc/WhiteRabbit.jardesc b/jarDesc/WhiteRabbit.jardesc
new file mode 100644
index 00000000..4bfe056a
--- /dev/null
+++ b/jarDesc/WhiteRabbit.jardesc
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/dom4j-1.6.1.jar b/lib/dom4j-1.6.1.jar
new file mode 100644
index 00000000..c8c4dbb9
Binary files /dev/null and b/lib/dom4j-1.6.1.jar differ
diff --git a/lib/jtds-1.3.0.jar b/lib/jtds-1.3.0.jar
new file mode 100644
index 00000000..60f119ca
Binary files /dev/null and b/lib/jtds-1.3.0.jar differ
diff --git a/lib/mysql-connector-java-5.1.30-bin.jar b/lib/mysql-connector-java-5.1.30-bin.jar
new file mode 100644
index 00000000..afef9b2d
Binary files /dev/null and b/lib/mysql-connector-java-5.1.30-bin.jar differ
diff --git a/lib/ojdbc5.jar b/lib/ojdbc5.jar
new file mode 100644
index 00000000..e85e3ea3
Binary files /dev/null and b/lib/ojdbc5.jar differ
diff --git a/lib/ojdbc6.jar b/lib/ojdbc6.jar
new file mode 100644
index 00000000..b663cd24
Binary files /dev/null and b/lib/ojdbc6.jar differ
diff --git a/lib/poi-3.9-20121203.jar b/lib/poi-3.9-20121203.jar
new file mode 100644
index 00000000..0f462880
Binary files /dev/null and b/lib/poi-3.9-20121203.jar differ
diff --git a/lib/poi-excelant-3.9-20121203.jar b/lib/poi-excelant-3.9-20121203.jar
new file mode 100644
index 00000000..cb403fa6
Binary files /dev/null and b/lib/poi-excelant-3.9-20121203.jar differ
diff --git a/lib/poi-ooxml-3.9-20121203.jar b/lib/poi-ooxml-3.9-20121203.jar
new file mode 100644
index 00000000..8792d463
Binary files /dev/null and b/lib/poi-ooxml-3.9-20121203.jar differ
diff --git a/lib/poi-ooxml-schemas-3.9-20121203.jar b/lib/poi-ooxml-schemas-3.9-20121203.jar
new file mode 100644
index 00000000..eda4ef49
Binary files /dev/null and b/lib/poi-ooxml-schemas-3.9-20121203.jar differ
diff --git a/lib/postgresql-9.3-1101.jdbc41.jar b/lib/postgresql-9.3-1101.jdbc41.jar
new file mode 100644
index 00000000..06fd9984
Binary files /dev/null and b/lib/postgresql-9.3-1101.jdbc41.jar differ
diff --git a/lib/sqljdbc4.jar b/lib/sqljdbc4.jar
new file mode 100644
index 00000000..d6b7f6da
Binary files /dev/null and b/lib/sqljdbc4.jar differ
diff --git a/lib/stax-api-1.0.1.jar b/lib/stax-api-1.0.1.jar
new file mode 100644
index 00000000..d9a16651
Binary files /dev/null and b/lib/stax-api-1.0.1.jar differ
diff --git a/lib/xmlbeans-2.3.0.jar b/lib/xmlbeans-2.3.0.jar
new file mode 100644
index 00000000..ccd81634
Binary files /dev/null and b/lib/xmlbeans-2.3.0.jar differ
diff --git a/src/org/ohdsi/databases/DbType.java b/src/org/ohdsi/databases/DbType.java
new file mode 100644
index 00000000..e7273821
--- /dev/null
+++ b/src/org/ohdsi/databases/DbType.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.databases;
+
+public class DbType {
+ public static DbType MYSQL = new DbType("mysql");
+ public static DbType MSSQL = new DbType("mssql");
+ public static DbType ORACLE = new DbType("oracle");
+ public static DbType POSTGRESQL = new DbType("postgresql");
+
+ private enum Type {
+ MYSQL, MSSQL, ORACLE, POSTGRESQL
+ };
+
+ private Type type;
+
+ public DbType(String type) {
+ this.type = Type.valueOf(type.toUpperCase());
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof DbType && ((DbType) other).type == type)
+ return true;
+ else
+ return false;
+ }
+}
diff --git a/src/org/ohdsi/databases/QueryDB.java b/src/org/ohdsi/databases/QueryDB.java
new file mode 100644
index 00000000..535a2742
--- /dev/null
+++ b/src/org/ohdsi/databases/QueryDB.java
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.databases;
+
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.ohdsi.utilities.files.ReadTextFile;
+import org.ohdsi.utilities.files.Row;
+
+public class QueryDB implements Iterable{
+ private String sql;
+ private Connection connection;
+
+ public QueryDB(InputStream sqlStream, Connection connection){
+ this(sqlStream,null,connection);
+ }
+
+ public QueryDB(InputStream sqlStream, Map parameterToValue, Connection connection){
+ this.connection = connection;
+ sql = loadSQL(sqlStream);
+ if (parameterToValue != null)
+ for (String parameter : parameterToValue.keySet())
+ sql = sql.replaceAll(parameter, parameterToValue.get(parameter));
+ trimSQL();
+ }
+
+ public QueryDB(String sql, Connection connection){
+ this.connection = connection;
+ this.sql = sql;
+ trimSQL();
+ }
+
+ private void trimSQL() {
+ sql = sql.trim();
+ if (sql.endsWith(";"))
+ sql = sql.substring(0,sql.length()-1);
+ }
+
+ private String loadSQL(InputStream sqlStream) {
+ StringBuilder sql = new StringBuilder();
+ for (String line : new ReadTextFile(sqlStream)){
+ sql.append(line.trim());
+ sql.append('\n');
+ }
+ return sql.substring(0, sql.lastIndexOf(";"));
+ }
+
+ public boolean execute(){
+ boolean result = false;
+ for (String subQuery : sql.split(";"))
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ result = statement.execute(subQuery.toString());
+ } catch (SQLException e) {
+ if (e.getMessage().contains("ORA-00942") && sql.toUpperCase().startsWith("DROP"))
+ System.out.println("Tried dropping non-existing table");
+ else {
+ System.err.println("SQL: " + subQuery);
+ e.printStackTrace();
+ }
+ }
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new DBRowIterator(sql);
+ }
+ public class DBRowIterator implements Iterator{
+
+ private ResultSet resultSet;
+
+ private boolean hasNext;
+
+ public DBRowIterator(String sql) {
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ resultSet = statement.executeQuery(sql.toString());
+ hasNext = resultSet.next();
+ if (!hasNext)
+ connection.close();
+ } catch (SQLException e){
+ System.err.println(sql.toString());
+ System.err.println(e.getMessage());
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ return hasNext;
+ }
+
+ @Override
+ public Row next() {
+ try {
+ Row row = new Row();
+ ResultSetMetaData metaData;
+ metaData = resultSet.getMetaData();
+ for (int i = 1; i < metaData.getColumnCount()+1; i++) {
+ String columnName = metaData.getColumnName(i);
+ String value = resultSet.getString(i);
+ if (value == null)
+ value = "";
+ row.add(columnName, value.replace(" 00:00:00", ""));
+ }
+ hasNext = resultSet.next();
+ if (!hasNext)
+ connection.close();
+ return row;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void remove() {
+ }
+ }
+}
diff --git a/src/org/ohdsi/databases/QueryParameters.java b/src/org/ohdsi/databases/QueryParameters.java
new file mode 100644
index 00000000..059c497e
--- /dev/null
+++ b/src/org/ohdsi/databases/QueryParameters.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.databases;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class QueryParameters {
+ private Map key2Value = new HashMap();
+ public void set(String key, String value){
+ key2Value.put(key, value);
+ }
+
+ public void set(String key, int value){
+ key2Value.put(key, Integer.toString(value));
+ }
+
+ protected Map getMap() {
+ return key2Value;
+ }
+
+}
diff --git a/src/org/ohdsi/databases/RichConnection.java b/src/org/ohdsi/databases/RichConnection.java
new file mode 100644
index 00000000..bd690f22
--- /dev/null
+++ b/src/org/ohdsi/databases/RichConnection.java
@@ -0,0 +1,772 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.databases;
+
+import java.io.InputStream;
+import java.sql.BatchUpdateException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.ohdsi.utilities.SimpleCounter;
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.utilities.files.ReadCSVFileWithHeader;
+import org.ohdsi.utilities.files.ReadTextFile;
+import org.ohdsi.utilities.files.Row;
+import org.ohdsi.utilities.files.WriteCSVFileWithHeader;
+
+public class RichConnection {
+ public static int INSERT_BATCH_SIZE = 100000;
+ private Connection connection;
+ private Class> context; // Used for locating resources
+ private boolean verbose = false;
+ private static DecimalFormat decimalFormat = new DecimalFormat("#.#");
+ private Map localVariables = new HashMap();
+ private DbType dbType;
+
+ public RichConnection(String server, String domain, String user, String password, DbType dbType) {
+ this.connection = DBConnector.connect(server, domain, user, password, dbType);
+ this.dbType = dbType;
+ }
+
+ /**
+ * Executes the SQL statement specified in the resource. The first parameter string is the parameter name, the second string the value, etc.
+ *
+ * @param resourceName
+ * @param parameters
+ */
+ public void executeResource(String resourceName, Object... parameters) {
+ QueryParameters parameterMap = new QueryParameters();
+ for (int i = 0; i < parameters.length; i += 2)
+ parameterMap.set(parameters[i].toString(), parameters[i + 1].toString());
+ executeResource(resourceName, parameterMap);
+ }
+
+ /**
+ * Executes the SQL statement specified in the resource
+ *
+ * @param resourceName
+ * @param parameters
+ */
+ public void executeResource(String resourceName, QueryParameters parameters) {
+ executeResource(context.getResourceAsStream(resourceName), parameters);
+ }
+
+ /**
+ * Executes the SQL statement specified in the resource
+ *
+ * @param sqlStream
+ * @param parameters
+ */
+ public void executeResource(InputStream sqlStream, QueryParameters parameters) {
+ String sql = loadSQL(sqlStream);
+ if (parameters != null)
+ sql = applyVariables(sql, parameters.getMap());
+ execute(sql);
+ }
+
+ /**
+ * Executes the SQL statement specified in the resource
+ *
+ * @param sqlStream
+ */
+ public void executeResource(InputStream sqlStream) {
+ executeResource(sqlStream, null);
+ }
+
+ /**
+ * Executes the SQL statement specified in the resource
+ *
+ * @param sql
+ */
+ public void executeResource(String sql) {
+ if (context == null)
+ throw new RuntimeException("Context not specified, unable to load resource");
+ executeResource(context.getResourceAsStream(sql));
+ }
+
+ public void executeAsOne(String sql) {
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ statement.execute(sql);
+ } catch (SQLException e) {
+ System.err.println(sql);
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Execute the given SQL statement.
+ *
+ * @param sql
+ */
+ public void execute(String sql) {
+ try {
+ sql = handleSQLDefineStatements(sql);
+ if (sql.length() == 0)
+ return;
+ Statement statement = null;
+
+ statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ for (String subQuery : sql.split(";")) {
+ if (verbose) {
+ String abbrSQL = subQuery.replace('\n', ' ').replace('\t', ' ').trim();
+ if (abbrSQL.length() > 100)
+ abbrSQL = abbrSQL.substring(0, 100).trim() + "...";
+ System.out.println("Adding query to batch: " + abbrSQL);
+ }
+
+ statement.addBatch(subQuery);
+ }
+ long start = System.currentTimeMillis();
+ if (verbose)
+ System.out.println("Executing batch");
+ statement.executeBatch();
+ if (verbose)
+ outputQueryStats(statement, System.currentTimeMillis() - start);
+ statement.close();
+ } catch (SQLException e) {
+ System.err.println(sql);
+ e.printStackTrace();
+ }
+ }
+
+ private String handleSQLDefineStatements(String sql) {
+ sql = extractSQLDefineStatements(sql);
+ sql = applyVariables(sql, localVariables);
+ return sql;
+ }
+
+ private String applyVariables(String sql, Map key2Value) {
+ List sortedKeys = new ArrayList(key2Value.keySet());
+ Collections.sort(sortedKeys, new Comparator() {
+
+ @Override
+ public int compare(String o1, String o2) {
+ if (o1.length() > o2.length())
+ return 1;
+ else if (o1.length() < o2.length())
+ return -1;
+ else
+ return 0;
+ }
+ });
+ for (String key : sortedKeys)
+ sql = sql.replaceAll(key, key2Value.get(key));
+ return sql.trim();
+ }
+
+ private String extractSQLDefineStatements(String sql) {
+ int start = sql.toLowerCase().indexOf("sqldefine");
+
+ while (start != -1) {
+ int end = sql.indexOf(";", start);
+ if (end == -1)
+ throw new RuntimeException("No closing semicolon found for SQLDEFINE in:\n" + sql);
+
+ String definition = sql.substring(start, end);
+ int as = definition.toLowerCase().indexOf(" as");
+ if (as == -1)
+ as = definition.toLowerCase().indexOf("\nas");
+ if (as == -1)
+ as = definition.toLowerCase().indexOf("\tas");
+ if (as == -1)
+ throw new RuntimeException("No AS found for SQLDEFINE in:\n" + sql);
+ String variableName = definition.substring("SQLDEFINE".length(), as).trim();
+ String variableValue = definition.substring(as + 3).trim();
+ variableValue = applyVariables(variableValue, localVariables);
+ if (verbose)
+ System.out.println("Found definition for " + variableName);
+ localVariables.put(variableName, variableValue);
+ sql = sql.substring(0, start) + " " + sql.substring(end + 1);
+
+ start = sql.toLowerCase().indexOf("sqldefine");
+ }
+ return sql;
+ }
+
+ private void outputQueryStats(Statement statement, long ms) throws SQLException {
+ Throwable warning = statement.getWarnings();
+ if (warning != null)
+ System.out.println("- SERVER: " + warning.getMessage());
+ String timeString;
+ if (ms < 1000)
+ timeString = ms + " ms";
+ else if (ms < 60000)
+ timeString = decimalFormat.format(ms / 1000d) + " seconds";
+ else if (ms < 3600000)
+ timeString = decimalFormat.format(ms / 60000d) + " minutes";
+ else
+ timeString = decimalFormat.format(ms / 3600000d) + " hours";
+ System.out.println("- Query completed in " + timeString);
+ }
+
+ public QueryResult queryResource(String resourceName) {
+ return queryResource(resourceName, new QueryParameters());
+ }
+
+ public QueryResult queryResource(String resourceName, QueryParameters parameters) {
+ if (context == null)
+ throw new RuntimeException("Context not specified, unable to load resource");
+ return queryResource(context.getResourceAsStream(resourceName), parameters);
+ }
+
+ /**
+ * Query the database using the SQL statement specified in the resource
+ *
+ * @param sqlStream
+ * @param parameters
+ * @return
+ */
+ public QueryResult queryResource(InputStream sqlStream, QueryParameters parameters) {
+ String sql = loadSQL(sqlStream);
+ sql = applyVariables(sql, parameters.getMap());
+ return query(sql);
+ }
+
+ /**
+ * Query the database using the SQL statement specified in the resource
+ *
+ * @param sqlStream
+ * @return
+ */
+ public QueryResult queryResource(InputStream sqlStream) {
+ return queryResource(sqlStream, null);
+ }
+
+ /**
+ * Query the database using the provided SQL statement.
+ *
+ * @param sql
+ * @return
+ */
+ public QueryResult query(String sql) {
+ return new QueryResult(sql);
+ }
+
+ /**
+ * Switch the database to use.
+ *
+ * @param database
+ */
+ public void use(String database) {
+ if (database == null)
+ return;
+ if (dbType == DbType.ORACLE)
+ execute("ALTER SESSION SET current_schema = " + database);
+ else if (dbType == DbType.POSTGRESQL)
+ execute("SET search_path TO " + database);
+ else
+ execute("USE " + database);
+ }
+
+ public List getDatabaseNames() {
+ List names = new ArrayList();
+ String query = null;
+ if (dbType == DbType.MYSQL)
+ query = "SHOW DATABASES";
+ else if (dbType == DbType.MSSQL)
+ query = "SELECT name FROM master..sysdatabases";
+ else
+ throw new RuntimeException("Database type not supported");
+
+ for (Row row : query(query))
+ names.add(row.get(row.getFieldNames().get(0)));
+ return names;
+ }
+
+ public List getTableNames(String database) {
+ List names = new ArrayList();
+ String query = null;
+ if (dbType == DbType.MYSQL) {
+ if (database == null)
+ query = "SHOW TABLES";
+ else
+ query = "SHOW TABLES IN " + database;
+ } else if (dbType == DbType.MSSQL) {
+ query = "SELECT name FROM " + database + ".sys.tables ";
+ } else if (dbType == DbType.ORACLE) {
+ query = "SELECT table_name FROM all_tables WHERE owner='" + database.toUpperCase() + "'";
+ } else if (dbType == DbType.POSTGRESQL) {
+ query = "SELECT table_name FROM information_schema.tables WHERE table_schema = '" + database + "'";
+ }
+
+ for (Row row : query(query))
+ names.add(row.get(row.getFieldNames().get(0)));
+ return names;
+ }
+
+ public List getFieldNames(String table) {
+ List names = new ArrayList();
+ if (dbType == DbType.MSSQL) {
+ for (Row row : query("SELECT name FROM syscolumns WHERE id=OBJECT_ID('" + table + "')"))
+ names.add(row.get("name"));
+ } else if (dbType == DbType.MYSQL)
+ for (Row row : query("SHOW COLUMNS FROM " + table))
+ names.add(row.get("COLUMN_NAME"));
+ else
+ throw new RuntimeException("DB type not supported");
+
+ return names;
+ }
+
+ public void dropTableIfExists(String table) {
+ if (dbType == DbType.ORACLE) {
+ try {
+ Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ if (verbose) {
+ System.out.println("Executing: TRUNCATE TABLE " + table);
+ }
+ statement.execute("TRUNCATE TABLE " + table);
+ if (verbose) {
+ System.out.println("Executing: DROP TABLE " + table);
+ }
+ statement.execute("DROP TABLE " + table);
+ statement.close();
+ } catch (Exception e) {
+ if (verbose)
+ System.out.println(e.getMessage());
+ }
+ } else if (dbType == DbType.MSSQL) {
+ execute("IF OBJECT_ID('" + table + "', 'U') IS NOT NULL DROP TABLE " + table + ";");
+ } else {
+ execute("DROP TABLE " + table + " IF EXISTS");
+ }
+ }
+
+ public void dropDatabaseIfExists(String database) {
+ execute("DROP DATABASE " + database);
+ }
+
+ /**
+ * Returns the row count of the specified table.
+ *
+ * @param tableName
+ * @return
+ */
+ public long getTableSize(String tableName) {
+ if (dbType == DbType.MSSQL)
+ return Long.parseLong(query("SELECT COUNT(*) FROM [" + tableName + "];").iterator().next().getCells().get(0));
+ else
+ return Long.parseLong(query("SELECT COUNT(*) FROM " + tableName + ";").iterator().next().getCells().get(0));
+ }
+
+ /**
+ * Close the connection to the database.
+ */
+ public void close() {
+ try {
+ connection.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public boolean isVerbose() {
+ return verbose;
+ }
+
+ public void setVerbose(boolean verbose) {
+ this.verbose = verbose;
+ }
+
+ private String loadSQL(InputStream sqlStream) {
+ StringBuilder sql = new StringBuilder();
+ for (String line : new ReadTextFile(sqlStream)) {
+ line = line.replaceAll("--.*", ""); // Remove comments
+ line = line.trim();
+ if (line.length() != 0) {
+ sql.append(line.trim());
+ sql.append('\n');
+ }
+ }
+ return sql.toString();
+ }
+
+ public Class> getContext() {
+ return context;
+ }
+
+ public void setContext(Class> context) {
+ this.context = context;
+ }
+
+ public class QueryResult implements Iterable {
+ private String sql;
+
+ private List iterators = new ArrayList();
+
+ public QueryResult(String sql) {
+ this.sql = sql;
+ }
+
+ @Override
+ public Iterator iterator() {
+ DBRowIterator iterator = new DBRowIterator(sql);
+ iterators.add(iterator);
+ return iterator;
+ }
+
+ public void close() {
+ for (DBRowIterator iterator : iterators) {
+ iterator.close();
+ }
+ }
+ }
+
+ /**
+ * Writes the results of a query to the specified file in CSV format.
+ *
+ * @param queryResult
+ * @param filename
+ */
+ public void writeToFile(QueryResult queryResult, String filename) {
+ WriteCSVFileWithHeader out = new WriteCSVFileWithHeader(filename);
+ for (Row row : queryResult)
+ out.write(row);
+ out.close();
+ }
+
+ /**
+ * Reads a table from a file in CSV format, and inserts it into the database.
+ *
+ * @param filename
+ * @param table
+ * @param create
+ * If true, the data format is determined based on the first batch of rows and used to create the table structure.
+ */
+ public void readFromFile(String filename, String table, boolean create) {
+ insertIntoTable(new ReadCSVFileWithHeader(filename).iterator(), table, create);
+ }
+
+ /**
+ * Inserts the rows into a table in the database.
+ *
+ * @param iterator
+ * @param tableName
+ * @param create
+ * If true, the data format is determined based on the first batch of rows and used to create the table structure.
+ */
+ public void insertIntoTable(Iterator iterator, String table, boolean create) {
+ List batch = new ArrayList(INSERT_BATCH_SIZE);
+
+ boolean first = true;
+ SimpleCounter counter = new SimpleCounter(1000000, true);
+ while (iterator.hasNext()) {
+ if (batch.size() == INSERT_BATCH_SIZE) {
+ if (first && create)
+ createTable(table, batch);
+ insert(table, batch);
+ batch.clear();
+ first = false;
+ }
+ batch.add(iterator.next());
+ counter.count();
+ }
+ if (batch.size() != 0) {
+ if (first && create)
+ createTable(table, batch);
+ insert(table, batch);
+ }
+ }
+
+ // private Map getNumericFieldsInPostgreSQL(String table) {
+ // Map fieldToType = new HashMap();
+ // for (Row row : query("SELECT column_name, data_type FROM information_schema.columns WHERE table_name = '" + table + "'"))
+ // fieldToType.put(row.get("column_name"), row.get("data_type"));
+ // return fieldToType;
+ // }
+
+ private void insert(String tableName, List rows) {
+ List columns = null;
+ columns = rows.get(0).getFieldNames();
+ for (int i = 0; i < columns.size(); i++)
+ columns.set(i, columnNameToSqlName(columns.get(i)));
+
+ String sql = "INSERT INTO " + tableName;
+ sql = sql + " (" + StringUtilities.join(columns, ",") + ")";
+ sql = sql + " VALUES (?";
+ for (int i = 1; i < columns.size(); i++)
+ sql = sql + ",?";
+ sql = sql + ")";
+ try {
+ connection.setAutoCommit(false);
+ PreparedStatement statement = connection.prepareStatement(sql);
+ for (Row row : rows) {
+ for (int i = 0; i < columns.size(); i++) {
+ String value = row.get(columns.get(i));
+ if (value == null)
+ System.out.println(row.toString());
+ if (value.length() == 0)
+ value = null;
+ // System.out.println(value);
+ if (dbType == DbType.POSTGRESQL) // PostgreSQL does not allow unspecified types
+ statement.setObject(i + 1, value, Types.OTHER);
+ else if (dbType == DbType.ORACLE) {
+ if (isDate(value)) {
+ // System.out.println(value);
+ statement.setDate(i + 1, java.sql.Date.valueOf(value));
+
+ } else
+ statement.setString(i + 1, value);
+ } else
+ statement.setString(i + 1, value);
+ }
+ statement.addBatch();
+ }
+ statement.executeBatch();
+ connection.commit();
+ statement.close();
+ connection.setAutoCommit(true);
+ connection.clearWarnings();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ if (e instanceof BatchUpdateException) {
+ System.err.println(((BatchUpdateException) e).getNextException().getMessage());
+ }
+ }
+ }
+
+ private static boolean isDate(String string) {
+ if (string != null && string.length() == 10 && string.charAt(4) == '-' && string.charAt(7) == '-')
+ try {
+ int year = Integer.parseInt(string.substring(0, 4));
+ if (year < 1700 || year > 2200)
+ return false;
+ int month = Integer.parseInt(string.substring(5, 7));
+ if (month < 1 || month > 12)
+ return false;
+ int day = Integer.parseInt(string.substring(8, 10));
+ if (day < 1 || day > 31)
+ return false;
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ return false;
+ }
+
+ private Set createTable(String tableName, List rows) {
+ Set numericFields = new HashSet();
+ Row firstRow = rows.get(0);
+ List fields = new ArrayList(rows.size());
+ for (String field : firstRow.getFieldNames())
+ fields.add(new FieldInfo(field));
+ for (Row row : rows) {
+ for (FieldInfo fieldInfo : fields) {
+ String value = row.get(fieldInfo.name);
+ if (fieldInfo.isNumeric && !StringUtilities.isInteger(value))
+ fieldInfo.isNumeric = false;
+ if (value.length() > fieldInfo.maxLength)
+ fieldInfo.maxLength = value.length();
+ }
+ }
+
+ StringBuilder sql = new StringBuilder();
+ sql.append("CREATE TABLE " + tableName + " (\n");
+ for (FieldInfo fieldInfo : fields) {
+ sql.append(" " + fieldInfo.toString() + ",\n");
+ if (fieldInfo.isNumeric)
+ numericFields.add(fieldInfo.name);
+ }
+ sql.append(");");
+ execute(sql.toString());
+ return numericFields;
+ }
+
+ private String columnNameToSqlName(String name) {
+ return name.replaceAll(" ", "_").replace("-", "_").replace(",", "_").replaceAll("_+", "_");
+ }
+
+ private class FieldInfo {
+ public String name;
+ public boolean isNumeric = true;
+ public int maxLength = 0;
+
+ public FieldInfo(String name) {
+ this.name = name;
+ }
+
+ public String toString() {
+ if (dbType == DbType.MYSQL) {
+ if (isNumeric)
+ return columnNameToSqlName(name) + " int(" + maxLength + ")";
+ else if (maxLength > 255)
+ return columnNameToSqlName(name) + " text";
+ else
+ return columnNameToSqlName(name) + " varchar(255)";
+ } else if (dbType == DbType.MSSQL) {
+ if (isNumeric) {
+ if (maxLength < 10)
+ return columnNameToSqlName(name) + " int";
+ else
+ return columnNameToSqlName(name) + " bigint";
+ } else if (maxLength > 255)
+ return columnNameToSqlName(name) + " varchar(max)";
+ else
+ return columnNameToSqlName(name) + " varchar(255)";
+ } else
+ throw new RuntimeException("Create table syntax not specified for type " + dbType);
+ }
+ }
+
+ public void copyTable(String sourceDatabase, String sourceTable, RichConnection targetConnection, String targetDatabase, String targetTable) {
+ StringBuilder sql = new StringBuilder();
+ sql.append("CREATE TABLE ");
+ sql.append(targetDatabase);
+ if (targetConnection.dbType == DbType.MSSQL)
+ sql.append(".dbo.");
+ else
+ sql.append(".");
+ sql.append(targetTable);
+ sql.append("(");
+ boolean first = true;
+ String query;
+ if (dbType == DbType.ORACLE || dbType == DbType.MSSQL)
+ query = "SELECT COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_CATALOG='" + sourceDatabase + "' AND TABLE_NAME='" + sourceTable
+ + "';";
+ else
+ // mysql
+ query = "SELECT COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '" + sourceDatabase + "' AND TABLE_NAME = '"
+ + sourceTable + "';";
+
+ for (Row row : query(query)) {
+ if (first)
+ first = false;
+ else
+ sql.append(',');
+ sql.append(row.get("COLUMN_NAME"));
+ sql.append(' ');
+ if (targetConnection.dbType == DbType.ORACLE) {
+ if (row.get("DATA_TYPE").equals("bigint"))
+ sql.append("number");
+ else
+ sql.append(row.get("DATA_TYPE"));
+ } else {
+ sql.append(row.get("DATA_TYPE"));
+ if (row.get("DATA_TYPE").equals("varchar"))
+ sql.append("(max)");
+ }
+ }
+ sql.append(");");
+ targetConnection.execute(sql.toString());
+ targetConnection.use(targetDatabase);
+ targetConnection.insertIntoTable(query("SELECT * FROM " + sourceDatabase + ".dbo." + sourceTable).iterator(), targetTable, false);
+ }
+
+ private class DBRowIterator implements Iterator {
+
+ private ResultSet resultSet;
+
+ private boolean hasNext;
+
+ private Set columnNames = new HashSet();
+
+ public DBRowIterator(String sql) {
+ try {
+ sql.trim();
+ if (sql.endsWith(";"))
+ sql = sql.substring(0, sql.length() - 1);
+ if (verbose) {
+ String abbrSQL = sql.replace('\n', ' ').replace('\t', ' ').trim();
+ if (abbrSQL.length() > 100)
+ abbrSQL = abbrSQL.substring(0, 100).trim() + "...";
+ System.out.println("Executing query: " + abbrSQL);
+ }
+ long start = System.currentTimeMillis();
+ Statement statement = connection.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
+ resultSet = statement.executeQuery(sql.toString());
+ hasNext = resultSet.next();
+ if (verbose)
+ outputQueryStats(statement, System.currentTimeMillis() - start);
+ } catch (SQLException e) {
+ System.err.println(sql.toString());
+ System.err.println(e.getMessage());
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void close() {
+ if (resultSet != null) {
+ try {
+ resultSet.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ resultSet = null;
+ hasNext = false;
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ return hasNext;
+ }
+
+ @Override
+ public Row next() {
+ try {
+ Row row = new Row();
+ ResultSetMetaData metaData;
+ metaData = resultSet.getMetaData();
+ columnNames.clear();
+
+ for (int i = 1; i < metaData.getColumnCount() + 1; i++) {
+ String columnName = metaData.getColumnName(i);
+ if (columnNames.add(columnName)) {
+ String value = resultSet.getString(i);
+ if (value == null)
+ value = "";
+
+ row.add(columnName, value.replace(" 00:00:00", ""));
+ }
+ }
+ hasNext = resultSet.next();
+ if (!hasNext) {
+ resultSet.close();
+ resultSet = null;
+ }
+ return row;
+ } catch (SQLException e) {
+ e.printStackTrace();
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public void remove() {
+ }
+ }
+}
diff --git a/src/org/ohdsi/ooxml/CustomXWPFDocument.java b/src/org/ohdsi/ooxml/CustomXWPFDocument.java
new file mode 100644
index 00000000..170937f9
--- /dev/null
+++ b/src/org/ohdsi/ooxml/CustomXWPFDocument.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.ooxml;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.imageio.ImageIO;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.xwpf.usermodel.Document;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlToken;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
+import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
+
+/**
+ * This class offers workaround for bug in Apache POI, allowing images to be inserted
+ *
+ * @author MSCHUEMI
+ */
+public class CustomXWPFDocument extends XWPFDocument {
+
+ public CustomXWPFDocument() {
+ super();
+ }
+
+ public CustomXWPFDocument(InputStream in) throws IOException {
+ super(in);
+ }
+
+ public void addPicture(BufferedImage image, int width, int height) throws InvalidFormatException, FileNotFoundException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ try {
+ ImageIO.write(image, "PNG", out);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ addPicture(in, Document.PICTURE_TYPE_PNG, width, height);
+ }
+
+ public void addPicture(String filename, int type, int width, int height) throws InvalidFormatException, FileNotFoundException {
+ addPicture(new FileInputStream(filename), type, width, height);
+ }
+
+ public void addPicture(InputStream inputStream, int type, int width, int height) throws InvalidFormatException, FileNotFoundException {
+ String id = addPictureData(inputStream, type);
+ createPicture(id, getNextPicNameNumber(type), width, height);
+ }
+
+ private void createPicture(String blipId, int id, int width, int height) {
+ final int EMU = 9525;
+ width *= EMU;
+ height *= EMU;
+ CTInline inline = createParagraph().createRun().getCTR().addNewDrawing().addNewInline();
+
+ String picXml = "" + ""
+ + " "
+ + " " + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " "
+ + " " + " " + " " + "";
+
+ XmlToken xmlToken = null;
+ try {
+ xmlToken = XmlToken.Factory.parse(picXml);
+ } catch (XmlException xe) {
+ xe.printStackTrace();
+ }
+ inline.set(xmlToken);
+
+ inline.setDistT(0);
+ inline.setDistB(0);
+ inline.setDistL(0);
+ inline.setDistR(0);
+
+ CTPositiveSize2D extent = inline.addNewExtent();
+ extent.setCx(width);
+ extent.setCy(height);
+
+ CTNonVisualDrawingProps docPr = inline.addNewDocPr();
+ docPr.setId(id);
+ docPr.setName("Picture " + id);
+ docPr.setDescr("Generated");
+ }
+}
diff --git a/src/org/ohdsi/ooxml/ReadXlsxFileWithHeader.java b/src/org/ohdsi/ooxml/ReadXlsxFileWithHeader.java
new file mode 100644
index 00000000..f85dcc57
--- /dev/null
+++ b/src/org/ohdsi/ooxml/ReadXlsxFileWithHeader.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.ooxml;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.ohdsi.utilities.files.Row;
+
+public class ReadXlsxFileWithHeader implements Iterable {
+ private InputStream inputstream;
+
+ public ReadXlsxFileWithHeader(String filename) {
+ try {
+ inputstream = new FileInputStream(filename);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public ReadXlsxFileWithHeader(InputStream inputstream) {
+ this.inputstream = inputstream;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new RowIterator();
+ }
+
+ public class RowIterator implements Iterator {
+
+ private Iterator iterator;
+ private Map fieldName2ColumnIndex;
+ private DecimalFormat myFormatter = new DecimalFormat("###############.################");
+
+ public RowIterator() {
+ try {
+ XSSFWorkbook workbook = new XSSFWorkbook(inputstream);
+ XSSFSheet sheet = workbook.getSheetAt(0);
+ iterator = sheet.iterator();
+ fieldName2ColumnIndex = new HashMap();
+ for (Cell header : iterator.next())
+ fieldName2ColumnIndex.put(header.toString(), fieldName2ColumnIndex.size());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public Row next() {
+ List cells = new ArrayList(fieldName2ColumnIndex.size());
+ for (Cell cell : iterator.next()) {
+ String text;
+ if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC)
+ text = myFormatter.format(cell.getNumericCellValue());
+ else
+ text = cell.toString();
+ cells.add(text);
+ }
+ for (int i = cells.size(); i < fieldName2ColumnIndex.size(); i++)
+ cells.add("");
+ return new Row(cells, fieldName2ColumnIndex);
+ }
+
+ @Override
+ public void remove() {
+ throw new RuntimeException("Remove not supported");
+ }
+
+ }
+}
diff --git a/src/org/ohdsi/utilities/DirectoryUtilities.java b/src/org/ohdsi/utilities/DirectoryUtilities.java
new file mode 100644
index 00000000..ea89fbd0
--- /dev/null
+++ b/src/org/ohdsi/utilities/DirectoryUtilities.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DirectoryUtilities {
+ public static boolean deleteDir(File dir) {
+ if (dir.isDirectory()) {
+ String[] children = dir.list();
+ for (int i=0; i 0) {
+ out.write(buf, 0, len);
+ }
+ in.close();
+ out.close();
+ }
+ }
+
+ public static List getFileListing(File dir) {
+ List result = new ArrayList();
+ for(String filename: dir.list())
+ result.add(new File(dir, filename));
+ return result;
+ }
+
+ private static List getPathList(File f) {
+ List l = new ArrayList();
+ File r;
+ r = f.getAbsoluteFile();
+ while(r != null) {
+ l.add(r.getName());
+ r = r.getParentFile();
+ }
+ return l;
+ }
+
+
+ private static String matchPathLists(List r,List f) {
+ int i;
+ int j;
+ String s;
+ // start at the beginning of the lists
+ // iterate while both lists are equal
+ s = "";
+ i = r.size()-1;
+ j = f.size()-1;
+
+ // first eliminate common root
+ while((i >= 0)&&(j >= 0)&&(r.get(i).equals(f.get(j)))) {
+ i--;
+ j--;
+ }
+
+ // for each remaining level in the home path, add a ..
+ for(;i>=0;i--) {
+ s += ".." + File.separator;
+ }
+
+ // for each level in the file path, add the path
+ for(;j>=1;j--) {
+ s += f.get(j) + File.separator;
+ }
+
+ // file name
+ s += f.get(j);
+ return s;
+ }
+
+
+ public static String getRelativePath(File home,File f){
+ return matchPathLists(getPathList(home),getPathList(f));
+ }
+
+
+
+}
diff --git a/src/org/ohdsi/utilities/RandomUtilities.java b/src/org/ohdsi/utilities/RandomUtilities.java
new file mode 100644
index 00000000..16d03bfc
--- /dev/null
+++ b/src/org/ohdsi/utilities/RandomUtilities.java
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+public class RandomUtilities {
+ public static List sampleWithoutReplacement(List items, int sampleSize) {
+ if (sampleSize > items.size()) {
+ return items;
+ }
+ Random random = new Random();
+ List sample = new ArrayList();
+ for (int i = 0; i < sampleSize; i++)
+ sample.add(items.remove(random.nextInt(items.size())));
+ return sample;
+ }
+
+ public static int[] sampleWithoutReplacement(int minValue, int maxValue, int sampleSize) {
+ if (sampleSize > (maxValue - minValue + 1)) {
+ int[] sample = new int[maxValue - minValue + 1];
+ for (int i = minValue; i <= maxValue; i++)
+ sample[i - minValue] = i;
+ return sample;
+ } else {
+ Random random = new Random();
+ int[] sample = new int[sampleSize];
+ for (int i = 0; i < sampleSize; i++) {
+ int number = random.nextInt(maxValue - minValue + 1);
+ while (contains(sample, number))
+ number = random.nextInt(maxValue - minValue + 1);
+ sample[i] = number;
+ }
+ return sample;
+ }
+
+ }
+
+ private static boolean contains(int[] sample, int number) {
+ for (int i : sample)
+ if (i == number)
+ return true;
+ return false;
+ }
+
+}
diff --git a/src/org/ohdsi/utilities/SimpleCounter.java b/src/org/ohdsi/utilities/SimpleCounter.java
new file mode 100644
index 00000000..770c9184
--- /dev/null
+++ b/src/org/ohdsi/utilities/SimpleCounter.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities;
+
+public class SimpleCounter {
+ private int reportN;
+ private long count;
+ private long lastTime;
+ private long lastCount;
+ private boolean reportRate = false;
+
+ public SimpleCounter(int reportN) {
+ this.reportN = reportN;
+ count = 0;
+ lastCount = 0;
+ lastTime = System.currentTimeMillis();
+ }
+
+ public SimpleCounter(int reportN, boolean reportRate){
+ this(reportN);
+ setReportRate(reportRate);
+ }
+
+ public void count() {
+ count++;
+ if (count % reportN == 0)
+ report();
+ }
+
+ private void report() {
+ if (reportRate){
+ long interval = System.currentTimeMillis() - lastTime;
+ long processed = count - lastCount;
+ System.out.println(count + " (time per unit = " + interval/(double)processed + "ms)");
+ lastTime = System.currentTimeMillis();
+ lastCount = count;
+ } else
+ System.out.println(count);
+ }
+
+ public void finish() {
+ report();
+ }
+
+ public long getCount() {
+ return count;
+ }
+
+ public boolean isReportRate() {
+ return reportRate;
+ }
+
+ public void setReportRate(boolean value) {
+ this.reportRate = value;
+ }
+}
diff --git a/src/org/ohdsi/utilities/StringUtilities.java b/src/org/ohdsi/utilities/StringUtilities.java
new file mode 100644
index 00000000..36f2651e
--- /dev/null
+++ b/src/org/ohdsi/utilities/StringUtilities.java
@@ -0,0 +1,873 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.DateFormat;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.List;
+import java.util.zip.DataFormatException;
+
+public class StringUtilities {
+
+ public static long SECOND = 1000;
+ public static long MINUTE = 60 * SECOND;
+ public static long HOUR = 60 * MINUTE;
+ public static long DAY = 24 * HOUR;
+ public static long WEEK = 7 * DAY;
+ public static long YEAR = 365 * DAY;
+ public static long CENTURY = 100 * YEAR;
+ public static long MILLENIUM = 1000 * YEAR;
+ public static long MISSING_DATE = -999999;
+
+ private static Calendar calendar = new GregorianCalendar();
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ public static String joinSorted(Collection extends Comparable> s, String delimiter) {
+ List list = new ArrayList(s);
+ Collections.sort(list);
+ return join(list, delimiter);
+ }
+
+ public static String join(Collection> s, String delimiter) {
+ StringBuffer buffer = new StringBuffer();
+ Iterator> iter = s.iterator();
+ if (iter.hasNext()) {
+ buffer.append(iter.next().toString());
+ }
+ while (iter.hasNext()) {
+ buffer.append(delimiter);
+ buffer.append(iter.next().toString());
+ }
+ return buffer.toString();
+ }
+
+ public static String join(Object[] objects, String delimiter) {
+ StringBuffer buffer = new StringBuffer();
+ if (objects.length != 0)
+ buffer.append(objects[0].toString());
+ for (int i = 1; i < objects.length; i++) {
+ buffer.append(delimiter);
+ buffer.append(objects[i].toString());
+ }
+ return buffer.toString();
+ }
+
+ public static int twoHexDigitsToInt(String value, int index) {
+ return Integer.parseInt(value.substring(index, index + 2), 16);
+ }
+
+ public static boolean isInteger(String string) {
+ try {
+ Integer.parseInt(string);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public static boolean isLong(String string) {
+ try {
+ Long.parseLong(string);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ return true;
+ }
+
+ // private static Pattern numberPattern = Pattern.compile("^-?\\d[0-9]*(\\.[0-9]+)?((E|e)-?[0-9]*)?\\d$");
+
+ public static boolean isNumber(String string) {
+ try {
+ Double.parseDouble(string);
+ } catch (Exception e) {
+ return false;
+ }
+ return true;
+ // string.trim();
+ // if (string.length() == 1) {
+ // return Character.isDigit(string.charAt(0));
+ // }
+ // return numberPattern.matcher(string).matches();
+ }
+
+ public static boolean isRomanNumeral(String string) {
+ return (string.equals("I") || string.equals("II") || string.equals("III") || string.equals("IV") || string.equals("V") || string.equals("VI")
+ || string.equals("VII") || string.equals("VIII") || string.equals("IX") || string.equals("IX"));
+ }
+
+ public static boolean isGreekLetter(String string) {
+ String lcstring = string.toLowerCase();
+ return (lcstring.equals("alpha") || lcstring.equals("beta") || lcstring.equals("gamma") || lcstring.equals("delta") || lcstring.equals("epsilon")
+ || lcstring.equals("zeta") || lcstring.equals("eta") || lcstring.equals("theta") || lcstring.equals("iota") || lcstring.equals("kappa")
+ || lcstring.equals("lambda") || lcstring.equals("mu") || lcstring.equals("nu") || lcstring.equals("xi") || lcstring.equals("omicron")
+ || lcstring.equals("pi") || lcstring.equals("rho") || lcstring.equals("sigma") || lcstring.equals("tau") || lcstring.equals("upsilon")
+ || lcstring.equals("phi") || lcstring.equals("chi") || lcstring.equals("psi") || lcstring.equals("omega"));
+ }
+
+ // Adds PSF file specific escape characters to string
+ // Author: Martijn
+ public static String escape(String string) {
+ StringBuffer result = new StringBuffer();
+ for (int i = 0; i < string.length(); i++) {
+ char currentChar = string.charAt(i);
+ if (currentChar == '"' || currentChar == '?' || currentChar == ';' || currentChar == '\\' || currentChar == '|') {
+ result.append('\\');
+ }
+ result.append(currentChar);
+ }
+ return result.toString();
+ }
+
+ // Removes any escape characters from string
+ // Author: Martijn
+ public static String unescape(String string) {
+ StringBuffer result = new StringBuffer();
+ if (string.length() > 0) {
+ if (string.charAt(0) == '"' && string.charAt(string.length() - 1) == '"') {
+ result.append(string.substring(1, string.length() - 1));
+ } else {
+ boolean escape = false;
+ char currentchar;
+ for (int i = 0; i < string.length(); i++) {
+ currentchar = string.charAt(i);
+ if (escape) {
+ escape = false;
+ result.append(currentchar);
+ } else {
+ if (currentchar == '\\') {
+ escape = true;
+ } else {
+ result.append(currentchar);
+ }
+ }
+ }
+ }
+ }
+ return result.toString();
+ }
+
+ // Safesplit works the same as default split, but takes escapes into account
+ // Author: Martijn
+ public static List safeSplit(String string, char delimiter) {
+ List result = new ArrayList();
+ if (string.length() == 0) {
+ result.add("");
+ return result;
+ }
+ boolean literal = false;
+ boolean escape = false;
+ int startpos = 0;
+ int i = 0;
+ char currentchar;
+ while (i < string.length()) {
+ currentchar = string.charAt(i);
+ if (currentchar == '"' && !escape) {
+ literal = !literal;
+ }
+ if (!literal && (currentchar == delimiter && !escape)) {
+ result.add(string.substring(startpos, i));
+ startpos = i + 1;
+ }
+ if (currentchar == '\\') {
+ escape = !escape;
+ } else {
+ escape = false;
+ }
+ i++;
+ }
+ result.add(string.substring(startpos, i));
+ return result;
+ }
+
+ public static boolean containsNumber(String string) {
+ for (int i = 0; i < string.length(); i++) {
+ if ((int) string.charAt(i) < 58 && (int) string.charAt(i) > 47) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static int countNumbers(String string) {
+ int total = 0;
+ for (int i = 0; i < string.length(); i++) {
+ if ((int) string.charAt(i) < 58 && (int) string.charAt(i) > 47) {
+ total++;
+ }
+ }
+ return total;
+ }
+
+ public static boolean containsLetter(String string) {
+ for (int i = 0; i < string.length(); i++) {
+ if (Character.isLetter(string.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static int countLetters(String string) {
+ int total = 0;
+ for (int i = 0; i < string.length(); i++) {
+ if (Character.isLetter(string.charAt(i))) {
+ total++;
+ }
+ }
+ return total;
+ }
+
+ public static boolean containsCurlyBracket(String string) {
+ for (int i = 0; i < string.length(); i++) {
+ if (isCurlyBracket(string.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean containsParenthesis(String string) {
+ for (int i = 0; i < string.length(); i++) {
+ if (isParenthesis(string.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean containsBracket(String string) {
+ for (int i = 0; i < string.length(); i++) {
+ if (isBracket(string.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean containsArrow(String string) {
+ for (int i = 0; i < string.length(); i++) {
+ if (isArrow(string.charAt(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean isParenthesis(char ch) {
+ return (ch == ('(') || ch == (')'));
+ }
+
+ // Checks whether the word is a brackets
+ // Author: Kristina
+ public static boolean isBracket(char ch) {
+ return (ch == ('[') || ch == (']'));
+ }
+
+ public static boolean isArrow(char ch) {
+ return (ch == ('<') || ch == ('>'));
+ }
+
+ // Checks whether the word is a curly bracket
+ // Author: Kristina
+ public static boolean isCurlyBracket(char ch) {
+ return (ch == ('{') || ch == ('}'));
+ }
+
+ // Converts a string to a list of words
+ // Author: Martijn
+ public static List mapToWords(String string) {
+ List result = new ArrayList();
+
+ int start = 0;
+ int i = 0;
+ for (; i < string.length(); i++) {
+ char ch = string.charAt(i);
+ if (!Character.isLetterOrDigit(ch)
+ && !(ch == '\'' && i > 0 && Character.isLetter(string.charAt(i - 1)) && string.length() - 1 > i && string.charAt(i + 1) == 's' && (string
+ .length() - 2 == i || !Character.isLetterOrDigit(string.charAt(i + 2))))) { // leaves ' in possesive pattern
+ if (start != i) {
+ result.add(string.substring(start, i));
+ }
+ start = i + 1;
+ }
+ }
+ if (start != i) {
+ result.add(string.substring(start, i));
+ }
+ return result;
+ }
+
+ // Returns a string with the current time
+ // Author: Martijn
+ public static String now() {
+ Date d = new Date();
+ DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
+ return df.format(d);
+ }
+
+ public static void outputWithTime(String message) {
+ System.out.println(now() + "\t" + message);
+ }
+
+ // Checks whether the word is an abbreviation
+ // Author: Martijn
+ public static boolean isAbbr(String word) {
+ int lowercase = 0;
+ int uppercase = 0;
+ int charInt = 0;
+ for (int i = 0; i < word.length(); i++) {
+ charInt = (int) word.charAt(i);
+ if (charInt < 58) {
+ if (charInt > 47) {
+ }// its a number
+ } else if (charInt < 91) {
+ if (charInt > 64) {
+ uppercase++;
+ }
+ } else if (charInt < 123 && charInt > 96) {
+ lowercase++;
+ }
+ }
+ return (uppercase > 0 && lowercase < uppercase);
+ }
+
+ /**
+ * If only the first letter of a word is a capital, the word is reduced to lowercase, else the original string is returned
+ *
+ * @param string
+ * @return
+ */
+ public static String firstLetterToLowerCase(String string) {
+ boolean uppercase = false;
+ int charInt = 0;
+ for (int i = 1; i < string.length(); i++) {
+ charInt = (int) string.charAt(i);
+ if (charInt < 91)
+ if (charInt > 64) {
+ uppercase = true;
+ break;
+ }
+ }
+ if (!uppercase)
+ return string.toLowerCase();
+ else
+ return string;
+ }
+
+ public static int countsCharactersInUpperCase(String string) {
+ int uppercase = 0;
+ int charInt = 0;
+ for (int i = 0; i < string.length(); i++) {
+ charInt = (int) string.charAt(i);
+ if (charInt > 64 && charInt < 91) {
+ uppercase++;
+ }
+ }
+ return uppercase;
+ }
+
+ public static int countsCharactersInLowerCase(String string) {
+ int lowercase = 0;
+ int charInt = 0;
+ for (int i = 0; i < string.length(); i++) {
+ charInt = (int) string.charAt(i);
+ if (charInt > 96 && charInt < 123) {
+ lowercase++;
+ }
+ }
+ return lowercase;
+ }
+
+ // Converts a double to a formatted string. Examples of valid patterns are:
+ // "###,###.###"
+ // "###.##"
+ // "000000.000"
+ // "$###,###.###"
+ // "\u00a5###,###.###"
+ // # indicates optional number, 0 indicates forced number (will be printed as 0 when 0)
+ // Author: Martijn
+ public static String formatNumber(String pattern, double number) {
+ DecimalFormat myFormatter = new DecimalFormat(pattern);
+ return myFormatter.format(number);
+ }
+
+ public static boolean isPlural(String string) {
+ if (string.length() > 1)
+ if (string.charAt(string.length() - 1) == 's')
+ if (Character.isLetter(string.charAt(string.length() - 2)))
+ return true;
+ return false;
+ }
+
+ public static String findBetween(String source, String pre, String post) {
+ int start = source.indexOf(pre);
+ if (start == -1)
+ return "";
+ int end = source.indexOf(post, start + pre.length());
+ if (end == -1)
+ return "";
+ return source.substring(start + pre.length(), end);
+ }
+
+ public static List multiFindBetween(String source, String pre, String post) {
+ List result = new ArrayList();
+ int start = 0;
+ int end = 0;
+ while (start != -1 && end != -1) {
+ start = source.indexOf(pre, end);
+ if (start != -1) {
+ end = source.indexOf(post, start + pre.length());
+ if (end != -1)
+ result.add(source.substring(start + pre.length(), end));
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Returns true if every parenthesis in the string is matched
+ *
+ * @param string
+ * @return
+ */
+ public static boolean parenthesisMatch(String string) {
+ int count = 0;
+ for (int i = 0; i < string.length(); i++) {
+ char ch = string.charAt(i);
+ if (ch == '(')
+ count++;
+ else if (ch == ')') {
+ count--;
+ if (count == -1)
+ return false;
+ }
+ }
+ return (count == 0);
+ }
+
+ public static int count(String s, char ch) {
+ int cnt = 0;
+ for (int i = 0; i < s.length(); i++)
+ if (s.charAt(i) == ch)
+ cnt++;
+ return cnt;
+ }
+
+ /**
+ * Removes parenthesis and what is within the parenthesis from the string. For example: 'cold (disease)' -> 'cold '
+ *
+ * @param string
+ * @return
+ */
+ public static String removeParenthesisAndContent(String string) {
+ StringBuilder result = new StringBuilder();
+ int count = 0;
+ for (int i = 0; i < string.length(); i++) {
+ char ch = string.charAt(i);
+ if (ch == '(')
+ count++;
+ else if (ch == ')') {
+ count--;
+ } else if (count == 0)
+ result.append(ch);
+ }
+ return result.toString();
+ }
+
+ public static String daysToSortableDateString(long days) {
+ long ms = days * DAY;
+ // Calendar calendar = new GregorianCalendar();
+ ms -= calendar.getTimeZone().getOffset(ms);
+ calendar.setTimeInMillis(ms);
+ StringBuilder sb = new StringBuilder();
+ sb.append(calendar.get(Calendar.YEAR));
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.MONTH) + 1));
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.DATE)));
+ return sb.toString();
+ }
+
+ public static String daysToDatabaseDateString(long days) {
+ if (days == MISSING_DATE)
+ return "";
+ long ms = days * DAY;
+ ms -= calendar.getTimeZone().getOffset(ms);
+ calendar.setTimeInMillis(ms);
+ StringBuilder sb = new StringBuilder();
+ sb.append(calendar.get(Calendar.YEAR));
+ sb.append("-");
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.MONTH) + 1));
+ sb.append("-");
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.DATE)));
+ return sb.toString();
+ }
+
+ public static String daysToCalendarYear(long days) {
+ long ms = days * DAY;
+ ms -= calendar.getTimeZone().getOffset(ms);
+ calendar.setTimeInMillis(ms);
+ return Integer.toString(calendar.get(Calendar.YEAR));
+ }
+
+ public static String dateToCalendarYear(Date date) {
+ calendar.setTime(date);
+ return Integer.toString(calendar.get(Calendar.YEAR));
+ }
+
+ public static String daysToCalendarMonth(long days) {
+ long ms = days * DAY;
+ ms -= calendar.getTimeZone().getOffset(ms);
+ calendar.setTimeInMillis(ms);
+ return Integer.toString(calendar.get(Calendar.MONTH) + 1);
+ }
+
+ public static String daysToCalendarDayOfMonth(long days) {
+ long ms = days * DAY;
+ ms -= calendar.getTimeZone().getOffset(ms);
+ calendar.setTimeInMillis(ms);
+ return Integer.toString(calendar.get(Calendar.DATE) + 1);
+ }
+
+ public static String daysToCalendarQuarterYear(long days) {
+ long ms = days * DAY;
+ ms -= calendar.getTimeZone().getOffset(ms);
+ calendar.setTimeInMillis(ms);
+ return Integer.toString(1 + (calendar.get(Calendar.MONTH) / 3));
+ }
+
+ public static String millisecondsToSortableTimeString(long ms) {
+ // Calendar calendar = new GregorianCalendar();
+ ms -= calendar.getTimeZone().getOffset(ms + 2 * HOUR);
+ calendar.setTimeInMillis(ms);
+ StringBuilder sb = new StringBuilder();
+ sb.append(calendar.get(Calendar.YEAR));
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.MONTH) + 1));
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.DATE)));
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.HOUR)));
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.MINUTE)));
+ sb.append(StringUtilities.formatNumber("00", calendar.get(Calendar.SECOND)));
+ return sb.toString();
+ }
+
+ public static long sortableTimeStringToDays(String string) throws DataFormatException {
+ // Calendar calendar = new GregorianCalendar();
+ try {
+ int year = Integer.parseInt(string.substring(0, 4));
+ int month = Integer.parseInt(string.substring(4, 6)) - 1;
+ int day = Integer.parseInt(string.substring(6, 8));
+ calendar.set(year, month, day);
+ long time = calendar.getTimeInMillis();
+ time += calendar.getTimeZone().getOffset(time);
+
+ if (string.length() > 8) {
+ int hour = Integer.parseInt(string.substring(8, 10));
+ time += hour * 60 * 60 * 1000;
+ if (string.length() > 8) {
+ int minute = Integer.parseInt(string.substring(10, 12));
+ time += minute * 60 * 1000;
+ if (string.length() > 8) {
+ int second = Integer.parseInt(string.substring(12, 14));
+ time += second * 1000;
+ }
+ }
+ }
+ // Millenium is added because for negative numbers, integer division truncates upwards! (-8/10 = 0)
+ return (((MILLENIUM + time) / DAY) - (1000 * 365));
+ } catch (Exception e) {
+ throw new DataFormatException("Error parsing date: \"" + string + "\"");
+ }
+ }
+
+ public static long databaseTimeStringToDays(String string) {
+ if (string.equals(""))
+ return MISSING_DATE;
+ int year = Integer.parseInt(string.substring(0, 4));
+ int month = Integer.parseInt(string.substring(5, 7)) - 1;
+ int day = Integer.parseInt(string.substring(8, 10));
+ calendar.set(year, month, day);
+ long time = calendar.getTimeInMillis();
+ time += calendar.getTimeZone().getOffset(time);
+ // Millenium is added because for negative numbers, integer division truncates upwards! (-8/10 = 0)
+ return (((MILLENIUM + time) / DAY) - (1000 * 365));
+ }
+
+ public static long sortableTimeStringToMS(String string) throws DataFormatException {
+ // Calendar calendar = new GregorianCalendar();
+ try {
+ int year = Integer.parseInt(string.substring(0, 4));
+ int month = Integer.parseInt(string.substring(4, 6)) - 1;
+ int day = Integer.parseInt(string.substring(6, 8));
+ calendar.set(year, month, day);
+ long time = calendar.getTimeInMillis();
+ time += calendar.getTimeZone().getOffset(time);
+
+ if (string.length() > 8) {
+ int hour = Integer.parseInt(string.substring(8, 10));
+ time += hour * 60 * 60 * 1000;
+ if (string.length() > 8) {
+ int minute = Integer.parseInt(string.substring(10, 12));
+ time += minute * 60 * 1000;
+ if (string.length() > 8) {
+ int second = Integer.parseInt(string.substring(12, 14));
+ time += second * 1000;
+ }
+ }
+ }
+ // Millenium is added because for negative numbers, integer division truncates upwards! (-8/10 = 0)
+ return (time);
+ } catch (Exception e) {
+ throw new DataFormatException("Error parsing date: \"" + string + "\"");
+ }
+ }
+
+ public static String replaceInternationalChars(String string) {
+ char result[] = string.toCharArray();
+ for (int i = 0; i < result.length; i++) {
+ char ch = result[i];
+ int charInt = (int) ch;
+ if (charInt == 216)
+ result[i] = 'O';
+ else if (charInt == 248)
+ result[i] = 'o';
+ else if (charInt == 246)
+ result[i] = 'o';
+ else if (charInt == 244)
+ result[i] = 'o';
+ else if (charInt == 245)
+ result[i] = 'o';
+ else if (charInt == 242)
+ result[i] = 'o';
+ else if (charInt == 243)
+ result[i] = 'o';
+ else if (charInt == 237)
+ result[i] = 'i';
+ else if (charInt == 238)
+ result[i] = 'i';
+ else if (charInt == 239)
+ result[i] = 'i';
+ else if (charInt == 232)
+ result[i] = 'e';
+ else if (charInt == 233)
+ result[i] = 'e';
+ else if (charInt == 234)
+ result[i] = 'e';
+ else if (charInt == 235)
+ result[i] = 'e';
+ else if (charInt == 231)
+ result[i] = 'c';
+ else if (charInt == 224)
+ result[i] = 'a';
+ else if (charInt == 225)
+ result[i] = 'a';
+ else if (charInt == 226)
+ result[i] = 'a';
+ else if (charInt == 227)
+ result[i] = 'a';
+ else if (charInt == 228)
+ result[i] = 'a';
+ else if (charInt == 229)
+ result[i] = 'a';
+ else if (charInt == 252)
+ result[i] = 'u';
+ else if (charInt == 250)
+ result[i] = 'u';
+ else if (charInt == 253)
+ result[i] = 'y';
+ else if (charInt == 241)
+ result[i] = 'n';
+ }
+ return new String(result);
+ }
+
+ public static int caseInsensitiveIndexOf(String value, List list) {
+ String queryLC = value.toLowerCase();
+ for (int i = 0; i < list.size(); i++) {
+ String string = list.get(i);
+ if (string.toLowerCase().equals(queryLC))
+ return i;
+ }
+ return -1;
+ }
+
+ public static int levenshteinDistance(String s, String t) {
+ int d[][]; // matrix
+ int n; // length of s
+ int m; // length of t
+ int i; // iterates through s
+ int j; // iterates through t
+ char s_i; // ith character of s
+ char t_j; // jth character of t
+ int cost; // cost
+ n = s.length();
+ m = t.length();
+ if (n == 0) {
+ return m;
+ }
+ if (m == 0) {
+ return n;
+ }
+ d = new int[n + 1][m + 1];
+ for (i = 0; i <= n; i++) {
+ d[i][0] = i;
+ }
+ for (j = 0; j <= m; j++) {
+ d[0][j] = j;
+ }
+ for (i = 1; i <= n; i++) {
+ s_i = s.charAt(i - 1);
+ for (j = 1; j <= m; j++) {
+ t_j = t.charAt(j - 1);
+ if (s_i == t_j) {
+ cost = 0;
+ } else {
+ cost = 1;
+ }
+ d[i][j] = Math.min(d[i - 1][j] + 1, Math.min(d[i][j - 1] + 1, d[i - 1][j - 1] + cost));
+ }
+ }
+ return d[n][m];
+ }
+
+ /**
+ * Get hex string interpretation of the 16-byte MD5 hash for an input string Author: Kristina
+ */
+ public static String getMD5Digest(String str) {
+ try {
+ byte[] buffer = str.getBytes();
+ byte[] result = null;
+ StringBuffer buf = null;
+ MessageDigest md5 = MessageDigest.getInstance("MD5");
+ // allocate room for the hash
+ result = new byte[md5.getDigestLength()];
+ // calculate hash
+ md5.reset();
+ md5.update(buffer);
+
+ result = md5.digest();
+ // System.out.println(result);
+ // create hex string from the 16-byte hash
+ buf = new StringBuffer(result.length * 2);
+ for (int i = 0; i < result.length; i++) {
+ int intVal = result[i] & 0xff;
+ if (intVal < 0x10) {
+ buf.append("0");
+ }
+ buf.append(Integer.toHexString(intVal).toUpperCase());
+ }
+ return buf.toString();
+ } catch (NoSuchAlgorithmException e) {
+ System.err.println("Exception caught: " + e);
+ e.printStackTrace();
+
+ }
+ return null;
+ }
+
+ /**
+ * Get hex string interpretation of the SHA-256 hash for an input string Author: Kristina
+ */
+ public static String getSHA256Digest(String str) {
+ try {
+ byte[] buffer = str.getBytes();
+ byte[] result = null;
+ StringBuffer buf = null;
+ MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
+ // allocate room for the hash
+ result = new byte[sha256.getDigestLength()];
+ // calculate hash
+ sha256.reset();
+ sha256.update(buffer);
+
+ result = sha256.digest();
+ // System.out.println(result);
+ // create hex string from the 16-byte hash
+ buf = new StringBuffer(result.length * 2);
+ for (int i = 0; i < result.length; i++) {
+ int intVal = result[i] & 0xff;
+ if (intVal < 0x10) {
+ buf.append("0");
+ }
+ buf.append(Integer.toHexString(intVal).toUpperCase());
+ }
+ return buf.toString();
+ } catch (NoSuchAlgorithmException e) {
+ System.err.println("Exception caught: " + e);
+ e.printStackTrace();
+
+ }
+ return null;
+ }
+
+ public static String wordWrap(String text, int lineLength) {
+ text = text.trim();
+ if (text.length() < lineLength)
+ return text;
+ if (text.substring(0, lineLength).contains("\n"))
+ return text.substring(0, text.indexOf("\n")).trim() + "\n\n" + wordWrap(text.substring(text.indexOf("\n") + 1), lineLength);
+ int place = Math.max(Math.max(text.lastIndexOf(" ", lineLength), text.lastIndexOf("\t", lineLength)), text.lastIndexOf("-", lineLength));
+ return text.substring(0, place).trim() + "\n" + wordWrap(text.substring(place), lineLength);
+ }
+
+ public static boolean isDate(String string) {
+ if (string.length() == 10) {
+ if ((string.charAt(4) == '-' || string.charAt(4) == '/') || (string.charAt(4) == string.charAt(7)))
+ try {
+ int year = Integer.parseInt(string.substring(0, 4));
+ if (year < 1700 || year > 2200)
+ return false;
+ int month = Integer.parseInt(string.substring(5, 7));
+ if (month < 1 || month > 12)
+ return false;
+ int day = Integer.parseInt(string.substring(8, 10));
+ if (day < 1 || day > 31)
+ return false;
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ } else if (string.length() == 8) {
+ if ((string.charAt(2) == '-' || string.charAt(5) == '/') || (string.charAt(2) == string.charAt(5)))
+ try {
+ Integer.parseInt(string.substring(6, 8));
+ int month = Integer.parseInt(string.substring(0, 2));
+ if (month < 1 || month > 12)
+ return false;
+ int day = Integer.parseInt(string.substring(3, 5));
+ if (day < 1 || day > 31)
+ return false;
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+
+ }
+ return false;
+ }
+
+}
diff --git a/src/org/ohdsi/utilities/collections/CountingSet.java b/src/org/ohdsi/utilities/collections/CountingSet.java
new file mode 100644
index 00000000..cb7cb3c1
--- /dev/null
+++ b/src/org/ohdsi/utilities/collections/CountingSet.java
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.collections;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Class for counting recurring objects.
+ *
+ * @author schuemie
+ * @param
+ */
+public class CountingSet implements Set {
+
+ public Map key2count;
+
+ public CountingSet() {
+ key2count = new HashMap();
+ }
+
+ public CountingSet(int capacity) {
+ key2count = new HashMap(capacity);
+ }
+
+ public CountingSet(CountingSet set) {
+ key2count = new HashMap(set.key2count.size());
+ for (Map.Entry entry : set.key2count.entrySet())
+ key2count.put(entry.getKey(), new Count(entry.getValue().count));
+ }
+
+ public int getCount(T key) {
+ Count count = key2count.get(key);
+ if (count == null)
+ return 0;
+ else
+ return count.count;
+ }
+
+ /**
+ * Computes the sum of the counts
+ *
+ * @return
+ */
+ public int getSum() {
+ int sum = 0;
+ for (Count count : key2count.values())
+ sum += count.count;
+ return sum;
+ }
+
+ /**
+ * Returns the maximum count
+ *
+ * @return
+ */
+ public int getMax() {
+ int max = 0;
+ for (Count count : key2count.values())
+ if (count.count > max)
+ max = count.count;
+ return max;
+ }
+
+ /**
+ * Computes the mean of the counts
+ *
+ * @return
+ */
+ public double getMean() {
+ return (getSum() / (double) key2count.size());
+ }
+
+ /**
+ * Computes the standard deviations of the counts
+ *
+ * @return
+ */
+ public double getSD() {
+ double mean = getMean();
+ double sum = 0;
+ for (Count count : key2count.values())
+ sum += sqr(count.count - mean);
+ return Math.sqrt(sum / (double) key2count.size());
+ }
+
+ private double sqr(double d) {
+ return d * d;
+ }
+
+ public int size() {
+ return key2count.size();
+ }
+
+ public boolean isEmpty() {
+ return key2count.isEmpty();
+ }
+
+ public boolean contains(Object arg0) {
+ return key2count.containsKey(arg0);
+ }
+
+ public Iterator iterator() {
+ return key2count.keySet().iterator();
+ }
+
+ public Object[] toArray() {
+ return key2count.keySet().toArray();
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object[] toArray(Object[] arg0) {
+ return key2count.keySet().toArray(arg0);
+ }
+
+ public boolean add(T arg0) {
+ Count count = key2count.get(arg0);
+ if (count == null) {
+ count = new Count();
+ key2count.put(arg0, count);
+ return true;
+ } else {
+ count.count++;
+ return false;
+ }
+ }
+
+ public boolean add(T arg0, int inc) {
+ Count count = key2count.get(arg0);
+ if (count == null) {
+ count = new Count();
+ count.count = inc;
+ key2count.put(arg0, count);
+ return true;
+ } else {
+ count.count += inc;
+ return false;
+ }
+ }
+
+ public boolean remove(Object arg0) {
+
+ return (key2count.remove(arg0) != null);
+ }
+
+ public boolean containsAll(Collection> arg0) {
+ return key2count.keySet().containsAll(arg0);
+ }
+
+ public boolean addAll(Collection extends T> arg0) {
+ boolean changed = false;
+ for (T object : arg0) {
+ if (add(object))
+ changed = true;
+ }
+ return changed;
+ }
+
+ public boolean retainAll(Collection> arg0) {
+ return key2count.keySet().retainAll(arg0);
+ }
+
+ public boolean removeAll(Collection> arg0) {
+ return key2count.keySet().removeAll(arg0);
+ }
+
+ public void clear() {
+ key2count.clear();
+ }
+
+ /**
+ * Keep the n most frequent values, remove the rest
+ *
+ * @param n
+ */
+ public void keepTopN(int n) {
+ if (size() < n)
+ return;
+ List> list = new ArrayList>(key2count.entrySet());
+ Collections.sort(list, new Comparator>() {
+
+ @Override
+ public int compare(Entry arg0, Entry arg1) {
+ return IntegerComparator.compare(arg1.getValue().count, arg0.getValue().count);
+ }
+ });
+
+ Map newMap = new HashMap(n);
+ for (int i = 0; i < n; i++)
+ newMap.put(list.get(i).getKey(), list.get(i).getValue());
+
+ key2count = newMap;
+ }
+
+ public static class Count {
+ public int count = 1;
+
+ public Count() {
+ }
+
+ public Count(int count) {
+ this.count = count;
+ }
+
+ }
+
+ public void printCounts() {
+ List> result = new ArrayList>(key2count.entrySet());
+ Collections.sort(result, new Comparator>() {
+ public int compare(Entry o1, Entry o2) {
+ return IntegerComparator.compare(o2.getValue().count, o1.getValue().count);
+ }
+ });
+ for (Map.Entry entry : result)
+ System.out.println(entry.getKey() + "\t" + entry.getValue().count);
+ }
+}
diff --git a/src/org/ohdsi/utilities/collections/IntegerComparator.java b/src/org/ohdsi/utilities/collections/IntegerComparator.java
new file mode 100644
index 00000000..dcbd2dff
--- /dev/null
+++ b/src/org/ohdsi/utilities/collections/IntegerComparator.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.collections;
+
+import java.util.Comparator;
+
+public class IntegerComparator implements Comparator {
+
+ @Override
+ public int compare(Integer arg0, Integer arg1) {
+ if (arg0 < arg1)
+ return -1;
+ else if (arg0 > arg1)
+ return 1;
+ else
+ return 0;
+ }
+
+ public static int compare(int arg0, int arg1) {
+ if (arg0 < arg1)
+ return -1;
+ else if (arg0 > arg1)
+ return 1;
+ else
+ return 0;
+ }
+}
diff --git a/src/org/ohdsi/utilities/collections/LongComparator.java b/src/org/ohdsi/utilities/collections/LongComparator.java
new file mode 100644
index 00000000..a9763496
--- /dev/null
+++ b/src/org/ohdsi/utilities/collections/LongComparator.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.collections;
+
+import java.util.Comparator;
+
+public class LongComparator implements Comparator {
+
+ @Override
+ public int compare(Long arg0, Long arg1) {
+ if (arg0 < arg1)
+ return -1;
+ else if (arg0 > arg1)
+ return 1;
+ else
+ return 0;
+ }
+
+ public static int compare(long arg0, long arg1) {
+ if (arg0 < arg1)
+ return -1;
+ else if (arg0 > arg1)
+ return 1;
+ else
+ return 0;
+ }
+}
diff --git a/src/org/ohdsi/utilities/collections/OneToManyList.java b/src/org/ohdsi/utilities/collections/OneToManyList.java
new file mode 100644
index 00000000..db8216da
--- /dev/null
+++ b/src/org/ohdsi/utilities/collections/OneToManyList.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.collections;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class OneToManyList {
+ private Map> map = new HashMap>();
+
+ public void put(K key, V value) {
+ List list = map.get(key);
+ if (list == null) {
+ list = new ArrayList();
+ map.put(key, list);
+ }
+ list.add(value);
+ }
+
+ public void putAll(OneToManyList other) {
+ for (Map.Entry> entry : other.map.entrySet())
+ for (V value : entry.getValue())
+ put(entry.getKey(), value);
+ }
+
+ public void putAll(K key, Collection values) {
+ for (V value : values)
+ put(key, value);
+ }
+
+ public List get(K key) {
+ List list = map.get(key);
+ if (list == null)
+ return Collections.emptyList();
+ else
+ return list;
+ }
+
+ public Set keySet() {
+ return map.keySet();
+ }
+
+ public Collection> values() {
+ return map.values();
+ }
+
+ public List remove(K key) {
+ return map.remove(key);
+ }
+
+ public void clear() {
+ map.clear();
+ }
+
+ public int size() {
+ int size = 0;
+ for (List value : map.values())
+ size += value.size();
+ return size;
+ }
+
+}
diff --git a/src/org/ohdsi/utilities/collections/OneToManySet.java b/src/org/ohdsi/utilities/collections/OneToManySet.java
new file mode 100644
index 00000000..bf91989b
--- /dev/null
+++ b/src/org/ohdsi/utilities/collections/OneToManySet.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.collections;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class OneToManySet {
+ private Map> map = new HashMap>();
+
+ public boolean put(K key, V value){
+ Set set = map.get(key);
+ if (set == null){
+ set = new HashSet();
+ map.put(key, set);
+ }
+ return set.add(value);
+ }
+
+ public void set(K key, Set set){
+ map.put(key, set);
+ }
+
+ public Set get(K key){
+ Set set = map.get(key);
+ if (set == null)
+ return Collections.emptySet();
+ else
+ return set;
+ }
+
+ public Set keySet(){
+ return map.keySet();
+ }
+
+ public Collection> values(){
+ return map.values();
+ }
+
+ public Set>> entrySet(){
+ return map.entrySet();
+ }
+
+ public int size(){
+ return map.size();
+ }
+
+
+}
+
diff --git a/src/org/ohdsi/utilities/collections/Pair.java b/src/org/ohdsi/utilities/collections/Pair.java
new file mode 100644
index 00000000..b9457c28
--- /dev/null
+++ b/src/org/ohdsi/utilities/collections/Pair.java
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.collections;
+
+import java.io.Serializable;
+
+public class Pair implements Serializable {
+
+ private A object1;
+ private B object2;
+ private static final long serialVersionUID = 1784282381416947673L;
+
+ public Pair(A item1, B item2) {
+ this.object1 = item1;
+ this.object2 = item2;
+ }
+
+ public String toString() {
+ return "[[" + object1.toString() + "],[" + object2.toString() + "]]";
+ }
+
+ public int hashCode() {
+ return object1.hashCode() + object2.hashCode();
+ }
+
+ public A getItem1() {
+ return object1;
+ }
+
+ public B getItem2() {
+ return object2;
+ }
+
+ public void setItem1(A item1) {
+ object1 = item1;
+ }
+
+ public void setItem2(B item2) {
+ object2 = item2;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public boolean equals(Object other) {
+ if (other instanceof Pair)
+ if (((Pair) other).object1.equals(object1))
+ if (((Pair) other).object2.equals(object2))
+ return true;
+ return false;
+ }
+}
diff --git a/src/org/ohdsi/utilities/files/FileSorter.java b/src/org/ohdsi/utilities/files/FileSorter.java
new file mode 100644
index 00000000..3e54e0e4
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/FileSorter.java
@@ -0,0 +1,325 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Class for sorting (large) comma separated value text files. Assumes first row contains header
+ *
+ * @author schuemie
+ */
+public class FileSorter {
+
+ /**
+ * Chunksize is the number of rows sorted in memory in one time. Higher chunk size leads to better performance but requires more memory. Set chunksize to -1
+ * to let the system determine the largest chunk size based on available memory.
+ */
+ public static int chunckSize = -1;
+ public static boolean verbose = false;
+ public static boolean caseSensitiveColumnNames = false;
+ public static int maxNumberOfTempFiles = 500;
+ public static double minFreeMemFraction = 0.25;
+ public static boolean checkIfAlreadySorted = false;
+ public static int maxCheckRows = 10000000; // Check only first 10000000 rows to see if already sorted
+
+ public static void sort(String filename, String... columnNames) {
+ boolean[] sortNumeric = new boolean[columnNames.length];
+ Arrays.fill(sortNumeric, false);
+ sort(filename, columnNames, sortNumeric);
+ }
+
+ public static void sort(String filename, String[] columnnames, boolean[] sortNumeric) {
+ if (columnnames.length != sortNumeric.length)
+ throw new RuntimeException("Numeric sort array lenght does not equal sort column names");
+
+ System.gc();
+ long availableMem = getFreeMem();
+ long minFreeMem = Math.round(availableMem * minFreeMemFraction);
+
+ if (verbose) {
+ System.out.println("Starting sort of " + filename);
+ if (chunckSize == -1)
+ System.out.println("Memory available for sorting: " + availableMem + " bytes. Min free = " + minFreeMem);
+ }
+
+ Iterator> iterator = new ReadCSVFile(filename).iterator();
+
+ List header = iterator.next();
+
+ Comparator> comparator = buildComparator(columnnames, sortNumeric, header);
+
+ if (checkIfAlreadySorted) {
+ if (isSorted(iterator, comparator))
+ return;
+ else {
+ iterator = new ReadCSVFile(filename).iterator();
+ iterator.next(); // skip header
+ }
+ }
+
+ int nrOfFiles = 0;
+ int sorted = 0;
+ while (iterator.hasNext()) {
+ List> tempRows;
+ if (chunckSize == -1)
+ tempRows = readUntilMemFull(iterator, minFreeMem);
+ else
+ tempRows = readRows(iterator, chunckSize);
+
+ // sort the rows
+ Collections.sort(tempRows, comparator);
+
+ String tempFilename = generateFilename(filename, nrOfFiles++);
+
+ // write temp file to disk
+ writeToDisk(header, tempRows, tempFilename);
+
+ sorted += tempRows.size();
+ if (verbose)
+ System.out.println("-Sorted " + sorted + " lines");
+ }
+ mergeByBatches(nrOfFiles, filename, comparator);
+ }
+
+ private static boolean isSorted(Iterator> iterator, Comparator> comparator) {
+ if (verbose)
+ System.out.println("Checking whether already sorted");
+ List previous = null;
+ if (iterator.hasNext()) {
+ previous = iterator.next();
+ }
+ int i = 0;
+ while (iterator.hasNext()) {
+ List row = iterator.next();
+ if (comparator.compare(previous, row) > 0) {
+ if (verbose)
+ System.out.println("File not yet sorted");
+ return false;
+ }
+ previous = row;
+ i++;
+ if (i > maxCheckRows)
+ break;
+ }
+ if (verbose)
+ System.out.println("File already sorted");
+ return true;
+ }
+
+ private static void mergeByBatches(int nrOfFiles, String source, Comparator> comparator) {
+ int level = 0;
+ String sourceBase = source;
+ String targetBase;
+ do {
+ if (verbose)
+ System.out.println("Merging " + nrOfFiles + " files");
+
+ int newNrOfFiles = 0;
+ int from = 0;
+ targetBase = source + "_" + level;
+ while (from < nrOfFiles) {
+ String targetFilename;
+ if (nrOfFiles <= maxNumberOfTempFiles)
+ targetFilename = source;
+ else
+ targetFilename = generateFilename(targetBase, newNrOfFiles++);
+
+ int to = Math.min(from + maxNumberOfTempFiles, nrOfFiles);
+ mergeFiles(sourceBase, from, to, targetFilename, comparator);
+ deleteTempFiles(sourceBase, from, to);
+ from = to;
+ }
+ nrOfFiles = newNrOfFiles;
+ level++;
+ sourceBase = targetBase;
+ } while (nrOfFiles > 1);
+ }
+
+ private static void writeToDisk(List header, List> rows, String filename) {
+ WriteCSVFile out = new WriteCSVFile(filename);
+ if (header != null)
+ out.write(header);
+ for (List row : rows)
+ out.write(row);
+ out.close();
+ }
+
+ private static List> readRows(Iterator> iterator, int nrOfRows) {
+ List> rows = new ArrayList>();
+ int i = 0;
+ while (i++ < nrOfRows && iterator.hasNext())
+ rows.add(iterator.next());
+ return rows;
+ }
+
+ private static List> readUntilMemFull(Iterator> iterator, long minFreeMem) {
+ List> rows = new ArrayList>();
+ System.gc();
+ if (verbose)
+ System.out.println("Loading next batch. Available memory: " + getFreeMem());
+ long freeMem = Long.MAX_VALUE;
+ while (freeMem > minFreeMem && iterator.hasNext()) {
+ rows.add(iterator.next());
+ freeMem = getFreeMem();
+ }
+ return rows;
+ }
+
+ private static long getFreeMem() {
+ return Runtime.getRuntime().freeMemory() + Runtime.getRuntime().maxMemory() - Runtime.getRuntime().totalMemory();
+ }
+
+ private static Comparator> buildComparator(String[] columnnames, boolean[] sortNumeric, List header) {
+ int[] indexesToCompare = new int[columnnames.length];
+ for (int i = 0; i < columnnames.length; i++)
+ indexesToCompare[i] = getIndexForColumn(header, new String(columnnames[i]));
+
+ return new RowComparator(indexesToCompare, sortNumeric);
+ }
+
+ private static class RowComparator implements Comparator> {
+ private int[] indexes;
+ private boolean[] sortNumeric;
+
+ public RowComparator(int[] indexes, boolean[] sortNumeric) {
+ this.indexes = indexes;
+ this.sortNumeric = sortNumeric;
+ }
+
+ public int compare(List o1, List o2) {
+ int result = 0;
+ int i = 0;
+ while (result == 0 && i < indexes.length) {
+ String value1 = o1.get(indexes[i]);
+ String value2 = o2.get(indexes[i]);
+ if (sortNumeric[i])
+ result = efficientLongCompare(value1, value2);
+ else
+ result = value1.compareTo(value2);
+ i++;
+ }
+ return result;
+ }
+
+ private int efficientLongCompare(String value1, String value2) {
+ if (value1.length() > value2.length())
+ return 1;
+ else if (value1.length() < value2.length())
+ return -1;
+ else
+ return value1.compareTo(value2);
+ }
+
+ }
+
+ private static void deleteTempFiles(String base, int start, int end) {
+ for (int i = start; i < end; i++)
+ (new File(generateFilename(base, i))).delete();
+ }
+
+ private static String generateFilename(String base, int number) {
+ return base + "_" + number + ".tmp";
+ }
+
+ private static void mergeFiles(String sourceBase, int start, int end, String target, Comparator> comparator) {
+ List>> tempFiles = new ArrayList>>();
+
+ List> filerows = new ArrayList>();
+ List header = null;
+ boolean done = true;
+ for (int i = start; i < end; i++) {
+ ReadCSVFile tempFile = new ReadCSVFile(generateFilename(sourceBase, i));
+ Iterator> iterator = tempFile.getIterator();
+ if (iterator.hasNext()) {
+ if (tempFiles.size() == 0) // its the first one
+ header = iterator.next();
+ else
+ iterator.next();
+ }
+ tempFiles.add(iterator);
+
+ // initialize
+ if (iterator.hasNext()) {
+ filerows.add(iterator.next());
+ done = false;
+ } else
+ filerows.add(null);
+ }
+ WriteCSVFile out = new WriteCSVFile(target);
+ out.write(header);
+ while (!done) {
+ // Find best file to pick from:
+ List bestRow = null;
+ int bestFile = -1;
+ for (int i = 0; i < filerows.size(); i++) {
+ if (bestRow == null || (filerows.get(i) != null && comparator.compare(filerows.get(i), bestRow) < 0)) {
+ bestRow = filerows.get(i);
+ bestFile = i;
+ }
+ }
+ if (bestRow == null)
+ done = true;
+ else {
+ // write it to file:
+ out.write(bestRow);
+
+ // get next from winning file:
+ List newRow;
+ Iterator> bestFileIterator = tempFiles.get(bestFile);
+ if (bestFileIterator.hasNext())
+ newRow = bestFileIterator.next();
+ else
+ newRow = null;
+ filerows.set(bestFile, newRow);
+ }
+ }
+ out.close();
+ }
+
+ private static int getIndexForColumn(List list, String value) throws RuntimeException {
+ int result;
+ if (caseSensitiveColumnNames)
+ result = list.indexOf(value);
+ else
+ result = caseInsensitiveIndexOf(value, list);
+ if (result == -1)
+ throw (new RuntimeException("File sorter could not find column \"" + value + "\""));
+ return result;
+ }
+
+ public static int caseInsensitiveIndexOf(String value, List list) {
+ String queryLC = value.toLowerCase();
+ for (int i = 0; i < list.size(); i++) {
+ String string = list.get(i);
+ if (string.toLowerCase().equals(queryLC))
+ return i;
+ }
+ return -1;
+ }
+
+}
diff --git a/src/org/ohdsi/utilities/files/MultiRowIterator.java b/src/org/ohdsi/utilities/files/MultiRowIterator.java
new file mode 100644
index 00000000..5f9e6c37
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/MultiRowIterator.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+import org.ohdsi.utilities.files.MultiRowIterator.MultiRowSet;
+
+/**
+ * Allows iteration over multiple tables (as Iterator) simultaneously, synchronized by the value of the [linkingColumn]. Assumes all tables are sorted by
+ * the [linkingColumn].
+ *
+ * @author MSCHUEMI
+ */
+public class MultiRowIterator implements Iterator {
+
+ private Iterator[] iterators;
+ private String[] tableNames;
+ private Row[] nextRows;
+ private MultiRowSet buffer;
+ private String linkingColumn;
+ private boolean sortedNumerically;
+
+ public MultiRowIterator(String linkingColumn, String[] tableNames, Iterator... tableIterators) {
+ this(linkingColumn, false, tableNames, tableIterators);
+ }
+
+ public MultiRowIterator(String linkingColumn, boolean sortedNumerically, String[] tableNames, Iterator[] tableIterators) {
+ this.iterators = tableIterators;
+ this.linkingColumn = linkingColumn;
+ this.tableNames = tableNames;
+ this.sortedNumerically = sortedNumerically;
+ startRead();
+ }
+
+ private void startRead() {
+ nextRows = new Row[iterators.length];
+ for (int i = 0; i < iterators.length; i++)
+ if (iterators[i].hasNext())
+ nextRows[i] = iterators[i].next();
+ else
+ nextRows[i] = null;
+ readNext();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return (buffer != null);
+ }
+
+ @Override
+ public MultiRowSet next() {
+ MultiRowSet result = buffer;
+ readNext();
+ return result;
+ }
+
+ private void readNext() {
+ String lowestLinkingColumn = findLowestLinkingColumn(nextRows);
+ if (lowestLinkingColumn == null) {
+ buffer = null;
+ return;
+ }
+ buffer = new MultiRowSet(tableNames);
+ buffer.linkingId = lowestLinkingColumn;
+ for (int i = 0; i < iterators.length; i++) {
+ Iterator iterator = iterators[i];
+ while (nextRows[i] != null && nextRows[i].get(linkingColumn).equals(lowestLinkingColumn)) {
+ buffer.get(tableNames[i]).add(nextRows[i]);
+ if (iterator.hasNext())
+ nextRows[i] = iterator.next();
+ else
+ nextRows[i] = null;
+ }
+ }
+ }
+
+ private String findLowestLinkingColumn(Row[] rows) {
+ String linkingId = null;
+ for (Row row : rows)
+ if (row != null && (linkingId == null || compare(row.get(linkingColumn), linkingId) < 0))
+ linkingId = row.get(linkingColumn);
+ return linkingId;
+ }
+
+ private int compare(String value1, String value2) {
+ if (sortedNumerically)
+ return efficientLongCompare(value1, value2);
+ else
+ return value1.compareTo(value2);
+ }
+
+ private int efficientLongCompare(String value1, String value2) {
+ if (value1.length() > value2.length())
+ return 1;
+ else if (value1.length() < value2.length())
+ return -1;
+ else
+ return value1.compareTo(value2);
+ }
+
+ @Override
+ public void remove() {
+ System.err.println("Calling unimplemented remove method in class " + this.getClass().getName());
+ }
+
+ public static class MultiRowSet extends HashMap> {
+ private static final long serialVersionUID = 1164317535150664720L;
+
+ public String linkingId;
+
+ public MultiRowSet(String[] tableNames) {
+ for (String tableName : tableNames) {
+ put(tableName, new ArrayList());
+ }
+ }
+
+ public List getNonEmptyTableNames() {
+ List result = new ArrayList();
+ for (String tableName : keySet())
+ if (get(tableName).size() != 0)
+ result.add(tableName);
+ return result;
+ }
+
+ /**
+ * returns the total number of rows (summed across the tables)
+ *
+ * @return
+ */
+ public int totalSize() {
+ int size = 0;
+ for (List rows : values())
+ size += rows.size();
+ return size;
+ }
+
+ }
+
+}
diff --git a/src/org/ohdsi/utilities/files/QuickAndDirtyXlsxReader.java b/src/org/ohdsi/utilities/files/QuickAndDirtyXlsxReader.java
new file mode 100644
index 00000000..5f79e977
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/QuickAndDirtyXlsxReader.java
@@ -0,0 +1,568 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.utilities.collections.IntegerComparator;
+import org.ohdsi.utilities.files.QuickAndDirtyXlsxReader.Sheet;
+
+public class QuickAndDirtyXlsxReader extends ArrayList {
+
+ private static final long serialVersionUID = 25124428448185386L;
+
+ private List sharedStrings = new ArrayList();
+
+ private Map rIdToSheet = new HashMap();
+ private Map filenameToSheet = new HashMap();
+
+ public static void main(String[] args) {
+ QuickAndDirtyXlsxReader reader = new QuickAndDirtyXlsxReader("S:/Data/THIN/ScanReport.xlsx");
+ WriteCSVFile out = new WriteCSVFile("c:/temp/xlsxdump.csv");
+ for (Sheet sheet : reader) {
+ List sheetHeader = new ArrayList();
+ sheetHeader.add("*** " + sheet.name + " ***");
+ out.write(sheetHeader);
+ for (Row row : sheet)
+ out.write(row);
+
+ List sheetFooter = new ArrayList();
+ sheetHeader.add("");
+ out.write(sheetFooter);
+ }
+ out.close();
+
+ }
+
+ public QuickAndDirtyXlsxReader(String filename) {
+ try {
+ // Step 1: load the shared strings (if any), and the rels
+ FileInputStream inputStream = new FileInputStream(filename);
+ loadSharedStringsAndRels(inputStream);
+
+ // Step 2: load the data:
+ inputStream = new FileInputStream(filename);
+ readFromStream(inputStream);
+
+ // Step 3: order the sheets:
+ Collections.sort(this, new Comparator() {
+
+ @Override
+ public int compare(Sheet o1, Sheet o2) {
+ return IntegerComparator.compare(o1.order, o2.order);
+ }
+ });
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void loadSharedStringsAndRels(FileInputStream inputStream) {
+ try {
+ int tasksComplete = 0;
+ ZipInputStream zipInputStream = new ZipInputStream(inputStream);
+
+ ZipEntry zipEntry = null;
+ while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+ String filename = zipEntry.getName();
+ if (filename.equals("xl/sharedStrings.xml")) {
+ processSharedStrings(zipInputStream);
+ tasksComplete++;
+ } else if (filename.equals("xl/_rels/workbook.xml.rels")) {
+ processRels(zipInputStream);
+ tasksComplete++;
+ }
+
+ if (tasksComplete == 2) {
+ zipInputStream.close();
+ break;
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void processRels(ZipInputStream inputStream) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+ String line = null;
+ while ((line = bufferedReader.readLine()) != null)
+ for (String tag : StringUtilities.multiFindBetween(line, "")) {
+ String rId = StringUtilities.findBetween(tag, "Id=\"", "\"");
+ String filename = "xl/" + StringUtilities.findBetween(tag, "Target=\"", "\"");
+ if (filename.contains("/sheet")) {
+ Sheet sheet = new Sheet();
+ add(sheet);
+ rIdToSheet.put(rId, sheet);
+ filenameToSheet.put(filename, sheet);
+ }
+ }
+ }
+
+ public QuickAndDirtyXlsxReader(InputStream stream) {
+ readFromStream(stream);
+ }
+
+ private void readFromStream(InputStream inputStream) {
+ try {
+ ZipInputStream zipInputStream = new ZipInputStream(inputStream);
+
+ ZipEntry zipEntry = null;
+ while ((zipEntry = zipInputStream.getNextEntry()) != null) {
+ String filename = zipEntry.getName();
+ if (filename.equals("xl/workbook.xml"))
+ processWorkBook(zipInputStream);
+ else if (filename.startsWith("xl/worksheets/sheet"))
+ processSheet(filename, zipInputStream);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ private void processSharedStrings(ZipInputStream inputStream) throws IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+ StringBuilder fullFile = new StringBuilder();
+ String line;
+ while ((line = bufferedReader.readLine()) != null)
+ fullFile.append(line);
+
+ for (String string : StringUtilities.multiFindBetween(fullFile.toString(), "", ""))
+ if (string.trim().equals("
")) // Empty string
+ sharedStrings.add("");
+ else {
+ string = StringUtilities.findBetween(string, ">", "<");
+ sharedStrings.add(string);
+ }
+ }
+
+ private void processSheet(String filename, ZipInputStream inputStream) throws IOException {
+ Sheet sheet = filenameToSheet.get(filename);
+ //System.out.println(filename + "\t" + sheet.name);
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+ String line;
+ StringBuilder fullSheet = new StringBuilder();
+ while ((line = bufferedReader.readLine()) != null)
+ fullSheet.append(line);
+
+ for (String rowLine : StringUtilities.multiFindBetween(fullSheet.toString(), "")) {
+ Row row = new Row();
+ row.addAll(findCellValues(rowLine));
+ if (row.size() != 0)
+ sheet.add(row);
+ }
+
+ }
+
+ public List findCellValues(String string) {
+ List result = new ArrayList();
+ int tagStart = -1;
+ int stringStart = -1;
+ int column = -1;
+ boolean sharedString = false;
+ for (int i = 0; i < string.length(); i++) {
+ char ch = string.charAt(i);
+ if (ch == '<')
+ tagStart = i + 1;
+ else if (ch == '>') {
+ if (tagStart != -1 && i > tagStart) {
+ String tag = string.substring(tagStart, i);
+ if (tag.charAt(0) == 'c') {
+ sharedString = tag.contains("t=\"s\"");
+ column = parseColumn(StringUtilities.findBetween(tag, "r=\"", "\""));
+ } else if (tag.startsWith("v") || tag.startsWith("t"))
+ stringStart = i + 1;
+ else if (tag.equals("/v") || tag.equals("/t")) {
+ if (stringStart != -1 && i > stringStart) {
+ for (int j = result.size(); j <= column; j++)
+ result.add("");
+ if (sharedString) {
+ int index = Integer.parseInt(string.substring(stringStart, tagStart - 1));
+ result.set(column, sharedStrings.get(index));
+ } else
+ result.set(column, decode(string.substring(stringStart, tagStart - 1)));
+ }
+ stringStart = -1;
+ column = -1;
+ }
+
+ }
+ }
+
+ }
+ return result;
+ }
+
+ private int parseColumn(String cellIdString) {
+ int column = 0;
+ for (int i = 0; i < cellIdString.length(); i++) {
+ char ch = cellIdString.charAt(i);
+ if (Character.isDigit(cellIdString.charAt(i))) {
+ return column - 1;
+ } else {
+ column *= 26;
+ column += (int) ch - 64;
+ }
+ }
+ return -1;
+ }
+
+ private static HashMap htmlEntities = new HashMap();
+ static {
+ htmlEntities.put("nbsp", new Integer(160));
+ htmlEntities.put("iexcl", new Integer(161));
+ htmlEntities.put("cent", new Integer(162));
+ htmlEntities.put("pound", new Integer(163));
+ htmlEntities.put("curren", new Integer(164));
+ htmlEntities.put("yen", new Integer(165));
+ htmlEntities.put("brvbar", new Integer(166));
+ htmlEntities.put("sect", new Integer(167));
+ htmlEntities.put("uml", new Integer(168));
+ htmlEntities.put("copy", new Integer(169));
+ htmlEntities.put("ordf", new Integer(170));
+ htmlEntities.put("laquo", new Integer(171));
+ htmlEntities.put("not", new Integer(172));
+ htmlEntities.put("shy", new Integer(173));
+ htmlEntities.put("reg", new Integer(174));
+ htmlEntities.put("macr", new Integer(175));
+ htmlEntities.put("deg", new Integer(176));
+ htmlEntities.put("plusmn", new Integer(177));
+ htmlEntities.put("sup2", new Integer(178));
+ htmlEntities.put("sup3", new Integer(179));
+ htmlEntities.put("acute", new Integer(180));
+ htmlEntities.put("micro", new Integer(181));
+ htmlEntities.put("para", new Integer(182));
+ htmlEntities.put("middot", new Integer(183));
+ htmlEntities.put("cedil", new Integer(184));
+ htmlEntities.put("sup1", new Integer(185));
+ htmlEntities.put("ordm", new Integer(186));
+ htmlEntities.put("raquo", new Integer(187));
+ htmlEntities.put("frac14", new Integer(188));
+ htmlEntities.put("frac12", new Integer(189));
+ htmlEntities.put("frac34", new Integer(190));
+ htmlEntities.put("iquest", new Integer(191));
+ htmlEntities.put("Agrave", new Integer(192));
+ htmlEntities.put("Aacute", new Integer(193));
+ htmlEntities.put("Acirc", new Integer(194));
+ htmlEntities.put("Atilde", new Integer(195));
+ htmlEntities.put("Auml", new Integer(196));
+ htmlEntities.put("Aring", new Integer(197));
+ htmlEntities.put("AElig", new Integer(198));
+ htmlEntities.put("Ccedil", new Integer(199));
+ htmlEntities.put("Egrave", new Integer(200));
+ htmlEntities.put("Eacute", new Integer(201));
+ htmlEntities.put("Ecirc", new Integer(202));
+ htmlEntities.put("Euml", new Integer(203));
+ htmlEntities.put("Igrave", new Integer(204));
+ htmlEntities.put("Iacute", new Integer(205));
+ htmlEntities.put("Icirc", new Integer(206));
+ htmlEntities.put("Iuml", new Integer(207));
+ htmlEntities.put("ETH", new Integer(208));
+ htmlEntities.put("Ntilde", new Integer(209));
+ htmlEntities.put("Ograve", new Integer(210));
+ htmlEntities.put("Oacute", new Integer(211));
+ htmlEntities.put("Ocirc", new Integer(212));
+ htmlEntities.put("Otilde", new Integer(213));
+ htmlEntities.put("Ouml", new Integer(214));
+ htmlEntities.put("times", new Integer(215));
+ htmlEntities.put("Oslash", new Integer(216));
+ htmlEntities.put("Ugrave", new Integer(217));
+ htmlEntities.put("Uacute", new Integer(218));
+ htmlEntities.put("Ucirc", new Integer(219));
+ htmlEntities.put("Uuml", new Integer(220));
+ htmlEntities.put("Yacute", new Integer(221));
+ htmlEntities.put("THORN", new Integer(222));
+ htmlEntities.put("szlig", new Integer(223));
+ htmlEntities.put("agrave", new Integer(224));
+ htmlEntities.put("aacute", new Integer(225));
+ htmlEntities.put("acirc", new Integer(226));
+ htmlEntities.put("atilde", new Integer(227));
+ htmlEntities.put("auml", new Integer(228));
+ htmlEntities.put("aring", new Integer(229));
+ htmlEntities.put("aelig", new Integer(230));
+ htmlEntities.put("ccedil", new Integer(231));
+ htmlEntities.put("egrave", new Integer(232));
+ htmlEntities.put("eacute", new Integer(233));
+ htmlEntities.put("ecirc", new Integer(234));
+ htmlEntities.put("euml", new Integer(235));
+ htmlEntities.put("igrave", new Integer(236));
+ htmlEntities.put("iacute", new Integer(237));
+ htmlEntities.put("icirc", new Integer(238));
+ htmlEntities.put("iuml", new Integer(239));
+ htmlEntities.put("eth", new Integer(240));
+ htmlEntities.put("ntilde", new Integer(241));
+ htmlEntities.put("ograve", new Integer(242));
+ htmlEntities.put("oacute", new Integer(243));
+ htmlEntities.put("ocirc", new Integer(244));
+ htmlEntities.put("otilde", new Integer(245));
+ htmlEntities.put("ouml", new Integer(246));
+ htmlEntities.put("divide", new Integer(247));
+ htmlEntities.put("oslash", new Integer(248));
+ htmlEntities.put("ugrave", new Integer(249));
+ htmlEntities.put("uacute", new Integer(250));
+ htmlEntities.put("ucirc", new Integer(251));
+ htmlEntities.put("uuml", new Integer(252));
+ htmlEntities.put("yacute", new Integer(253));
+ htmlEntities.put("thorn", new Integer(254));
+ htmlEntities.put("yuml", new Integer(255));
+ htmlEntities.put("fnof", new Integer(402));
+ htmlEntities.put("Alpha", new Integer(913));
+ htmlEntities.put("Beta", new Integer(914));
+ htmlEntities.put("Gamma", new Integer(915));
+ htmlEntities.put("Delta", new Integer(916));
+ htmlEntities.put("Epsilon", new Integer(917));
+ htmlEntities.put("Zeta", new Integer(918));
+ htmlEntities.put("Eta", new Integer(919));
+ htmlEntities.put("Theta", new Integer(920));
+ htmlEntities.put("Iota", new Integer(921));
+ htmlEntities.put("Kappa", new Integer(922));
+ htmlEntities.put("Lambda", new Integer(923));
+ htmlEntities.put("Mu", new Integer(924));
+ htmlEntities.put("Nu", new Integer(925));
+ htmlEntities.put("Xi", new Integer(926));
+ htmlEntities.put("Omicron", new Integer(927));
+ htmlEntities.put("Pi", new Integer(928));
+ htmlEntities.put("Rho", new Integer(929));
+ htmlEntities.put("Sigma", new Integer(931));
+ htmlEntities.put("Tau", new Integer(932));
+ htmlEntities.put("Upsilon", new Integer(933));
+ htmlEntities.put("Phi", new Integer(934));
+ htmlEntities.put("Chi", new Integer(935));
+ htmlEntities.put("Psi", new Integer(936));
+ htmlEntities.put("Omega", new Integer(937));
+ htmlEntities.put("alpha", new Integer(945));
+ htmlEntities.put("beta", new Integer(946));
+ htmlEntities.put("gamma", new Integer(947));
+ htmlEntities.put("delta", new Integer(948));
+ htmlEntities.put("epsilon", new Integer(949));
+ htmlEntities.put("zeta", new Integer(950));
+ htmlEntities.put("eta", new Integer(951));
+ htmlEntities.put("theta", new Integer(952));
+ htmlEntities.put("iota", new Integer(953));
+ htmlEntities.put("kappa", new Integer(954));
+ htmlEntities.put("lambda", new Integer(955));
+ htmlEntities.put("mu", new Integer(956));
+ htmlEntities.put("nu", new Integer(957));
+ htmlEntities.put("xi", new Integer(958));
+ htmlEntities.put("omicron", new Integer(959));
+ htmlEntities.put("pi", new Integer(960));
+ htmlEntities.put("rho", new Integer(961));
+ htmlEntities.put("sigmaf", new Integer(962));
+ htmlEntities.put("sigma", new Integer(963));
+ htmlEntities.put("tau", new Integer(964));
+ htmlEntities.put("upsilon", new Integer(965));
+ htmlEntities.put("phi", new Integer(966));
+ htmlEntities.put("chi", new Integer(967));
+ htmlEntities.put("psi", new Integer(968));
+ htmlEntities.put("omega", new Integer(969));
+ htmlEntities.put("thetasym", new Integer(977));
+ htmlEntities.put("upsih", new Integer(978));
+ htmlEntities.put("piv", new Integer(982));
+ htmlEntities.put("bull", new Integer(8226));
+ htmlEntities.put("hellip", new Integer(8230));
+ htmlEntities.put("prime", new Integer(8242));
+ htmlEntities.put("Prime", new Integer(8243));
+ htmlEntities.put("oline", new Integer(8254));
+ htmlEntities.put("frasl", new Integer(8260));
+ htmlEntities.put("weierp", new Integer(8472));
+ htmlEntities.put("image", new Integer(8465));
+ htmlEntities.put("real", new Integer(8476));
+ htmlEntities.put("trade", new Integer(8482));
+ htmlEntities.put("alefsym", new Integer(8501));
+ htmlEntities.put("larr", new Integer(8592));
+ htmlEntities.put("uarr", new Integer(8593));
+ htmlEntities.put("rarr", new Integer(8594));
+ htmlEntities.put("darr", new Integer(8595));
+ htmlEntities.put("harr", new Integer(8596));
+ htmlEntities.put("crarr", new Integer(8629));
+ htmlEntities.put("lArr", new Integer(8656));
+ htmlEntities.put("uArr", new Integer(8657));
+ htmlEntities.put("rArr", new Integer(8658));
+ htmlEntities.put("dArr", new Integer(8659));
+ htmlEntities.put("hArr", new Integer(8660));
+ htmlEntities.put("forall", new Integer(8704));
+ htmlEntities.put("part", new Integer(8706));
+ htmlEntities.put("exist", new Integer(8707));
+ htmlEntities.put("empty", new Integer(8709));
+ htmlEntities.put("nabla", new Integer(8711));
+ htmlEntities.put("isin", new Integer(8712));
+ htmlEntities.put("notin", new Integer(8713));
+ htmlEntities.put("ni", new Integer(8715));
+ htmlEntities.put("prod", new Integer(8719));
+ htmlEntities.put("sum", new Integer(8721));
+ htmlEntities.put("minus", new Integer(8722));
+ htmlEntities.put("lowast", new Integer(8727));
+ htmlEntities.put("radic", new Integer(8730));
+ htmlEntities.put("prop", new Integer(8733));
+ htmlEntities.put("infin", new Integer(8734));
+ htmlEntities.put("ang", new Integer(8736));
+ htmlEntities.put("and", new Integer(8743));
+ htmlEntities.put("or", new Integer(8744));
+ htmlEntities.put("cap", new Integer(8745));
+ htmlEntities.put("cup", new Integer(8746));
+ htmlEntities.put("int", new Integer(8747));
+ htmlEntities.put("there4", new Integer(8756));
+ htmlEntities.put("sim", new Integer(8764));
+ htmlEntities.put("cong", new Integer(8773));
+ htmlEntities.put("asymp", new Integer(8776));
+ htmlEntities.put("ne", new Integer(8800));
+ htmlEntities.put("equiv", new Integer(8801));
+ htmlEntities.put("le", new Integer(8804));
+ htmlEntities.put("ge", new Integer(8805));
+ htmlEntities.put("sub", new Integer(8834));
+ htmlEntities.put("sup", new Integer(8835));
+ htmlEntities.put("nsub", new Integer(8836));
+ htmlEntities.put("sube", new Integer(8838));
+ htmlEntities.put("supe", new Integer(8839));
+ htmlEntities.put("oplus", new Integer(8853));
+ htmlEntities.put("otimes", new Integer(8855));
+ htmlEntities.put("perp", new Integer(8869));
+ htmlEntities.put("sdot", new Integer(8901));
+ htmlEntities.put("lceil", new Integer(8968));
+ htmlEntities.put("rceil", new Integer(8969));
+ htmlEntities.put("lfloor", new Integer(8970));
+ htmlEntities.put("rfloor", new Integer(8971));
+ htmlEntities.put("lang", new Integer(9001));
+ htmlEntities.put("rang", new Integer(9002));
+ htmlEntities.put("loz", new Integer(9674));
+ htmlEntities.put("spades", new Integer(9824));
+ htmlEntities.put("clubs", new Integer(9827));
+ htmlEntities.put("hearts", new Integer(9829));
+ htmlEntities.put("diams", new Integer(9830));
+ htmlEntities.put("quot", new Integer(34));
+ htmlEntities.put("amp", new Integer(38));
+ htmlEntities.put("lt", new Integer(60));
+ htmlEntities.put("gt", new Integer(62));
+ htmlEntities.put("OElig", new Integer(338));
+ htmlEntities.put("oelig", new Integer(339));
+ htmlEntities.put("Scaron", new Integer(352));
+ htmlEntities.put("scaron", new Integer(353));
+ htmlEntities.put("Yuml", new Integer(376));
+ htmlEntities.put("circ", new Integer(710));
+ htmlEntities.put("tilde", new Integer(732));
+ htmlEntities.put("ensp", new Integer(8194));
+ htmlEntities.put("emsp", new Integer(8195));
+ htmlEntities.put("thinsp", new Integer(8201));
+ htmlEntities.put("zwnj", new Integer(8204));
+ htmlEntities.put("zwj", new Integer(8205));
+ htmlEntities.put("lrm", new Integer(8206));
+ htmlEntities.put("rlm", new Integer(8207));
+ htmlEntities.put("ndash", new Integer(8211));
+ htmlEntities.put("mdash", new Integer(8212));
+ htmlEntities.put("lsquo", new Integer(8216));
+ htmlEntities.put("rsquo", new Integer(8217));
+ htmlEntities.put("sbquo", new Integer(8218));
+ htmlEntities.put("ldquo", new Integer(8220));
+ htmlEntities.put("rdquo", new Integer(8221));
+ htmlEntities.put("bdquo", new Integer(8222));
+ htmlEntities.put("dagger", new Integer(8224));
+ htmlEntities.put("Dagger", new Integer(8225));
+ htmlEntities.put("permil", new Integer(8240));
+ htmlEntities.put("lsaquo", new Integer(8249));
+ htmlEntities.put("rsaquo", new Integer(8250));
+ htmlEntities.put("euro", new Integer(8364));
+ }
+
+ public static String decode(String s) {
+ StringBuffer result = new StringBuffer(s.length());
+ int ampInd = s.indexOf("&");
+ int lastEnd = 0;
+ while (ampInd >= 0) {
+ int nextAmp = s.indexOf("&", ampInd + 1);
+ int nextSemi = s.indexOf(";", ampInd + 1);
+ if (nextSemi != -1 && (nextAmp == -1 || nextSemi < nextAmp)) {
+ int value = -1;
+ String escape = s.substring(ampInd + 1, nextSemi);
+ try {
+ if (escape.startsWith("#")) {
+ value = Integer.parseInt(escape.substring(1), 10);
+ } else {
+ if (htmlEntities.containsKey(escape)) {
+ value = ((Integer) (htmlEntities.get(escape))).intValue();
+ }
+ }
+ } catch (NumberFormatException x) {
+ }
+ result.append(s.substring(lastEnd, ampInd));
+ lastEnd = nextSemi + 1;
+ if (value >= 0 && value <= 0xffff) {
+ result.append((char) value);
+ } else {
+ result.append("&").append(escape).append(";");
+ }
+ }
+ ampInd = nextAmp;
+ }
+ result.append(s.substring(lastEnd));
+ return result.toString();
+ }
+
+ private void processWorkBook(InputStream inputStream) throws NumberFormatException, IOException {
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+ String line = null;
+ while ((line = bufferedReader.readLine()) != null) {
+ for (String sheetTag : StringUtilities.multiFindBetween(line, "")) {
+ String name = StringUtilities.findBetween(sheetTag, "name=\"", "\"");
+ String order = StringUtilities.findBetween(sheetTag, "sheetId=\"", "\"");
+ String rId = StringUtilities.findBetween(sheetTag, "r:id=\"", "\"");
+ Sheet sheet = rIdToSheet.get(rId);
+ sheet.setName(name);
+ sheet.order = Integer.parseInt(order);
+ }
+ }
+ }
+
+ public class Sheet extends ArrayList {
+ private static final long serialVersionUID = -8597151681911998153L;
+ private String name;
+ private int order;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ }
+
+ public class Row extends ArrayList {
+ private static final long serialVersionUID = -6391290892840364766L;
+
+ }
+}
diff --git a/src/org/ohdsi/utilities/files/ReadCSVFile.java b/src/org/ohdsi/utilities/files/ReadCSVFile.java
new file mode 100644
index 00000000..2e6806d2
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/ReadCSVFile.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.ohdsi.utilities.StringUtilities;
+
+public class ReadCSVFile implements Iterable>{
+ protected BufferedReader bufferedReader;
+ public boolean EOF = false;
+ private char delimiter = ',';
+
+ public ReadCSVFile(String filename) {
+ try {
+ FileInputStream textFileStream = new FileInputStream(filename);
+ bufferedReader = new BufferedReader(new InputStreamReader(textFileStream, "UTF-8"));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public ReadCSVFile(InputStream inputstream){
+ try {
+ bufferedReader = new BufferedReader(new InputStreamReader(inputstream, "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public Iterator> getIterator() {
+ return iterator();
+ }
+
+ private class CSVFileIterator implements Iterator> {
+ private String buffer;
+
+ public CSVFileIterator() {
+ try {
+ buffer = bufferedReader.readLine();
+ if (buffer == null){
+ EOF = true;
+ bufferedReader.close();
+ }
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public boolean hasNext() {
+ return !EOF;
+ }
+
+ public List next() {
+ String result = buffer;
+ try {
+ buffer = bufferedReader.readLine();
+ if (buffer == null){
+ EOF = true;
+ bufferedReader.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return line2columns(result);
+ }
+
+ public void remove() {
+ System.err.println("Unimplemented method 'remove' called");
+ }
+ }
+
+ public Iterator> iterator() {
+ return new CSVFileIterator();
+ }
+
+ private List line2columns(String line){
+ List columns = StringUtilities.safeSplit(line, delimiter);
+ for (int i = 0; i < columns.size(); i++){
+ String column = columns.get(i);
+ if (column.startsWith("\"") && column.endsWith("\"") && column.length() > 1)
+ column = column.substring(1, column.length()-1);
+ column = column.replace("\\\"", "\"");
+ columns.set(i, column);
+ }
+ return columns;
+ }
+
+ public void setDelimiter(char delimiter) {
+ this.delimiter = delimiter;
+ }
+
+ public char getDelimiter() {
+ return delimiter;
+ }
+}
diff --git a/src/org/ohdsi/utilities/files/ReadCSVFileWithHeader.java b/src/org/ohdsi/utilities/files/ReadCSVFileWithHeader.java
new file mode 100644
index 00000000..33cda1c2
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/ReadCSVFileWithHeader.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+
+public class ReadCSVFileWithHeader implements Iterable{
+ private InputStream inputstream;
+
+ public ReadCSVFileWithHeader(String filename) {
+ try {
+ inputstream = new FileInputStream(filename);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public ReadCSVFileWithHeader(InputStream inputstream){
+ this.inputstream = inputstream;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new RowIterator();
+ }
+
+ public class RowIterator implements Iterator{
+
+ private Iterator> iterator;
+ private Map fieldName2ColumnIndex;
+
+ public RowIterator(){
+ iterator = new ReadCSVFile(inputstream).iterator();
+ fieldName2ColumnIndex = new HashMap();
+ for (String header : iterator.next())
+ fieldName2ColumnIndex.put(header, fieldName2ColumnIndex.size());
+ }
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public Row next() {
+ return new Row(iterator.next(),fieldName2ColumnIndex);
+ }
+
+ @Override
+ public void remove() {
+ throw new RuntimeException("Remove not supported");
+ }
+
+ }
+}
diff --git a/src/org/ohdsi/utilities/files/ReadTextFile.java b/src/org/ohdsi/utilities/files/ReadTextFile.java
new file mode 100644
index 00000000..54100320
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/ReadTextFile.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class ReadTextFile implements Iterable{
+ public String filename;
+ protected BufferedReader bufferedReader;
+ public boolean EOF = false;
+
+
+ public ReadTextFile(InputStream inputStream) {
+ try {
+ bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ System.err.println("Computer does not support UTF-8 encoding");
+ e.printStackTrace();
+ }
+
+ }
+ public ReadTextFile(String filename) {
+ this.filename = filename;
+ try {
+ FileInputStream inputStream = new FileInputStream(filename);
+ bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ System.err.println("Computer does not support UTF-8 encoding");
+ e.printStackTrace();
+ }
+ }
+
+
+ public Iterator getIterator() {
+ return iterator();
+ }
+
+ public List loadFromFileInBatches(Integer batchsize) {
+ List result = new ArrayList();
+ if (!EOF) {
+ try {
+ int i = 0;
+ while (!EOF && i++ < batchsize) {
+ String nextLine = bufferedReader.readLine();
+ if (nextLine == null)
+ EOF = true;
+ else
+ result.add(nextLine);
+ }
+ if (EOF) {
+ bufferedReader.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return result;
+ }
+
+ private class TextFileIterator implements Iterator {
+ private String buffer;
+
+ public TextFileIterator() {
+ try {
+ buffer = bufferedReader.readLine();
+ if(buffer == null) {
+ EOF = true;
+ bufferedReader.close();
+ }
+ }
+ catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public boolean hasNext() {
+ return !EOF;
+ }
+
+ public String next() {
+ String result = buffer;
+ try {
+ buffer = bufferedReader.readLine();
+ if(buffer == null) {
+ EOF = true;
+ bufferedReader.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ return result;
+ }
+
+ public void remove() {
+ // not implemented
+ }
+
+ }
+
+ public Iterator iterator() {
+ return new TextFileIterator();
+ }
+}
diff --git a/src/org/ohdsi/utilities/files/Row.java b/src/org/ohdsi/utilities/files/Row.java
new file mode 100644
index 00000000..7d3a0d81
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/Row.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.ohdsi.utilities.StringUtilities;
+
+public class Row {
+ private List cells;
+ private Map fieldName2ColumnIndex;
+
+ public Row() {
+ fieldName2ColumnIndex = new HashMap();
+ cells = new ArrayList();
+ }
+
+ public Row(List cells, Map fieldName2ColumnIndex) {
+ this.cells = cells;
+ this.fieldName2ColumnIndex = fieldName2ColumnIndex;
+ }
+
+ public Row(Row row) {
+ cells = new ArrayList(row.cells);
+ fieldName2ColumnIndex = new HashMap(row.fieldName2ColumnIndex);
+ }
+
+ public String get(String fieldName) {
+ int index;
+ try {
+ index = fieldName2ColumnIndex.get(fieldName);
+ } catch (NullPointerException e) {
+ throw new RuntimeException("Field \"" + fieldName + "\" not found");
+ }
+ if (cells.size() <= index)
+ return null;
+ else
+ return cells.get(index);
+ }
+
+ public List getFieldNames() {
+ List names = new ArrayList(fieldName2ColumnIndex.size());
+ for (int i = 0; i < fieldName2ColumnIndex.size(); i++)
+ names.add(null);
+ for (Map.Entry entry : fieldName2ColumnIndex.entrySet())
+ names.set(entry.getValue(), entry.getKey());
+ return names;
+ }
+
+ public int getInt(String fieldName) {
+ return Integer.parseInt(get(fieldName).trim());
+ }
+
+ public long getLong(String fieldName) {
+ return Long.parseLong(get(fieldName));
+ }
+
+ public double getDouble(String fieldName) {
+ return Double.parseDouble(get(fieldName));
+ }
+
+ public void add(String fieldName, String value) {
+ fieldName2ColumnIndex.put(fieldName, cells.size());
+ cells.add(value);
+ }
+
+ public void add(String fieldName, int value) {
+ add(fieldName, Integer.toString(value));
+ }
+
+ public void add(String fieldName, boolean value) {
+ add(fieldName, Boolean.toString(value));
+ }
+
+ public void add(String fieldName, double value) {
+ add(fieldName, Double.toString(value));
+ }
+
+ public void add(String fieldName, long value) {
+ add(fieldName, Long.toString(value));
+ }
+
+ public void set(String fieldName, String value) {
+ cells.set(fieldName2ColumnIndex.get(fieldName), value);
+ }
+
+ public void set(String fieldName, int value) {
+ set(fieldName, Integer.toString(value));
+ }
+
+ public void set(String fieldName, long value) {
+ set(fieldName, Long.toString(value));
+ }
+
+ public void set(String fieldName, double value) {
+ set(fieldName, Double.toString(value));
+ }
+
+ public List getCells() {
+ return cells;
+ }
+
+ protected Map getfieldName2ColumnIndex() {
+ return fieldName2ColumnIndex;
+ }
+
+ public String toString() {
+ List data = new ArrayList(cells);
+ for (String fieldName : fieldName2ColumnIndex.keySet()) {
+ int index = fieldName2ColumnIndex.get(fieldName);
+ if (data.size() > index)
+ data.set(index, "[" + fieldName + ": " + data.get(index) + "]");
+ }
+ return StringUtilities.join(data, ",");
+ }
+
+ public void remove(String field) {
+ Integer index = fieldName2ColumnIndex.remove(field);
+ cells.remove(index);
+ Map tempMap = new HashMap();
+ for (Map.Entry entry : fieldName2ColumnIndex.entrySet())
+ if (entry.getValue() > index)
+ tempMap.put(entry.getKey(), entry.getValue() - 1);
+ else
+ tempMap.put(entry.getKey(), entry.getValue());
+ }
+}
diff --git a/src/org/ohdsi/utilities/files/RowUtilities.java b/src/org/ohdsi/utilities/files/RowUtilities.java
new file mode 100644
index 00000000..7bad6051
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/RowUtilities.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+public class RowUtilities {
+ public static void sort(List rows, String... fieldName) {
+ if (rows.size() < 2)
+ return;
+ int[] indexes = new int[fieldName.length];
+ for (int i = 0; i < fieldName.length; i++) {
+ Integer index = rows.get(0).getfieldName2ColumnIndex().get(fieldName[i]);
+ if (index == null)
+ throw new RuntimeException("Column '" + fieldName[i] + "' not found");
+ indexes[i] = index;
+ }
+ Collections.sort(rows, new RowComparator(indexes));
+ }
+
+ private static class RowComparator implements Comparator {
+ private int[] indexes;
+ private StringIdComparator stringIdComparator = new StringIdComparator();
+
+ public RowComparator(int[] indexes) {
+ this.indexes = indexes;
+ }
+
+ public int compare(Row o1, Row o2) {
+ int result = 0;
+ int i = 0;
+ while (result == 0 && i < indexes.length) {
+ String value1 = o1.getCells().get(indexes[i]);
+ String value2 = o2.getCells().get(indexes[i]);
+ result = stringIdComparator.compare(value1, value2);
+ i++;
+ }
+ return result;
+ }
+
+ }
+}
diff --git a/src/org/ohdsi/utilities/files/StringIdComparator.java b/src/org/ohdsi/utilities/files/StringIdComparator.java
new file mode 100644
index 00000000..6e0a6e70
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/StringIdComparator.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.util.Comparator;
+
+/**
+ * Comparator for strings. If both strings are numbers, they are compared as numbers, else as strings
+ * @author MSCHUEMI
+ *
+ */
+public class StringIdComparator implements Comparator {
+
+ @Override
+ public int compare(String value1, String value2) {
+ if (isNumber(value1)) {
+ if (isNumber(value2))
+ return efficientLongCompare(value1, value2);
+ else
+ return 1;
+ } else {
+ if (isNumber(value2))
+ return -1;
+ else
+ return value1.compareTo(value2);
+ }
+ }
+
+ private int efficientLongCompare(String value1, String value2) {
+ if (value1.length() > value2.length())
+ return 1;
+ else if (value1.length() < value2.length())
+ return -1;
+ else
+ return value1.compareTo(value2);
+ }
+
+ private boolean isNumber(String string) {
+ if (string.length() == 0)
+ return false;
+ for (int i = 0; i < string.length(); i++)
+ if (!Character.isDigit(string.charAt(i)))
+ return false;
+ return true;
+ }
+
+}
diff --git a/src/org/ohdsi/utilities/files/WriteCSVFile.java b/src/org/ohdsi/utilities/files/WriteCSVFile.java
new file mode 100644
index 00000000..081d2b0e
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/WriteCSVFile.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.io.BufferedWriter;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.List;
+
+public class WriteCSVFile {
+
+ public WriteCSVFile(String filename, boolean append) {
+ FileOutputStream stream;
+ try {
+ stream = new FileOutputStream(filename, append);
+ bufferedWrite = new BufferedWriter(new OutputStreamWriter(stream, "UTF-8"), 10000);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ public WriteCSVFile(String filename) {
+ this(filename, false);
+ }
+
+ public void write(List string) {
+ try {
+ bufferedWrite.write(columns2line(string));
+ bufferedWrite.newLine();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static String columns2line(List columns) {
+ StringBuilder sb = new StringBuilder();
+ Iterator iterator = columns.iterator();
+ while (iterator.hasNext()) {
+ String column = iterator.next();
+ column = column.replaceAll("\"", "\\\"");
+ column = column.replaceAll("\n", "\\n");
+ if (column.contains(","))
+ column = "\"" + column + "\"";
+ sb.append(column);
+ if (iterator.hasNext())
+ sb.append(",");
+ }
+ return sb.toString();
+ }
+
+ public void flush() {
+ try {
+ bufferedWrite.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void close() {
+ try {
+ bufferedWrite.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private BufferedWriter bufferedWrite;
+}
diff --git a/src/org/ohdsi/utilities/files/WriteCSVFileWithHeader.java b/src/org/ohdsi/utilities/files/WriteCSVFileWithHeader.java
new file mode 100644
index 00000000..2f1bcf92
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/WriteCSVFileWithHeader.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class WriteCSVFileWithHeader {
+
+ private WriteCSVFile out;
+ private boolean headerWritten;
+ private boolean threadSafe = false;
+ private ReentrantLock lock;
+
+ public WriteCSVFileWithHeader(String filename) {
+ out = new WriteCSVFile(filename);
+ headerWritten = false;
+ }
+
+ public WriteCSVFileWithHeader(String filename, boolean append) {
+ out = new WriteCSVFile(filename, append);
+ headerWritten = true;
+ }
+
+ public void write(Row row) {
+ if (threadSafe)
+ lock.lock();
+ if (!headerWritten)
+ writeHeader(row);
+ out.write(row.getCells());
+ if (threadSafe)
+ lock.unlock();
+ }
+
+ public void close() {
+ out.close();
+ }
+
+ public void flush() {
+ if (threadSafe)
+ lock.lock();
+ out.flush();
+ if (threadSafe)
+ lock.unlock();
+ }
+
+ public void setThreadSafe(boolean value) {
+ threadSafe = value;
+ if (threadSafe)
+ lock = new ReentrantLock();
+ }
+
+ public boolean getThreadSafe() {
+ return threadSafe;
+ }
+
+ private void writeHeader(Row row) {
+ headerWritten = true;
+ Map fieldName2ColumnIndex = row.getfieldName2ColumnIndex();
+ int size = fieldName2ColumnIndex.size();
+ List header = new ArrayList(size);
+ for (int i = 0; i < size; i++)
+ header.add(null);
+ for (Map.Entry entry : fieldName2ColumnIndex.entrySet())
+ header.set(entry.getValue(), entry.getKey());
+ out.write(header);
+ }
+}
diff --git a/src/org/ohdsi/utilities/files/WriteTextFile.java b/src/org/ohdsi/utilities/files/WriteTextFile.java
new file mode 100644
index 00000000..fe2a1709
--- /dev/null
+++ b/src/org/ohdsi/utilities/files/WriteTextFile.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.utilities.files;
+
+import java.io.BufferedWriter;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+
+public class WriteTextFile {
+
+ public WriteTextFile(String filename){
+ FileOutputStream stream;
+ try {
+ stream = new FileOutputStream(filename);
+ bufferedWrite = new BufferedWriter( new OutputStreamWriter(stream, "UTF-8"),10000);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ System.err.println("Computer does not support UTF-8 encoding");
+ e.printStackTrace();
+ }
+ }
+
+ public void writeln(String string){
+ try {
+ bufferedWrite.write(string);
+ bufferedWrite.newLine();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void writeln(int integer){
+ writeln(Integer.toString(integer));
+ }
+
+ public void writeln(Object object){
+ writeln(object.toString());
+ }
+
+ public void flush(){
+ try {
+ bufferedWrite.flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void close() {
+ try {
+ bufferedWrite.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private BufferedWriter bufferedWrite;
+}
diff --git a/src/org/ohdsi/whiteRabbit/Console.java b/src/org/ohdsi/whiteRabbit/Console.java
new file mode 100644
index 00000000..75518bba
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/Console.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.swing.JTextArea;
+import javax.swing.text.BadLocationException;
+
+import org.ohdsi.utilities.files.WriteTextFile;
+
+public class Console extends OutputStream {
+
+ private StringBuffer buffer = new StringBuffer();
+ private WriteTextFile debug = null;
+ private JTextArea textArea;
+
+ public void println(String string) {
+ textArea.append(string + "\n");
+ textArea.repaint();
+ System.out.println(string);
+ }
+
+ public void setTextArea(JTextArea textArea) {
+ this.textArea = textArea;
+ }
+
+ public void setDebugFile(String filename) {
+ debug = new WriteTextFile(filename);
+ }
+
+ public String getText() {
+ try {
+ return textArea.getDocument().getText(0, textArea.getDocument().getLength());
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ buffer.append((char) b);
+ if ((char) b == '\n') {
+ if (textArea != null) {
+ textArea.append(buffer.toString());
+ textArea.setCaretPosition(textArea.getDocument().getLength());
+ }
+ if (debug != null) {
+ debug.writeln(buffer.toString());
+ debug.flush();
+ }
+ buffer = new StringBuffer();
+ }
+ }
+
+}
diff --git a/src/org/ohdsi/whiteRabbit/DbSettings.java b/src/org/ohdsi/whiteRabbit/DbSettings.java
new file mode 100644
index 00000000..95113ab2
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/DbSettings.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.ohdsi.databases.DbType;
+
+public class DbSettings {
+ public static int DATABASE = 1;
+ public static int CSVFILES = 2;
+
+ public int dataType;
+ public List tables = new ArrayList();
+
+ // Database settings
+ public DbType dbType;
+ public String user;
+ public String password;
+ public String database;
+ public String server;
+ public String domain;
+
+ // CSV file settings
+ public char delimiter = ',';
+}
diff --git a/src/org/ohdsi/whiteRabbit/ErrorReport.java b/src/org/ohdsi/whiteRabbit/ErrorReport.java
new file mode 100644
index 00000000..f8004ad1
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/ErrorReport.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit;
+
+import java.io.File;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.utilities.files.WriteTextFile;
+
+public class ErrorReport {
+ public static String generate(String folder, Exception e) {
+ String filename = folder + "/Error.txt";
+ int i = 1;
+ while (new File(filename).exists())
+ filename = folder + "/Error" + (i++) + ".txt";
+ DecimalFormat df = new DecimalFormat();
+ DecimalFormatSymbols dfs = new DecimalFormatSymbols();
+ dfs.setGroupingSeparator(',');
+ df.setDecimalFormatSymbols(dfs);
+
+ WriteTextFile out = new WriteTextFile(filename);
+
+ out.writeln("*** Generic error information ***");
+ out.writeln("Message: " + e.getMessage());
+ out.writeln("Time: " + StringUtilities.now());
+ Runtime runTime = Runtime.getRuntime();
+ out.writeln("Processor type: " + System.getProperty("sun.cpu.isalist"));
+ out.writeln("Available processors: " + runTime.availableProcessors());
+ out.writeln("Maximum available memory: " + df.format(runTime.maxMemory()) + " bytes");
+ out.writeln("Used memory: " + df.format(runTime.totalMemory() - runTime.freeMemory()) + " bytes");
+ out.writeln("Java version: " + System.getProperty("java.version"));
+ out.writeln("Java vendor: " + System.getProperty("java.vendor"));
+ out.writeln("OS architecture: " + System.getProperty("os.arch"));
+ out.writeln("OS name: " + System.getProperty("os.name"));
+ out.writeln("OS version: " + System.getProperty("os.version"));
+ out.writeln("OS patch level: " + System.getProperty("sun.os.patch.level"));
+ out.writeln("");
+ out.writeln("*** Stack trace ***");
+ for (StackTraceElement element : e.getStackTrace())
+ out.writeln(element.toString());
+ out.writeln("");
+ out.writeln("*** Console ***");
+ out.writeln(ObjectExchange.console.getText());
+ out.writeln("");
+ out.writeln("*** Working folder contents ***");
+ out.writeln("Directory of " + folder);
+ out.writeln("");
+ SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy hh:mm:ss");
+ File[] files = new File(folder).listFiles();
+ Arrays.sort(files, new Comparator() {
+ @Override
+ public int compare(File o1, File o2) {
+ return Long.valueOf(o1.lastModified()).compareTo(o2.lastModified());
+ }
+ });
+
+ for (File file : files) {
+ String name = file.getName();
+ String length = df.format(file.length());
+ String dir = file.isDirectory() ? "" : " ";
+ String modifiedDate = sdf.format(new Date(file.lastModified()));
+ StringBuilder filler = new StringBuilder();
+ for (int x = 0; x < (80 - name.length() - length.length()); x++)
+ filler.append(' ');
+ out.writeln(name + filler.toString() + length + " " + dir + " " + modifiedDate);
+ }
+ out.writeln("");
+ out.writeln("Available disc space: " + df.format(new File(folder).getFreeSpace()) + " bytes");
+ out.close();
+ return filename;
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/EtlReport.java b/src/org/ohdsi/whiteRabbit/EtlReport.java
new file mode 100644
index 00000000..e3ce076b
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/EtlReport.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.utilities.collections.CountingSet;
+import org.ohdsi.utilities.collections.CountingSet.Count;
+import org.ohdsi.utilities.collections.IntegerComparator;
+import org.ohdsi.utilities.collections.OneToManyList;
+import org.ohdsi.utilities.files.MultiRowIterator.MultiRowSet;
+import org.ohdsi.whiteRabbit.utilities.CodeToConceptMap;
+import org.ohdsi.whiteRabbit.utilities.CodeToConceptMap.CodeData;
+
+public class EtlReport {
+
+ public static long MAX_REPORT_PROBLEM = 1000;
+
+ private Map problems = new HashMap();
+ private CountingSet incomingTableRowCounts = new CountingSet();
+ private CountingSet outgoingTableRowCounts = new CountingSet();
+ private String folder;
+ private long totalProblemCount = 0;
+
+ public EtlReport(String folder) {
+ this.folder = folder;
+ }
+
+ public void reportProblem(String table, String problemType, String personId) {
+ totalProblemCount++;
+ Problem problem = problems.get(table + "\t" + problemType);
+ if (problem == null) {
+ problem = new Problem();
+ problem.problemType = problemType;
+ problem.table = table;
+ problems.put(table + "\t" + problemType, problem);
+ }
+ problem.count++;
+ if (problem.count < MAX_REPORT_PROBLEM)
+ problem.personId.add(personId);
+ if (problem.count == MAX_REPORT_PROBLEM)
+ System.out.println("Warning: encountered " + MAX_REPORT_PROBLEM + " problems of type '" + problemType + "' in table " + table);
+ }
+
+ public long getTotalProblemCount() {
+ return totalProblemCount;
+ }
+
+ public String generateProblemList() {
+ StringUtilities.outputWithTime("Generating ETL problem list");
+ String filename = generateETLProblemListFilename(folder);
+ XSSFWorkbook workbook = new XSSFWorkbook();
+
+ XSSFSheet sheet = workbook.createSheet("Problems");
+ addRow(sheet, "Table", "Problem", "Person_id");
+ for (Problem problem : problems.values()) {
+ for (int i = 0; i < Math.min(MAX_REPORT_PROBLEM, problem.count); i++)
+ addRow(sheet, problem.table, problem.problemType, problem.personId.get(i));
+ if (problem.count > MAX_REPORT_PROBLEM)
+ addRow(sheet, problem.table, problem.problemType, "in " + (problem.count - MAX_REPORT_PROBLEM) + " other persons");
+ }
+ try {
+ FileOutputStream out = new FileOutputStream(new File(filename));
+ workbook.write(out);
+ out.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+ return filename;
+ }
+
+ public String generate(CodeToConceptMap... codeToConceptMaps) {
+ StringUtilities.outputWithTime("Generating ETL report");
+ String filename = generateFilename(folder);
+ XSSFWorkbook workbook = new XSSFWorkbook();
+
+ XSSFSheet sheet = workbook.createSheet("Overview");
+ addRow(sheet, "Source tables");
+ addRow(sheet, "");
+ addRow(sheet, "Table name", "Number of records");
+ for (String table : incomingTableRowCounts)
+ addRow(sheet, table, Integer.valueOf(incomingTableRowCounts.getCount(table)));
+ addRow(sheet, "");
+
+ addRow(sheet, "CDM tables");
+ addRow(sheet, "");
+ addRow(sheet, "Table name", "Number of records");
+ for (String table : outgoingTableRowCounts)
+ addRow(sheet, table, Integer.valueOf(outgoingTableRowCounts.getCount(table)));
+ addRow(sheet, "");
+
+ addRow(sheet, "Number of problems encountered", Long.valueOf(totalProblemCount));
+ addRow(sheet, "");
+ addRow(sheet, "Mapping", "Mapped unique codes", "Unmapped unique codes", "Mapped total codes", "Unmapped total codes");
+ for (CodeToConceptMap codeToConceptMap : codeToConceptMaps) {
+ int uniqueMapped = 0;
+ int uniqueUnmapped = 0;
+ long totalMapped = 0;
+ long totalUnmapped = 0;
+ CountingSet codeCounts = codeToConceptMap.getCodeCounts();
+ for (String code : codeCounts) {
+ if (!codeToConceptMap.getConceptId(code).equals(0)) {
+ uniqueMapped++;
+ totalMapped += codeCounts.getCount(code);
+ } else {
+ uniqueUnmapped++;
+ totalUnmapped += codeCounts.getCount(code);
+ }
+ }
+ addRow(sheet, codeToConceptMap.getName(), Integer.valueOf(uniqueMapped), Integer.valueOf(uniqueUnmapped), Long.valueOf(totalMapped),
+ Long.valueOf(totalUnmapped));
+ }
+
+ sheet = workbook.createSheet("Problems");
+ addRow(sheet, "Table", "Description", "Nr of rows");
+ for (Problem problem : problems.values())
+ addRow(sheet, problem.table, problem.problemType, Long.valueOf(problem.count));
+
+ for (CodeToConceptMap codeToConceptMap : codeToConceptMaps) {
+ sheet = workbook.createSheet(codeToConceptMap.getName());
+ addRow(sheet, "Frequency", "Source code", "Source code description", "Target concept ID", "Target code", "Target concept description");
+ CountingSet codeCounts = codeToConceptMap.getCodeCounts();
+ List> codes = new ArrayList>(codeCounts.key2count.entrySet());
+ reverseFrequencySort(codes);
+ for (Map.Entry code : codes) {
+ CodeData codeData = codeToConceptMap.getCodeData(code.getKey());
+ if (codeData == null)
+ addRow(sheet, Integer.valueOf(code.getValue().count), code.getKey(), "", Integer.valueOf(0), "", "");
+ else
+ for (int i = 0; i < codeData.targetConceptIds.length; i++)
+ addRow(sheet, Integer.valueOf(code.getValue().count), code.getKey(), codeData.description,
+ Integer.valueOf(codeData.targetConceptIds[i]), codeData.targetCodes[i], codeData.targetDescriptions[i]);
+ }
+ }
+
+ try {
+ FileOutputStream out = new FileOutputStream(new File(filename));
+ workbook.write(out);
+ out.close();
+ } catch (IOException e) {
+ throw new RuntimeException(e.getMessage());
+ }
+
+ return filename;
+ }
+
+ private void reverseFrequencySort(List> codes) {
+ Collections.sort(codes, new Comparator>() {
+
+ @Override
+ public int compare(Entry o1, Entry o2) {
+ return -IntegerComparator.compare(o1.getValue().count, o2.getValue().count);
+ }
+ });
+
+ }
+
+ private void addRow(XSSFSheet sheet, Object... values) {
+ Row row = sheet.createRow(sheet.getPhysicalNumberOfRows());
+ for (Object value : values) {
+ Cell cell = row.createCell(row.getPhysicalNumberOfCells());
+
+ if (value instanceof Integer && value instanceof Long && value instanceof Double)
+ cell.setCellValue(Double.valueOf(value.toString()));
+ else
+ cell.setCellValue(value.toString());
+
+ }
+ }
+
+ private String generateFilename(String folder) {
+ String filename = folder + "/ETLReport.xlsx";
+ int i = 1;
+ while (new File(filename).exists())
+ filename = folder + "/ETLReport" + (i++) + ".xlsx";
+ return filename;
+ }
+
+ private String generateETLProblemListFilename(String folder) {
+ String filename = folder + "/ETLProblems.xlsx";
+ int i = 1;
+ while (new File(filename).exists())
+ filename = folder + "/ETLPRoblems" + (i++) + ".xlsx";
+ return filename;
+ }
+
+ public void registerIncomingData(String table, org.ohdsi.utilities.files.Row row) {
+ incomingTableRowCounts.add(table, 1);
+ }
+
+ public void registerIncomingData(MultiRowSet data) {
+ for (String table : data.keySet())
+ incomingTableRowCounts.add(table, data.get(table).size());
+ }
+
+ public void registerOutgoingData(OneToManyList data) {
+ for (String table : data.keySet())
+ outgoingTableRowCounts.add(table, data.get(table).size());
+ }
+
+ private class Problem {
+ public String table;
+ public String problemType;
+ public long count = 0;
+ public List personId = new ArrayList();
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/ObjectExchange.java b/src/org/ohdsi/whiteRabbit/ObjectExchange.java
new file mode 100644
index 00000000..612d6e24
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/ObjectExchange.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit;
+
+import javax.swing.JFrame;
+
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.ETL;
+
+public class ObjectExchange {
+ public static JFrame frame;
+ public static Console console;
+ public static ETL etl;
+}
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbit.ico b/src/org/ohdsi/whiteRabbit/WhiteRabbit.ico
new file mode 100644
index 00000000..fd0a1949
Binary files /dev/null and b/src/org/ohdsi/whiteRabbit/WhiteRabbit.ico differ
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbit128.png b/src/org/ohdsi/whiteRabbit/WhiteRabbit128.png
new file mode 100644
index 00000000..1c4b6fa5
Binary files /dev/null and b/src/org/ohdsi/whiteRabbit/WhiteRabbit128.png differ
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbit16.png b/src/org/ohdsi/whiteRabbit/WhiteRabbit16.png
new file mode 100644
index 00000000..60bb7cfc
Binary files /dev/null and b/src/org/ohdsi/whiteRabbit/WhiteRabbit16.png differ
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbit256.png b/src/org/ohdsi/whiteRabbit/WhiteRabbit256.png
new file mode 100644
index 00000000..708e5d0a
Binary files /dev/null and b/src/org/ohdsi/whiteRabbit/WhiteRabbit256.png differ
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbit32.png b/src/org/ohdsi/whiteRabbit/WhiteRabbit32.png
new file mode 100644
index 00000000..2c1e62f4
Binary files /dev/null and b/src/org/ohdsi/whiteRabbit/WhiteRabbit32.png differ
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbit48.png b/src/org/ohdsi/whiteRabbit/WhiteRabbit48.png
new file mode 100644
index 00000000..4329065d
Binary files /dev/null and b/src/org/ohdsi/whiteRabbit/WhiteRabbit48.png differ
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbit64.png b/src/org/ohdsi/whiteRabbit/WhiteRabbit64.png
new file mode 100644
index 00000000..830d066e
Binary files /dev/null and b/src/org/ohdsi/whiteRabbit/WhiteRabbit64.png differ
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbitMain.java b/src/org/ohdsi/whiteRabbit/WhiteRabbitMain.java
new file mode 100644
index 00000000..8b12c963
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/WhiteRabbitMain.java
@@ -0,0 +1,955 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.GridLayout;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.File;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.border.TitledBorder;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.ohdsi.databases.DbType;
+import org.ohdsi.databases.RichConnection;
+import org.ohdsi.utilities.DirectoryUtilities;
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.whiteRabbit.etls.ars.ARSETL;
+import org.ohdsi.whiteRabbit.etls.hcup.HCUPETL;
+import org.ohdsi.whiteRabbit.scan.SourceDataScan;
+import org.ohdsi.whiteRabbit.utilities.SqlDump;
+import org.ohdsi.whiteRabbit.vocabulary.InsertVocabularyInServer;
+
+public class WhiteRabbitMain {
+
+ private JFrame frame;
+ private JTextField folderField;
+ private JTextField vocabFileField;
+
+ private JComboBox etlType;
+ private JComboBox sourceType;
+ private JComboBox targetType;
+ private JTextField targetUserField;
+ private JTextField targetPasswordField;
+ private JTextField targetServerField;
+ private JTextField targetDatabaseField;
+ private JTextField sourceDelimiterField;
+ private JTextField sourceServerField;
+ private JTextField sourceUserField;
+ private JTextField sourcePasswordField;
+ private JTextField sourceDatabaseField;
+ private JButton addAllButton;
+ private JList tableList;
+ private List tables = new ArrayList();
+ private JTextArea sqlArea;
+ private JTextField sqlDumpFilenameField;
+ private JButton dumpButton;
+ private boolean sourceIsFiles = true;
+
+ private List componentsToDisableWhenRunning = new ArrayList();
+
+ public static void main(String[] args) {
+ new WhiteRabbitMain(args);
+ }
+
+ public WhiteRabbitMain(String[] args) {
+ frame = new JFrame("White Rabbit");
+
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ System.exit(0);
+ }
+ });
+ frame.setLayout(new BorderLayout());
+
+ JComponent tabsPanel = createTabsPanel();
+ JComponent consolePanel = createConsolePanel();
+
+ frame.add(consolePanel, BorderLayout.CENTER);
+ frame.add(tabsPanel, BorderLayout.NORTH);
+
+ loadIcons(frame);
+ frame.pack();
+ frame.setVisible(true);
+ ObjectExchange.frame = frame;
+ executeParameters(args);
+ }
+
+ private JComponent createTabsPanel() {
+ JTabbedPane tabbedPane = new JTabbedPane();
+
+ JPanel locationPanel = createLocationsPanel();
+ tabbedPane.addTab("Locations", null, locationPanel, "Specify the location of the source data, the CDM, and the working folder");
+
+ JPanel dumpPanel = createSqlDumpPanel();
+ tabbedPane.addTab("Bulk SQL dump", null, dumpPanel, "Write the results of a SQL query to a CSV file");
+
+ JPanel scanPanel = createScanPanel();
+ tabbedPane.addTab("Scan", null, scanPanel, "Create a scan of the source data");
+
+ JPanel vocabPanel = createVocabPanel();
+ tabbedPane.addTab("Vocabulary", null, vocabPanel, "Upload the vocabulary to the server");
+
+ JPanel etlPanel = createEtlPanel();
+ tabbedPane.addTab("ETL", null, etlPanel, "Extract, Transform and Load the data into the OMOP CDM");
+
+ return tabbedPane;
+ }
+
+ private JPanel createLocationsPanel() {
+ JPanel panel = new JPanel();
+
+ panel.setLayout(new GridBagLayout());
+ GridBagConstraints c = new GridBagConstraints();
+ c.fill = GridBagConstraints.BOTH;
+ c.weightx = 0.5;
+
+ JPanel folderPanel = new JPanel();
+ folderPanel.setLayout(new BoxLayout(folderPanel, BoxLayout.X_AXIS));
+ folderPanel.setBorder(BorderFactory.createTitledBorder("Working folder"));
+ folderField = new JTextField();
+ folderField.setText((new File("").getAbsolutePath()));
+ folderField.setToolTipText("The folder where all output will be written");
+ folderPanel.add(folderField);
+ JButton pickButton = new JButton("Pick folder");
+ pickButton.setToolTipText("Pick a different working folder");
+ folderPanel.add(pickButton);
+ pickButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ pickFile();
+ }
+ });
+ componentsToDisableWhenRunning.add(pickButton);
+ c.gridx = 0;
+ c.gridy = 0;
+ c.gridwidth = 2;
+ panel.add(folderPanel, c);
+
+ JPanel sourcePanel = new JPanel();
+ sourcePanel.setLayout(new GridLayout(0, 2));
+ sourcePanel.setBorder(BorderFactory.createTitledBorder("Source data location"));
+ sourcePanel.add(new JLabel("Data type"));
+ sourceType = new JComboBox(new String[] { "Delimited text files", "MySQL", "Oracle", "SQL Server", "PostgreSQL" });
+ sourceType.setToolTipText("Select the type of source data available");
+ sourceType.addItemListener(new ItemListener() {
+
+ @Override
+ public void itemStateChanged(ItemEvent arg0) {
+ sourceIsFiles = arg0.getItem().toString().equals("Delimited text files");
+ sourceServerField.setEnabled(!sourceIsFiles);
+ sourceUserField.setEnabled(!sourceIsFiles);
+ sourcePasswordField.setEnabled(!sourceIsFiles);
+ sourceDatabaseField.setEnabled(!sourceIsFiles);
+ sourceDelimiterField.setEnabled(sourceIsFiles);
+ addAllButton.setEnabled(!sourceIsFiles);
+ dumpButton.setEnabled(!sourceIsFiles);
+
+ if (!sourceIsFiles && arg0.getItem().toString().equals("Oracle")) {
+ sourceServerField
+ .setToolTipText("For Oracle servers this field contains the SID, servicename, and optionally the port: '/', ':/', '/', or ':/'");
+ sourceUserField.setToolTipText("For Oracle servers this field contains the name of the user used to log in");
+ sourcePasswordField.setToolTipText("For Oracle servers this field contains the password corresponding to the user");
+ sourceDatabaseField
+ .setToolTipText("For Oracle servers this field contains the schema (i.e. 'user' in Oracle terms) containing the source tables");
+ } else if (!sourceIsFiles && arg0.getItem().toString().equals("PostgreSQL")) {
+ sourceServerField.setToolTipText("For PostgreSQL servers this field contains the host name and database name (/)");
+ sourceUserField.setToolTipText("The user used to log in to the server");
+ sourcePasswordField.setToolTipText("The password used to log in to the server");
+ sourceDatabaseField.setToolTipText("For PostgreSQL servers this field contains the schema containing the source tables");
+ } else if (!sourceIsFiles) {
+ sourceServerField.setToolTipText("This field contains the name or IP address of the database server");
+ if (arg0.getItem().toString().equals("SQL Server"))
+ sourceUserField
+ .setToolTipText("The user used to log in to the server. Optionally, the domain can be specified as / (e.g. 'MyDomain/Joe')");
+ else
+ sourceUserField.setToolTipText("The user used to log in to the server");
+ sourcePasswordField.setToolTipText("The password used to log in to the server");
+ sourceDatabaseField.setToolTipText("The name of the database containing the source tables");
+ }
+ }
+ });
+ sourcePanel.add(sourceType);
+
+ sourcePanel.add(new JLabel("Server location"));
+ sourceServerField = new JTextField("127.0.0.1");
+ sourceServerField.setEnabled(false);
+ sourcePanel.add(sourceServerField);
+ sourcePanel.add(new JLabel("User name"));
+ sourceUserField = new JTextField("");
+ sourceUserField.setEnabled(false);
+ sourcePanel.add(sourceUserField);
+ sourcePanel.add(new JLabel("Password"));
+ sourcePasswordField = new JPasswordField("");
+ sourcePasswordField.setEnabled(false);
+ sourcePanel.add(sourcePasswordField);
+ sourcePanel.add(new JLabel("Database name"));
+ sourceDatabaseField = new JTextField("");
+ sourceDatabaseField.setEnabled(false);
+ sourcePanel.add(sourceDatabaseField);
+
+ sourcePanel.add(new JLabel("Delimiter"));
+ sourceDelimiterField = new JTextField(",");
+ sourceDelimiterField.setToolTipText("The delimiter that separates values. Enter 'tab' for tab.");
+ sourcePanel.add(sourceDelimiterField);
+
+ c.gridx = 0;
+ c.gridy = 1;
+ c.gridwidth = 1;
+ panel.add(sourcePanel, c);
+
+ JPanel targetPanel = new JPanel();
+ targetPanel.setLayout(new GridLayout(0, 2));
+ targetPanel.setBorder(BorderFactory.createTitledBorder("Target data location"));
+ targetPanel.add(new JLabel("Data type"));
+ targetType = new JComboBox(new String[] { "MySQL", "Oracle", "SQL Server", "PostgreSQL" });
+ targetType.setToolTipText("Select the type of server where the CDM and vocabulary will be stored");
+ targetPanel.add(targetType);
+ targetPanel.add(new JLabel("Server location"));
+ targetServerField = new JTextField("127.0.0.1");
+ targetPanel.add(targetServerField);
+ targetPanel.add(new JLabel("User name"));
+ targetUserField = new JTextField("root");
+ targetPanel.add(targetUserField);
+ targetPanel.add(new JLabel("Password"));
+ targetPasswordField = new JPasswordField("");
+ targetPanel.add(targetPasswordField);
+ targetPanel.add(new JLabel("CDM database name"));
+ targetDatabaseField = new JTextField("CDM_v4");
+ targetPanel.add(targetDatabaseField);
+ targetPanel.add(new JLabel(""));
+ targetPanel.add(new JLabel(""));
+
+ c.gridx = 1;
+ c.gridy = 1;
+ c.gridwidth = 1;
+ panel.add(targetPanel, c);
+
+ return panel;
+ }
+
+ private JPanel createSqlDumpPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+
+ JPanel inputPanel = new JPanel();
+ inputPanel.setLayout(new BorderLayout());
+
+ sqlArea = new JTextArea();
+ sqlArea.setToolTipText("Enter the SQL statement to retrieve the date here");
+ JScrollPane sqlPane = new JScrollPane(sqlArea);
+ sqlPane.setBorder(BorderFactory.createTitledBorder("SQL"));
+ sqlPane.setAutoscrolls(true);
+ inputPanel.add(sqlPane, BorderLayout.CENTER);
+
+ sqlDumpFilenameField = new JTextField("Dump.csv");
+ sqlDumpFilenameField.setBorder(BorderFactory.createTitledBorder("Output filename"));
+ sqlDumpFilenameField.setToolTipText("The name of the CSV file where the result of the SQL query will be written");
+ inputPanel.add(sqlDumpFilenameField, BorderLayout.SOUTH);
+
+ panel.add(inputPanel, BorderLayout.CENTER);
+
+ JPanel dumpButtonPanel = new JPanel();
+ dumpButtonPanel.setLayout(new BoxLayout(dumpButtonPanel, BoxLayout.X_AXIS));
+ dumpButtonPanel.add(Box.createHorizontalGlue());
+
+ dumpButton = new JButton("Dump SQL results to file");
+ dumpButton.setBackground(new Color(151, 220, 141));
+ dumpButton.setToolTipText("Execute the SQL statement, and write the output to the file");
+ dumpButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ sqlDumpRun();
+ }
+ });
+ dumpButton.setEnabled(false);
+ componentsToDisableWhenRunning.add(dumpButton);
+ dumpButtonPanel.add(dumpButton);
+ panel.add(dumpButtonPanel, BorderLayout.SOUTH);
+
+ return panel;
+ }
+
+ private JPanel createScanPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+
+ JPanel tablePanel = new JPanel();
+ tablePanel.setLayout(new BorderLayout());
+ tablePanel.setBorder(new TitledBorder("Tables"));
+ tableList = new JList();
+ tableList.setToolTipText("Specify the tables (or CSV files) to be scanned here");
+ tablePanel.add(new JScrollPane(tableList), BorderLayout.CENTER);
+
+ JPanel tableButtonPanel = new JPanel();
+ tableButtonPanel.setLayout(new GridLayout(3, 1));
+ addAllButton = new JButton("Add all in DB");
+ addAllButton.setToolTipText("Add all tables in the database");
+ addAllButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ addAllTables();
+ }
+ });
+ addAllButton.setEnabled(false);
+ tableButtonPanel.add(addAllButton);
+ JButton addButton = new JButton("Add");
+ addButton.setToolTipText("Add tables to list");
+ addButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ pickTables();
+ }
+ });
+ tableButtonPanel.add(addButton);
+ JButton removeButton = new JButton("Remove");
+ removeButton.setToolTipText("Remove tables from list");
+ removeButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ removeTables();
+ }
+ });
+ tableButtonPanel.add(removeButton);
+ tablePanel.add(tableButtonPanel, BorderLayout.EAST);
+
+ panel.add(tablePanel, BorderLayout.CENTER);
+
+ JPanel scanButtonPanel = new JPanel();
+ scanButtonPanel.setLayout(new BoxLayout(scanButtonPanel, BoxLayout.X_AXIS));
+ scanButtonPanel.add(Box.createHorizontalGlue());
+
+ JButton scan100kButton = new JButton("Scan 100k rows per table");
+ scan100kButton.setBackground(new Color(151, 220, 141));
+ scan100kButton.setToolTipText("Perform the scan on a random sample of 100,000 rows per table");
+ scan100kButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ scanRun(100000);
+ }
+ });
+ componentsToDisableWhenRunning.add(scan100kButton);
+ scanButtonPanel.add(scan100kButton);
+
+ JButton scan1mButton = new JButton("Scan 1m rows per table");
+ scan1mButton.setBackground(new Color(151, 220, 141));
+ scan1mButton.setToolTipText("Perform the scan on a random sample of 1 million rows per table");
+ scan1mButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ scanRun(1000000);
+ }
+ });
+ componentsToDisableWhenRunning.add(scan1mButton);
+ scanButtonPanel.add(scan1mButton);
+
+ JButton scanButton = new JButton("Scan full tables");
+ scanButton.setBackground(new Color(151, 220, 141));
+ scanButton.setToolTipText("Perform the scan on the full tables");
+ scanButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ scanRun(-1);
+ }
+ });
+ componentsToDisableWhenRunning.add(scanButton);
+ scanButtonPanel.add(scanButton);
+ panel.add(scanButtonPanel, BorderLayout.SOUTH);
+
+ return panel;
+ }
+
+ private JPanel createVocabPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+
+ JPanel vocabFilePanel = new JPanel();
+ vocabFilePanel.setLayout(new BoxLayout(vocabFilePanel, BoxLayout.X_AXIS));
+ vocabFilePanel.setBorder(BorderFactory.createTitledBorder("Vocabulary data file"));
+
+ vocabFileField = new JTextField();
+ vocabFileField.setText("Vocabulary.dat");
+ vocabFileField.setToolTipText("Specify the name of the file containing the vocabulary here");
+ vocabFilePanel.add(vocabFileField);
+ JButton pickButton = new JButton("Pick file");
+ pickButton.setToolTipText("Select a different vocabulary file");
+ vocabFilePanel.add(pickButton);
+ pickButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ pickVocabFile();
+ }
+ });
+ vocabFilePanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, vocabFilePanel.getPreferredSize().height));
+ panel.add(vocabFilePanel);
+
+ panel.add(Box.createVerticalGlue());
+
+ JPanel vocabButtonPanel = new JPanel();
+ vocabButtonPanel.setLayout(new BoxLayout(vocabButtonPanel, BoxLayout.X_AXIS));
+
+ vocabButtonPanel.add(Box.createHorizontalGlue());
+ JButton vocabButton = new JButton("Insert vocabulary");
+ vocabButton.setBackground(new Color(151, 220, 141));
+ vocabButton.setToolTipText("Insert the vocabulary database into the server");
+ vocabButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ vocabRun();
+ }
+ });
+ componentsToDisableWhenRunning.add(vocabButton);
+ vocabButtonPanel.add(vocabButton);
+
+ panel.add(vocabButtonPanel);
+
+ return panel;
+ }
+
+ private JPanel createEtlPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
+
+ JPanel etlTypePanel = new JPanel();
+ etlTypePanel.setLayout(new BoxLayout(etlTypePanel, BoxLayout.X_AXIS));
+ etlTypePanel.setBorder(BorderFactory.createTitledBorder("ETL type"));
+ etlType = new JComboBox(new String[] { "ARS -> OMOP CDM V4", "HCUP -> OMOP CDM V4" });
+ etlType.setToolTipText("Select the appropriate ETL process");
+ etlTypePanel.add(etlType);
+ etlTypePanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, etlTypePanel.getPreferredSize().height));
+ panel.add(etlTypePanel);
+
+ panel.add(Box.createVerticalGlue());
+
+ JPanel etlButtonPanel = new JPanel();
+ etlButtonPanel.setLayout(new BoxLayout(etlButtonPanel, BoxLayout.X_AXIS));
+ etlButtonPanel.add(Box.createHorizontalGlue());
+
+ JButton etl10kButton = new JButton("Perform 10k persons ETL");
+ etl10kButton.setBackground(new Color(151, 220, 141));
+ etl10kButton.setToolTipText("Perform the ETL for the first 10,000 persons");
+ etl10kButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ etlRun(10000);
+ }
+ });
+ componentsToDisableWhenRunning.add(etl10kButton);
+ etlButtonPanel.add(etl10kButton);
+
+ // etlButtonPanel.add(Box.createHorizontalStrut(10));
+
+ JButton etlButton = new JButton("Perform ETL");
+ etlButton.setBackground(new Color(151, 220, 141));
+ etlButton.setToolTipText("Extract, Transform and Load the data into the OMOP CDM");
+ etlButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ etlRun(Integer.MAX_VALUE);
+ }
+ });
+ componentsToDisableWhenRunning.add(etlButton);
+ etlButtonPanel.add(etlButton);
+ panel.add(etlButtonPanel);
+
+ return panel;
+ }
+
+ private JComponent createConsolePanel() {
+ JTextArea consoleArea = new JTextArea();
+ consoleArea.setToolTipText("General progress information");
+ consoleArea.setEditable(false);
+ Console console = new Console();
+ console.setTextArea(consoleArea);
+ // console.setDebugFile("c:/temp/debug.txt");
+ System.setOut(new PrintStream(console));
+ System.setErr(new PrintStream(console));
+ JScrollPane consoleScrollPane = new JScrollPane(consoleArea);
+ consoleScrollPane.setBorder(BorderFactory.createTitledBorder("Console"));
+ consoleScrollPane.setPreferredSize(new Dimension(800, 200));
+ consoleScrollPane.setAutoscrolls(true);
+ ObjectExchange.console = console;
+ return consoleScrollPane;
+ }
+
+ private void loadIcons(JFrame f) {
+ List icons = new ArrayList();
+ icons.add(loadIcon("WhiteRabbit16.png", f));
+ icons.add(loadIcon("WhiteRabbit32.png", f));
+ icons.add(loadIcon("WhiteRabbit48.png", f));
+ icons.add(loadIcon("WhiteRabbit64.png", f));
+ icons.add(loadIcon("WhiteRabbit128.png", f));
+ icons.add(loadIcon("WhiteRabbit256.png", f));
+ f.setIconImages(icons);
+ }
+
+ private Image loadIcon(String name, JFrame f) {
+ Image icon = Toolkit.getDefaultToolkit().getImage(WhiteRabbitMain.class.getResource(name));
+ MediaTracker mediaTracker = new MediaTracker(f);
+ mediaTracker.addImage(icon, 0);
+ try {
+ mediaTracker.waitForID(0);
+ return icon;
+ } catch (Exception e1) {
+ e1.printStackTrace();
+ }
+ return null;
+ }
+
+ private void executeParameters(String[] args) {
+ String mode = null;
+ for (String arg : args) {
+ if (arg.startsWith("-")) {
+ mode = arg.toLowerCase();
+ } else {
+ if (mode.equals("-folder"))
+ folderField.setText(arg);
+ if (mode.equals("-targetpassword"))
+ targetPasswordField.setText(arg);
+ if (mode.equals("-targetserver"))
+ targetServerField.setText(arg);
+ if (mode.equals("-targettype"))
+ targetType.setSelectedItem(arg);
+ if (mode.equals("-targetdatabase"))
+ targetDatabaseField.setText(arg);
+ if (mode.equals("-targetuser"))
+ targetUserField.setText(arg);
+ if (mode.equals("-sourceserver"))
+ sourceServerField.setText(arg);
+ if (mode.equals("-sourcetype"))
+ sourceType.setSelectedItem(arg);
+ if (mode.equals("-sourcedatabase"))
+ sourceDatabaseField.setText(arg);
+ if (mode.equals("-sourceuser"))
+ sourceUserField.setText(arg);
+ mode = null;
+ }
+ }
+ }
+
+ private void pickFile() {
+ JFileChooser fileChooser = new JFileChooser(new File(folderField.getText()));
+ fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+ int returnVal = fileChooser.showDialog(frame, "Select folder");
+ if (returnVal == JFileChooser.APPROVE_OPTION)
+ folderField.setText(fileChooser.getSelectedFile().getAbsolutePath());
+ }
+
+ private void removeTables() {
+ for (Object item : tableList.getSelectedValues()) {
+ tables.remove(item);
+ tableList.setListData(tables.toArray());
+ }
+ }
+
+ private void addAllTables() {
+ DbSettings sourceDbSettings = getSourceDbSettings();
+ if (sourceDbSettings != null) {
+ RichConnection connection = new RichConnection(sourceDbSettings.server, sourceDbSettings.domain, sourceDbSettings.user, sourceDbSettings.password,
+ sourceDbSettings.dbType);
+ for (String table : connection.getTableNames(sourceDbSettings.database)) {
+ if (!tables.contains(table))
+ tables.add((String) table);
+ tableList.setListData(tables.toArray());
+ }
+ connection.close();
+ }
+ }
+
+ private void pickTables() {
+ DbSettings sourceDbSettings = getSourceDbSettings();
+ if (sourceDbSettings != null) {
+ if (sourceDbSettings.dataType == DbSettings.CSVFILES) {
+ JFileChooser fileChooser = new JFileChooser(new File(folderField.getText()));
+ fileChooser.setMultiSelectionEnabled(true);
+ fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ FileNameExtensionFilter filter = new FileNameExtensionFilter("Delimited text files", "csv", "txt");
+ fileChooser.setFileFilter(filter);
+
+ int returnVal = fileChooser.showDialog(frame, "Select tables");
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ for (File table : fileChooser.getSelectedFiles()) {
+ String tableName = DirectoryUtilities.getRelativePath(new File(folderField.getText()), table);
+ if (!tables.contains(tableName))
+ tables.add(tableName);
+ tableList.setListData(tables.toArray());
+ }
+
+ }
+ } else if (sourceDbSettings.dataType == DbSettings.DATABASE) {
+ RichConnection connection = new RichConnection(sourceDbSettings.server, sourceDbSettings.domain, sourceDbSettings.user,
+ sourceDbSettings.password, sourceDbSettings.dbType);
+ String tableNames = StringUtilities.join(connection.getTableNames(sourceDbSettings.database), "\t");
+ DBTableSelectionDialog selectionDialog = new DBTableSelectionDialog(frame, true, tableNames);
+ if (selectionDialog.getAnswer()) {
+ for (Object item : selectionDialog.getSelectedItems()) {
+ if (!tables.contains(item))
+ tables.add((String) item);
+ tableList.setListData(tables.toArray());
+ }
+ }
+ connection.close();
+ }
+ }
+ }
+
+ private void pickVocabFile() {
+ JFileChooser fileChooser = new JFileChooser(new File(folderField.getText()));
+ fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ int returnVal = fileChooser.showDialog(frame, "Select vocabulary file");
+ if (returnVal == JFileChooser.APPROVE_OPTION)
+ vocabFileField.setText(DirectoryUtilities.getRelativePath(new File(folderField.getText()), fileChooser.getSelectedFile()));
+ }
+
+ private DbSettings getSourceDbSettings() {
+ DbSettings dbSettings = new DbSettings();
+ if (sourceType.getSelectedItem().equals("Delimited text files")) {
+ dbSettings.dataType = DbSettings.CSVFILES;
+ if (sourceDelimiterField.getText().length() == 0) {
+ JOptionPane.showMessageDialog(frame, "Delimiter field cannot be empty for source database", "Error connecting to server",
+ JOptionPane.ERROR_MESSAGE);
+ return null;
+ }
+ if (sourceDelimiterField.getText().toLowerCase().equals("tab"))
+ dbSettings.delimiter = '\t';
+ else
+ dbSettings.delimiter = sourceDelimiterField.getText().charAt(0);
+ } else {
+ dbSettings.dataType = DbSettings.DATABASE;
+ dbSettings.user = sourceUserField.getText();
+ dbSettings.password = sourcePasswordField.getText();
+ dbSettings.server = sourceServerField.getText();
+ dbSettings.database = sourceDatabaseField.getText().trim().length() == 0 ? null : sourceDatabaseField.getText();
+ if (sourceType.getSelectedItem().toString().equals("MySQL"))
+ dbSettings.dbType = DbType.MYSQL;
+ else if (sourceType.getSelectedItem().toString().equals("Oracle"))
+ dbSettings.dbType = DbType.ORACLE;
+ else if (sourceType.getSelectedItem().toString().equals("PostgreSQL"))
+ dbSettings.dbType = DbType.POSTGRESQL;
+ else if (sourceType.getSelectedItem().toString().equals("SQL Server")) {
+ dbSettings.dbType = DbType.MSSQL;
+ if (sourceUserField.getText().length() != 0) { // Not using windows authentication
+ String[] parts = sourceUserField.getText().split("/");
+ if (parts.length < 2) {
+ throw new RuntimeException("For SQL server you need to specify the domain in the user name field (e.g. Mydomain/Joe)");
+ } else {
+ dbSettings.user = parts[1];
+ dbSettings.domain = parts[0];
+ }
+ }
+
+ }
+
+ if (dbSettings.database == null) {
+ String message = "Please specify a name for the source database";
+ JOptionPane.showMessageDialog(frame, StringUtilities.wordWrap(message, 80), "Database error", JOptionPane.ERROR_MESSAGE);
+ return null;
+ }
+
+ }
+ return dbSettings;
+ }
+
+ private void testConnection(DbSettings dbSettings, boolean testConnectionToDb) {
+ RichConnection connection;
+ try {
+ connection = new RichConnection(dbSettings.server, dbSettings.domain, dbSettings.user, dbSettings.password, dbSettings.dbType);
+ } catch (Exception e) {
+ String message = "Could not connect to source server: " + e.getMessage();
+ JOptionPane.showMessageDialog(frame, StringUtilities.wordWrap(message, 80), "Error connecting to server", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+
+ if (testConnectionToDb)
+ try {
+ connection.getTableNames(dbSettings.database);
+ } catch (Exception e) {
+ String message = "Could not connect to database: " + e.getMessage();
+ JOptionPane.showMessageDialog(frame, StringUtilities.wordWrap(message, 80), "Error connecting to server", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+
+ connection.close();
+ }
+
+ private DbSettings getTargetDbSettings() {
+ DbSettings dbSettings = new DbSettings();
+ dbSettings.dataType = DbSettings.DATABASE;
+ dbSettings.user = targetUserField.getText();
+ dbSettings.password = targetPasswordField.getText();
+ dbSettings.server = targetServerField.getText();
+ dbSettings.database = targetDatabaseField.getText();
+ if (targetType.getSelectedItem().toString().equals("MySQL"))
+ dbSettings.dbType = DbType.MYSQL;
+ else if (targetType.getSelectedItem().toString().equals("Oracle"))
+ dbSettings.dbType = DbType.ORACLE;
+ else if (sourceType.getSelectedItem().toString().equals("PostgreSQL"))
+ dbSettings.dbType = DbType.POSTGRESQL;
+ else if (sourceType.getSelectedItem().toString().equals("SQL Server")) {
+ dbSettings.dbType = DbType.MSSQL;
+ if (sourceUserField.getText().length() != 0) { // Not using windows authentication
+ String[] parts = sourceUserField.getText().split("/");
+ if (parts.length < 2) {
+ throw new RuntimeException("For SQL server you need to specify the domain in the user name field (e.g. Mydomain/Joe)");
+ } else {
+ dbSettings.user = parts[1];
+ dbSettings.domain = parts[0];
+ }
+ }
+ }
+
+ if (dbSettings.database.trim().length() == 0) {
+ String message = "Please specify a name for the target database";
+ JOptionPane.showMessageDialog(frame, StringUtilities.wordWrap(message, 80), "Database error", JOptionPane.ERROR_MESSAGE);
+ return null;
+ }
+
+ return dbSettings;
+ }
+
+ private void etlRun(int maxPersons) {
+ EtlThread etlThread = new EtlThread(maxPersons);
+ etlThread.start();
+ }
+
+ private void scanRun(int maxRows) {
+ ScanThread scanThread = new ScanThread(maxRows);
+ scanThread.start();
+ }
+
+ private void sqlDumpRun() {
+ SqlDumpThread sqlDumpThread = new SqlDumpThread();
+ sqlDumpThread.start();
+ }
+
+ private void vocabRun() {
+ VocabRunThread thread = new VocabRunThread();
+ thread.start();
+ }
+
+ private class SqlDumpThread extends Thread {
+
+ public void run() {
+ for (JComponent component : componentsToDisableWhenRunning)
+ component.setEnabled(false);
+ try {
+ DbSettings dbSettings = getSourceDbSettings();
+ testConnection(dbSettings, true);
+ if (dbSettings != null) {
+ SqlDump sqlDump = new SqlDump();
+ sqlDump.process(dbSettings, sqlArea.getText(), folderField.getText() + "/" + sqlDumpFilenameField.getText());
+ }
+
+ } catch (Exception e) {
+ handleError(e);
+ } finally {
+ for (JComponent component : componentsToDisableWhenRunning)
+ component.setEnabled(true);
+ dumpButton.setEnabled(!sourceIsFiles);
+ }
+ }
+
+ }
+
+ private class EtlThread extends Thread {
+
+ private int maxPersons;
+
+ public EtlThread(int maxPersons) {
+ this.maxPersons = maxPersons;
+ }
+
+ public void run() {
+ for (JComponent component : componentsToDisableWhenRunning)
+ component.setEnabled(false);
+
+ try {
+ if (etlType.getSelectedItem().equals("ARS -> OMOP CDM V4")) {
+ ARSETL etl = new ARSETL();
+ DbSettings dbSettings = getTargetDbSettings();
+ testConnection(dbSettings, false);
+ if (dbSettings != null)
+ etl.process(folderField.getText(), dbSettings, maxPersons);
+ }
+ if (etlType.getSelectedItem().equals("HCUP -> OMOP CDM V4")) {
+ HCUPETL etl = new HCUPETL();
+ DbSettings sourceDbSettings = getSourceDbSettings();
+ DbSettings targetDbSettings = getTargetDbSettings();
+ if (sourceDbSettings != null && targetDbSettings != null) {
+ testConnection(sourceDbSettings, true);
+ testConnection(targetDbSettings, false);
+ etl.process(folderField.getText(), sourceDbSettings, targetDbSettings, maxPersons);
+ }
+ }
+
+ } catch (Exception e) {
+ handleError(e);
+ } finally {
+ for (JComponent component : componentsToDisableWhenRunning)
+ component.setEnabled(true);
+ dumpButton.setEnabled(!sourceIsFiles);
+ }
+ }
+
+ }
+
+ private class ScanThread extends Thread {
+
+ private int maxRows;
+
+ public ScanThread(int maxRows) {
+ this.maxRows = maxRows;
+ }
+
+ public void run() {
+ for (JComponent component : componentsToDisableWhenRunning)
+ component.setEnabled(false);
+ try {
+ SourceDataScan sourceDataScan = new SourceDataScan();
+ DbSettings dbSettings = getSourceDbSettings();
+ if (dbSettings != null) {
+ for (String table : tables) {
+ if (dbSettings.dataType == DbSettings.CSVFILES)
+ table = folderField.getText() + "/" + table;
+ dbSettings.tables.add(table);
+ }
+ sourceDataScan.process(dbSettings, maxRows, folderField.getText() + "/ScanReport.xlsx");
+ }
+ } catch (Exception e) {
+ handleError(e);
+ } finally {
+ for (JComponent component : componentsToDisableWhenRunning)
+ component.setEnabled(true);
+ dumpButton.setEnabled(!sourceIsFiles);
+ }
+ }
+
+ }
+
+ private class VocabRunThread extends Thread {
+
+ public void run() {
+ for (JComponent component : componentsToDisableWhenRunning)
+ component.setEnabled(false);
+ try {
+ InsertVocabularyInServer process = new InsertVocabularyInServer();
+ DbSettings dbSettings = getTargetDbSettings();
+ if (dbSettings != null)
+ process.process(folderField.getText() + "/" + vocabFileField.getText(), dbSettings);
+ } catch (Exception e) {
+ handleError(e);
+ } finally {
+ for (JComponent component : componentsToDisableWhenRunning)
+ component.setEnabled(true);
+ dumpButton.setEnabled(!sourceIsFiles);
+ }
+
+ }
+ }
+
+ private class DBTableSelectionDialog extends JDialog implements ActionListener {
+ private static final long serialVersionUID = 4527207331482143091L;
+ private JButton yesButton = null;
+ private JButton noButton = null;
+ private boolean answer = false;
+ private JList list;
+
+ public boolean getAnswer() {
+ return answer;
+ }
+
+ public DBTableSelectionDialog(JFrame frame, boolean modal, String tableNames) {
+ super(frame, modal);
+
+ setTitle("Select tables");
+ JPanel panel = new JPanel();
+ panel.setPreferredSize(new Dimension(800, 500));
+ getContentPane().add(panel);
+ panel.setLayout(new BorderLayout());
+
+ JLabel message = new JLabel("Select tables");
+ panel.add(message, BorderLayout.NORTH);
+
+ list = new JList(tableNames.split("\t"));
+ JScrollPane scrollPane = new JScrollPane(list);
+ panel.add(scrollPane, BorderLayout.CENTER);
+
+ JPanel buttonPanel = new JPanel();
+ yesButton = new JButton("Select tables");
+ yesButton.addActionListener(this);
+ buttonPanel.add(yesButton);
+ noButton = new JButton("Cancel");
+ noButton.addActionListener(this);
+ buttonPanel.add(noButton);
+ panel.add(buttonPanel, BorderLayout.SOUTH);
+
+ pack();
+ setLocationRelativeTo(frame);
+ setVisible(true);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (yesButton == e.getSource()) {
+ answer = true;
+ setVisible(false);
+ } else if (noButton == e.getSource()) {
+ answer = false;
+ setVisible(false);
+ }
+ }
+
+ public Object[] getSelectedItems() {
+ return list.getSelectedValues();
+ }
+
+ }
+
+ private void handleError(Exception e) {
+ System.err.println("Error: " + e.getMessage());
+ String errorReportFilename = ErrorReport.generate(folderField.getText(), e);
+ String message = "Error: " + e.getLocalizedMessage();
+ message += "\nAn error report has been generated:\n" + errorReportFilename;
+ System.out.println(message);
+ JOptionPane.showMessageDialog(frame, StringUtilities.wordWrap(message, 80), "Error", JOptionPane.ERROR_MESSAGE);
+ }
+
+}
diff --git a/src/org/ohdsi/whiteRabbit/WhiteRabbitProcess.java b/src/org/ohdsi/whiteRabbit/WhiteRabbitProcess.java
new file mode 100644
index 00000000..627f6f27
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/WhiteRabbitProcess.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit;
+
+public class WhiteRabbitProcess {
+ public void process(String folder) {
+ if (!folder.endsWith("/"))
+ folder = folder + "/";
+
+
+
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/cdm/CDMV4NullableChecker.java b/src/org/ohdsi/whiteRabbit/cdm/CDMV4NullableChecker.java
new file mode 100644
index 00000000..788db98c
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/cdm/CDMV4NullableChecker.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.cdm;
+
+import org.ohdsi.utilities.collections.OneToManySet;
+import org.ohdsi.utilities.files.ReadCSVFileWithHeader;
+import org.ohdsi.utilities.files.Row;
+
+public class CDMV4NullableChecker {
+
+ private OneToManySet tableToNotNullableFields;
+
+ public CDMV4NullableChecker() {
+ tableToNotNullableFields = new OneToManySet();
+ for (Row row : new ReadCSVFileWithHeader(this.getClass().getResourceAsStream("NotNullableV4.csv"))) {
+ if (row.get("IS_NULLABLE").equals("NO"))
+ tableToNotNullableFields.put(row.get("TABLE_NAME").toLowerCase(), row.get("COLUMN_NAME").toLowerCase());
+ }
+ }
+
+ public String findNonAllowedNull(String tableName, Row row) {
+ for (String notNullableField : tableToNotNullableFields.get(tableName))
+ try {
+ if (row.get(notNullableField).length() == 0)
+ return notNullableField;
+ } catch (Exception e) {
+ return notNullableField;
+ }
+ return null;
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/cdm/CdmV4.java b/src/org/ohdsi/whiteRabbit/cdm/CdmV4.java
new file mode 100644
index 00000000..f048bcdd
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/cdm/CdmV4.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.cdm;
+
+import org.ohdsi.databases.DbType;
+import org.ohdsi.databases.RichConnection;
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.whiteRabbit.DbSettings;
+
+public class CdmV4 {
+
+ public static void createStructure(DbSettings dbSettings) {
+ RichConnection connection = new RichConnection(dbSettings.server, dbSettings.domain, dbSettings.user, dbSettings.password, dbSettings.dbType);
+ connection.setContext(CdmV4.class);
+ connection.setVerbose(false);
+
+ StringUtilities.outputWithTime("Creating CDM V4 data structure");
+ if (dbSettings.dbType == DbType.MYSQL) {
+ connection.execute("CREATE DATABASE IF NOT EXISTS `" + dbSettings.database + "`");
+ connection.use(dbSettings.database);
+ connection.executeResource("CreateCDMStructureMySQL.sql");
+ } else if (dbSettings.dbType == DbType.MSSQL) {
+ //connection.execute("CREATE DATABASE IF NOT EXISTS \"" + dbSettings.database + "\"");
+ connection.use(dbSettings.database);
+ connection.executeResource("CreateCDMStructureSQLServer.sql");
+ }
+
+ }
+
+ public static void createIndices(DbSettings dbSettings) {
+ RichConnection connection = new RichConnection(dbSettings.server, dbSettings.domain, dbSettings.user, dbSettings.password, dbSettings.dbType);
+ connection.setContext(CdmV4.class);
+ connection.setVerbose(false);
+
+ StringUtilities.outputWithTime("Creating CDM V4 indices");
+ connection.use(dbSettings.database);
+ connection.executeResource("CreateCDMIndices.sql");
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/cdm/CreateCDMIndices.sql b/src/org/ohdsi/whiteRabbit/cdm/CreateCDMIndices.sql
new file mode 100644
index 00000000..3b608210
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/cdm/CreateCDMIndices.sql
@@ -0,0 +1,61 @@
+CREATE INDEX INDEX_VISIT_OCCURRENCE_PLACE_OF_SERVICE_CONCEPT_ID ON VISIT_OCCURRENCE (PLACE_OF_SERVICE_CONCEPT_ID ASC);
+CREATE INDEX INDEX_VISIT_PLACE_OF_SERVICE_SOURCE_VALUE ON VISIT_OCCURRENCE (PLACE_OF_SERVICE_SOURCE_VALUE ASC);
+CREATE INDEX INDEX_VISIT_VISIT_START_DATE ON VISIT_OCCURRENCE (VISIT_START_DATE ASC);
+CREATE INDEX INDEX_VISIT_VISIT_END_DATE ON VISIT_OCCURRENCE (VISIT_END_DATE ASC);
+CREATE INDEX INDEX_VISIT_OCCURRENCE_PERSON_ID ON VISIT_OCCURRENCE (PERSON_ID ASC);
+
+CREATE INDEX INDEX_COHORT_COHORT_CONCEPT_ID ON COHORT (COHORT_CONCEPT_ID ASC);
+CREATE INDEX INDEX_COHORT_COHORT_START_DATE ON COHORT (COHORT_START_DATE ASC);
+CREATE INDEX INDEX_COHORT_COHORT_END_DATE ON COHORT (COHORT_END_DATE ASC);
+CREATE INDEX INDEX_COHORT_SUBJECT_ID ON COHORT (SUBJECT_ID ASC);
+
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PROCEDURE_OCCURRENCE_ID ON PROCEDURE_OCCURRENCE (PROCEDURE_OCCURRENCE_ID ASC);
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PROCEDURE_TYPE_CONCEPT_ID ON PROCEDURE_OCCURRENCE (PROCEDURE_TYPE_CONCEPT_ID ASC);
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PROCEDURE_SOURCE_VALUE ON PROCEDURE_OCCURRENCE (PROCEDURE_SOURCE_VALUE ASC);
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PROCEDURE_DATE ON PROCEDURE_OCCURRENCE (PROCEDURE_DATE ASC);
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PERSON_ID ON PROCEDURE_OCCURRENCE (PERSON_ID ASC);
+
+CREATE INDEX INDEX_PROCEDURE_COST_PROCEDURE_OCCURRENCE_ID ON PROCEDURE_COST (PROCEDURE_OCCURRENCE_ID ASC);
+CREATE INDEX INDEX_PROCEDURE_COST_DISEASE_CLASS_CONCEPT_ID ON PROCEDURE_COST (DISEASE_CLASS_CONCEPT_ID ASC);
+CREATE INDEX INDEX_PROCEDURE_COST_DISEASE_CLASS_SOURCE_VALUE ON PROCEDURE_COST (DISEASE_CLASS_SOURCE_VALUE ASC);
+
+CREATE INDEX INDEX_PROVIDER_PROVIDER_ID ON PROVIDER (PROVIDER_ID ASC);
+CREATE INDEX INDEX_PROVIDER_SPECIALTY_CONCEPT_ID ON PROVIDER (SPECIALTY_CONCEPT_ID ASC);
+CREATE INDEX INDEX_PROVIDER_SPECIALTY_SOURCE_VALUE ON PROVIDER (SPECIALTY_SOURCE_VALUE ASC);
+
+CREATE INDEX INDEX_PERSON_PERSON_ID ON PERSON (PERSON_ID ASC);
+
+CREATE INDEX INDEX_OBSERVATION_OBSERVATION_PERIOD_START_DATE ON OBSERVATION_PERIOD (OBSERVATION_PERIOD_START_DATE ASC);
+CREATE INDEX INDEX_OBSERVATION_OBSERVATION_PERIOD_END_DATE ON OBSERVATION_PERIOD (OBSERVATION_PERIOD_END_DATE ASC);
+CREATE INDEX INDEX_OBSERVATION_PERIOD_PERSON_ID ON OBSERVATION_PERIOD (PERSON_ID ASC);
+
+CREATE INDEX INDEX_OBSERVATION_OBSERVATION_CONCEPT_ID ON OBSERVATION (OBSERVATION_CONCEPT_ID ASC);
+CREATE INDEX INDEX_OBSERVATION_OBSERVATION_DATE ON OBSERVATION (OBSERVATION_DATE ASC);
+CREATE INDEX INDEX_OBSERVATION_PERSON_ID ON OBSERVATION (PERSON_ID ASC);
+
+CREATE INDEX INDEX_DRUG_ERA_DRUG_CONCEPT_ID ON DRUG_ERA (DRUG_CONCEPT_ID ASC);
+CREATE INDEX INDEX_DRUG_ERA_DRUG_ERA_START_DATE ON DRUG_ERA (DRUG_ERA_START_DATE ASC);
+CREATE INDEX INDEX_DRUG_ERA_DRUG_ERA_END_DATE ON DRUG_ERA (DRUG_ERA_END_DATE ASC);
+CREATE INDEX INDEX_DRUG_ERA_PERSON_ID ON DRUG_ERA (PERSON_ID ASC);
+
+CREATE INDEX INDEX_DRUG_EXPOSURE_DRUG_CONCEPT_ID ON DRUG_EXPOSURE (DRUG_CONCEPT_ID ASC);
+CREATE INDEX INDEX_DRUG_EXPOSURE_DRUG_SOURCE_VALUE ON DRUG_EXPOSURE (DRUG_SOURCE_VALUE ASC);
+CREATE INDEX INDEX_DRUG_EXPOSURE_DRUG_EXPOSURE_START_DATE ON DRUG_EXPOSURE (DRUG_EXPOSURE_START_DATE ASC);
+CREATE INDEX INDEX_DRUG_EXPOSURE_DRUG_EXPOSURE_END_DATE ON DRUG_EXPOSURE (DRUG_EXPOSURE_END_DATE ASC);
+CREATE INDEX INDEX_DRUG_EXPOSURE_PERSON_ID ON DRUG_EXPOSURE (PERSON_ID ASC);
+
+CREATE INDEX INDEX_DEATH_DEATH_DATE ON DEATH (DEATH_DATE ASC);
+CREATE INDEX INDEX_DEATH_PERSON_ID ON DEATH (PERSON_ID ASC);
+
+CREATE INDEX INDEX_CONDITION_ERA_CONDITION_CONCEPT_ID ON CONDITION_ERA (CONDITION_CONCEPT_ID ASC);
+CREATE INDEX INDEX_CONDITION_ERA_CONDITION_ERA_START_DATE ON CONDITION_ERA (CONDITION_ERA_START_DATE ASC);
+CREATE INDEX INDEX_CONDITION_ERA_CONDITION_ERA_END_DATE ON CONDITION_ERA (CONDITION_ERA_END_DATE ASC);
+CREATE INDEX INDEX_CONDITION_ERA_PERSON_ID ON CONDITION_ERA (PERSON_ID ASC);
+
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_CONDITION_CONCEPT_ID ON CONDITION_OCCURRENCE (CONDITION_CONCEPT_ID ASC);
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_CONDITION_SOURCE_VALUE ON CONDITION_OCCURRENCE (CONDITION_SOURCE_VALUE ASC);
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_CONDITION_START_DATE ON CONDITION_OCCURRENCE (CONDITION_START_DATE ASC);
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_CONDITION_END_DATE ON CONDITION_OCCURRENCE (CONDITION_END_DATE ASC);
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_PERSON_ID ON CONDITION_OCCURRENCE (PERSON_ID ASC);
+
+
diff --git a/src/org/ohdsi/whiteRabbit/cdm/CreateCDMIndicesSQLServer.sql b/src/org/ohdsi/whiteRabbit/cdm/CreateCDMIndicesSQLServer.sql
new file mode 100644
index 00000000..3b608210
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/cdm/CreateCDMIndicesSQLServer.sql
@@ -0,0 +1,61 @@
+CREATE INDEX INDEX_VISIT_OCCURRENCE_PLACE_OF_SERVICE_CONCEPT_ID ON VISIT_OCCURRENCE (PLACE_OF_SERVICE_CONCEPT_ID ASC);
+CREATE INDEX INDEX_VISIT_PLACE_OF_SERVICE_SOURCE_VALUE ON VISIT_OCCURRENCE (PLACE_OF_SERVICE_SOURCE_VALUE ASC);
+CREATE INDEX INDEX_VISIT_VISIT_START_DATE ON VISIT_OCCURRENCE (VISIT_START_DATE ASC);
+CREATE INDEX INDEX_VISIT_VISIT_END_DATE ON VISIT_OCCURRENCE (VISIT_END_DATE ASC);
+CREATE INDEX INDEX_VISIT_OCCURRENCE_PERSON_ID ON VISIT_OCCURRENCE (PERSON_ID ASC);
+
+CREATE INDEX INDEX_COHORT_COHORT_CONCEPT_ID ON COHORT (COHORT_CONCEPT_ID ASC);
+CREATE INDEX INDEX_COHORT_COHORT_START_DATE ON COHORT (COHORT_START_DATE ASC);
+CREATE INDEX INDEX_COHORT_COHORT_END_DATE ON COHORT (COHORT_END_DATE ASC);
+CREATE INDEX INDEX_COHORT_SUBJECT_ID ON COHORT (SUBJECT_ID ASC);
+
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PROCEDURE_OCCURRENCE_ID ON PROCEDURE_OCCURRENCE (PROCEDURE_OCCURRENCE_ID ASC);
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PROCEDURE_TYPE_CONCEPT_ID ON PROCEDURE_OCCURRENCE (PROCEDURE_TYPE_CONCEPT_ID ASC);
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PROCEDURE_SOURCE_VALUE ON PROCEDURE_OCCURRENCE (PROCEDURE_SOURCE_VALUE ASC);
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PROCEDURE_DATE ON PROCEDURE_OCCURRENCE (PROCEDURE_DATE ASC);
+CREATE INDEX INDEX_PROCEDURE_OCCURRENCE_PERSON_ID ON PROCEDURE_OCCURRENCE (PERSON_ID ASC);
+
+CREATE INDEX INDEX_PROCEDURE_COST_PROCEDURE_OCCURRENCE_ID ON PROCEDURE_COST (PROCEDURE_OCCURRENCE_ID ASC);
+CREATE INDEX INDEX_PROCEDURE_COST_DISEASE_CLASS_CONCEPT_ID ON PROCEDURE_COST (DISEASE_CLASS_CONCEPT_ID ASC);
+CREATE INDEX INDEX_PROCEDURE_COST_DISEASE_CLASS_SOURCE_VALUE ON PROCEDURE_COST (DISEASE_CLASS_SOURCE_VALUE ASC);
+
+CREATE INDEX INDEX_PROVIDER_PROVIDER_ID ON PROVIDER (PROVIDER_ID ASC);
+CREATE INDEX INDEX_PROVIDER_SPECIALTY_CONCEPT_ID ON PROVIDER (SPECIALTY_CONCEPT_ID ASC);
+CREATE INDEX INDEX_PROVIDER_SPECIALTY_SOURCE_VALUE ON PROVIDER (SPECIALTY_SOURCE_VALUE ASC);
+
+CREATE INDEX INDEX_PERSON_PERSON_ID ON PERSON (PERSON_ID ASC);
+
+CREATE INDEX INDEX_OBSERVATION_OBSERVATION_PERIOD_START_DATE ON OBSERVATION_PERIOD (OBSERVATION_PERIOD_START_DATE ASC);
+CREATE INDEX INDEX_OBSERVATION_OBSERVATION_PERIOD_END_DATE ON OBSERVATION_PERIOD (OBSERVATION_PERIOD_END_DATE ASC);
+CREATE INDEX INDEX_OBSERVATION_PERIOD_PERSON_ID ON OBSERVATION_PERIOD (PERSON_ID ASC);
+
+CREATE INDEX INDEX_OBSERVATION_OBSERVATION_CONCEPT_ID ON OBSERVATION (OBSERVATION_CONCEPT_ID ASC);
+CREATE INDEX INDEX_OBSERVATION_OBSERVATION_DATE ON OBSERVATION (OBSERVATION_DATE ASC);
+CREATE INDEX INDEX_OBSERVATION_PERSON_ID ON OBSERVATION (PERSON_ID ASC);
+
+CREATE INDEX INDEX_DRUG_ERA_DRUG_CONCEPT_ID ON DRUG_ERA (DRUG_CONCEPT_ID ASC);
+CREATE INDEX INDEX_DRUG_ERA_DRUG_ERA_START_DATE ON DRUG_ERA (DRUG_ERA_START_DATE ASC);
+CREATE INDEX INDEX_DRUG_ERA_DRUG_ERA_END_DATE ON DRUG_ERA (DRUG_ERA_END_DATE ASC);
+CREATE INDEX INDEX_DRUG_ERA_PERSON_ID ON DRUG_ERA (PERSON_ID ASC);
+
+CREATE INDEX INDEX_DRUG_EXPOSURE_DRUG_CONCEPT_ID ON DRUG_EXPOSURE (DRUG_CONCEPT_ID ASC);
+CREATE INDEX INDEX_DRUG_EXPOSURE_DRUG_SOURCE_VALUE ON DRUG_EXPOSURE (DRUG_SOURCE_VALUE ASC);
+CREATE INDEX INDEX_DRUG_EXPOSURE_DRUG_EXPOSURE_START_DATE ON DRUG_EXPOSURE (DRUG_EXPOSURE_START_DATE ASC);
+CREATE INDEX INDEX_DRUG_EXPOSURE_DRUG_EXPOSURE_END_DATE ON DRUG_EXPOSURE (DRUG_EXPOSURE_END_DATE ASC);
+CREATE INDEX INDEX_DRUG_EXPOSURE_PERSON_ID ON DRUG_EXPOSURE (PERSON_ID ASC);
+
+CREATE INDEX INDEX_DEATH_DEATH_DATE ON DEATH (DEATH_DATE ASC);
+CREATE INDEX INDEX_DEATH_PERSON_ID ON DEATH (PERSON_ID ASC);
+
+CREATE INDEX INDEX_CONDITION_ERA_CONDITION_CONCEPT_ID ON CONDITION_ERA (CONDITION_CONCEPT_ID ASC);
+CREATE INDEX INDEX_CONDITION_ERA_CONDITION_ERA_START_DATE ON CONDITION_ERA (CONDITION_ERA_START_DATE ASC);
+CREATE INDEX INDEX_CONDITION_ERA_CONDITION_ERA_END_DATE ON CONDITION_ERA (CONDITION_ERA_END_DATE ASC);
+CREATE INDEX INDEX_CONDITION_ERA_PERSON_ID ON CONDITION_ERA (PERSON_ID ASC);
+
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_CONDITION_CONCEPT_ID ON CONDITION_OCCURRENCE (CONDITION_CONCEPT_ID ASC);
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_CONDITION_SOURCE_VALUE ON CONDITION_OCCURRENCE (CONDITION_SOURCE_VALUE ASC);
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_CONDITION_START_DATE ON CONDITION_OCCURRENCE (CONDITION_START_DATE ASC);
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_CONDITION_END_DATE ON CONDITION_OCCURRENCE (CONDITION_END_DATE ASC);
+CREATE INDEX INDEX_CONDITION_OCCURRENCE_PERSON_ID ON CONDITION_OCCURRENCE (PERSON_ID ASC);
+
+
diff --git a/src/org/ohdsi/whiteRabbit/cdm/CreateCDMStructureMySQL.sql b/src/org/ohdsi/whiteRabbit/cdm/CreateCDMStructureMySQL.sql
new file mode 100644
index 00000000..f83c64b2
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/cdm/CreateCDMStructureMySQL.sql
@@ -0,0 +1,214 @@
+CREATE TABLE IF NOT EXISTS `CARE_SITE` (
+ `CARE_SITE_ID` INT NOT NULL,
+ `LOCATION_ID` INT NULL,
+ `ORGANIZATION_ID` INT NULL,
+ `PLACE_OF_SERVICE_CONCEPT_ID` INT NULL,
+ `CARE_SITE_SOURCE_VALUE` VARCHAR(50) NULL,
+ `PLACE_OF_SERVICE_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `COHORT` (
+ `COHORT_ID` INT AUTO_INCREMENT PRIMARY KEY,
+ `COHORT_CONCEPT_ID` INT NOT NULL,
+ `COHORT_START_DATE` DATE NOT NULL,
+ `COHORT_END_DATE` DATE NULL,
+ `SUBJECT_ID` BIGINT NOT NULL,
+ `STOP_REASON` VARCHAR(20) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `CONDITION_ERA` (
+ `CONDITION_ERA_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `CONDITION_CONCEPT_ID` INT NOT NULL,
+ `CONDITION_ERA_START_DATE` DATE NOT NULL,
+ `CONDITION_ERA_END_DATE` DATE NOT NULL,
+ `CONDITION_TYPE_CONCEPT_ID` INT NOT NULL,
+ `CONDITION_OCCURRENCE_COUNT` INT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `CONDITION_OCCURRENCE` (
+ `CONDITION_OCCURRENCE_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `CONDITION_CONCEPT_ID` INT NOT NULL,
+ `CONDITION_START_DATE` DATE NOT NULL,
+ `CONDITION_END_DATE` DATE NULL,
+ `CONDITION_TYPE_CONCEPT_ID` INT NOT NULL,
+ `STOP_REASON` VARCHAR(20) NULL,
+ `ASSOCIATED_PROVIDER_ID` INT NULL,
+ `VISIT_OCCURRENCE_ID` BIGINT NULL,
+ `CONDITION_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `DEATH` (
+ `PERSON_ID` BIGINT NOT NULL,
+ `DEATH_DATE` DATE NOT NULL,
+ `DEATH_TYPE_CONCEPT_ID` INT NOT NULL,
+ `CAUSE_OF_DEATH_CONCEPT_ID` INT NULL,
+ `CAUSE_OF_DEATH_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `DRUG_COST` (
+ `DRUG_COST_ID` BIGINT NOT NULL,
+ `DRUG_EXPOSURE_ID` BIGINT NOT NULL,
+ `PAID_COPAY` NUMERIC NULL,
+ `PAID_COINSURANCE` NUMERIC NULL,
+ `PAID_TOWARD_DEDUCTIBLE` NUMERIC NULL,
+ `PAID_BY_PAYER` NUMERIC NULL,
+ `PAID_BY_COORDINATION_BENEFITS` NUMERIC NULL,
+ `TOTAL_OUT_OF_POCKET` NUMERIC NULL,
+ `TOTAL_PAID` NUMERIC NULL,
+ `INGREDIENT_COST` NUMERIC NULL,
+ `DISPENSING_FEE` NUMERIC NULL,
+ `AVERAGE_WHOLESALE_PRICE` NUMERIC NULL,
+ `PAYER_PLAN_PERIOD_ID` INT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `DRUG_ERA` (
+ `DRUG_ERA_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `DRUG_ERA_START_DATE` DATE NOT NULL,
+ `DRUG_ERA_END_DATE` DATE NOT NULL,
+ `DRUG_TYPE_CONCEPT_ID` INT NOT NULL,
+ `DRUG_CONCEPT_ID` INT NULL,
+ `DRUG_EXPOSURE_COUNT` INT NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `DRUG_EXPOSURE` (
+ `DRUG_EXPOSURE_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `DRUG_CONCEPT_ID` INT NOT NULL,
+ `DRUG_EXPOSURE_START_DATE` DATE NOT NULL,
+ `DRUG_EXPOSURE_END_DATE` DATE NULL,
+ `DRUG_TYPE_CONCEPT_ID` INT NOT NULL,
+ `STOP_REASON` VARCHAR(20) NULL,
+ `REFILLS` INT NULL,
+ `QUANTITY` INT NULL,
+ `DAYS_SUPPLY` INT NULL,
+ `SIG` VARCHAR(500) NULL,
+ `PRESCRIBING_PROVIDER_ID` INT NULL,
+ `VISIT_OCCURRENCE_ID` BIGINT NULL,
+ `RELEVANT_CONDITION_CONCEPT_ID` INT NULL,
+ `DRUG_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `LOCATION` (
+ `LOCATION_ID` INT NOT NULL,
+ `ADDRESS_1` VARCHAR(50) NULL,
+ `ADDRESS_2` VARCHAR(50) NULL,
+ `CITY` VARCHAR(50) NULL,
+ `STATE` CHAR(2) NULL,
+ `ZIP` VARCHAR(9) NULL,
+ `COUNTY` VARCHAR(20) NULL,
+ `LOCATION_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `OBSERVATION` (
+ `OBSERVATION_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `OBSERVATION_CONCEPT_ID` BIGINT NOT NULL,
+ `OBSERVATION_TYPE_CONCEPT_ID` INT NOT NULL,
+ `OBSERVATION_DATE` DATE NOT NULL,
+ `OBSERVATION_TIME` TIME NULL,
+ `VALUE_AS_NUMBER` NUMERIC NULL,
+ `VALUE_AS_STRING` VARCHAR(256) NULL,
+ `VALUE_AS_CONCEPT_ID` INT NULL,
+ `UNIT_CONCEPT_ID` BIGINT NULL,
+ `RANGE_LOW` FLOAT NULL,
+ `RANGE_HIGH` FLOAT NULL,
+ `ASSOCIATED_PROVIDER_ID` INT NULL,
+ `VISIT_OCCURRENCE_ID` BIGINT NULL,
+ `OBSERVATION_SOURCE_VALUE` VARCHAR(256) NULL,
+ `UNIT_SOURCE_VALUE` VARCHAR(256) NULL,
+ `RELEVANT_CONDITION_CONCEPT_ID` INT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `OBSERVATION_PERIOD` (
+ `OBSERVATION_PERIOD_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `OBSERVATION_PERIOD_START_DATE` DATE NOT NULL,
+ `OBSERVATION_PERIOD_END_DATE` DATE NOT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `ORGANIZATION` (
+ `ORGANIZATION_ID` INT NOT NULL,
+ `PLACE_OF_SERVICE_CONCEPT_ID` INT NULL,
+ `LOCATION_ID` INT NULL,
+ `ORGANIZATION_SOURCE_VALUE` VARCHAR(50) NULL,
+ `PLACE_OF_SERVICE_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `PAYER_PLAN_PERIOD` (
+ `PAYER_PLAN_PERIOD_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `PAYER_PLAN_PERIOD_START_DATE` DATE NOT NULL,
+ `PAYER_PLAN_PERIOD_END_DATE` DATE NOT NULL,
+ `PAYER_SOURCE_VALUE` VARCHAR(50) NULL,
+ `PLAN_SOURCE_VALUE` VARCHAR(50) NULL,
+ `FAMILY_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `PERSON` (
+ `PERSON_ID` BIGINT NOT NULL,
+ `GENDER_CONCEPT_ID` INT NOT NULL,
+ `YEAR_OF_BIRTH` INT NOT NULL,
+ `MONTH_OF_BIRTH` INT NULL,
+ `DAY_OF_BIRTH` INT NULL,
+ `RACE_CONCEPT_ID` INT NULL,
+ `ETHNICITY_CONCEPT_ID` INT NULL,
+ `LOCATION_ID` INT NULL,
+ `PROVIDER_ID` INT NULL,
+ `CARE_SITE_ID` INT NULL,
+ `PERSON_SOURCE_VALUE` VARCHAR(50) NULL,
+ `GENDER_SOURCE_VALUE` VARCHAR(50) NULL,
+ `RACE_SOURCE_VALUE` VARCHAR(50) NULL,
+ `ETHNICITY_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `PROCEDURE_COST` (
+ `PROCEDURE_COST_ID` BIGINT NOT NULL,
+ `PROCEDURE_OCCURRENCE_ID` BIGINT NOT NULL,
+ `PAID_COPAY` NUMERIC NULL,
+ `PAID_COINSURANCE` NUMERIC NULL,
+ `PAID_TOWARD_DEDUCTIBLE` NUMERIC NULL,
+ `PAID_BY_PAYER` NUMERIC NULL,
+ `PAID_BY_COORDINATION_BENEFITS` NUMERIC NULL,
+ `TOTAL_OUT_OF_POCKET` NUMERIC NULL,
+ `TOTAL_PAID` NUMERIC NULL,
+ `DISEASE_CLASS_CONCEPT_ID` INT NULL,
+ `REVENUE_CODE_CONCEPT_ID` INT NULL,
+ `PAYER_PLAN_PERIOD_ID` BIGINT NULL,
+ `DISEASE_CLASS_SOURCE_VALUE` VARCHAR(50) NULL,
+ `REVENUE_CODE_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `PROCEDURE_OCCURRENCE` (
+ `PROCEDURE_OCCURRENCE_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `PROCEDURE_TYPE_CONCEPT_ID` INT NOT NULL,
+ `PROCEDURE_DATE` DATE NOT NULL,
+ `PROCEDURE_CONCEPT_ID` BIGINT NOT NULL,
+ `ASSOCIATED_PROVIDER_ID` INT NULL,
+ `PROCEDURE_SOURCE_VALUE` VARCHAR(50) NULL,
+ `VISIT_OCCURRENCE_ID` BIGINT NULL,
+ `RELEVANT_CONDITION_CONCEPT_ID` INT NULL
+);
+
+CREATE TABLE IF NOT EXISTS `PROVIDER` (
+ `PROVIDER_ID` BIGINT NOT NULL,
+ `NPI` VARCHAR(20) NULL,
+ `DEA` VARCHAR(20) NULL,
+ `SPECIALTY_CONCEPT_ID` INT NULL,
+ `CARE_SITE_ID` INT NULL,
+ `PROVIDER_SOURCE_VALUE` VARCHAR(50) NULL,
+ `SPECIALTY_SOURCE_VALUE` VARCHAR(50) NULL
+);
+
+CREATE TABLE IF NOT EXISTS `VISIT_OCCURRENCE` (
+ `VISIT_OCCURRENCE_ID` BIGINT NOT NULL,
+ `PERSON_ID` BIGINT NOT NULL,
+ `PLACE_OF_SERVICE_CONCEPT_ID` INT NOT NULL,
+ `VISIT_START_DATE` DATE NOT NULL,
+ `VISIT_END_DATE` DATE NOT NULL,
+ `PLACE_OF_SERVICE_SOURCE_VALUE` VARCHAR(50) NULL,
+ `CARE_SITE_ID` INT NULL
+);
diff --git a/src/org/ohdsi/whiteRabbit/cdm/CreateCDMStructureSQLServer.sql b/src/org/ohdsi/whiteRabbit/cdm/CreateCDMStructureSQLServer.sql
new file mode 100644
index 00000000..c975938c
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/cdm/CreateCDMStructureSQLServer.sql
@@ -0,0 +1,272 @@
+
+CREATE TABLE "CARE_SITE" (
+ "CARE_SITE_ID" INT NOT NULL,
+ "LOCATION_ID" INT NULL,
+ "ORGANIZATION_ID" INT NULL,
+ "PLACE_OF_SERVICE_CONCEPT_ID" INT NULL,
+ "CARE_SITE_SOURCE_VALUE" VARCHAR(50) NULL,
+ "PLACE_OF_SERVICE_SOURCE_VALUE" VARCHAR(50) NULL,
+ PRIMARY KEY ("CARE_SITE_ID")
+);
+
+CREATE TABLE "COHORT" (
+ "COHORT_ID" INT NOT NULL,
+ "COHORT_CONCEPT_ID" INT NOT NULL,
+ "COHORT_START_DATE" DATE NOT NULL,
+ "COHORT_END_DATE" DATE NULL,
+ "SUBJECT_ID" BIGINT NOT NULL,
+ "STOP_REASON" VARCHAR(20) NULL
+);
+
+CREATE TABLE "CONCEPT" (
+ "CONCEPT_ID" INT NOT NULL,
+ "CONCEPT_NAME" VARCHAR(256) NOT NULL,
+ "CONCEPT_LEVEL" INT NULL,
+ "CONCEPT_CLASS" VARCHAR(60) NOT NULL,
+ "VOCABULARY_ID" INT NOT NULL,
+ "CONCEPT_CODE" VARCHAR(40) NOT NULL,
+ "VALID_START_DATE" DATE NOT NULL,
+ "VALID_END_DATE" DATE NOT NULL,
+ "INVALID_REASON" CHAR(1) NULL,
+ PRIMARY KEY ("CONCEPT_ID")
+);
+
+CREATE TABLE "CONCEPT_ANCESTOR" (
+ "ANCESTOR_CONCEPT_ID" INT NOT NULL,
+ "DESCENDANT_CONCEPT_ID" INT NOT NULL,
+ "MIN_LEVELS_OF_SEPARATION" INT NULL,
+ "MAX_LEVELS_OF_SEPARATION" INT NULL,
+ PRIMARY KEY ("ANCESTOR_CONCEPT_ID","DESCENDANT_CONCEPT_ID")
+);
+
+CREATE TABLE "CONCEPT_RELATIONSHIP" (
+ "CONCEPT_ID_1" INT NOT NULL,
+ "CONCEPT_ID_2" INT NOT NULL,
+ "RELATIONSHIP_ID" INT NOT NULL,
+ "VALID_START_DATE" DATE NOT NULL,
+ "VALID_END_DATE" DATE NOT NULL,
+ "INVALID_REASON" CHAR(1) NULL,
+ PRIMARY KEY ("CONCEPT_ID_1","CONCEPT_ID_2","RELATIONSHIP_ID")
+);
+
+CREATE TABLE "CONCEPT_SYNONYM" (
+ "CONCEPT_SYNONYM_ID" INT NOT NULL,
+ "CONCEPT_ID" INT NOT NULL,
+ "CONCEPT_SYNONYM_NAME" VARCHAR(1000) NOT NULL,
+ PRIMARY KEY ("CONCEPT_SYNONYM_ID")
+);
+
+CREATE TABLE "CONDITION_ERA" (
+ "CONDITION_ERA_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "CONDITION_CONCEPT_ID" INT NOT NULL,
+ "CONDITION_ERA_START_DATE" DATE NOT NULL,
+ "CONDITION_ERA_END_DATE" DATE NOT NULL,
+ "CONDITION_TYPE_CONCEPT_ID" INT NOT NULL,
+ "CONDITION_OCCURRENCE_COUNT" INT NULL
+);
+
+CREATE TABLE "CONDITION_OCCURRENCE" (
+ "CONDITION_OCCURRENCE_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "CONDITION_CONCEPT_ID" INT NOT NULL,
+ "CONDITION_START_DATE" DATE NOT NULL,
+ "CONDITION_END_DATE" DATE NULL,
+ "CONDITION_TYPE_CONCEPT_ID" INT NOT NULL,
+ "STOP_REASON" VARCHAR(20) NULL,
+ "ASSOCIATED_PROVIDER_ID" INT NULL,
+ "VISIT_OCCURRENCE_ID" BIGINT NULL,
+ "CONDITION_SOURCE_VALUE" VARCHAR(50) NULL
+);
+
+-- Data exporting was unselected.
+
+
+-- Dumping structure for table CDM_Truven_MDCR.DEATH
+CREATE TABLE "DEATH" (
+ "PERSON_ID" BIGINT NOT NULL,
+ "DEATH_DATE" DATE NOT NULL,
+ "DEATH_TYPE_CONCEPT_ID" INT NOT NULL,
+ "CAUSE_OF_DEATH_CONCEPT_ID" INT NULL,
+ "CAUSE_OF_DEATH_SOURCE_VALUE" VARCHAR(50) NULL
+);
+
+CREATE TABLE "DRG_MAP" (
+ "SOURCE_CODE" VARCHAR(40) NOT NULL,
+ "TARGET_CONCEPT_ID" INT NOT NULL,
+ "VALID_START_DATE" DATE NOT NULL,
+ "VALID_END_DATE" DATE NOT NULL
+);
+
+CREATE TABLE "DRUG_COST" (
+ "DRUG_COST_ID" BIGINT NOT NULL,
+ "DRUG_EXPOSURE_ID" BIGINT NOT NULL,
+ "PAID_COPAY" NUMERIC NULL,
+ "PAID_COINSURANCE" NUMERIC NULL,
+ "PAID_TOWARD_DEDUCTIBLE" NUMERIC NULL,
+ "PAID_BY_PAYER" NUMERIC NULL,
+ "PAID_BY_COORDINATION_BENEFITS" NUMERIC NULL,
+ "TOTAL_OUT_OF_POCKET" NUMERIC NULL,
+ "TOTAL_PAID" NUMERIC NULL,
+ "INGREDIENT_COST" NUMERIC NULL,
+ "DISPENSING_FEE" NUMERIC NULL,
+ "AVERAGE_WHOLESALE_PRICE" NUMERIC NULL,
+ "PAYER_PLAN_PERIOD_ID" INT NULL,
+ PRIMARY KEY ("DRUG_EXPOSURE_ID")
+);
+
+CREATE TABLE "DRUG_ERA" (
+ "DRUG_ERA_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "DRUG_ERA_START_DATE" DATE NOT NULL,
+ "DRUG_ERA_END_DATE" DATE NOT NULL,
+ "DRUG_TYPE_CONCEPT_ID" INT NOT NULL,
+ "DRUG_CONCEPT_ID" INT NULL,
+ "DRUG_EXPOSURE_COUNT" INT NOT NULL
+);
+
+CREATE TABLE "DRUG_EXPOSURE" (
+ "DRUG_EXPOSURE_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "DRUG_CONCEPT_ID" INT NOT NULL,
+ "DRUG_EXPOSURE_START_DATE" DATE NOT NULL,
+ "DRUG_EXPOSURE_END_DATE" DATE NULL,
+ "DRUG_TYPE_CONCEPT_ID" INT NOT NULL,
+ "STOP_REASON" VARCHAR(20) NULL,
+ "REFILLS" INT NULL,
+ "QUANTITY" INT NULL,
+ "DAYS_SUPPLY" INT NULL,
+ "SIG" VARCHAR(500) NULL,
+ "PRESCRIBING_PROVIDER_ID" INT NULL,
+ "VISIT_OCCURRENCE_ID" BIGINT NULL,
+ "RELEVANT_CONDITION_CONCEPT_ID" INT NULL,
+ "DRUG_SOURCE_VALUE" VARCHAR(50) NULL,
+ PRIMARY KEY ("DRUG_EXPOSURE_ID")
+);
+
+CREATE TABLE "LOCATION" (
+ "LOCATION_ID" INT NOT NULL,
+ "ADDRESS_1" VARCHAR(50) NULL,
+ "ADDRESS_2" VARCHAR(50) NULL,
+ "CITY" VARCHAR(50) NULL,
+ "STATE" CHAR(2) NULL,
+ "ZIP" VARCHAR(9) NULL,
+ "COUNTY" VARCHAR(20) NULL,
+ "LOCATION_SOURCE_VALUE" VARCHAR(50) NULL,
+ PRIMARY KEY ("LOCATION_ID")
+);
+
+CREATE TABLE "OBSERVATION" (
+ "OBSERVATION_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "OBSERVATION_CONCEPT_ID" BIGINT NOT NULL,
+ "OBSERVATION_TYPE_CONCEPT_ID" INT NOT NULL,
+ "OBSERVATION_DATE" DATE NOT NULL,
+ "OBSERVATION_TIME" TIME NULL,
+ "VALUE_AS_NUMBER" NUMERIC NULL,
+ "VALUE_AS_STRING" VARCHAR(256) NULL,
+ "VALUE_AS_CONCEPT_ID" INT NULL,
+ "UNIT_CONCEPT_ID" BIGINT NULL,
+ "RANGE_LOW" FLOAT NULL,
+ "RANGE_HIGH" FLOAT NULL,
+ "ASSOCIATED_PROVIDER_ID" INT NULL,
+ "VISIT_OCCURRENCE_ID" BIGINT NULL,
+ "OBSERVATION_SOURCE_VALUE" VARCHAR(256) NULL,
+ "UNIT_SOURCE_VALUE" VARCHAR(256) NULL,
+ "RELEVANT_CONDITION_CONCEPT_ID" INT NULL
+);
+
+CREATE TABLE "OBSERVATION_PERIOD" (
+ "OBSERVATION_PERIOD_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "OBSERVATION_PERIOD_START_DATE" DATE NOT NULL,
+ "OBSERVATION_PERIOD_END_DATE" DATE NOT NULL
+);
+
+
+CREATE TABLE "ORGANIZATION" (
+ "ORGANIZATION_ID" INT NOT NULL,
+ "PLACE_OF_SERVICE_CONCEPT_ID" INT NULL,
+ "LOCATION_ID" INT NULL,
+ "ORGANIZATION_SOURCE_VALUE" VARCHAR(50) NULL,
+ "PLACE_OF_SERVICE_SOURCE_VALUE" VARCHAR(50) NULL,
+ PRIMARY KEY ("ORGANIZATION_ID")
+);
+
+CREATE TABLE "PAYER_PLAN_PERIOD" (
+ "PAYER_PLAN_PERIOD_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "PAYER_PLAN_PERIOD_START_DATE" DATE NOT NULL,
+ "PAYER_PLAN_PERIOD_END_DATE" DATE NOT NULL,
+ "PAYER_SOURCE_VALUE" VARCHAR(50) NULL,
+ "PLAN_SOURCE_VALUE" VARCHAR(50) NULL,
+ "FAMILY_SOURCE_VALUE" VARCHAR(50) NULL
+);
+
+CREATE TABLE "PERSON" (
+ "PERSON_ID" BIGINT NOT NULL,
+ "GENDER_CONCEPT_ID" INT NOT NULL,
+ "YEAR_OF_BIRTH" INT NOT NULL,
+ "MONTH_OF_BIRTH" INT NULL,
+ "DAY_OF_BIRTH" INT NULL,
+ "RACE_CONCEPT_ID" INT NULL,
+ "ETHNICITY_CONCEPT_ID" INT NULL,
+ "LOCATION_ID" INT NULL,
+ "PROVIDER_ID" INT NULL,
+ "CARE_SITE_ID" INT NULL,
+ "PERSON_SOURCE_VALUE" VARCHAR(50) NULL,
+ "GENDER_SOURCE_VALUE" VARCHAR(50) NULL,
+ "RACE_SOURCE_VALUE" VARCHAR(50) NULL,
+ "ETHNICITY_SOURCE_VALUE" VARCHAR(50) NULL,
+ PRIMARY KEY ("PERSON_ID")
+);
+
+CREATE TABLE "PROCEDURE_COST" (
+ "PROCEDURE_COST_ID" BIGINT NOT NULL,
+ "PROCEDURE_OCCURRENCE_ID" BIGINT NOT NULL,
+ "PAID_COPAY" NUMERIC NULL,
+ "PAID_COINSURANCE" NUMERIC NULL,
+ "PAID_TOWARD_DEDUCTIBLE" NUMERIC NULL,
+ "PAID_BY_PAYER" NUMERIC NULL,
+ "PAID_BY_COORDINATION_BENEFITS" NUMERIC NULL,
+ "TOTAL_OUT_OF_POCKET" NUMERIC NULL,
+ "TOTAL_PAID" NUMERIC NULL,
+ "DISEASE_CLASS_CONCEPT_ID" INT NULL,
+ "REVENUE_CODE_CONCEPT_ID" INT NULL,
+ "PAYER_PLAN_PERIOD_ID" BIGINT NULL,
+ "DISEASE_CLASS_SOURCE_VALUE" VARCHAR(50) NULL,
+ "REVENUE_CODE_SOURCE_VALUE" VARCHAR(50) NULL
+);
+
+CREATE TABLE "PROCEDURE_OCCURRENCE" (
+ "PROCEDURE_OCCURRENCE_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "PROCEDURE_TYPE_CONCEPT_ID" INT NOT NULL,
+ "PROCEDURE_DATE" DATE NOT NULL,
+ "PROCEDURE_CONCEPT_ID" BIGINT NOT NULL,
+ "ASSOCIATED_PROVIDER_ID" INT NULL,
+ "PROCEDURE_SOURCE_VALUE" VARCHAR(50) NULL,
+ "VISIT_OCCURRENCE_ID" BIGINT NULL,
+ "RELEVANT_CONDITION_CONCEPT_ID" INT NULL,
+ PRIMARY KEY ("PROCEDURE_OCCURRENCE_ID")
+);
+
+CREATE TABLE "PROVIDER" (
+ "PROVIDER_ID" BIGINT NOT NULL,
+ "NPI" VARCHAR(20) NULL,
+ "DEA" VARCHAR(20) NULL,
+ "SPECIALTY_CONCEPT_ID" INT NULL,
+ "CARE_SITE_ID" INT NULL,
+ "PROVIDER_SOURCE_VALUE" VARCHAR(50) NULL,
+ "SPECIALTY_SOURCE_VALUE" VARCHAR(50) NULL,
+ PRIMARY KEY ("PROVIDER_ID")
+);
+CREATE TABLE "VISIT_OCCURRENCE" (
+ "VISIT_OCCURRENCE_ID" BIGINT NOT NULL,
+ "PERSON_ID" BIGINT NOT NULL,
+ "PLACE_OF_SERVICE_CONCEPT_ID" INT NOT NULL,
+ "VISIT_START_DATE" DATE NOT NULL,
+ "VISIT_END_DATE" DATE NOT NULL,
+ "PLACE_OF_SERVICE_SOURCE_VALUE" VARCHAR(50) NULL,
+ "CARE_SITE_ID" INT NULL
+);
diff --git a/src/org/ohdsi/whiteRabbit/cdm/FetchNullableFromServer.java b/src/org/ohdsi/whiteRabbit/cdm/FetchNullableFromServer.java
new file mode 100644
index 00000000..7b0b6a0c
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/cdm/FetchNullableFromServer.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.cdm;
+
+import org.ohdsi.databases.DbType;
+import org.ohdsi.databases.RichConnection;
+import org.ohdsi.utilities.files.Row;
+import org.ohdsi.utilities.files.WriteCSVFileWithHeader;
+
+public class FetchNullableFromServer {
+
+ public static void main(String[] args) {
+ RichConnection connection = new RichConnection("127.0.0.1", null, "root", "F1r3starter", DbType.MYSQL);
+ connection.use("cdm_v4");
+
+ WriteCSVFileWithHeader out = new WriteCSVFileWithHeader("c:/temp/NotNullableV4.csv");
+ String query = "SELECT table_name,column_name,is_nullable FROM information_schema.columns WHERE table_schema = 'cdm_v4';";
+ for (Row row : connection.query(query))
+ out.write(row);
+ out.close();
+
+ }
+
+}
diff --git a/src/org/ohdsi/whiteRabbit/cdm/NotNullableV4.csv b/src/org/ohdsi/whiteRabbit/cdm/NotNullableV4.csv
new file mode 100644
index 00000000..03b87b17
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/cdm/NotNullableV4.csv
@@ -0,0 +1,162 @@
+TABLE_NAME,COLUMN_NAME,IS_NULLABLE
+care_site,CARE_SITE_ID,NO
+care_site,LOCATION_ID,YES
+care_site,ORGANIZATION_ID,YES
+care_site,PLACE_OF_SERVICE_CONCEPT_ID,YES
+care_site,CARE_SITE_SOURCE_VALUE,YES
+care_site,PLACE_OF_SERVICE_SOURCE_VALUE,YES
+cohort,COHORT_ID,NO
+cohort,COHORT_CONCEPT_ID,NO
+cohort,COHORT_START_DATE,NO
+cohort,COHORT_END_DATE,YES
+cohort,SUBJECT_ID,NO
+cohort,STOP_REASON,YES
+condition_era,CONDITION_ERA_ID,NO
+condition_era,PERSON_ID,NO
+condition_era,CONDITION_CONCEPT_ID,NO
+condition_era,CONDITION_ERA_START_DATE,NO
+condition_era,CONDITION_ERA_END_DATE,NO
+condition_era,CONDITION_TYPE_CONCEPT_ID,NO
+condition_era,CONDITION_OCCURRENCE_COUNT,YES
+condition_occurrence,CONDITION_OCCURRENCE_ID,NO
+condition_occurrence,PERSON_ID,NO
+condition_occurrence,CONDITION_CONCEPT_ID,NO
+condition_occurrence,CONDITION_START_DATE,NO
+condition_occurrence,CONDITION_END_DATE,YES
+condition_occurrence,CONDITION_TYPE_CONCEPT_ID,NO
+condition_occurrence,STOP_REASON,YES
+condition_occurrence,ASSOCIATED_PROVIDER_ID,YES
+condition_occurrence,VISIT_OCCURRENCE_ID,YES
+condition_occurrence,CONDITION_SOURCE_VALUE,YES
+death,PERSON_ID,NO
+death,DEATH_DATE,NO
+death,DEATH_TYPE_CONCEPT_ID,NO
+death,CAUSE_OF_DEATH_CONCEPT_ID,YES
+death,CAUSE_OF_DEATH_SOURCE_VALUE,YES
+drug_cost,DRUG_COST_ID,NO
+drug_cost,DRUG_EXPOSURE_ID,NO
+drug_cost,PAID_COPAY,YES
+drug_cost,PAID_COINSURANCE,YES
+drug_cost,PAID_TOWARD_DEDUCTIBLE,YES
+drug_cost,PAID_BY_PAYER,YES
+drug_cost,PAID_BY_COORDINATION_BENEFITS,YES
+drug_cost,TOTAL_OUT_OF_POCKET,YES
+drug_cost,TOTAL_PAID,YES
+drug_cost,INGREDIENT_COST,YES
+drug_cost,DISPENSING_FEE,YES
+drug_cost,AVERAGE_WHOLESALE_PRICE,YES
+drug_cost,PAYER_PLAN_PERIOD_ID,YES
+drug_era,DRUG_ERA_ID,NO
+drug_era,PERSON_ID,NO
+drug_era,DRUG_ERA_START_DATE,NO
+drug_era,DRUG_ERA_END_DATE,NO
+drug_era,DRUG_TYPE_CONCEPT_ID,NO
+drug_era,DRUG_CONCEPT_ID,YES
+drug_era,DRUG_EXPOSURE_COUNT,NO
+drug_exposure,DRUG_EXPOSURE_ID,NO
+drug_exposure,PERSON_ID,NO
+drug_exposure,DRUG_CONCEPT_ID,NO
+drug_exposure,DRUG_EXPOSURE_START_DATE,NO
+drug_exposure,DRUG_EXPOSURE_END_DATE,YES
+drug_exposure,DRUG_TYPE_CONCEPT_ID,NO
+drug_exposure,STOP_REASON,YES
+drug_exposure,REFILLS,YES
+drug_exposure,QUANTITY,YES
+drug_exposure,DAYS_SUPPLY,YES
+drug_exposure,SIG,YES
+drug_exposure,PRESCRIBING_PROVIDER_ID,YES
+drug_exposure,VISIT_OCCURRENCE_ID,YES
+drug_exposure,RELEVANT_CONDITION_CONCEPT_ID,YES
+drug_exposure,DRUG_SOURCE_VALUE,YES
+location,LOCATION_ID,NO
+location,ADDRESS_1,YES
+location,ADDRESS_2,YES
+location,CITY,YES
+location,STATE,YES
+location,ZIP,YES
+location,COUNTY,YES
+location,LOCATION_SOURCE_VALUE,YES
+observation,OBSERVATION_ID,NO
+observation,PERSON_ID,NO
+observation,OBSERVATION_CONCEPT_ID,NO
+observation,OBSERVATION_TYPE_CONCEPT_ID,NO
+observation,OBSERVATION_DATE,NO
+observation,OBSERVATION_TIME,YES
+observation,VALUE_AS_NUMBER,YES
+observation,VALUE_AS_STRING,YES
+observation,VALUE_AS_CONCEPT_ID,YES
+observation,UNIT_CONCEPT_ID,YES
+observation,RANGE_LOW,YES
+observation,RANGE_HIGH,YES
+observation,ASSOCIATED_PROVIDER_ID,YES
+observation,VISIT_OCCURRENCE_ID,YES
+observation,OBSERVATION_SOURCE_VALUE,YES
+observation,UNIT_SOURCE_VALUE,YES
+observation,RELEVANT_CONDITION_CONCEPT_ID,YES
+observation_period,OBSERVATION_PERIOD_ID,NO
+observation_period,PERSON_ID,NO
+observation_period,OBSERVATION_PERIOD_START_DATE,NO
+observation_period,OBSERVATION_PERIOD_END_DATE,NO
+organization,ORGANIZATION_ID,NO
+organization,PLACE_OF_SERVICE_CONCEPT_ID,YES
+organization,LOCATION_ID,YES
+organization,ORGANIZATION_SOURCE_VALUE,YES
+organization,PLACE_OF_SERVICE_SOURCE_VALUE,YES
+payer_plan_period,PAYER_PLAN_PERIOD_ID,NO
+payer_plan_period,PERSON_ID,NO
+payer_plan_period,PAYER_PLAN_PERIOD_START_DATE,NO
+payer_plan_period,PAYER_PLAN_PERIOD_END_DATE,NO
+payer_plan_period,PAYER_SOURCE_VALUE,YES
+payer_plan_period,PLAN_SOURCE_VALUE,YES
+payer_plan_period,FAMILY_SOURCE_VALUE,YES
+person,PERSON_ID,NO
+person,GENDER_CONCEPT_ID,NO
+person,YEAR_OF_BIRTH,NO
+person,MONTH_OF_BIRTH,YES
+person,DAY_OF_BIRTH,YES
+person,RACE_CONCEPT_ID,YES
+person,ETHNICITY_CONCEPT_ID,YES
+person,LOCATION_ID,YES
+person,PROVIDER_ID,YES
+person,CARE_SITE_ID,YES
+person,PERSON_SOURCE_VALUE,YES
+person,GENDER_SOURCE_VALUE,YES
+person,RACE_SOURCE_VALUE,YES
+person,ETHNICITY_SOURCE_VALUE,YES
+procedure_cost,PROCEDURE_COST_ID,NO
+procedure_cost,PROCEDURE_OCCURRENCE_ID,NO
+procedure_cost,PAID_COPAY,YES
+procedure_cost,PAID_COINSURANCE,YES
+procedure_cost,PAID_TOWARD_DEDUCTIBLE,YES
+procedure_cost,PAID_BY_PAYER,YES
+procedure_cost,PAID_BY_COORDINATION_BENEFITS,YES
+procedure_cost,TOTAL_OUT_OF_POCKET,YES
+procedure_cost,TOTAL_PAID,YES
+procedure_cost,DISEASE_CLASS_CONCEPT_ID,YES
+procedure_cost,REVENUE_CODE_CONCEPT_ID,YES
+procedure_cost,PAYER_PLAN_PERIOD_ID,YES
+procedure_cost,DISEASE_CLASS_SOURCE_VALUE,YES
+procedure_cost,REVENUE_CODE_SOURCE_VALUE,YES
+procedure_occurrence,PROCEDURE_OCCURRENCE_ID,NO
+procedure_occurrence,PERSON_ID,NO
+procedure_occurrence,PROCEDURE_TYPE_CONCEPT_ID,NO
+procedure_occurrence,PROCEDURE_DATE,NO
+procedure_occurrence,PROCEDURE_CONCEPT_ID,NO
+procedure_occurrence,ASSOCIATED_PROVIDER_ID,YES
+procedure_occurrence,PROCEDURE_SOURCE_VALUE,YES
+procedure_occurrence,VISIT_OCCURRENCE_ID,YES
+procedure_occurrence,RELEVANT_CONDITION_CONCEPT_ID,YES
+provider,PROVIDER_ID,NO
+provider,NPI,YES
+provider,DEA,YES
+provider,SPECIALTY_CONCEPT_ID,YES
+provider,CARE_SITE_ID,YES
+provider,PROVIDER_SOURCE_VALUE,YES
+provider,SPECIALTY_SOURCE_VALUE,YES
+visit_occurrence,VISIT_OCCURRENCE_ID,NO
+visit_occurrence,PERSON_ID,NO
+visit_occurrence,PLACE_OF_SERVICE_CONCEPT_ID,NO
+visit_occurrence,VISIT_START_DATE,NO
+visit_occurrence,VISIT_END_DATE,NO
+visit_occurrence,PLACE_OF_SERVICE_SOURCE_VALUE,YES
+visit_occurrence,CARE_SITE_ID,YES
diff --git a/src/org/ohdsi/whiteRabbit/etls/ars/ARSETL.java b/src/org/ohdsi/whiteRabbit/etls/ars/ARSETL.java
new file mode 100644
index 00000000..085a79ff
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/etls/ars/ARSETL.java
@@ -0,0 +1,661 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.etls.ars;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.ohdsi.databases.RichConnection;
+import org.ohdsi.ooxml.ReadXlsxFileWithHeader;
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.utilities.collections.OneToManyList;
+import org.ohdsi.utilities.files.FileSorter;
+import org.ohdsi.utilities.files.MultiRowIterator;
+import org.ohdsi.utilities.files.MultiRowIterator.MultiRowSet;
+import org.ohdsi.utilities.files.ReadCSVFileWithHeader;
+import org.ohdsi.utilities.files.Row;
+import org.ohdsi.utilities.files.RowUtilities;
+import org.ohdsi.whiteRabbit.DbSettings;
+import org.ohdsi.whiteRabbit.EtlReport;
+import org.ohdsi.whiteRabbit.ObjectExchange;
+import org.ohdsi.whiteRabbit.cdm.CDMV4NullableChecker;
+import org.ohdsi.whiteRabbit.cdm.CdmV4;
+import org.ohdsi.whiteRabbit.utilities.CSVFileChecker;
+import org.ohdsi.whiteRabbit.utilities.CodeToConceptMap;
+import org.ohdsi.whiteRabbit.utilities.ConditionEraGenerator;
+import org.ohdsi.whiteRabbit.utilities.DrugEraGenerator;
+import org.ohdsi.whiteRabbit.utilities.ETLUtils;
+import org.ohdsi.whiteRabbit.utilities.QCSampleConstructor;
+
+public class ARSETL {
+
+ public static String EXTRACTION_DATE = "2012-12-31";
+ public static String MIN_OBSERVATION_DATE = "2003-01-01";
+ public static int MAX_ROWS_PER_PERSON = 100000;
+ public static String[] TABLES = new String[] { "DDRUG", "DRUGS", "EXE", "HOSP", "OUTPAT", "PERSON" };
+ public static int BATCH_SIZE = 100;
+
+ private int personCount;
+ private String folder;
+ private RichConnection connection;
+ private long personId;
+ private long observationPeriodId;
+ private long drugExposureId;
+ private long conditionOccurrenceId;
+ private long visitOccurrenceId;
+ private long procedureOccurrenceId;
+ private long procedureCostId;
+ private long extractionDate;
+ private long minObservationDate;
+ private OneToManyList tableToRows;
+ private CodeToConceptMap atcToConcept;
+ private CodeToConceptMap atcToRxNormConcepts;
+ private Map procToType;
+ private CodeToConceptMap icd9ToConcept;
+ private CodeToConceptMap icd9ProcToConcept;
+ private CodeToConceptMap specialtyToConcept;
+ private Map hospRowToVisitOccurrenceId = new HashMap();
+ private Map outpatRowToVisitOccurrenceId = new HashMap();
+ private Map hospRowToProcedureOccurrenceId = new HashMap();
+ private Set providerIds;
+ private QCSampleConstructor qcSampleConstructor;
+ private EtlReport etlReport;
+ private CDMV4NullableChecker cdmv4NullableChecker = new CDMV4NullableChecker();
+
+ public void process(String folder, DbSettings dbSettings, int maxPersons) {
+ this.folder = folder;
+ extractionDate = StringUtilities.databaseTimeStringToDays(EXTRACTION_DATE);
+ minObservationDate = StringUtilities.databaseTimeStringToDays(MIN_OBSERVATION_DATE);
+ System.out.println("Extraction date is set at " + EXTRACTION_DATE);
+ System.out.println("Minimum observation date is set at " + MIN_OBSERVATION_DATE);
+
+ if (ETLUtils.databaseAlreadyExists(dbSettings))
+ return;
+ // checkTablesForFormattingErrors();
+ // sortTables();
+ CdmV4.createStructure(dbSettings);
+ connection = new RichConnection(dbSettings.server, dbSettings.domain, dbSettings.user, dbSettings.password, dbSettings.dbType);
+ connection.setContext(this.getClass());
+ connection.use(dbSettings.database);
+ loadMappings(dbSettings);
+
+ personCount = 0;
+ personId = 0;
+ observationPeriodId = 0;
+ drugExposureId = 0;
+ conditionOccurrenceId = 0;
+ visitOccurrenceId = 0;
+ procedureOccurrenceId = 0;
+ procedureCostId = 0;
+ providerIds = new HashSet();
+ qcSampleConstructor = new QCSampleConstructor(folder + "/sample");
+ tableToRows = new OneToManyList();
+ etlReport = new EtlReport(folder);
+
+ StringUtilities.outputWithTime("Processing persons");
+ MultiRowIterator iterator = constructMultiRowIterator();
+ while (iterator.hasNext()) {
+ processPerson(iterator.next());
+
+ if (personCount == maxPersons) {
+ System.out.println("Reached limit of " + maxPersons + " persons, terminating");
+ break;
+ }
+ if (personCount % BATCH_SIZE == 0) {
+ insertBatch();
+ System.out.println("Processed " + personCount + " persons");
+ }
+ }
+ insertBatch();
+ System.out.println("Processed " + personCount + " persons");
+ CdmV4.createIndices(dbSettings);
+ qcSampleConstructor.addCdmData(dbSettings, dbSettings);
+ String etlReportName = etlReport.generate(atcToConcept, icd9ProcToConcept, icd9ToConcept, atcToRxNormConcepts, specialtyToConcept);
+ System.out.println("An ETL report was generated and written to :" + etlReportName);
+ if (etlReport.getTotalProblemCount() > 0) {
+ String etlProblemListname = etlReport.generateProblemList();
+ System.out.println("An ETL problem list was generated and written to :" + etlProblemListname);
+ }
+ StringUtilities.outputWithTime("Finished ETL");
+ }
+
+ private void checkTablesForFormattingErrors() {
+ StringUtilities.outputWithTime("Checking tables for formatting errors");
+
+ // for (String table : TABLES) {
+ // StringUtilities.outputWithTime("- Checking " + table);
+ CSVFileChecker checker = new CSVFileChecker();
+ checker.setFrame(ObjectExchange.frame);
+ // checker.checkFile(folder + "/" + table + ".csv");
+ checker.checkSpecifiedFields(folder, new ReadXlsxFileWithHeader(this.getClass().getResourceAsStream("Fields.xlsx")).iterator());
+ // }
+ StringUtilities.outputWithTime("Finished checking tables");
+ }
+
+ private void sortTables() {
+ StringUtilities.outputWithTime("Sorting tables");
+ for (String table : TABLES) {
+ StringUtilities.outputWithTime("- Sorting " + table);
+ FileSorter.sort(folder + "/" + table + ".csv", "PERSON_ID");
+ }
+ StringUtilities.outputWithTime("Finished sorting");
+ }
+
+ private void loadMappings(DbSettings dbSettings) {
+ StringUtilities.outputWithTime("Loading mappings from server");
+ RichConnection connection = new RichConnection(dbSettings.server, dbSettings.domain, dbSettings.user, dbSettings.password, dbSettings.dbType);
+
+ connection.use("vocabulary");
+
+ System.out.println("- Loading ATC to concept_id mapping");
+ atcToConcept = new CodeToConceptMap("ATC to concept_id mapping");
+ String query = "SELECT concept_id,concept_name,concept_code FROM concept WHERE VOCABULARY_ID = 21";
+ for (Row row : connection.query(query))
+ atcToConcept.add(row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"), row.getInt("CONCEPT_ID"), row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"));
+
+ System.out.println("- Loading ICD-9 to concept_id mapping");
+ icd9ToConcept = new CodeToConceptMap("ICD-9 to concept_id mapping");
+ query = "SELECT source_code,source_code_description,target_concept_id,concept_code,concept_name FROM source_to_concept_map INNER JOIN concept ON target_concept_id = concept_id WHERE source_vocabulary_id = 2 AND target_vocabulary_id = 1";
+ for (Row row : connection.query(query)) {
+ icd9ToConcept.add(row.get("SOURCE_CODE"), row.get("SOURCE_CODE_DESCRIPTION"), row.getInt("TARGET_CONCEPT_ID"), row.get("CONCEPT_CODE"),
+ row.get("CONCEPT_NAME"));
+ icd9ToConcept.add(row.get("SOURCE_CODE").replace(".", ""), row.get("SOURCE_CODE_DESCRIPTION"), row.getInt("TARGET_CONCEPT_ID"),
+ row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"));
+ }
+
+ System.out.println("- Loading ICD-9 Procedure to concept_id mapping");
+ icd9ProcToConcept = new CodeToConceptMap("ICD-9 Procedure to concept_id mapping");
+ query = "SELECT concept_id,concept_name,concept_code FROM concept WHERE VOCABULARY_ID = 3";
+ for (Row row : connection.query(query)) {
+ icd9ProcToConcept.add(row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"), row.getInt("CONCEPT_ID"), row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"));
+ icd9ProcToConcept.add(row.get("CONCEPT_CODE").replace(".", ""), row.get("CONCEPT_NAME"), row.getInt("CONCEPT_ID"), row.get("CONCEPT_CODE"),
+ row.get("CONCEPT_NAME"));
+ }
+
+ System.out.println("- Loading ATC to RxNorm concept_id mapping");
+ atcToRxNormConcepts = new CodeToConceptMap("ATC to RxNorm ingredient mapping");
+ for (Row row : new ReadCSVFileWithHeader(this.getClass().getResourceAsStream("AtcToRxNormIngredient.csv")))
+ atcToRxNormConcepts.add(row.get("atc"), row.get("atc_name"), row.getInt("rxnorm_concept_id"), row.get("rxnorm_code"),
+ row.get("rxnorm_concept name"));
+
+ System.out.println("- Loading specialty to concept mapping");
+ specialtyToConcept = new CodeToConceptMap("Specialty to concept mapping");
+ for (Row row : new ReadCSVFileWithHeader(this.getClass().getResourceAsStream("specialty_italian.csv")))
+ specialtyToConcept.add(removeLeadingZeroes(row.get("COD")), row.get("DESCRIZIONE"), row.getInt("CONCEPT_ID"), row.get("CONCEPT_CODE"),
+ row.get("CONCEPT_NAME"));
+
+ System.out.println("- Loading proc_cod to type_outpat mapping");
+ procToType = new HashMap();
+ for (Row row : new ReadCSVFileWithHeader(this.getClass().getResourceAsStream("proc_OUTPAT.csv")))
+ procToType.put(row.get("PROC_COD"), row.get("TYPE_OUTPAT"));
+
+ StringUtilities.outputWithTime("Finished loading mappings");
+ }
+
+ private MultiRowIterator constructMultiRowIterator() {
+ @SuppressWarnings("unchecked")
+ Iterator[] iterators = new Iterator[TABLES.length];
+ for (int i = 0; i < TABLES.length; i++)
+ iterators[i] = new ReadCSVFileWithHeader(folder + "/" + TABLES[i] + ".csv").iterator();
+ return new MultiRowIterator("PERSON_ID", TABLES, iterators);
+ }
+
+ private void processPerson(MultiRowSet personData) {
+ etlReport.registerIncomingData(personData);
+
+ if (personData.linkingId.trim().length() == 0) {
+ for (String table : personData.keySet())
+ if (personData.get(table).size() > 0)
+ etlReport.reportProblem(table, "Missing person_id in " + personData.get(table).size() + " rows in table " + table, "");
+ return;
+ }
+
+ if (personData.totalSize() > MAX_ROWS_PER_PERSON) {
+ etlReport.reportProblem("", "Person has too many rows (" + personData.totalSize() + "). Skipping person", personData.linkingId);
+ return;
+ }
+
+ personCount++;
+ personId++;
+
+ qcSampleConstructor.registerPersonData(personData, personId);
+ fixDateProblem(personData);
+
+ hospRowToVisitOccurrenceId.clear();
+ outpatRowToVisitOccurrenceId.clear();
+ hospRowToProcedureOccurrenceId.clear();
+ addToProvider(personData);
+ addToPerson(personData);
+ addToObservationPeriod(personData);
+ addToDeath(personData);
+ addToVisitOccurrence(personData);
+ addToDrugExposure(personData);
+ addToConditionOccurrence(personData);
+ addToProcedureOccurrence(personData);
+ addToProcedureCost(personData);
+ }
+
+ private void fixDateProblem(MultiRowSet personData) {
+ for (List rows : personData.values())
+ if (rows.size() != 0) {
+ List dateFields = new ArrayList();
+ for (String fieldName : rows.get(0).getFieldNames())
+ if (fieldName.toLowerCase().startsWith("date") || fieldName.toLowerCase().endsWith("date"))
+ dateFields.add(fieldName);
+ for (Row row : rows)
+ for (String fieldName : dateFields) {
+ String value = row.get(fieldName);
+ if (CSVFileChecker.isDateFormat1(value))
+ row.set(fieldName, value.substring(0, 10));
+ }
+ }
+ }
+
+ private void insertBatch() {
+ addToDrugEra();
+ addToConditionEra();
+ removeRowsWithNonNullableNulls();
+
+ etlReport.registerOutgoingData(tableToRows);
+ for (String table : tableToRows.keySet())
+ connection.insertIntoTable(tableToRows.get(table).iterator(), table, false);
+ tableToRows.clear();
+ }
+
+ private void removeRowsWithNonNullableNulls() {
+ for (String table : tableToRows.keySet()) {
+ Iterator iterator = tableToRows.get(table).iterator();
+ while (iterator.hasNext()) {
+ Row row = iterator.next();
+ String nonAllowedNullField = cdmv4NullableChecker.findNonAllowedNull(table, row);
+ if (nonAllowedNullField != null) {
+ if (row.getFieldNames().contains("person_id"))
+ etlReport.reportProblem(table, "Column " + nonAllowedNullField + " is null, could not create row", row.get("person_id"));
+ else
+ etlReport.reportProblem(table, "Column " + nonAllowedNullField + " is null, could not create row", "");
+ iterator.remove();
+ }
+ }
+ }
+ }
+
+ private void addToProvider(MultiRowSet personData) {
+ for (Row row : personData.get("OUTPAT")) {
+ if (row.get("GROUP_CODE").length() > 0) {
+ int providerId = row.getInt("GROUP_CODE"); // Provider ID for outpatient providers is
+ if (providerIds.add(providerId)) { // Did not encounter this group code before
+ int specialtyConceptId = specialtyToConcept.getConceptId(removeLeadingZeroes(row.get("GROUP_CODE")));
+
+ Row provider = new Row();
+ provider.add("provider_id", providerId);
+ provider.add("specialty_concept_id", specialtyConceptId);
+ provider.add("specialty_source_value", row.get("GROUP_CODE"));
+ provider.add("provider_source_value", "");
+ tableToRows.put("provider", provider);
+ }
+ }
+ }
+
+ for (Row row : personData.get("HOSP")) {
+ if (row.get("WARD_DISCHARGE").length() > 0) {
+ int providerId = row.getInt("WARD_DISCHARGE") + 1000; // Provider ID for hosp providers is + 1000;
+ if (providerIds.add(providerId)) { // Did not encounter this specialty code before
+ String specialtyCode = row.get("WARD_DISCHARGE").substring(0, 2);
+ int specialtyConceptId = specialtyToConcept.getConceptId(removeLeadingZeroes(specialtyCode));
+
+ Row provider = new Row();
+ provider.add("provider_id", providerId);
+ provider.add("specialty_concept_id", specialtyConceptId);
+ provider.add("specialty_source_value", specialtyCode);
+ provider.add("provider_source_value", row.get("WARD_DISCHARGE"));
+ tableToRows.put("provider", provider);
+ }
+ }
+ }
+
+ for (Row row : personData.get("PERSON")) {
+ if (row.get("GP_ID").length() != 0) {
+ int providerId = row.getInt("GP_ID") + 100000; // Provider ID for gp providers is + 100000;
+ if (providerIds.add(providerId)) { // Did not encounter this gp_id before
+ Row provider = new Row();
+ provider.add("provider_id", providerId);
+ provider.add("specialty_concept_id", 38004446); // General Practice
+ provider.add("specialty_source_value", "");
+ provider.add("provider_source_value", row.get("GP_ID"));
+ tableToRows.put("provider", provider);
+ }
+ }
+ }
+ }
+
+ private void addToProcedureOccurrence(MultiRowSet personData) {
+ for (Row row : personData.get("HOSP")) {
+ String startDate = row.get("START_DATE");
+ String mainProcDate = row.get("DATE_MAIN_PROC");
+ String providerId = "";
+ if (row.get("WARD_DISCHARGE").length() != 0)
+ providerId = Integer.toString(row.getInt("WARD_DISCHARGE") + 1000); // Provider ID for hosp providers is + 1000;
+ if (mainProcDate.length() == 0)
+ mainProcDate = startDate;
+ Long visitId = hospRowToVisitOccurrenceId.get(row.toString());
+ hospRowToProcedureOccurrenceId.put(row.toString(), procedureOccurrenceId);
+ addHospProcedure(row.get("MAIN_PROC"), mainProcDate, visitId, providerId, 38000248);
+ addHospProcedure(row.get("SECONDARY_PROC_1"), startDate, visitId, providerId, 38000249);
+ addHospProcedure(row.get("SECONDARY_PROC_2"), startDate, visitId, providerId, 38000249);
+ addHospProcedure(row.get("SECONDARY_PROC_3"), startDate, visitId, providerId, 38000249);
+ addHospProcedure(row.get("SECONDARY_PROC_4"), startDate, visitId, providerId, 38000249);
+ addHospProcedure(row.get("SECONDARY_PROC_5"), startDate, visitId, providerId, 38000249);
+ }
+
+ for (Row row : personData.get("OUTPAT")) {
+ String procDate = row.get("PROC_START_DATE");
+ if (procDate.length() == 0)
+ procDate = row.get("PROC_DATE");
+ if (procDate.length() != 0) { // Currently suppressing problems due to missing dates
+ Row procedureOccurrence = new Row();
+ procedureOccurrence.add("procedure_occurrence_id", procedureOccurrenceId++);
+ procedureOccurrence.add("person_id", personId);
+ procedureOccurrence.add("procedure_concept_id", 0);
+ procedureOccurrence.add("procedure_date", procDate);
+ procedureOccurrence.add("procedure_type_concept_id", 38000266);
+ Long visitId = outpatRowToVisitOccurrenceId.get(row.toString());
+ procedureOccurrence.add("visit_occurrence_id", (visitId == null ? "" : visitId.toString()));
+ procedureOccurrence.add("procedure_source_value", row.get("PROC_COD"));
+ procedureOccurrence.add("associated_provider_id", row.get("GROUP_CODE")); // Provider ID for outpatient providers is
+ tableToRows.put("procedure_occurrence", procedureOccurrence);
+ }
+ }
+ }
+
+ private void addToProcedureCost(MultiRowSet personData) {
+ for (Row row : personData.get("HOSP"))
+ if (row.get("DRG").length() != 0) {
+ Row procedureCost = new Row();
+ procedureCost.add("procedure_cost_id", procedureCostId++);
+ Long procedureOccurrenceId = hospRowToProcedureOccurrenceId.get(row.toString());
+ procedureCost.add("procedure_occurrence_id", (procedureOccurrenceId == null ? "" : procedureOccurrenceId.toString()));
+ procedureCost.add("disease_class_source_value", row.get("DRG"));
+ tableToRows.put("procedure_cost", procedureCost);
+ }
+ }
+
+ private void addHospProcedure(String proc, String date, Long visitId, String providerId, int procedureTypeConceptId) {
+ proc = proc.trim();
+ if (proc.length() != 0) {
+ Row procedureOccurrence = new Row();
+ procedureOccurrence.add("procedure_occurrence_id", procedureOccurrenceId++);
+ procedureOccurrence.add("person_id", personId);
+ procedureOccurrence.add("procedure_concept_id", icd9ProcToConcept.getConceptId(proc));
+ procedureOccurrence.add("procedure_date", date);
+ procedureOccurrence.add("procedure_type_concept_id", procedureTypeConceptId);
+ procedureOccurrence.add("visit_occurrence_id", visitId);
+ procedureOccurrence.add("procedure_source_value", proc);
+ procedureOccurrence.add("associated_provider_id", providerId);
+ tableToRows.put("procedure_occurrence", procedureOccurrence);
+ }
+ }
+
+ private void addToVisitOccurrence(MultiRowSet personData) {
+ for (Row row : personData.get("HOSP")) {
+ hospRowToVisitOccurrenceId.put(row.toString(), visitOccurrenceId);
+
+ Row visitOccurrence = new Row();
+ visitOccurrence.add("visit_occurrence_id", visitOccurrenceId++);
+ visitOccurrence.add("person_id", personId);
+ visitOccurrence.add("visit_start_date", row.get("START_DATE"));
+ if (row.get("END_DATE").length() == 0)
+ visitOccurrence.add("visit_end_date", row.get("START_DATE"));
+ else
+ visitOccurrence.add("visit_end_date", row.get("END_DATE"));
+ visitOccurrence.add("place_of_service_concept_id", 9201); // Inpatient visit
+ tableToRows.put("visit_occurrence", visitOccurrence);
+ }
+
+ for (Row row : personData.get("OUTPAT")) {
+ String type = procToType.get(row.get("PROC_COD"));
+ if (type != null && type.equals("CLIN")) {
+ outpatRowToVisitOccurrenceId.put(row.toString(), visitOccurrenceId);
+
+ Row visitOccurrence = new Row();
+ visitOccurrence.add("visit_occurrence_id", visitOccurrenceId++);
+ visitOccurrence.add("person_id", personId);
+ visitOccurrence.add("visit_start_date", row.get("PROC_START_DATE"));
+ if (row.get("PROC_END_DATE").length() == 0)
+ visitOccurrence.add("visit_end_date", row.get("PROC_START_DATE"));
+ else
+ visitOccurrence.add("visit_end_date", row.get("PROC_END_DATE"));
+ visitOccurrence.add("place_of_service_concept_id", 9202); // Outpatient visit
+ tableToRows.put("visit_occurrence", visitOccurrence);
+ }
+ }
+ }
+
+ private void addToConditionOccurrence(MultiRowSet personData) {
+ for (Row row : personData.get("HOSP")) {
+ String startDate = row.get("START_DATE");
+ Long visitId = hospRowToVisitOccurrenceId.get(row.toString());
+ String providerId = "";
+ if (row.get("WARD_DISCHARGE").length() != 0)
+ providerId = Integer.toString(row.getInt("WARD_DISCHARGE") + 1000); // Provider ID for hosp providers is + 1000;
+ addHospCondition(startDate, row.get("MAIN_DIAGNOSIS"), visitId, providerId, 38000183); // Inpatient detail, primary
+ addHospCondition(startDate, row.get("SECONDARY_DIAGNOSIS_1"), visitId, providerId, 38000184); // Inpatient detail - 1st position
+ addHospCondition(startDate, row.get("SECONDARY_DIAGNOSIS_2"), visitId, providerId, 38000185); // Inpatient detail - 2st position
+ addHospCondition(startDate, row.get("SECONDARY_DIAGNOSIS_3"), visitId, providerId, 38000186); // Inpatient detail - 3st position
+ addHospCondition(startDate, row.get("SECONDARY_DIAGNOSIS_4"), visitId, providerId, 38000187); // Inpatient detail - 4st position
+ addHospCondition(startDate, row.get("SECONDARY_DIAGNOSIS_5"), visitId, providerId, 38000188); // Inpatient detail - 5st position
+ }
+
+ for (Row row : personData.get("EXE")) {
+ Row conditionOccurrence = new Row();
+ conditionOccurrence.add("condition_occurrence_id", conditionOccurrenceId++);
+ conditionOccurrence.add("person_id", personId);
+ conditionOccurrence.add("condition_concept_id", icd9ToConcept.getConceptId(row.get("EXEMPTION_CODE")));
+ conditionOccurrence.add("condition_start_date", row.get("EXE_START_DATE"));
+ conditionOccurrence.add("condition_type_concept_id", 38000245);
+ conditionOccurrence.add("visit_occurrence_id", "");
+ conditionOccurrence.add("condition_source_value", row.get("EXEMPTION_CODE"));
+ conditionOccurrence.add("associated_provider_id", "");
+ tableToRows.put("condition_occurrence", conditionOccurrence);
+ }
+ }
+
+ private void addToConditionEra() {
+ ConditionEraGenerator conditionEraGenerator = new ConditionEraGenerator();
+ for (Row row : tableToRows.get("condition_occurrence")) {
+ int personId = row.getInt("person_id");
+ long startDate = StringUtilities.databaseTimeStringToDays(row.get("condition_start_date"));
+ long endDate = StringUtilities.MISSING_DATE;
+ int conceptId = row.getInt("condition_concept_id");
+ conditionEraGenerator.addCondition(personId, startDate, endDate, conceptId);
+ }
+
+ tableToRows.putAll("condition_era", conditionEraGenerator.generateRows());
+ }
+
+ private void addHospCondition(String startDate, String diagnose, Long visitId, String providerId, int typeConceptId) {
+ diagnose = diagnose.trim();
+ if (diagnose.length() != 0) {
+ Row conditionOccurrence = new Row();
+ conditionOccurrence.add("condition_occurrence_id", conditionOccurrenceId++);
+ conditionOccurrence.add("person_id", personId);
+ conditionOccurrence.add("condition_concept_id", icd9ToConcept.getConceptId(diagnose));
+ conditionOccurrence.add("condition_start_date", startDate);
+ conditionOccurrence.add("condition_type_concept_id", typeConceptId);
+ conditionOccurrence.add("visit_occurrence_id", visitId);
+ conditionOccurrence.add("condition_source_value", diagnose);
+ conditionOccurrence.add("associated_provider_id", providerId);
+ tableToRows.put("condition_occurrence", conditionOccurrence);
+ }
+ }
+
+ private void addToDrugExposure(MultiRowSet personData) {
+ for (Row row : personData.get("DRUGS")) {
+ Row drugExposure = new Row();
+ drugExposure.add("drug_exposure_id", drugExposureId++);
+ drugExposure.add("person_id", personId);
+ drugExposure.add("drug_concept_id", atcToConcept.getConceptId(row.get("ATC")));
+ drugExposure.add("drug_exposure_start_date", row.get("DRUG_DISPENSING_DATE"));
+ drugExposure.add("days_supply", row.get("DURATION"));
+ drugExposure.add("drug_type_concept_id", 38000175);
+ drugExposure.add("drug_source_value", row.get("PRODUCT_CODE"));
+ drugExposure.add("atc", row.get("ATC")); // Store temporarily for drug era
+ tableToRows.put("drug_exposure", drugExposure);
+ }
+
+ for (Row row : personData.get("DDRUG")) {
+ Row drugExposure = new Row();
+ drugExposure.add("drug_exposure_id", drugExposureId++);
+ drugExposure.add("person_id", personId);
+ drugExposure.add("drug_concept_id", atcToConcept.getConceptId(row.get("ATC")));
+ drugExposure.add("drug_exposure_start_date", row.get("DRUG_DISPENSING_DATE"));
+ drugExposure.add("days_supply", row.get("DURATION"));
+ drugExposure.add("drug_type_concept_id", 38000175);
+ drugExposure.add("drug_source_value", row.get("PRODUCT_CODE"));
+ drugExposure.add("atc", row.get("ATC")); // Store temporarily for drug era
+ tableToRows.put("drug_exposure", drugExposure);
+ }
+ }
+
+ private void addToDrugEra() {
+ DrugEraGenerator drugEraGenerator = new DrugEraGenerator();
+ for (Row row : tableToRows.get("drug_exposure")) {
+ int personId = row.getInt("person_id");
+ long startDate = StringUtilities.databaseTimeStringToDays(row.get("drug_exposure_start_date"));
+ long endDate = startDate + Math.round(parseZeroIfEmpty(row.get("days_supply")));
+ for (int conceptId : atcToRxNormConcepts.getConceptIds(row.get("atc")))
+ drugEraGenerator.addExposure(personId, startDate, endDate, conceptId);
+ row.remove("atc");
+ }
+
+ tableToRows.putAll("drug_era", drugEraGenerator.generateRows());
+ }
+
+ private void addToDeath(MultiRowSet personData) {
+ for (Row row : personData.get("PERSON")) {
+ if (row.get("DATE_OF_DEATH").trim().length() != 0) {
+ Row death = new Row();
+ death.add("person_id", personId);
+ death.add("death_type_concept_id", 38003565);
+ death.add("death_date", row.get("DATE_OF_DEATH"));
+ tableToRows.put("death", death);
+ }
+ }
+ }
+
+ private void addToObservationPeriod(MultiRowSet personData) {
+ List rows = personData.get("PERSON");
+ if (rows.size() == 0)
+ return;
+
+ RowUtilities.sort(rows, "STARTDATE");
+ long observationPeriodStartDate = Long.MIN_VALUE;
+ long observationPeriodEndDate = Long.MIN_VALUE;
+ for (Row row : rows) {
+ if (row.get("STARTDATE").length() == 0) {
+ etlReport.reportProblem("PERSON", "No person startdate, could not create observation period", row.get("PERSON_ID"));
+ continue;
+ }
+ long startDate = StringUtilities.databaseTimeStringToDays(row.get("STARTDATE"));
+ startDate = Math.max(startDate, minObservationDate);
+ long endDate = StringUtilities.databaseTimeStringToDays(row.get("ENDDATE"));
+ endDate = endDate == StringUtilities.MISSING_DATE ? extractionDate : Math.min(endDate, extractionDate);
+ if (observationPeriodEndDate == startDate - 1) {
+ observationPeriodEndDate = endDate;
+ } else {
+ if (observationPeriodStartDate != Long.MIN_VALUE && observationPeriodStartDate < observationPeriodEndDate) {
+ Row observationPeriod = new Row();
+ observationPeriod.add("observation_period_id", observationPeriodId++);
+ observationPeriod.add("person_id", personId);
+ observationPeriod.add("observation_period_start_date", StringUtilities.daysToDatabaseDateString(observationPeriodStartDate));
+ observationPeriod.add("observation_period_end_date", StringUtilities.daysToDatabaseDateString(observationPeriodEndDate));
+ tableToRows.put("observation_period", observationPeriod);
+ }
+ observationPeriodStartDate = startDate;
+ observationPeriodEndDate = endDate;
+
+ }
+ }
+ if (observationPeriodStartDate != Long.MIN_VALUE && observationPeriodStartDate < observationPeriodEndDate) {
+ Row observationPeriod = new Row();
+ observationPeriod.add("observation_period_id", observationPeriodId++);
+ observationPeriod.add("person_id", personId);
+ observationPeriod.add("observation_period_start_date", StringUtilities.daysToDatabaseDateString(observationPeriodStartDate));
+ observationPeriod.add("observation_period_end_date", StringUtilities.daysToDatabaseDateString(observationPeriodEndDate));
+ tableToRows.put("observation_period", observationPeriod);
+ }
+ }
+
+ private void addToPerson(MultiRowSet personData) {
+ List rows = personData.get("PERSON");
+ if (rows.size() == 0)
+ return;
+
+ Row row = rows.get(0);
+ if (rows.size() > 1) { // Multiple rows: find the one with the latest startdate:
+ RowUtilities.sort(rows, "STARTDATE");
+ row = rows.get(rows.size() - 1);
+ }
+
+ Row person = new Row();
+ person.add("person_id", personId);
+ person.add("person_source_value", row.get("PERSON_ID"));
+ String gender = row.get("GENDER_CONCEPT_ID");
+ person.add("gender_source_value", gender);
+ person.add("gender_concept_id", gender.toLowerCase().equals("m") || gender.toLowerCase().equals("1") ? "8507" : gender.toLowerCase().equals("f")
+ || gender.toLowerCase().equals("2") ? "8532" : "8521");
+ String dateOfBirth = row.get("DATE_OF_BIRTH");
+
+ if (dateOfBirth.length() < 10) {
+ person.add("year_of_birth", "");
+ person.add("month_of_birth", "");
+ person.add("day_of_birth", "");
+ } else {
+ person.add("year_of_birth", dateOfBirth.substring(0, 4));
+ person.add("month_of_birth", dateOfBirth.substring(5, 7));
+ person.add("day_of_birth", dateOfBirth.substring(8, 10));
+ }
+ if (row.get("GP_ID").length() != 0)
+ person.add("provider_id", row.getInt("GP_ID") + 100000);// Provider ID for gp providers is + 100000;
+ else
+ person.add("provider_id", "");
+ person.add("location_id", row.get("LOCATION_CONCEPT_ID"));
+ tableToRows.put("person", person);
+ }
+
+ private double parseZeroIfEmpty(String number) {
+ if (number.length() == 0)
+ return 0;
+ else
+ return Double.parseDouble(number);
+ }
+
+ private String removeLeadingZeroes(String string) {
+ for (int i = 0; i < string.length(); i++)
+ if (string.charAt(i) != '0')
+ return string.substring(i);
+ return string;
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/etls/ars/AddExtraInfoToAtcToRxNormMap.java b/src/org/ohdsi/whiteRabbit/etls/ars/AddExtraInfoToAtcToRxNormMap.java
new file mode 100644
index 00000000..faae0984
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/etls/ars/AddExtraInfoToAtcToRxNormMap.java
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.etls.ars;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.ohdsi.databases.DbType;
+import org.ohdsi.databases.RichConnection;
+import org.ohdsi.utilities.files.ReadCSVFileWithHeader;
+import org.ohdsi.utilities.files.Row;
+import org.ohdsi.utilities.files.WriteCSVFileWithHeader;
+
+public class AddExtraInfoToAtcToRxNormMap {
+
+ public static void main(String[] args) {
+ RichConnection connection = new RichConnection("RNDUSRDHIT06", null, null, null, DbType.MSSQL);
+ connection.setContext(AddExtraInfoToAtcToRxNormMap.class);
+ connection.use("OMOP_Vocabulary");
+
+ Map atcToConceptId = new HashMap();
+ Map conceptIdToRxNormCode = new HashMap();
+
+ String query = "SELECT concept_id,concept_name,concept_code FROM concept WHERE VOCABULARY_ID = 21";
+ for (Row row : connection.query(query))
+ atcToConceptId.put(row.get("CONCEPT_CODE"), row.getInt("CONCEPT_ID"));
+
+ query = "SELECT concept_id,concept_name,concept_code FROM concept WHERE VOCABULARY_ID = 8";
+ for (Row row : connection.query(query))
+ conceptIdToRxNormCode.put(row.getInt("CONCEPT_ID"),row.get("CONCEPT_CODE"));
+
+ WriteCSVFileWithHeader out = new WriteCSVFileWithHeader("c:/temp/AtcToRxNormIngredient.csv");
+ for (Row row : new ReadCSVFileWithHeader(AddExtraInfoToAtcToRxNormMap.class.getResourceAsStream("ATCToConceptID.csv"))){
+ Integer atcConceptId = atcToConceptId.get(row.get("ATC"));
+ if (atcConceptId == null)
+ atcConceptId = 0;
+ String rxNormCode = conceptIdToRxNormCode.get(row.getInt("ConceptID"));
+ if (rxNormCode == null)
+ rxNormCode = "";
+ row.add("atc_concept_id", atcConceptId);
+ row.add("rxnorm_code", rxNormCode);
+ out.write(row);
+ }
+ out.close();
+ }
+
+}
diff --git a/src/org/ohdsi/whiteRabbit/etls/ars/AtcToRxNormIngredient.csv b/src/org/ohdsi/whiteRabbit/etls/ars/AtcToRxNormIngredient.csv
new file mode 100644
index 00000000..a362bbf5
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/etls/ars/AtcToRxNormIngredient.csv
@@ -0,0 +1,3285 @@
+atc,atc_name,rxnorm_concept_id,rxnorm_concept name,atc_concept_id,rxnorm_code
+A01AA,CARIES PROPHYLACTIC AGENTS,19035704,Calcium Carbonate,21600004,1897
+A01AA,CARIES PROPHYLACTIC AGENTS,19068715,monofluorophosphate,21600004,52885
+A01AA01,SODIUM FLUORIDE,19069022,Sodium Fluoride,21600005,9873
+A01AA04,STANNOUS FLUORIDE,1036094,Stannous Fluoride,21600008,10030
+A01AA51,"SODIUM FLUORIDE, COMBINATIONS",927322,potassium nitrate,21600010,34316
+A01AA51,"SODIUM FLUORIDE, COMBINATIONS",19035704,Calcium Carbonate,21600010,1897
+A01AA51,"SODIUM FLUORIDE, COMBINATIONS",19069022,Sodium Fluoride,21600010,9873
+A01AB02,HYDROGEN PEROXIDE,1776430,Hydrogen Peroxide,21600012,5499
+A01AB03,CHLORHEXIDINE,1790812,Chlorhexidine,21600013,2358
+A01AB04,AMPHOTERICIN B,1717240,Amphotericin B,21600014,732
+A01AB11,VARIOUS,991706,SULFONATED PHENOL,21600021,236718
+A01AB11,VARIOUS,1036600,Sulfuric acid,21600021,10231
+A01AB11,VARIOUS,1750087,Povidone-Iodine,21600021,8611
+A01AB18,CLOTRIMAZOLE,1000632,Clotrimazole,21600028,2623
+A01AB22,DOXYCYCLINE,1738521,Doxycycline,21600031,3640
+A01AB23,MINOCYCLINE,1708880,Minocycline,21600032,6980
+A01AC01,TRIAMCINOLONE,903963,Triamcinolone,21600034,10759
+A01AD07,AMLEXANOX,957623,amlexanox,21600043,46307
+A01AD11,VARIOUS,906914,Urea,21600045,11002
+A01AD11,VARIOUS,916460,Benzalkonium,21600045,1378
+A01AD11,VARIOUS,917006,Benzocaine,21600045,1399
+A01AD11,VARIOUS,919681,Benzyl Alcohol,21600045,1426
+A01AD11,VARIOUS,942494,chlorophyllin copper complex,21600045,82242
+A01AD11,VARIOUS,958999,carbamide peroxide,21600045,47686
+A01AD11,VARIOUS,961145,Glycerin,21600045,4910
+A01AD11,VARIOUS,989301,Cetylpyridinium,21600045,2286
+A01AD11,VARIOUS,19044317,zinc chloride,21600045,39937
+A02AA01,MAGNESIUM CARBONATE,908464,magnesium carbonate,21600049,29155
+A02AA04,MAGNESIUM HYDROXIDE,992956,Magnesium Hydroxide,21600052,6581
+A02AA05,MAGNESIUM SILICATE,908730,magnesium trisilicate,21600053,29170
+A02AB,ALUMINIUM COMPOUNDS,934431,basic aluminum carbonate gel,21600055,18789
+A02AB,ALUMINIUM COMPOUNDS,959420,Aluminum carbonate,21600055,89858
+A02AB01,ALUMINIUM HYDROXIDE,985247,Aluminum Hydroxide,21600056,612
+A02AB03,ALUMINIUM PHOSPHATE,19030675,aluminum phosphate,21600058,17618
+A02AB04,DIHYDROXIALUMINI SODIUM CARBONATE,989727,dihydroxyaluminum sodium carbonate,21600059,23163
+A02AC,CALCIUM COMPOUNDS,1337159,Calcium Glycerophosphate,21600064,1909
+A02AC01,CALCIUM CARBONATE,1516800,Risedronate,21600065,73056
+A02AC01,CALCIUM CARBONATE,19035704,Calcium Carbonate,21600065,1897
+A02AD01,ORDINARY SALT COMBINATIONS,908464,magnesium carbonate,21600069,29155
+A02AD01,ORDINARY SALT COMBINATIONS,985247,Aluminum Hydroxide,21600069,612
+A02AD01,ORDINARY SALT COMBINATIONS,992956,Magnesium Hydroxide,21600069,6581
+A02AD01,ORDINARY SALT COMBINATIONS,19035704,Calcium Carbonate,21600069,1897
+A02AD02,MAGALDRATE,908360,magaldrate,21600070,29151
+A02AF01,MAGALDRATE AND ANTIFLATULENTS,908360,magaldrate,21600075,29151
+A02AF01,MAGALDRATE AND ANTIFLATULENTS,966991,Simethicone,21600075,9796
+A02AF02,ORDINARY SALT COMBINATIONS AND ANTIFLATULENTS,966991,Simethicone,21600076,9796
+A02AF02,ORDINARY SALT COMBINATIONS AND ANTIFLATULENTS,985247,Aluminum Hydroxide,21600076,612
+A02AF02,ORDINARY SALT COMBINATIONS AND ANTIFLATULENTS,992956,Magnesium Hydroxide,21600076,6581
+A02AF02,ORDINARY SALT COMBINATIONS AND ANTIFLATULENTS,1701928,Activated Charcoal,21600076,272
+A02AF02,ORDINARY SALT COMBINATIONS AND ANTIFLATULENTS,19035704,Calcium Carbonate,21600076,1897
+A02AH,ANTACIDS WITH SODIUM BICARBONATE,939506,Sodium Bicarbonate,21600078,36676
+A02AX,"ANTACIDS, OTHER COMBINATIONS",939506,Sodium Bicarbonate,21600079,36676
+A02AX,"ANTACIDS, OTHER COMBINATIONS",962398,Glycine,21600079,4919
+A02AX,"ANTACIDS, OTHER COMBINATIONS",19027080,potassium bicarbonate,21600079,34296
+A02AX,"ANTACIDS, OTHER COMBINATIONS",19035704,Calcium Carbonate,21600079,1897
+A02BA01,CIMETIDINE,997276,Cimetidine,21600082,2541
+A02BA02,RANITIDINE,961047,Ranitidine,21600083,9143
+A02BA03,FAMOTIDINE,953076,Famotidine,21600084,4278
+A02BA04,NIZATIDINE,950696,Nizatidine,21600085,42319
+A02BA07,RANITIDINE BISMUTH CITRATE,961047,Ranitidine,21600088,9143
+A02BA53,"FAMOTIDINE, COMBINATIONS",953076,Famotidine,21600091,4278
+A02BA53,"FAMOTIDINE, COMBINATIONS",992956,Magnesium Hydroxide,21600091,6581
+A02BA53,"FAMOTIDINE, COMBINATIONS",19035704,Calcium Carbonate,21600091,1897
+A02BB01,MISOPROSTOL,1150871,Misoprostol,21600093,42331
+A02BC,PROTON PUMP INHIBITORS,19039926,dexlansoprazole,21600095,816346
+A02BC01,OMEPRAZOLE,923645,Omeprazole,21600096,7646
+A02BC01,OMEPRAZOLE,939506,Sodium Bicarbonate,21600096,36676
+A02BC02,PANTOPRAZOLE,948078,pantoprazole,21600097,40790
+A02BC03,LANSOPRAZOLE,929887,lansoprazole,21600098,17128
+A02BC03,LANSOPRAZOLE,1115008,Naproxen,21600098,7258
+A02BC03,LANSOPRAZOLE,1713332,Amoxicillin,21600098,723
+A02BC03,LANSOPRAZOLE,1750500,Clarithromycin,21600098,21212
+A02BC05,ESOMEPRAZOLE,904453,Esomeprazole,21600100,283742
+A02BD07,"LANSOPRAZOLE, AMOXICILLIN AND CLARITHROMYCIN",929887,lansoprazole,21600108,17128
+A02BD07,"LANSOPRAZOLE, AMOXICILLIN AND CLARITHROMYCIN",1713332,Amoxicillin,21600108,723
+A02BD07,"LANSOPRAZOLE, AMOXICILLIN AND CLARITHROMYCIN",1750500,Clarithromycin,21600108,21212
+A02BX02,SUCRALFATE,1036228,Sucralfate,21600111,10156
+A02BX13,ALGINIC ACID,908464,magnesium carbonate,21600122,29155
+A02BX13,ALGINIC ACID,985247,Aluminum Hydroxide,21600122,612
+A03AA01,OXYPHENCYCLIMINE,19019094,oxyphencyclimine,21600130,32698
+A03AA07,DICYCLOVERINE,734275,Phenobarbital,21600135,8134
+A03AA07,DICYCLOVERINE,924724,Dicyclomine,21600135,3361
+A03AB,"SYNTH ANTICHOLINERGICS,QUATERNARY AMMONIUM CMPDS",950792,clidinium,21600139,21232
+A03AB02,GLYCOPYRRONIUM,963353,Glycopyrrolate,21600141,4955
+A03AB03,OXYPHENONIUM,19025928,Oxyphenonium,21600142,7818
+A03AB05,PROPANTHELINE,953391,Propantheline,21600144,8761
+A03AB07,METHANTHELINE,19004153,methantheline,21600146,6821
+A03AB08,TRIDIHEXETHYL,19042695,tridihexethyl,21600147,38617
+A03AB09,ISOPROPAMIDE,19058613,Isopropamide,21600148,89784
+A03AB10,HEXOCYCLIUM,19001653,hexocyclium,21600149,26867
+A03AB12,MEPENZOLATE,904704,Mepenzolate,21600151,107770
+A03AB15,DIPHEMANIL,19135822,Diphemanil,21600154,89782
+A03AD01,PAPAVERINE,1326901,Papaverine,21600166,7895
+A03AE01,ALOSETRON,948555,alosetron,21600170,85248
+A03AE02,TEGASEROD,916943,tegaserod,21600171,139778
+A03AX13,SILICONES,966991,Simethicone,21600187,9796
+A03BA,"BELLADONNA ALKALOIDS, TERTIARY AMINES",914335,Atropine,21600191,1223
+A03BA,"BELLADONNA ALKALOIDS, TERTIARY AMINES",923672,Hyoscyamine,21600191,153970
+A03BA,"BELLADONNA ALKALOIDS, TERTIARY AMINES",965748,Scopolamine,21600191,9601
+A03BA01,ATROPINE,914335,Atropine,21600192,1223
+A03BA03,HYOSCYAMINE,923672,Hyoscyamine,21600193,153970
+A03BA04,BELLADONNA TOTAL ALKALOIDS,1116109,Belladonna Alkaloids,21600194,1359
+A03BB03,METHYLSCOPOLAMINE,1158632,Methscopolamine,21600198,89785
+A03CA01,ISOPROPAMIDE AND PSYCHOLEPTICS,752061,Prochlorperazine,21600203,8704
+A03CA01,ISOPROPAMIDE AND PSYCHOLEPTICS,19058613,Isopropamide,21600203,89784
+A03CA02,CLIDINIUM AND PSYCHOLEPTICS,950792,clidinium,21600204,21232
+A03CA02,CLIDINIUM AND PSYCHOLEPTICS,990678,Chlordiazepoxide,21600204,2356
+A03CA02,CLIDINIUM AND PSYCHOLEPTICS,1158632,Methscopolamine,21600204,89785
+C01AA04,DIGITOXIN,19026180,Digitoxin,21600233,3403
+C01AA05,DIGOXIN,1326303,Digoxin,21600234,3407
+C01AA07,DESLANOSIDE,19017074,Deslanoside,21600236,3248
+C01AC01,G-STROPHANTHIN,19129640,Ouabain,21600244,7762
+C01BA02,PROCAINAMIDE,1351461,Procainamide,21600251,8700
+C01BA03,DISOPYRAMIDE,1335606,Disopyramide,21600252,3541
+C01BB01,LIDOCAINE,989878,Lidocaine,21600260,6387
+C01BB02,MEXILETINE,1307542,Mexiletine,21600261,6926
+C01BB03,TOCAINIDE,1351447,Tocainide,21600262,42359
+C01BC03,PROPAFENONE,1353256,Propafenone,21600265,8754
+C01BC04,FLECAINIDE,1354860,Flecainide,21600266,4441
+C01BC08,ENCAINIDE,19051513,Encainide,21600268,42368
+C01BD01,AMIODARONE,1309944,Amiodarone,21600270,703
+C01BD02,BRETYLIUM TOSILATE,19038998,bretylium,21600271,19685
+C01BD04,DOFETILIDE,1362979,dofetilide,21600273,49247
+C01BD05,IBUTILIDE,19050087,ibutilide,21600274,41289
+C01BG01,MORACIZINE,1344996,Moricizine,21600277,40169
+C01CA02,ISOPRENALINE,1183554,Isoproterenol,21600282,6054
+C01CA03,NOREPINEPHRINE,1321341,Norepinephrine,21600283,7512
+C01CA04,DOPAMINE,1337860,Dopamine,21600284,3628
+C01CA06,PHENYLEPHRINE,1135766,Phenylephrine,21600286,8163
+C01CA07,DOBUTAMINE,1337720,Dobutamine,21600287,3616
+C01CA09,METARAMINOL,19003303,Metaraminol,21600289,6805
+C01CA10,METHOXAMINE,19005208,Methoxamine,21600290,6853
+C01CA11,MEPHENTERMINE,19002664,Mephentermine,21600291,6756
+C01CA17,MIDODRINE,1308368,Midodrine,21600297,6963
+C01CA19,FENOLDOPAM,19095721,Fenoldopam,21600299,24853
+C01CA22,ARBUTAMINE,19086330,arbutamine,21600301,61609
+C01CA24,EPINEPHRINE,1192710,Chlorpheniramine,21600303,2400
+C01CA24,EPINEPHRINE,1343916,Epinephrine,21600303,3992
+C01CE01,AMRINONE,19017805,Inamrinone,21600307,738
+C01CE02,MILRINONE,1368671,Milrinone,21600308,52769
+C01DA02,GLYCERYL TRINITRATE,1361711,Nitroglycerin,21600317,4917
+C01DA05,PENTAERITHRITYL TETRANITRATE,19022446,pentaerythritol,21600319,33055
+C01DA08,ISOSORBIDE DINITRATE,1383925,Isosorbide Dinitrate,21600321,6058
+C01DA13,ERYTRITYL TETRANITRATE,19045644,Erythrityl Tetranitrate,21600323,4040
+C01DA14,ISOSORBIDE MONONITRATE,1383815,Isosorbide,21600324,6057
+C01DA55,"PENTAERITHRITYL TETRANITRATE, COMBINATIONS",734275,Phenobarbital,21600329,8134
+C01DA55,"PENTAERITHRITYL TETRANITRATE, COMBINATIONS",19022446,pentaerythritol,21600329,33055
+C01DB01,FLOSEQUINAN,19096489,flosequinan,21600336,25089
+C01DX19,NESIRITIDE,1338985,Brain natriuretic peptide,21600355,19666
+C01EA01,ALPROSTADIL,1381504,Alprostadil,21600362,598
+C01EB,OTHER CARDIAC PREPARATIONS,1351115,coenzyme Q10,21600363,21406
+C01EB,OTHER CARDIAC PREPARATIONS,1389885,red yeast rice,21600363,232540
+C01EB03,INDOMETACIN,1178663,Indomethacin,21600365,5781
+C01EB04,CRATAEGUS GLYCOSIDES,1324250,Hawthorn preparation,21600366,155097
+C01EB04,CRATAEGUS GLYCOSIDES,1401437,Garlic preparation,21600366,265647
+C01EB09,UBIDECARENONE,1306837,Ubiquinone,21600370,10975
+C01EB09,UBIDECARENONE,1351115,coenzyme Q10,21600370,21406
+C01EB09,UBIDECARENONE,19101786,ubiquinol,21600370,39085
+C01EB10,ADENOSINE,1309204,Adenosine,21600371,296
+C01EB10,ADENOSINE,19015230,Adenosine Triphosphate,21600371,318
+C01EB16,IBUPROFEN,1177480,Ibuprofen,21600375,5640
+C01EB18,RANOLAZINE,1337107,ranolazine,21600377,35829
+C01EB21,REGADENOSON,19090761,regadenoson,21600379,640062
+C01EX,OTHER CARDIAC COMBINATION PRODUCTS,1351115,coenzyme Q10,21600380,21406
+C01EX,OTHER CARDIAC COMBINATION PRODUCTS,1373928,Hydralazine,21600380,5470
+C01EX,OTHER CARDIAC COMBINATION PRODUCTS,1383925,Isosorbide Dinitrate,21600380,6058
+C01EX,OTHER CARDIAC COMBINATION PRODUCTS,1553610,Levocarnitine,21600380,42955
+C01EX,OTHER CARDIAC COMBINATION PRODUCTS,19009540,Vitamin E,21600380,11256
+C01EX,OTHER CARDIAC COMBINATION PRODUCTS,19062817,Riboflavin,21600380,9346
+C02AA01,RESCINNAMINE,19062195,rescinnamine,21600384,9259
+C02AA02,RESERPINE,1362225,Reserpine,21600385,9260
+C02AA04,"RAUWOLFIA ALKALOIDS, WHOLE ROOT",1326378,Rauwolfia preparation,21600387,78678
+C02AA05,DESERPIDINE,1387219,deserpidine,21600388,62174
+C02AB01,METHYLDOPA (LEVOROTATORY),1305447,Methyldopa,21600395,6876
+C02AB01,METHYLDOPA (LEVOROTATORY),1305496,Methyldopate,21600395,6877
+C02AC,IMIDAZOLINE RECEPTOR AGONISTS,1366237,Guanabenz,21600397,5033
+C02AC01,CLONIDINE,1398937,Clonidine,21600398,2599
+C02AC02,GUANFACINE,1344965,Guanfacine,21600399,40114
+C02BA01,TRIMETAPHAN,19005658,Trimethaphan,21600405,10828
+C02BB01,MECAMYLAMINE,1394333,Mecamylamine,21600407,6673
+C02CA01,PRAZOSIN,1350489,Prazosin,21600411,8629
+C02CA04,DOXAZOSIN,1363053,Doxazosin,21600414,49276
+C02CC,GUANIDINE DERIVATIVES,1400959,guanadrel,21600416,26296
+C02CC02,GUANETHIDINE,1366279,Guanethidine,21600418,5036
+C02DA01,DIAZOXIDE,1523280,Diazoxide,21600426,3327
+C02DB02,HYDRALAZINE,1373928,Hydralazine,21600429,5470
+C02DC01,MINOXIDIL,1309068,Minoxidil,21600433,6984
+C02DD01,NITROPRUSSIDE,19020994,Nitroprusside,21600435,7476
+C02KB01,METIROSINE,1401581,Metyrosine,21600442,266604
+C02KC01,PARGYLINE,19027413,Pargyline,21600444,7930
+C02KX,OTHER ANTIHYPERTENSIVES,1316262,sildenafil,21600447,136411
+C02KX01,BOSENTAN,1321636,bosentan,21600448,75207
+C02KX02,AMBRISENTAN,1337068,ambrisentan,21600449,358274
+C02LA01,RESERPINE AND DIURETICS,904639,Trichlormethiazide,21600453,10772
+C02LA01,RESERPINE AND DIURETICS,905273,Methyclothiazide,21600453,6860
+C02LA01,RESERPINE AND DIURETICS,948787,Polythiazide,21600453,8565
+C02LA01,RESERPINE AND DIURETICS,974166,Hydrochlorothiazide,21600453,5487
+C02LA01,RESERPINE AND DIURETICS,992590,Chlorothiazide,21600453,2396
+C02LA01,RESERPINE AND DIURETICS,1362225,Reserpine,21600453,9260
+C02LA01,RESERPINE AND DIURETICS,1373928,Hydralazine,21600453,5470
+C02LA01,RESERPINE AND DIURETICS,1376289,Hydroflumethiazide,21600453,5495
+C02LA01,RESERPINE AND DIURETICS,1395058,Chlorthalidone,21600453,2409
+C02LA01,RESERPINE AND DIURETICS,19036731,benzothiazide,21600453,19008
+C02LA03,DESERPIDINE AND DIURETICS,905273,Methyclothiazide,21600455,6860
+C02LA03,DESERPIDINE AND DIURETICS,974166,Hydrochlorothiazide,21600455,5487
+C02LA03,DESERPIDINE AND DIURETICS,1387219,deserpidine,21600455,62174
+C02LA08,"RAUWOLFIA ALKALOIDS, WHOLE ROOT AND DIURETICS",1316354,Bendroflumethiazide,21600458,1369
+C02LA08,"RAUWOLFIA ALKALOIDS, WHOLE ROOT AND DIURETICS",1326378,Rauwolfia preparation,21600458,78678
+C02LB01,METHYLDOPA (LEVOROTATORY) AND DIURETICS,974166,Hydrochlorothiazide,21600465,5487
+C02LB01,METHYLDOPA (LEVOROTATORY) AND DIURETICS,992590,Chlorothiazide,21600465,2396
+C02LB01,METHYLDOPA (LEVOROTATORY) AND DIURETICS,1305447,Methyldopa,21600465,6876
+C02LC01,CLONIDINE AND DIURETICS,1395058,Chlorthalidone,21600467,2409
+C02LC01,CLONIDINE AND DIURETICS,1398937,Clonidine,21600467,2599
+C02LE01,PRAZOSIN AND DIURETICS,948787,Polythiazide,21600471,8565
+C02LE01,PRAZOSIN AND DIURETICS,1350489,Prazosin,21600471,8629
+C02LF01,GUANETHIDINE AND DIURETICS,974166,Hydrochlorothiazide,21600473,5487
+C02LF01,GUANETHIDINE AND DIURETICS,1366279,Guanethidine,21600473,5036
+C02LG02,HYDRALAZINE AND DIURETICS,974166,Hydrochlorothiazide,21600476,5487
+C02LG02,HYDRALAZINE AND DIURETICS,1373928,Hydralazine,21600476,5470
+A03ED,ANTISPASMODICS IN COMBINATION WITH OTHER DRUGS,734275,Phenobarbital,21600481,8134
+A03ED,ANTISPASMODICS IN COMBINATION WITH OTHER DRUGS,914335,Atropine,21600481,1223
+A03ED,ANTISPASMODICS IN COMBINATION WITH OTHER DRUGS,923672,Hyoscyamine,21600481,153970
+A03ED,ANTISPASMODICS IN COMBINATION WITH OTHER DRUGS,965748,Scopolamine,21600481,9601
+A03ED,ANTISPASMODICS IN COMBINATION WITH OTHER DRUGS,966991,Simethicone,21600481,9796
+A03ED,ANTISPASMODICS IN COMBINATION WITH OTHER DRUGS,1116109,Belladonna Alkaloids,21600481,1359
+A03ED,ANTISPASMODICS IN COMBINATION WITH OTHER DRUGS,1123904,phenyltoloxamine,21600481,33408
+A03ED,ANTISPASMODICS IN COMBINATION WITH OTHER DRUGS,1145379,Ergotamine,21600481,4025
+A03FA01,METOCLOPRAMIDE,906780,Metoclopramide,21600484,6915
+A03FA02,CISAPRIDE,932196,Cisapride,21600485,35255
+A04AA01,ONDANSETRON,1000560,Ondansetron,21600493,26225
+A04AA02,GRANISETRON,1000772,Granisetron,21600494,26237
+A04AA04,DOLASETRON,903459,Dolasetron,21600496,68091
+A04AA05,PALONOSETRON,911354,palonosetron,21600497,70561
+A04AD,OTHER ANTIEMETICS,917006,Benzocaine,21600498,1399
+A04AD,OTHER ANTIEMETICS,942799,trimethobenzamide,21600498,38685
+A04AD,OTHER ANTIEMETICS,19089992,diphenidol,21600498,23370
+A04AD01,SCOPOLAMINE,965748,Scopolamine,21600499,9601
+A04AD10,DRONABINOL,1037005,Tetrahydrocannabinol,21600503,10402
+A04AD11,NABILONE,913440,nabilone,21600504,31447
+A04AD12,APREPITANT,936748,aprepitant,21600505,358255
+A05AA01,CHENODEOXYCHOLIC ACID,19052447,Chenodeoxycholate,21600512,42588
+A05AA02,URSODEOXYCHOLIC ACID,988095,Ursodeoxycholate,21600513,62427
+A05AB,PREPARATIONS FOR BILIARY TRACT THERAPY,19052817,Dehydrocholate,21600515,42625
+A05BA,LIVER THERAPY,19042345,Lecithin,21600522,8214
+A06AA,"SOFTENERS, EMOLLIENTS",941258,Docusate,21600533,82003
+A06AA01,LIQUID PARAFFIN,908523,Mineral Oil,21600534,6972
+A06AA02,DOCUSATE SODIUM,941258,Docusate,21600535,82003
+A06AB02,BISACODYL,908464,magnesium carbonate,21600539,29155
+A06AB02,BISACODYL,924939,Bisacodyl,21600539,1596
+A06AB02,BISACODYL,939506,Sodium Bicarbonate,21600539,36676
+A06AB02,BISACODYL,939871,sodium phosphate,21600539,36709
+A06AB02,BISACODYL,950435,Citric Acid,21600539,21183
+A06AB02,BISACODYL,967823,Sodium Chloride,21600539,9863
+A06AB02,BISACODYL,976545,potassium citrate,21600539,54993
+A06AB02,BISACODYL,986417,POLYETHYLENE GLYCOL 3350,21600539,221147
+A06AB02,BISACODYL,990499,"Sodium Phosphate, Monobasic",21600539,235496
+A06AB02,BISACODYL,19049105,Potassium Chloride,21600539,8591
+A06AB03,DANTRON,19086560,danthron,21600540,22293
+A06AB04,PHENOLPHTHALEIN,914085,Yellow phenolphthalein,21600541,314784
+A06AB04,PHENOLPHTHALEIN,924309,Phenolphthalein,21600541,155122
+A06AB04,PHENOLPHTHALEIN,941258,Docusate,21600541,82003
+A06AB05,CASTOR OIL,950933,Castor Oil,21600542,2129
+A06AB06,SENNA GLYCOSIDES,938268,Sennosides,21600543,36387
+A06AB06,SENNA GLYCOSIDES,960820,Senna Leaf Extract,21600543,485853
+A06AB06,SENNA GLYCOSIDES,966346,Senna Extract,21600543,9658
+A06AB06,SENNA GLYCOSIDES,19086491,standardized senna concentrate,21600543,221166
+A06AB07,CASCARA,900017,Cascara sagrada,21600544,66869
+A06AB53,"DANTRON, COMBINATIONS",941258,Docusate,21600550,82003
+A06AB53,"DANTRON, COMBINATIONS",19086560,danthron,21600550,22293
+A06AB56,"SENNA GLYCOSIDES, COMBINATIONS",938268,Sennosides,21600551,36387
+A06AB56,"SENNA GLYCOSIDES, COMBINATIONS",941258,Docusate,21600551,82003
+A06AB56,"SENNA GLYCOSIDES, COMBINATIONS",966346,Senna Extract,21600551,9658
+A06AB56,"SENNA GLYCOSIDES, COMBINATIONS",19094011,Prune preparation,21600551,340262
+A06AB57,"CASCARA, COMBINATIONS",900017,Cascara sagrada,21600552,66869
+A06AB57,"CASCARA, COMBINATIONS",900093,Casanthranol,21600552,66870
+A06AB57,"CASCARA, COMBINATIONS",941258,Docusate,21600552,82003
+A06AB57,"CASCARA, COMBINATIONS",960900,Aloe Extract,21600552,91263
+A06AC,BULK PRODUCERS,986517,Cellulose,21600554,2221
+A06AC,BULK PRODUCERS,990337,Malt extract,21600554,235375
+A06AC,BULK PRODUCERS,1000979,guar gum,21600554,26344
+A06AC,BULK PRODUCERS,1037015,Bran,21600554,104125
+A06AC01,ISPAGHULA (PSYLLA SEEDS),957797,Psyllium,21600555,8928
+A06AC01,ISPAGHULA (PSYLLA SEEDS),975125,Hydrocortisone,21600555,5492
+A06AC01,ISPAGHULA (PSYLLA SEEDS),989878,Lidocaine,21600555,6387
+A06AC01,ISPAGHULA (PSYLLA SEEDS),19132965,Plantago Seed,21600555,82088
+A06AC05,LINSEED,1315342,Flaxseed extract,21600558,318224
+A06AC05,LINSEED,19090767,Linseed Oil,21600558,6404
+A06AC06,METHYLCELLULOSE,905371,Methylcellulose,21600559,6873
+A06AC08,POLYCARBOPHIL CALCIUM,940426,calcium polycarbophil,21600561,20063
+A06AC51,"ISPAGHULA, COMBINATIONS",938268,Sennosides,21600562,36387
+A06AC51,"ISPAGHULA, COMBINATIONS",957797,Psyllium,21600562,8928
+A06AC51,"ISPAGHULA, COMBINATIONS",19035704,Calcium Carbonate,21600562,1897
+A06AD02,MAGNESIUM OXIDE,993631,Magnesium Oxide,21600567,6582
+A06AD04,MAGNESIUM SULFATE,19093848,Magnesium Sulfate,21600569,6585
+A06AD11,LACTULOSE,987245,Lactulose,21600571,6218
+A06AD17,SODIUM PHOSPHATE,990499,"Sodium Phosphate, Monobasic",21600577,235496
+A06AD17,SODIUM PHOSPHATE,991710,"Sodium Phosphate, Dibasic",21600577,236719
+A06AG01,SODIUM PHOSPHATE,990499,"Sodium Phosphate, Monobasic",21600584,235496
+A06AG01,SODIUM PHOSPHATE,991710,"Sodium Phosphate, Dibasic",21600584,236719
+A06AG02,BISACODYL,924939,Bisacodyl,21600585,1596
+A06AG04,GLYCEROL,961145,Glycerin,21600587,4910
+A06AG10,"DOCUSATE SODIUM, INCL. COMBINATIONS",917006,Benzocaine,21600590,1399
+A06AG10,"DOCUSATE SODIUM, INCL. COMBINATIONS",941258,Docusate,21600590,82003
+A06AH01,METHYLNALTREXONE BROMIDE,909841,methylnaltrexone,21600594,29899
+A06AH02,ALVIMOPAN,19059654,alvimopan,21600595,480639
+A06AX01,GLYCEROL,961145,Glycerin,21600597,4910
+A06AX03,LUBIPROSTONE,987366,lubiprostone,21600599,623033
+A07AA02,NYSTATIN,922570,Nystatin,21600604,7597
+A07AA06,PAROMOMYCIN,1727443,Paromomycin,21600608,7934
+A07AA08,KANAMYCIN,1784749,Kanamycin,21600610,6099
+A07AA09,VANCOMYCIN,1707687,Vancomycin,21600611,11124
+A07AA11,RIFAXIMIN,1735947,rifaximin,21600613,35619
+A07BA01,MEDICINAL CHARCOAL,1701928,Activated Charcoal,21600629,272
+A07BA51,"MEDICINAL CHARCOAL, COMBINATIONS",966991,Simethicone,21600630,9796
+A07BA51,"MEDICINAL CHARCOAL, COMBINATIONS",1701928,Activated Charcoal,21600630,272
+A07BB,BISMUTH PREPARATIONS,937725,bismuth subgallate,21600631,19476
+A07BB,BISMUTH PREPARATIONS,937791,bismuth subsalicylate,21600631,19478
+A07BB,BISMUTH PREPARATIONS,1707164,Metronidazole,21600631,6922
+A07BB,BISMUTH PREPARATIONS,1836948,Tetracycline,21600631,10395
+A07BC01,PECTIN,922191,pectin,21600633,32987
+A07BC04,ATTAPULGITE,933794,attapulgite,21600636,18516
+A07BC54,"ATTAPULGITE, COMBINATIONS",922191,pectin,21600639,32987
+A07BC54,"ATTAPULGITE, COMBINATIONS",933794,attapulgite,21600639,18516
+A07DA,ANTIPROPULSIVES,914335,Atropine,21600643,1223
+A07DA,ANTIPROPULSIVES,922024,paregoric,21600643,32926
+A07DA,ANTIPROPULSIVES,989567,difenoxin,21600643,23024
+A07DA01,DIPHENOXYLATE,914335,Atropine,21600644,1223
+A07DA01,DIPHENOXYLATE,930916,Diphenoxylate,21600644,3500
+A07DA02,OPIUM,923829,Opium,21600645,7676
+A07DA02,OPIUM,1116109,Belladonna Alkaloids,21600645,1359
+A07DA03,LOPERAMIDE,991876,Loperamide,21600646,6468
+A07DA53,"LOPERAMIDE, COMBINATIONS",966991,Simethicone,21600650,9796
+A07DA53,"LOPERAMIDE, COMBINATIONS",991876,Loperamide,21600650,6468
+A07EA02,HYDROCORTISONE,975125,Hydrocortisone,21600654,5492
+A07EA06,BUDESONIDE,939259,Budesonide,21600658,19831
+A07EB01,CROMOGLICIC ACID,1152631,Cromolyn,21600661,42612
+A07EC01,SULFASALAZINE,964339,Sulfasalazine,21600663,9524
+A07EC02,MESALAZINE,968426,mesalamine,21600664,52582
+A07EC03,OLSALAZINE,916282,olsalazine,21600665,32385
+A07EC04,BALSALAZIDE,934262,balsalazide,21600666,18747
+A07FA01,LACTIC ACID PRODUCING ORGANISMS,987153,Lactobacillus acidophilus,21600669,6205
+A07FA01,LACTIC ACID PRODUCING ORGANISMS,19136097,Bifidobacterium Infantis,21600669,100213
+A07FA02,SACCHAROMYCES BOULARDII,991855,Saccharomyces boulardii,21600670,236782
+A07FA51,"LACTIC ACID PRODUCING ORGANISMS, COMBINATIONS",987153,Lactobacillus acidophilus,21600671,6205
+A07FA51,"LACTIC ACID PRODUCING ORGANISMS, COMBINATIONS",19056614,Lactobacillus bifidus,21600671,236855
+A08AA,CENTRALLY ACTING ANTIOBESITY PRODUCTS,719128,Benzphetamine,21600681,1422
+A08AA,CENTRALLY ACTING ANTIOBESITY PRODUCTS,723344,phendimetrazine,21600681,33272
+A08AA01,PHENTERMINE,735340,Phentermine,21600682,8152
+A08AA02,FENFLURAMINE,753860,Fenfluramine,21600683,4328
+A08AA03,AMFEPRAMONE,725822,Diethylpropion,21600684,3389
+A08AA04,DEXFENFLURAMINE,719057,Dexfenfluramine,21600685,3268
+A08AA05,MAZINDOL,794229,Mazindol,21600686,6664
+A08AA10,SIBUTRAMINE,739363,sibutramine,21600691,36514
+A08AB,PERIPHERALLY ACTING ANTIOBESITY PRODUCTS,1378790,HOODIA GORDONII EXTRACT,21600693,578315
+A08AB01,ORLISTAT,741530,orlistat,21600694,37925
+A09AA,ENZYME PREPARATIONS,919204,Amylases,21600699,743
+A09AA,ENZYME PREPARATIONS,931973,Endopeptidases,21600699,8031
+A09AA,ENZYME PREPARATIONS,950183,Lactase,21600699,41397
+A09AA,ENZYME PREPARATIONS,990760,Lipase,21600699,6406
+A09AA,ENZYME PREPARATIONS,19030387,Bromelains,21600699,1752
+A09AA,ENZYME PREPARATIONS,19066564,"ENZYMES,DIGESTIVE (PLANT)",21600699,259374
+A09AA02,"MULTIENZYMES (LIPASE, PROTEASE ETC)",919204,Amylases,21600701,743
+A09AA02,"MULTIENZYMES (LIPASE, PROTEASE ETC)",926487,Pancreatin,21600701,7880
+A09AA02,"MULTIENZYMES (LIPASE, PROTEASE ETC)",931973,Endopeptidases,21600701,8031
+A09AA02,"MULTIENZYMES (LIPASE, PROTEASE ETC)",990760,Lipase,21600701,6406
+A09AA04,TILACTASE,950183,Lactase,21600703,41397
+A09AB01,GLUTAMIC ACID HYDROCHLORIDE,911486,Glutamate,21600705,70602
+A09AB02,BETAINE HYDROCHLORIDE,1520218,Betaine,21600706,1512
+A09AB03,HYDROCHLORIC ACID,974140,Hydrochloric Acid,21600707,5486
+A09AC,"ENZYME AND ACID PREPARATIONS, COMBINATIONS",931973,Endopeptidases,21600709,8031
+A09AC,"ENZYME AND ACID PREPARATIONS, COMBINATIONS",1520218,Betaine,21600709,1512
+A10AB01,INSULIN (HUMAN),1596977,"Regular Insulin, Human",21600715,253182
+A10AB02,INSULIN (BEEF),19013951,"Insulin, Regular, Beef",21600716,314686
+A10AB03,INSULIN (PORK),1586346,"Insulin, Regular, Pork",21600717,221109
+A10AB04,INSULIN LISPRO,1550023,Insulin Lispro,21600718,86009
+A10AB05,INSULIN ASPART,1567198,"Insulin, Aspart, Human",21600719,51428
+A10AB06,INSULIN GLULISINE,1544838,"Insulin, Glulisine, Human",21600720,400008
+A10AB30,COMBINATIONS,1590165,"Insulin, Regular, Beef-Pork",21600721,235275
+A10AC01,INSULIN (HUMAN),1596914,"NPH Insulin, Human",21600723,253181
+A10AC02,INSULIN (BEEF),19014950,"NPH Insulin, Beef",21600724,317235
+A10AC02,INSULIN (BEEF),19090180,"insulin, protamine zinc, beef",21600724,235278
+A10AC03,INSULIN (PORK),1586326,"NPH Insulin, Pork",21600725,221108
+A10AC30,COMBINATIONS,1515106,"NPH Insulin, Beef-Pork",21600727,317598
+A10AC30,COMBINATIONS,19013926,"Insulin, Protamine Zinc, Beef-Pork",21600727,314685
+A10AD01,INSULIN (HUMAN),1596914,"NPH Insulin, Human",21600729,253181
+A10AD01,INSULIN (HUMAN),1596977,"Regular Insulin, Human",21600729,253182
+A10AD03,INSULIN (PORK),1586326,"NPH Insulin, Pork",21600731,221108
+A10AD04,INSULIN LISPRO,1513876,"Insulin, Protamine Lispro, Human",21600732,314684
+A10AD04,INSULIN LISPRO,1550023,Insulin Lispro,21600732,86009
+A10AD05,INSULIN ASPART,1531601,"Insulin, Aspart Protamine, Human",21600733,352385
+A10AD05,INSULIN ASPART,1567198,"Insulin, Aspart, Human",21600733,51428
+A10AE01,INSULIN (HUMAN),1513849,"Insulin, Zinc, Human",21600736,314683
+A10AE01,INSULIN (HUMAN),1586369,"Ultralente Insulin, Human",21600736,221110
+A10AE02,INSULIN (BEEF),19090204,"Lente Insulin, Beef",21600737,235280
+A10AE03,INSULIN (PORK),1562586,"Insulin, Zinc, Pork",21600738,93108
+A10AE04,INSULIN GLARGINE,1502905,Insulin Glargine,21600739,274783
+A10AE05,INSULIN DETEMIR,1516976,insulin detemir,21600740,139825
+A10AE30,COMBINATIONS,1513843,"Lente Insulin, Beef-Pork",21600741,314682
+A10AE30,COMBINATIONS,19090221,"Ultralente Insulin, Beef-Pork",21600741,235281
+A10AE30,COMBINATIONS,19090229,"Insulin, Prompt Zinc, Beef-Pork",21600741,235283
+A10BA02,METFORMIN,1503297,Metformin,21600747,6809
+A10BB01,GLIBENCLAMIDE,1559684,Glyburide,21600750,4815
+A10BB02,CHLORPROPAMIDE,1594973,Chlorpropamide,21600751,2404
+A10BB03,TOLBUTAMIDE,1502855,Tolbutamide,21600752,10635
+A10BB05,TOLAZAMIDE,1502809,Tolazamide,21600754,10633
+A10BB07,GLIPIZIDE,1560171,Glipizide,21600756,4821
+A10BB12,GLIMEPIRIDE,1597756,glimepiride,21600761,25789
+A10BB31,ACETOHEXAMIDE,1530014,Acetohexamide,21600762,173
+A10BD,COMBINATIONS OF ORAL BLOOD GLUCOSE LOWERING DRUGS,1503297,Metformin,21600765,6809
+A10BD,COMBINATIONS OF ORAL BLOOD GLUCOSE LOWERING DRUGS,1516766,repaglinide,21600765,73044
+A10BD02,METFORMIN AND SULFONAMIDES,1503297,Metformin,21600767,6809
+A10BD02,METFORMIN AND SULFONAMIDES,1559684,Glyburide,21600767,4815
+A10BD02,METFORMIN AND SULFONAMIDES,1560171,Glipizide,21600767,4821
+A10BD03,METFORMIN AND ROSIGLITAZONE,1503297,Metformin,21600768,6809
+A10BD03,METFORMIN AND ROSIGLITAZONE,1547504,rosiglitazone,21600768,84108
+A10BD04,GLIMEPIRIDE AND ROSIGLITAZONE,1547504,rosiglitazone,21600769,84108
+A10BD04,GLIMEPIRIDE AND ROSIGLITAZONE,1597756,glimepiride,21600769,25789
+A10BD05,METFORMIN AND PIOGLITAZONE,1503297,Metformin,21600770,6809
+A10BD05,METFORMIN AND PIOGLITAZONE,1525215,pioglitazone,21600770,33738
+A10BD06,GLIMEPIRIDE AND PIOGLITAZONE,1525215,pioglitazone,21600771,33738
+A10BD06,GLIMEPIRIDE AND PIOGLITAZONE,1597756,glimepiride,21600771,25789
+A10BD07,METFORMIN AND SITAGLIPTIN,1503297,Metformin,21600772,6809
+A10BD07,METFORMIN AND SITAGLIPTIN,1580747,sitagliptin,21600772,593411
+A10BF01,ACARBOSE,1529331,Acarbose,21600776,16681
+A10BF02,MIGLITOL,1510202,miglitol,21600777,30009
+A10BG01,TROGLITAZONE,1515249,troglitazone,21600780,72610
+A10BG02,ROSIGLITAZONE,1547504,rosiglitazone,21600781,84108
+A10BG03,PIOGLITAZONE,1525215,pioglitazone,21600782,33738
+A10BH01,SITAGLIPTIN,1580747,sitagliptin,21600784,593411
+A10BX02,REPAGLINIDE,1516766,repaglinide,21600790,73044
+A10BX03,NATEGLINIDE,1502826,nateglinide,21600791,274332
+A10BX04,EXENATIDE,1583722,exenatide,21600792,60548
+A10BX05,PRAMLINTIDE,1517998,Pramlintide,21600793,139953
+A11AA,MULTIVITAMINS WITH MINERALS,1195334,Choline,21600802,2449
+A11AA,MULTIVITAMINS WITH MINERALS,1379525,Inositol,21600802,5833
+A11CA01,RETINOL (VIT A),19008339,Vitamin A,21600812,11246
+A11CA02,BETACAROTENE,19037223,Beta Carotene,21600813,19143
+A11CB,VITAMIN A AND D IN COMBINATION,19008339,Vitamin A,21600814,11246
+A11CB,VITAMIN A AND D IN COMBINATION,19045045,Ergocalciferol,21600814,4018
+A11CB,VITAMIN A AND D IN COMBINATION,19095164,Cholecalciferol,21600814,2418
+A11CC01,ERGOCALCIFEROL,19045045,Ergocalciferol,21600816,4018
+A11CC02,DIHYDROTACHYSTEROL,19027015,Dihydrotachysterol,21600817,3429
+A11CC04,CALCITRIOL,19035631,Calcitriol,21600819,1894
+A11CC05,COLECALCIFEROL,19038464,soy protein isolate,21600820,196238
+A11CC05,COLECALCIFEROL,19095164,Cholecalciferol,21600820,2418
+A11CC06,CALCIFEDIOL,19035569,Calcifediol,21600821,1889
+A11DA01,THIAMINE (VIT B1),19137312,Thiamine,21600825,10454
+A11EB,VITAMIN B-COMPLEX WITH VITAMIN C,1387426,Folate,21600831,62356
+A11EB,VITAMIN B-COMPLEX WITH VITAMIN C,19010970,Vitamin B Complex,21600831,11251
+A11EB,VITAMIN B-COMPLEX WITH VITAMIN C,19035704,Calcium Carbonate,21600831,1897
+A11GA01,ASCORBIC ACID (VIT C),19011773,Ascorbic Acid,21600837,1151
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",922191,pectin,21600838,32987
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",1389112,Echinacea Preparation,21600838,228041
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",1399063,Echinacea purpurea extract,21600838,260025
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",19010696,Zinc,21600838,11416
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",19011773,Ascorbic Acid,21600838,1151
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",19024669,Bioflavonoids,21600838,1562
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",19055756,"BIOFLAVONOID, LEMON",21600838,236117
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",19079204,Zinc Gluconate,21600838,58300
+A11GB,"ASCORBIC ACID (VITAMIN C), COMBINATIONS",19112632,"COLLAGEN, HYDROLYZED",21600838,477454
+A11HA,OTHER PLAIN VITAMIN PREPARATIONS,1308185,lycopene,21600841,29008
+A11HA,OTHER PLAIN VITAMIN PREPARATIONS,19018384,4-Aminobenzoic Acid,21600841,74
+A11HA,OTHER PLAIN VITAMIN PREPARATIONS,19087067,4-Aminobenzoate,21600841,618974
+A11HA01,NICOTINAMIDE,19018419,Niacinamide,21600842,7405
+A11HA02,PYRIDOXINE (VIT B6),1353228,Vitamin B6,21600843,42954
+A11HA03,TOCOPHEROL (VIT E),19009540,Vitamin E,21600844,11256
+A11HA03,TOCOPHEROL (VIT E),19014164,Wheat germ oil,21600844,72385
+A11HA04,RIBOFLAVIN (VIT B2),19056500,Flavin Mononucleotide,21600845,4509
+A11HA04,RIBOFLAVIN (VIT B2),19062817,Riboflavin,21600845,9346
+A11HA05,BIOTIN,19024770,Biotin,21600846,1588
+A11HA05,BIOTIN,19035704,Calcium Carbonate,21600846,1897
+A11HA05,BIOTIN,19080550,CHROMIUM PICOLINATE,21600846,59308
+A11HA06,PYRIDOXAL PHOSPHATE,19059817,Pyridoxal,21600847,9002
+A11HA07,INOSITOL,1379525,Inositol,21600848,5833
+A11HA08,TOCOFERSOLAN,19018322,tocophersolan,21600849,159151
+A11HA31,CALCIUM PANTOTHENATE,19026739,Pantothenic Acid,21600851,7891
+A11HA31,CALCIUM PANTOTHENATE,19088079,pantothenate,21600851,62400
+A11JA,COMBINATIONS OF VITAMINS,1195334,Choline,21600854,2449
+A11JA,COMBINATIONS OF VITAMINS,1308738,Vitamin B 12,21600854,11248
+A11JA,COMBINATIONS OF VITAMINS,1353228,Vitamin B6,21600854,42954
+A11JA,COMBINATIONS OF VITAMINS,19008339,Vitamin A,21600854,11246
+A11JA,COMBINATIONS OF VITAMINS,19009405,Vitamin D,21600854,11253
+A11JA,COMBINATIONS OF VITAMINS,19009540,Vitamin E,21600854,11256
+A11JA,COMBINATIONS OF VITAMINS,19011773,Ascorbic Acid,21600854,1151
+A11JA,COMBINATIONS OF VITAMINS,19026739,Pantothenic Acid,21600854,7891
+A11JA,COMBINATIONS OF VITAMINS,19037223,Beta Carotene,21600854,19143
+A11JA,COMBINATIONS OF VITAMINS,19062817,Riboflavin,21600854,9346
+A11JA,COMBINATIONS OF VITAMINS,19137312,Thiamine,21600854,10454
+A11JB,VITAMINS WITH MINERALS,1308738,Vitamin B 12,21600855,11248
+A11JB,VITAMINS WITH MINERALS,1353228,Vitamin B6,21600855,42954
+A11JB,VITAMINS WITH MINERALS,19010696,Zinc,21600855,11416
+A11JB,VITAMINS WITH MINERALS,19011773,Ascorbic Acid,21600855,1151
+A11JB,VITAMINS WITH MINERALS,19079390,ZINC PICOLINATE,21600855,58301
+A11JB,VITAMINS WITH MINERALS,19080550,CHROMIUM PICOLINATE,21600855,59308
+A11JB,VITAMINS WITH MINERALS,19095164,Cholecalciferol,21600855,2418
+A11JB,VITAMINS WITH MINERALS,19106287,Vitamin K 2,21600855,42781
+A11JC,"VITAMINS, OTHER COMBINATIONS",1195334,Choline,21600856,2449
+A11JC,"VITAMINS, OTHER COMBINATIONS",1308185,lycopene,21600856,29008
+A11JC,"VITAMINS, OTHER COMBINATIONS",1308738,Vitamin B 12,21600856,11248
+A11JC,"VITAMINS, OTHER COMBINATIONS",1310353,Lutein,21600856,11359
+A11JC,"VITAMINS, OTHER COMBINATIONS",1353228,Vitamin B6,21600856,42954
+A11JC,"VITAMINS, OTHER COMBINATIONS",1391889,Ginkgo biloba extract,21600856,236809
+A11JC,"VITAMINS, OTHER COMBINATIONS",19007600,Soybean preparation,21600856,287515
+A11JC,"VITAMINS, OTHER COMBINATIONS",19009540,Vitamin E,21600856,11256
+A11JC,"VITAMINS, OTHER COMBINATIONS",19011773,Ascorbic Acid,21600856,1151
+A11JC,"VITAMINS, OTHER COMBINATIONS",19035704,Calcium Carbonate,21600856,1897
+A11JC,"VITAMINS, OTHER COMBINATIONS",19095164,Cholecalciferol,21600856,2418
+A12AA,CALCIUM,19018602,Calcium Glucarate,21600859,1907
+A12AA,CALCIUM,19058572,Calcium Citrate,21600859,47613
+A12AA01,CALCIUM PHOSPHATE,19037401,calcium phosphate,21600860,1919
+A12AA02,CALCIUM GLUBIONATE,19097867,glubionate calcium,21600861,25806
+A12AA03,CALCIUM GLUCONATE,1560524,Glucose,21600862,4850
+A12AA03,CALCIUM GLUCONATE,19037038,Calcium Gluconate,21600862,1908
+A12AA04,CALCIUM CARBONATE,1516800,Risedronate,21600863,73056
+A12AA04,CALCIUM CARBONATE,19035704,Calcium Carbonate,21600863,1897
+A12AA05,CALCIUM LACTATE,19058896,calcium lactate,21600864,47622
+A12AA10,CALCIUM GLUCOHEPTONATE,19058867,Calcium gluceptate,21600869,47618
+A12AA11,CALCIUM PANGAMATE,19091973,pangamate,21600870,646818
+A12AA12,CALCIUM ACETATE ANHYDROUS,951469,calcium acetate,21600871,214342
+A12AA20,CALCIUM (DIFFERENT SALTS IN COMBINATION),1337159,Calcium Glycerophosphate,21600872,1909
+A12AA20,CALCIUM (DIFFERENT SALTS IN COMBINATION),19058896,calcium lactate,21600872,47622
+A12AA20,CALCIUM (DIFFERENT SALTS IN COMBINATION),19058971,CALCIUM LEVULINATE,21600872,47624
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",911486,Glutamate,21600874,70602
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",967861,magnesium citrate,21600874,52356
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",993631,Magnesium Oxide,21600874,6582
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",1391642,Chaste tree preparation,21600874,236664
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",1595799,Ferrous fumarate,21600874,24941
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19007600,Soybean preparation,21600874,287515
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19009405,Vitamin D,21600874,11253
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19010696,Zinc,21600874,11416
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19019904,Docosahexanoic acid,21600874,144450
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19029824,Boron,21600874,1705
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19035704,Calcium Carbonate,21600874,1897
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19037401,calcium phosphate,21600874,1919
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19038464,soy protein isolate,21600874,196238
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19044727,Vitamin K 1,21600874,8308
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19045045,Ergocalciferol,21600874,4018
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19058348,Gamboge,21600874,89698
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19058572,Calcium Citrate,21600874,47613
+A12AX,"CALCIUM, COMBINATIONS WITH OTHER DRUGS",19095164,Cholecalciferol,21600874,2418
+A12BA,POTASSIUM,19027080,potassium bicarbonate,21600876,34296
+A12BA,POTASSIUM,19049024,Potassium,21600876,8588
+A12BA01,POTASSIUM CHLORIDE,19049105,Potassium Chloride,21600877,8591
+A12BA02,POTASSIUM CITRATE,950435,Citric Acid,21600878,21183
+A12BA02,POTASSIUM CITRATE,976545,potassium citrate,21600878,54993
+A12BA05,POTASSIUM GLUCONATE,19059547,Potassium gluconate,21600881,89903
+A12BA51,"POTASSIUM CHLORIDE, COMBINATIONS",19019131,Magnesium Aspartate,21600883,142131
+A12CA01,SODIUM CHLORIDE,967823,Sodium Chloride,21600886,9863
+A12CB,ZINC,979096,Zinc Acetate,21600888,58295
+A12CB,ZINC,1135766,Phenylephrine,21600888,8163
+A12CB,ZINC,1140640,carbetapentane,21600888,20217
+A12CB,ZINC,1154332,Pseudoephedrine,21600888,8896
+A12CB,ZINC,1158632,Methscopolamine,21600888,89785
+A12CB,ZINC,1163944,Guaifenesin,21600888,5032
+A12CB,ZINC,1192710,Chlorpheniramine,21600888,2400
+A12CB,ZINC,19010696,Zinc,21600888,11416
+A12CB,ZINC,19079390,ZINC PICOLINATE,21600888,58301
+A12CB01,ZINC SULFATE,19044522,Zinc Sulfate,21600889,39954
+A12CB02,ZINC GLUCONATE,19079204,Zinc Gluconate,21600890,58300
+A12CC,MAGNESIUM,19059006,Magnesium glycinate,21600892,476818
+A12CC,MAGNESIUM,19060896,magnesium amino acid chelate,21600892,486895
+A12CC01,MAGNESIUM CHLORIDE,19092849,Magnesium Chloride,21600893,6579
+A12CC02,MAGNESIUM SULFATE,19093848,Magnesium Sulfate,21600894,6585
+A12CC03,MAGNESIUM GLUCONATE,19067971,MAGNESIUM GLUCONATE,21600895,52358
+A12CC06,MAGNESIUM LACTATE,19051926,Magnesium lactate,21600898,214688
+A12CC10,MAGNESIUM OXIDE,993631,Magnesium Oxide,21600902,6582
+A12CC30,MAGNESIUM (DIFFERENT SALTS IN COMBINATION),19019131,Magnesium Aspartate,21600903,142131
+A12CE,SELENIUM,19038024,Selenious Acid,21600908,36344
+A12CX,OTHER MINERAL PRODUCTS,1359148,Echinacea Root Extract,21600911,477379
+A12CX,OTHER MINERAL PRODUCTS,19004810,Copper Gluconate,21600911,2839
+A12CX,OTHER MINERAL PRODUCTS,19008893,manganese chloride,21600911,29261
+A12CX,OTHER MINERAL PRODUCTS,19008897,manganese sulfate,21600911,29268
+A12CX,OTHER MINERAL PRODUCTS,19009896,Molybdenum,21600911,7024
+A12CX,OTHER MINERAL PRODUCTS,19010696,Zinc,21600911,11416
+A12CX,OTHER MINERAL PRODUCTS,19029824,Boron,21600911,1705
+A12CX,OTHER MINERAL PRODUCTS,19038433,bone meal,21600911,19596
+A12CX,OTHER MINERAL PRODUCTS,19043266,vanadyl sulfate,21600911,39364
+A12CX,OTHER MINERAL PRODUCTS,19049877,chromic chloride,21600911,21009
+A12CX,OTHER MINERAL PRODUCTS,19057346,Copper Sulfate,21600911,21579
+A12CX,OTHER MINERAL PRODUCTS,19059405,Germanium,21600911,4784
+A12CX,OTHER MINERAL PRODUCTS,19073031,cupric chloride,21600911,21833
+A12CX,OTHER MINERAL PRODUCTS,19079390,ZINC PICOLINATE,21600911,58301
+A12CX,OTHER MINERAL PRODUCTS,19080550,CHROMIUM PICOLINATE,21600911,59308
+A12CX,OTHER MINERAL PRODUCTS,19082847,BORON CITRATE,21600911,324014
+A12CX,OTHER MINERAL PRODUCTS,19127669,Lithium Aspartate,21600911,746070
+A13A,TONICS,1398499,Hops extract,21600913,259266
+A13A,TONICS,19006410,Arginine,21600913,1091
+A13A,TONICS,19010128,Vitamin K,21600913,11258
+A13A,TONICS,19012197,Berberine,21600913,1437
+A13A,TONICS,19035704,Calcium Carbonate,21600913,1897
+A13A,TONICS,19082762,Maca preparation,21600913,319839
+A13A,TONICS,19095164,Cholecalciferol,21600913,2418
+A14AA02,STANOZOLOL,1636145,Stanozolol,21600918,10032
+A14AA05,OXYMETHOLONE,1525741,Oxymetholone,21600921,7813
+A14AA07,PRASTERONE,1312007,dehydroepiandrosterone,21600923,3143
+A14AA07,PRASTERONE,19035704,Calcium Carbonate,21600923,1897
+A14AA07,PRASTERONE,19037401,calcium phosphate,21600923,1919
+A14AA08,OXANDROLONE,1524769,Oxandrolone,21600924,7779
+A14AB01,NANDROLONE,1514412,Nandrolone,21600927,7244
+A14AB02,ETHYLESTRENOL,19050387,Ethylestrenol,21600928,4162
+A15,APPETITE STIMULANTS,1300978,Megestrol,21600931,6703
+A16AA,AMINO ACIDS AND DERIVATIVES,962398,Glycine,21600934,4919
+A16AA,AMINO ACIDS AND DERIVATIVES,1139042,Acetylcysteine,21600934,197
+A16AA,AMINO ACIDS AND DERIVATIVES,19000537,Threonine,21600934,10524
+A16AA,AMINO ACIDS AND DERIVATIVES,19007572,Valine,21600934,11115
+A16AA,AMINO ACIDS AND DERIVATIVES,19012686,Aspartic Acid,21600934,1169
+A16AA,AMINO ACIDS AND DERIVATIVES,19069149,Histidine,21600934,5340
+A16AA,AMINO ACIDS AND DERIVATIVES,19082306,Isoleucine,21600934,6033
+A16AA,AMINO ACIDS AND DERIVATIVES,19136716,Taurine,21600934,10337
+A16AA01,LEVOCARNITINE,1553610,Levocarnitine,21600935,42955
+A16AA03,GLUTAMINE,19060985,Glutamine,21600937,4885
+A16AB01,ALGLUCERASE,19057354,alglucerase,21600942,46049
+A16AB02,IMIGLUCERASE,1348407,imiglucerase,21600943,84959
+A16AB04,AGALSIDASE BETA,1525746,agalsidase beta,21600945,338817
+A16AB05,LARONIDASE,1543229,Laronidase,21600946,392509
+A16AB06,SACROSIDASE,951980,Sacrosidase,21600947,214817
+A16AB07,ALGLUCOSIDASE ALFA,19088328,alglucosidase alfa,21600948,629565
+A16AB08,GALSULFASE,19078649,galsulfase,21600949,578033
+A16AB09,IDURSULFASE,19091430,Idursulfase,21600950,644101
+A16AX,VARIOUS ALIMENTARY TRACT AND METABOLISM PRODUCTS,922191,pectin,21600951,32987
+A16AX,VARIOUS ALIMENTARY TRACT AND METABOLISM PRODUCTS,987128,Lactobacillus,21600951,6204
+A16AX,VARIOUS ALIMENTARY TRACT AND METABOLISM PRODUCTS,987153,Lactobacillus acidophilus,21600951,6205
+A16AX,VARIOUS ALIMENTARY TRACT AND METABOLISM PRODUCTS,988294,dexpanthenol,21600951,22701
+A16AX,VARIOUS ALIMENTARY TRACT AND METABOLISM PRODUCTS,19066563,fructooligosaccharide,21600951,259372
+A16AX01,TIOCTIC ACID,1351115,coenzyme Q10,21600952,21406
+A16AX01,TIOCTIC ACID,1386670,Thioctate,21600952,618060
+A16AX01,TIOCTIC ACID,19009540,Vitamin E,21600952,11256
+A16AX01,TIOCTIC ACID,19037596,Acetylcarnitine,21600952,193
+A16AX01,TIOCTIC ACID,19125750,Chromium Polynicotinate,21600952,700888
+A16AX03,SODIUM PHENYLBUTYRATE,1539954,phenylbutyrate,21600954,81647
+A16AX04,NITISINONE,1586640,nitisinone,21600955,61805
+A16AX06,MIGLUSTAT,19045272,Miglustat,21600957,402316
+A16AX07,SAPROPTERIN,19021959,Sapropterin,21600958,753340
+B01AA,VITAMIN K ANTAGONISTS,1332661,anisindione,21600962,17941
+B01AA01,DICOUMAROL,1325124,Dicumarol,21600963,1598
+B01AA03,WARFARIN,1310149,Warfarin,21600965,11289
+B01AA04,PHENPROCOUMON,19035344,Phenprocoumon,21600966,8150
+B01AB01,HEPARIN,1367571,Heparin,21600973,5224
+B01AB04,DALTEPARIN,1301065,Dalteparin,21600975,67109
+B01AB09,DANAPAROID,19026343,danaparoid,21600980,78484
+B01AB10,TINZAPARIN,1308473,tinzaparin,21600981,69646
+B01AC04,CLOPIDOGREL,1322184,clopidogrel,21600989,32968
+B01AC05,TICLOPIDINE,1302398,Ticlopidine,21600990,10594
+B01AC06,ACETYLSALICYLIC ACID,1112807,Aspirin,21600991,1191
+B01AC06,ACETYLSALICYLIC ACID,1551860,Pravastatin,21600991,42463
+B01AC07,DIPYRIDAMOLE,1331270,Dipyridamole,21600992,3521
+B01AC09,EPOPROSTENOL,1354118,Epoprostenol,21600994,8814
+B01AC11,ILOPROST,1344992,Iloprost,21600996,40138
+B01AC13,ABCIXIMAB,19047423,abciximab,21600997,83929
+B01AC16,EPTIFIBATIDE,1322199,eptifibatide,21600999,75635
+B01AC17,TIROFIBAN,19017067,tirofiban,21601000,73137
+B01AC21,TREPROSTINIL,1327256,Treprostinil,21601003,343048
+B01AC30,COMBINATIONS,1112807,Aspirin,21601005,1191
+B01AC30,COMBINATIONS,1331270,Dipyridamole,21601005,3521
+B01AD01,STREPTOKINASE,19136187,Streptokinase,21601007,10106
+B01AD02,ALTEPLASE,1347450,Alteplase,21601008,8410
+B01AD03,ANISTREPLASE,19044890,Anistreplase,21601009,40028
+B01AD04,UROKINASE,1307515,Urokinase,21601010,11055
+B01AD10,DROTRECOGIN ALFA (ACTIVATED),1731597,drotrecogin alfa,21601016,352374
+B01AD12,PROTEIN C,19014221,Protein C Concentrate (Human),21601018,723868
+B01AE02,LEPIRUDIN,19092139,lepirudin,21601021,237057
+B01AE03,ARGATROBAN,1322207,argatroban,21601022,15202
+B01AE06,BIVALRUDIN,19084670,bivalirudin,21601025,60819
+B01AX05,FONDAPARINUX,1315865,fondaparinux,21601030,321208
+B02AA01,AMINOCAPROIC ACID,1369939,6-Aminocaproic Acid,21601035,99
+B02AA02,TRANEXAMIC ACID,1303425,Tranexamic Acid,21601036,10691
+B02AB01,APROTININ,19000729,Aprotinin,21601039,1056
+B02AB02,ALFA1 ANTITRYPSIN,1169352,alpha 1-Antitrypsin,21601040,535
+B02AB03,C1-INHIBITOR,1333635,C1 inhibitor (Human),0,809864
+B02BA01,PHYTOMENADIONE,19044727,Vitamin K 1,21601045,8308
+B02BA02,MENADIONE,19009057,menadiol,21601046,29491
+B02BC06,THROMBIN,1300673,Thrombin,21601054,10528
+B02BD08,EPTACOG ALFA (ACTIVATED),1391474,"FACTOR VIIA,RECOMB(BHK CELLS)",21601068,236489
+B02BX04,ROMIPLOSTIM,19032407,Romiplostim,21601075,805452
+B02BX05,ELTROMBOPAG,19012346,eltrombopag,21601076,711942
+B03A,IRON PREPARATIONS,1303339,iron succinyl milk protein complex,21601078,27825
+B03A,IRON PREPARATIONS,1305063,FE HEME POLYPEPTIDE,21601078,284110
+B03A,IRON PREPARATIONS,1360067,Iron,21601078,90176
+B03A,IRON PREPARATIONS,1400498,Iron Carbonyl,21601078,262150
+B03A,IRON PREPARATIONS,19135928,Soy protein-iron complex,21601078,91495
+B03AA02,FERROUS FUMARATE,941258,Docusate,21601081,82003
+B03AA02,FERROUS FUMARATE,1521369,Norethindrone,21601081,7514
+B03AA02,FERROUS FUMARATE,1549786,Ethinyl Estradiol,21601081,4124
+B03AA02,FERROUS FUMARATE,1595799,Ferrous fumarate,21601081,24941
+B03AA03,FERROUS GLUCONATE,1396012,ferrous gluconate,21601082,24942
+B03AA07,FERROUS SULFATE,1300751,Polysaccharide iron complex,21601086,105669
+B03AA07,FERROUS SULFATE,1396131,ferrous sulfate,21601086,24947
+B03AA07,FERROUS SULFATE,1400498,Iron Carbonyl,21601086,262150
+B03AA07,FERROUS SULFATE,1595799,Ferrous fumarate,21601086,24941
+B03AA07,FERROUS SULFATE,19011773,Ascorbic Acid,21601086,1151
+B03AB02,SACCHARATED IRON OXIDE,1300751,Polysaccharide iron complex,21601093,105669
+B03AB02,SACCHARATED IRON OXIDE,1377898,Iron polysaccharide,21601093,219315
+B03AC,"IRON TRIVALENT, PARENTERAL PREPARATIONS",19055036,FERROUS CACODYLATE,21601101,235271
+B03AC02,SACCHARATED IRON OXIDE,1395773,"ferric oxide, saccharated",21601103,24909
+B03AC06,FERRIC OXIDE DEXTRAN COMPLEX,1381661,Iron-Dextran Complex,21601106,5992
+B03AC07,FERRIC SODIUM GLUCONATE COMPLEX,1399177,Sodium ferric gluconate complex,21601107,261435
+B03AD,IRON IN COMBINATION WITH FOLIC ACID,1305063,FE HEME POLYPEPTIDE,21601108,284110
+B03AD,IRON IN COMBINATION WITH FOLIC ACID,1360067,Iron,21601108,90176
+B03AD,IRON IN COMBINATION WITH FOLIC ACID,1387426,Folate,21601108,62356
+B03AD02,FERROUS FUMARATE,1387426,Folate,21601110,62356
+B03AD02,FERROUS FUMARATE,1595799,Ferrous fumarate,21601110,24941
+B03AD03,FERROUS SULFATE,1387426,Folate,21601111,62356
+B03AD03,FERROUS SULFATE,1396131,ferrous sulfate,21601111,24947
+B03AE01,"IRON, VITAMIN B12 AND FOLIC ACID",1300751,Polysaccharide iron complex,21601114,105669
+B03AE01,"IRON, VITAMIN B12 AND FOLIC ACID",1308738,Vitamin B 12,21601114,11248
+B03AE01,"IRON, VITAMIN B12 AND FOLIC ACID",1387426,Folate,21601114,62356
+B03AE02,"IRON, MULTIVITAMINS AND FOLIC ACID",1387426,Folate,21601115,62356
+B03AE02,"IRON, MULTIVITAMINS AND FOLIC ACID",1396131,ferrous sulfate,21601115,24947
+B03AE02,"IRON, MULTIVITAMINS AND FOLIC ACID",19011773,Ascorbic Acid,21601115,1151
+B03AE10,VARIOUS COMBINATIONS,941258,Docusate,21601118,82003
+B03AE10,VARIOUS COMBINATIONS,1308738,Vitamin B 12,21601118,11248
+B03AE10,VARIOUS COMBINATIONS,1360067,Iron,21601118,90176
+B03AE10,VARIOUS COMBINATIONS,1387426,Folate,21601118,62356
+B03AE10,VARIOUS COMBINATIONS,1595799,Ferrous fumarate,21601118,24941
+B03AE10,VARIOUS COMBINATIONS,19011773,Ascorbic Acid,21601118,1151
+B03BA,VITAMIN B12 (CYANOCOBALAMIN AND ANALOGUES),1139042,Acetylcysteine,21601120,197
+B03BA,VITAMIN B12 (CYANOCOBALAMIN AND ANALOGUES),19009025,mecobalamin,21601120,29421
+B03BA,VITAMIN B12 (CYANOCOBALAMIN AND ANALOGUES),19048046,L-METHYLFOLATE,21601120,407884
+B03BA,VITAMIN B12 (CYANOCOBALAMIN AND ANALOGUES),19091701,Liver Extract,21601120,6459
+B03BA01,CYANOCOBALAMIN,1308738,Vitamin B 12,21601121,11248
+B03BA03,HYDROXOCOBALAMIN,1377023,Hydroxocobalamin,21601123,5514
+B03BA05,MECOBALAMIN,19009025,mecobalamin,21601125,29421
+B03BA05,MECOBALAMIN,19059817,Pyridoxal,21601125,9002
+B03BA05,MECOBALAMIN,19112915,methylfolic acid,21601125,486456
+B03BA51,"CYANOCOBALAMIN, COMBINATIONS",1308738,Vitamin B 12,21601126,11248
+B03BA51,"CYANOCOBALAMIN, COMBINATIONS",1353228,Vitamin B6,21601126,42954
+B03BA51,"CYANOCOBALAMIN, COMBINATIONS",1380472,Intrinsic factor,21601126,5920
+B03BA51,"CYANOCOBALAMIN, COMBINATIONS",1387426,Folate,21601126,62356
+B03BA51,"CYANOCOBALAMIN, COMBINATIONS",19005046,pyridoxine,21601126,684879
+B03BA51,"CYANOCOBALAMIN, COMBINATIONS",19009025,mecobalamin,21601126,29421
+B03BA51,"CYANOCOBALAMIN, COMBINATIONS",19048026,cobamamide,21601126,21373
+B03BB01,FOLIC ACID,1387426,Folate,21601129,62356
+B03BB01,FOLIC ACID,19048046,L-METHYLFOLATE,21601129,407884
+B03BB51,"FOLIC ACID, COMBINATIONS",1387426,Folate,21601130,62356
+B03BB51,"FOLIC ACID, COMBINATIONS",19011773,Ascorbic Acid,21601130,1151
+B03XA01,ERYTHROPOIETIN,1301125,Epoetin Alfa,21601133,105694
+B03XA02,DARBEPOETIN ALFA,1304643,darbepoetin alfa,21601134,283838
+B05AA01,ALBUMIN,1344143,"Albumin Human, USP",21601139,828529
+B05AA02,OTHER PLASMA PROTEIN FRACTIONS,19025693,plasma protein fraction,21601140,33835
+B05AA05,DEXTRAN,1319156,Dextran 70,21601142,3274
+B05AA05,DEXTRAN,19019122,Dextran 40,21601142,3272
+B05AA05,DEXTRAN,19019193,Dextran 75,21601142,3275
+B05AA05,DEXTRAN,19051646,Dextran 1,21601142,214485
+B05AA07,HYDROXYETHYLSTARCH,19077117,Hetastarch,21601144,5531
+B05BA01,AMINO ACIDS,19010955,Cysteine,21601155,3024
+B05BA02,FAT EMULSIONS,961145,Glycerin,21601156,4910
+B05BA02,FAT EMULSIONS,19013789,EGG YOLK PHOSPHOLIPIDS,21601156,314605
+B05BA02,FAT EMULSIONS,19070224,Soybean Oil,21601156,9949
+B05BA03,CARBOHYDRATES,956691,Fructose,21601157,4570
+B05BA03,CARBOHYDRATES,1560524,Glucose,21601157,4850
+B05BA10,COMBINATIONS,19003107,invert sugar,21601159,27712
+B05BB01,ELECTROLYTES,904826,Lactic acid,21601161,28393
+B05BB01,ELECTROLYTES,967823,Sodium Chloride,21601161,9863
+B05BB01,ELECTROLYTES,19036781,Calcium Chloride,21601161,1901
+B05BB01,ELECTROLYTES,19049105,Potassium Chloride,21601161,8591
+B05BB01,ELECTROLYTES,19092849,Magnesium Chloride,21601161,6579
+B05BB01,ELECTROLYTES,19093848,Magnesium Sulfate,21601161,6585
+B05BB02,ELECTROLYTES WITH CARBOHYDRATES,904826,Lactic acid,21601162,28393
+B05BB02,ELECTROLYTES WITH CARBOHYDRATES,967823,Sodium Chloride,21601162,9863
+B05BB02,ELECTROLYTES WITH CARBOHYDRATES,1560524,Glucose,21601162,4850
+B05BB02,ELECTROLYTES WITH CARBOHYDRATES,19036781,Calcium Chloride,21601162,1901
+B05BB02,ELECTROLYTES WITH CARBOHYDRATES,19049105,Potassium Chloride,21601162,8591
+B05BB03,TROMETAMOL,19006047,Tromethamine,21601163,10865
+B05BC01,MANNITOL,994058,Mannitol,21601165,6628
+B05BC02,CARBAMIDE,906914,Urea,21601166,11002
+B05CA10,COMBINATIONS,915981,Neomycin,21601178,7299
+B05CA10,COMBINATIONS,948582,Polymyxin B,21601178,8536
+B05CB01,SODIUM CHLORIDE,967823,Sodium Chloride,21601180,9863
+B05CB10,COMBINATIONS,904826,Lactic acid,21601184,28393
+B05CB10,COMBINATIONS,967823,Sodium Chloride,21601184,9863
+B05CB10,COMBINATIONS,19036781,Calcium Chloride,21601184,1901
+B05CB10,COMBINATIONS,19049105,Potassium Chloride,21601184,8591
+B05CX,OTHER IRRIGATING SOLUTIONS,904826,Lactic acid,21601185,28393
+B05CX,OTHER IRRIGATING SOLUTIONS,929549,Acetic Acid,21601185,168
+B05CX,OTHER IRRIGATING SOLUTIONS,967823,Sodium Chloride,21601185,9863
+B05CX,OTHER IRRIGATING SOLUTIONS,19036781,Calcium Chloride,21601185,1901
+B05CX,OTHER IRRIGATING SOLUTIONS,19049105,Potassium Chloride,21601185,8591
+B05CX02,SORBITOL,970011,Sorbitol,21601187,9945
+B05CX03,GLYCINE,962398,Glycine,21601188,4919
+B05CX04,MANNITOL,994058,Mannitol,21601189,6628
+B05CX10,COMBINATIONS,970011,Sorbitol,21601190,9945
+B05CX10,COMBINATIONS,994058,Mannitol,21601190,6628
+B05XA,ELECTROLYTE SOLUTIONS,904826,Lactic acid,21601195,28393
+B05XA,ELECTROLYTE SOLUTIONS,19092849,Magnesium Chloride,21601195,6579
+B05XA,ELECTROLYTE SOLUTIONS,19093848,Magnesium Sulfate,21601195,6585
+B05XA01,POTASSIUM CHLORIDE,19049105,Potassium Chloride,21601196,8591
+B05XA02,SODIUM BICARBONATE,939506,Sodium Bicarbonate,21601197,36676
+B05XA03,SODIUM CHLORIDE,967823,Sodium Chloride,21601198,9863
+B05XA03,SODIUM CHLORIDE,19081343,"Sodium Chloride, Bacteriostatic",21601198,219965
+B05XA04,AMMONIUM CHLORIDE,912362,Ammonium Chloride,21601199,712
+B05XA05,MAGNESIUM SULFATE,19093848,Magnesium Sulfate,21601200,6585
+B05XA06,"POTASSIUM PHOS,INCL. COMB W/OTHER POTASSIUM SALTS",19027362,potassium phosphate,21601201,34322
+B05XA06,"POTASSIUM PHOS,INCL. COMB W/OTHER POTASSIUM SALTS",19049024,Potassium,21601201,8588
+B05XA07,CALCIUM CHLORIDE,19036781,Calcium Chloride,21601202,1901
+B05XA08,SODIUM ACETATE,19077884,Sodium Acetate,21601203,56443
+B05XA09,SODIUM PHOSPHATE,939871,sodium phosphate,21601204,36709
+B05XA12,ZINC CHLORIDE,19044317,zinc chloride,21601207,39937
+B05XA13,HYDROCHLORIC ACID,974140,Hydrochloric Acid,21601208,5486
+B05XA17,POTASSIUM ACETATE,19076414,Potassium Acetate,21601212,54987
+B06AA03,HYALURONIDASE,19073699,Hyaluronidase,21601229,5464
+B06AA04,CHYMOTRYPSIN,19096710,CHYMOTRYPSIN,21601230,2530
+B06AB01,HEMATIN,19067303,Hemin,21601236,5175
+C01AA03,DIGITALIS LEAVES,19054998,DIGITALIS LEAF,21601243,235219
+C01AA03,DIGITALIS LEAVES,19060903,Digitalis preparation,21601243,91235
+J06AA06,RABIES SERUM,544509,"rabies immune globulin, (human) vaccine",21601253,830471
+J06BA01,"IMMUNOGLOBULINS,NORMAL HUMAN,FOR EXTRAVASCULAR ADM",19117912,Immunoglobulin G,21601256,5666
+J06BA02,"IMMUNOGLOBULINS,NORMAL HUMAN,FOR INTRAVASCULAR ADM",19117912,Immunoglobulin G,21601257,5666
+J06BB,SPECIFIC IMMUNOGLOBULINS,19013765,respiratory syncytial virus immune globulin intravenous,21601258,119246
+J06BB01,ANTI-D (RH) IMMUNOGLOBULIN,535714,Rho(D) Immune Globulin,21601259,35465
+J06BB03,VARICELLA/ZOSTER IMMUNOGLOBULIN,543291,varicella-zoster immune globulin,21601261,39385
+J06BB04,HEPATITIS B IMMUNOGLOBULIN,501343,hepatitis B immune globulin,21601262,26744
+J06BB05,RABIES IMMUNOGLOBULIN,544509,"rabies immune globulin, (human) vaccine",21601263,830471
+J06BB09,CYTOMEGALOVIRUS IMMUNOGLOBULIN,586491,cytotect,21601267,22178
+J06BB16,PALIVIZUMAB,537647,palivizumab,21601274,194279
+J07AG51,"HEMOPHILUS INFLUENZAE B, COMBINATIONS WITH TOXOIDS",529118,"Haemophilus influenzae b, capsular polysaccharide inactivated tetanus toxoid conjugate vaccine",21601292,798279
+J07AG51,"HEMOPHILUS INFLUENZAE B, COMBINATIONS WITH TOXOIDS",529218,Acellular Pertussis Vaccine,21601292,798302
+J07AG51,"HEMOPHILUS INFLUENZAE B, COMBINATIONS WITH TOXOIDS",529303,Diphtheria Toxoid Vaccine,21601292,798304
+J07AG51,"HEMOPHILUS INFLUENZAE B, COMBINATIONS WITH TOXOIDS",529411,Tetanus Toxoid Vaccine,21601292,798306
+J07AG53,"HEMOPHILUS INFLUENZAE B, COMBOS W/MENING C, CONJ",530007,Haemophilus influenzae b (Ross strain) capsular polysaccharide Meningococcal Protein Conjugate Vaccine,21601294,798444
+J07AG53,"HEMOPHILUS INFLUENZAE B, COMBOS W/MENING C, CONJ",19056377,HAEMOPH B POLYSAC CONJ-MENING,21601294,236568
+J07AH04,"MENINGOCOCCUS, TETRAVALENT PURIF POLYSAC ANTIGEN",509079,meningococcal group A polysaccharide,21601299,29501
+J07AH04,"MENINGOCOCCUS, TETRAVALENT PURIF POLYSAC ANTIGEN",509081,meningococcal group C polysaccharide,21601299,29503
+J07AH04,"MENINGOCOCCUS, TETRAVALENT PURIF POLYSAC ANTIGEN",514012,MENINGOCOCCAL POLYSACCHARIDE VACCINE GROUP W-135,21601299,314724
+J07AH04,"MENINGOCOCCUS, TETRAVALENT PURIF POLYSAC ANTIGEN",514015,MENINGOCOCCAL POLYSACCHARIDE VACCINE GROUP Y,21601299,314725
+J07AH08,"MENINGOCOCCUS, TETRAVAL PURIF POLYSAC ANTIGEN CONJ",528271,Neisseria meningitidis serogroup A capsular polysaccharide diphtheria toxoid protein conjugate vaccine,21601303,797629
+J07AH08,"MENINGOCOCCUS, TETRAVAL PURIF POLYSAC ANTIGEN CONJ",528295,Neisseria meningitidis serogroup C capsular polysaccharide diphtheria toxoid protein conjugate vaccine,21601303,797631
+J07AH08,"MENINGOCOCCUS, TETRAVAL PURIF POLYSAC ANTIGEN CONJ",528297,Neisseria meningitidis serogroup W-135 capsular polysaccharide diphtheria toxoid protein conjugate vaccine,21601303,797633
+J07AH08,"MENINGOCOCCUS, TETRAVAL PURIF POLYSAC ANTIGEN CONJ",528301,Neisseria meningitidis serogroup Y capsular polysaccharide diphtheria toxoid protein conjugate vaccine,21601303,797635
+J07AJ51,"PERTUSSIS, INACT, WHOLE CELL, COMBOS W/TOXOIDS",529118,"Haemophilus influenzae b, capsular polysaccharide inactivated tetanus toxoid conjugate vaccine",21601307,798279
+J07AJ51,"PERTUSSIS, INACT, WHOLE CELL, COMBOS W/TOXOIDS",529218,Acellular Pertussis Vaccine,21601307,798302
+J07AJ51,"PERTUSSIS, INACT, WHOLE CELL, COMBOS W/TOXOIDS",529303,Diphtheria Toxoid Vaccine,21601307,798304
+J07AJ51,"PERTUSSIS, INACT, WHOLE CELL, COMBOS W/TOXOIDS",529411,Tetanus Toxoid Vaccine,21601307,798306
+J07AJ51,"PERTUSSIS, INACT, WHOLE CELL, COMBOS W/TOXOIDS",551943,"Pertussis, acellular",21601307,214755
+J07AJ52,"PERTUSSIS, PURIFIED ANTIGEN, COMBOS WITH TOXOIDS",529118,"Haemophilus influenzae b, capsular polysaccharide inactivated tetanus toxoid conjugate vaccine",21601308,798279
+J07AJ52,"PERTUSSIS, PURIFIED ANTIGEN, COMBOS WITH TOXOIDS",529218,Acellular Pertussis Vaccine,21601308,798302
+J07AJ52,"PERTUSSIS, PURIFIED ANTIGEN, COMBOS WITH TOXOIDS",529303,Diphtheria Toxoid Vaccine,21601308,798304
+J07AJ52,"PERTUSSIS, PURIFIED ANTIGEN, COMBOS WITH TOXOIDS",529411,Tetanus Toxoid Vaccine,21601308,798306
+J07AJ52,"PERTUSSIS, PURIFIED ANTIGEN, COMBOS WITH TOXOIDS",551943,"Pertussis, acellular",21601308,214755
+J07AL02,"PNEUMOCOCCUS, PURIF POLYSACCHARIDES ANTIGEN CONJ",528986,Streptococcus pneumoniae serotype 14 capsular antigen diphtheria CRM197 protein conjugate vaccine,21601313,798220
+J07AL02,"PNEUMOCOCCUS, PURIF POLYSACCHARIDES ANTIGEN CONJ",528988,Streptococcus pneumoniae serotype 18C capsular antigen diphtheria CRM197 protein conjugate vaccine,21601313,798222
+J07AL02,"PNEUMOCOCCUS, PURIF POLYSACCHARIDES ANTIGEN CONJ",528990,Streptococcus pneumoniae serotype 19F capsular antigen diphtheria CRM197 protein conjugate vaccine,21601313,798224
+J07AL02,"PNEUMOCOCCUS, PURIF POLYSACCHARIDES ANTIGEN CONJ",529042,Streptococcus pneumoniae serotype 23F capsular antigen diphtheria CRM197 protein conjugate vaccine,21601313,798226
+J07AL02,"PNEUMOCOCCUS, PURIF POLYSACCHARIDES ANTIGEN CONJ",529044,Streptococcus pneumoniae serotype 4 capsular antigen diphtheria CRM197 protein conjugate vaccine,21601313,798228
+J07AL02,"PNEUMOCOCCUS, PURIF POLYSACCHARIDES ANTIGEN CONJ",529046,Streptococcus pneumoniae serotype 6B capsular antigen diphtheria CRM197 protein conjugate vaccine,21601313,798230
+J07AL02,"PNEUMOCOCCUS, PURIF POLYSACCHARIDES ANTIGEN CONJ",529072,Streptococcus pneumoniae serotype 9V capsular antigen diphtheria CRM197 protein conjugate vaccine,21601313,798232
+J07AM01,TETANUS TOXOID,529411,Tetanus Toxoid Vaccine,21601316,798306
+J07AM51,"TETANUS TOXOID, COMBINATIONS W/DIPHTHERIA TOXOID",529303,Diphtheria Toxoid Vaccine,21601317,798304
+J07AM51,"TETANUS TOXOID, COMBINATIONS W/DIPHTHERIA TOXOID",529411,Tetanus Toxoid Vaccine,21601317,798306
+J07AP03,"TYPHOID, PURIFIED POLYSACCHARIDE ANTIGEN",532881,"Typhoid Vi Polysaccharide Vaccine, S typhi Ty2 strain",21601324,807219
+J07AX,OTHER BACTERIAL VACCINES,551463,Lyme Disease Vaccine,21601328,214177
+J07BC01,"HEPATITIS B, PURIFIED ANTIGEN",501488,Hepatitis B Vaccine,21601338,26746
+J07BC01,"HEPATITIS B, PURIFIED ANTIGEN",528323,Hepatitis B Surface Antigen Vaccine,21601338,797752
+J07BC01,"HEPATITIS B, PURIFIED ANTIGEN",19030114,"Hepatitis B Surface Antigen (Australia antigen) MSD, Vaccine",21601338,798456
+J07BC02,"HEPATITIS A, INACTIVATED, WHOLE VIRUS",596876,"Hepatitis A Vaccine, Inactivated",21601339,253174
+J07BC20,COMBINATIONS,501488,Hepatitis B Vaccine,21601340,26746
+J07BC20,COMBINATIONS,596876,"Hepatitis A Vaccine, Inactivated",21601340,253174
+J07BG01,"RABIES, INACTIVATED, WHOLE VIRUS",544505,rabies virus vaccine wistar strain PM-1503-3M (Human),21601354,830464
+J07BH01,"ROTA VIRUS, LIVE ATTENUATED",19032599,"Rotavirus Vaccine, Live Attenuated, G1P[8] Human 89-12 strain",21601356,805573
+J07BM01,"PAPILLOMAVIRUS (HUMAN TYPES 6,11,16,18)",529076,"L1 protein, Human papillomavirus type 11 Vaccine",21601367,798262
+J07BM01,"PAPILLOMAVIRUS (HUMAN TYPES 6,11,16,18)",529112,"L1 protein, Human papillomavirus type 16 Vaccine",21601367,798264
+J07BM01,"PAPILLOMAVIRUS (HUMAN TYPES 6,11,16,18)",529114,"L1 protein, Human papillomavirus type 18 Vaccine",21601367,798266
+J07BM01,"PAPILLOMAVIRUS (HUMAN TYPES 6,11,16,18)",529116,"L1 protein, Human papillomavirus type 6 Vaccine",21601367,798268
+J07CA06,DIPHTHERIA-HEMOPH INFLUENZAE B-PERTUSSIS-POLIO-TET,529118,"Haemophilus influenzae b, capsular polysaccharide inactivated tetanus toxoid conjugate vaccine",21601377,798279
+J07CA06,DIPHTHERIA-HEMOPH INFLUENZAE B-PERTUSSIS-POLIO-TET,529218,Acellular Pertussis Vaccine,21601377,798302
+J07CA06,DIPHTHERIA-HEMOPH INFLUENZAE B-PERTUSSIS-POLIO-TET,529303,Diphtheria Toxoid Vaccine,21601377,798304
+J07CA06,DIPHTHERIA-HEMOPH INFLUENZAE B-PERTUSSIS-POLIO-TET,529411,Tetanus Toxoid Vaccine,21601377,798306
+J07CA06,DIPHTHERIA-HEMOPH INFLUENZAE B-PERTUSSIS-POLIO-TET,19031464,"Inactivated Polioviruses Type 1, Mahoney strain vaccine",21601377,801830
+J07CA06,DIPHTHERIA-HEMOPH INFLUENZAE B-PERTUSSIS-POLIO-TET,19031466,"Inactivated Polioviruses Type 2, MEF-1 strain vaccine",21601377,801832
+J07CA06,DIPHTHERIA-HEMOPH INFLUENZAE B-PERTUSSIS-POLIO-TET,19031468,"Inactivated Polioviruses Type 3, Saukett strain vaccine",21601377,801834
+L01AA01,CYCLOPHOSPHAMIDE,1310317,Cyclophosphamide,21601390,3002
+L01AA02,CHLORAMBUCIL,1390051,Chlorambucil,21601391,2346
+L01AA03,MELPHALAN,1301267,Melphalan,21601392,6718
+L01AA05,CHLORMETHINE,1394337,Mechlorethamine,21601393,6674
+L01AA06,IFOSFAMIDE,1354698,Mesna,21601394,44
+L01AA06,IFOSFAMIDE,19078187,Ifosfamide,21601394,5657
+L01AA09,BENDAMUSTINE,19015523,bendamustine,21601397,134547
+L01AB01,BUSULFAN,1333357,Busulfan,21601399,1828
+L01AC01,THIOTEPA,19137385,Thiotepa,21601403,10473
+L01AD01,CARMUSTINE,1350066,Carmustine,21601407,2105
+L01AD02,LOMUSTINE,1391846,Lomustine,21601408,6466
+L01AD04,STREPTOZOCIN,19136210,Streptozocin,21601410,10114
+L01AX02,PIPOBROMAN,19046625,Pipobroman,21601418,8347
+L01AX03,TEMOZOLOMIDE,1341149,temozolomide,21601419,37776
+L01AX04,DACARBAZINE,1311409,Dacarbazine,21601420,3098
+L01BA01,METHOTREXATE,1305058,Methotrexate,21601423,6851
+L01BA04,PEMETREXED,1304919,pemetrexed,21601425,68446
+L01BB02,MERCAPTOPURINE,1436650,6-Mercaptopurine,21601428,103
+L01BB03,TIOGUANINE,1437379,Thioguanine,21601429,10485
+L01BB04,CLADRIBINE,19054825,Cladribine,21601430,44157
+L01BB05,FLUDARABINE,1395557,fludarabine,21601431,24698
+L01BB06,CLOFARABINE,19054821,clofarabine,21601432,44151
+L01BB07,NELARABINE,19002912,nelarabine,21601433,274771
+L01BC,PYRIMIDINE ANALOGUES,1355509,Floxuridine,21601434,4488
+L01BC01,CYTARABINE,1311078,Cytarabine,21601435,3041
+L01BC01,CYTARABINE,19041067,cytarabine liposomal,21601435,81932
+L01BC02,FLUOROURACIL,955632,Fluorouracil,21601436,4492
+L01BC05,GEMCITABINE,1314924,gemcitabine,21601439,12574
+L01BC06,CAPECITABINE,1337620,capecitabine,21601440,194000
+L01BC07,AZACITABINE,1314865,Azacitidine,21601441,1251
+L01BC08,DECITABINE,19024728,decitabine,21601442,15657
+L01CA01,VINBLASTINE,19008264,Vinblastine,21601447,11198
+L01CA02,VINCRISTINE,1308290,Vincristine,21601448,11202
+L01CA04,VINORELBINE,1343346,vinorelbine,21601450,39541
+C03AA01,BENDROFLUMETHIAZIDE,1316354,Bendroflumethiazide,21601464,1369
+C03AA02,HYDROFLUMETHIAZIDE,1376289,Hydroflumethiazide,21601465,5495
+C03AA03,HYDROCHLOROTHIAZIDE,974166,Hydrochlorothiazide,21601466,5487
+C03AA04,CHLOROTHIAZIDE,992590,Chlorothiazide,21601467,2396
+C03AA05,POLYTHIAZIDE,948787,Polythiazide,21601468,8565
+C03AA06,TRICHLORMETHIAZIDE,904639,Trichlormethiazide,21601469,10772
+C03AA08,METHYCLOTHIAZIDE,905273,Methyclothiazide,21601471,6860
+C03AA09,CYCLOTHIAZIDE,19082886,cyclothiazide,21601472,22033
+C03BA04,CHLORTALIDONE,1395058,Chlorthalidone,21601493,2409
+C03BA08,METOLAZONE,907013,Metolazone,21601496,6916
+C03BA11,INDAPAMIDE,978555,Indapamide,21601499,5764
+C03BB02,QUINETHAZONE AND POTASSIUM,19081320,quinethazone,21601504,59743
+C03BD,XANTHINE DERIVATIVES,912362,Ammonium Chloride,21601511,712
+C03BD,XANTHINE DERIVATIVES,1134439,Caffeine,21601511,1886
+C03CA01,FUROSEMIDE,956874,Furosemide,21601518,4603
+C03CA02,BUMETANIDE,932745,Bumetanide,21601519,1808
+C03CA04,TORASEMIDE,942350,torsemide,21601521,38413
+C03CC01,ETACRYNIC ACID,987406,Ethacrynate,21601526,62349
+C03DA01,SPIRONOLACTONE,970250,Spironolactone,21601534,9997
+C03DA04,EPLERENONE,1309799,eplerenone,21601537,298869
+C03DB01,AMILORIDE,991382,Amiloride,21601539,644
+C03DB02,TRIAMTERENE,904542,Triamterene,21601540,10763
+C03EA01,HYDROCHLOROTHIAZIDE AND POTASSIUM-SPARING AGENTS,904542,Triamterene,21601543,10763
+C03EA01,HYDROCHLOROTHIAZIDE AND POTASSIUM-SPARING AGENTS,970250,Spironolactone,21601543,9997
+C03EA01,HYDROCHLOROTHIAZIDE AND POTASSIUM-SPARING AGENTS,974166,Hydrochlorothiazide,21601543,5487
+C03EA01,HYDROCHLOROTHIAZIDE AND POTASSIUM-SPARING AGENTS,991382,Amiloride,21601543,644
+C03XA01,TOLVAPTAN,19036797,tolvaptan,21601558,358257
+C03XA02,CONIVAPTAN,19010927,conivaptan,21601559,302285
+C04A,PERIPHERAL VASODILATORS,19095288,ethaverine,21601561,24464
+C04AA01,ISOXSUPRINE,1384360,Isoxsuprine,21601563,6066
+C04AA02,BUPHENINE,19022494,Nylidrin,21601564,7595
+C04AB01,PHENTOLAMINE,1335539,Phentolamine,21601567,8153
+C04AB02,TOLAZOLINE,19002829,Tolazoline,21601568,10634
+C04AC01,NICOTINIC ACID,1517824,Niacin,21601570,7393
+C04AC02,NICOTINYL ALCOHOL (PYRIDYLCARBINOL),19018823,Nicotinyl Alcohol,21601571,7414
+C04AD03,PENTOXIFYLLINE,1331247,Pentoxifylline,21601577,8013
+C04AE01,ERGOLOID MESYLATES,745268,"ergoloid mesylates, USP",21601580,4024
+C04AX,OTHER PERIPHERAL VASODILATORS,19008269,Vincamine,21601587,11201
+C04AX,OTHER PERIPHERAL VASODILATORS,19098505,GINKGO BILOBA LEAF,21601587,259265
+C04AX01,CYCLANDELATE,1309323,Cyclandelate,21601588,2970
+C04AX02,PHENOXYBENZAMINE,1335301,Phenoxybenzamine,21601589,8149
+C04AX33,CILOSTAZOL,1350310,cilostazol,0,21107
+C05AA01,HYDROCORTISONE,927478,pramoxine,21601608,34347
+C05AA01,HYDROCORTISONE,957797,Psyllium,21601608,8928
+C05AA01,HYDROCORTISONE,975125,Hydrocortisone,21601608,5492
+C05AA01,HYDROCORTISONE,989878,Lidocaine,21601608,6387
+C05AD01,LIDOCAINE,989878,Lidocaine,21601618,6387
+C05AD03,BENZOCAINE,916802,Benzethonium,21601620,1390
+C05AD03,BENZOCAINE,917006,Benzocaine,21601620,1399
+C05AD04,CINCHOCAINE,923840,Dibucaine,21601621,3339
+C05AD07,PRAMOCAINE,911064,Zinc Oxide,21601624,11423
+C05AD07,PRAMOCAINE,927478,pramoxine,21601624,34347
+C05AD07,PRAMOCAINE,961145,Glycerin,21601624,4910
+C05AD07,PRAMOCAINE,1135766,Phenylephrine,21601624,8163
+C05AX03,"OTHER PREPARATIONS, COMBINATIONS",959196,Witch Hazel,21601631,89821
+C05AX03,"OTHER PREPARATIONS, COMBINATIONS",961145,Glycerin,21601631,4910
+C05AX03,"OTHER PREPARATIONS, COMBINATIONS",1135766,Phenylephrine,21601631,8163
+C05AX04,ZINC PREPARATIONS,911064,Zinc Oxide,21601632,11423
+C05AX04,ZINC PREPARATIONS,1135766,Phenylephrine,21601632,8163
+C05BA04,PENTOSAN POLYSULFATE SODIUM,924151,Pentosan Polysulfate,21601639,155046
+C05BB01,MONOETHANOLAMINE OLEATE,19095285,ethanolamine oleate,21601643,24460
+C05BB03,INVERT SUGAR,19003107,invert sugar,21601645,27712
+C05BB04,SODIUM TETRADECYL SULFATE,19070012,Sodium Tetradecyl Sulfate,21601646,9913
+C05BX,OTHER SCLEROSING AGENTS,19069904,Sodium Morrhuate,21601649,9892
+C05CA,BIOFLAVONOIDS,19024669,Bioflavonoids,21601653,1562
+C05CA01,RUTOSIDE,19063981,Rutin,21601654,9500
+C05CA03,DIOSMIN,19029488,Diosmin,21601656,3489
+C05CA53,"DIOSMIN, COMBINATIONS",19029488,Diosmin,21601660,3489
+C05CA53,"DIOSMIN, COMBINATIONS",19068688,Hesperidin,21601660,5281
+C07AA03,PINDOLOL,1345858,Pindolol,21601669,8332
+C07AA05,PROPRANOLOL,1353766,Propranolol,21601670,8787
+C07AA06,TIMOLOL,902427,Timolol,21601671,10600
+C07AA07,SOTALOL,1370109,Sotalol,21601672,9947
+C07AA12,NADOLOL,1313200,Nadolol,21601673,7226
+C07AA15,CARTEOLOL,950370,Carteolol,21601675,2116
+C07AA23,PENBUTOLOL,1327978,Penbutolol,21601679,7973
+C07AB02,METOPROLOL,1307046,Metoprolol,21601684,6918
+C07AB03,ATENOLOL,1314002,Atenolol,21601685,1202
+C07AB04,ACEBUTOLOL,1319998,Acebutolol,21601686,149
+C07AB05,BETAXOLOL,1322081,Betaxolol,21601687,1520
+C07AB07,BISOPROLOL,1338005,Bisoprolol,21601689,19484
+C07AB09,ESMOLOL,19063575,esmolol,21601691,49737
+C07AB12,NEBIVOLOL,1314577,nebivolol,21601694,31555
+C07AG01,LABETALOL,1386957,Labetalol,21601699,6185
+C07AG02,CARVEDILOL,1346823,carvedilol,21601700,20352
+C07BA06,TIMOLOL AND THIAZIDES,902427,Timolol,21601705,10600
+C07BA06,TIMOLOL AND THIAZIDES,974166,Hydrochlorothiazide,21601705,5487
+C07BA12,NADOLOL AND THIAZIDES,1313200,Nadolol,21601707,7226
+C07BA12,NADOLOL AND THIAZIDES,1316354,Bendroflumethiazide,21601707,1369
+C07BB02,METOPROLOL AND THIAZIDES,974166,Hydrochlorothiazide,21601710,5487
+C07BB02,METOPROLOL AND THIAZIDES,1307046,Metoprolol,21601710,6918
+C07BG01,LABETALOL AND THIAZIDES,974166,Hydrochlorothiazide,21601717,5487
+C07BG01,LABETALOL AND THIAZIDES,1386957,Labetalol,21601717,6185
+C07CB03,ATENOLOL AND OTHER DIURETICS,1314002,Atenolol,21601726,1202
+C07CB03,ATENOLOL AND OTHER DIURETICS,1395058,Chlorthalidone,21601726,2409
+C08CA,DIHYDROPYRIDINE DERIVATIVES,19089969,clevidipine,21601746,233603
+C08CA01,AMLODIPINE,1332418,Amlodipine,21601747,17767
+C08CA02,FELODIPINE,1353776,Felodipine,21601748,4316
+C08CA03,ISRADIPINE,1326012,Isradipine,21601749,33910
+C08CA04,NICARDIPINE,1318137,Nicardipine,21601750,7396
+C08CA05,NIFEDIPINE,1318853,Nifedipine,21601751,7417
+C08CA06,NIMODIPINE,1319133,Nimodipine,21601752,7426
+C08CA07,NISOLDIPINE,1319880,Nisoldipine,21601753,7435
+C08CX01,MIBEFRADIL,1345141,Mibefradil,21601764,83213
+C08DA01,VERAPAMIL,1307863,Verapamil,21601767,11170
+C08DB01,DILTIAZEM,1328165,Diltiazem,21601771,3443
+C08EA02,BEPRIDIL,1319751,Bepridil,21601775,1436
+C09AA01,CAPTOPRIL,1340128,Captopril,21601785,1998
+C09AA02,ENALAPRIL,1341927,Enalapril,21601786,3827
+C09AA02,ENALAPRIL,1342001,Enalaprilat,21601786,3829
+C09AA03,LISINOPRIL,1308216,Lisinopril,21601787,29046
+C09AA05,RAMIPRIL,1334456,Ramipril,21601789,35296
+C09AA06,QUINAPRIL,1331235,quinapril,21601790,35208
+C09AA07,BENAZEPRIL,1335471,benazepril,21601791,18867
+C09AA10,TRANDOLAPRIL,1342439,trandolapril,21601794,38454
+C09AA13,MOEXIPRIL,1310756,moexipril,21601797,30131
+C09BA01,CAPTOPRIL AND DIURETICS,974166,Hydrochlorothiazide,21601803,5487
+C09BA01,CAPTOPRIL AND DIURETICS,1340128,Captopril,21601803,1998
+C09BA02,ENALAPRIL AND DIURETICS,974166,Hydrochlorothiazide,21601804,5487
+C09BA02,ENALAPRIL AND DIURETICS,1341927,Enalapril,21601804,3827
+C09BA03,LISINOPRIL AND DIURETICS,974166,Hydrochlorothiazide,21601805,5487
+C09BA03,LISINOPRIL AND DIURETICS,1308216,Lisinopril,21601805,29046
+C09BA06,QUINAPRIL AND DIURETICS,974166,Hydrochlorothiazide,21601808,5487
+C09BA06,QUINAPRIL AND DIURETICS,1331235,quinapril,21601808,35208
+C09BA07,BENAZEPRIL AND DIURETICS,974166,Hydrochlorothiazide,21601809,5487
+C09BA07,BENAZEPRIL AND DIURETICS,1335471,benazepril,21601809,18867
+C09BA13,MOXEIPRIL AND DIURETICS,974166,Hydrochlorothiazide,21601813,5487
+C09BA13,MOXEIPRIL AND DIURETICS,1310756,moexipril,21601813,30131
+C09BB,ACE INHIBITORS AND CALCIUM CHANNEL BLOCKERS,1332418,Amlodipine,21601815,17767
+C09BB,ACE INHIBITORS AND CALCIUM CHANNEL BLOCKERS,1335471,benazepril,21601815,18867
+C09BB,ACE INHIBITORS AND CALCIUM CHANNEL BLOCKERS,1341927,Enalapril,21601815,3827
+C09BB,ACE INHIBITORS AND CALCIUM CHANNEL BLOCKERS,1353776,Felodipine,21601815,4316
+C09BB10,TRANDOLAPRIL AND VERAPAMIL,1307863,Verapamil,21601820,11170
+C09BB10,TRANDOLAPRIL AND VERAPAMIL,1342439,trandolapril,21601820,38454
+C09CA01,LOSARTAN,1367500,Losartan,21601824,52175
+C09CA02,EPROSARTAN,1346686,eprosartan,21601825,83515
+C09CA03,VALSARTAN,1308842,valsartan,21601826,69749
+C09CA04,IRBESARTAN,1347384,irbesartan,21601827,83818
+C09CA06,CANDESARTAN,1351557,candesartan,21601829,214354
+C09CA07,TELMISARTAN,1317640,telmisartan,21601830,73494
+C09CA08,OLMESARTAN MEDOXOMIL,1312742,Olmesartan medoxomil,21601831,118463
+C09DA01,LOSARTAN AND DIURETICS,974166,Hydrochlorothiazide,21601834,5487
+C09DA01,LOSARTAN AND DIURETICS,1367500,Losartan,21601834,52175
+C09DA02,EPROSARTAN AND DIURETICS,974166,Hydrochlorothiazide,21601835,5487
+C09DA02,EPROSARTAN AND DIURETICS,1346686,eprosartan,21601835,83515
+C09DA03,VALSARTAN AND DIURETICS,974166,Hydrochlorothiazide,21601836,5487
+C09DA03,VALSARTAN AND DIURETICS,1308842,valsartan,21601836,69749
+C09DA04,IRBESARTAN AND DIURETICS,974166,Hydrochlorothiazide,21601837,5487
+C09DA04,IRBESARTAN AND DIURETICS,1347384,irbesartan,21601837,83818
+C09DA06,CANDESARTAN AND DIURETICS,974166,Hydrochlorothiazide,21601838,5487
+C09DA06,CANDESARTAN AND DIURETICS,1351557,candesartan,21601838,214354
+C09DA07,TELMISARTAN AND DIURETICS,974166,Hydrochlorothiazide,21601839,5487
+C09DA07,TELMISARTAN AND DIURETICS,1317640,telmisartan,21601839,73494
+C09DA08,OLMESARTAN MEDOXOMIL AND DIURETICS,974166,Hydrochlorothiazide,21601840,5487
+C09DA08,OLMESARTAN MEDOXOMIL AND DIURETICS,1312742,Olmesartan medoxomil,21601840,118463
+C09DB01,VALSARTAN AND AMLODIPINE,1308842,valsartan,21601842,69749
+C09DB01,VALSARTAN AND AMLODIPINE,1332418,Amlodipine,21601842,17767
+C09DB02,OLMESARTAN MEDOXOMIL AND AMLODIPINE,1312742,Olmesartan medoxomil,21601843,118463
+C09DB02,OLMESARTAN MEDOXOMIL AND AMLODIPINE,1332418,Amlodipine,21601843,17767
+C09DX01,"VALSARTAN, AMLODIPINE AND HYDROCHLOROTHIAZIDE",974166,Hydrochlorothiazide,21601846,5487
+C09DX01,"VALSARTAN, AMLODIPINE AND HYDROCHLOROTHIAZIDE",1308842,valsartan,21601846,69749
+C09DX01,"VALSARTAN, AMLODIPINE AND HYDROCHLOROTHIAZIDE",1332418,Amlodipine,21601846,17767
+C09XA02,ALISKIREN,1317967,aliskiren,21601851,325646
+C09XA52,ALISKIREN AND HYDROCHLOROTHIAZIDE,974166,Hydrochlorothiazide,21601852,5487
+C09XA52,ALISKIREN AND HYDROCHLOROTHIAZIDE,1317967,aliskiren,21601852,325646
+C10AA01,SIMVASTATIN,1539403,Simvastatin,21601856,36567
+C10AA02,LOVASTATIN,1592085,Lovastatin,21601857,6472
+C10AA03,PRAVASTATIN,1112807,Aspirin,21601858,1191
+C10AA03,PRAVASTATIN,1551860,Pravastatin,21601858,42463
+C10AA04,FLUVASTATIN,1549686,fluvastatin,21601859,41127
+C10AA05,ATROVASTATIN,1545958,atorvastatin,21601860,83367
+C10AA06,CERIVASTATIN,1586226,Cerivastatin sodium,21601861,221072
+C10AA07,ROSUVASTATIN,1510813,rosuvastatin,21601862,301542
+C10AB,FIBRATES,1551803,Fenofibrate,21601864,8703
+C10AB01,CLOFIBRATE,1598658,Clofibrate,21601865,2594
+C10AB04,GEMFIBROZIL,1558242,Gemfibrozil,21601868,4719
+C10AB05,FENOFIBRATE,1551803,Fenofibrate,21601869,8703
+C10AC01,COLESTYRAMINE,19095309,Cholestyramine,21601876,2447
+C10AC02,COLESTIPOL,1501617,Colestipol,21601877,2685
+C10AC04,COLESEVELAM,1518148,colesevelam,21601879,141626
+C10AD02,NICOTINIC ACID,1379525,Inositol,21601882,5833
+C10AD02,NICOTINIC ACID,1517824,Niacin,21601882,7393
+C10AX,OTHER LIPID MODIFYING AGENTS,1195334,Choline,21601888,2449
+C10AX,OTHER LIPID MODIFYING AGENTS,1379525,Inositol,21601888,5833
+C10AX,OTHER LIPID MODIFYING AGENTS,1398573,plant stanol ester,21601888,259320
+C10AX,OTHER LIPID MODIFYING AGENTS,1401437,Garlic preparation,21601888,265647
+C10AX,OTHER LIPID MODIFYING AGENTS,1508241,policosanol,21601888,69440
+C10AX,OTHER LIPID MODIFYING AGENTS,19019877,eicosapentanoic acid,21601888,144449
+C10AX,OTHER LIPID MODIFYING AGENTS,19042345,Lecithin,21601888,8214
+C10AX01,DEXTROTHYROXINE,19022003,Dextrothyroxine,21601889,3292
+C10AX02,PROBUCOL,19051463,Probucol,21601890,8699
+C10AX06,OMEGA-3-TRIGLYCERIDES INCL. OTHER ESTERS AND ACIDS,1315342,Flaxseed extract,21601893,318224
+C10AX06,OMEGA-3-TRIGLYCERIDES INCL. OTHER ESTERS AND ACIDS,1560305,Omega-3 Acid Ethyl Esters (USP),21601893,484348
+C10AX06,OMEGA-3-TRIGLYCERIDES INCL. OTHER ESTERS AND ACIDS,19009540,Vitamin E,21601893,11256
+C10AX06,OMEGA-3-TRIGLYCERIDES INCL. OTHER ESTERS AND ACIDS,19016670,Docosahexaenoate,21601893,73
+C10AX06,OMEGA-3-TRIGLYCERIDES INCL. OTHER ESTERS AND ACIDS,19087063,Eicosapentaenoate,21601893,618597
+C10AX08,POLICOSANOL,1508241,policosanol,21601895,69440
+C10AX09,EZETIMIBE,1526475,ezetimibe,21601896,341248
+C10BA,HMG COA REDUCTASE INHIB COMB W/OTHER LIPID MOD AGT,1517824,Niacin,21601899,7393
+C10BA,HMG COA REDUCTASE INHIB COMB W/OTHER LIPID MOD AGT,1539403,Simvastatin,21601899,36567
+C10BA01,LOVASTATIN AND NICOTINIC ACID,1517824,Niacin,21601900,7393
+C10BA01,LOVASTATIN AND NICOTINIC ACID,1592085,Lovastatin,21601900,6472
+C10BA02,SIMVASTATIN AND EZEMTIMIBE,1526475,ezetimibe,21601901,341248
+C10BA02,SIMVASTATIN AND EZEMTIMIBE,1539403,Simvastatin,21601901,36567
+C10BX03,ATORVASTATIN AND AMLOPIDINE,1332418,Amlodipine,21601906,17767
+C10BX03,ATORVASTATIN AND AMLOPIDINE,1545958,atorvastatin,21601906,83367
+D01AA01,NYSTATIN,922570,Nystatin,21601911,7597
+D01AC,IMIDAZOLE AND TRIAZOLE DERIVATIVES,975125,Hydrocortisone,21601919,5492
+D01AC,IMIDAZOLE AND TRIAZOLE DERIVATIVES,985708,Ketoconazole,21601919,6135
+D01AC01,CLOTRIMAZOLE,1000632,Clotrimazole,21601920,2623
+D01AC02,MICONAZOLE,907879,Miconazole,21601921,6932
+D01AC08,KETOCONAZOLE,931035,pyrithione,21601927,35100
+D01AC08,KETOCONAZOLE,944360,zinc pyrithione,21601927,39952
+D01AC08,KETOCONAZOLE,975125,Hydrocortisone,21601927,5492
+D01AC08,KETOCONAZOLE,985708,Ketoconazole,21601927,6135
+D01AC09,SULCONAZOLE,940535,sulconazole,21601928,37319
+D01AC11,OXICONAZOLE,918222,oxiconazole,21601930,32638
+D01AC14,SERTACONAZOLE,939134,sertaconazole,21601933,36435
+D01AC52,"MICONAZOLE, COMBINATIONS",907879,Miconazole,21601937,6932
+D01AC52,"MICONAZOLE, COMBINATIONS",911064,Zinc Oxide,21601937,11423
+D01AE,OTHER ANTIFUNGALS FOR TOPICAL USE,19003914,Triacetin,21601939,10756
+D01AE02,METHYLROSANILINE,959362,Gentian Violet,21601941,4778
+D01AE04,UNDECYLENIC ACID,914244,Undecylenate,21601943,314881
+D01AE11,HALOPROGIN,19101422,haloprogin,21601950,26422
+D01AE13,SELENIUM SULFIDE,938061,selenium disulfide,21601952,36345
+D01AE14,CICLOPIROX,950098,ciclopirox,21601953,21090
+D01AE15,TERBINAFINE,1741309,terbinafine,21601954,37801
+D01AE18,TOLNAFTATE,902950,Tolnaftate,21601957,10637
+D01AE20,COMBINATIONS,936519,Benzoic Acid,21601959,18989
+D01AE20,COMBINATIONS,940004,sodium thiosulfate,21601959,36726
+D01AE20,COMBINATIONS,964407,Salicylic Acid,21601959,9525
+D01AE22,NAFTIFINE,914053,naftifine,21601961,31476
+D01AE23,BUTENAFINE,958396,butenafine,21601962,47461
+D01AE54,"UNDECYLENIC ACID, COMBINATIONS",914244,Undecylenate,21601963,314881
+D01AE54,"UNDECYLENIC ACID, COMBINATIONS",949459,chloroxylenol,21601963,20877
+D01BA01,GRISEOFULVIN,1763779,Griseofulvin,21601966,5021
+D01BA02,TERBINAFINE,1741309,terbinafine,21601967,37801
+D02AA,SILICONE PRODUCTS,916662,dimethicone,21601970,324072
+D02AA,SILICONE PRODUCTS,966376,Allantoin,21601970,508
+D02AA,SILICONE PRODUCTS,986261,Colloidal oatmeal,21601970,221082
+D02AA,SILICONE PRODUCTS,19066894,Silicones,21601970,9778
+D02AB,ZINC PRODUCTS,901656,Menthol,21601971,6750
+D02AB,ZINC PRODUCTS,911064,Zinc Oxide,21601971,11423
+D02AB,ZINC PRODUCTS,916662,dimethicone,21601971,324072
+D02AB,ZINC PRODUCTS,923540,phenol,21601971,33290
+D02AB,ZINC PRODUCTS,942172,"Petrolatum, White",21601971,82074
+D02AB,ZINC PRODUCTS,979096,Zinc Acetate,21601971,58295
+D02AB,ZINC PRODUCTS,984801,Kaolin,21601971,6102
+D02AB,ZINC PRODUCTS,1036667,Talc,21601971,10323
+D02AB,ZINC PRODUCTS,19007539,Corn starch preparation,21601971,2858
+D02AB,ZINC PRODUCTS,19033354,Petrolatum,21601971,8091
+D02AC,SOFT PARAFFIN AND FAT PRODUCTS,908523,Mineral Oil,21601972,6972
+D02AC,SOFT PARAFFIN AND FAT PRODUCTS,911064,Zinc Oxide,21601972,11423
+D02AC,SOFT PARAFFIN AND FAT PRODUCTS,929128,Propylene glycol,21601972,34693
+D02AC,SOFT PARAFFIN AND FAT PRODUCTS,942172,"Petrolatum, White",21601972,82074
+D02AC,SOFT PARAFFIN AND FAT PRODUCTS,942691,triethanolamine,21601972,38623
+D02AC,SOFT PARAFFIN AND FAT PRODUCTS,19033354,Petrolatum,21601972,8091
+D02AC,SOFT PARAFFIN AND FAT PRODUCTS,19087317,Lanolin,21601972,6227
+D02AE01,CARBAMIDE,906914,Urea,21601975,11002
+D02AE01,CARBAMIDE,1036252,Sulfacetamide,21601975,10169
+D02AE51,"CARBAMIDE, COMBINATIONS",904826,Lactic acid,21601976,28393
+D02AE51,"CARBAMIDE, COMBINATIONS",906914,Urea,21601976,11002
+D02AE51,"CARBAMIDE, COMBINATIONS",926770,Papain,21601976,7892
+D02AE51,"CARBAMIDE, COMBINATIONS",942494,chlorophyllin copper complex,21601976,82242
+D02AE51,"CARBAMIDE, COMBINATIONS",1036252,Sulfacetamide,21601976,10169
+D02AF,SALICYLIC ACID PREPARATIONS,901656,Menthol,21601977,6750
+D02AF,SALICYLIC ACID PREPARATIONS,923540,phenol,21601977,33290
+D02AF,SALICYLIC ACID PREPARATIONS,938205,Camphor,21601977,1952
+D02AF,SALICYLIC ACID PREPARATIONS,964407,Salicylic Acid,21601977,9525
+D02AF,SALICYLIC ACID PREPARATIONS,1738521,Doxycycline,21601977,3640
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,904826,Lactic acid,21601978,28393
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,916802,Benzethonium,21601978,1390
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,961145,Glycerin,21601978,4910
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,966376,Allantoin,21601978,508
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,977949,ichthammol,21601978,5645
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,986261,Colloidal oatmeal,21601978,221082
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,992308,dyclonine,21601978,23744
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,19008339,Vitamin A,21601978,11246
+D02AX,OTHER EMOLLIENTS AND PROTECTIVES,19009540,Vitamin E,21601978,11256
+D02BA,PROTECTIVES AGAINST UV-RADIATION FOR TOPICAL USE,19071908,cinoxate,21601980,288262
+D02BA01,AMINOBENZOIC ACID,19018384,4-Aminobenzoic Acid,21601981,74
+D03AX01,CADEXOMER IODINE,1740226,cadexomer iodine,21601989,20012
+D03AX03,DEXPANTHENOL,988294,dexpanthenol,21601991,22701
+D03AX05,HYALURONIC ACID,787787,hyaluronate,21601993,62372
+D03AX05,HYALURONIC ACID,918172,Benzoyl Peroxide,21601993,1418
+D03AX06,BECAPLERMIN,912476,Becaplermin,21601994,115238
+D03BA01,TRYPSIN,906149,TRYPSIN,21601999,10890
+D03BA01,TRYPSIN,922976,Peruvian balsam,21601999,33219
+D03BA01,TRYPSIN,950933,Castor Oil,21601999,2129
+D03BA02,COLLAGENASE,980311,COLLAGENASE,21602000,58939
+D04AA02,MEPYRAMINE,917006,Benzocaine,21602006,1399
+D04AA02,MEPYRAMINE,1159811,Pyrilamine,21602006,9009
+D04AA02,MEPYRAMINE,19010696,Zinc,21602006,11416
+D04AA04,TRIPELENNAMINE,1105853,Tripelennamine,21602008,10847
+D04AA32,DIPHENHYDRAMINE,902616,Calamine,21602016,106212
+D04AA32,DIPHENHYDRAMINE,911064,Zinc Oxide,21602016,11423
+D04AA32,DIPHENHYDRAMINE,938205,Camphor,21602016,1952
+D04AA32,DIPHENHYDRAMINE,979096,Zinc Acetate,21602016,58295
+D04AA32,DIPHENHYDRAMINE,1129625,Diphenhydramine,21602016,3498
+D04AB,ANESTHETICS FOR TOPICAL USE,914840,Dichlorotetrafluoroethane,21602019,124848
+D04AB,ANESTHETICS FOR TOPICAL USE,917006,Benzocaine,21602019,1399
+D04AB,ANESTHETICS FOR TOPICAL USE,939726,butamben,21602019,19861
+D04AB,ANESTHETICS FOR TOPICAL USE,950316,Ethyl Chloride,21602019,4141
+D04AB,ANESTHETICS FOR TOPICAL USE,1036884,Tetracaine,21602019,10391
+D04AB01,LIDOCAINE,901656,Menthol,21602020,6750
+D04AB01,LIDOCAINE,916460,Benzalkonium,21602020,1378
+D04AB01,LIDOCAINE,916802,Benzethonium,21602020,1390
+D04AB01,LIDOCAINE,989878,Lidocaine,21602020,6387
+D04AB02,CINCHOCAINE,923840,Dibucaine,21602021,3339
+D04AB04,BENZOCAINE,901656,Menthol,21602023,6750
+D04AB04,BENZOCAINE,916802,Benzethonium,21602023,1390
+D04AB04,BENZOCAINE,917006,Benzocaine,21602023,1399
+D04AB04,BENZOCAINE,923540,phenol,21602023,33290
+D04AB04,BENZOCAINE,935390,resorcinol,21602023,35382
+D04AB04,BENZOCAINE,961145,Glycerin,21602023,4910
+D04AB04,BENZOCAINE,1704758,Triclosan,21602023,10795
+D04AB06,TETRACAINE,1036884,Tetracaine,21602025,10391
+D04AB07,PRAMOCAINE,901656,Menthol,21602026,6750
+D04AB07,PRAMOCAINE,902616,Calamine,21602026,106212
+D04AB07,PRAMOCAINE,904826,Lactic acid,21602026,28393
+D04AB07,PRAMOCAINE,916662,dimethicone,21602026,324072
+D04AB07,PRAMOCAINE,919681,Benzyl Alcohol,21602026,1426
+D04AB07,PRAMOCAINE,927478,pramoxine,21602026,34347
+D04AB07,PRAMOCAINE,966376,Allantoin,21602026,508
+D04AB07,PRAMOCAINE,979096,Zinc Acetate,21602026,58295
+D04AB07,PRAMOCAINE,19033354,Petrolatum,21602026,8091
+D04AX,OTHER ANTIPRURITICS,738156,Doxepin,21602027,3638
+D04AX,OTHER ANTIPRURITICS,901656,Menthol,21602027,6750
+D04AX,OTHER ANTIPRURITICS,902616,Calamine,21602027,106212
+D04AX,OTHER ANTIPRURITICS,911064,Zinc Oxide,21602027,11423
+D04AX,OTHER ANTIPRURITICS,923540,phenol,21602027,33290
+D04AX,OTHER ANTIPRURITICS,938205,Camphor,21602027,1952
+D04AX,OTHER ANTIPRURITICS,1036690,Tannic Acid,21602027,10328
+D04AX,OTHER ANTIPRURITICS,19092412,Chlorobutanol,21602027,2378
+D05AA,TARS,901656,Menthol,21602030,6750
+D05AA,TARS,935390,resorcinol,21602030,35382
+D05AA,TARS,964407,Salicylic Acid,21602030,9525
+D05AA,TARS,966376,Allantoin,21602030,508
+D05AA,TARS,1000995,Coal Tar,21602030,2635
+D05AC01,DITHRANOL,952538,Anthralin,21602032,873
+D05AD02,METHOXSALEN,905223,Methoxsalen,21602036,6854
+D05AX,OTHER ANTIPSORIATICS FOR TOPICAL USE,964407,Salicylic Acid,21602037,9525
+D05AX,OTHER ANTIPSORIATICS FOR TOPICAL USE,19009148,"Mercury, Ammoniated",21602037,29542
+D05AX02,CALCIPOTRIOL,908921,calcipotriene,21602039,29365
+D05AX05,TAZAROTENE,947416,tazarotene,21602042,83947
+D05BA01,TRIOXYSALEN,905829,Trioxsalen,21602046,10844
+D05BA02,METHOXSALEN,905223,Methoxsalen,21602047,6854
+D05BB01,ETRETINATE,19050554,Etretinate,21602050,4182
+D05BB02,ACITRETIN,929638,Acitretin,21602051,16818
+D05BX,OTHER ANTIPSORIATICS FOR SYSTEMIC USE,1036525,Sulfur,21602052,10223
+D05BX,OTHER ANTIPSORIATICS FOR SYSTEMIC USE,19082458,nickel sulfate,21602052,31738
+D05BX,OTHER ANTIPSORIATICS FOR SYSTEMIC USE,19095079,potassium bromide,21602052,34299
+D05BX51,"FUMARIC ACID DERIVATIVES, COMBINATIONS",19082458,nickel sulfate,21602053,31738
+D05BX51,"FUMARIC ACID DERIVATIVES, COMBINATIONS",19095079,potassium bromide,21602053,34299
+D05BX51,"FUMARIC ACID DERIVATIVES, COMBINATIONS",19126510,fumarate,21602053,70598
+D06AA02,CHLORTETRACYCLINE,19095043,Chlortetracycline,21602058,2408
+D06AA04,TETRACYCLINE,1836948,Tetracycline,21602060,10395
+D06AX02,CHLORAMPHENICOL,990069,Chloramphenicol,21602063,2348
+D06AX04,NEOMYCIN,915175,Bacitracin,21602064,1291
+D06AX04,NEOMYCIN,915981,Neomycin,21602064,7299
+D06AX04,NEOMYCIN,927478,pramoxine,21602064,34347
+D06AX04,NEOMYCIN,948582,Polymyxin B,21602064,8536
+D06AX04,NEOMYCIN,963742,Gramicidin,21602064,5011
+D06AX05,BACITRACIN,915175,Bacitracin,21602065,1291
+D06AX05,BACITRACIN,948582,Polymyxin B,21602065,8536
+D06AX07,GENTAMICIN,919345,Gentamicin Sulfate (USP),21602066,142438
+D06AX09,MUPIROCIN,951511,Mupirocin,21602068,42372
+D06AX13,RETAPAMULIN,991003,retapamulin,21602072,642274
+D06BA,SULFONAMIDES,906914,Urea,21602074,11002
+D06BA,SULFONAMIDES,1036252,Sulfacetamide,21602074,10169
+D06BA01,SILVER SULFADIAZINE,966956,Silver Sulfadiazine,21602075,9793
+D06BA02,SULFATHIAZOLE,1036487,sulfathiazole,21602076,10193
+D06BA03,MAFENIDE,992716,Mafenide,21602077,6572
+D06BB,ANTIVIRALS,921956,Sinecatechins,21602082,753346
+D06BB03,ACICLOVIR,1703687,Acyclovir,21602085,281
+D06BB04,PODOPHYLLOTOXIN,947651,podophyllin,21602086,8462
+D06BB04,PODOPHYLLOTOXIN,947705,podophyllotoxin,21602086,8463
+D06BB06,PENCICLOVIR,981654,penciclovir,21602088,59839
+D06BB10,IMIQUIMOD,981691,imiquimod,21602092,59943
+D06BB11,DOCOSANOL,980955,docosanol,21602093,594680
+D06BX01,METRONIDAZOLE,1707164,Metronidazole,21602096,6922
+D07AA01,METHYLPREDNISOLONE,1506270,Methylprednisolone,21602101,6902
+D07AA02,HYDROCORTISONE,964407,Salicylic Acid,21602102,9525
+D07AA02,HYDROCORTISONE,975125,Hydrocortisone,21602102,5492
+D07AA02,HYDROCORTISONE,985708,Ketoconazole,21602102,6135
+D07AA02,HYDROCORTISONE,1036525,Sulfur,21602102,10223
+D07AB02,HYDROCORTISONE BUTYRATE,975125,Hydrocortisone,21602106,5492
+D07AB03,FLUMETASONE,19055156,Flumethasone,21602107,4458
+D07AB08,DESONIDE,917205,Desonide,21602112,3254
+D07AB09,TRIAMCINOLONE,903963,Triamcinolone,21602113,10759
+D07AB11,HYDROCORTISONE BUTEPRATE,975125,Hydrocortisone,21602115,5492
+D07AB19,DEXAMETHASONE,1518254,Dexamethasone,21602116,3264
+D07AB21,CLOCORTOLONE,950882,clocortolone,21602117,21249
+D07AC01,BETAMETHASONE,920458,Betamethasone,21602120,1514
+D07AC03,DESOXIMETASONE,917336,Desoximetasone,21602122,3255
+D07AC04,FLUOCINOLONE ACETONIDE,996541,fluocinolone,21602123,25126
+D07AC07,FLUDROXYCORTIDE,956266,Flurandrenolide,21602126,4500
+D07AC08,FLUOCINONIDE,955252,Fluocinonide,21602127,4462
+D07AC10,DIFLORASONE,960988,Diflorasone,21602129,91311
+D07AC11,AMCINONIDE,930747,amcinonide,21602130,17652
+D07AC13,MOMETASONE,905233,Mometasone,21602132,108118
+D07AC17,FLUTICASONE,1149380,fluticasone,21602136,41126
+D07AC18,PREDNICARBATE,928110,prednicarbate,21602137,34369
+D07AC21,ULOBETASOL,949759,halobetasol,21602139,41208
+D07AD01,CLOBETASOL,998415,Clobetasol,21602141,2590
+D07AD02,HALCINONIDE,966468,Halcinonide,21602142,5084
+D07BA04,HYDROCORTISONE AND ANTISEPTICS,918172,Benzoyl Peroxide,21602146,1418
+D07BA04,HYDROCORTISONE AND ANTISEPTICS,928006,Iodoquinol,21602146,3435
+D07BA04,HYDROCORTISONE AND ANTISEPTICS,958994,Aloe Polysaccharide,21602146,476786
+D07BA04,HYDROCORTISONE AND ANTISEPTICS,975125,Hydrocortisone,21602146,5492
+D07BA04,HYDROCORTISONE AND ANTISEPTICS,980867,Clioquinol,21602146,5942
+D07CA01,HYDROCORTISONE AND ANTIBIOTICS,915175,Bacitracin,21602160,1291
+D07CA01,HYDROCORTISONE AND ANTIBIOTICS,915981,Neomycin,21602160,7299
+D07CA01,HYDROCORTISONE AND ANTIBIOTICS,928006,Iodoquinol,21602160,3435
+D07CA01,HYDROCORTISONE AND ANTIBIOTICS,948582,Polymyxin B,21602160,8536
+D07CA01,HYDROCORTISONE AND ANTIBIOTICS,975125,Hydrocortisone,21602160,5492
+D07CB01,TRIAMCINOLONE AND ANTIBIOTICS,903963,Triamcinolone,21602164,10759
+D07CB01,TRIAMCINOLONE AND ANTIBIOTICS,922570,Nystatin,21602164,7597
+D07CC01,BETAMETHASONE AND ANTIBIOTICS,920458,Betamethasone,21602170,1514
+D07CC01,BETAMETHASONE AND ANTIBIOTICS,1000632,Clotrimazole,21602170,2623
+D07XA,"CORTICOSTEROIDS, WEAK, OTHER COMBINATIONS",927478,pramoxine,21602179,34347
+D07XA,"CORTICOSTEROIDS, WEAK, OTHER COMBINATIONS",975125,Hydrocortisone,21602179,5492
+D07XA,"CORTICOSTEROIDS, WEAK, OTHER COMBINATIONS",980867,Clioquinol,21602179,5942
+D07XA01,HYDROCORTISONE,906914,Urea,21602180,11002
+D07XA01,HYDROCORTISONE,916802,Benzethonium,21602180,1390
+D07XA01,HYDROCORTISONE,927478,pramoxine,21602180,34347
+D07XA01,HYDROCORTISONE,958994,Aloe Polysaccharide,21602180,476786
+D07XA01,HYDROCORTISONE,975125,Hydrocortisone,21602180,5492
+D07XA01,HYDROCORTISONE,979096,Zinc Acetate,21602180,58295
+D07XA01,HYDROCORTISONE,990413,chlorcyclizine,21602180,2354
+D07XA01,HYDROCORTISONE,1129625,Diphenhydramine,21602180,3498
+D07XB02,TRIAMCINOLONE,903963,Triamcinolone,21602184,10759
+D07XB02,TRIAMCINOLONE,906914,Urea,21602184,11002
+D07XC01,BETAMETHASONE,908921,calcipotriene,21602190,29365
+D07XC01,BETAMETHASONE,920458,Betamethasone,21602190,1514
+D08AC02,CHLORHEXIDINE,1790812,Chlorhexidine,21602204,2358
+D08AC52,"CHLORHEXIDINE,COMBINATIONS",1790812,Chlorhexidine,21602208,2358
+D08AD,BORIC ACID PRODUCTS,929698,boric acid,21602209,1700
+D08AE01,HEXACHLOROPHENE,1768734,Hexachlorophene,21602211,5293
+D08AE03,PHENOL,923540,phenol,21602213,33290
+D08AE03,PHENOL,938205,Camphor,21602213,1952
+D08AE04,TRICLOSAN,1704758,Triclosan,21602214,10795
+D08AE05,CHLOROXYLENOL,949459,chloroxylenol,21602215,20877
+D08AF,NITROFURAN DERIVATIVES,920378,Nitrofurazone,21602217,7455
+D08AG02,POVIDONE-IODINE,1750087,Povidone-Iodine,21602221,8611
+D08AG02,POVIDONE-IODINE,19028106,Isopropyl Alcohol,21602221,797541
+D08AH30,CLIOQUINOL,980867,Clioquinol,21602228,5942
+D08AJ01,BENZALKONIUM,916460,Benzalkonium,21602230,1378
+D08AJ01,BENZALKONIUM,946340,Piperonyl Butoxide,21602230,8345
+D08AJ01,BENZALKONIUM,959665,Pyrethrins,21602230,8991
+D08AJ08,BENZETHONIUM CHLORIDE,916802,Benzethonium,21602236,1390
+D08AK04,MERCUROCHROME,1703026,Merbromin,21602244,6762
+D08AK06,THIOMERSAL,19137377,Thimerosal,21602246,10472
+D08AL01,SILVER NITRATE,966913,Silver Nitrate,21602249,9789
+D08AX,OTHER ANTISEPTICS AND DISINFECTANTS,949459,chloroxylenol,21602251,20877
+D08AX,OTHER ANTISEPTICS AND DISINFECTANTS,1761033,Glutaral,21602251,4888
+D08AX,OTHER ANTISEPTICS AND DISINFECTANTS,19060367,Pyrogallol,21602251,9022
+D08AX01,HYDROGEN PEROXIDE,1776430,Hydrogen Peroxide,21602252,5499
+D08AX05,ISOPROPANOL,19028106,Isopropyl Alcohol,21602256,797541
+D08AX06,POTASSIUM PERMANGANATE,19135788,Potassium Permanganate,21602257,8604
+D08AX07,SODIUM HYPOCHLORITE,1769774,Sodium Hypochlorite,21602258,9881
+D08AX08,ETHANOL,955372,Ethanol,21602259,448
+D10AB02,SULFUR,906914,Urea,21602289,11002
+D10AB02,SULFUR,918172,Benzoyl Peroxide,21602289,1418
+D10AB02,SULFUR,935390,resorcinol,21602289,35382
+D10AB02,SULFUR,964407,Salicylic Acid,21602289,9525
+D10AB02,SULFUR,975125,Hydrocortisone,21602289,5492
+D10AB02,SULFUR,1036252,Sulfacetamide,21602289,10169
+D10AB02,SULFUR,1036525,Sulfur,21602289,10223
+D10AD01,TRETINOIN,903643,Tretinoin,21602293,10753
+D10AD03,ADAPALENE,981774,adapalene,21602295,60223
+D10AD51,"TRETINOIN, COMBINATIONS",903643,Tretinoin,21602298,10753
+D10AD51,"TRETINOIN, COMBINATIONS",997881,Clindamycin,21602298,2582
+D10AD53,"ADAPALENE, COMBINATIONS",918172,Benzoyl Peroxide,21602299,1418
+D10AD53,"ADAPALENE, COMBINATIONS",981774,adapalene,21602299,60223
+D10AE01,BENZOYL PEROXIDE,787787,hyaluronate,21602302,62372
+D10AE01,BENZOYL PEROXIDE,918172,Benzoyl Peroxide,21602302,1418
+D10AE51,"BENZOYL PEROXIDE, COMBINATIONS",906914,Urea,21602303,11002
+D10AE51,"BENZOYL PEROXIDE, COMBINATIONS",918172,Benzoyl Peroxide,21602303,1418
+D10AE51,"BENZOYL PEROXIDE, COMBINATIONS",964407,Salicylic Acid,21602303,9525
+D10AF01,CLINDAMYCIN,997881,Clindamycin,21602305,2582
+D10AF02,ERYTHROMYCIN,1746940,Erythromycin,21602306,4053
+D10AF04,MECLOCYCLINE,19009022,meclocycline,21602308,29418
+D10AF51,"CLINDAMYCIN, COMBINATIONS",918172,Benzoyl Peroxide,21602309,1418
+D10AF51,"CLINDAMYCIN, COMBINATIONS",997881,Clindamycin,21602309,2582
+D10AF52,"ERYTHROMYCIN, COMBINATIONS",918172,Benzoyl Peroxide,21602310,1418
+D10AF52,"ERYTHROMYCIN, COMBINATIONS",1746940,Erythromycin,21602310,4053
+D10AX,OTHER ANTI-ACNE PREPARATIONS FOR TOPICAL USE,19018419,Niacinamide,21602311,7405
+D10AX02,RESORCINOL,923540,phenol,21602313,33290
+D10AX02,RESORCINOL,935390,resorcinol,21602313,35382
+D10AX03,AZELAIC ACID,986790,Azelate,21602314,618278
+D10AX05,DAPSONE,1711759,Dapsone,21602316,3108
+D10AX30,VARIOUS COMBINATIONS,964407,Salicylic Acid,21602317,9525
+D10AX30,VARIOUS COMBINATIONS,19028106,Isopropyl Alcohol,21602317,797541
+D10BA01,ISOTRETINOIN,984232,Isotretinoin,21602320,6064
+D10BX,OTHER ANTI-ACNE PREPARATIONS FOR SYSTEMIC USE,1387426,Folate,21602321,62356
+D10BX,OTHER ANTI-ACNE PREPARATIONS FOR SYSTEMIC USE,19010696,Zinc,21602321,11416
+D10BX,OTHER ANTI-ACNE PREPARATIONS FOR SYSTEMIC USE,19018419,Niacinamide,21602321,7405
+D11AA,ANTIHIDROTICS,929698,boric acid,21602325,1700
+D11AA,ANTIHIDROTICS,930604,aluminum acetate,21602325,17609
+D11AA,ANTIHIDROTICS,957393,aluminum chloride,21602325,46241
+D11AA,ANTIHIDROTICS,1756524,Formaldehyde,21602325,4530
+D11AC03,SELENIUM COMPOUNDS,901656,Menthol,21602329,6750
+D11AC03,SELENIUM COMPOUNDS,938061,selenium disulfide,21602329,36345
+D11AC06,POVIDONE-IODINE,1750087,Povidone-Iodine,21602330,8611
+D11AC30,OTHERS,904826,Lactic acid,21602333,28393
+D11AC30,OTHERS,916460,Benzalkonium,21602333,1378
+D11AC30,OTHERS,931035,pyrithione,21602333,35100
+D11AC30,OTHERS,944360,zinc pyrithione,21602333,39952
+D11AC30,OTHERS,949453,chloroxine,21602333,20875
+D11AC30,OTHERS,964407,Salicylic Acid,21602333,9525
+D11AC30,OTHERS,975125,Hydrocortisone,21602333,5492
+D11AC30,OTHERS,985708,Ketoconazole,21602333,6135
+D11AC30,OTHERS,1036525,Sulfur,21602333,10223
+D11AF,WART AND ANTI-CORN PREPARATIONS,964407,Salicylic Acid,21602336,9525
+D11AF,WART AND ANTI-CORN PREPARATIONS,19039679,Cantharidin,21602336,1984
+D11AH01,TACROLIMUS,950637,Tacrolimus,21602338,42316
+D11AH02,PIMECROLIMUS,915935,Pimecrolimus,21602339,321952
+D11AX,OTHER DERMATOLOGICALS,903643,Tretinoin,21602341,10753
+D11AX,OTHER DERMATOLOGICALS,904525,bimatoprost,21602341,283810
+D11AX,OTHER DERMATOLOGICALS,911638,glycolate,21602341,70603
+D11AX,OTHER DERMATOLOGICALS,920113,mequinol,21602341,15080
+D11AX,OTHER DERMATOLOGICALS,925209,N6-furfuryladenine,21602341,16054
+D11AX,OTHER DERMATOLOGICALS,927194,Dihydroxyacetone,21602341,3430
+D11AX,OTHER DERMATOLOGICALS,986790,Azelate,21602341,618278
+D11AX,OTHER DERMATOLOGICALS,987009,Trichloroacetate,21602341,618564
+D11AX,OTHER DERMATOLOGICALS,1036690,Tannic Acid,21602341,10328
+D11AX,OTHER DERMATOLOGICALS,19027308,Potassium Hydroxide,21602341,34311
+D11AX,OTHER DERMATOLOGICALS,19056581,ALPHA HYDROXY ACIDS,21602341,236797
+D11AX01,MINOXIDIL,1309068,Minoxidil,21602342,6984
+D11AX02,GAMOLENIC ACID,19086939,gamma-Linolenate,21602343,618453
+D11AX03,CALCIUM GLUCONATE,19037038,Calcium Gluconate,21602344,1908
+D11AX11,HYDROQUINONE,903643,Tretinoin,21602351,10753
+D11AX11,HYDROQUINONE,976778,hydroquinone,21602351,5509
+D11AX11,HYDROQUINONE,996416,Finasteride,21602351,25025
+D11AX11,HYDROQUINONE,996541,fluocinolone,21602351,25126
+D11AX11,HYDROQUINONE,19011773,Ascorbic Acid,21602351,1151
+D11AX12,PYRITHIONE ZINC,901656,Menthol,21602352,6750
+D11AX12,PYRITHIONE ZINC,944360,zinc pyrithione,21602352,39952
+D11AX13,MONOBENZONE,929983,monobenzone,21602353,17145
+D11AX16,EFLORNITHINE,978236,Eflornithine,21602354,569
+D11AX19,ALITRETINOIN,941052,alitretinoin,0,81864
+D11AX52,"GAMOLENIC ACID, COMBINATIONS",19009540,Vitamin E,21602357,11256
+D11AX52,"GAMOLENIC ACID, COMBINATIONS",19086939,gamma-Linolenate,21602357,618453
+G01AA01,NYSTATIN,922570,Nystatin,21602363,7597
+G01AA05,CHLORAMPHENICOL,990069,Chloramphenicol,21602367,2348
+G01AA10,CLINDAMYCIN,997881,Clindamycin,21602372,2582
+G01AC30,OXYQUINOLINE,906874,Oxyquinoline,21602383,110
+G01AC30,OXYQUINOLINE,929549,Acetic Acid,21602383,168
+G01AD,ORGANIC ACIDS,906874,Oxyquinoline,21602384,110
+G01AD,ORGANIC ACIDS,929549,Acetic Acid,21602384,168
+G01AD,ORGANIC ACIDS,19123754,Ricinoleate,21602384,618482
+G01AF01,METRONIDAZOLE,1707164,Metronidazole,21602392,6922
+G01AF02,CLOTRIMAZOLE,1000632,Clotrimazole,21602393,2623
+G01AF04,MICONAZOLE,907879,Miconazole,21602394,6932
+G01AF08,TIOCONAZOLE,942028,tioconazole,21602398,38298
+G01AF15,BUTOCONAZOLE,939784,butoconazole,21602403,19884
+G01AG02,TERCONAZOLE,941472,terconazole,21602409,37806
+G01AX06,FURAZOLIDONE,1756822,Furazolidone,21602415,4601
+G01AX09,METHYLROSANILINE,959362,Gentian Violet,21602416,4778
+G01AX11,POVIDONE-IODINE,1750087,Povidone-Iodine,21602417,8611
+G02AB01,METHYLERGOMETRINE,1305637,Methylergonovine,21602432,6883
+G02AB02,ERGOT ALKALOIDS,19102230,Ergot Alkaloids,21602433,4023
+G02AB03,ERGOMETRINE,1345205,Ergonovine,21602434,4021
+G02AD01,DINOPROST,19029421,Dinoprost,21602438,3477
+G02AD02,DINOPROSTONE,1329415,Dinoprostone,21602439,3478
+G02AD04,CARBOPROST,19049150,Carboprost,21602441,2051
+G02BA03,PLASTIC IUD WITH PROGESTOGEN,1589505,Levonorgestrel,21602449,6373
+G02BB,INTRAVAGINAL CONTRACEPTIVES,969444,Nonoxynol-9,21602450,53750
+G02BB,INTRAVAGINAL CONTRACEPTIVES,970277,Octoxynol-9,21602450,54034
+G02CA01,RITODRINE,1563413,Ritodrine,21602454,9392
+G02CB01,BROMOCRIPTINE,730548,Bromocriptine,21602458,1760
+G02CB03,CABERGOLINE,1558471,cabergoline,21602460,47579
+G03AA01,ETYNODIOL AND ESTROGEN,1503184,Mestranol,21602474,6782
+G03AA01,ETYNODIOL AND ESTROGEN,1549786,Ethinyl Estradiol,21602474,4124
+G03AA01,ETYNODIOL AND ESTROGEN,1595461,ethynodiol,21602474,24591
+G03AA05,NORETHISTERONE AND ESTROGEN,1503184,Mestranol,21602478,6782
+G03AA05,NORETHISTERONE AND ESTROGEN,1521369,Norethindrone,21602478,7514
+G03AA05,NORETHISTERONE AND ESTROGEN,1549786,Ethinyl Estradiol,21602478,4124
+G03AA05,NORETHISTERONE AND ESTROGEN,1595799,Ferrous fumarate,21602478,24941
+G03AA06,NORGESTREL AND ESTROGEN,1521592,Norgestrel,21602479,7518
+G03AA06,NORGESTREL AND ESTROGEN,1549786,Ethinyl Estradiol,21602479,4124
+G03AA07,LEVONORGESTREL AND ESTROGEN,1549786,Ethinyl Estradiol,21602480,4124
+G03AA07,LEVONORGESTREL AND ESTROGEN,1589505,Levonorgestrel,21602480,6373
+G03AA08,MEDROXYPROGESTERONE AND ESTROGEN,1500211,Medroxyprogesterone,21602481,6691
+G03AA08,MEDROXYPROGESTERONE AND ESTROGEN,1548195,Estradiol,21602481,4083
+G03AA09,DESOGESTREL AND ESTROGEN,1549786,Ethinyl Estradiol,21602482,4124
+G03AA09,DESOGESTREL AND ESTROGEN,1588000,Desogestrel,21602482,22656
+G03AA11,NORGESTIMATE AND ESTROGEN,1515774,norgestimate,21602484,31994
+G03AA11,NORGESTIMATE AND ESTROGEN,1549786,Ethinyl Estradiol,21602484,4124
+G03AA12,DROSPIRENONE AND ESTROGEN,1512674,drospirenone,21602485,11636
+G03AA12,DROSPIRENONE AND ESTROGEN,1549786,Ethinyl Estradiol,21602485,4124
+G03AA13,NORELGESTROMIN AND ESTROGEN,1518198,norelgestromin,21602486,326374
+G03AA13,NORELGESTROMIN AND ESTROGEN,1549786,Ethinyl Estradiol,21602486,4124
+G03AB03,LEVONORGESTREL AND ESTROGEN,1548195,Estradiol,21602491,4083
+G03AB03,LEVONORGESTREL AND ESTROGEN,1549786,Ethinyl Estradiol,21602491,4124
+G03AB03,LEVONORGESTREL AND ESTROGEN,1589505,Levonorgestrel,21602491,6373
+G03AB04,NORETHISTERONE AND ESTROGEN,1521369,Norethindrone,21602492,7514
+G03AB04,NORETHISTERONE AND ESTROGEN,1549786,Ethinyl Estradiol,21602492,4124
+G03AB04,NORETHISTERONE AND ESTROGEN,1595799,Ferrous fumarate,21602492,24941
+G03AC,PROGESTOGENS,1521592,Norgestrel,21602496,7518
+G03AC01,NORETHISTERONE,1521369,Norethindrone,21602497,7514
+G03AC03,LEVONORGESTREL,1549786,Ethinyl Estradiol,21602499,4124
+G03AC03,LEVONORGESTREL,1589505,Levonorgestrel,21602499,6373
+G03AC06,MEDROXYPROGESTERONE,1500211,Medroxyprogesterone,21602502,6691
+G03AC08,ETONOGESTREL,1519936,Etonogestrel,21602504,14584
+G03BA01,FLUOXYMESTERONE,1555887,Fluoxymesterone,21602508,4494
+G03BA02,METHYLTESTOSTERONE,1506602,Methyltestosterone,21602509,6904
+G03BA03,TESTOSTERONE,1636780,Testosterone,21602510,10379
+G03CA,"NATURAL AND SEMISYNTHETIC ESTROGENS, PLAIN",1551673,"Estrogens, Esterified (USP)",21602515,214549
+G03CA01,ETHINYLESTRADIOL,1549786,Ethinyl Estradiol,21602516,4124
+G03CA01,ETHINYLESTRADIOL,1588000,Desogestrel,21602516,22656
+G03CA01,ETHINYLESTRADIOL,1589505,Levonorgestrel,21602516,6373
+G03CA03,ESTRADIOL,1515774,norgestimate,21602517,31994
+G03CA03,ESTRADIOL,1548195,Estradiol,21602517,4083
+G03CA06,CHLOROTRIANISENE,19092684,Chlorotrianisene,21602519,2397
+G03CA07,ESTRONE,1525278,estropipate,21602520,33747
+G03CA07,ESTRONE,1549254,Estrone,21602520,4103
+G03CA57,CONJUGATED ESTROGENS,1500211,Medroxyprogesterone,21602523,6691
+G03CA57,CONJUGATED ESTROGENS,1549080,"Estrogens, Conjugated (USP)",21602523,4099
+G03CA57,CONJUGATED ESTROGENS,1586808,"estrogens, conjugated synthetic B",21602523,618365
+G03CA57,CONJUGATED ESTROGENS,1596779,"estrogens, conjugated synthetic A",21602523,253166
+G03CB01,DIENESTROL,925102,Dienestrol,21602525,3368
+G03CC,"ESTROGENS, COMBINATIONS WITH OTHER DRUGS",702865,Meprobamate,21602529,6760
+G03CC,"ESTROGENS, COMBINATIONS WITH OTHER DRUGS",990678,Chlordiazepoxide,21602529,2356
+G03CC,"ESTROGENS, COMBINATIONS WITH OTHER DRUGS",1549080,"Estrogens, Conjugated (USP)",21602529,4099
+G03CC,"ESTROGENS, COMBINATIONS WITH OTHER DRUGS",1551673,"Estrogens, Esterified (USP)",21602529,214549
+G03DA02,MEDROXYPROGESTERONE,1500211,Medroxyprogesterone,21602540,6691
+G03DA02,MEDROXYPROGESTERONE,1549080,"Estrogens, Conjugated (USP)",21602540,4099
+G03DA03,HYDROXYPROGESTERONE,19077143,Hydroxyprogesterone,21602541,5542
+G03DA04,PROGESTERONE,1552310,Progesterone,21602542,8727
+G03DC02,NORETHISTERONE,1521369,Norethindrone,21602553,7514
+G03EA,ANDROGENS AND ESTROGENS,1549786,Ethinyl Estradiol,21602559,4124
+G03EA,ANDROGENS AND ESTROGENS,1555887,Fluoxymesterone,21602559,4494
+G03EA02,TESTOSTERONE AND ESTROGEN,1548195,Estradiol,21602561,4083
+G03EA02,TESTOSTERONE AND ESTROGEN,1636780,Testosterone,21602561,10379
+G03EK01,METHYLTESTOSTERONE,1506602,Methyltestosterone,21602565,6904
+G03EK01,METHYLTESTOSTERONE,1525866,Diethylstilbestrol,21602565,3390
+G03EK01,METHYLTESTOSTERONE,1549080,"Estrogens, Conjugated (USP)",21602565,4099
+G03EK01,METHYLTESTOSTERONE,1551673,"Estrogens, Esterified (USP)",21602565,214549
+G03FA01,NORETHISTERONE AND ESTROGEN,1503184,Mestranol,21602568,6782
+G03FA01,NORETHISTERONE AND ESTROGEN,1521369,Norethindrone,21602568,7514
+G03FA01,NORETHISTERONE AND ESTROGEN,1548195,Estradiol,21602568,4083
+G03FA01,NORETHISTERONE AND ESTROGEN,1549786,Ethinyl Estradiol,21602568,4124
+G03FA01,NORETHISTERONE AND ESTROGEN,1595799,Ferrous fumarate,21602568,24941
+G03FA09,NORETYNODREL AND ESTROGEN,1503184,Mestranol,21602576,6782
+G03FA12,MEDROXYPROGESTERONE AND ESTROGEN,1500211,Medroxyprogesterone,21602579,6691
+G03FA12,MEDROXYPROGESTERONE AND ESTROGEN,1549080,"Estrogens, Conjugated (USP)",21602579,4099
+G03FA13,NORGESTIMATE AND ESTROGEN,1515774,norgestimate,21602580,31994
+G03FA13,NORGESTIMATE AND ESTROGEN,1548195,Estradiol,21602580,4083
+G03FA17,DROSPIRENONE AND ESTROGEN,1512674,drospirenone,21602584,11636
+G03FA17,DROSPIRENONE AND ESTROGEN,1549786,Ethinyl Estradiol,21602584,4124
+G03FB09,LEVONORGESTREL AND ESTROGEN,1548195,Estradiol,21602594,4083
+G03FB09,LEVONORGESTREL AND ESTROGEN,1589505,Levonorgestrel,21602594,6373
+G03GA01,CHORIONIC GONADOTROPIN,1563600,Chorionic Gonadotropin,21602599,4986
+G03GA01,CHORIONIC GONADOTROPIN,19071182,"HCG ALPHA,RECOMBINANT",21602599,283783
+G03GA02,HUMAN MENOPAUSAL GONADOTROPIN,1588712,Follicle Stimulating Hormone,21602600,227518
+G03GA02,HUMAN MENOPAUSAL GONADOTROPIN,1589795,Luteinizing Hormone,21602600,6383
+G03GA04,UROFOLLITROPIN,1515417,Urofollitropin,21602602,134404
+G03GA05,FOLLITROPIN ALFA,1542948,Follitropin Alfa,21602603,386938
+G03GA06,FOLLITROPIN BETA,1597235,follitropin beta,21602604,25357
+G03GA07,LUTROPIN ALFA,1543112,Lutropin alfa,21602605,388084
+G03GB02,CLOMIFENE,1598819,Clomiphene,21602611,2596
+G03XA01,DANAZOL,1511449,Danazol,21602620,3102
+G03XB01,MIFEPRISTONE,1508439,Mifepristone,21602623,6964
+G03XC01,RALOXIFENE,1513103,Raloxifene,21602625,72143
+G04BA,ACIDIFIERS,939871,sodium phosphate,21602629,36709
+G04BA,ACIDIFIERS,19027362,potassium phosphate,21602629,34322
+G04BA,ACIDIFIERS,19060837,Racemethionine,21602629,9100
+G04BA01,AMMONIUM CHLORIDE,912362,Ammonium Chloride,21602630,712
+G04BC,URINARY CONCREMENT SOLVENTS,908464,magnesium carbonate,21602632,29155
+G04BC,URINARY CONCREMENT SOLVENTS,950435,Citric Acid,21602632,21183
+G04BC,URINARY CONCREMENT SOLVENTS,976545,potassium citrate,21602632,54993
+G04BC,URINARY CONCREMENT SOLVENTS,977968,sodium citrate,21602632,56466
+G04BC,URINARY CONCREMENT SOLVENTS,993631,Magnesium Oxide,21602632,6582
+G04BC,URINARY CONCREMENT SOLVENTS,998392,Gluconolactone,21602632,25842
+G04BC,URINARY CONCREMENT SOLVENTS,1353228,Vitamin B6,21602632,42954
+G04BD02,FLAVOXATE,954853,Flavoxate,21602635,4440
+G04BD04,OXYBUTYNIN,918906,oxybutynin,21602637,32675
+G04BD08,SOLIFENACIN,916005,Solifenacin,21602641,322167
+G04BD10,DARIFENACIN,916230,darifenacin,21602643,136198
+G04BD11,FESOTERODINE,19027958,fesoterodine,21602644,797195
+G04BE01,ALPROSTADIL,1381504,Alprostadil,21602646,598
+G04BE03,SILDENAFIL,1316262,sildenafil,21602648,136411
+G04BE04,YOHIMBIN,1385800,Yohimbe Preparation,21602649,220982
+G04BE08,TADALAFIL,1336926,tadalafil,21602653,358263
+G04BE09,VARDENAFIL,1311276,vardenafil,21602654,306674
+G04BE30,COMBINATIONS,1326901,Papaverine,21602655,7895
+G04BE30,COMBINATIONS,1335539,Phentolamine,21602655,8153
+G04BE30,COMBINATIONS,1385800,Yohimbe Preparation,21602655,220982
+G04BE30,COMBINATIONS,19044522,Zinc Sulfate,21602655,39954
+G04BX,OTHER UROLOGICALS,976545,potassium citrate,21602657,54993
+G04BX03,ACETOHYDROXAMIC ACID,929542,acetohydroxamic acid,21602659,16728
+G04BX06,PHENAZOPYRIDINE,923672,Hyoscyamine,21602660,153970
+G04BX06,PHENAZOPYRIDINE,933724,Phenazopyridine,21602660,8120
+G04BX06,PHENAZOPYRIDINE,959174,butabarbital,21602660,477631
+G04BX13,DIMETHYL SULFOXIDE,928980,Dimethyl Sulfoxide,21602664,3455
+G04CA01,ALFUZOSIN,930021,alfuzosin,21602668,17300
+G04CA02,TAMSULOSIN,924566,tamsulosin,21602669,77492
+G04CA03,TERAZOSIN,1341238,Terazosin,21602670,37798
+G04CA04,SILODOSIN,19012925,silodosin,21602671,720825
+G04CB01,FINASTERIDE,996416,Finasteride,21602675,25025
+G04CB02,DUTASTERIDE,989482,Dutasteride,21602676,228790
+G04CX,OTHER DRUGS USED IN BENIGN PROSTATIC HYPERTROPHY,1391307,Saw palmetto extract,21602677,236344
+G04CX,OTHER DRUGS USED IN BENIGN PROSTATIC HYPERTROPHY,19004810,Copper Gluconate,21602677,2839
+G04CX,OTHER DRUGS USED IN BENIGN PROSTATIC HYPERTROPHY,19010696,Zinc,21602677,11416
+G04CX,OTHER DRUGS USED IN BENIGN PROSTATIC HYPERTROPHY,19017671,Ginseng Preparation,21602677,325526
+G04CX,OTHER DRUGS USED IN BENIGN PROSTATIC HYPERTROPHY,19079011,African Pygeum Extract,21602677,580117
+G04CX,OTHER DRUGS USED IN BENIGN PROSTATIC HYPERTROPHY,19079204,Zinc Gluconate,21602677,58300
+G04CX,OTHER DRUGS USED IN BENIGN PROSTATIC HYPERTROPHY,19112533,Pumpkin seed oil extract,21602677,466570
+G04CX01,PYGEUM AFRICANUM,1391440,Pygeum Africanum Preparation,21602678,236466
+G04CX02,SERENOA REPENS,1391307,Saw palmetto extract,21602679,236344
+G04CX02,SERENOA REPENS,19059155,Saw Palmetto Fruit Extract,21602679,477189
+G04CX02,SERENOA REPENS,19079390,ZINC PICOLINATE,21602679,58301
+H01AA01,CORTICOTROPIN,1541079,Corticotropin,21602685,376
+H01AA02,TETRACOSACTIDE,19008009,Cosyntropin,21602686,2890
+H01AC01,SOMATROPIN,1584910,Somatropin,21602690,61148
+H01AC02,SOMATREM,1578181,somatrem,21602691,56570
+H01AC03,MECASERMIN,1502877,mecasermin,21602692,274403
+H01AC04,SERMORELIN,19077457,Sermorelin,21602693,56188
+H01AC05,MECASERMIN RINFABATE,1586449,mecasermin rinfabate,21602694,616877
+H01AX01,PEGVISOMANT,1503432,pegvisomant,21602696,278739
+H01BA01,VASOPRESSIN,1507835,Vasopressin (USP),21602699,11149
+H01BA02,DESMOPRESSIN,1517070,desmopressin,21602700,3251
+H01BA03,LYPRESSIN,19092373,lypressin,21602701,6531
+H01BB02,OXYTOCIN,1326115,Oxytocin,21602707,7824
+H01CA,GONADOTROPIN-RELEASING HORMONES,1351541,Leuprolide,21602710,42375
+H01CA01,GONADORELIN,19089810,Gonadorelin,21602711,6384
+H01CA03,HISTRELIN,1366773,histrelin,21602713,50975
+H01CB02,OCTREOTIDE,1522957,Octreotide,21602716,7617
+H02AA02,FLUDROCORTISONE,1555120,Fludrocortisone,21602726,4452
+H02AA03,DESOXYCORTONE,19017895,Deoxycorticosterone,21602727,3256
+H02AB01,BETAMETHASONE,920458,Betamethasone,21602729,1514
+H02AB02,DEXAMETHASONE,1518254,Dexamethasone,21602730,3264
+H02AB04,METHYLPREDNISOLONE,1506270,Methylprednisolone,21602732,6902
+H02AB05,PARAMETHASONE,19027186,Paramethasone,21602733,7910
+H02AB06,PREDNISOLONE,1550557,prednisolone,21602734,8638
+H02AB07,PREDNISONE,1551099,Prednisone,21602735,8640
+H02AB08,TRIAMCINOLONE,903963,Triamcinolone,21602736,10759
+H02AB09,HYDROCORTISONE,975125,Hydrocortisone,21602737,5492
+H02AB10,CORTISONE,1507705,Cortisone,21602738,2878
+H02AB15,MEPREDNISONE,19009116,meprednisone,21602743,29523
+H02CA01,TRILOSTANE,19042801,trilostane,21602750,38668
+H03AA01,LEVOTHYROXINE SODIUM,1501700,Thyroxine,21602754,10582
+H03AA02,LIOTHYRONINE SODIUM,1505346,Triiodothyronine,21602755,10814
+H03AA03,COMBINATIONS OF LEVOTHYROXINE AND LIOTHYRONINE,1501700,Thyroxine,21602756,10582
+H03AA03,COMBINATIONS OF LEVOTHYROXINE AND LIOTHYRONINE,1505346,Triiodothyronine,21602756,10814
+H03AA05,THYROID GLAND PREPARATIONS,1501309,Desiccated Thyroid Extract,21602758,10572
+H03AA05,THYROID GLAND PREPARATIONS,1590418,THYROID (PORK),21602758,235479
+H03AA05,THYROID GLAND PREPARATIONS,1590479,THYROID STRONG,21602758,235480
+H03AA05,THYROID GLAND PREPARATIONS,19000732,Thyroglobulin,21602758,10565
+H03AA05,THYROID GLAND PREPARATIONS,19017575,THYROID (BEEF),21602758,325521
+H03AA05,THYROID GLAND PREPARATIONS,19032857,Thyroid preparation,21602758,80697
+H03BA02,PROPYLTHIOURACIL,1554072,Propylthiouracil,21602762,8794
+H03BB02,THIAMAZOLE,1504620,Methimazole,21602766,6835
+H03CA,IODINE THERAPY,1103137,iodinated glycerol,21602774,27723
+H03CA,IODINE THERAPY,1780601,Iodine,21602774,5933
+H03CA,IODINE THERAPY,19049909,Potassium Iodide,21602774,8597
+H03CA,IODINE THERAPY,19069873,Sodium Iodide,21602774,9884
+H04AA01,GLUCAGON,1560278,Glucagon,21602778,4832
+H05AA02,TERIPARATIDE,1521987,Teriparatide,21602783,32915
+H05BA01,CALCITONIN (SALMON SYNTHETIC),1537655,salmon calcitonin,21602787,36118
+H05BX01,CINACALCET,1548111,cinacalcet,21602792,407990
+H05BX02,PARICALCITOL,1517740,paricalcitol,21602793,73710
+H05BX03,DOXERCALCIFEROL,1512446,Doxercalciferol,21602794,11516
+J01AA01,DEMECLOCYCLINE,1714527,Demeclocycline,21602799,3154
+J01AA02,DOXYCYCLINE,964407,Salicylic Acid,21602800,9525
+J01AA02,DOXYCYCLINE,1738521,Doxycycline,21602800,3640
+J01AA05,METACYCLINE,19003644,Methacycline,21602803,6812
+J01AA06,OXYTETRACYCLINE,925952,Oxytetracycline,21602804,7821
+J01AA07,TETRACYCLINE,937791,bismuth subsalicylate,21602805,19478
+J01AA07,TETRACYCLINE,1707164,Metronidazole,21602805,6922
+J01AA07,TETRACYCLINE,1836948,Tetracycline,21602805,10395
+J01AA08,MINOCYCLINE,1708880,Minocycline,21602806,6980
+J01AA12,TIGECYCLINE,1742432,tigecycline,21602810,384455
+J01AA56,"OXYTETRACYCLINE, COMBINATIONS",925952,Oxytetracycline,21602812,7821
+J01AA56,"OXYTETRACYCLINE, COMBINATIONS",989878,Lidocaine,21602812,6387
+J01BA01,CHLORAMPHENICOL,990069,Chloramphenicol,21602815,2348
+J01CA01,AMPICILLIN,1717327,Ampicillin,21602820,733
+J01CA03,CARBENICILLIN,1740546,Carbenicillin,21602822,2015
+J01CA04,AMOXICILLIN,929887,lansoprazole,21602823,17128
+J01CA04,AMOXICILLIN,1713332,Amoxicillin,21602823,723
+J01CA04,AMOXICILLIN,1750500,Clarithromycin,21602823,21212
+J01CA05,CARINDACILLIN,1740546,Carbenicillin,21602824,2015
+J01CA06,BACAMPICILLIN,1734205,bacampicillin,21602825,18687
+J01CA09,AZLOCILLIN,19015123,Azlocillin,21602828,1266
+J01CA10,MEZLOCILLIN,19007701,Mezlocillin,21602829,6927
+J01CA12,PIPERACILLIN,1746114,Piperacillin,21602831,8339
+J01CA13,TICARCILLIN,1702364,Ticarcillin,21602832,10591
+J01CA18,HETACILLIN,19069006,hetacillin,21602837,26797
+J01CE01,BENZYLPENICILLIN,1728416,Penicillin G,21602841,7980
+J01CE02,PHENOXYMETHYLPENICILLIN,1729720,Penicillin V,21602842,7984
+J01CE08,BENZATHINE BENZYLPENICILLIN,1728416,Penicillin G,21602848,7980
+J01CE09,PROCAINE BENZYLPENICILLIN,1728416,Penicillin G,21602849,7980
+J01CF,BETA-LACTAMASE RESISTANT PENICILLINS,1713930,Nafcillin,21602852,7233
+J01CF01,DICLOXACILLIN,1724666,Dicloxacillin,21602853,3356
+J01CF02,CLOXACILLIN,1800835,Cloxacillin,21602854,2625
+J01CF03,METHICILLIN,19001323,Methicillin Sodium,21602855,267073
+J01CF04,OXACILLIN,1724703,Oxacillin,21602856,7773
+J01CR01,AMPICILLIN AND ENZYME INHIBITOR,1717327,Ampicillin,21602862,733
+J01CR01,AMPICILLIN AND ENZYME INHIBITOR,1836241,Sulbactam,21602862,10167
+J01CR02,AMOXICILLIN AND ENZYME INHIBITOR,1713332,Amoxicillin,21602863,723
+J01CR02,AMOXICILLIN AND ENZYME INHIBITOR,1759842,Clavulanate,21602863,48203
+J01CR03,TICARCILLIN AND ENZYME INHIBITOR,1702364,Ticarcillin,21602864,10591
+J01CR03,TICARCILLIN AND ENZYME INHIBITOR,1759842,Clavulanate,21602864,48203
+J01CR05,PIPERACILLIN AND ENZYME INHIBITOR,1741122,tazobactam,21602866,37617
+J01CR05,PIPERACILLIN AND ENZYME INHIBITOR,1746114,Piperacillin,21602866,8339
+J01CR50,COMBINATIONS OF PENICILLINS,1728416,Penicillin G,21602867,7980
+J01DB01,CEFALEXIN,1786621,Cephalexin,21602870,2231
+J01DB03,CEFALOTIN,19086759,Cephalothin,21602872,2236
+J01DB04,CEFAZOLIN,1771162,Cefazolin,21602873,2180
+J01DB05,CEFADROXIL,1769535,Cefadroxil,21602874,2177
+J01DB08,CEFAPIRIN,19086790,Cephapirin,21602877,2238
+J01DB09,CEFRADINE,1786842,Cephradine,21602878,2239
+J01DC01,CEFOXITIN,1775741,Cefoxitin,21602883,2189
+J01DC02,CEFUROXIME,1778162,Cefuroxime,21602884,2194
+J01DC03,CEFAMANDOLE,19070174,Cefamandole,21602885,2178
+J01DC04,CEFACLOR,1768849,Cefaclor,21602886,2176
+J01DC05,CEFOTETAN,1774932,Cefotetan,21602887,2187
+J01DC06,CEFONICIDE,19072857,Cefonicid,21602888,2183
+J01DC08,LORACARBEF,1708100,loracarbef,21602890,28981
+J01DC09,CEFMETAZOLE,19072255,Cefmetazole,21602891,2182
+J01DC10,CEFPROZIL,1738366,cefprozil,21602892,19552
+J01DD01,CEFOTAXIME,1774470,Cefotaxime,21602895,2186
+J01DD02,CEFTAZIDIME,1776684,Ceftazidime,21602896,2191
+J01DD04,CEFTRIAXONE,1777806,Ceftriaxone,21602898,2193
+J01DD07,CEFTIZOXIME,1777254,Ceftizoxime,21602901,2192
+J01DD08,CEFIXIME,1796435,Cefixime,21602902,25033
+J01DD12,CEFOPERAZONE,1773402,Cefoperazone,21602906,2184
+J01DD13,CEFPODOXIME,1749008,cefpodoxime,21602907,20489
+J01DD14,CEFTIBUTEN,1749083,ceftibuten,21602908,20492
+J01DD15,CEFDINIR,1796458,cefdinir,21602909,25037
+J01DD16,CEFDITOREN,1747005,cefditoren,21602910,83682
+J01DE01,CEFEPIME,1748975,cefepime,21602915,20481
+J01DF01,AZTREONAM,1715117,Aztreonam,21602919,1272
+J01DH02,MEROPENEM,1709170,meropenem,21602921,29561
+J01DH03,ERTAPENEM,1717963,ertapenem,21602922,325642
+J01DH04,DORIPENEM,1713905,doripenem,21602923,119771
+J01DH51,IMIPENEM AND ENZYME INHIBITOR,1778262,Imipenem,21602925,5690
+J01DH51,IMIPENEM AND ENZYME INHIBITOR,1797258,Cilastatin,21602925,2540
+J01EA01,TRIMETHOPRIM,1705674,Trimethoprim,21602931,10829
+J01EB,SHORT-ACTING SULFONAMIDES,19026707,sulfacytine,21602934,78902
+J01EB02,SULFAMETHIZOLE,1036425,Sulfamethizole,21602936,10179
+J01EB04,SULFAPYRIDINE,19136493,Sulfapyridine,21602938,10188
+J01EB05,SULFAFURAZOLE,933724,Phenazopyridine,21602939,8120
+J01EB05,SULFAFURAZOLE,1836503,Sulfisoxazole,21602939,10207
+J01EB06,SULFANILAMIDE,1036475,Sulfanilamide,21602940,10184
+J01EC01,SULFAMETHOXAZOLE,933724,Phenazopyridine,21602945,8120
+J01EC01,SULFAMETHOXAZOLE,1836430,Sulfamethoxazole,21602945,10180
+J01EC02,SULFADIAZINE,1836391,Sulfadiazine,21602946,10171
+J01EE01,SULFAMETHOXAZOLE AND TRIMETHOPRIM,1705674,Trimethoprim,21602961,10829
+J01EE01,SULFAMETHOXAZOLE AND TRIMETHOPRIM,1836430,Sulfamethoxazole,21602961,10180
+J01FA01,ERYTHROMYCIN,1746940,Erythromycin,21602970,4053
+J01FA08,TROLEANDOMYCIN,19006043,Troleandomycin,21602976,10864
+J01FA09,CLARITHROMYCIN,929887,lansoprazole,21602977,17128
+J01FA09,CLARITHROMYCIN,1713332,Amoxicillin,21602977,723
+J01FA09,CLARITHROMYCIN,1750500,Clarithromycin,21602977,21212
+J01FA10,AZITHROMYCIN,1712549,trovafloxacin,21602978,115552
+J01FA10,AZITHROMYCIN,1734104,Azithromycin,21602978,18631
+J01FA13,DIRITHROMYCIN,1790024,dirithromycin,21602981,23437
+J01FA15,TELIITHROMYCIN,1702911,telithromycin,21602983,274786
+J01FF01,CLINDAMYCIN,997881,Clindamycin,21602985,2582
+J01FF02,LINCOMYCIN,1790692,Lincomycin,21602986,6398
+J01FG02,QUINUPRISTIN/DALFOPRISTIN,1789515,quinupristin,21602989,229367
+J01FG02,QUINUPRISTIN/DALFOPRISTIN,1789517,dalfopristin,21602989,229369
+J01GA01,STREPTOMYCIN,1836191,Streptomycin,21602992,10109
+J01GB01,TOBRAMYCIN,902722,Tobramycin,21602995,10627
+J01GB03,GENTAMICIN,919345,Gentamicin Sulfate (USP),21602996,142438
+J01GB04,KANAMYCIN,1784749,Kanamycin,21602997,6099
+J01GB05,NEOMYCIN,915981,Neomycin,21602998,7299
+J01GB06,AMIKACIN,1790868,Amikacin,21602999,641
+J01GB07,NETILMICIN,19017585,Netilmicin,21603000,7337
+J01MA,FLUOROQUINOLONES,19018154,alatrofloxacin,21603007,141440
+J01MA01,OFLOXACIN,923081,Ofloxacin,21603008,7623
+J01MA02,CIPROFLOXACIN,1797513,Ciprofloxacin,21603009,2551
+J01MA04,ENOXACIN,1743222,Enoxacin,21603011,3925
+J01MA05,TEMAFLOXACIN,19041153,temafloxacin,21603012,37771
+J01MA06,NORFLOXACIN,1721543,Norfloxacin,21603013,7517
+J01MA07,LOMEFLOXACIN,1707800,lomefloxacin,21603014,28872
+J01MA09,SPARFLOXACIN,1733765,sparfloxacin,21603016,18469
+J01MA11,GREPAFLOXACIN,1747032,grepafloxacin,21603018,83719
+J01MA12,LEVOFLOXACIN,1742253,Levofloxacin,21603019,82122
+J01MA13,TROVAFLOXACIN,1712549,trovafloxacin,21603020,115552
+J01MA13,TROVAFLOXACIN,1734104,Azithromycin,21603020,18631
+J01MA14,MOXIFLOXACIN,1716903,moxifloxacin,21603021,139462
+J01MA15,GEMIFLOXACIN,1716721,gemifloxacin,21603022,138099
+J01MA16,GATIFLOXACIN,1789276,gatifloxacin,21603023,228476
+J01MB06,CINOXACIN,997496,Cinoxacin,21603033,2550
+J01RA02,"SULFONAMIDES,COMBOS W-OTHER ANTIBACT (EXCL TMP)",1746940,Erythromycin,21603038,4053
+J01RA02,"SULFONAMIDES,COMBOS W-OTHER ANTIBACT (EXCL TMP)",1836503,Sulfisoxazole,21603038,10207
+J01XA01,VANCOMYCIN,1707687,Vancomycin,21603043,11124
+J01XB01,COLISTIN,1701677,colistimethate,21603049,2708
+J01XB02,POLYMYXIN B,948582,Polymyxin B,21603050,8536
+J01XD01,METRONIDAZOLE,1707164,Metronidazole,21603054,6922
+J01XE01,NITROFURANTOIN,920293,Nitrofurantoin,21603058,7454
+J01XX,OTHER ANTIBACTERIALS,915175,Bacitracin,21603060,1291
+J01XX04,SPECTINOMYCIN,1701651,Spectinomycin,21603064,270
+J01XX05,METHENAMINE,904356,Methenamine,21603065,6832
+J01XX05,METHENAMINE,939871,sodium phosphate,21603065,36709
+J01XX05,METHENAMINE,986389,"SODIUM PHOSPHATE,MONOBASIC,MONOHYDRATE",21603065,221125
+J01XX05,METHENAMINE,990499,"Sodium Phosphate, Monobasic",21603065,235496
+J01XX08,LINEZOLID,1736887,linezolid,21603068,190376
+J01XX09,DAPTOMYCIN,1786617,Daptomycin,21603069,22299
+J02AA01,AMPHOTERICIN B,1717240,Amphotericin B,21603074,732
+J02AB01,MICONAZOLE,907879,Miconazole,21603077,6932
+J02AB02,KETOCONAZOLE,985708,Ketoconazole,21603078,6135
+J02AC01,FLUCONAZOLE,1754994,Fluconazole,21603080,4450
+J02AC02,ITRACONAZOLE,1703653,Itraconazole,21603081,28031
+J02AC03,VORICONAZOLE,1714277,voriconazole,21603082,121243
+J02AC04,POSACONAZOLE,1704139,posaconazole,21603083,282446
+J02AX01,FLUCYTOSINE,1755112,Flucytosine,21603085,4451
+J02AX04,CASPOFUNGIN,1718054,Caspofungin,21603086,140108
+J02AX05,MICAFUNGIN,19018013,micafungin,21603087,325887
+J02AX06,ANIDULAFUNGIN,19026450,anidulafungin,21603088,341018
+J04AA01,AMINOSALICYLIC ACID,1726228,aminosalicylic acid,21603092,7833
+J04AA02,SODIUM AMINOSALICYLATE,1726228,aminosalicylic acid,21603093,7833
+J04AA02,SODIUM AMINOSALICYLATE,19010337,AMINOSALICYLATE,21603093,113374
+J04AB01,CYCLOSERINE,1710446,Cycloserine,21603096,3007
+J04AB02,RIFAMPICIN,1763204,Rifampin,21603097,9384
+J04AB04,RIFABUTIN,1777417,Rifabutin,21603099,55672
+J04AB05,RIFAPENTINE,19035953,rifapentine,21603100,35617
+J04AB30,CAPREOMYCIN,19026710,Capreomycin,21603101,78903
+J04AC01,ISONIAZID,1782521,isoniazid,21603103,6038
+J04AC51,"ISONIAZID, COMBINATIONS",1353228,Vitamin B6,21603104,42954
+J04AC51,"ISONIAZID, COMBINATIONS",1782521,isoniazid,21603104,6038
+J04AC51,"ISONIAZID, COMBINATIONS",19005046,pyridoxine,21603104,684879
+J04AD03,ETHIONAMIDE,1750074,Ethionamide,21603108,4127
+J04AK01,PYRAZINAMIDE,1759455,Pyrazinamide,21603110,8987
+J04AK02,ETHAMBUTOL,1749301,Ethambutol,21603111,4110
+J04AM02,RIFAMPICIN AND ISONIAZID,1763204,Rifampin,21603116,9384
+J04AM02,RIFAMPICIN AND ISONIAZID,1782521,isoniazid,21603116,6038
+J04AM05,"RIFAMPICIN, PYRAZINAMIDE AND ISONIAZID",1759455,Pyrazinamide,21603119,8987
+J04AM05,"RIFAMPICIN, PYRAZINAMIDE AND ISONIAZID",1763204,Rifampin,21603119,9384
+J04AM05,"RIFAMPICIN, PYRAZINAMIDE AND ISONIAZID",1782521,isoniazid,21603119,6038
+J04BA01,CLOFAZIMINE,1798476,Clofazimine,21603123,2592
+J04BA02,DAPSONE,1711759,Dapsone,21603124,3108
+J05AB01,ACICLOVIR,1703687,Acyclovir,21603131,281
+J05AB03,VIDARABINE,908126,Vidarabine,21603133,11194
+J05AB04,RIBAVIRIN,1380068,Interferon Alfa-2b,21603134,5880
+J05AB04,RIBAVIRIN,1762711,Ribavirin,21603134,9344
+J05AB06,GANCICLOVIR,1757803,Ganciclovir,21603135,4678
+J05AB09,FAMCICLOVIR,1703603,famciclovir,21603136,68099
+J05AB11,VALACICLOVIR,1717704,valacyclovir,21603137,73645
+J05AB12,CIDOFOVIR,1745072,Cidofovir,21603138,83171
+J05AB14,VALGANCICLOVIR,1703063,valganciclovir,21603140,275891
+J05AE01,SAQUINAVIR,1746244,Saquinavir,21603149,83395
+J05AE02,INDINAVIR,1711523,Indinavir,21603150,114289
+J05AE03,RITONAVIR,1748921,Ritonavir,21603151,85762
+J05AE04,NELFINAVIR,1715472,Nelfinavir,21603152,134527
+J05AE05,AMPRENAVIR,1789428,Amprenavir,21603153,228656
+J05AE05,AMPRENAVIR,19009540,Vitamin E,21603153,11256
+J05AE06,LOPINAVIR,1738170,lopinavir,21603154,195088
+J05AE06,LOPINAVIR,1748921,Ritonavir,21603154,85762
+J05AE07,FOSAMPRENAVIR,1736829,fosamprenavir,21603155,358262
+J05AE08,ATAZANAVIR,1727223,Atazanavir,21603156,343047
+J05AE09,TIPRANAVIR,1736999,tipranavir,21603157,190548
+J05AE10,DARUNAVIR,1756831,darunavir,21603158,460132
+J05AF01,ZIDOVUDINE,1710612,Zidovudine,21603160,11413
+J05AF02,DIDANOSINE,1724869,Didanosine,21603161,3364
+J05AF03,ZALCITABINE,1724827,Zalcitabine,21603162,3363
+J05AF04,STAVUDINE,1781406,Stavudine,21603163,59763
+J05AF05,LAMIVUDINE,1704183,Lamivudine,21603164,68244
+J05AF06,ABACAVIR,1736971,abacavir,21603165,190521
+J05AF07,TENOFOVIR DISOPROXIL,1710281,tenofovir disoproxil,21603166,300195
+J05AF08,ADEFOVIR DIPIVOXIL,1729323,adefovir,21603167,16521
+J05AF09,EMTRICITABINE,1703069,emtricitabine,21603168,276237
+J05AF10,ENTECAVIR,1711246,entecavir,21603169,306266
+J05AF11,TELBIVUDINE,1758392,telbivudine,21603170,474128
+J05AG01,NEVIRAPINE,1769389,Nevirapine,21603173,53654
+J05AG03,EFAVIRENZ,1738135,efavirenz,21603175,195085
+J05AG04,ETRAVIRINE,1758536,etravirine,21603176,475969
+J05AH01,ZANAMIVIR,1708748,Zanamivir,21603178,69722
+J05AH02,OSELTAMIVIR,1799139,Oseltamivir,21603179,260101
+J05AR01,ZIDOVUDINE AND LAMIVUDINE,1704183,Lamivudine,21603181,68244
+J05AR01,ZIDOVUDINE AND LAMIVUDINE,1710612,Zidovudine,21603181,11413
+J05AR02,LAMIVUDINE AND ABACAVIR,1704183,Lamivudine,21603182,68244
+J05AR02,LAMIVUDINE AND ABACAVIR,1736971,abacavir,21603182,190521
+J05AR03,TENOFOVIR DISOPROXIL AND EMTRICITABINE,1703069,emtricitabine,21603183,276237
+J05AR03,TENOFOVIR DISOPROXIL AND EMTRICITABINE,1710281,tenofovir disoproxil,21603183,300195
+J05AR04,"ZIDOVUDINE, LAMIVUDINE AND ABACAVIR",1704183,Lamivudine,21603184,68244
+J05AR04,"ZIDOVUDINE, LAMIVUDINE AND ABACAVIR",1710612,Zidovudine,21603184,11413
+J05AR04,"ZIDOVUDINE, LAMIVUDINE AND ABACAVIR",1736971,abacavir,21603184,190521
+J05AR06,"EMTRICITABINE,TENOFOVIR DISOPROXIL AND EFAVIRENZ",1703069,emtricitabine,21603186,276237
+J05AR06,"EMTRICITABINE,TENOFOVIR DISOPROXIL AND EFAVIRENZ",1710281,tenofovir disoproxil,21603186,300195
+J05AR06,"EMTRICITABINE,TENOFOVIR DISOPROXIL AND EFAVIRENZ",1738135,efavirenz,21603186,195085
+J05AX07,ENFUVIRTIDE,1717002,enfuvirtide,21603193,139896
+J05AX08,RALTEGRAVIR,1712889,Raltegravir,21603194,719872
+J05AX09,MARAVIROC,1787101,maraviroc,21603195,620216
+R01AX03,IPRATROPIUM BROMIDE,1112921,Ipratropium,21603199,7213
+R01AX06,MUPIROCIN,951511,Mupirocin,21603201,42372
+R01AX10,VARIOUS,967823,Sodium Chloride,21603205,9863
+R01AX30,COMBINATIONS,929128,Propylene glycol,21603206,34693
+R01AX30,COMBINATIONS,948515,Polyethylene Glycols,21603206,8516
+R01BA01,PHENYLPROPANOLAMINE,1139993,Phenylpropanolamine,21603209,8175
+R01BA02,PSEUDOEPHEDRINE,1154332,Pseudoephedrine,21603210,8896
+R01BA03,PHENYLEPHRINE,1135766,Phenylephrine,21603211,8163
+R01BA51,"PHENYLPROPANOLAMINE, COMBINATIONS",1130863,Brompheniramine,21603212,1767
+R01BA51,"PHENYLPROPANOLAMINE, COMBINATIONS",1135766,Phenylephrine,21603212,8163
+R01BA51,"PHENYLPROPANOLAMINE, COMBINATIONS",1139993,Phenylpropanolamine,21603212,8175
+R01BA51,"PHENYLPROPANOLAMINE, COMBINATIONS",1192710,Chlorpheniramine,21603212,2400
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",965748,Scopolamine,21603213,9601
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",979096,Zinc Acetate,21603213,58295
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1103006,desloratadine,21603213,275635
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1105889,Triprolidine,21603213,10849
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1107830,Loratadine,21603213,28889
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1116109,Belladonna Alkaloids,21603213,1359
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1129625,Diphenhydramine,21603213,3498
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1130863,Brompheniramine,21603213,1767
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1133993,azatadine,21603213,18600
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1135766,Phenylephrine,21603213,8163
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1140123,acrivastine,21603213,19959
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1141018,carbinoxamine,21603213,20220
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1149196,Cetirizine,21603213,20610
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1153428,fexofenadine,21603213,87636
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1154332,Pseudoephedrine,21603213,8896
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1158632,Methscopolamine,21603213,89785
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1159811,Pyrilamine,21603213,9009
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1188052,dexbrompheniramine,21603213,22696
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1188114,dexchlorpheniramine,21603213,22697
+R01BA52,"PSEUDOEPHEDRINE, COMBINATIONS",1192710,Chlorpheniramine,21603213,2400
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",933952,Pheniramine,21603214,8132
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",965748,Scopolamine,21603214,9601
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",979096,Zinc Acetate,21603214,58295
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1105889,Triprolidine,21603214,10849
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1119510,Dextromethorphan,21603214,3289
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1123904,phenyltoloxamine,21603214,33408
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1129625,Diphenhydramine,21603214,3498
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1130863,Brompheniramine,21603214,1767
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1135766,Phenylephrine,21603214,8163
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1141018,carbinoxamine,21603214,20220
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1153013,Promethazine,21603214,8745
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1154332,Pseudoephedrine,21603214,8896
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1158632,Methscopolamine,21603214,89785
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1159811,Pyrilamine,21603214,9009
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1163944,Guaifenesin,21603214,5032
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1188052,dexbrompheniramine,21603214,22696
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1188114,dexchlorpheniramine,21603214,22697
+R01BA53,"PHENYLEPHRINE, COMBINATIONS",1192710,Chlorpheniramine,21603214,2400
+R02AA06,CETYLPYRIDINIUM,917006,Benzocaine,21603222,1399
+R02AA06,CETYLPYRIDINIUM,989301,Cetylpyridinium,21603222,2286
+R02AA12,HEXYLRESORCINOL,969004,Hexylresorcinol,21603226,5321
+R02AA19,PHENOL,923540,phenol,21603233,33290
+R02AA20,VARIOUS,901656,Menthol,21603234,6750
+R02AA20,VARIOUS,917006,Benzocaine,21603234,1399
+R02AA20,VARIOUS,989301,Cetylpyridinium,21603234,2286
+R02AA20,VARIOUS,19009686,methylbenzethonium,21603234,29829
+R02AD,"ANESTHETICS, LOCAL",901656,Menthol,21603241,6750
+R02AD,"ANESTHETICS, LOCAL",917006,Benzocaine,21603241,1399
+R02AD01,BENZOCAINE,917006,Benzocaine,21603242,1399
+R02AD01,BENZOCAINE,961145,Glycerin,21603242,4910
+R02AD04,DYCLONINE,992308,dyclonine,21603245,23744
+R03AA01,EPINEPHRINE,1300153,Racepinephrine,21603251,66887
+R03AA01,EPINEPHRINE,1343916,Epinephrine,21603251,3992
+R03AB02,ISOPRENALINE,1183554,Isoproterenol,21603253,6054
+R03AB03,ORCIPRENALINE,1123995,Orciprenaline,21603254,7688
+R03AC,SELECTIVE BETA-2-ADRENOCEPTOR AGONISTS,1111220,arformoterol,21603255,304962
+R03AC,SELECTIVE BETA-2-ADRENOCEPTOR AGONISTS,1192218,Levalbuterol,21603255,237159
+R03AC02,SALBUTAMOL,1154343,Albuterol,21603256,435
+R03AC07,ISOETARINE,1181809,Isoetharine,21603261,6023
+R03AC08,PIRBUTEROL,1125449,pirbuterol,21603262,33767
+R03AC12,SALMETEROL,1137529,salmeterol,21603266,36117
+R03AC13,FORMOTEROL,1196677,formoterol,21603267,25255
+R03AC17,BITOLTEROL,1138050,bitolterol,21603271,19499
+R03AK01,EPINEPHRINE & OTHER DRUGS FOR OBSTRUCT AIRWAY DIS,1300153,Racepinephrine,21603275,66887
+R03AK04,SALBUTAMOL & OTHER DRUGS FOR OBSTRUCT AIRWAY DIS,1112921,Ipratropium,21603278,7213
+R03AK04,SALBUTAMOL & OTHER DRUGS FOR OBSTRUCT AIRWAY DIS,1154343,Albuterol,21603278,435
+R03AK06,SALMETEROL & OTHER DRUGS FOR OBSTRUCT AIRWAY DIS,1137529,salmeterol,21603280,36117
+R03AK06,SALMETEROL & OTHER DRUGS FOR OBSTRUCT AIRWAY DIS,1149380,fluticasone,21603280,41126
+R03AK07,FORMOTEROL & OTHER DRUGS FOR OBSTRUCT AIRWAY DIS,939259,Budesonide,21603281,19831
+R03AK07,FORMOTEROL & OTHER DRUGS FOR OBSTRUCT AIRWAY DIS,1196677,formoterol,21603281,25255
+R03BA01,BECLOMETASONE,1115572,Beclomethasone,21603284,1347
+R03BA02,BUDESONIDE,939259,Budesonide,21603285,19831
+R03BA03,FLUNISOLIDE,1196514,flunisolide,21603286,25120
+R03BA05,FLUTICASONE,1149380,fluticasone,21603288,41126
+R03BA06,TRIAMCINOLONE,903963,Triamcinolone,21603289,10759
+R03BA07,MOMETASONE,905233,Mometasone,21603290,108118
+R03BA08,CICLESONIDE,902938,ciclesonide,21603291,274964
+R03BB01,IPRATROPIUM BROMIDE,1112921,Ipratropium,21603293,7213
+R03BB04,TIOTROPIUM BROMIDE,1106776,tiotropium,21603296,69120
+R03BC01,CROMOGLICIC ACID,1152631,Cromolyn,21603298,42612
+R03BC03,NEDOCROMIL,1114620,Nedocromil,21603299,31563
+R03CA02,EPHEDRINE,1143374,Ephedrine,21603304,3966
+R03CB02,METHOXYPHENAMINE,19009365,methoxyphenamine,21603307,29704
+R03CB03,ORCIPRENALINE,1123995,Orciprenaline,21603308,7688
+R03CC02,SALBUTAMOL,1154343,Albuterol,21603312,435
+R03DA01,DIPROPHYLLINE,1140088,Dyphylline,21603329,3714
+R03DA02,CHOLINE THEOPHYLLINATE,19049816,cholinophyllin,21603330,20976
+R03DA04,THEOPHYLLINE,1237049,Theophylline,21603332,10438
+R03DA05,AMINOPHYLLINE,1105775,Aminophylline,21603333,689
+R03DA54,"THEOPHYLLINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1163944,Guaifenesin,21603342,5032
+R03DA54,"THEOPHYLLINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1237049,Theophylline,21603342,10438
+R03DA54,"THEOPHYLLINE, COMBINATIONS EXCL. PSYCHOLEPTICS",19049816,cholinophyllin,21603342,20976
+R03DB04,THEOPHYLLINE AND ADRENERGICS,734275,Phenobarbital,21603350,8134
+R03DB04,THEOPHYLLINE AND ADRENERGICS,1143374,Ephedrine,21603350,3966
+R03DB04,THEOPHYLLINE AND ADRENERGICS,1237049,Theophylline,21603350,10438
+R03DC01,ZAFIRLUKAST,1111706,zafirlukast,21603354,114970
+R03DC03,MONTELUKAST,1154161,montelukast,21603356,88249
+R03DX,OTHER SYSTEMIC DRUGS FOR OBSTRUCTIVE AIRWAY DISEAS,1147878,zileuton,21603358,40575
+R03DX05,OMALIZUMAB,1110942,omalizumab,21603362,302379
+R05CA,EXPECTORANTS,19059707,Terpin hydrate,21603367,89916
+R05CA02,POTASSIUM IODIDE,1237049,Theophylline,21603369,10438
+R05CA02,POTASSIUM IODIDE,19049909,Potassium Iodide,21603369,8597
+R05CA03,GUAIFENESIN,1163944,Guaifenesin,21603370,5032
+R05CA09,GUAIACOLSULFONATE,1189220,guaiacolsulfonate,21603376,636827
+R05CA10,COMBINATIONS,976545,potassium citrate,21603377,54993
+R05CA10,COMBINATIONS,979096,Zinc Acetate,21603377,58295
+R05CA10,COMBINATIONS,1130863,Brompheniramine,21603377,1767
+R05CA10,COMBINATIONS,1135766,Phenylephrine,21603377,8163
+R05CA10,COMBINATIONS,1139993,Phenylpropanolamine,21603377,8175
+R05CA10,COMBINATIONS,1140088,Dyphylline,21603377,3714
+R05CA10,COMBINATIONS,1143374,Ephedrine,21603377,3966
+R05CA10,COMBINATIONS,1154332,Pseudoephedrine,21603377,8896
+R05CA10,COMBINATIONS,1158632,Methscopolamine,21603377,89785
+R05CA10,COMBINATIONS,1159811,Pyrilamine,21603377,9009
+R05CA10,COMBINATIONS,1163944,Guaifenesin,21603377,5032
+R05CA10,COMBINATIONS,1189220,guaiacolsulfonate,21603377,636827
+R05CA10,COMBINATIONS,1192710,Chlorpheniramine,21603377,2400
+R05CA10,COMBINATIONS,1200939,guaiacolsulfonic acid,21603377,26288
+R05CA10,COMBINATIONS,1201620,Codeine,21603377,2670
+R05CA10,COMBINATIONS,19049909,Potassium Iodide,21603377,8597
+R05CB01,ACETYLCYSTEINE,1139042,Acetylcysteine,21603380,197
+R05CB03,CARBOCISTEINE,19041843,Carbocysteine,21603382,2023
+R05CB12,TIOPRONIN,903031,Thiopronine,21603391,6765
+R05CB13,DORNASE ALFA (DESOXYRIBONUCLEASE),1125443,Dornase Alfa,21603392,337623
+R05DA04,CODEINE,1201620,Codeine,21603399,2670
+R05DA09,DEXTROMETHORPHAN,1119510,Dextromethorphan,21603404,3289
+R05DA20,COMBINATIONS,738818,Doxylamine,21603408,3642
+R05DA20,COMBINATIONS,917006,Benzocaine,21603408,1399
+R05DA20,COMBINATIONS,961145,Glycerin,21603408,4910
+R05DA20,COMBINATIONS,965748,Scopolamine,21603408,9601
+R05DA20,COMBINATIONS,1101703,homatropine,21603408,27084
+R05DA20,COMBINATIONS,1105889,Triprolidine,21603408,10849
+R05DA20,COMBINATIONS,1119510,Dextromethorphan,21603408,3289
+R05DA20,COMBINATIONS,1129625,Diphenhydramine,21603408,3498
+R05DA20,COMBINATIONS,1130863,Brompheniramine,21603408,1767
+R05DA20,COMBINATIONS,1135766,Phenylephrine,21603408,8163
+R05DA20,COMBINATIONS,1139216,bromodiphenhydramine,21603408,19759
+R05DA20,COMBINATIONS,1139993,Phenylpropanolamine,21603408,8175
+R05DA20,COMBINATIONS,1140640,carbetapentane,21603408,20217
+R05DA20,COMBINATIONS,1141018,carbinoxamine,21603408,20220
+R05DA20,COMBINATIONS,1153013,Promethazine,21603408,8745
+R05DA20,COMBINATIONS,1154332,Pseudoephedrine,21603408,8896
+R05DA20,COMBINATIONS,1159811,Pyrilamine,21603408,9009
+R05DA20,COMBINATIONS,1163944,Guaifenesin,21603408,5032
+R05DA20,COMBINATIONS,1174888,Hydrocodone,21603408,5489
+R05DA20,COMBINATIONS,1188052,dexbrompheniramine,21603408,22696
+R05DA20,COMBINATIONS,1188114,dexchlorpheniramine,21603408,22697
+R05DA20,COMBINATIONS,1189220,guaiacolsulfonate,21603408,636827
+R05DA20,COMBINATIONS,1189596,dihydrocodeine,21603408,23088
+R05DA20,COMBINATIONS,1192710,Chlorpheniramine,21603408,2400
+R05DA20,COMBINATIONS,1200939,guaiacolsulfonic acid,21603408,26288
+R05DA20,COMBINATIONS,1201620,Codeine,21603408,2670
+R05DB01,BENZONATATE,1136601,benzonatate,21603410,18993
+R05DB05,PENTOXYVERINE,1140640,carbetapentane,21603414,20217
+R05DB20,COMBINATIONS,979096,Zinc Acetate,21603427,58295
+R05DB20,COMBINATIONS,1119510,Dextromethorphan,21603427,3289
+R05DB20,COMBINATIONS,1129625,Diphenhydramine,21603427,3498
+R05DB20,COMBINATIONS,1130863,Brompheniramine,21603427,1767
+R05DB20,COMBINATIONS,1135766,Phenylephrine,21603427,8163
+R05DB20,COMBINATIONS,1140640,carbetapentane,21603427,20217
+R05DB20,COMBINATIONS,1141018,carbinoxamine,21603427,20220
+R05DB20,COMBINATIONS,1143374,Ephedrine,21603427,3966
+R05DB20,COMBINATIONS,1154332,Pseudoephedrine,21603427,8896
+R05DB20,COMBINATIONS,1159811,Pyrilamine,21603427,9009
+R05DB20,COMBINATIONS,1192710,Chlorpheniramine,21603427,2400
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,976545,potassium citrate,21603439,54993
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,977968,sodium citrate,21603439,56466
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1119510,Dextromethorphan,21603439,3289
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1126658,Hydromorphone,21603439,3423
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1130863,Brompheniramine,21603439,1767
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1135766,Phenylephrine,21603439,8163
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1139993,Phenylpropanolamine,21603439,8175
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1154332,Pseudoephedrine,21603439,8896
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1158632,Methscopolamine,21603439,89785
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1159811,Pyrilamine,21603439,9009
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1163944,Guaifenesin,21603439,5032
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1174888,Hydrocodone,21603439,5489
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1188052,dexbrompheniramine,21603439,22696
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1188114,dexchlorpheniramine,21603439,22697
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1189220,guaiacolsulfonate,21603439,636827
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1189596,dihydrocodeine,21603439,23088
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1192710,Chlorpheniramine,21603439,2400
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1200939,guaiacolsulfonic acid,21603439,26288
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,1201620,Codeine,21603439,2670
+R05FA02,OPIUM DERIVATIVES AND EXPECTORANTS,19049909,Potassium Iodide,21603439,8597
+R05FB02,COUGH SUPPRESSANTS AND EXPECTORANTS,1135766,Phenylephrine,21603442,8163
+R05FB02,COUGH SUPPRESSANTS AND EXPECTORANTS,1140640,carbetapentane,21603442,20217
+R05FB02,COUGH SUPPRESSANTS AND EXPECTORANTS,1150886,clofedanol,21603442,21254
+R05FB02,COUGH SUPPRESSANTS AND EXPECTORANTS,1154332,Pseudoephedrine,21603442,8896
+R05FB02,COUGH SUPPRESSANTS AND EXPECTORANTS,1163944,Guaifenesin,21603442,5032
+R05X,OTHER COLD COMBINATION PREPARATIONS,901656,Menthol,21603443,6750
+R05X,OTHER COLD COMBINATION PREPARATIONS,912362,Ammonium Chloride,21603443,712
+R05X,OTHER COLD COMBINATION PREPARATIONS,922191,pectin,21603443,32987
+R05X,OTHER COLD COMBINATION PREPARATIONS,938205,Camphor,21603443,1952
+R05X,OTHER COLD COMBINATION PREPARATIONS,977968,sodium citrate,21603443,56466
+R05X,OTHER COLD COMBINATION PREPARATIONS,1129625,Diphenhydramine,21603443,3498
+R05X,OTHER COLD COMBINATION PREPARATIONS,1180412,Eucalyptus oil,21603443,59087
+R05X,OTHER COLD COMBINATION PREPARATIONS,19004430,SWEETLEAF Preparation,21603443,283740
+R05X,OTHER COLD COMBINATION PREPARATIONS,19044317,zinc chloride,21603443,39937
+R06AA02,DIPHENHYDRAMINE,928744,Dimenhydrinate,21603448,3444
+R06AA02,DIPHENHYDRAMINE,1129625,Diphenhydramine,21603448,3498
+R06AA07,DIPHENYLPYRALINE,19090000,diphenylpyraline,21603451,23386
+R06AA08,CARBINOXAMINE,1141018,carbinoxamine,21603452,20220
+R06AA09,DOXYLAMINE,738818,Doxylamine,21603453,3642
+R06AA09,DOXYLAMINE,1353228,Vitamin B6,21603453,42954
+R06AB01,BROMPHENIRAMINE,1130863,Brompheniramine,21603459,1767
+R06AB02,DEXCHLORPHENIRAMINE,1188114,dexchlorpheniramine,21603460,22697
+R06AB04,CHLORPHENAMINE,1192710,Chlorpheniramine,21603462,2400
+R06AB04,CHLORPHENAMINE,1343916,Epinephrine,21603462,3992
+R06AB06,DEXBROMPHENIRAMINE,1188052,dexbrompheniramine,21603464,22696
+R06AB54,"CHLORPHENAMINE, COMBINATIONS",965748,Scopolamine,21603468,9601
+R06AB54,"CHLORPHENAMINE, COMBINATIONS",1135766,Phenylephrine,21603468,8163
+R06AB54,"CHLORPHENAMINE, COMBINATIONS",1154332,Pseudoephedrine,21603468,8896
+R06AB54,"CHLORPHENAMINE, COMBINATIONS",1158632,Methscopolamine,21603468,89785
+R06AB54,"CHLORPHENAMINE, COMBINATIONS",1192710,Chlorpheniramine,21603468,2400
+R06AC01,MEPYRAMINE,1159811,Pyrilamine,21603471,9009
+R06AC04,TRIPELENNAMINE,1105853,Tripelennamine,21603474,10847
+R06AC05,METHAPYRILENE,19004158,Methapyrilene,21603475,6822
+R06AD01,ALIMEMAZINE,19005570,Trimeprazine,21603480,10825
+R06AD02,PROMETHAZINE,1153013,Promethazine,21603481,8745
+R06AD03,THIETHYLPERAZINE,1037358,Thiethylperazine,21603482,10471
+R06AD04,METHDILAZINE,19009250,methdilazine,21603483,29648
+R06AE01,BUCLIZINE,19081195,buclizine,21603492,59636
+R06AE03,CYCLIZINE,909358,Cyclizine,21603493,2977
+R06AE05,MECLOZINE,994341,Meclizine,21603495,6676
+R06AE07,CETIRIZINE,1149196,Cetirizine,21603497,20610
+R06AK,COMBINATIONS OF ANTIHISTAMINES,933952,Pheniramine,21603502,8132
+R06AK,COMBINATIONS OF ANTIHISTAMINES,1123904,phenyltoloxamine,21603502,33408
+R06AK,COMBINATIONS OF ANTIHISTAMINES,1129625,Diphenhydramine,21603502,3498
+R06AK,COMBINATIONS OF ANTIHISTAMINES,1130863,Brompheniramine,21603502,1767
+R06AK,COMBINATIONS OF ANTIHISTAMINES,1159811,Pyrilamine,21603502,9009
+R06AK,COMBINATIONS OF ANTIHISTAMINES,1188052,dexbrompheniramine,21603502,22696
+R06AX02,CYPROHEPTADINE,1110727,Cyproheptadine,21603505,3013
+R06AX04,PHENINDAMINE,1123534,phenindamine,21603507,33283
+R06AX05,ANTAZOLINE,951237,Antazoline,21603508,865
+R06AX07,TRIPROLIDINE,1105889,Triprolidine,21603509,10849
+R06AX09,AZATADINE,1133993,azatadine,21603511,18600
+R06AX11,ASTEMIZOLE,1150770,Astemizole,21603512,42328
+R06AX12,TERFENADINE,1150836,Terfenadine,21603513,42330
+R06AX13,LORATADINE,1107830,Loratadine,21603514,28889
+R06AX26,FEXOFENADINE,1153428,fexofenadine,21603525,87636
+R06AX27,DESLORATADINE,1103006,desloratadine,21603526,275635
+R07AA02,NATURAL PHOSPHOLIPIDS,19057932,beractant,21603534,46967
+R07AA02,NATURAL PHOSPHOLIPIDS,19089891,calfactant,21603534,232539
+R07AA02,NATURAL PHOSPHOLIPIDS,19091377,Poractant alfa,21603534,236381
+R07AB01,DOXAPRAM,738152,Doxapram,21603537,3637
+R07AB02,NIKETHAMIDE,19019088,Nikethamide,21603538,7424
+R07AX,OTHER RESPIRATORY SYSTEM PRODUCTS,967823,Sodium Chloride,21603548,9863
+S01AA01,CHLORAMPHENICOL,990069,Chloramphenicol,21603554,2348
+S01AA02,CHLORTETRACYCLINE,19095043,Chlortetracycline,21603555,2408
+S01AA09,TETRACYCLINE,1836948,Tetracycline,21603560,10395
+S01AA10,NATAMYCIN,915392,Natamycin,21603561,7268
+S01AA11,GENTAMICIN,919345,Gentamicin Sulfate (USP),21603562,142438
+S01AA12,TOBRAMYCIN,902722,Tobramycin,21603563,10627
+S01AA17,ERYTHROMYCIN,1746940,Erythromycin,21603568,4053
+S01AA20,ANTIBIOTICS IN COMBINATION WITH OTHER DRUGS,1036252,Sulfacetamide,21603571,10169
+S01AA20,ANTIBIOTICS IN COMBINATION WITH OTHER DRUGS,1135766,Phenylephrine,21603571,8163
+S01AA26,AZITHROMYCIN,1734104,Azithromycin,21603577,18631
+S01AA30,COMBINATIONS OF DIFFERENT ANTIBIOTICS,915175,Bacitracin,21603578,1291
+S01AA30,COMBINATIONS OF DIFFERENT ANTIBIOTICS,915981,Neomycin,21603578,7299
+S01AA30,COMBINATIONS OF DIFFERENT ANTIBIOTICS,948582,Polymyxin B,21603578,8536
+S01AA30,COMBINATIONS OF DIFFERENT ANTIBIOTICS,963742,Gramicidin,21603578,5011
+S01AA30,COMBINATIONS OF DIFFERENT ANTIBIOTICS,1705674,Trimethoprim,21603578,10829
+S01AB04,SULFACETAMIDE,1036252,Sulfacetamide,21603583,10169
+S01AD01,IDOXURIDINE,19078156,Idoxuridine,21603586,5653
+S01AD02,TRIFLURIDINE,905078,Trifluridine,21603587,10803
+S01AD06,VIDARABINE,908126,Vidarabine,21603590,11194
+S01AD08,FOMIVIRSEN,19048999,fomivirsen,21603592,85763
+S01AD09,GANCICLOVIR,1757803,Ganciclovir,21603593,4678
+S01AX,OTHER ANTIINFECTIVES,915175,Bacitracin,21603594,1291
+S01AX03,ZINC COMPOUNDS,19044522,Zinc Sulfate,21603597,39954
+S01AX11,OFLOXACIN,923081,Ofloxacin,21603605,7623
+S01AX12,NORFLOXACIN,1721543,Norfloxacin,21603606,7517
+S01AX13,CIPROFLOXACIN,1797513,Ciprofloxacin,21603607,2551
+S01AX18,POVIDONE-IODINE,1750087,Povidone-Iodine,21603612,8611
+S01AX19,LEVOFLOXACIN,1742253,Levofloxacin,21603613,82122
+S01AX21,GATIFLOXACIN,1789276,gatifloxacin,21603614,228476
+S01AX22,MOXIFLOXACIN,1716903,moxifloxacin,21603615,139462
+S01BA,"CORTICOSTEROIDS, PLAIN",19089579,difluprednate,21603617,23043
+S01BA01,DEXAMETHASONE,1518254,Dexamethasone,21603618,3264
+S01BA02,HYDROCORTISONE,975125,Hydrocortisone,21603619,5492
+S01BA04,PREDNISOLONE,1550557,prednisolone,21603621,8638
+S01BA05,TRIAMCINOLONE,903963,Triamcinolone,21603622,10759
+S01BA07,FLUOROMETHOLONE,955583,Fluorometholone,21603624,4491
+S01BA08,MEDRYSONE,909021,medrysone,21603625,29439
+S01BA13,RIMEXOLONE,977421,rimexolone,21603630,55681
+S01BA14,LOTEPREDNOL,967562,loteprednol etabonate,21603631,52177
+S01BC,"ANTIINFLAMMATORY AGENTS, NON-STEROIDS",1036636,Suprofen,21603638,10255
+S01BC04,FLURBIPROFEN,1156378,Flurbiprofen,21603642,4502
+S01BC05,KETOROLAC,1136980,Ketorolac,21603643,35827
+S01BC10,NEPAFENAC,909795,nepafenac,21603648,298665
+S01BC11,BROMFENAC,1139179,bromfenac,21603649,19737
+S01CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,902722,Tobramycin,21603651,10627
+S01CA,CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION,992127,Loteprednol,21603651,237027
+S01CA01,DEXAMETHASONE AND ANTIINFECTIVES,902722,Tobramycin,21603652,10627
+S01CA01,DEXAMETHASONE AND ANTIINFECTIVES,915981,Neomycin,21603652,7299
+S01CA01,DEXAMETHASONE AND ANTIINFECTIVES,948582,Polymyxin B,21603652,8536
+S01CA01,DEXAMETHASONE AND ANTIINFECTIVES,1518254,Dexamethasone,21603652,3264
+S01CA02,PREDNISOLONE AND ANTIINFECTIVES,915981,Neomycin,21603653,7299
+S01CA02,PREDNISOLONE AND ANTIINFECTIVES,919345,Gentamicin Sulfate (USP),21603653,142438
+S01CA02,PREDNISOLONE AND ANTIINFECTIVES,948582,Polymyxin B,21603653,8536
+S01CA02,PREDNISOLONE AND ANTIINFECTIVES,1036252,Sulfacetamide,21603653,10169
+S01CA02,PREDNISOLONE AND ANTIINFECTIVES,1550557,prednisolone,21603653,8638
+S01CA03,HYDROCORTISONE AND ANTIINFECTIVES,915981,Neomycin,21603654,7299
+S01CA03,HYDROCORTISONE AND ANTIINFECTIVES,948582,Polymyxin B,21603654,8536
+S01CA03,HYDROCORTISONE AND ANTIINFECTIVES,975125,Hydrocortisone,21603654,5492
+S01CA07,FLUOROMETHOLONE AND ANTIINFECTIVES,955583,Fluorometholone,21603658,4491
+S01CA07,FLUOROMETHOLONE AND ANTIINFECTIVES,1036252,Sulfacetamide,21603658,10169
+S01EA01,EPINEPHRINE,1343916,Epinephrine,21603673,3992
+S01EA02,DIPIVEFRINE,990009,Dipivefrin,21603674,23410
+S01EA03,APRACLONIDINE,919986,apraclonidine,21603675,14845
+S01EA05,BRIMONIDINE,915542,brimonidine,21603677,134615
+S01EB01,PILOCARPINE,945286,Pilocarpine,21603680,8328
+S01EB02,CARBACHOL,940183,Carbachol,21603681,1999
+S01EB03,ECOTHIOPATE,958368,Echothiophate,21603682,89778
+S01EB04,DEMECARIUM,19004718,Demecarium,21603683,107771
+S01EB05,PHYSOSTIGMINE,19044337,Physostigmine,21603684,8299
+S01EB07,FLUOSTIGMINE,19082111,Isoflurophate,21603686,6027
+S01EB09,ACETYLCHOLINE,19037624,Acetylcholine,21603688,194
+S01EB51,"PILOCARPINE, COMBINATIONS",945286,Pilocarpine,21603690,8328
+S01EB51,"PILOCARPINE, COMBINATIONS",1343916,Epinephrine,21603690,3992
+S01EB51,"PILOCARPINE, COMBINATIONS",19044337,Physostigmine,21603690,8299
+S01EC01,ACETAZOLAMIDE,929435,Acetazolamide,21603693,167
+S01EC02,DICLOFENAMIDE,924296,Dichlorphenamide,21603694,3353
+S01EC03,DORZOLAMIDE,981709,dorzolamide,21603695,60207
+S01EC04,BRINZOLAMIDE,938044,brinzolamide,21603696,194881
+S01EC05,METHAZOLAMIDE,904250,Methazolamide,21603697,6826
+S01ED01,TIMOLOL,902427,Timolol,21603699,10600
+S01ED02,BETAXOLOL,1322081,Betaxolol,21603700,1520
+S01ED03,LEVOBUNOLOL,932815,Levobunolol,21603701,1813
+S01ED04,METIPRANOLOL,905531,Metipranolol,21603702,10824
+S01ED05,CARTEOLOL,950370,Carteolol,21603703,2116
+S01ED51,"TIMOLOL, COMBINATIONS",902427,Timolol,21603705,10600
+S01ED51,"TIMOLOL, COMBINATIONS",915542,brimonidine,21603705,134615
+S01ED51,"TIMOLOL, COMBINATIONS",981709,dorzolamide,21603705,60207
+S01EE01,LATANOPROST,954688,latanoprost,21603710,43611
+S01EE02,UNOPROSTONE,915829,isopropyl unoprostone,21603711,135313
+S01EE03,BIMATOPROST,904525,bimatoprost,21603712,283810
+S01EE04,TRAVOPROST,904501,travoprost,21603713,283809
+S01EX,OTHER ANTIGLAUCOMA PREPARATIONS,961145,Glycerin,21603715,4910
+S01EX,OTHER ANTIGLAUCOMA PREPARATIONS,1383815,Isosorbide,21603715,6057
+S01EX02,DAPIPRAZOLE,19086622,dapiprazole,21603717,22298
+L01CB01,ETOPOSIDE,1350504,Etoposide,21603718,4179
+L01CB02,TENIPOSIDE,19136750,Teniposide,21603719,10362
+L01CD01,PACLITAXEL,1378382,Paclitaxel,21603723,56946
+L01CD02,DOCETAXEL,1315942,docetaxel,21603724,72962
+L01DA01,DACTINOMYCIN,1311443,Dactinomycin,21603730,3100
+L01DB01,DOXORUBICIN,1338512,Doxorubicin,21603732,3639
+L01DB01,DOXORUBICIN,19051649,Liposomal Doxorubicin,21603732,214525
+L01DB02,DAUNORUBICIN,1311799,Daunorubicin,21603733,3109
+L01DB02,DAUNORUBICIN,19051599,Daunorubicin Liposomal,21603733,214468
+L01DB03,EPIRUBICIN,1344354,Epirubicin,21603734,3995
+L01DB06,IDARUBICIN,19078097,Idarubicin,21603737,5650
+L01DB07,MITOXANTRONE,1309188,Mitoxantrone,21603738,7005
+L01DB09,VALRUBICIN,19012543,valrubicin,21603740,31435
+L01DC01,BLEOMYCIN,1329241,Bleomycin,21603742,1622
+L01DC02,PLICAMYCIN,19009165,Plicamycin,21603743,6995
+L01DC03,MITOMYCIN,1389036,Mitomycin,21603744,632
+L01DC04,IXABEPILONE,19025348,ixabepilone,21603745,337523
+L01XA01,CISPLATIN,1397599,Cisplatin,21603748,2555
+L01XA02,CARBOPLATIN,1344905,Carboplatin,21603749,40048
+L01XA03,OXALIPLATIN,1318011,oxaliplatin,21603750,32592
+L01XB01,PROCARBAZINE,1351779,Procarbazine,21603753,8702
+L01XC02,RITUXIMAB,1314273,rituximab,21603756,121191
+L01XC03,TRASTUZUMAB,1387104,trastuzumab,21603757,224905
+L01XC04,ALEMTUZUMAB,1312706,alemtuzumab,21603758,117055
+L01XC05,GEMTUZUMAB,19098566,gemtuzumab,21603759,259315
+L01XC06,CETUXIMAB,1315411,cetuximab,21603760,318341
+L01XC07,BEVACIZUMAB,1397141,bevacizumab,21603761,253337
+L01XC08,PANITUMUMAB,19100985,panitumumab,21603762,263034
+L01XD,SENSITIZERS USED IN PHOTODYNAMIC/RADIATION THERAPY,905223,Methoxsalen,21603765,6854
+L01XD01,PORFIMER SODIUM,19089602,Dihematoporphyrin Ether,21603766,23066
+L01XD04,AMINOLEVULINIC ACID,924120,Aminolevulinate,21603768,155002
+L01XE01,IMATINIB,1304107,imatinib,21603772,282388
+L01XE02,GEFITINIB,1319193,gefitinib,21603773,328134
+L01XE03,ERLOTINIB,1325363,erlotinib,21603774,337525
+L01XE04,SUNITINIB,1336539,sunitinib,21603775,357977
+L01XE05,SORAFENIB,1363387,sorafenib,21603776,495881
+L01XE06,DASATINIB,1358436,dasatinib,21603777,475342
+L01XE07,LAPATINIB,1359548,lapatinib,21603778,480167
+L01XE08,NILOTINIB,1394023,nilotinib,21603779,662281
+L01XE09,TEMSIROLIMUS,19092845,temsirolimus,21603780,657797
+L01XE10,EVEROLIMUS,19011440,everolimus,21603781,141704
+L01XX,OTHER ANTINEOPLASTIC AGENTS,1436776,Testolactone,21603783,10378
+L01XX02,ASPARAGINASE,19012585,ASPARAGINASE,21603785,1156
+L01XX03,ALTRETAMINE,1368823,Altretamine,21603786,5296
+L01XX05,HYDROXYCARBAMIDE,1377141,hydroxyurea,21603787,5552
+L01XX08,PENTOSTATIN,19031224,Pentostatin,21603789,8011
+L01XX10,MASOPROCOL,988447,Masoprocol,21603791,227239
+L01XX11,ESTRAMUSTINE,1349025,Estramustine,21603792,4089
+L01XX14,TRETINOIN,903643,Tretinoin,21603793,10753
+L01XX17,TOPOTECAN,1378509,Topotecan,21603795,57308
+L01XX19,IRINOTECAN,1367268,irinotecan,21603797,51499
+L01XX23,MITOTANE,1309161,Mitotane,21603799,7004
+L01XX24,PEGASPARGASE,1326481,pegaspargase,21603800,34132
+L01XX25,BEXAROTENE,1389888,bexarotene,21603801,233272
+L01XX27,ARSENIC TRIOXIDE,1333379,arsenic trioxide,21603802,18330
+L01XX29,DENILEUKIN DIFTITOX,19051642,denileukin diftitox,21603803,214470
+L01XX32,BORTEZOMIB,1336825,bortezomib,21603804,358258
+L01XX35,ANAGRELIDE,1381253,anagrelide,21603806,596724
+L01XX38,VORINOSTAT,1337651,Vorinostat,21603809,194337
+L02AA01,DIETHYLSTILBESTROL,1525866,Diethylstilbestrol,21603815,3390
+L02AA04,FOSFESTROL,1525866,Diethylstilbestrol,21603818,3390
+L02AB01,MEGESTROL,1300978,Megestrol,21603820,6703
+L02AB02,MEDROXYPROGESTERONE,1500211,Medroxyprogesterone,21603821,6691
+L02AE02,LEUPRORELIN,1351541,Leuprolide,21603825,42375
+L02AE03,GOSERELIN,1366310,Goserelin,21603826,50610
+L02AE04,TRIPTORELIN,1343039,Triptorelin,21603827,38782
+L02BA01,TAMOXIFEN,1436678,Tamoxifen,21603831,10324
+L02BA02,TOREMIFENE,1342346,Toremifene,21603832,38409
+L02BA03,FULVESTRANT,1304044,fulvestrant,21603833,282357
+L02BB01,FLUTAMIDE,1356461,Flutamide,21603835,4508
+L02BB02,NILUTAMIDE,1315286,nilutamide,21603836,31805
+L02BB03,BICALUTAMIDE,1344381,bicalutamide,21603837,83008
+L02BG01,AMINOGLUTHETIMIDE,1503057,Aminoglutethimide,21603839,677
+L02BG03,ANASTROZOLE,1348265,anastrozole,21603841,84857
+L02BG04,LETROZOLE,1315946,letrozole,21603842,72965
+L02BG06,EXEMESTANE,1398399,exemestane,21603844,258494
+L02BX01,ABARELIX,19010868,abarelix,21603846,301739
+L02BX02,DEGARELIX,19058410,degarelix,21603847,475230
+L03AA02,FILGRASTIM,1304850,Filgrastim,21603851,68442
+L03AA09,SARGRAMOSTIM,1308432,sargramostim,21603853,69634
+L03AA13,PEGFILGRASTIM,1325608,pegfilgrastim,21603856,338036
+L03AB01,INTERFERON ALFA NATURAL,1385645,Interferon Alfa-n3,21603858,612937
+L03AB03,INTERFERON GAMMA,1380191,Interferon gamma-1b,21603860,5882
+L03AB04,INTERFERON ALFA-2A,1379969,Interferon Alfa-2a,21603861,5879
+L03AB05,INTERFERON ALFA-2B,1380068,Interferon Alfa-2b,21603862,5880
+L03AB05,INTERFERON ALFA-2B,1762711,Ribavirin,21603862,9344
+L03AB07,INTERFERON BETA-1A,722424,Interferon beta-1a,21603864,75917
+L03AB07,INTERFERON BETA-1A,1379969,Interferon Alfa-2a,21603864,5879
+L03AB08,INTERFERON BETA-1B,713196,interferon beta-1b,21603865,72257
+L03AB09,INTERFERON ALFACON-1,1781314,interferon alfacon-1,21603866,59744
+L03AB10,PEGINTERFERON ALFA-2B,1797155,peginterferon alfa-2b,21603867,253453
+L03AB11,PEGINTERFERON ALFA-2A,1714165,peginterferon alfa-2a,21603868,120608
+L03AC01,ALDESLEUKIN,1309770,Aldesleukin,21603872,70223
+L03AC02,OPRELVEKIN,1318030,Oprelvekin,21603873,139994
+L03AX03,BCG VACCINE,19023835,"BCG, Live, Connaught Strain",21603877,76469
+L03AX04,PEGADEMASE,581480,pegademase bovine,21603878,59768
+L03AX16,PLERIXAFOR,19017581,Plerixafor,21603889,733003
+L04AA02,MUROMONAB-CD3,19051865,Muromonab-CD3,21603893,42405
+L04AA03,ANTILYMPHOCYTE IMMUNOGLOBULIN (HORSE),19061406,Lymphocyte immune globulin,21603894,91601
+L04AA06,MYCOPHENOLIC ACID,19003999,mycophenolate mofetil,21603896,68149
+L04AA06,MYCOPHENOLIC ACID,19012565,Mycophenolic Acid,21603896,7145
+L04AA10,SIROLIMUS,19034726,Sirolimus,21603897,35302
+L04AA13,LEFLUNOMIDE,1101898,leflunomide,21603898,27169
+L04AA15,ALEFACEPT,909959,alefacept,21603899,299635
+L04AA23,NATALIZUMAB,735843,natalizumab,21603904,354770
+L04AA24,ABATACEPT,1186087,abatacept,21603905,614391
+L04AA25,ECULIZUMAB,19080458,eculizumab,21603906,591781
+L04AB01,ETANERCEPT,1151789,Etanercept,21603908,214555
+L04AB02,INFLIXIMAB,937368,infliximab,21603909,191831
+L04AB04,ADALIMUMAB,1119119,adalimumab,21603911,327361
+L04AB05,CERTOLIZUMAB PEGOL,912263,certolizumab pegol,21603912,709271
+L04AB06,GOLIMUMAB,19041065,golimumab,21603913,819300
+L04AC01,DACLIZUMAB,19036892,Daclizumab,21603915,190353
+L04AC02,BASILIXIMAB,19038440,basiliximab,21603916,196102
+L04AC03,ANAKINRA,1114375,anakinra,21603917,72435
+L04AD01,CICLOSPORIN,19010482,Cyclosporine,21603924,3008
+L04AD02,TACROLIMUS,950637,Tacrolimus,21603925,42316
+L04AX01,AZATHIOPRINE,19014878,Azathioprine,21603927,1256
+L04AX02,THALIDOMIDE,19137042,Thalidomide,21603928,10432
+L04AX03,METHOTREXATE,1305058,Methotrexate,21603929,6851
+L04AX04,LENALIDOMIDE,19026972,lenalidomide,21603930,342369
+M01AA01,PHENYLBUTAZONE,1135710,Phenylbutazone,21603935,8160
+M01AA03,OXYPHENBUTAZONE,19025925,Oxyphenbutazone,21603937,7816
+M01AB01,INDOMETACIN,1178663,Indomethacin,21603941,5781
+M01AB02,SULINDAC,1236607,Sulindac,21603942,10237
+M01AB03,TOLMETIN,1102917,Tolmetin,21603943,10636
+M01AB04,ZOMEPIRAC,19102108,zomepirac,21603944,39994
+M01AB08,ETODOLAC,1195492,Etodolac,21603948,24605
+M01AB15,KETOROLAC,1136980,Ketorolac,21603955,35827
+M01AC01,PIROXICAM,1146810,Piroxicam,21603961,8356
+M01AC06,MELOXICAM,1150345,meloxicam,21603965,41493
+M01AE01,IBUPROFEN,1177480,Ibuprofen,21603967,5640
+M01AE02,NAPROXEN,929887,lansoprazole,21603968,17128
+M01AE02,NAPROXEN,1115008,Naproxen,21603968,7258
+M01AE02,NAPROXEN,1154332,Pseudoephedrine,21603968,8896
+M01AE03,KETOPROFEN,1185922,Ketoprofen,21603969,6142
+M01AE04,FENOPROFEN,1153928,Fenoprofen,21603970,4331
+M01AE07,SUPROFEN,1036636,Suprofen,21603973,10255
+M01AE09,FLURBIPROFEN,1156378,Flurbiprofen,21603975,4502
+M01AE12,OXAPROZIN,1118045,oxaprozin,21603978,32613
+M01AE51,"IBUPROFEN, COMBINATIONS",1129625,Diphenhydramine,21603984,3498
+M01AE51,"IBUPROFEN, COMBINATIONS",1154332,Pseudoephedrine,21603984,8896
+M01AE51,"IBUPROFEN, COMBINATIONS",1174888,Hydrocodone,21603984,5489
+M01AE51,"IBUPROFEN, COMBINATIONS",1177480,Ibuprofen,21603984,5640
+M01AE51,"IBUPROFEN, COMBINATIONS",1192710,Chlorpheniramine,21603984,2400
+M01AG01,MEFENAMIC ACID,1197736,Mefenamate,21603987,257844
+M01AG04,MECLOFENAMIC ACID,1180182,Meclofenamate,21603990,588003
+M01AH01,CELECOXIB,1118084,celecoxib,21603992,140587
+M01AH02,ROFECOXIB,1189754,rofecoxib,21603993,232158
+M01AH03,VALDECOXIB,1103374,valdecoxib,21603994,278567
+M01AX,"OTHER ANTIINFLAM & ANTIRHEUMATIC AGNTS,NON-STEROID",1360332,Glucosamine,21603998,4845
+M01AX,"OTHER ANTIINFLAM & ANTIRHEUMATIC AGNTS,NON-STEROID",1363981,S-Adenosylmethionine,21603998,9504
+M01AX,"OTHER ANTIINFLAM & ANTIRHEUMATIC AGNTS,NON-STEROID",1389780,methylsulfonylmethane,21603998,23247
+M01AX,"OTHER ANTIINFLAM & ANTIRHEUMATIC AGNTS,NON-STEROID",1395573,Chondroitin Sulfates,21603998,2473
+M01AX,"OTHER ANTIINFLAM & ANTIRHEUMATIC AGNTS,NON-STEROID",19011773,Ascorbic Acid,21603998,1151
+M01AX,"OTHER ANTIINFLAM & ANTIRHEUMATIC AGNTS,NON-STEROID",19095164,Cholecalciferol,21603998,2418
+M01AX01,NABUMETONE,1113648,nabumetone,21603999,31448
+M01AX05,GLUCOSAMINE,1360332,Glucosamine,21604002,4845
+M01AX25,CHONDROITIN SULFATE,1395573,Chondroitin Sulfates,21604013,2473
+M01BX,OTHER ANTIINFLAM/ANTIRHEUM AGNTS COMB W/OTHER DRUG,929887,lansoprazole,21604020,17128
+M01BX,OTHER ANTIINFLAM/ANTIRHEUM AGNTS COMB W/OTHER DRUG,1115008,Naproxen,21604020,7258
+M01CB01,SODIUM AUROTHIOMALATE,1152134,Aurothiomalate,21604025,42547
+M01CB03,AURANOFIN,1114771,Auranofin,21604027,1227
+M01CB04,AUROTHIOGLUCOSE,1163570,Aurothioglucose,21604028,4980
+M01CC01,PENICILLAMINE,19028050,Penicillamine,21604031,7975
+M02AB01,CAPSAICIN,901656,Menthol,21604062,6750
+M02AB01,CAPSAICIN,938205,Camphor,21604062,1952
+M02AB01,CAPSAICIN,939881,Capsaicin,21604062,1992
+M02AB01,CAPSAICIN,1106647,Turpentine,21604062,10938
+M02AB01,CAPSAICIN,19055492,CAPSICUM OLEORESIN,21604062,235787
+M02AC,PREPARATIONS WITH SALICYLIC ACID DERIVATIVES,901656,Menthol,21604064,6750
+M02AC,PREPARATIONS WITH SALICYLIC ACID DERIVATIVES,909440,methyl salicylate,21604064,29787
+M02AC,PREPARATIONS WITH SALICYLIC ACID DERIVATIVES,917006,Benzocaine,21604064,1399
+M02AC,PREPARATIONS WITH SALICYLIC ACID DERIVATIVES,938205,Camphor,21604064,1952
+M02AC,PREPARATIONS WITH SALICYLIC ACID DERIVATIVES,939881,Capsaicin,21604064,1992
+M02AC,PREPARATIONS WITH SALICYLIC ACID DERIVATIVES,943116,trolamine salicylate,21604064,38866
+M02AX10,VARIOUS,901656,Menthol,21604068,6750
+M02AX10,VARIOUS,938205,Camphor,21604068,1952
+M03AA02,TUBOCURARINE,706644,Tubocurarine,21604073,10917
+M03AA04,DIMETHYLTUBOCURARINE,19009961,metocurine,21604074,29950
+M03AB01,SUXAMETHONIUM,836208,Succinylcholine,21604076,10154
+M03AC01,PANCURONIUM,19026674,Pancuronium,21604078,7883
+M03AC02,GALLAMINE,19057690,Gallamine,21604079,4638
+M03AC03,VECURONIUM,19012598,Vecuronium,21604080,71535
+M03AC04,ATRACURIUM,19014341,Atracurium,21604081,1218
+M03AC05,HEXAFLURONIUM,19001540,hexafluorenium,21604082,26826
+M03AC06,PIPECURONIUM BROMIDE,19025281,Pipecuronium,21604083,33742
+M03AC07,DOXACURIUM CHLORIDE,19091486,doxacurium,21604084,23651
+M03AC09,ROCURONIUM BROMIDE,19003953,Rocuronium,21604086,68139
+M03AC10,MIVACURIUM CHLORIDE,19010459,mivacurium,21604087,30077
+M03AC11,CISATRACURIUM,19015726,Cisatracurium,21604088,319864
+M03AX01,BOTULINUM TOXIN,729855,Botulinum Toxin Type A,21604090,1712
+M03AX01,BOTULINUM TOXIN,729959,botulinum toxin type B,21604090,1713
+M03BA02,CARISOPRODOL,749910,Carisoprodol,21604094,2101
+M03BA03,METHOCARBAMOL,704943,Methocarbamol,21604095,6845
+M03BA53,"METHOCARBAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",704943,Methocarbamol,21604100,6845
+M03BA53,"METHOCARBAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1112807,Aspirin,21604100,1191
+M03BB02,CHLORMEZANONE,19092290,Chlormezanone,21604105,2373
+M03BB03,CHLORZOXAZONE,795113,Chlorzoxazone,21604106,2410
+M03BC01,ORPHENADRINE (CITRATE),724394,Orphenadrine,21604112,7715
+M03BC51,"ORPHENADRINE, COMBINATIONS",724394,Orphenadrine,21604113,7715
+M03BC51,"ORPHENADRINE, COMBINATIONS",1112807,Aspirin,21604113,1191
+M03BC51,"ORPHENADRINE, COMBINATIONS",1125315,Acetaminophen,21604113,161
+M03BC51,"ORPHENADRINE, COMBINATIONS",1134439,Caffeine,21604113,1886
+M03BX,OTHER CENTRALLY ACTING AGENTS,780369,metaxalone,21604114,59078
+M03BX01,BACLOFEN,715233,Baclofen,21604115,1292
+M03BX02,TIZANIDINE,778474,tizanidine,21604116,57258
+M03BX08,CYCLOBENZAPRINE,778711,cyclobenzaprine,21604122,21949
+M04AA01,ALLOPURINOL,1167322,Allopurinol,21604131,519
+M04AA03,FEBUXOSTAT,19017742,febuxostat,21604133,73689
+M04AB01,PROBENECID,1151422,Probenecid,21604136,8698
+M04AB02,SULFINPYRAZONE,1236493,Sulfinpyrazone,21604137,10205
+M04AC01,COLCHICINE,1101554,Colchicine,21604141,2683
+M04AX,OTHER ANTIGOUT PREPARATIONS,1101554,Colchicine,21604143,2683
+M04AX,OTHER ANTIGOUT PREPARATIONS,1151422,Probenecid,21604143,8698
+M05BA01,ETIDRONIC ACID,1552929,Etidronate,21604149,42682
+M05BA03,PAMIDRONIC ACID,1511646,pamidronate,21604151,11473
+M05BA04,ALENDRONIC ACID,1557272,Alendronate,21604152,46041
+M05BA05,TILUDRONIC ACID,1578445,Tiludronate,21604153,57230
+M05BA06,IBANDRONIC ACID,1512480,Ibandronate,21604154,115264
+M05BA07,RISEDRONIC ACID,1516800,Risedronate,21604155,73056
+M05BA07,RISEDRONIC ACID,19035704,Calcium Carbonate,21604155,1897
+M05BA08,ZOLEDRONIC ACID,1524674,zoledronic acid,21604156,77655
+M05BB03,ALENDRONIC ACID AND COLECALCIFEROL,1557272,Alendronate,21604160,46041
+M05BB03,ALENDRONIC ACID AND COLECALCIFEROL,19095164,Cholecalciferol,21604160,2418
+M09AX,OTHER DRUGS FOR DISORDERS OF MUSCULO-SKELETAL SYS,705219,HYLAN G-F 20,21604178,284637
+M09AX,OTHER DRUGS FOR DISORDERS OF MUSCULO-SKELETAL SYS,766337,Guanidine,21604178,50675
+M09AX01,HYALURONIC ACID,787787,hyaluronate,21604179,62372
+M09AX01,HYALURONIC ACID,1395573,Chondroitin Sulfates,21604179,2473
+N01AF01,METHOHEXITAL,19005015,Methohexital,21604195,6847
+N01AF03,THIOPENTAL,700253,Thiopental,21604197,10493
+N01AH01,FENTANYL,1154029,Fentanyl,21604201,4337
+N01AH02,ALFENTANIL,19059528,Alfentanil,21604202,480
+N01AH03,SUFENTANIL,19078219,Sufentanil,21604203,56795
+N01AH06,REMIFENTANIL,19016749,remifentanil,21604206,73032
+N01AH51,"FENTANYL, COMBINATIONS",732893,Bupivacaine,21604207,1815
+N01AH51,"FENTANYL, COMBINATIONS",739323,Droperidol,21604207,3648
+N01AH51,"FENTANYL, COMBINATIONS",1136487,ropivacaine,21604207,35780
+N01AH51,"FENTANYL, COMBINATIONS",1154029,Fentanyl,21604207,4337
+N01AX01,DROPERIDOL,739323,Droperidol,21604209,3648
+N01AX03,KETAMINE,785649,Ketamine,21604210,6130
+N01AX07,ETOMIDATE,19050488,Etomidate,21604213,4177
+N01AX10,PROPOFOL,753626,Propofol,21604214,8782
+N01BA02,PROCAINE,751698,Procaine,21604223,8701
+N01BA03,TETRACAINE,1036884,Tetracaine,21604224,10391
+N01BA04,CHLOROPROCAINE,19049410,chloroprocaine,21604225,20859
+N01BB01,BUPIVACAINE,732893,Bupivacaine,21604229,1815
+N01BB02,LIDOCAINE,989878,Lidocaine,21604230,6387
+N01BB03,MEPIVACAINE,702774,Mepivacaine,21604231,6759
+N01BB04,PRILOCAINE,951279,Prilocaine,21604232,8686
+N01BB06,CINCHOCAINE,923840,Dibucaine,21604234,3339
+N01BB07,ETIDOCAINE,19050484,Etidocaine,21604235,4171
+N01BB09,ROPIVACAINE,1136487,ropivacaine,21604237,35780
+N01BB10,LEVOBUPIVACAINE,19098741,Levobupivacaine,21604238,259453
+N01BB20,COMBINATIONS,732893,Bupivacaine,21604239,1815
+N01BB20,COMBINATIONS,989878,Lidocaine,21604239,6387
+N01BB51,"BUPIVACAINE, COMBINATIONS",732893,Bupivacaine,21604240,1815
+N01BB51,"BUPIVACAINE, COMBINATIONS",1343916,Epinephrine,21604240,3992
+N01BB52,"LIDOCAINE, COMBINATIONS",916460,Benzalkonium,21604241,1378
+N01BB52,"LIDOCAINE, COMBINATIONS",939881,Capsaicin,21604241,1992
+N01BB52,"LIDOCAINE, COMBINATIONS",989878,Lidocaine,21604241,6387
+N01BB52,"LIDOCAINE, COMBINATIONS",1036884,Tetracaine,21604241,10391
+N01BB52,"LIDOCAINE, COMBINATIONS",1343916,Epinephrine,21604241,3992
+N01BB54,"PRILOCAINE, COMBINATIONS",951279,Prilocaine,21604243,8686
+N01BB54,"PRILOCAINE, COMBINATIONS",989878,Lidocaine,21604243,6387
+N01BB54,"PRILOCAINE, COMBINATIONS",1343916,Epinephrine,21604243,3992
+N01BB57,"ETIDOCAINE, COMBINATIONS",1343916,Epinephrine,21604244,3992
+N01BB57,"ETIDOCAINE, COMBINATIONS",19050484,Etidocaine,21604244,4171
+N01BB58,"ARTICAINE, COMBINATIONS",1343916,Epinephrine,21604245,3992
+N01BB58,"ARTICAINE, COMBINATIONS",19080512,Articaine,21604245,592464
+N01BC01,COCAINE,1001419,Cocaine,21604247,2653
+N01BX,OTHER LOCAL ANESTHETICS,942659,trichlorofluoromethane,21604248,38578
+N01BX,OTHER LOCAL ANESTHETICS,963747,dichlorodifluoromethane,21604248,50110
+N01BX01,ETHYL CHLORIDE,950316,Ethyl Chloride,21604249,4141
+N01BX02,DYCLONINE,992308,dyclonine,21604250,23744
+N02AA01,MORPHINE,1110410,Morphine,21604256,7052
+N02AA01,MORPHINE,19112635,Morphine Liposomal,21604256,477468
+N02AA02,OPIUM,923829,Opium,21604257,7676
+N02AA03,HYDROMORPHONE,1126658,Hydromorphone,21604258,3423
+N02AA05,OXYCODONE,1124957,Oxycodone,21604260,7804
+N02AA55,"OXYCODONE, COMBINATIONS",1112807,Aspirin,21604265,1191
+N02AA55,"OXYCODONE, COMBINATIONS",1124957,Oxycodone,21604265,7804
+N02AA55,"OXYCODONE, COMBINATIONS",1125315,Acetaminophen,21604265,161
+N02AA55,"OXYCODONE, COMBINATIONS",1177480,Ibuprofen,21604265,5640
+N02AA58,"DIHYDROCODEINE, COMBINATIONS",1125315,Acetaminophen,21604266,161
+N02AA58,"DIHYDROCODEINE, COMBINATIONS",1134439,Caffeine,21604266,1886
+N02AA58,"DIHYDROCODEINE, COMBINATIONS",1189596,dihydrocodeine,21604266,23088
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1112807,Aspirin,21604267,1191
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1125315,Acetaminophen,21604267,161
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1134439,Caffeine,21604267,1886
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1135766,Phenylephrine,21604267,8163
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1139699,butalbital,21604267,19860
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1154332,Pseudoephedrine,21604267,8896
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1163944,Guaifenesin,21604267,5032
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1192710,Chlorpheniramine,21604267,2400
+N02AA59,"CODEINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1201620,Codeine,21604267,2670
+N02AB02,PETHIDINE,1102527,Meperidine,21604271,6754
+N02AB03,FENTANYL,1154029,Fentanyl,21604272,4337
+N02AB52,"PETHIDINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1102527,Meperidine,21604273,6754
+N02AB52,"PETHIDINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1125315,Acetaminophen,21604273,161
+N02AB52,"PETHIDINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1153013,Promethazine,21604273,8745
+N02AC04,DEXTROPROPOXYPHENE,1153664,Propoxyphene,21604278,8785
+N02AC54,"DEXTROPROPOXYPHENE, COMB. EXCL. PSYCHOLEPTICS",1112807,Aspirin,21604281,1191
+N02AC54,"DEXTROPROPOXYPHENE, COMB. EXCL. PSYCHOLEPTICS",1125315,Acetaminophen,21604281,161
+N02AC54,"DEXTROPROPOXYPHENE, COMB. EXCL. PSYCHOLEPTICS",1134439,Caffeine,21604281,1886
+N02AC54,"DEXTROPROPOXYPHENE, COMB. EXCL. PSYCHOLEPTICS",1153664,Propoxyphene,21604281,8785
+N02AD,BENZOMORPHAN DERIVATIVES,1114220,Naloxone,21604283,7242
+N02AD,BENZOMORPHAN DERIVATIVES,1125315,Acetaminophen,21604283,161
+N02AD,BENZOMORPHAN DERIVATIVES,1130585,Pentazocine,21604283,8001
+N02AD01,PENTAZOCINE,1130585,Pentazocine,21604284,8001
+N02AE01,BUPRENORPHINE,1133201,Buprenorphine,21604287,1819
+N02AF01,BUTORPHANOL,1133732,Butorphanol,21604289,1841
+N02AF02,NALBUFINE,1114122,Nalbuphine,21604290,7238
+N02AX,OTHER OPIOIDS,1125765,Oxymorphone,21604296,7814
+N02AX,OTHER OPIOIDS,1189766,Levorphanol,21604296,6378
+N02AX02,TRAMADOL,1103314,Tramadol,21604298,10689
+N02AX03,DEZOCINE,19088393,dezocine,21604299,22713
+N02AX06,TAPENTADOL,19026459,tapentadol,21604301,787390
+N02AX52,"TRAMADOL, COMBINATIONS",1103314,Tramadol,21604302,10689
+N02AX52,"TRAMADOL, COMBINATIONS",1125315,Acetaminophen,21604302,161
+N02BA,SALICYLIC ACID AND DERIVATIVES,901656,Menthol,21604304,6750
+N02BA,SALICYLIC ACID AND DERIVATIVES,909440,methyl salicylate,21604304,29787
+N02BA,SALICYLIC ACID AND DERIVATIVES,964407,Salicylic Acid,21604304,9525
+N02BA,SALICYLIC ACID AND DERIVATIVES,1123904,phenyltoloxamine,21604304,33408
+N02BA,SALICYLIC ACID AND DERIVATIVES,1129625,Diphenhydramine,21604304,3498
+N02BA,SALICYLIC ACID AND DERIVATIVES,1168079,Magnesium Salicylate,21604304,52364
+N02BA,SALICYLIC ACID AND DERIVATIVES,1195334,Choline,21604304,2449
+N02BA,SALICYLIC ACID AND DERIVATIVES,19060877,Thiosalicylate,21604304,91099
+N02BA01,ACETYLSALICYLIC ACID,1112807,Aspirin,21604305,1191
+N02BA01,ACETYLSALICYLIC ACID,1551860,Pravastatin,21604305,42463
+N02BA03,CHOLINE SALICYLATE,1195334,Choline,21604307,2449
+N02BA04,SODIUM SALICYLATE,964407,Salicylic Acid,21604308,9525
+N02BA05,SALICYLAMIDE,1164108,salicylamide,21604309,9518
+N02BA06,SALSALATE,1137460,Salsalate,21604310,36108
+N02BA11,DIFLUNISAL,1126128,Diflunisal,21604315,3393
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",749910,Carisoprodol,21604320,2101
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1112807,Aspirin,21604320,1191
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1129625,Diphenhydramine,21604320,3498
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1134439,Caffeine,21604320,1886
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1135766,Phenylephrine,21604320,8163
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1139993,Phenylpropanolamine,21604320,8175
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1164108,salicylamide,21604320,9518
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1189596,dihydrocodeine,21604320,23088
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1192710,Chlorpheniramine,21604320,2400
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1201620,Codeine,21604320,2670
+N02BA51,"ACETYLSALICYLIC ACID, COMB. EXCL. PSYCHOLEPTICS",1551860,Pravastatin,21604320,42463
+N02BA71,"ACETYLSALICYLIC ACID, COMB WITH PSYCHOLEPTICS",702865,Meprobamate,21604325,6760
+N02BA71,"ACETYLSALICYLIC ACID, COMB WITH PSYCHOLEPTICS",1112807,Aspirin,21604325,1191
+N02BA71,"ACETYLSALICYLIC ACID, COMB WITH PSYCHOLEPTICS",1134439,Caffeine,21604325,1886
+N02BA71,"ACETYLSALICYLIC ACID, COMB WITH PSYCHOLEPTICS",1139699,butalbital,21604325,19860
+N02BA71,"ACETYLSALICYLIC ACID, COMB WITH PSYCHOLEPTICS",1201620,Codeine,21604325,2670
+N02BE01,PARACETAMOL,1125315,Acetaminophen,21604344,161
+N02BE01,PARACETAMOL,1129625,Diphenhydramine,21604344,3498
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",738818,Doxylamine,21604348,3642
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",749910,Carisoprodol,21604348,2101
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1112807,Aspirin,21604348,1191
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1119510,Dextromethorphan,21604348,3289
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1123904,phenyltoloxamine,21604348,33408
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1125315,Acetaminophen,21604348,161
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1129625,Diphenhydramine,21604348,3498
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1130863,Brompheniramine,21604348,1767
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1134439,Caffeine,21604348,1886
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1135766,Phenylephrine,21604348,8163
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1139993,Phenylpropanolamine,21604348,8175
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1154332,Pseudoephedrine,21604348,8896
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1159811,Pyrilamine,21604348,9009
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1163944,Guaifenesin,21604348,5032
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1164108,salicylamide,21604348,9518
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1168079,Magnesium Salicylate,21604348,52364
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1172206,pamabrom,21604348,54365
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1174888,Hydrocodone,21604348,5489
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1188052,dexbrompheniramine,21604348,22696
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1188114,dexchlorpheniramine,21604348,22697
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1189596,dihydrocodeine,21604348,23088
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1192710,Chlorpheniramine,21604348,2400
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1201620,Codeine,21604348,2670
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",1301152,Melatonin,21604348,6711
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",19009540,Vitamin E,21604348,11256
+N02BE51,"PARACETAMOL, COMBINATIONS EXCL. PSYCHOLEPTICS",19035704,Calcium Carbonate,21604348,1897
+N02BE71,"PARACETAMOL, COMBINATIONS WITH PSYCHOLEPTICS",1125315,Acetaminophen,21604351,161
+N02BE71,"PARACETAMOL, COMBINATIONS WITH PSYCHOLEPTICS",1134439,Caffeine,21604351,1886
+N02BE71,"PARACETAMOL, COMBINATIONS WITH PSYCHOLEPTICS",1139699,butalbital,21604351,19860
+N02BG08,ZICONOTIDE,19005061,ziconotide,21604361,68503
+N02C,ANTIMIGRAINE PREPARATIONS,1115008,Naproxen,21604364,7258
+N02C,ANTIMIGRAINE PREPARATIONS,1140643,Sumatriptan,21604364,37418
+N02CA01,DIHYDROERGOTAMINE,1126557,Dihydroergotamine,21604366,3418
+N02CA02,ERGOTAMINE,1145379,Ergotamine,21604367,4025
+N02CA04,METHYSERGIDE,1106740,Methysergide,21604368,6911
+N02CA52,"ERGOTAMINE, COMBINATIONS EXCL. PSYCHOLEPTICS",734275,Phenobarbital,21604371,8134
+N02CA52,"ERGOTAMINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1116109,Belladonna Alkaloids,21604371,1359
+N02CA52,"ERGOTAMINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1134439,Caffeine,21604371,1886
+N02CA52,"ERGOTAMINE, COMBINATIONS EXCL. PSYCHOLEPTICS",1145379,Ergotamine,21604371,4025
+N02CC01,SUMATRIPTAN,1140643,Sumatriptan,21604376,37418
+N02CC02,NARATRIPTAN,1118117,naratriptan,21604377,141366
+N02CC03,ZOLMITRIPTAN,1116031,zolmitriptan,21604378,135775
+N02CC04,RIZATRIPTAN,1154077,rizatriptan,21604379,88014
+N02CC05,ALMOTRIPTAN,1103552,almotriptan,21604380,279645
+N02CC06,ELETRIPTAN,1189697,eletriptan,21604381,231049
+N02CC07,FROVATRIPTAN,1189458,frovatriptan,21604382,228783
+N02CX,OTHER ANTIMIGRAINE PREPARATIONS,1103518,isometheptene,21604383,27946
+N02CX,OTHER ANTIMIGRAINE PREPARATIONS,1125315,Acetaminophen,21604383,161
+N02CX,OTHER ANTIMIGRAINE PREPARATIONS,1134439,Caffeine,21604383,1886
+N02CX,OTHER ANTIMIGRAINE PREPARATIONS,1189490,dichloralphenazone,21604383,22892
+N02CX02,CLONIDINE,1398937,Clonidine,21604385,2599
+N03AA01,METHYLPHENOBARBITAL,702685,Mephobarbital,21604392,6758
+N03AA02,PHENOBARBITAL,734275,Phenobarbital,21604393,8134
+N03AA03,PRIMIDONE,751347,Primidone,21604394,8691
+N03AA30,METHARBITAL,19004254,metharbital,21604396,6825
+N03AB01,ETHOTOIN,750146,Ethotoin,21604398,4136
+N03AB04,MEPHENYTOIN,702661,Mephenytoin,21604401,6757
+N03AC01,PARAMETHADIONE,19021932,paramethadione,21604406,32894
+N03AC02,TRIMETHADIONE,19005629,Trimethadione,21604407,10827
+N03AD01,ETHOSUXIMIDE,750119,Ethosuximide,21604410,4135
+N03AD02,PHENSUXIMIDE,19023842,phensuximide,21604411,33309
+N03AD03,MESUXIMIDE,759401,methsuximide,21604412,47858
+N03AE01,CLONAZEPAM,798874,Clonazepam,21604415,2598
+N03AF01,CARBAMAZEPINE,740275,Carbamazepine,21604417,2002
+N03AF02,OXCARBAZEPINE,718122,oxcarbazepine,21604418,32624
+N03AF03,RUFINAMIDE,19006586,rufinamide,21604419,69036
+N03AG01,VALPROIC ACID,745466,Valproate,21604422,40254
+N03AG06,TIAGABINE,715458,tiagabine,21604427,31914
+N03AX07,PHENACEMIDE,19023286,phenacemide,21604430,33253
+N03AX09,LAMOTRIGINE,705103,lamotrigine,21604431,28439
+N03AX10,FELBAMATE,795661,felbamate,21604432,24812
+N03AX11,TOPIRAMATE,742267,topiramate,21604433,38404
+N03AX12,GABAPENTIN,797399,gabapentin,21604434,25480
+N03AX14,LEVETIRACETAM,711584,Levetiracetam,21604436,114477
+N03AX15,ZONISAMIDE,744798,zonisamide,21604437,39998
+N03AX16,PREGABALIN,734354,pregabalin,21604438,187832
+N03AX18,LACOSAMIDE,19087394,lacosamide,21604440,623400
+N04AA01,TRIHEXYPHENIDYL,705178,Trihexyphenidyl,21604446,10811
+N04AA04,PROCYCLIDINE,752276,Procyclidine,21604449,8718
+N04AA05,PROFENAMINE,19050123,ethopropazine,21604450,4134
+N04AB02,ORPHENADRINE (CHLORIDE),724394,Orphenadrine,21604458,7715
+N04AC01,BENZATROPINE,719174,Benztropine,21604460,1424
+N04BA01,LEVODOPA,789578,Levodopa,21604464,6375
+N04BA02,LEVODOPA AND DECARBOXYLASE INHIBITOR,740560,Carbidopa,21604465,2019
+N04BA02,LEVODOPA AND DECARBOXYLASE INHIBITOR,789578,Levodopa,21604465,6375
+N04BB01,AMANTADINE,19087090,Amantadine,21604471,620
+N04BC01,BROMOCRIPTINE,730548,Bromocriptine,21604473,1760
+N04BC02,PERGOLIDE,732309,Pergolide,21604474,8047
+N04BC04,ROPINIROLE,713823,ropinirole,21604476,72302
+N04BC05,PRAMIPEXOLE,720810,Pramipexole,21604477,746741
+N04BC07,APOMORPHINE,837027,Apomorphine,21604479,1043
+N04BC09,ROTIGOTINE,786426,Rotigotine,21604481,616739
+N04BD01,SELEGILINE,766209,Selegiline,21604483,9639
+N04BD02,RASAGILINE,715710,rasagiline,21604484,134748
+N04BX,OTHER DOPAMINERGIC AGENTS,740560,Carbidopa,21604485,2019
+N04BX,OTHER DOPAMINERGIC AGENTS,782211,entacapone,21604485,60307
+N04BX,OTHER DOPAMINERGIC AGENTS,789578,Levodopa,21604485,6375
+N04BX01,TOLCAPONE,715727,tolcapone,21604486,72937
+N04BX02,ENTACAPONE,782211,entacapone,21604487,60307
+N05AA01,CHLORPROMAZINE,794852,Chlorpromazine,21604492,2403
+N05AA02,LEVOMEPROMAZINE,19005147,Methotrimeprazine,21604493,6852
+N05AA03,PROMAZINE,19052903,Promazine,21604494,8742
+N05AA05,TRIFLUPROMAZINE,19005104,Triflupromazine,21604496,10805
+N05AB02,FLUPHENAZINE,756018,Fluphenazine,21604501,4496
+N05AB03,PERPHENAZINE,733008,Perphenazine,21604502,8076
+N05AB04,PROCHLORPERAZINE,752061,Prochlorperazine,21604503,8704
+N05AB06,TRIFLUOPERAZINE,704984,Trifluoperazine,21604505,10800
+N05AB07,ACETOPHENAZINE,19029555,acetophenazine,21604506,16735
+N05AC02,THIORIDAZINE,700299,Thioridazine,21604512,10502
+N05AC03,MESORIDAZINE,703083,Mesoridazine,21604513,6779
+N05AD01,HALOPERIDOL,766529,Haloperidol,21604516,5093
+N05AE02,MOLINDONE,709699,Molindone,21604527,7019
+N05AE04,ZIPRASIDONE,712615,ziprasidone,21604529,115698
+N05AF03,CHLORPROTHIXENE,19095002,Chlorprothixene,21604533,2406
+N05AF04,TIOTIXENE,700465,Thiothixene,21604534,10510
+N05AG02,PIMOZIDE,745790,Pimozide,21604538,8331
+N05AH01,LOXAPINE,792263,Loxapine,21604541,6475
+N05AH02,CLOZAPINE,800878,Clozapine,21604542,2626
+N05AH03,OLANZAPINE,785788,olanzapine,21604543,61381
+N05AH04,QUETIAPINE,766814,quetiapine,21604544,51272
+N05AN01,LITHIUM,751246,Lithium Carbonate,21604556,42351
+N05AN01,LITHIUM,767410,lithium citrate,21604556,52105
+N05AX08,RISPERIDONE,735979,Risperidone,21604559,35636
+N05AX12,ARIPIPRAZOLE,757688,aripiprazole,21604562,89013
+N05AX13,PALIPERIDONE,703244,paliperidone,21604563,679314
+N05BA01,DIAZEPAM,723013,Diazepam,21604566,3322
+N05BA02,CHLORDIAZEPOXIDE,990678,Chlordiazepoxide,21604567,2356
+N05BA04,OXAZEPAM,724816,Oxazepam,21604569,7781
+N05BA05,POTASSIUM CLORAZEPATE,790253,Chlorazepate,21604570,2353
+N05BA06,LORAZEPAM,791967,Lorazepam,21604571,6470
+N05BA11,PRAZEPAM,19050461,Prazepam,21604576,8627
+N05BA12,ALPRAZOLAM,781039,Alprazolam,21604577,596
+N05BA13,HALAZEPAM,801396,halazepam,21604578,26412
+N05BB01,HYDROXYZINE,777221,Hydroxyzine,21604590,5553
+N05BC01,MEPROBAMATE,702865,Meprobamate,21604594,6760
+N05BE01,BUSPIRONE,733301,Buspirone,21604601,1827
+N05CA01,PENTOBARBITAL,730729,Pentobarbital,21604608,8004
+N05CA02,AMOBARBITAL,712757,Amobarbital,21604609,719
+N05CA03,BUTOBARBITAL,959174,butabarbital,21604610,477631
+N05CA05,APROBARBITAL,19030299,aprobarbital,21604612,17381
+N05CA06,SECOBARBITAL,766067,Secobarbital,21604613,9624
+N05CA07,TALBUTAL,19059149,talbutal,21604614,89810
+N05CA16,HEXOBARBITAL,19068964,Hexobarbital,21604621,5302
+N05CB01,COMBINATIONS OF BARBITURATES,712757,Amobarbital,21604627,719
+N05CB01,COMBINATIONS OF BARBITURATES,766067,Secobarbital,21604627,9624
+N05CC01,CHLORAL HYDRATE,742594,trichloroacetaldehyde,21604630,38574
+N05CD01,FLURAZEPAM,756349,Flurazepam,21604636,4501
+N05CD04,ESTAZOLAM,748010,Estazolam,21604639,4077
+N05CD05,TRIAZOLAM,704599,Triazolam,21604640,10767
+N05CD07,TEMAZEPAM,836715,Temazepam,21604642,10355
+N05CD08,MIDAZOLAM,708298,Midazolam,21604643,6960
+N05CD10,QUAZEPAM,731188,quazepam,21604645,35185
+N05CE01,GLUTETHIMIDE,19061124,Glutethimide,21604650,4903
+N05CE02,METHYPRYLON,19006742,Methyprylon,21604651,6910
+N05CF03,ZALEPLON,720727,zaleplon,21604656,74667
+N05CF04,ESZOPICLONE,757352,Eszopiclone,21604657,461016
+N05CH01,MELATONIN,1301152,Melatonin,21604659,6711
+N05CH01,MELATONIN,1353228,Vitamin B6,21604659,42954
+N05CH01,MELATONIN,19037401,calcium phosphate,21604659,1919
+N05CH01,MELATONIN,19100575,theanine,21604659,38022
+N05CH02,RAMELTEON,781182,ramelteon,21604660,596205
+N05CM,OTHER HYPNOTICS AND SEDATIVES,19052620,CHAMOMILE FLOWERS,21604661,221916
+N05CM01,METHAQUALONE,19004160,Methaqualone,21604662,6823
+N05CM04,CARBROMAL,19033243,carbromal,21604665,2067
+N05CM05,SCOPOLAMINE,965748,Scopolamine,21604666,9601
+N05CM08,ETHCHLORVYNOL,749727,Ethchlorvynol,21604669,4118
+N05CM09,VALERIAN,1307353,Valerian extract,21604670,285250
+N05CM09,VALERIAN,1397059,VALERIAN ROOT,21604670,253206
+N05CM09,VALERIAN,1398499,Hops extract,21604670,259266
+N05CM18,DEXMEDETOMIDINE,19061088,Dexmedetomidine,21604677,48937
+N06A,ANTIDEPRESSANTS,766209,Selegiline,21604686,9639
+N06AA01,DESIPRAMINE,716968,Desipramine,21604688,3247
+N06AA02,IMIPRAMINE,778268,Imipramine,21604689,5691
+N06AA06,TRIMIPRAMINE,705755,Trimipramine,21604693,10834
+N06AA10,NORTRIPTYLINE,721724,Nortriptyline,21604697,7531
+N06AA11,PROTRIPTYLINE,754270,Protriptyline,21604698,8886
+N06AA12,DOXEPIN,738156,Doxepin,21604699,3638
+N06AA17,AMOXAPINE,713109,Amoxapine,21604704,722
+N06AA21,MAPROTILINE,794147,Maprotiline,21604707,6646
+N06AB03,FLUOXETINE,755695,Fluoxetine,21604711,4493
+N06AB04,CITALOPRAM,797617,Citalopram,21604712,2556
+N06AB05,PAROXETINE,722031,Paroxetine,21604713,32937
+N06AB06,SERTRALINE,739138,Sertraline,21604714,36437
+N06AB08,FLUVOXAMINE,751412,Fluvoxamine,21604716,42355
+N06AB10,ESCITALOPRAM,715939,Escitalopram,21604718,321988
+N06AF01,ISOCARBOXAZID,781705,Isocarboxazid,21604720,6011
+N06AF03,PHENELZINE,733896,Phenelzine,21604722,8123
+N06AF04,TRANYLCYPROMINE,703470,Tranylcypromine,21604723,10734
+N06AX,OTHER ANTIDEPRESSANTS,1363516,5-Hydroxytryptophan,21604729,94
+N06AX02,TRYPTOPHAN,19006186,Tryptophan,21604731,10898
+N06AX06,NEFAZODONE,714684,nefazodone,21604735,31565
+N06AX11,MIRTAZAPINE,725131,Mirtazapine,21604740,15996
+N06AX12,BUPROPION,750982,Bupropion,21604741,42347
+N06AX16,VENLAFAXINE,743670,venlafaxine,21604745,39786
+N06AX17,MILNACIPRAN,19080226,milnacipran,21604746,588250
+N06AX21,DULOXETINE,715259,duloxetine,21604749,72625
+N06AX23,DESVENLAFAXINE,717607,Desvenlafaxine,21604751,734064
+N06BA,CENTRALLY ACTING SYMPATHOMIMETICS,19090984,armodafinil,21604753,641465
+N06BA01,AMFETAMINE,714785,Amphetamine,21604754,725
+N06BA01,AMFETAMINE,719311,Dextroamphetamine,21604754,3288
+N06BA02,DEXAMFETAMINE,719311,Dextroamphetamine,21604755,3288
+N06BA03,METAMFETAMINE,704053,Methamphetamine,21604756,6816
+N06BA04,METHYLPHENIDATE,705944,Methylphenidate,21604757,6901
+N06BA05,PEMOLINE,727835,Pemoline,21604758,7966
+N06BA07,MODAFINIL,710650,modafinil,21604760,30125
+N06BA09,ATOMOXETINE,742185,atomoxetine,21604762,38400
+N06BA11,DEXMETHYLPHENIDATE,731533,dexmethylphenidate,21604764,352372
+N06BC01,CAFFEINE,1134439,Caffeine,21604766,1886
+N06BC01,CAFFEINE,1560524,Glucose,21604766,4850
+N06BX,OTHER PSYCHOSTIMULANTS AND NOOTROPICS,769935,Sodium Oxybate,21604768,9899
+N06BX04,DEANOL,1311826,Deanol,21604772,3116
+N06BX12,ACETYLCARNITINE,19037596,Acetylcarnitine,21604780,193
+N06CA,ANTIDEPRESSANTS IN COMBINATION WITH PSYCHOLEPTICS,755695,Fluoxetine,21604788,4493
+N06CA,ANTIDEPRESSANTS IN COMBINATION WITH PSYCHOLEPTICS,785788,olanzapine,21604788,61381
+N06DA01,TACRINE,836654,Tacrine,21604794,10318
+N06DA02,DONEPEZIL,715997,donepezil,21604795,135447
+N06DA03,RIVASTIGMINE,733523,rivastigmine,21604796,183379
+N06DA04,GALANTAMINE,757627,Galantamine,21604797,4637
+N06DX,OTHER ANTI-DEMENTIA DRUGS,1391889,Ginkgo biloba extract,21604798,236809
+N06DX,OTHER ANTI-DEMENTIA DRUGS,19008269,Vincamine,21604798,11201
+N06DX,OTHER ANTI-DEMENTIA DRUGS,19098505,GINKGO BILOBA LEAF,21604798,259265
+N06DX,OTHER ANTI-DEMENTIA DRUGS,19098769,Korean Ginseng Root Extract,21604798,259471
+N06DX01,MEMANTINE,701322,Memantine,21604799,6719
+N06DX02,GINKGO BILOBA,1391889,Ginkgo biloba extract,21604800,236809
+N06DX02,GINKGO BILOBA,1398560,GINKGO BILOBA LEAF EXTRACT,21604800,259316
+N07AA,ANTICHOLINESTERASES,740924,Edrophonium,21604803,3752
+N07AA01,NEOSTIGMINE,717136,Neostigmine,21604804,7315
+N07AA02,PYRIDOSTIGMINE,759740,Pyridostigmine,21604805,9000
+N07AA30,AMBENONIUM,787362,Ambenonium,21604807,623
+N07AX01,PILOCARPINE,945286,Pilocarpine,21604813,8328
+N07AX03,CEVIMELINE,954819,cevimeline,21604815,44281
+N07BA,DRUGS USED IN NICOTINE DEPENDENCE,19016725,silver acetate,21604817,137939
+N07BA01,NICOTINE,718583,Nicotine,21604818,7407
+N07BA03,VARENICLINE,780442,varenicline,21604819,591622
+N07BB,DRUGS USED IN ALCOHOL DEPENDENCE,19014158,nalmefene,21604820,31479
+N07BB01,DISULFIRAM,735850,Disulfiram,21604821,3554
+N07BB03,ACAMPROSATE,19043959,acamprosate,21604823,82819
+N07BB04,NALTREXONE,1714319,Naltrexone,21604824,7243
+N07BC01,BUPRENORPHINE,1133201,Buprenorphine,21604826,1819
+N07BC02,METHADONE,1103640,Methadone,21604827,6813
+N07BC03,LEVACETYLMETHADOL,19003959,Methadyl Acetate,21604828,6814
+N07BC51,"BUPRENORPHINE, COMBINATIONS",1114220,Naloxone,21604830,7242
+N07BC51,"BUPRENORPHINE, COMBINATIONS",1133201,Buprenorphine,21604830,1819
+N07XX02,RILUZOLE,735951,Riluzole,21604842,35623
+N07XX06,TETRABENAZINE,836877,Tetrabenazine,21604846,10390
+P01AA,HYDROXYQUINOLINE DERIVATIVES,928006,Iodoquinol,21604850,3435
+P01AB01,METRONIDAZOLE,937791,bismuth subsalicylate,21604857,19478
+P01AB01,METRONIDAZOLE,1707164,Metronidazole,21604857,6922
+P01AB01,METRONIDAZOLE,1836948,Tetracycline,21604857,10395
+P01AB02,TINIDAZOLE,1702559,Tinidazole,21604858,10612
+P01AX02,EMETINE,19041857,Emetine,21604876,3820
+P01AX05,MEPACRINE,19060400,Quinacrine,21604878,9061
+P01AX06,ATOVAQUONE,1781733,Atovaquone,21604879,60212
+P01AX07,TRIMETREXATE,1750928,Trimetrexate,21604880,42333
+P01AX11,NITAZOXAMIDE,1715315,nitazoxanide,21604884,31819
+P01BA01,CHLOROQUINE,1792515,Chloroquine,21604888,2393
+P01BA02,HYDROXYCHLOROQUINE,1777087,Hydroxychloroquine,21604889,5521
+P01BA03,PRIMAQUINE,1751310,Primaquine,21604890,8687
+P01BB51,"PROGUANIL, COMBINATIONS",1781733,Atovaquone,21604895,60212
+P01BB51,"PROGUANIL, COMBINATIONS",1792429,Chloroguanide,21604895,2382
+P01BC01,QUININE,1760616,Quinine,21604897,9071
+P01BC02,MEFLOQUINE,19000498,Mefloquine,21604898,6694
+P01BD01,PYRIMETHAMINE,1760039,Pyrimethamine,21604900,9010
+P01BD51,"PYRIMETHAMINE, COMBINATIONS",1760039,Pyrimethamine,21604901,9010
+P01BD51,"PYRIMETHAMINE, COMBINATIONS",1836410,Sulfadoxine,21604901,10173
+P01BE52,"ARTEMETHER, COMBINATIONS",19033634,artemether,0,18343
+P01BE52,"ARTEMETHER, COMBINATIONS",19048037,lumefantrine,0,847728
+P01BX01,HALOFANTRINE,1766340,halofantrine,21604910,50749
+P01CX01,PENTAMIDINE ISETHIONATE,1730370,Pentamidine,21604924,7994
+P02BA01,PRAZIQUANTEL,1750461,Praziquantel,21604930,8628
+P02BA02,OXAMNIQUINE,19024775,Oxamniquine,21604931,7778
+P02CA01,MEBENDAZOLE,1794280,Mebendazole,21604941,6672
+P02CA02,TIABENDAZOLE,1837289,Thiabendazole,21604942,10450
+P02CA03,ALBENDAZOLE,1753745,Albendazole,21604943,430
+P02CB01,PIPERAZINE,19046291,piperazine,21604949,8340
+P02CB02,DIETHYLCARBAMAZINE,19025698,Diethylcarbamazine,21604950,3384
+P02CC01,PYRANTEL,1759270,Pyrantel,21604952,8984
+P02CE01,LEVAMISOLE,1389464,Levamisole,21604955,6371
+P02CF01,IVERMECTIN,1784444,Ivermectin,21604957,6069
+P02DA01,NICLOSAMIDE,19018416,Niclosamide,21604963,7402
+P03AA,SULFUR CONTAINING PRODUCTS,917006,Benzocaine,21604969,1399
+P03AA,SULFUR CONTAINING PRODUCTS,1036525,Sulfur,21604969,10223
+P03AB02,LINDANE,916751,Lindane,21604978,1388
+P03AB02,LINDANE,989878,Lidocaine,21604978,6387
+P03AC01,PYRETHRUM,959665,Pyrethrins,21604981,8991
+P03AC03,PHENOTHRIN,19023819,phenothrin,21604983,33303
+P03AC04,PERMETHRIN,922868,Permethrin,21604984,33199
+P03AC51,"PYRETHRUM, COMBINATIONS",916460,Benzalkonium,21604985,1378
+P03AC51,"PYRETHRUM, COMBINATIONS",946340,Piperonyl Butoxide,21604985,8345
+P03AC51,"PYRETHRUM, COMBINATIONS",959665,Pyrethrins,21604985,8991
+P03AX,"OTHER ECTOPARASITICIDES, INCL. SCABICIDES",969276,crotamiton,21604989,21766
+P03AX03,MALATHION,993979,Malathion,21604992,6606
+P03BX01,DIETHYLTOLUAMIDE,19079469,Deet,21605001,3129
+R01AA03,EPHEDRINE,1143374,Ephedrine,21605012,3966
+R01AA03,EPHEDRINE,1343916,Epinephrine,21605012,3992
+R01AA04,PHENYLEPHRINE,1135766,Phenylephrine,21605013,8163
+R01AA05,OXYMETAZOLINE,925636,Oxymetazoline,21605014,7812
+R01AA06,TETRYZOLINE,941577,tetrahydrozoline,21605015,37935
+R01AA07,XYLOMETAZOLINE,943852,xylometazoline,21605016,39841
+R01AA08,NAPHAZOLINE,914533,Naphazoline,21605017,7247
+R01AA14,EPINEPHRINE,1343916,Epinephrine,21605023,3992
+R01AB01,PHENYLEPHRINE,933952,Pheniramine,21605025,8132
+R01AB01,PHENYLEPHRINE,1135766,Phenylephrine,21605025,8163
+R01AB07,OXYMETAZOLINE,925636,Oxymetazoline,21605030,7812
+R01AC01,CROMOGLICIC ACID,1152631,Cromolyn,21605033,42612
+R01AC03,AZELASTINE,934075,azelastine,21605035,18603
+R01AC08,OLOPATADINE,915855,olopatadine,21605040,135391
+R01AD01,BECLOMETASONE,1115572,Beclomethasone,21605043,1347
+R01AD04,FLUNISOLIDE,1196514,flunisolide,21605046,25120
+R01AD05,BUDESONIDE,939259,Budesonide,21605047,19831
+R01AD08,FLUTICASONE,1149380,fluticasone,21605050,41126
+R01AD09,MOMETASONE,905233,Mometasone,21605051,108118
+R01AD11,TRIAMCINOLONE,903963,Triamcinolone,21605052,10759
+R01AD12,FLUTICASONE FUROATE,1149380,fluticasone,21605053,41126
+S01FA01,ATROPINE,914335,Atropine,21605060,1223
+S01FA02,SCOPOLAMINE,965748,Scopolamine,21605061,9601
+S01FA02,SCOPOLAMINE,1135766,Phenylephrine,21605061,8163
+S01FA04,CYCLOPENTOLATE,910232,Cyclopentolate,21605063,3001
+S01FA04,CYCLOPENTOLATE,1135766,Phenylephrine,21605063,8163
+S01FA05,HOMATROPINE,1101703,homatropine,21605064,27084
+S01FA06,TROPICAMIDE,906072,Tropicamide,21605065,10869
+S01FA56,"TROPICAMIDE, COMBINATIONS",906072,Tropicamide,21605066,10869
+S01FA56,"TROPICAMIDE, COMBINATIONS",19026274,p-Hydroxyamphetamine,21605066,7839
+S01FB,SYMPATHOMIMETICS EXCL. ANTIGLAUCOMA PREPARATIONS,19026274,p-Hydroxyamphetamine,21605067,7839
+S01FB01,PHENYLEPHRINE,1135766,Phenylephrine,21605068,8163
+S01GA01,NAPHAZOLINE,914533,Naphazoline,21605073,7247
+S01GA02,TETRYZOLINE,941577,tetrahydrozoline,21605074,37935
+S01GA04,OXYMETAZOLINE,925636,Oxymetazoline,21605076,7812
+S01GA05,PHENYLEPHRINE,1135766,Phenylephrine,21605077,8163
+S01GA51,"NAPHAZOLINE, COMBINATIONS",902251,hypromellose,21605079,27334
+S01GA51,"NAPHAZOLINE, COMBINATIONS",914533,Naphazoline,21605079,7247
+S01GA51,"NAPHAZOLINE, COMBINATIONS",933952,Pheniramine,21605079,8132
+S01GA51,"NAPHAZOLINE, COMBINATIONS",948487,Polyethylene Glycol 300,21605079,8513
+S01GA51,"NAPHAZOLINE, COMBINATIONS",951237,Antazoline,21605079,865
+S01GA51,"NAPHAZOLINE, COMBINATIONS",961145,Glycerin,21605079,4910
+S01GA51,"NAPHAZOLINE, COMBINATIONS",19044522,Zinc Sulfate,21605079,39954
+S01GA52,"TETRYZOLINE, COMBINATIONS",941577,tetrahydrozoline,21605080,37935
+S01GA52,"TETRYZOLINE, COMBINATIONS",948515,Polyethylene Glycols,21605080,8516
+S01GA52,"TETRYZOLINE, COMBINATIONS",19044522,Zinc Sulfate,21605080,39954
+S01GA55,"PHENYLEPHRINE, COMBINATIONS",1036059,Antipyrine,21605082,1001
+S01GA55,"PHENYLEPHRINE, COMBINATIONS",1135766,Phenylephrine,21605082,8163
+S01GX01,CROMOGLICIC ACID,1152631,Cromolyn,21605085,42612
+S01GX02,LEVOCABASTINE,907553,levocabastine,21605086,28627
+S01GX04,NEDOCROMIL,1114620,Nedocromil,21605088,31563
+S01GX05,LODOXAMIDE,967496,Lodoxamide,21605089,52151
+S01GX06,EMEDASTINE,903893,emedastine,21605090,28144
+S01GX07,AZELASTINE,934075,azelastine,21605091,18603
+S01GX08,KETOTIFEN,986117,Ketotifen,21605092,6146
+S01GX09,OLOPATADINE,915855,olopatadine,21605093,135391
+S01GX10,EPINASTINE,943634,epinastine,21605094,39684
+S01HA03,TETRACAINE,1036884,Tetracaine,21605100,10391
+S01HA04,PROXYMETACAINE,929504,proxymetacaine,21605101,34905
+S01JA,COLOURING AGENTS,935529,Benoxinate,21605107,18889
+S01JA,COLOURING AGENTS,19132210,Oftasceine Disodium,21605107,806916
+S01JA01,FLUORESCEIN,996625,Fluorescein,21605108,25138
+S01JA02,ROSE BENGAL SODIUM,19063871,Rose Bengal,21605109,9471
+S01JA51,"FLUORESCEIN, COMBINATIONS",929504,proxymetacaine,21605110,34905
+S01JA51,"FLUORESCEIN, COMBINATIONS",935529,Benoxinate,21605110,18889
+S01JA51,"FLUORESCEIN, COMBINATIONS",996625,Fluorescein,21605110,25138
+S01KA01,HYALURONIC ACID,787787,hyaluronate,21605114,62372
+S01KA02,HYPROMELLOSE,902251,hypromellose,21605115,27334
+S01KA51,"HYALURONIC ACID, COMBINATIONS",787787,hyaluronate,21605116,62372
+S01KA51,"HYALURONIC ACID, COMBINATIONS",1395573,Chondroitin Sulfates,21605116,2473
+S01KX,OTHER SURGICAL AIDS,19006155,Trypan Blue,21605117,10878
+S01LA01,VERTEPORFIN,912803,Verteporfin,21605121,118886
+S01LA03,PEGAPTANIB,19063605,pegaptanib,21605123,498509
+S01LA04,RANIBIZUMAB,19080982,ranibizumab,21605124,595060
+S01XA03,"SODIUM CHLORIDE, HYPERTONIC",967823,Sodium Chloride,21605129,9863
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,902251,hypromellose,21605143,27334
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,905371,Methylcellulose,21605143,6873
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,908523,Mineral Oil,21605143,6972
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,929128,Propylene glycol,21605143,34693
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,942172,"Petrolatum, White",21605143,82074
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,943191,tyloxapol,21605143,38998
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,948490,Polyethylene Glycol 400,21605143,8514
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,948760,Polysorbate 80,21605143,8560
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,948856,Polyvinyl Alcohol,21605143,8570
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,949279,Carboxymethylcellulose,21605143,2062
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,950056,Povidone,21605143,8610
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,961145,Glycerin,21605143,4910
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,967823,Sodium Chloride,21605143,9863
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,978577,"Mineral Oil, Light",21605143,577312
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,1319156,Dextran 70,21605143,3274
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,1352890,Dextran,21605143,42635
+S01XA20,ARTIFICIAL TEARS & OTHER INDIFFERENT PREPARATIONS,19002257,hydroxypropylcellulose,21605143,27291
+S02AA,ANTIINFECTIVES,923081,Ofloxacin,21605146,7623
+S02AA01,CHLORAMPHENICOL,990069,Chloramphenicol,21605147,2348
+S02AA10,ACETIC ACID,929549,Acetic Acid,21605156,168
+S02AA15,CIPROFLOXACIN,1797513,Ciprofloxacin,21605161,2551
+S02AA30,"ANTIINFECTIVES, COMBINATIONS",927478,pramoxine,21605163,34347
+S02AA30,"ANTIINFECTIVES, COMBINATIONS",949459,chloroxylenol,21605163,20877
+S02AA30,"ANTIINFECTIVES, COMBINATIONS",979096,Zinc Acetate,21605163,58295
+S02BA08,FLUOCINOLONE ACETONIDE,996541,fluocinolone,21605170,25126
+S02CA03,HYDROCORTISONE AND ANTIINFECTIVES,915981,Neomycin,21605175,7299
+S02CA03,HYDROCORTISONE AND ANTIINFECTIVES,927478,pramoxine,21605175,34347
+S02CA03,HYDROCORTISONE AND ANTIINFECTIVES,929549,Acetic Acid,21605175,168
+S02CA03,HYDROCORTISONE AND ANTIINFECTIVES,948582,Polymyxin B,21605175,8536
+S02CA03,HYDROCORTISONE AND ANTIINFECTIVES,949459,chloroxylenol,21605175,20877
+S02CA03,HYDROCORTISONE AND ANTIINFECTIVES,975125,Hydrocortisone,21605175,5492
+S02CA03,HYDROCORTISONE AND ANTIINFECTIVES,1797513,Ciprofloxacin,21605175,2551
+S02CA06,DEXAMETHASONE AND ANTIINFECTIVES,1518254,Dexamethasone,21605178,3264
+S02CA06,DEXAMETHASONE AND ANTIINFECTIVES,1797513,Ciprofloxacin,21605178,2551
+S02DA,ANALGESICS AND ANESTHETICS,917006,Benzocaine,21605181,1399
+S02DA01,LIDOCAINE,989878,Lidocaine,21605182,6387
+S02DA30,COMBINATIONS,916460,Benzalkonium,21605185,1378
+S02DA30,COMBINATIONS,917006,Benzocaine,21605185,1399
+S02DA30,COMBINATIONS,927478,pramoxine,21605185,34347
+S02DA30,COMBINATIONS,949459,chloroxylenol,21605185,20877
+S02DA30,COMBINATIONS,979096,Zinc Acetate,21605185,58295
+S02DA30,COMBINATIONS,1036059,Antipyrine,21605185,1001
+S02DA30,COMBINATIONS,1135766,Phenylephrine,21605185,8163
+S02DC,INDIFFERENT PREPARATIONS,942765,TRIETHANOLAMINE POLYPEPTIDE OLEATE CONDENSATE,21605186,38624
+S02DC,INDIFFERENT PREPARATIONS,958999,carbamide peroxide,21605186,47686
+V01AA04,MOULD FUNGUS AND YEAST FUNGUS,590768,Mold Extract,21605219,235618
+V01AA04,MOULD FUNGUS AND YEAST FUNGUS,19057718,Trichophyton antigen,21605219,465118
+V01AA07,INSECTS,514834,Honey bee venom,21605221,124427
+V01AA07,INSECTS,19006951,Yellow Jacket Venom Protein,21605221,285170
+V01AA07,INSECTS,19014846,White faced hornet venom,21605221,124428
+V01AA07,INSECTS,19055259,HYMENOPTERA ALLERGENIC EXTRACT,21605221,235614
+V01AA07,INSECTS,19097029,Mixed vespid venom,21605221,253189
+V01AA07,INSECTS,19099126,WASP VENOM PROTEIN,21605221,260051
+V03AB,ANTIDOTES,740924,Edrophonium,21605229,3752
+V03AB,ANTIDOTES,910888,Cysteamine,21605229,3022
+V03AB,ANTIDOTES,914335,Atropine,21605229,1223
+V03AB,ANTIDOTES,979096,Zinc Acetate,21605229,58295
+V03AB,ANTIDOTES,1728909,Succimer,21605229,3446
+V03AB,ANTIDOTES,19004969,Trientine,21605229,10798
+V03AB,ANTIDOTES,19011565,Zinc-DTPA,21605229,11431
+V03AB,ANTIDOTES,19015348,pentetate calcium trisodium,21605229,132879
+V03AB01,IPECACUANHA,1781321,Ipecac,21605230,5975
+V03AB03,EDETATES,1741008,Edetic Acid,21605232,3755
+V03AB04,PRALIDOXIME,914335,Atropine,21605233,1223
+V03AB04,PRALIDOXIME,1727468,pralidoxime,21605233,34345
+V03AB06,THIOSULFATE,940004,sodium thiosulfate,21605235,36726
+V03AB08,SODIUM NITRITE,940004,sodium thiosulfate,21605236,36726
+V03AB08,SODIUM NITRITE,19069907,Sodium Nitrite,21605236,9894
+V03AB09,DIMERCAPROL,1728903,Dimercaprol,21605237,3445
+V03AB14,PROTAMINE,19054242,Protamine Sulfate (USP),21605239,8825
+V03AB15,NALOXONE,1114220,Naloxone,21605240,7242
+V03AB17,METHYLTHIONINIUM CHLORIDE,905518,Methylene blue,21605242,6878
+V03AB19,PHYSOSTIGMINE,19044337,Physostigmine,21605244,8299
+V03AB21,POTASSIUM IODIDE,19049909,Potassium Iodide,21605246,8597
+V03AB22,AMYL NITRITE,940004,sodium thiosulfate,21605247,36726
+V03AB22,AMYL NITRITE,1319051,Amyl Nitrite,21605247,742
+V03AB23,ACETYLCYSTEINE,1139042,Acetylcysteine,21605248,197
+V03AB24,DIGITALIS ANTITOXIN,19045317,digoxin antibodies Fab fragments,21605249,203223
+V03AB25,FLUMAZENIL,19055153,Flumazenil,21605250,4457
+V03AB26,METHIONINE,19004724,Methionine,21605251,6837
+V03AB31,PRUSSIAN BLUE,19011393,Insoluble berlin blue stain,21605254,705707
+V03AB32,GLUTATHIONE,19061083,Glutathione,21605255,4890
+V03AB33,HYDROXOCOBALAMIN,1377023,Hydroxocobalamin,21605256,5514
+V03AB34,FOMEPIZOLE,19022479,fomepizole,21605257,15226
+V03AC01,DEFEROXAMINE,1711947,Deferoxamine,21605260,3131
+V03AC03,DEFERASIROX,1786055,deferasirox,21605262,614373
+V03AE,DRUGS FOR TX OF HYPERKALEMIA &HYPERPHOSPOSPHATEMIA,908464,magnesium carbonate,21605263,29155
+V03AE,DRUGS FOR TX OF HYPERKALEMIA &HYPERPHOSPOSPHATEMIA,951469,calcium acetate,21605263,214342
+V03AE,DRUGS FOR TX OF HYPERKALEMIA &HYPERPHOSPOSPHATEMIA,1387426,Folate,21605263,62356
+V03AE,DRUGS FOR TX OF HYPERKALEMIA &HYPERPHOSPOSPHATEMIA,19035704,Calcium Carbonate,21605263,1897
+V03AE01,POLYSTYRENE SULFONATE,19078126,Sodium polystyrene sulfonate,21605264,56512
+V03AE02,SEVELAMER,993997,sevelamer carbonate,21605265,660890
+V03AE03,LANTHANUM CARBONATE,990028,lanthanum carbonate,21605266,234416
+V03AE04,CALCIUM ACETATE AND MAGNESIUM CARBONATE,908464,magnesium carbonate,21605267,29155
+V03AE04,CALCIUM ACETATE AND MAGNESIUM CARBONATE,951469,calcium acetate,21605267,214342
+V03AF01,MESNA,1354698,Mesna,21605269,44
+V03AF01,MESNA,19078187,Ifosfamide,21605269,5657
+V03AF02,DEXRAZOXANE,1353011,Dexrazoxane,21605270,42736
+V03AF03,CALCIUM FOLINATE,1388796,Leucovorin,21605271,6313
+V03AF04,CALCIUM LEVOFOLINATE,1388796,Leucovorin,21605272,6313
+V03AF05,AMIFOSTINE,1350040,Amifostine,21605273,4126
+V03AF07,RASBURICASE,1304565,Rasburicase,21605275,283821
+V03AF08,PALIFERMIN,19038562,Palifermin,21605276,196319
+V03AG,DRUGS FOR TREATMENT OF HYPERCALCEMIA,19097605,gallium nitrate,21605279,25544
+V03AH01,DIAZOXIDE,1523280,Diazoxide,21605282,3327
+V03AX,OTHER THERAPEUTIC PRODUCTS,711452,Benzoate,21605291,70589
+V03AX,OTHER THERAPEUTIC PRODUCTS,942494,chlorophyllin copper complex,21605291,82242
+V03AX,OTHER THERAPEUTIC PRODUCTS,1511856,phenylacetate,21605291,70619
+V03AX,OTHER THERAPEUTIC PRODUCTS,1741008,Edetic Acid,21605291,3755
+V03AX,OTHER THERAPEUTIC PRODUCTS,19027339,potassium perchlorate,21605291,34318
+V03AX,OTHER THERAPEUTIC PRODUCTS,19087067,4-Aminobenzoate,21605291,618974
+V03AZ01,ETHANOL,955372,Ethanol,21605294,448
+V04CA01,TOLBUTAMIDE,1502855,Tolbutamide,21605299,10635
+V04CA02,GLUCOSE,1560524,Glucose,21605300,4850
+V04CC03,SINCALIDE,19067803,Sincalide,21605306,9800
+V04CD,TESTS FOR PITUITARY FUNCTION,19006410,Arginine,21605308,1091
+V04CD01,METYRAPONE,19007490,Metyrapone,21605309,6923
+V04CE02,SULFOBROMOPHTALEIN,19000826,Sulfobromophthalein,21605315,10212
+V04CF01,TUBERCULIN,19058274,Purified Protein Derivative of Tuberculin,21605317,8948
+V04CG03,HISTAMINE PHOSPHATE,19069019,Histamine,21605321,5333
+V04CG04,PENTAGASTRIN,19030376,Pentagastrin,21605322,7993
+V04CH01,INULIN AND OTHER POLYFRUCTOSANS,980478,Inulin,21605326,5924
+V04CH02,INDIGO CARMINE,19017390,Indigotindisulfonate,21605327,325514
+V04CH30,AMINOHIPPURIC ACID,19053177,p-Aminohippurate,21605330,42837
+V04CJ01,THYROTROPIN,19063297,thyrotropin alfa (USP),21605332,4952
+V04CJ02,PROTIRELIN,19001701,Thyrotropin-Releasing Hormone,21605333,10580
+V04CK01,SECRETIN,19084212,Human Secretin,21605335,606396
+V04CK03,BENTIROMIDE,19035595,bentiromide,21605337,18896
+V04CL,TESTS FOR ALLERGIC DISEASES,514834,Honey bee venom,21605338,124427
+V04CL,TESTS FOR ALLERGIC DISEASES,19006951,Yellow Jacket Venom Protein,21605338,285170
+V04CL,TESTS FOR ALLERGIC DISEASES,19014846,White faced hornet venom,21605338,124428
+V04CL,TESTS FOR ALLERGIC DISEASES,19055259,HYMENOPTERA ALLERGENIC EXTRACT,21605338,235614
+V04CL,TESTS FOR ALLERGIC DISEASES,19097029,Mixed vespid venom,21605338,253189
+V04CL,TESTS FOR ALLERGIC DISEASES,19099126,WASP VENOM PROTEIN,21605338,260051
+V04CX,OTHER DIAGNOSTIC AGENTS,996625,Fluorescein,21605341,25138
+V04CX,OTHER DIAGNOSTIC AGENTS,19003412,iso-sulfan blue,21605341,27863
+V04CX,OTHER DIAGNOSTIC AGENTS,19024227,Methacholine,21605341,155080
+V04CX,OTHER DIAGNOSTIC AGENTS,19054337,[13C] urea,21605341,226724
+V04CX,OTHER DIAGNOSTIC AGENTS,19078612,Indocyanine Green,21605341,5775
+V04CX,OTHER DIAGNOSTIC AGENTS,19101568,Coccidioidin,21605341,2660
+V06A,DIET FORMULATIONS FOR TREATMENT OF OBESITY,917006,Benzocaine,21605343,1399
+V06A,DIET FORMULATIONS FOR TREATMENT OF OBESITY,964407,Salicylic Acid,21605343,9525
+V06A,DIET FORMULATIONS FOR TREATMENT OF OBESITY,1134439,Caffeine,21605343,1886
+V06A,DIET FORMULATIONS FOR TREATMENT OF OBESITY,1164108,salicylamide,21605343,9518
+V06DC01,GLUCOSE,1560524,Glucose,21605352,4850
+V06DC02,FRUCTOSE,956691,Fructose,21605353,4570
+V06DD,"AMINO ACIDS,INCL. COMBINATIONS WITH POLYPEPTIDES",19006410,Arginine,21605354,1091
+V06DD,"AMINO ACIDS,INCL. COMBINATIONS WITH POLYPEPTIDES",19006692,Tyrosine,21605354,10962
+V06DD,"AMINO ACIDS,INCL. COMBINATIONS WITH POLYPEPTIDES",19010955,Cysteine,21605354,3024
+V06DD,"AMINO ACIDS,INCL. COMBINATIONS WITH POLYPEPTIDES",19024365,Ornithine,21605354,7704
+V06DD,"AMINO ACIDS,INCL. COMBINATIONS WITH POLYPEPTIDES",19035577,Phenylalanine,21605354,8156
+V06DD,"AMINO ACIDS,INCL. COMBINATIONS WITH POLYPEPTIDES",19092377,Lysine,21605354,6536
+V06DD,"AMINO ACIDS,INCL. COMBINATIONS WITH POLYPEPTIDES",19097664,Citrulline,21605354,2567
+V06DE,"AMINO ACIDS/CARBOHYDRATES/MINERALS/VITAMINS, COMB",19006410,Arginine,21605355,1091
+V06DE,"AMINO ACIDS/CARBOHYDRATES/MINERALS/VITAMINS, COMB",19035704,Calcium Carbonate,21605355,1897
+V07AB,"SOLVENTS & DILUTING AGENTS,INCL. IRRIGATING SOLNS",967823,Sodium Chloride,21605361,9863
+V07AB,"SOLVENTS & DILUTING AGENTS,INCL. IRRIGATING SOLNS",1319156,Dextran 70,21605361,3274
+V07AB,"SOLVENTS & DILUTING AGENTS,INCL. IRRIGATING SOLNS",19010309,Water,21605361,11295
+V07AC,"BLOOD TRANSFUSION, AUXILIARY PRODUCTS",977968,sodium citrate,21605362,56466
+V07AV,TECHNICAL DISINFECTANTS,1790812,Chlorhexidine,21605368,2358
+V07AX,WASHING AGENTS ETC.,967823,Sodium Chloride,21605369,9863
+V07AX,WASHING AGENTS ETC.,19024665,Poloxamer,21605369,155156
+V07AY,OTHER NON-THERAPEUTIC AUXILIARY PRODUCTS,19058092,Gelatin,21605370,4716
+V07AY,OTHER NON-THERAPEUTIC AUXILIARY PRODUCTS,19087208,Lactose,21605370,6211
+V08AA01,DIATRIZOIC ACID,19022596,Diatrizoate,21605375,3319
+V08AA03,IODAMIDE,19080542,Iodamide,21605377,5928
+V08AB02,IOHEXOL,19080985,Iohexol,21605387,5956
+V08AB05,IOPROMIDE,19003206,iopromide,21605390,27781
+V08AB12,IOXILAN,19003249,ioxilan,21605397,27793
+V08AC06,IOPANOIC ACID,19081256,Iopanoic Acid,21605404,5967
+V08AC07,IOCETAMIC ACID,19033638,iocetamic acid,21605405,183830
+V08AC08,SODIUM IOPODATE,19081385,Ipodate,21605406,5976
+V08AC09,TYROPANOIC ACID,19006659,Tyropanoate,21605407,10960
+V08AC10,CALCIUM IOPODATE,19081385,Ipodate,21605408,5976
+V08AD01,ETHYL ESTERS OF IODISED FATTY ACIDS,19050016,Ethiodized Oil,21605410,4125
+V08AD03,PROPYLIODONE,19054048,Propyliodone,21605412,8793
+V08CA04,GADOTERIDOL,19097463,gadoteridol,21605423,25483
+V08CA05,MANGAFODIPIR,19092105,MANGAFODIPIR,21605424,236987
+V08CA06,GADOVERSETAMIDE,19089496,gadoversetamide,21605425,228833
+V08CA08,GADOBENIC ACID,19007652,Gadobenate,21605427,692620
+V08CA10,GADOXETIC ACID,19031583,gadoxetate,21605429,802624
+V08CB,SUPERPARAMAGNETIC CONTRAST MEDIA,19015703,ferumoxides,21605431,72901
+V08CB01,FERUMOXSIL,19024772,ferumoxsil,21605432,77754
+M03BA03,Methocarbamol,704943,Methocarbamol,21604095,6845
+M03BA53,"Methocarbamol, combinations excl. psycholeptics",704943,Methocarbamol,21604100,6845
+M03BA73,"Methocarbamol, combinations with psycholeptics",704943,Methocarbamol,21604103,6845
+N06BA05,Pemoline,727835,Pemoline,21604758,7966
+A08AA01,Phentermine,735340,Phentermine,21600682,8152
+C01CA11,Mephentermine,735340,Phentermine,21600291,8152
+N05CF02,Zolpidem,744740,zolpidem,21604655,39993
+N05CF04,eszopiclone�,757352,Eszopiclone,21604657,461016
+N05CH02,Ramelteon,781182,ramelteon,21604660,596205
+A02BC04,Rabeprazole,911735,rabeprazole,21600099,114979
+A03AA07 �,dicycloverine�,924724,Dicyclomine,0,3361
+G04BX13,Dimethyl sulfoxide,928980,Dimethyl Sulfoxide,21602664,3455
+M02AX03,Dimethyl sulfoxide,928980,Dimethyl Sulfoxide,21604067,3455
+D10AX01 ,Aluminium chloride ,957393,aluminum chloride,0,46241
+D11AX18,Diclofenac,1124300,Diclofenac,21602355,3355
+M01AB05,Diclofenac,1124300,Diclofenac,21603945,3355
+M01AB55,"Diclofenac, combinations",1124300,Diclofenac,21603959,3355
+M02AA15,Diclofenac,1124300,Diclofenac,21604051,3355
+S01BC03,Diclofenac,1124300,Diclofenac,21603641,3355
+S01CC01,Diclofenac and antiinfectives,1124300,Diclofenac,21603670,3355
+R05DB01,Benzonatate,1136601,benzonatate,21603410,18993
+N02BA06,Salsalate,1137460,Salsalate,21604310,36108
+S01BC11,bromfenac,1139179,bromfenac,21603649,19737
+L01AX04,Dacarbazine,1311409,Dacarbazine,21601420,3098
+B02BD08 �,eptacog alfa (activated)�,1352141,Factor VIIa,0,4256
+J01MA15,Gemifloxacin,1716721,gemifloxacin,21603022,138099
+J01MA16,Gatifloxacin,1789276,gatifloxacin,21603023,228476
+S01AX21,Gatifloxacin,1789276,gatifloxacin,21603614,228476
+D01AC06 �,tiabendazole�,1837289,Thiabendazole,0,10450
+P02CA02,tiabendazole�,1837289,Thiabendazole,21604942,10450
+J05AF07,Tenofovir disoproxil,19011093,Tenofovir,21603166,117466
+J05AR03,Tenofovir disoproxil and emtricitabine,19011093,Tenofovir,21603183,117466
+J05AR06,"Emtricitabine, tenofovir disoproxil and efavirenz",19011093,Tenofovir,21603186,117466
+J04AB30,Capreomycin,19026710,Capreomycin,21603101,78903
+G03DC05,Unknown,19041933,tibolone,0,38260
+L04AA01,Unknown,19010482,Cyclosporine,0,3008
+V03AB49,Unknown,987245,Lactulose,0,6218
+G04BX49,Unknown,1363053,Doxazosin,0,49276
+M01AX49,Unknown,1102917,Tolmetin,0,10636
+B03AB49,Unknown,1399177,Sodium ferric gluconate complex,0,261435
+M05BX99,Unknown,19058572,Calcium Citrate,0,47613
+M05BX99,Unknown,19037038,Calcium Gluconate,0,1908
+C02CA49,Unknown,1341238,Terazosin,0,37798
+M05BA49,Unknown,1557272,Alendronate,0,46041
+S01EX03,Unknown,954688,latanoprost,0,43611
+M04AX49,Unknown,19046291,piperazine,0,8340
+A05AA49,Unknown,988095,Ursodeoxycholate,0,62427
+L04AA05,Unknown,950637,Tacrolimus,0,42316
+D03AX08,Unknown,1383925,Isosorbide Dinitrate,0,6058
+G03FB49,Unknown,1549080,"Estrogens, Conjugated (USP)",0,4099
+N02AA99,Unknown,1112807,Aspirin,0,1191
+N02AA99,Unknown,1124957,Oxycodone,0,7804
+N02AA99,Unknown,1125315,Acetaminophen,0,161
+N02AA99,Unknown,1177480,Ibuprofen,0,5640
+R05DA49,Unknown,1189596,dihydrocodeine,0,23088
+J01DA06,Unknown,1778162,Cefuroxime,0,2194
+B03AC49,Unknown,1395773,"ferric oxide, saccharated",0,24909
+J01DA13,Unknown,1777806,Ceftriaxone,0,2193
+J01DA08,Unknown,1768849,Cefaclor,0,2176
+A02EA01,Unknown,908464,magnesium carbonate,0,29155
+A02EA01,Unknown,985247,Aluminum Hydroxide,0,612
+S01CA49,Unknown,919345,Gentamicin Sulfate (USP),0,142438
+A04AD49,Unknown,928744,Dimenhydrinate,0,3444
+J01DA41,Unknown,1738366,cefprozil,0,19552
+N04BC49,Unknown,19091472,Lisuride,0,6446
+G04AC01,Unknown,920293,Nitrofurantoin,0,7454
+J01DA31,Unknown,1786842,Cephradine,0,2239
+N05CM17,Unknown,1301152,Melatonin,0,6711
+N05CM17,Unknown,1353228,Vitamin B6,0,42954
+N05CM17,Unknown,19037401,calcium phosphate,0,1919
+N05CM17,Unknown,19100575,theanine,0,38022
+N05AK01,Unknown,836877,Tetrabenazine,0,10390
+L04AA11,Unknown,1151789,Etanercept,0,214555
+B03AA49,Unknown,1300751,Polysaccharide iron complex,0,105669
+R06AE08,Unknown,1136422,levocetirizine,0,356887
+J01DA39,Unknown,1749083,ceftibuten,0,20492
+J01DA01,Unknown,1786621,Cephalexin,0,2231
+J01DA11,Unknown,1776684,Ceftazidime,0,2191
+C10AA51,Unknown,1539403,Simvastatin,0,36567
+N02AC02,Unknown,1103640,Methadone,0,6813
+J01DA23,Unknown,1796435,Cefixime,0,25033
+N06AE02,Unknown,751412,Fluvoxamine,0,42355
+V03AZ49,Unknown,19012660,Magnesium Pidolate,0,116240
+A02DA01,Unknown,966991,Simethicone,0,9796
+L01XX28,Unknown,1304107,imatinib,0,282388
+J01DA38,Unknown,1708100,loracarbef,0,28981
+J01DA17,Unknown,19072857,Cefonicid,0,2183
+V03AF49,Unknown,1388796,Leucovorin,0,6313
+L04AA14,Unknown,1114375,anakinra,0,72435
+N07AA05,Unknown,715997,donepezil,0,135447
+L04AA17,Unknown,1119119,adalimumab,0,327361
+R03DA49,Unknown,19088167,Ambroxol,0,625
+J01DA04,Unknown,1771162,Cefazolin,0,2180
+A01AC99,Unknown,19026096,Diflucortolone,0,3392
+A03FA99,Unknown,906780,Metoclopramide,0,6915
+J01DA10,Unknown,1774470,Cefotaxime,0,2186
+J01DA33,Unknown,1749008,cefpodoxime,0,20489
+S02AA49,Unknown,902722,Tobramycin,0,10627
+P01BA05,Unknown,19000498,Mefloquine,0,6694
+G04AA01,Unknown,904356,Methenamine,0,6832
+G04AA01,Unknown,939871,sodium phosphate,0,36709
+G04AA01,Unknown,986389,"SODIUM PHOSPHATE,MONOBASIC,MONOHYDRATE",0,221125
+G04AA01,Unknown,990499,"Sodium Phosphate, Monobasic",0,235496
+L01XX34,Unknown,1325363,erlotinib,0,337525
+L04AA12,Unknown,937368,infliximab,0,191831
+J01DA24,Unknown,1748975,cefepime,0,20481
+S01BB49,Unknown,915981,Neomycin,0,7299
+S01BB49,Unknown,1518254,Dexamethasone,0,3264
+S01BB49,Unknown,948582,Polymyxin B,0,8536
+S01BB49,Unknown,902722,Tobramycin,0,10627
+J01DA03,Unknown,19086759,Cephalothin,0,2236
+V03AB30,Unknown,1714319,Naltrexone,0,7243
+V03AA01,Unknown,735850,Disulfiram,0,3554
+L01BB01,Unknown,19014878,Azathioprine,0,1256
+N06AA22,Unknown,743670,venlafaxine,0,39786
+J01DA22,Unknown,1777254,Ceftizoxime,0,2192
+N02CX04,Unknown,1140643,Sumatriptan,0,37418
+N06BX19,Unknown,1391889,Ginkgo biloba extract,0,236809
+N06BX19,Unknown,1398560,GINKGO BILOBA LEAF EXTRACT,0,259316
+L03AA04,Unknown,1385645,Interferon Alfa-n3,0,612937
+G04BX05,Unknown,1381504,Alprostadil,0,598
+B01AC14,Unknown,1381253,anagrelide,0,596724
+J01DA07,Unknown,19070174,Cefamandole,0,2178
+J05AB10,Unknown,1704183,Lamivudine,0,68244
+R03CA01,Unknown,1343916,Epinephrine,0,3992
+R03CA01,Unknown,1192710,Chlorpheniramine,0,2400
+V03AB07,Unknown,837027,Apomorphine,0,1043
+B04AD01,Unknown,19095309,Cholestyramine,0,2447
+H02AB16,Unknown,939259,Budesonide,0,19831
+V03AA03,Unknown,19043959,acamprosate,0,82819
+D11AX15,Pimecrolimus,915935,Pimecrolimus,0,321952
+A11CC07,Paricalcitol,1517740,paricalcitol,0,73710
+D11AX14,Tacrolimus,950637,Tacrolimus,0,42316
+C10AX04,Benfluorex,19035533,benfluorex,0,18880
+N07BA02,Bupropion,750982,Bupropion,0,42347
diff --git a/src/org/ohdsi/whiteRabbit/etls/ars/Fields.xlsx b/src/org/ohdsi/whiteRabbit/etls/ars/Fields.xlsx
new file mode 100644
index 00000000..0c801c28
Binary files /dev/null and b/src/org/ohdsi/whiteRabbit/etls/ars/Fields.xlsx differ
diff --git a/src/org/ohdsi/whiteRabbit/etls/ars/proc_OUTPAT.csv b/src/org/ohdsi/whiteRabbit/etls/ars/proc_OUTPAT.csv
new file mode 100644
index 00000000..b68b4be7
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/etls/ars/proc_OUTPAT.csv
@@ -0,0 +1,1728 @@
+PROC_COD,TYPE_OUTPAT
+91.90.2,CLIN
+91.90.3,CLIN
+91.90.4,CLIN
+91.90.5,CLIN
+91.90.6,CLIN
+91.90.7,CLIN
+91.90.8,CLIN
+92.29.9,CLIN
+99.82,CLIN
+99.82.1,CLIN
+C.02,CLIN
+C.03,CLIN
+C.04,CLIN
+C.05,CLIN
+C.06,CLIN
+T.01,CLIN
+T.02,CLIN
+T.03,CLIN
+89.01,CLIN
+89.03,CLIN
+89.07,CLIN
+89.13,CLIN
+89.26,CLIN
+38.22,CLIN
+38.22.1,CLIN
+89.39.1,CLIN
+89.39.2,CLIN
+89.39.3,CLIN
+89.39.4,CLIN
+89.7,CLIN
+86.19.1,CLIN
+86.19.2,CLIN
+86.19.3,CLIN
+86.19.4,CLIN
+93.01.5,CLIN
+93.07.1,CLIN
+93.18.1,CLIN
+93.18.2,CLIN
+93.29,CLIN
+93.36,CLIN
+93.37,CLIN
+93.39.2,CLIN
+93.39.5,CLIN
+93.46,CLIN
+93.49.2,CLIN
+90.70.3,CLIN
+90.78.1,CLIN
+93.59.1,CLIN
+93.82.1,CLIN
+93.82.2,CLIN
+93.89.5,CLIN
+93.89.6,CLIN
+93.94,CLIN
+93.99,CLIN
+93.99.1,CLIN
+94.01.1,CLIN
+94.01.2,CLIN
+94.02.1,CLIN
+94.02.2,CLIN
+94.08.1,CLIN
+94.08.2,CLIN
+94.08.3,CLIN
+94.08.4,CLIN
+94.08.5,CLIN
+94.08.6,CLIN
+94.09,CLIN
+94.12.1,CLIN
+94.19.1,CLIN
+94.3,CLIN
+94.32,CLIN
+94.42,CLIN
+94.44,CLIN
+95.01,CLIN
+95.02,CLIN
+96.61,CLIN
+97.1,CLIN
+97.88,CLIN
+99.12,CLIN
+99.13,CLIN
+99.15.1,CLIN
+99.29.7,CLIN
+91.90.1,CLIN
+92.18.2,IMAG
+92.18.3,IMAG
+92.18.4,IMAG
+92.18.5,IMAG
+92.18.6,IMAG
+92.19.1,IMAG
+92.19.2,IMAG
+92.19.3,IMAG
+92.19.5,IMAG
+92.19.6,IMAG
+92.19.7,IMAG
+92.19.8,IMAG
+87.99.1,IMAG
+87.99.2,IMAG
+88.01.1,IMAG
+88.01.2,IMAG
+88.01.3,IMAG
+88.01.4,IMAG
+88.01.5,IMAG
+88.01.6,IMAG
+88.03.1,IMAG
+88.04,IMAG
+88.19,IMAG
+88.21,IMAG
+88.22,IMAG
+88.23,IMAG
+88.25,IMAG
+88.26,IMAG
+92.01.1,IMAG
+92.01.2,IMAG
+92.01.3,IMAG
+92.01.4,IMAG
+92.02.1,IMAG
+92.02.2,IMAG
+92.02.3,IMAG
+92.02.4,IMAG
+92.02.5,IMAG
+92.03.1,IMAG
+92.03.2,IMAG
+92.03.3,IMAG
+92.03.4,IMAG
+92.03.5,IMAG
+92.04.1,IMAG
+92.04.2,IMAG
+92.04.3,IMAG
+92.04.4,IMAG
+92.04.5,IMAG
+92.05.1,IMAG
+92.05.2,IMAG
+92.05.3,IMAG
+92.05.4,IMAG
+92.05.5,IMAG
+92.05.6,IMAG
+92.09.1,IMAG
+92.09.2,IMAG
+92.09.3,IMAG
+92.09.4,IMAG
+92.09.5,IMAG
+92.09.6,IMAG
+92.09.7,IMAG
+92.11.1,IMAG
+92.11.2,IMAG
+92.11.5,IMAG
+92.11.6,IMAG
+92.11.7,IMAG
+92.13,IMAG
+92.14.1,IMAG
+92.14.2,IMAG
+92.14.3,IMAG
+92.15.1,IMAG
+92.15.2,IMAG
+92.15.3,IMAG
+92.15.4,IMAG
+92.15.5,IMAG
+92.16.1,IMAG
+92.18.1,IMAG
+87.07,IMAG
+87.09.1,IMAG
+87.09.2,IMAG
+87.11.1,IMAG
+87.11.2,IMAG
+87.11.3,IMAG
+87.11.4,IMAG
+87.12.1,IMAG
+87.12.2,IMAG
+87.13.1,IMAG
+87.13.2,IMAG
+87.16.1,IMAG
+87.16.2,IMAG
+87.16.3,IMAG
+87.16.4,IMAG
+87.17.1,IMAG
+87.17.2,IMAG
+87.17.3,IMAG
+87.22,IMAG
+87.23,IMAG
+87.24,IMAG
+87.29,IMAG
+87.35,IMAG
+87.37.1,IMAG
+87.37.2,IMAG
+87.37.3,IMAG
+87.38,IMAG
+87.41,IMAG
+87.41.1,IMAG
+87.42.1,IMAG
+87.42.2,IMAG
+87.42.3,IMAG
+87.43.1,IMAG
+87.43.2,IMAG
+87.44.1,IMAG
+87.44.2,IMAG
+87.49.1,IMAG
+87.52,IMAG
+87.54.1,IMAG
+87.59.1,IMAG
+87.61,IMAG
+87.62,IMAG
+87.62.1,IMAG
+87.62.2,IMAG
+87.62.3,IMAG
+87.63,IMAG
+87.64,IMAG
+87.65.1,IMAG
+87.65.2,IMAG
+87.65.3,IMAG
+87.66,IMAG
+87.69.1,IMAG
+87.72,IMAG
+87.73,IMAG
+87.74.1,IMAG
+87.74.2,IMAG
+87.75.1,IMAG
+87.76,IMAG
+87.76.1,IMAG
+87.77,IMAG
+87.77.1,IMAG
+87.79.1,IMAG
+87.83,IMAG
+87.89.1,IMAG
+88.90.3,IMAG
+88.90.4,IMAG
+88.91.1,IMAG
+88.91.2,IMAG
+88.91.3,IMAG
+88.91.4,IMAG
+88.91.5,IMAG
+88.91.6,IMAG
+88.91.7,IMAG
+88.91.8,IMAG
+88.91.A,IMAG
+88.91.B,IMAG
+88.91.C,IMAG
+88.92,IMAG
+88.92.1,IMAG
+88.92.2,IMAG
+88.92.3,IMAG
+88.92.4,IMAG
+88.92.5,IMAG
+88.92.6,IMAG
+88.92.7,IMAG
+88.92.8,IMAG
+88.92.9,IMAG
+88.93,IMAG
+88.93.1,IMAG
+88.94.1,IMAG
+88.94.2,IMAG
+88.94.3,IMAG
+88.95.1,IMAG
+88.95.2,IMAG
+88.95.3,IMAG
+88.95.4,IMAG
+88.95.5,IMAG
+88.95.6,IMAG
+88.97.1,IMAG
+88.97.2,IMAG
+88.97.3,IMAG
+88.99.1,IMAG
+88.99.2,IMAG
+88.99.3,IMAG
+88.99.4,IMAG
+88.99.5,IMAG
+89.58.1,IMAG
+89.58.2,IMAG
+89.58.3,IMAG
+89.58.4,IMAG
+89.58.5,IMAG
+89.58.6,IMAG
+89.58.7,IMAG
+89.58.8,IMAG
+87.03,IMAG
+87.03.1,IMAG
+87.03.2,IMAG
+87.03.3,IMAG
+87.03.4,IMAG
+87.03.5,IMAG
+87.03.6,IMAG
+87.03.7,IMAG
+87.03.8,IMAG
+87.03.9,IMAG
+87.04.1,IMAG
+87.05,IMAG
+87.06,IMAG
+87.06.1,IMAG
+88.27,IMAG
+88.28,IMAG
+88.29.1,IMAG
+88.29.2,IMAG
+88.31,IMAG
+88.31.1,IMAG
+88.32,IMAG
+88.33.1,IMAG
+88.33.2,IMAG
+88.35.1,IMAG
+88.37.1,IMAG
+88.38.1,IMAG
+88.38.2,IMAG
+88.38.3,IMAG
+88.38.4,IMAG
+88.38.5,IMAG
+88.38.6,IMAG
+88.38.7,IMAG
+88.38.8,IMAG
+88.39.1,IMAG
+88.39.5,IMAG
+88.42.1,IMAG
+88.42.2,IMAG
+88.48,IMAG
+88.60.1,IMAG
+88.61.1,IMAG
+88.61.2,IMAG
+88.63.1,IMAG
+88.63.2,IMAG
+88.65.1,IMAG
+88.65.2,IMAG
+88.65.3,IMAG
+88.66.1,IMAG
+88.66.2,IMAG
+88.71.1,IMAG
+88.71.2,IMAG
+88.71.3,IMAG
+88.71.4,IMAG
+88.73.1,IMAG
+88.73.2,IMAG
+88.73.3,IMAG
+88.73.4,IMAG
+88.73.5,IMAG
+88.74.1,IMAG
+88.75.1,IMAG
+88.76.1,IMAG
+88.77.1,IMAG
+88.77.2,IMAG
+88.77.3,IMAG
+88.78,IMAG
+88.78.1,IMAG
+88.78.2,IMAG
+88.79.1,IMAG
+88.79.2,IMAG
+88.79.3,IMAG
+88.79.5,IMAG
+88.79.6,IMAG
+88.79.7,IMAG
+88.79.8,IMAG
+88.83.1,IMAG
+88.85,IMAG
+88.89,IMAG
+88.90.1,IMAG
+88.90.2,IMAG
+89.04.1,LAB
+45.29.1,LAB
+45.29.2,LAB
+45.29.3,LAB
+64.19.2,LAB
+44.19.2,LAB
+90.47.4,LAB
+90.47.5,LAB
+90.47.6,LAB
+90.47.7,LAB
+90.48.1,LAB
+90.48.2,LAB
+90.48.3,LAB
+90.48.4,LAB
+90.48.5,LAB
+90.49.1,LAB
+90.49.2,LAB
+90.49.3,LAB
+90.49.4,LAB
+90.49.5,LAB
+90.49.6,LAB
+89.65.1,LAB
+89.66,LAB
+90.01.1,LAB
+90.01.2,LAB
+90.01.3,LAB
+90.01.4,LAB
+90.01.5,LAB
+90.02.1,LAB
+90.02.2,LAB
+90.02.3,LAB
+90.02.4,LAB
+90.02.5,LAB
+90.03.1,LAB
+90.03.2,LAB
+90.03.3,LAB
+90.03.4,LAB
+90.03.5,LAB
+90.04.1,LAB
+90.04.2,LAB
+90.04.3,LAB
+90.04.4,LAB
+90.04.5,LAB
+90.05.1,LAB
+90.05.2,LAB
+90.05.3,LAB
+90.05.4,LAB
+90.05.5,LAB
+90.06.1,LAB
+90.06.2,LAB
+90.06.3,LAB
+90.06.4,LAB
+90.06.5,LAB
+90.06.7,LAB
+90.07.1,LAB
+90.07.2,LAB
+90.07.3,LAB
+90.07.4,LAB
+90.07.5,LAB
+90.07.6,LAB
+90.08.1,LAB
+90.08.2,LAB
+90.08.3,LAB
+90.08.4,LAB
+90.08.5,LAB
+90.08.6,LAB
+90.09.1,LAB
+90.09.2,LAB
+90.09.3,LAB
+90.09.4,LAB
+90.09.5,LAB
+90.10.1,LAB
+90.10.2,LAB
+90.10.3,LAB
+90.10.4,LAB
+90.10.5,LAB
+90.10.6,LAB
+90.11.1,LAB
+90.11.2,LAB
+90.11.3,LAB
+90.11.4,LAB
+90.11.5,LAB
+90.11.6,LAB
+90.12.1,LAB
+90.12.2,LAB
+90.12.3,LAB
+90.12.4,LAB
+90.12.5,LAB
+90.13.1,LAB
+90.13.2,LAB
+90.86.3,LAB
+90.86.4,LAB
+90.86.8,LAB
+90.87.1,LAB
+90.87.3,LAB
+90.88.5,LAB
+90.88.6,LAB
+90.89.3,LAB
+90.89.5,LAB
+90.90.3,LAB
+90.91.4,LAB
+90.92.4,LAB
+90.93.3,LAB
+90.93.4,LAB
+90.93.5,LAB
+90.93.6,LAB
+90.94.1,LAB
+90.94.2,LAB
+90.94.3,LAB
+90.94.5,LAB
+90.94.6,LAB
+90.95.1,LAB
+90.95.3,LAB
+90.96.5,LAB
+90.97.2,LAB
+90.97.3,LAB
+90.98.4,LAB
+90.98.5,LAB
+91.01.1,LAB
+91.01.2,LAB
+91.02.2,LAB
+91.02.4,LAB
+91.03.5,LAB
+91.04.1,LAB
+91.04.5,LAB
+91.05.2,LAB
+91.05.6,LAB
+91.05.7,LAB
+91.05.8,LAB
+91.05.9,LAB
+91.06.7,LAB
+91.06.8,LAB
+91.08.1,LAB
+91.08.4,LAB
+91.08.5,LAB
+91.09.1,LAB
+91.09.2,LAB
+91.09.3,LAB
+91.10.3,LAB
+91.10.6,LAB
+91.11.1,LAB
+91.11.2,LAB
+91.11.3,LAB
+91.11.5,LAB
+91.12.1,LAB
+91.12.2,LAB
+91.13.2,LAB
+91.13.3,LAB
+91.13.7,LAB
+91.14.5,LAB
+91.14.6,LAB
+91.14.7,LAB
+91.14.8,LAB
+91.14.9,LAB
+91.15.6,LAB
+91.15.7,LAB
+91.15.8,LAB
+91.15.9,LAB
+91.16.6,LAB
+91.16.7,LAB
+69.92.1,LAB
+90.49.7,LAB
+90.50.1,LAB
+90.50.2,LAB
+90.50.3,LAB
+90.50.4,LAB
+90.50.5,LAB
+90.51.1,LAB
+90.51.2,LAB
+90.51.3,LAB
+90.51.4,LAB
+90.51.5,LAB
+90.52.1,LAB
+90.52.2,LAB
+90.52.3,LAB
+90.52.4,LAB
+90.52.5,LAB
+90.53.1,LAB
+90.53.2,LAB
+90.53.3,LAB
+90.53.4,LAB
+90.53.5,LAB
+90.53.6,LAB
+90.54.1,LAB
+90.54.2,LAB
+90.54.3,LAB
+90.54.4,LAB
+90.54.5,LAB
+90.55.1,LAB
+90.55.2,LAB
+90.55.3,LAB
+90.55.4,LAB
+90.55.5,LAB
+90.56.1,LAB
+90.56.2,LAB
+90.56.3,LAB
+90.56.4,LAB
+90.56.5,LAB
+90.57.1,LAB
+90.57.2,LAB
+90.57.3,LAB
+90.57.4,LAB
+90.57.5,LAB
+90.57.6,LAB
+90.58.1,LAB
+90.58.2,LAB
+90.58.3,LAB
+90.58.4,LAB
+90.58.5,LAB
+90.59.1,LAB
+90.59.2,LAB
+90.59.3,LAB
+90.59.4,LAB
+90.60.1,LAB
+90.60.2,LAB
+90.60.3,LAB
+90.60.4,LAB
+90.60.5,LAB
+90.61.1,LAB
+90.61.2,LAB
+90.61.3,LAB
+90.61.4,LAB
+90.61.5,LAB
+90.62.1,LAB
+90.62.2,LAB
+90.62.3,LAB
+90.62.4,LAB
+90.62.5,LAB
+90.63.1,LAB
+90.63.2,LAB
+90.63.3,LAB
+90.63.4,LAB
+90.63.5,LAB
+90.64.1,LAB
+90.64.2,LAB
+90.64.3,LAB
+90.64.4,LAB
+90.64.5,LAB
+90.65.1,LAB
+90.65.2,LAB
+90.65.3,LAB
+90.65.4,LAB
+90.66.1,LAB
+90.66.2,LAB
+90.66.3,LAB
+90.66.4,LAB
+90.66.5,LAB
+90.67.1,LAB
+90.67.2,LAB
+90.67.3,LAB
+90.67.4,LAB
+90.67.5,LAB
+90.67.6,LAB
+90.68.1,LAB
+90.13.3,LAB
+90.13.4,LAB
+90.13.5,LAB
+90.14.1,LAB
+90.14.2,LAB
+90.14.3,LAB
+90.14.4,LAB
+90.14.5,LAB
+90.15.1,LAB
+90.15.2,LAB
+90.15.3,LAB
+90.15.4,LAB
+90.15.5,LAB
+90.15.6,LAB
+90.16.1,LAB
+90.16.2,LAB
+90.16.3,LAB
+90.16.4,LAB
+90.16.5,LAB
+90.17.1,LAB
+90.17.2,LAB
+90.17.3,LAB
+90.17.4,LAB
+90.17.5,LAB
+90.17.6,LAB
+90.18.1,LAB
+90.18.2,LAB
+90.18.3,LAB
+90.18.4,LAB
+90.18.5,LAB
+90.18.6,LAB
+90.18.7,LAB
+90.18.8,LAB
+90.19.1,LAB
+90.19.2,LAB
+90.19.3,LAB
+90.19.4,LAB
+90.19.5,LAB
+90.20.1,LAB
+90.20.2,LAB
+90.20.3,LAB
+90.20.4,LAB
+90.20.5,LAB
+90.21.1,LAB
+90.21.2,LAB
+90.21.3,LAB
+90.21.4,LAB
+90.21.5,LAB
+90.21.6,LAB
+90.21.7,LAB
+90.22.1,LAB
+90.22.2,LAB
+90.22.3,LAB
+90.22.4,LAB
+90.22.5,LAB
+90.23.1,LAB
+90.23.2,LAB
+90.23.3,LAB
+90.23.4,LAB
+90.23.5,LAB
+90.24.1,LAB
+90.24.2,LAB
+90.24.3,LAB
+90.24.4,LAB
+90.24.5,LAB
+90.25.1,LAB
+90.25.2,LAB
+90.25.3,LAB
+90.25.4,LAB
+90.25.5,LAB
+90.26.1,LAB
+90.26.2,LAB
+90.26.3,LAB
+90.26.4,LAB
+90.27.1,LAB
+90.27.2,LAB
+90.27.3,LAB
+90.27.4,LAB
+90.27.5,LAB
+90.28.1,LAB
+90.28.2,LAB
+90.28.3,LAB
+90.28.4,LAB
+90.28.5,LAB
+90.29.1,LAB
+90.29.2,LAB
+90.29.3,LAB
+90.29.4,LAB
+90.29.5,LAB
+90.29.6,LAB
+90.30.1,LAB
+90.30.2,LAB
+90.30.3,LAB
+90.30.4,LAB
+90.30.5,LAB
+90.31.1,LAB
+90.31.2,LAB
+90.31.3,LAB
+90.31.4,LAB
+90.31.5,LAB
+90.32.1,LAB
+90.32.2,LAB
+90.32.3,LAB
+90.32.4,LAB
+90.32.5,LAB
+90.33.1,LAB
+90.33.2,LAB
+90.33.3,LAB
+90.33.4,LAB
+91.16.8,LAB
+91.16.9,LAB
+91.17.1,LAB
+91.17.2,LAB
+91.17.3,LAB
+91.17.4,LAB
+91.17.5,LAB
+91.18.1,LAB
+91.18.2,LAB
+91.18.3,LAB
+91.19.2,LAB
+91.19.3,LAB
+91.19.4,LAB
+91.19.5,LAB
+91.20.1,LAB
+91.20.2,LAB
+91.20.3,LAB
+91.20.4,LAB
+91.20.5,LAB
+91.21.3,LAB
+91.21.4,LAB
+91.22.1,LAB
+91.22.2,LAB
+91.22.3,LAB
+91.22.4,LAB
+91.22.5,LAB
+91.22.6,LAB
+91.23.1,LAB
+91.23.2,LAB
+91.23.3,LAB
+91.23.4,LAB
+91.23.5,LAB
+91.24.1,LAB
+91.24.2,LAB
+91.26.3,LAB
+91.27.5,LAB
+91.27.6,LAB
+91.27.7,LAB
+91.28.1,LAB
+91.28.2,LAB
+91.28.3,LAB
+91.28.4,LAB
+91.28.5,LAB
+91.29.1,LAB
+91.29.2,LAB
+91.29.3,LAB
+90.68.2,LAB
+90.68.3,LAB
+90.68.4,LAB
+90.68.5,LAB
+90.68.6,LAB
+90.68.7,LAB
+90.68.8,LAB
+90.69.1,LAB
+90.69.2,LAB
+90.69.3,LAB
+90.69.4,LAB
+90.69.5,LAB
+90.70.1,LAB
+90.70.2,LAB
+90.70.4,LAB
+90.70.5,LAB
+90.71.1,LAB
+90.71.2,LAB
+90.71.3,LAB
+90.71.4,LAB
+90.71.5,LAB
+90.72.1,LAB
+90.72.2,LAB
+90.72.3,LAB
+90.72.4,LAB
+90.72.5,LAB
+90.73.1,LAB
+90.73.2,LAB
+90.73.3,LAB
+90.73.4,LAB
+90.73.5,LAB
+90.74.1,LAB
+90.74.2,LAB
+90.74.3,LAB
+90.74.4,LAB
+90.74.5,LAB
+90.75.1,LAB
+90.75.2,LAB
+90.75.3,LAB
+90.75.4,LAB
+90.75.5,LAB
+90.76.1,LAB
+90.76.2,LAB
+90.76.3,LAB
+90.76.4,LAB
+90.76.5,LAB
+90.76.6,LAB
+90.77.1,LAB
+90.77.2,LAB
+90.77.3,LAB
+90.77.4,LAB
+90.77.5,LAB
+90.78.2,LAB
+90.78.3,LAB
+90.78.4,LAB
+90.78.5,LAB
+90.78.6,LAB
+90.79.1,LAB
+90.79.2,LAB
+90.79.3,LAB
+90.79.4,LAB
+90.79.5,LAB
+90.80.1,LAB
+90.80.2,LAB
+90.80.3,LAB
+90.80.4,LAB
+90.80.5,LAB
+90.33.5,LAB
+90.33.6,LAB
+90.34.1,LAB
+90.34.2,LAB
+90.34.3,LAB
+90.34.4,LAB
+90.34.5,LAB
+90.35.1,LAB
+90.35.2,LAB
+90.35.3,LAB
+90.35.4,LAB
+90.35.5,LAB
+90.36.1,LAB
+90.36.2,LAB
+90.36.3,LAB
+90.36.4,LAB
+90.36.5,LAB
+90.36.6,LAB
+90.37.1,LAB
+90.37.2,LAB
+90.37.3,LAB
+90.37.4,LAB
+90.37.5,LAB
+90.38.1,LAB
+90.38.2,LAB
+90.38.3,LAB
+90.38.4,LAB
+90.38.5,LAB
+90.39.1,LAB
+90.39.2,LAB
+90.39.3,LAB
+90.39.4,LAB
+90.39.5,LAB
+90.40.1,LAB
+90.40.2,LAB
+90.40.3,LAB
+90.40.4,LAB
+90.40.5,LAB
+90.40.6,LAB
+90.40.7,LAB
+90.41.1,LAB
+90.41.2,LAB
+90.41.3,LAB
+90.41.4,LAB
+90.41.5,LAB
+90.41.6,LAB
+90.42.1,LAB
+90.42.2,LAB
+90.42.3,LAB
+90.42.4,LAB
+90.42.5,LAB
+90.42.6,LAB
+90.43.1,LAB
+90.43.2,LAB
+90.43.3,LAB
+90.43.4,LAB
+90.43.5,LAB
+90.43.6,LAB
+90.44.1,LAB
+90.44.2,LAB
+90.44.3,LAB
+90.44.4,LAB
+90.44.5,LAB
+90.45.1,LAB
+90.45.2,LAB
+90.45.3,LAB
+90.45.4,LAB
+90.45.5,LAB
+90.46.3,LAB
+90.46.4,LAB
+90.46.5,LAB
+90.47.1,LAB
+90.47.2,LAB
+90.47.3,LAB
+90.81.1,LAB
+90.81.2,LAB
+90.81.3,LAB
+90.81.4,LAB
+90.81.5,LAB
+90.82.1,LAB
+90.82.2,LAB
+90.82.3,LAB
+90.82.4,LAB
+90.82.5,LAB
+90.83.1,LAB
+90.83.2,LAB
+90.83.4,LAB
+90.83.5,LAB
+90.84.1,LAB
+90.84.3,LAB
+90.85.2,LAB
+90.85.4,LAB
+90.85.5,LAB
+90.85.6,LAB
+90.85.7,LAB
+90.85.8,LAB
+90.86.2,LAB
+91.29.4,LAB
+91.29.5,LAB
+91.30.1,LAB
+91.30.2,LAB
+91.30.3,LAB
+91.30.4,LAB
+91.30.5,LAB
+91.31.1,LAB
+91.31.2,LAB
+91.31.3,LAB
+91.31.4,LAB
+91.31.5,LAB
+91.32.1,LAB
+91.32.2,LAB
+91.32.3,LAB
+91.32.4,LAB
+91.32.5,LAB
+91.33.1,LAB
+91.33.2,LAB
+91.33.3,LAB
+91.33.4,LAB
+91.33.5,LAB
+91.34.1,LAB
+91.34.2,LAB
+91.34.3,LAB
+91.34.4,LAB
+91.34.5,LAB
+91.35.1,LAB
+91.35.2,LAB
+91.35.3,LAB
+91.35.4,LAB
+91.35.5,LAB
+91.36.1,LAB
+91.36.2,LAB
+91.36.3,LAB
+91.36.4,LAB
+91.36.5,LAB
+91.37.1,LAB
+91.37.2,LAB
+91.37.3,LAB
+91.37.4,LAB
+91.37.5,LAB
+91.38.1,LAB
+91.38.2,LAB
+91.38.3,LAB
+91.38.4,LAB
+91.38.5,LAB
+91.39.1,LAB
+91.39.2,LAB
+91.39.3,LAB
+91.39.4,LAB
+91.39.5,LAB
+91.40.1,LAB
+91.40.2,LAB
+91.40.3,LAB
+91.40.4,LAB
+91.40.5,LAB
+91.41.1,LAB
+91.41.2,LAB
+91.41.3,LAB
+91.41.4,LAB
+91.41.5,LAB
+91.42.1,LAB
+91.42.2,LAB
+91.42.3,LAB
+91.42.4,LAB
+91.42.5,LAB
+91.43.1,LAB
+91.43.2,LAB
+91.43.3,LAB
+91.43.4,LAB
+91.43.5,LAB
+91.44.1,LAB
+91.44.2,LAB
+91.44.3,LAB
+91.44.4,LAB
+91.44.5,LAB
+91.45.1,LAB
+91.45.2,LAB
+91.45.3,LAB
+91.45.4,LAB
+91.45.5,LAB
+91.46.1,LAB
+91.46.2,LAB
+91.46.3,LAB
+91.46.4,LAB
+91.46.5,LAB
+91.47.1,LAB
+91.47.2,LAB
+91.47.3,LAB
+91.47.4,LAB
+91.47.5,LAB
+91.48.1,LAB
+91.48.2,LAB
+91.48.3,LAB
+91.48.4,LAB
+91.48.5,LAB
+91.49.1,LAB
+91.49.2,LAB
+91.49.3,LAB
+91.50.1,LAB
+91.50.2,LAB
+91.50.3,LAB
+91.50.4,LAB
+91.50.5,LAB
+91.50.6,LAB
+91.50.7,LAB
+91.50.8,LAB
+91.50.9,LAB
+91.51.1,LAB
+91.51.2,LAB
+91.51.3,LAB
+91.51.4,LAB
+91.51.5,LAB
+91.51.6,LAB
+91.51.7,LAB
+91.51.8,LAB
+91.51.9,LAB
+91.52.1,LAB
+91.52.2,LAB
+91.52.3,LAB
+91.52.4,LAB
+91.52.5,LAB
+91.52.6,LAB
+91.52.7,LAB
+91.52.8,LAB
+91.52.9,LAB
+91.53.1,LAB
+91.53.2,LAB
+91.53.3,LAB
+91.53.4,LAB
+91.53.5,LAB
+91.53.6,LAB
+91.53.7,LAB
+91.53.8,LAB
+91.53.9,LAB
+91.54.1,LAB
+91.54.2,LAB
+91.54.3,LAB
+91.54.4,LAB
+91.54.5,LAB
+99.88,LAB
+89.15.2,INSTR
+89.15.3,INSTR
+89.15.4,INSTR
+89.15.5,INSTR
+89.15.6,INSTR
+89.15.7,INSTR
+89.15.8,INSTR
+89.15.9,INSTR
+89.17,INSTR
+89.18.1,INSTR
+89.18.2,INSTR
+89.19.1,INSTR
+89.19.2,INSTR
+89.22,INSTR
+89.24,INSTR
+89.25,INSTR
+89.32,INSTR
+89.32.1,INSTR
+89.37.1,INSTR
+89.37.2,INSTR
+89.37.3,INSTR
+89.37.4,INSTR
+89.37.5,INSTR
+89.37.6,INSTR
+89.38.1,INSTR
+89.38.2,INSTR
+89.38.3,INSTR
+89.38.4,INSTR
+89.38.5,INSTR
+89.38.6,INSTR
+89.38.7,INSTR
+45.24.1,INSTR
+45.25,INSTR
+45.25.1,INSTR
+45.29.4,INSTR
+45.42,INSTR
+45.42.1,INSTR
+45.43.1,INSTR
+46.85,INSTR
+48.23,INSTR
+48.24,INSTR
+48.29.1,INSTR
+48.35,INSTR
+43.41.1,INSTR
+43.41.2,INSTR
+44.19.1,INSTR
+45.13,INSTR
+45.16,INSTR
+45.23,INSTR
+45.23.1,INSTR
+45.23.2,INSTR
+45.23.3,INSTR
+45.24,INSTR
+89.38.8,INSTR
+89.38.9,INSTR
+89.39.5,INSTR
+89.41,INSTR
+89.42,INSTR
+89.43,INSTR
+89.44,INSTR
+89.44.1,INSTR
+89.44.2,INSTR
+89.48.1,INSTR
+89.5,INSTR
+89.52,INSTR
+89.54,INSTR
+89.59.1,INSTR
+89.61.1,INSTR
+89.65.2,INSTR
+89.65.3,INSTR
+89.65.4,INSTR
+89.65.5,INSTR
+89.65.6,INSTR
+75.34.1,INSTR
+68.12.1,INSTR
+31.42,INSTR
+31.42.1,INSTR
+31.42.2,INSTR
+31.43,INSTR
+31.48.1,INSTR
+31.48.2,INSTR
+33.22,INSTR
+33.24,INSTR
+49.21,INSTR
+49.31,INSTR
+56.31,INSTR
+57.32,INSTR
+57.33,INSTR
+57.39.1,INSTR
+57.39.2,INSTR
+58.22,INSTR
+64.19.1,INSTR
+88.72.1,INSTR
+88.72.2,INSTR
+88.72.3,INSTR
+88.72.4,INSTR
+88.72.5,INSTR
+88.79.4,INSTR
+89.11,INSTR
+89.12,INSTR
+89.14,INSTR
+89.14.1,INSTR
+89.14.2,INSTR
+89.14.3,INSTR
+89.14.4,INSTR
+89.14.5,INSTR
+89.15.1,INSTR
+98.03,INSTR
+98.05,INSTR
+98.15,INSTR
+98.18,INSTR
+20.31,INSTR
+20.39.1,INSTR
+95.13.2,INSTR
+95.14,INSTR
+95.15,INSTR
+95.17,INSTR
+95.2,INSTR
+95.21,INSTR
+95.22,INSTR
+95.23,INSTR
+95.23.1,INSTR
+95.24.1,INSTR
+95.24.2,INSTR
+95.25,INSTR
+95.26,INSTR
+95.35,INSTR
+95.41.1,INSTR
+95.41.2,INSTR
+95.41.3,INSTR
+95.41.4,INSTR
+95.42,INSTR
+95.43,INSTR
+95.44.1,INSTR
+95.44.2,INSTR
+95.45,INSTR
+95.46,INSTR
+95.47,INSTR
+95.48.1,INSTR
+95.48.2,INSTR
+95.48.3,INSTR
+95.48.4,INSTR
+95.49,INSTR
+9.19,INSTR
+95.03.1,INSTR
+95.05,INSTR
+95.06,INSTR
+95.07,INSTR
+95.07.1,INSTR
+95.09.1,INSTR
+95.09.2,INSTR
+95.09.3,INSTR
+95.11,INSTR
+95.11.1,INSTR
+95.12,INSTR
+95.12.1,INSTR
+95.13,INSTR
+95.13.1,INSTR
+93.02,INSTR
+93.08.1,INSTR
+93.08.2,INSTR
+93.08.3,INSTR
+93.08.4,INSTR
+93.08.5,INSTR
+93.08.6,INSTR
+93.08.7,INSTR
+93.08.8,INSTR
+93.09.1,INSTR
+93.09.2,INSTR
+42.29.2,INSTR
+42.33.2,INSTR
+92.27.5,PROC
+92.28.1,PROC
+92.28.2,PROC
+92.28.3,PROC
+92.28.4,PROC
+92.28.5,PROC
+92.28.6,PROC
+92.29.1,PROC
+92.29.2,PROC
+92.29.3,PROC
+92.29.4,PROC
+92.29.5,PROC
+92.29.6,PROC
+92.29.7,PROC
+92.29.8,PROC
+99.79.2,PROC
+99.85,PROC
+99.91,PROC
+99.94,PROC
+99.95,PROC
+99.97.1,PROC
+99.97.2,PROC
+24.70.1,PROC
+97.82,PROC
+98.01,PROC
+98.11,PROC
+98.12,PROC
+98.13,PROC
+98.14,PROC
+98.16,PROC
+98.17,PROC
+98.19,PROC
+98.2,PROC
+98.21,PROC
+98.22,PROC
+98.23,PROC
+98.24,PROC
+98.25,PROC
+98.26,PROC
+98.27,PROC
+98.28,PROC
+98.29,PROC
+98.5,PROC
+99.06.1,PROC
+99.07.1,PROC
+99.14.1,PROC
+99.23,PROC
+99.24.1,PROC
+99.24.2,PROC
+99.25,PROC
+99.29.1,PROC
+99.29.2,PROC
+99.29.3,PROC
+99.29.4,PROC
+99.29.5,PROC
+99.29.6,PROC
+99.29.8,PROC
+99.29.9,PROC
+99.71,PROC
+99.72,PROC
+99.73,PROC
+99.73.1,PROC
+99.74,PROC
+99.79.1,PROC
+92.11.3,PROC
+92.11.4,PROC
+92.21.1,PROC
+92.23.1,PROC
+92.23.2,PROC
+92.23.3,PROC
+92.24.1,PROC
+92.24.2,PROC
+92.24.3,PROC
+92.24.4,PROC
+92.24.5,PROC
+92.24.6,PROC
+92.25.1,PROC
+92.25.2,PROC
+92.27.1,PROC
+92.27.2,PROC
+92.27.3,PROC
+92.27.4,PROC
+15,PROC
+15.1,PROC
+15.2,PROC
+15.3,PROC
+15.4,PROC
+15.5,PROC
+15.6,PROC
+15.7,PROC
+15.9,PROC
+16.22,PROC
+16.91,PROC
+18.02,PROC
+18.12,PROC
+18.21,PROC
+18.29,PROC
+18.31,PROC
+20,PROC
+20.32.1,PROC
+20.8,PROC
+21.01,PROC
+21.02,PROC
+21.03,PROC
+21.22,PROC
+21.31,PROC
+21.71,PROC
+21.88,PROC
+21.91,PROC
+22.01,PROC
+22.71,PROC
+23.01,PROC
+23.09,PROC
+23.11,PROC
+23.19,PROC
+23.2,PROC
+23.20.1,PROC
+23.20.2,PROC
+23.20.3,PROC
+23.3,PROC
+23.41,PROC
+23.41.1,PROC
+23.41.2,PROC
+23.41.3,PROC
+23.41.4,PROC
+23.42,PROC
+23.43.1,PROC
+23.43.2,PROC
+23.43.3,PROC
+23.49.1,PROC
+23.5,PROC
+23.6,PROC
+23.71.1,PROC
+23.71.2,PROC
+23.73,PROC
+24.00.1,PROC
+24.11,PROC
+24.12,PROC
+24.19.1,PROC
+24.20.1,PROC
+24.31,PROC
+24.39.1,PROC
+24.39.2,PROC
+24.4,PROC
+96.17,PROC
+96.18,PROC
+96.22,PROC
+96.26,PROC
+96.27,PROC
+96.49,PROC
+96.51,PROC
+96.52,PROC
+96.54.1,PROC
+96.54.2,PROC
+96.54.3,PROC
+96.57,PROC
+96.59,PROC
+97.29.1,PROC
+97.35,PROC
+97.71,PROC
+13.1,PROC
+13.64,PROC
+13.7,PROC
+13.71,PROC
+13.72,PROC
+13.72.1,PROC
+14.22,PROC
+14.24.1,PROC
+14.24.2,PROC
+14.24.3,PROC
+14.29.1,PROC
+14.31,PROC
+14.32,PROC
+14.33,PROC
+14.34,PROC
+14.4,PROC
+14.59.1,PROC
+14.79.1,PROC
+8.82,PROC
+8.83,PROC
+8.84,PROC
+8.91,PROC
+8.92,PROC
+08.99.1,PROC
+9,PROC
+9.11,PROC
+9.12,PROC
+9.21,PROC
+9.41,PROC
+9.42,PROC
+9.43,PROC
+9.51,PROC
+9.52,PROC
+9.53,PROC
+9.59,PROC
+12.64.1,PROC
+12.64.2,PROC
+12.66,PROC
+12.69,PROC
+12.7,PROC
+12.89.1,PROC
+12.89.2,PROC
+12.91,PROC
+86.30.3,PROC
+86.30.4,PROC
+86.4,PROC
+86.59.1,PROC
+86.59.2,PROC
+86.59.3,PROC
+86.6,PROC
+86.61,PROC
+86.62,PROC
+86.71,PROC
+86.72,PROC
+86.73,PROC
+86.74,PROC
+86.75,PROC
+86.81,PROC
+86.84,PROC
+93.56.3,PROC
+93.56.4,PROC
+93.56.5,PROC
+93.56.6,PROC
+93.56.7,PROC
+93.57.1,PROC
+93.91,PROC
+93.95,PROC
+93.54.2,PROC
+93.54.3,PROC
+93.54.4,PROC
+93.54.5,PROC
+93.54.6,PROC
+93.54.7,PROC
+93.54.8,PROC
+93.56.1,PROC
+93.56.2,PROC
+10.33,PROC
+10.4,PROC
+10.6,PROC
+10.91,PROC
+11.31,PROC
+11.32,PROC
+11.39,PROC
+11.42,PROC
+11.43,PROC
+11.6,PROC
+11.62.1,PROC
+11.62.2,PROC
+11.75.1,PROC
+11.91,PROC
+11.99.1,PROC
+11.99.2,PROC
+11.99.3,PROC
+11.99.4,PROC
+11.99.5,PROC
+12.14,PROC
+12.4,PROC
+12.41,PROC
+12.5,PROC
+12.59,PROC
+3.8,PROC
+3.91,PROC
+3.92,PROC
+04.07.1,PROC
+04.11.1,PROC
+4.43,PROC
+4.44,PROC
+04.81.1,PROC
+04.81.2,PROC
+5.31,PROC
+5.32,PROC
+6.01,PROC
+06.11.1,PROC
+06.11.2,PROC
+6.13,PROC
+8.01,PROC
+8.02,PROC
+8.09,PROC
+8.11,PROC
+8.21,PROC
+8.22,PROC
+8.23,PROC
+8.24,PROC
+8.25,PROC
+8.41,PROC
+8.42,PROC
+8.43,PROC
+8.44,PROC
+8.52,PROC
+8.6,PROC
+8.81,PROC
+79.03,PROC
+79.04,PROC
+79.07,PROC
+79.08,PROC
+79.7,PROC
+79.71,PROC
+79.72,PROC
+79.73,PROC
+79.74,PROC
+80.3,PROC
+81.91,PROC
+81.92,PROC
+82.91,PROC
+83.02,PROC
+83.03,PROC
+83.09,PROC
+83.21,PROC
+83.21.1,PROC
+83.31,PROC
+83.98,PROC
+85,PROC
+85.11,PROC
+85.11.1,PROC
+85.2,PROC
+85.21,PROC
+85.21.1,PROC
+85.53,PROC
+85.94,PROC
+86.01,PROC
+86.02.1,PROC
+86.02.2,PROC
+86.03,PROC
+86.04,PROC
+86.05.1,PROC
+86.11,PROC
+86.22,PROC
+86.23,PROC
+86.24,PROC
+86.25,PROC
+86.27,PROC
+86.28,PROC
+86.30.1,PROC
+86.30.2,PROC
+9.6,PROC
+9.71,PROC
+9.73,PROC
+10.21,PROC
+10.31,PROC
+10.32,PROC
+93.51,PROC
+93.52,PROC
+93.53,PROC
+93.54.1,PROC
+41.31,PROC
+42.29.1,PROC
+89.62,PROC
+69.92.2,PROC
+69.92.3,PROC
+69.92.4,PROC
+70.11.1,PROC
+70.21,PROC
+70.24,PROC
+70.29.1,PROC
+70.33.1,PROC
+71.11,PROC
+71.22,PROC
+71.30.1,PROC
+71.90.1,PROC
+75.10.1,PROC
+75.10.2,PROC
+75.10.3,PROC
+75.33.1,PROC
+75.8,PROC
+76.01,PROC
+76.2,PROC
+76.77,PROC
+76.92.1,PROC
+76.93,PROC
+76.96,PROC
+77.56,PROC
+78.7,PROC
+79,PROC
+79.01,PROC
+79.02,PROC
+68.16.1,PROC
+68.2,PROC
+68.29.1,PROC
+69.09,PROC
+69.7,PROC
+69.92,PROC
+24.70.3,PROC
+24.70.4,PROC
+24.80.1,PROC
+25.01,PROC
+25.91,PROC
+25.92,PROC
+26,PROC
+26.11,PROC
+26.91,PROC
+27.21,PROC
+27.23,PROC
+27.24,PROC
+27.41,PROC
+27.49.1,PROC
+27.51,PROC
+27.52,PROC
+27.71,PROC
+27.91,PROC
+28.00.1,PROC
+29.12,PROC
+34.24,PROC
+34.91,PROC
+34.91.1,PROC
+34.92,PROC
+38.59.1,PROC
+38.89,PROC
+38.93,PROC
+38.94,PROC
+38.95,PROC
+38.98,PROC
+38.99.1,PROC
+38.99.2,PROC
+39.27.1,PROC
+39.4,PROC
+39.43,PROC
+39.92,PROC
+39.95.1,PROC
+39.95.2,PROC
+39.95.3,PROC
+39.95.4,PROC
+39.95.5,PROC
+39.95.6,PROC
+39.95.7,PROC
+39.95.8,PROC
+39.95.9,PROC
+39.99.1,PROC
+40.11,PROC
+40.19.1,PROC
+40.19.2,PROC
+49.11,PROC
+49.23,PROC
+49.39,PROC
+49.42,PROC
+49.45,PROC
+49.46,PROC
+49.47,PROC
+49.59,PROC
+50.11,PROC
+50.19.1,PROC
+50.91,PROC
+51.12,PROC
+54.21,PROC
+54.22,PROC
+54.24,PROC
+54.24.1,PROC
+54.91,PROC
+54.91.1,PROC
+54.93,PROC
+54.97,PROC
+54.98.1,PROC
+54.98.2,PROC
+55.92,PROC
+57.17,PROC
+57.49.1,PROC
+57.94,PROC
+58.23,PROC
+58.31,PROC
+58.47,PROC
+58.5,PROC
+58.60.1,PROC
+58.60.2,PROC
+58.60.3,PROC
+59.8,PROC
+60,PROC
+60.11,PROC
+60.11.1,PROC
+60.13,PROC
+60.91,PROC
+61,PROC
+61.91,PROC
+62.11,PROC
+63.52,PROC
+63.71,PROC
+64,PROC
+64.11,PROC
+64.2,PROC
+64.92.1,PROC
+64.93,PROC
+65.91,PROC
+66.8,PROC
+67.12,PROC
+67.19.1,PROC
+67.32,PROC
+67.33,PROC
+88.73.6,PROC
+88.73.7,PROC
+24.70.2,PROC
+89.23,PROC
+49.01,PROC
+49.02,PROC
diff --git a/src/org/ohdsi/whiteRabbit/etls/ars/specialty_italian.csv b/src/org/ohdsi/whiteRabbit/etls/ars/specialty_italian.csv
new file mode 100644
index 00000000..7663abf4
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/etls/ars/specialty_italian.csv
@@ -0,0 +1,56 @@
+COD,DESCRIZIONE,CONCEPT_CODE,CONCEPT_ID,CONCEPT_NAME
+001,Allergologia,3,38004448,Allergy/Immunology
+003,Anatomia ed istologia patologica,246RM2200X,38004144,"Technologists, Technicians & Other Technical Service Providers, Technician, Pathology, Medical Laboratory"
+006,Cardiochirurgia pediatrica,78,38004497,Cardiac Surgery
+007,Cardiochirurgia,78,38004497,Cardiac Surgery
+008,Cardiologia,6,38004451,Cardiology
+009,Chirurgia generale,2,38004447,General Surgery
+010,Chirurgia maxillo facciale,85,38004504,Maxillofacial Surgery
+012,Chirurgia plastica,24,38004467,Plastic And Reconstructive Surgery
+013,Chirurgia toracica,33,38004473,Thoracic Surgery
+014,Chirurgia vascolare,77,38004496,Vascular Surgery
+018,Ematologia,246QH0000X,38004134,"Technologists, Technicians & Other Technical Service Providers, Spec/Tech, Pathology, Hematology"
+020,Immunologia,3,38004448,Allergy/Immunology
+021,Geriatria,38,38004478,Geriatric Medicine
+024,Malattie infettive e tropicali,44,38004484,Infectious Disease
+025,Medicina del lavoro,67,38004492,Occupational Therapy
+026,Medicina generale,1,38004446,General Practice
+027,Medicina legale,173000000X,38003790,"Other Service Providers, Legal Medicine"
+029,Nefrologia,39,38004479,Nephrology
+030,Neurochirurgia,14,38004459,Neurosurgery
+032,Neurologia,13,38004458,Neurology
+033,Neuropsichiatria infantile,86,38004505,Neuropsychiatry
+034,Oculistica,18,38004463,Ophthalmology
+035,Odontoiatria e stomatologia,1223G0001X,38003675,"Dental Providers, Dentist, General Practice"
+036,Ortopedia e traumatologia,20,38004465,Orthopedic Surgery
+037,Ostetricia e ginecologia,16,38004461,Obstetrics/Gynecology
+038,Otorinolaringoiatria,4,38004449,Otolaryngology
+039,Pediatria,37,38004477,Pediatric Medicine
+040,Psichiatria,26,38004469,Psychiatry
+043,Urologia,34,38004474,Urology
+048,Nefrologia (abilitazione trapianto rene),39,38004479,Nephrology
+049,Terapia intensiva,81,38004500,Critical care (intensivist)
+052,Dermatologia,7,38004452,Dermatology
+058,Gastroenterologia,10,38004455,Gastroenterology
+061,Medicina nucleare,36,38004476,Nuclear Medicine
+064,Oncologia,90,38004507,Medical Oncology
+065,Oncologia pediatrica,90,38004507,Medical Oncology
+066,Oncoematologia,83,38004502,Hematology/Oncology
+068,Pneumologia,29,38004472,Pulmonary Disease
+069,Radiologia,30,38004675, Physician/Diagnostic Radiology
+070,Radioterapia,94,38004511,Interventional Radiology
+071,Reumatologia,66,38004491,Rheumatology
+074,Radioterapia oncologica,92,38004509,Radiation Oncology
+076,Neurochirurgia pediatrica,14,38004459,Neurosurgery
+078,Urologia pediatrica,39,38004479,Nephrology
+502,Cardiologia pediatrica,6,38004451,Cardiology
+503,Chirurgia ricostruttiva della mano,24,38004467,Plastic And Reconstructive Surgery
+509,Genetica medica,170100000X,38003775,"Other Service Providers, Medical Genetics, Ph.D. Medical Genetics"
+510,Genetica medica pediatrica,170100000X,38003775,"Other Service Providers, Medical Genetics, Ph.D. Medical Genetics"
+513,Malattie infettive pediatriche,44,38004484,Infectious Disease
+514,Neuroradiologia,30,38004675, Physician/Diagnostic Radiology
+515,Psicologia,68,38004493,Clinical Psychology
+521,Laboratorio di immunologia e allergologia,3,38004448,Allergy/Immunology
+522,Medicina e chirurgia di accettazione e d'urgenza,93,38004510,Emergency Medicine
+523,Microbiologia,246QM0900X,38004141,"Technologists, Technicians & Other Technical Service Providers, Spec/Tech, Pathology, Microbiology"
+526,Anestesia,5,38004450,Anesthesiology
\ No newline at end of file
diff --git a/src/org/ohdsi/whiteRabbit/etls/hcup/HCUPETL.java b/src/org/ohdsi/whiteRabbit/etls/hcup/HCUPETL.java
new file mode 100644
index 00000000..9cae0aa4
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/etls/hcup/HCUPETL.java
@@ -0,0 +1,455 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.etls.hcup;
+
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.ohdsi.databases.DbType;
+import org.ohdsi.databases.RichConnection;
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.utilities.collections.OneToManyList;
+import org.ohdsi.utilities.files.ReadCSVFileWithHeader;
+import org.ohdsi.utilities.files.Row;
+import org.ohdsi.whiteRabbit.DbSettings;
+import org.ohdsi.whiteRabbit.EtlReport;
+import org.ohdsi.whiteRabbit.cdm.CDMV4NullableChecker;
+import org.ohdsi.whiteRabbit.cdm.CdmV4;
+import org.ohdsi.whiteRabbit.utilities.CodeToConceptMap;
+import org.ohdsi.whiteRabbit.utilities.ETLUtils;
+import org.ohdsi.whiteRabbit.utilities.QCSampleConstructor;
+
+public class HCUPETL {
+
+ public static int BATCH_SIZE = 10000;
+ public static String[] diagnoseFields = new String[] { "DX1", "DX2", "DX3", "DX4", "DX5", "DX6", "DX7", "DX8", "DX9", "DX10",
+ "DX11", "DX12", "DX13", "DX14", "DX15", "DX16", "DX17", "DX18", "DX19", "DX20", "DX21", "DX22", "DX23", "DX24", "DX25", "ECODE1", "ECODE2" };
+ public static String[] procedureFields = new String[] { "PR1", "PR2", "PR3", "PR4", "PR5", "PR6", "PR7", "PR8", "PR9", "PR10",
+ "PR11", "PR12", "PR13", "PR14", "PR15" };
+ public static String[] procedureDayFields = new String[] { "PRDAY1", "PRDAY2", "PRDAY3", "PRDAY4", "PRDAY5", "PRDAY6", "PRDAY7",
+ "PRDAY8", "PRDAY9", "PRDAY10", "PRDAY11", "PRDAY12", "PRDAY13", "PRDAY14", "PRDAY15" };
+ public static int[] diagnoseFieldConceptIds = new int[] { 38000184, 38000185, 38000186, 38000187, 38000188, 38000189, 38000190,
+ 38000191, 38000192, 38000193, 38000194, 38000195, 38000196, 38000197, 38000198, 38000198, 380001980, 38000198, 38000198, 38000198, 38000198,
+ 38000198, 38000198, 38000198, 38000198, 38000184, 38000185 };
+
+ public static int[] procedureFieldConceptIds = new int[] { 38000251, 38000252, 38000253, 38000254, 38000255, 38000256, 38000257,
+ 38000258, 38000259, 38000260, 38000261, 38000262, 38000263, 38000264, 38000265 };
+
+ private RichConnection sourceConnection;
+ private RichConnection targetConnection;
+ private QCSampleConstructor qcSampleConstructor;
+ private EtlReport etlReport;
+ private CDMV4NullableChecker cdmv4NullableChecker = new CDMV4NullableChecker();
+ private OneToManyList tableToRows;
+ private long personCount;
+ private long observationPeriodId;
+ private Integer locationId;
+ private long drugExposureId;
+ private long conditionOccurrenceId;
+ private long visitOccurrenceId;
+ private long procedureOccurrenceId;
+ private long procedureCostId;
+ private long visitStartDate;
+ private long visitEndDate;
+ private long primaryProcedureOccurrenceId;
+
+ private Map stateCountyToLocationId;
+ private Set careSiteIds;
+
+ private Map codeToCounty;
+ private CodeToConceptMap icd9ToConcept;
+ private CodeToConceptMap icd9ToRxNorm;
+ private CodeToConceptMap icd9ProcToConcept;
+ private CodeToConceptMap drgToConcept;
+
+ public void process(String folder, DbSettings sourceDbSettings, DbSettings targetDbSettings, int maxPersons) {
+ // Hardcode vocab server for now:
+ DbSettings vocabDbSettings = new DbSettings();
+ vocabDbSettings.database = "vocabulary";
+ vocabDbSettings.dataType = DbSettings.DATABASE;
+ vocabDbSettings.server = "127.0.0.1";
+ vocabDbSettings.dbType = DbType.MYSQL;
+ vocabDbSettings.user = "root";
+ vocabDbSettings.password = "F1r3starter";
+
+ if (ETLUtils.databaseAlreadyExists(targetDbSettings))
+ return;
+ CdmV4.createStructure(targetDbSettings);
+
+ sourceConnection = new RichConnection(sourceDbSettings.server, sourceDbSettings.domain, sourceDbSettings.user, sourceDbSettings.password,
+ sourceDbSettings.dbType);
+ sourceConnection.setContext(this.getClass());
+ sourceConnection.use(sourceDbSettings.database);
+
+ targetConnection = new RichConnection(targetDbSettings.server, targetDbSettings.domain, targetDbSettings.user, targetDbSettings.password,
+ targetDbSettings.dbType);
+ targetConnection.setContext(this.getClass());
+ targetConnection.use(targetDbSettings.database);
+
+ loadMappings(vocabDbSettings);
+
+ QCSampleConstructor.sampleProbability = 0.000001;
+ qcSampleConstructor = new QCSampleConstructor(folder + "/sample");
+ tableToRows = new OneToManyList();
+ etlReport = new EtlReport(folder);
+ stateCountyToLocationId = new HashMap();
+ careSiteIds = new HashSet();
+ personCount = 0;
+ drugExposureId = 0;
+ conditionOccurrenceId = 0;
+ visitOccurrenceId = 0;
+ procedureOccurrenceId = 0;
+ procedureCostId = 0;
+ observationPeriodId = 0;
+
+ StringUtilities.outputWithTime("Processing persons");
+ for (Row row : sourceConnection.query("SELECT * FROM core")) {
+ processPerson(row);
+ if (personCount == maxPersons) {
+ System.out.println("Reached limit of " + maxPersons + " persons, terminating");
+ break;
+ }
+ if (personCount % BATCH_SIZE == 0) {
+ insertBatch();
+ System.out.println("Processed " + personCount + " persons");
+ }
+ }
+ insertBatch();
+ System.out.println("Processed " + personCount + " persons");
+ CdmV4.createIndices(targetDbSettings);
+ qcSampleConstructor.addCdmData(targetDbSettings, vocabDbSettings);
+ String etlReportName = etlReport.generate(drgToConcept, icd9ProcToConcept, icd9ToConcept, icd9ToRxNorm);
+ System.out.println("An ETL report was generated and written to :" + etlReportName);
+ if (etlReport.getTotalProblemCount() > 0) {
+ String etlProblemListname = etlReport.generateProblemList();
+ System.out.println("An ETL problem list was generated and written to :" + etlProblemListname);
+ }
+ StringUtilities.outputWithTime("Finished ETL");
+ }
+
+ private void processPerson(Row row) {
+ etlReport.registerIncomingData("core", row);
+
+ personCount++;
+ visitOccurrenceId++;
+ observationPeriodId++;
+ primaryProcedureOccurrenceId = -1;
+ visitStartDate = computeVisitStartDate(row.get("YEAR"), row.get("AMONTH"), row.get("AWEEKEND"));
+ visitEndDate = computeVisitEndDate(visitStartDate, row.get("LOS"));
+
+ qcSampleConstructor.registerPersonData("core", row, row.getLong("KEY"));
+
+ addToLocation(row);
+ addToCareSite(row);
+ addToVisitOccurrence(row);
+ addToObservationPeriod(row);
+ addToPerson(row);
+ addToConditionOccurrence(row);
+ addToDeath(row);
+ addToDrugExposure(row);
+ addToProcedureOccurrence(row);
+ addToProcedureCost(row);
+ }
+
+ private void addToLocation(Row row) {
+ String stateCounty = row.get("HOSPST") + "\t" + (row.get("HOSPSTCO").equals("-9999") ? "" : row.get("HOSPSTCO"));
+ locationId = stateCountyToLocationId.get(stateCounty);
+ if (locationId == null) {
+ locationId = stateCountyToLocationId.size() + 1;
+ stateCountyToLocationId.put(stateCounty, locationId);
+
+ Row location = new Row();
+ location.add("location_id", locationId);
+ location.add("state", row.get("HOSPST"));
+ String county = codeToCounty.get(row.get("HOSPSTCO"));
+ if (county == null)
+ county = "";
+ if (county.length() > 20)
+ county = county.substring(0, 20); // County field in CDM limited to 20 chars
+ location.add("county", county);
+ location.add("location_source_value", row.get("HOSPSTCO"));
+ tableToRows.put("location", location);
+ }
+ }
+
+ private void addToCareSite(Row row) {
+ if (careSiteIds.add(row.getInt("HOSPID"))) {
+ Row careSite = new Row();
+ careSite.add("care_site_id", row.get("HOSPID"));
+ careSite.add("care_site_source_value", row.get("HOSPID"));
+ careSite.add("location_id", locationId);
+ tableToRows.put("care_site", careSite);
+ }
+ }
+
+ private void addToVisitOccurrence(Row row) {
+ Row visitOccurrence = new Row();
+ visitOccurrence.add("person_id", row.get("KEY"));
+ visitOccurrence.add("visit_occurrence_id", visitOccurrenceId);
+ visitOccurrence.add("visit_start_date", StringUtilities.daysToDatabaseDateString(visitStartDate));
+ visitOccurrence.add("visit_end_date", StringUtilities.daysToDatabaseDateString(visitEndDate));
+ visitOccurrence.add("care_site_id", row.get("HOSPID"));
+ visitOccurrence.add("place_of_service_concept_id", 9201); // Inpatient visit
+ tableToRows.put("visit_occurrence", visitOccurrence);
+ }
+
+ private void addToObservationPeriod(Row row) {
+ Row observationPeriod = new Row();
+ observationPeriod.add("observation_period_id", observationPeriodId);
+ observationPeriod.add("person_id", row.get("KEY"));
+ observationPeriod.add("observation_period_start_date", StringUtilities.daysToDatabaseDateString(visitStartDate));
+ observationPeriod.add("observation_period_end_date", StringUtilities.daysToDatabaseDateString(visitEndDate));
+ tableToRows.put("observation_period", observationPeriod);
+ }
+
+ private void addToPerson(Row row) {
+ if (row.getInt("AGE") < 0 || (row.getInt("AGE") == 0 && row.getInt("AGEDAY") < 0)) { // No age specified. Cannot create person, since birth year is
+ // required field
+ etlReport.reportProblem("Person", "No age specified so cannot create row", row.get("KEY"));
+ return;
+ }
+
+ Row person = new Row();
+ person.add("person_id", row.get("KEY"));
+ person.add("person_source_value", row.get("KEY"));
+ person.add("gender_source_value", row.get("FEMALE"));
+ person.add("gender_concept_id", row.get("FEMALE").equals("1") ? "8532" : row.get("FEMALE").equals("0") ? "8507" : "8551");
+
+ if (row.getInt("AGE") > 0) {
+ int yearOfBirth = Integer.parseInt(StringUtilities.daysToCalendarYear(visitStartDate)) - row.getInt("AGE");
+ person.add("year_of_birth", yearOfBirth);
+ person.add("month_of_birth", "");
+ person.add("day_of_birth", "");
+
+ } else if (row.getInt("AGEDAY") >= 0) {
+ long dateOfBirth = visitStartDate - row.getInt("AGEDAY");
+ person.add("year_of_birth", StringUtilities.daysToCalendarYear(dateOfBirth));
+ person.add("month_of_birth", StringUtilities.daysToCalendarMonth(dateOfBirth));
+ person.add("day_of_birth", StringUtilities.daysToCalendarDayOfMonth(dateOfBirth));
+ } else {
+ person.add("year_of_birth", "");
+ person.add("month_of_birth", "");
+ person.add("day_of_birth", "");
+ }
+
+ person.add("race_source_value", row.get("RACE"));
+ if (row.get("RACE").equals("1")) // White
+ person.add("race_concept_id", "8527");
+ else if (row.get("RACE").equals("2")) // Black
+ person.add("race_concept_id", "8516");
+ else if (row.get("RACE").equals("4")) // Pacific islander
+ person.add("race_concept_id", "8557");
+ else if (row.get("RACE").equals("5")) // Native American
+ person.add("race_concept_id", "8657");
+ else if (row.get("RACE").equals("3")) // Hispanic, should be coded as 'other'
+ person.add("race_concept_id", "8522");
+ else if (row.get("RACE").equals("6")) // Other
+ person.add("race_concept_id", "8522");
+ else
+ person.add("race_concept_id", "");
+
+ if (row.get("RACE").equals("3")) {// Hispanic
+ person.add("ethnicity_source_value", "3");
+ person.add("ethnicity_concept_id", "38003563");
+ } else {
+ person.add("ethnicity_source_value", "");
+ person.add("ethnicity_concept_id", "");
+ }
+
+ tableToRows.put("person", person);
+ }
+
+ private void addToConditionOccurrence(Row row) {
+ for (int i = 0; i < diagnoseFields.length; i++)
+ if (row.get(diagnoseFields[i]).trim().length() != 0) {
+ Row conditionOccurrence = new Row();
+ conditionOccurrence.add("person_id", row.get("KEY"));
+ conditionOccurrence.add("condition_occurrence_id", ++conditionOccurrenceId);
+ conditionOccurrence.add("condition_source_value", row.get(diagnoseFields[i]));
+ conditionOccurrence.add("condition_concept_id", icd9ToConcept.getConceptId(row.get(diagnoseFields[i]).trim()));
+ conditionOccurrence.add("condition_type_concept_id", diagnoseFieldConceptIds[i]);
+ conditionOccurrence.add("condition_start_date", StringUtilities.daysToDatabaseDateString(visitStartDate));
+ conditionOccurrence.add("visit_occurrence_id", visitOccurrenceId);
+ tableToRows.put("condition_occurrence", conditionOccurrence);
+ }
+ }
+
+ private void addToDeath(Row row) {
+ if (row.get("DIED").equals("1")) {
+ Row death = new Row();
+ death.add("person_id", row.get("KEY"));
+ death.add("death_date", StringUtilities.daysToDatabaseDateString(visitEndDate));
+ death.add("death_type_concept_id", 38003566); // EHR record patient status "Deceased"
+ tableToRows.put("death", death);
+ }
+ }
+
+ private void addToDrugExposure(Row row) {
+ for (int i = 0; i < procedureFields.length; i++)
+ if (row.get(procedureFields[i]).trim().length() != 0) {
+ int conceptId = icd9ToRxNorm.getConceptId(row.get(procedureFields[i]).trim());
+ if (conceptId != 0) {
+ Row drugExposure = new Row();
+ drugExposure.add("drug_exposure_id", ++drugExposureId);
+ drugExposure.add("person_id", row.get("KEY"));
+ int day = row.getInt(procedureDayFields[i]);
+ if (day < 0)
+ day = 0;
+ drugExposure.add("drug_exposure_start_date", StringUtilities.daysToDatabaseDateString(visitStartDate + day));
+ drugExposure.add("drug_source_value", row.get(procedureFields[i]));
+ drugExposure.add("drug_concept_id", conceptId);
+ drugExposure.add("drug_type_concept_id", 38000179); // Physician administered drug (identified as procedure)
+ drugExposure.add("visit_occurrence_id", visitOccurrenceId);
+ tableToRows.put("drug_exposure", drugExposure);
+ }
+ }
+ }
+
+ private void addToProcedureOccurrence(Row row) {
+ for (int i = 0; i < procedureFields.length; i++)
+ if (row.get(procedureFields[i]).trim().length() != 0) {
+ Row procedureOccurrence = new Row();
+ procedureOccurrence.add("procedure_occurrence_id", ++procedureOccurrenceId);
+ procedureOccurrence.add("person_id", row.get("KEY"));
+ int day = row.getInt(procedureDayFields[i]);
+ if (day < 0)
+ day = 0;
+ procedureOccurrence.add("procedure_date", StringUtilities.daysToDatabaseDateString(visitStartDate + day));
+ procedureOccurrence.add("procedure_source_value", row.get(procedureFields[i]));
+ procedureOccurrence.add("procedure_concept_id", icd9ProcToConcept.getConceptId(row.get(procedureFields[i]).trim()));
+ procedureOccurrence.add("procedure_type_concept_id", procedureFieldConceptIds[i]);
+ procedureOccurrence.add("visit_occurrence_id", visitOccurrenceId);
+ tableToRows.put("procedure_occurrence", procedureOccurrence);
+
+ if (procedureFields[i].equals("PR1"))
+ primaryProcedureOccurrenceId = procedureOccurrenceId;
+ }
+ }
+
+ private void addToProcedureCost(Row row) {
+ if (primaryProcedureOccurrenceId != -1) {
+ Row procedureCost = new Row();
+ procedureCost.add("procedure_occurrence_id", primaryProcedureOccurrenceId);
+ procedureCost.add("procedure_cost_id", ++procedureCostId);
+ procedureCost.add("disease_class_source_value", row.get("DRG"));
+ procedureCost.add("disease_class_concept_id", drgToConcept.getConceptId(row.get("DRG").trim()));
+ tableToRows.put("procedure_cost", procedureCost);
+ }
+ }
+
+ private long computeVisitStartDate(String year, String amonth, String aweekend) {
+ if (Integer.parseInt(amonth) < 1)
+ amonth = "1";
+ boolean isWeekend = aweekend.equals("1");
+ Calendar calendar = Calendar.getInstance();
+ calendar.set(Integer.parseInt(year), Integer.parseInt(amonth) - 1, 1);
+ while (isWeekend(calendar) != isWeekend)
+ calendar.add(Calendar.DATE, 1);
+ long time = calendar.getTimeInMillis();
+ time += calendar.getTimeZone().getOffset(time);
+ return (((StringUtilities.MILLENIUM + time) / StringUtilities.DAY) - (1000 * 365));
+ }
+
+ private long computeVisitEndDate(long visitStartDate, String los) {
+ int lengthOfStay = Integer.parseInt(los);
+ if (lengthOfStay < 0)
+ lengthOfStay = 0;
+ return visitStartDate + lengthOfStay;
+ }
+
+ private boolean isWeekend(Calendar calendar) {
+ int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
+ return (dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY);
+ }
+
+ private void insertBatch() {
+ // addToDrugEra();
+ // addToConditionEra();
+ removeRowsWithNonNullableNulls();
+
+ etlReport.registerOutgoingData(tableToRows);
+ for (String table : tableToRows.keySet())
+ targetConnection.insertIntoTable(tableToRows.get(table).iterator(), table, false);
+ tableToRows.clear();
+ }
+
+ private void loadMappings(DbSettings dbSettings) {
+ StringUtilities.outputWithTime("Loading mappings from server");
+ RichConnection connection = new RichConnection(dbSettings.server, dbSettings.domain, dbSettings.user, dbSettings.password, dbSettings.dbType);
+
+ connection.use("vocabulary");
+
+ System.out.println("- Loading ICD-9 to SNOMED concept_id mapping");
+ icd9ToConcept = new CodeToConceptMap("ICD-9 to SNOMED concept_id mapping");
+ String query = "SELECT source_code,source_code_description,target_concept_id,concept_code,concept_name FROM source_to_concept_map INNER JOIN concept ON target_concept_id = concept_id WHERE source_vocabulary_id = 2 AND target_vocabulary_id = 1 AND concept_class='Clinical finding'";
+ for (Row row : connection.query(query))
+ icd9ToConcept.add(row.get("SOURCE_CODE").replace(".", ""), row.get("SOURCE_CODE_DESCRIPTION"), row.getInt("TARGET_CONCEPT_ID"),
+ row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"));
+
+ System.out.println("- Loading ICD-9 to RxNorm concept_id mapping");
+ icd9ToRxNorm = new CodeToConceptMap("ICD-9 to RxNorm concept_id mapping");
+ query = "SELECT DISTINCT source_code,source_code_description,target_concept_id,concept_code,concept_name FROM source_to_concept_map INNER JOIN concept ON target_concept_id = concept_id WHERE target_vocabulary_id = 8 AND source_vocabulary_id in (3,4,5) AND primary_map = 'Y' AND source_to_concept_map.invalid_reason != 'D'";
+ for (Row row : connection.query(query))
+ icd9ToRxNorm.add(row.get("SOURCE_CODE").replace(".", ""), row.get("SOURCE_CODE_DESCRIPTION"), row.getInt("TARGET_CONCEPT_ID"),
+ row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"));
+
+ System.out.println("- Loading ICD-9 Procedure to concept_id mapping");
+ icd9ProcToConcept = new CodeToConceptMap("ICD-9 Procedure to concept_id mapping");
+ query = "SELECT concept_id,concept_name,concept_code FROM concept WHERE vocabulary_id = 3";
+ for (Row row : connection.query(query))
+ icd9ProcToConcept.add(row.get("CONCEPT_CODE").replace(".", ""), row.get("CONCEPT_NAME"), row.getInt("CONCEPT_ID"), row.get("CONCEPT_CODE"),
+ row.get("CONCEPT_NAME"));
+
+ System.out.println("- Loading DRG to concept_id mapping");
+ drgToConcept = new CodeToConceptMap("DRG to concept_id mapping");
+ query = "SELECT concept_id,concept_name,concept_code FROM concept WHERE vocabulary_id = 40 AND concept_class = 'DRG'";
+ for (Row row : connection.query(query))
+ drgToConcept.add(row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"), row.getInt("CONCEPT_ID"), row.get("CONCEPT_CODE"), row.get("CONCEPT_NAME"));
+
+ System.out.println("- Loading county code to name mapping");
+ codeToCounty = new HashMap();
+ for (Row row : new ReadCSVFileWithHeader(this.getClass().getResourceAsStream("national_county.txt")))
+ codeToCounty.put(row.get("State ANSI") + row.get("County ANSI"), row.get("County Name"));
+
+ StringUtilities.outputWithTime("Finished loading mappings");
+ }
+
+ private void removeRowsWithNonNullableNulls() {
+ for (String table : tableToRows.keySet()) {
+ Iterator iterator = tableToRows.get(table).iterator();
+ while (iterator.hasNext()) {
+ Row row = iterator.next();
+ String nonAllowedNullField = cdmv4NullableChecker.findNonAllowedNull(table, row);
+ if (nonAllowedNullField != null) {
+ if (row.getFieldNames().contains("person_id"))
+ etlReport.reportProblem(table, "Column " + nonAllowedNullField + " is null, could not create row", row.get("person_id"));
+ else
+ etlReport.reportProblem(table, "Column " + nonAllowedNullField + " is null, could not create row", "");
+ iterator.remove();
+ }
+ }
+ }
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/etls/hcup/national_county.txt b/src/org/ohdsi/whiteRabbit/etls/hcup/national_county.txt
new file mode 100644
index 00000000..530f8b25
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/etls/hcup/national_county.txt
@@ -0,0 +1,3236 @@
+State,State ANSI,County ANSI,County Name,ANSI Cl
+AL,01,001,Autauga County,H1
+AL,01,003,Baldwin County,H1
+AL,01,005,Barbour County,H1
+AL,01,007,Bibb County,H1
+AL,01,009,Blount County,H1
+AL,01,011,Bullock County,H1
+AL,01,013,Butler County,H1
+AL,01,015,Calhoun County,H1
+AL,01,017,Chambers County,H1
+AL,01,019,Cherokee County,H1
+AL,01,021,Chilton County,H1
+AL,01,023,Choctaw County,H1
+AL,01,025,Clarke County,H1
+AL,01,027,Clay County,H1
+AL,01,029,Cleburne County,H1
+AL,01,031,Coffee County,H1
+AL,01,033,Colbert County,H1
+AL,01,035,Conecuh County,H1
+AL,01,037,Coosa County,H1
+AL,01,039,Covington County,H1
+AL,01,041,Crenshaw County,H1
+AL,01,043,Cullman County,H1
+AL,01,045,Dale County,H1
+AL,01,047,Dallas County,H1
+AL,01,049,DeKalb County,H1
+AL,01,051,Elmore County,H1
+AL,01,053,Escambia County,H1
+AL,01,055,Etowah County,H1
+AL,01,057,Fayette County,H1
+AL,01,059,Franklin County,H1
+AL,01,061,Geneva County,H1
+AL,01,063,Greene County,H1
+AL,01,065,Hale County,H1
+AL,01,067,Henry County,H1
+AL,01,069,Houston County,H1
+AL,01,071,Jackson County,H1
+AL,01,073,Jefferson County,H1
+AL,01,075,Lamar County,H1
+AL,01,077,Lauderdale County,H1
+AL,01,079,Lawrence County,H1
+AL,01,081,Lee County,H1
+AL,01,083,Limestone County,H1
+AL,01,085,Lowndes County,H1
+AL,01,087,Macon County,H1
+AL,01,089,Madison County,H1
+AL,01,091,Marengo County,H1
+AL,01,093,Marion County,H1
+AL,01,095,Marshall County,H1
+AL,01,097,Mobile County,H1
+AL,01,099,Monroe County,H1
+AL,01,101,Montgomery County,H1
+AL,01,103,Morgan County,H1
+AL,01,105,Perry County,H1
+AL,01,107,Pickens County,H1
+AL,01,109,Pike County,H1
+AL,01,111,Randolph County,H1
+AL,01,113,Russell County,H1
+AL,01,115,St. Clair County,H1
+AL,01,117,Shelby County,H1
+AL,01,119,Sumter County,H1
+AL,01,121,Talladega County,H1
+AL,01,123,Tallapoosa County,H1
+AL,01,125,Tuscaloosa County,H1
+AL,01,127,Walker County,H1
+AL,01,129,Washington County,H1
+AL,01,131,Wilcox County,H1
+AL,01,133,Winston County,H1
+AK,02,013,Aleutians East Borough,H1
+AK,02,016,Aleutians West Census Area,H5
+AK,02,020,Anchorage Municipality,H6
+AK,02,050,Bethel Census Area,H5
+AK,02,060,Bristol Bay Borough,H1
+AK,02,068,Denali Borough,H1
+AK,02,070,Dillingham Census Area,H5
+AK,02,090,Fairbanks North Star Borough,H1
+AK,02,100,Haines Borough,H1
+AK,02,105,Hoonah-Angoon Census Area,H5
+AK,02,110,Juneau City and Borough,H6
+AK,02,122,Kenai Peninsula Borough,H1
+AK,02,130,Ketchikan Gateway Borough,H1
+AK,02,150,Kodiak Island Borough,H1
+AK,02,164,Lake and Peninsula Borough,H1
+AK,02,170,Matanuska-Susitna Borough,H1
+AK,02,180,Nome Census Area,H5
+AK,02,185,North Slope Borough,H1
+AK,02,188,Northwest Arctic Borough,H1
+AK,02,195,Petersburg Census Area,H5
+AK,02,198,Prince of Wales-Hyder Census Area,H5
+AK,02,220,Sitka City and Borough,H6
+AK,02,230,Skagway Municipality,H1
+AK,02,240,Southeast Fairbanks Census Area,H5
+AK,02,261,Valdez-Cordova Census Area,H5
+AK,02,270,Wade Hampton Census Area,H5
+AK,02,275,Wrangell City and Borough,H1
+AK,02,282,Yakutat City and Borough,H1
+AK,02,290,Yukon-Koyukuk Census Area,H5
+AZ,04,001,Apache County,H1
+AZ,04,003,Cochise County,H1
+AZ,04,005,Coconino County,H1
+AZ,04,007,Gila County,H1
+AZ,04,009,Graham County,H1
+AZ,04,011,Greenlee County,H1
+AZ,04,012,La Paz County,H1
+AZ,04,013,Maricopa County,H1
+AZ,04,015,Mohave County,H1
+AZ,04,017,Navajo County,H1
+AZ,04,019,Pima County,H1
+AZ,04,021,Pinal County,H1
+AZ,04,023,Santa Cruz County,H1
+AZ,04,025,Yavapai County,H1
+AZ,04,027,Yuma County,H1
+AR,05,001,Arkansas County,H1
+AR,05,003,Ashley County,H1
+AR,05,005,Baxter County,H1
+AR,05,007,Benton County,H1
+AR,05,009,Boone County,H1
+AR,05,011,Bradley County,H1
+AR,05,013,Calhoun County,H1
+AR,05,015,Carroll County,H1
+AR,05,017,Chicot County,H1
+AR,05,019,Clark County,H1
+AR,05,021,Clay County,H1
+AR,05,023,Cleburne County,H1
+AR,05,025,Cleveland County,H1
+AR,05,027,Columbia County,H1
+AR,05,029,Conway County,H1
+AR,05,031,Craighead County,H1
+AR,05,033,Crawford County,H1
+AR,05,035,Crittenden County,H1
+AR,05,037,Cross County,H1
+AR,05,039,Dallas County,H1
+AR,05,041,Desha County,H1
+AR,05,043,Drew County,H1
+AR,05,045,Faulkner County,H1
+AR,05,047,Franklin County,H1
+AR,05,049,Fulton County,H1
+AR,05,051,Garland County,H1
+AR,05,053,Grant County,H1
+AR,05,055,Greene County,H1
+AR,05,057,Hempstead County,H1
+AR,05,059,Hot Spring County,H1
+AR,05,061,Howard County,H1
+AR,05,063,Independence County,H1
+AR,05,065,Izard County,H1
+AR,05,067,Jackson County,H1
+AR,05,069,Jefferson County,H1
+AR,05,071,Johnson County,H1
+AR,05,073,Lafayette County,H1
+AR,05,075,Lawrence County,H1
+AR,05,077,Lee County,H1
+AR,05,079,Lincoln County,H1
+AR,05,081,Little River County,H1
+AR,05,083,Logan County,H1
+AR,05,085,Lonoke County,H1
+AR,05,087,Madison County,H1
+AR,05,089,Marion County,H1
+AR,05,091,Miller County,H1
+AR,05,093,Mississippi County,H1
+AR,05,095,Monroe County,H1
+AR,05,097,Montgomery County,H1
+AR,05,099,Nevada County,H1
+AR,05,101,Newton County,H1
+AR,05,103,Ouachita County,H1
+AR,05,105,Perry County,H1
+AR,05,107,Phillips County,H1
+AR,05,109,Pike County,H1
+AR,05,111,Poinsett County,H1
+AR,05,113,Polk County,H1
+AR,05,115,Pope County,H1
+AR,05,117,Prairie County,H1
+AR,05,119,Pulaski County,H1
+AR,05,121,Randolph County,H1
+AR,05,123,St. Francis County,H1
+AR,05,125,Saline County,H1
+AR,05,127,Scott County,H1
+AR,05,129,Searcy County,H1
+AR,05,131,Sebastian County,H1
+AR,05,133,Sevier County,H1
+AR,05,135,Sharp County,H1
+AR,05,137,Stone County,H1
+AR,05,139,Union County,H1
+AR,05,141,Van Buren County,H1
+AR,05,143,Washington County,H1
+AR,05,145,White County,H1
+AR,05,147,Woodruff County,H1
+AR,05,149,Yell County,H1
+CA,06,001,Alameda County,H1
+CA,06,003,Alpine County,H1
+CA,06,005,Amador County,H1
+CA,06,007,Butte County,H1
+CA,06,009,Calaveras County,H1
+CA,06,011,Colusa County,H1
+CA,06,013,Contra Costa County,H1
+CA,06,015,Del Norte County,H1
+CA,06,017,El Dorado County,H1
+CA,06,019,Fresno County,H1
+CA,06,021,Glenn County,H1
+CA,06,023,Humboldt County,H1
+CA,06,025,Imperial County,H1
+CA,06,027,Inyo County,H1
+CA,06,029,Kern County,H1
+CA,06,031,Kings County,H1
+CA,06,033,Lake County,H1
+CA,06,035,Lassen County,H1
+CA,06,037,Los Angeles County,H1
+CA,06,039,Madera County,H1
+CA,06,041,Marin County,H1
+CA,06,043,Mariposa County,H1
+CA,06,045,Mendocino County,H1
+CA,06,047,Merced County,H1
+CA,06,049,Modoc County,H1
+CA,06,051,Mono County,H1
+CA,06,053,Monterey County,H1
+CA,06,055,Napa County,H1
+CA,06,057,Nevada County,H1
+CA,06,059,Orange County,H1
+CA,06,061,Placer County,H1
+CA,06,063,Plumas County,H1
+CA,06,065,Riverside County,H1
+CA,06,067,Sacramento County,H1
+CA,06,069,San Benito County,H1
+CA,06,071,San Bernardino County,H1
+CA,06,073,San Diego County,H1
+CA,06,075,San Francisco County,H6
+CA,06,077,San Joaquin County,H1
+CA,06,079,San Luis Obispo County,H1
+CA,06,081,San Mateo County,H1
+CA,06,083,Santa Barbara County,H1
+CA,06,085,Santa Clara County,H1
+CA,06,087,Santa Cruz County,H1
+CA,06,089,Shasta County,H1
+CA,06,091,Sierra County,H1
+CA,06,093,Siskiyou County,H1
+CA,06,095,Solano County,H1
+CA,06,097,Sonoma County,H1
+CA,06,099,Stanislaus County,H1
+CA,06,101,Sutter County,H1
+CA,06,103,Tehama County,H1
+CA,06,105,Trinity County,H1
+CA,06,107,Tulare County,H1
+CA,06,109,Tuolumne County,H1
+CA,06,111,Ventura County,H1
+CA,06,113,Yolo County,H1
+CA,06,115,Yuba County,H1
+CO,08,001,Adams County,H1
+CO,08,003,Alamosa County,H1
+CO,08,005,Arapahoe County,H1
+CO,08,007,Archuleta County,H1
+CO,08,009,Baca County,H1
+CO,08,011,Bent County,H1
+CO,08,013,Boulder County,H1
+CO,08,014,Broomfield County,H6
+CO,08,015,Chaffee County,H1
+CO,08,017,Cheyenne County,H1
+CO,08,019,Clear Creek County,H1
+CO,08,021,Conejos County,H1
+CO,08,023,Costilla County,H1
+CO,08,025,Crowley County,H1
+CO,08,027,Custer County,H1
+CO,08,029,Delta County,H1
+CO,08,031,Denver County,H6
+CO,08,033,Dolores County,H1
+CO,08,035,Douglas County,H1
+CO,08,037,Eagle County,H1
+CO,08,039,Elbert County,H1
+CO,08,041,El Paso County,H1
+CO,08,043,Fremont County,H1
+CO,08,045,Garfield County,H1
+CO,08,047,Gilpin County,H1
+CO,08,049,Grand County,H1
+CO,08,051,Gunnison County,H1
+CO,08,053,Hinsdale County,H1
+CO,08,055,Huerfano County,H1
+CO,08,057,Jackson County,H1
+CO,08,059,Jefferson County,H1
+CO,08,061,Kiowa County,H1
+CO,08,063,Kit Carson County,H1
+CO,08,065,Lake County,H1
+CO,08,067,La Plata County,H1
+CO,08,069,Larimer County,H1
+CO,08,071,Las Animas County,H1
+CO,08,073,Lincoln County,H1
+CO,08,075,Logan County,H1
+CO,08,077,Mesa County,H1
+CO,08,079,Mineral County,H1
+CO,08,081,Moffat County,H1
+CO,08,083,Montezuma County,H1
+CO,08,085,Montrose County,H1
+CO,08,087,Morgan County,H1
+CO,08,089,Otero County,H1
+CO,08,091,Ouray County,H1
+CO,08,093,Park County,H1
+CO,08,095,Phillips County,H1
+CO,08,097,Pitkin County,H1
+CO,08,099,Prowers County,H1
+CO,08,101,Pueblo County,H1
+CO,08,103,Rio Blanco County,H1
+CO,08,105,Rio Grande County,H1
+CO,08,107,Routt County,H1
+CO,08,109,Saguache County,H1
+CO,08,111,San Juan County,H1
+CO,08,113,San Miguel County,H1
+CO,08,115,Sedgwick County,H1
+CO,08,117,Summit County,H1
+CO,08,119,Teller County,H1
+CO,08,121,Washington County,H1
+CO,08,123,Weld County,H1
+CO,08,125,Yuma County,H1
+CT,09,001,Fairfield County,H4
+CT,09,003,Hartford County,H4
+CT,09,005,Litchfield County,H4
+CT,09,007,Middlesex County,H4
+CT,09,009,New Haven County,H4
+CT,09,011,New London County,H4
+CT,09,013,Tolland County,H4
+CT,09,015,Windham County,H4
+DE,10,001,Kent County,H1
+DE,10,003,New Castle County,H1
+DE,10,005,Sussex County,H1
+DC,11,001,District of Columbia,H6
+FL,12,001,Alachua County,H1
+FL,12,003,Baker County,H1
+FL,12,005,Bay County,H1
+FL,12,007,Bradford County,H1
+FL,12,009,Brevard County,H1
+FL,12,011,Broward County,H1
+FL,12,013,Calhoun County,H1
+FL,12,015,Charlotte County,H1
+FL,12,017,Citrus County,H1
+FL,12,019,Clay County,H1
+FL,12,021,Collier County,H1
+FL,12,023,Columbia County,H1
+FL,12,027,DeSoto County,H1
+FL,12,029,Dixie County,H1
+FL,12,031,Duval County,H6
+FL,12,033,Escambia County,H1
+FL,12,035,Flagler County,H1
+FL,12,037,Franklin County,H1
+FL,12,039,Gadsden County,H1
+FL,12,041,Gilchrist County,H1
+FL,12,043,Glades County,H1
+FL,12,045,Gulf County,H1
+FL,12,047,Hamilton County,H1
+FL,12,049,Hardee County,H1
+FL,12,051,Hendry County,H1
+FL,12,053,Hernando County,H1
+FL,12,055,Highlands County,H1
+FL,12,057,Hillsborough County,H1
+FL,12,059,Holmes County,H1
+FL,12,061,Indian River County,H1
+FL,12,063,Jackson County,H1
+FL,12,065,Jefferson County,H1
+FL,12,067,Lafayette County,H1
+FL,12,069,Lake County,H1
+FL,12,071,Lee County,H1
+FL,12,073,Leon County,H1
+FL,12,075,Levy County,H1
+FL,12,077,Liberty County,H1
+FL,12,079,Madison County,H1
+FL,12,081,Manatee County,H1
+FL,12,083,Marion County,H1
+FL,12,085,Martin County,H1
+FL,12,086,Miami-Dade County,H1
+FL,12,087,Monroe County,H1
+FL,12,089,Nassau County,H1
+FL,12,091,Okaloosa County,H1
+FL,12,093,Okeechobee County,H1
+FL,12,095,Orange County,H1
+FL,12,097,Osceola County,H1
+FL,12,099,Palm Beach County,H1
+FL,12,101,Pasco County,H1
+FL,12,103,Pinellas County,H1
+FL,12,105,Polk County,H1
+FL,12,107,Putnam County,H1
+FL,12,109,St. Johns County,H1
+FL,12,111,St. Lucie County,H1
+FL,12,113,Santa Rosa County,H1
+FL,12,115,Sarasota County,H1
+FL,12,117,Seminole County,H1
+FL,12,119,Sumter County,H1
+FL,12,121,Suwannee County,H1
+FL,12,123,Taylor County,H1
+FL,12,125,Union County,H1
+FL,12,127,Volusia County,H1
+FL,12,129,Wakulla County,H1
+FL,12,131,Walton County,H1
+FL,12,133,Washington County,H1
+GA,13,001,Appling County,H1
+GA,13,003,Atkinson County,H1
+GA,13,005,Bacon County,H1
+GA,13,007,Baker County,H1
+GA,13,009,Baldwin County,H1
+GA,13,011,Banks County,H1
+GA,13,013,Barrow County,H1
+GA,13,015,Bartow County,H1
+GA,13,017,Ben Hill County,H1
+GA,13,019,Berrien County,H1
+GA,13,021,Bibb County,H1
+GA,13,023,Bleckley County,H1
+GA,13,025,Brantley County,H1
+GA,13,027,Brooks County,H1
+GA,13,029,Bryan County,H1
+GA,13,031,Bulloch County,H1
+GA,13,033,Burke County,H1
+GA,13,035,Butts County,H1
+GA,13,037,Calhoun County,H1
+GA,13,039,Camden County,H1
+GA,13,043,Candler County,H1
+GA,13,045,Carroll County,H1
+GA,13,047,Catoosa County,H1
+GA,13,049,Charlton County,H1
+GA,13,051,Chatham County,H1
+GA,13,053,Chattahoochee County,H1
+GA,13,055,Chattooga County,H1
+GA,13,057,Cherokee County,H1
+GA,13,059,Clarke County,H6
+GA,13,061,Clay County,H1
+GA,13,063,Clayton County,H1
+GA,13,065,Clinch County,H1
+GA,13,067,Cobb County,H1
+GA,13,069,Coffee County,H1
+GA,13,071,Colquitt County,H1
+GA,13,073,Columbia County,H1
+GA,13,075,Cook County,H1
+GA,13,077,Coweta County,H1
+GA,13,079,Crawford County,H1
+GA,13,081,Crisp County,H1
+GA,13,083,Dade County,H1
+GA,13,085,Dawson County,H1
+GA,13,087,Decatur County,H1
+GA,13,089,DeKalb County,H1
+GA,13,091,Dodge County,H1
+GA,13,093,Dooly County,H1
+GA,13,095,Dougherty County,H1
+GA,13,097,Douglas County,H1
+GA,13,099,Early County,H1
+GA,13,101,Echols County,H1
+GA,13,103,Effingham County,H1
+GA,13,105,Elbert County,H1
+GA,13,107,Emanuel County,H1
+GA,13,109,Evans County,H1
+GA,13,111,Fannin County,H1
+GA,13,113,Fayette County,H1
+GA,13,115,Floyd County,H1
+GA,13,117,Forsyth County,H1
+GA,13,119,Franklin County,H1
+GA,13,121,Fulton County,H1
+GA,13,123,Gilmer County,H1
+GA,13,125,Glascock County,H1
+GA,13,127,Glynn County,H1
+GA,13,129,Gordon County,H1
+GA,13,131,Grady County,H1
+GA,13,133,Greene County,H1
+GA,13,135,Gwinnett County,H1
+GA,13,137,Habersham County,H1
+GA,13,139,Hall County,H1
+GA,13,141,Hancock County,H1
+GA,13,143,Haralson County,H1
+GA,13,145,Harris County,H1
+GA,13,147,Hart County,H1
+GA,13,149,Heard County,H1
+GA,13,151,Henry County,H1
+GA,13,153,Houston County,H1
+GA,13,155,Irwin County,H1
+GA,13,157,Jackson County,H1
+GA,13,159,Jasper County,H1
+GA,13,161,Jeff Davis County,H1
+GA,13,163,Jefferson County,H1
+GA,13,165,Jenkins County,H1
+GA,13,167,Johnson County,H1
+GA,13,169,Jones County,H1
+GA,13,171,Lamar County,H1
+GA,13,173,Lanier County,H1
+GA,13,175,Laurens County,H1
+GA,13,177,Lee County,H1
+GA,13,179,Liberty County,H1
+GA,13,181,Lincoln County,H1
+GA,13,183,Long County,H1
+GA,13,185,Lowndes County,H1
+GA,13,187,Lumpkin County,H1
+GA,13,189,McDuffie County,H1
+GA,13,191,McIntosh County,H1
+GA,13,193,Macon County,H1
+GA,13,195,Madison County,H1
+GA,13,197,Marion County,H1
+GA,13,199,Meriwether County,H1
+GA,13,201,Miller County,H1
+GA,13,205,Mitchell County,H1
+GA,13,207,Monroe County,H1
+GA,13,209,Montgomery County,H1
+GA,13,211,Morgan County,H1
+GA,13,213,Murray County,H1
+GA,13,215,Muscogee County,H6
+GA,13,217,Newton County,H1
+GA,13,219,Oconee County,H1
+GA,13,221,Oglethorpe County,H1
+GA,13,223,Paulding County,H1
+GA,13,225,Peach County,H1
+GA,13,227,Pickens County,H1
+GA,13,229,Pierce County,H1
+GA,13,231,Pike County,H1
+GA,13,233,Polk County,H1
+GA,13,235,Pulaski County,H1
+GA,13,237,Putnam County,H1
+GA,13,239,Quitman County,H1
+GA,13,241,Rabun County,H1
+GA,13,243,Randolph County,H1
+GA,13,245,Richmond County,H6
+GA,13,247,Rockdale County,H1
+GA,13,249,Schley County,H1
+GA,13,251,Screven County,H1
+GA,13,253,Seminole County,H1
+GA,13,255,Spalding County,H1
+GA,13,257,Stephens County,H1
+GA,13,259,Stewart County,H1
+GA,13,261,Sumter County,H1
+GA,13,263,Talbot County,H1
+GA,13,265,Taliaferro County,H1
+GA,13,267,Tattnall County,H1
+GA,13,269,Taylor County,H1
+GA,13,271,Telfair County,H1
+GA,13,273,Terrell County,H1
+GA,13,275,Thomas County,H1
+GA,13,277,Tift County,H1
+GA,13,279,Toombs County,H1
+GA,13,281,Towns County,H1
+GA,13,283,Treutlen County,H1
+GA,13,285,Troup County,H1
+GA,13,287,Turner County,H1
+GA,13,289,Twiggs County,H1
+GA,13,291,Union County,H1
+GA,13,293,Upson County,H1
+GA,13,295,Walker County,H1
+GA,13,297,Walton County,H1
+GA,13,299,Ware County,H1
+GA,13,301,Warren County,H1
+GA,13,303,Washington County,H1
+GA,13,305,Wayne County,H1
+GA,13,307,Webster County,H1
+GA,13,309,Wheeler County,H1
+GA,13,311,White County,H1
+GA,13,313,Whitfield County,H1
+GA,13,315,Wilcox County,H1
+GA,13,317,Wilkes County,H1
+GA,13,319,Wilkinson County,H1
+GA,13,321,Worth County,H1
+HI,15,001,Hawaii County,H1
+HI,15,003,Honolulu County,H1
+HI,15,005,Kalawao County,H4
+HI,15,007,Kauai County,H1
+HI,15,009,Maui County,H1
+ID,16,001,Ada County,H1
+ID,16,003,Adams County,H1
+ID,16,005,Bannock County,H1
+ID,16,007,Bear Lake County,H1
+ID,16,009,Benewah County,H1
+ID,16,011,Bingham County,H1
+ID,16,013,Blaine County,H1
+ID,16,015,Boise County,H1
+ID,16,017,Bonner County,H1
+ID,16,019,Bonneville County,H1
+ID,16,021,Boundary County,H1
+ID,16,023,Butte County,H1
+ID,16,025,Camas County,H1
+ID,16,027,Canyon County,H1
+ID,16,029,Caribou County,H1
+ID,16,031,Cassia County,H1
+ID,16,033,Clark County,H1
+ID,16,035,Clearwater County,H1
+ID,16,037,Custer County,H1
+ID,16,039,Elmore County,H1
+ID,16,041,Franklin County,H1
+ID,16,043,Fremont County,H1
+ID,16,045,Gem County,H1
+ID,16,047,Gooding County,H1
+ID,16,049,Idaho County,H1
+ID,16,051,Jefferson County,H1
+ID,16,053,Jerome County,H1
+ID,16,055,Kootenai County,H1
+ID,16,057,Latah County,H1
+ID,16,059,Lemhi County,H1
+ID,16,061,Lewis County,H1
+ID,16,063,Lincoln County,H1
+ID,16,065,Madison County,H1
+ID,16,067,Minidoka County,H1
+ID,16,069,Nez Perce County,H1
+ID,16,071,Oneida County,H1
+ID,16,073,Owyhee County,H1
+ID,16,075,Payette County,H1
+ID,16,077,Power County,H1
+ID,16,079,Shoshone County,H1
+ID,16,081,Teton County,H1
+ID,16,083,Twin Falls County,H1
+ID,16,085,Valley County,H1
+ID,16,087,Washington County,H1
+IL,17,001,Adams County,H1
+IL,17,003,Alexander County,H1
+IL,17,005,Bond County,H1
+IL,17,007,Boone County,H1
+IL,17,009,Brown County,H1
+IL,17,011,Bureau County,H1
+IL,17,013,Calhoun County,H1
+IL,17,015,Carroll County,H1
+IL,17,017,Cass County,H1
+IL,17,019,Champaign County,H1
+IL,17,021,Christian County,H1
+IL,17,023,Clark County,H1
+IL,17,025,Clay County,H1
+IL,17,027,Clinton County,H1
+IL,17,029,Coles County,H1
+IL,17,031,Cook County,H1
+IL,17,033,Crawford County,H1
+IL,17,035,Cumberland County,H1
+IL,17,037,DeKalb County,H1
+IL,17,039,De Witt County,H1
+IL,17,041,Douglas County,H1
+IL,17,043,DuPage County,H1
+IL,17,045,Edgar County,H1
+IL,17,047,Edwards County,H1
+IL,17,049,Effingham County,H1
+IL,17,051,Fayette County,H1
+IL,17,053,Ford County,H1
+IL,17,055,Franklin County,H1
+IL,17,057,Fulton County,H1
+IL,17,059,Gallatin County,H1
+IL,17,061,Greene County,H1
+IL,17,063,Grundy County,H1
+IL,17,065,Hamilton County,H1
+IL,17,067,Hancock County,H1
+IL,17,069,Hardin County,H1
+IL,17,071,Henderson County,H1
+IL,17,073,Henry County,H1
+IL,17,075,Iroquois County,H1
+IL,17,077,Jackson County,H1
+IL,17,079,Jasper County,H1
+IL,17,081,Jefferson County,H1
+IL,17,083,Jersey County,H1
+IL,17,085,Jo Daviess County,H1
+IL,17,087,Johnson County,H1
+IL,17,089,Kane County,H1
+IL,17,091,Kankakee County,H1
+IL,17,093,Kendall County,H1
+IL,17,095,Knox County,H1
+IL,17,097,Lake County,H1
+IL,17,099,LaSalle County,H1
+IL,17,101,Lawrence County,H1
+IL,17,103,Lee County,H1
+IL,17,105,Livingston County,H1
+IL,17,107,Logan County,H1
+IL,17,109,McDonough County,H1
+IL,17,111,McHenry County,H1
+IL,17,113,McLean County,H1
+IL,17,115,Macon County,H1
+IL,17,117,Macoupin County,H1
+IL,17,119,Madison County,H1
+IL,17,121,Marion County,H1
+IL,17,123,Marshall County,H1
+IL,17,125,Mason County,H1
+IL,17,127,Massac County,H1
+IL,17,129,Menard County,H1
+IL,17,131,Mercer County,H1
+IL,17,133,Monroe County,H1
+IL,17,135,Montgomery County,H1
+IL,17,137,Morgan County,H1
+IL,17,139,Moultrie County,H1
+IL,17,141,Ogle County,H1
+IL,17,143,Peoria County,H1
+IL,17,145,Perry County,H1
+IL,17,147,Piatt County,H1
+IL,17,149,Pike County,H1
+IL,17,151,Pope County,H1
+IL,17,153,Pulaski County,H1
+IL,17,155,Putnam County,H1
+IL,17,157,Randolph County,H1
+IL,17,159,Richland County,H1
+IL,17,161,Rock Island County,H1
+IL,17,163,St. Clair County,H1
+IL,17,165,Saline County,H1
+IL,17,167,Sangamon County,H1
+IL,17,169,Schuyler County,H1
+IL,17,171,Scott County,H1
+IL,17,173,Shelby County,H1
+IL,17,175,Stark County,H1
+IL,17,177,Stephenson County,H1
+IL,17,179,Tazewell County,H1
+IL,17,181,Union County,H1
+IL,17,183,Vermilion County,H1
+IL,17,185,Wabash County,H1
+IL,17,187,Warren County,H1
+IL,17,189,Washington County,H1
+IL,17,191,Wayne County,H1
+IL,17,193,White County,H1
+IL,17,195,Whiteside County,H1
+IL,17,197,Will County,H1
+IL,17,199,Williamson County,H1
+IL,17,201,Winnebago County,H1
+IL,17,203,Woodford County,H1
+IN,18,001,Adams County,H1
+IN,18,003,Allen County,H1
+IN,18,005,Bartholomew County,H1
+IN,18,007,Benton County,H1
+IN,18,009,Blackford County,H1
+IN,18,011,Boone County,H1
+IN,18,013,Brown County,H1
+IN,18,015,Carroll County,H1
+IN,18,017,Cass County,H1
+IN,18,019,Clark County,H1
+IN,18,021,Clay County,H1
+IN,18,023,Clinton County,H1
+IN,18,025,Crawford County,H1
+IN,18,027,Daviess County,H1
+IN,18,029,Dearborn County,H1
+IN,18,031,Decatur County,H1
+IN,18,033,DeKalb County,H1
+IN,18,035,Delaware County,H1
+IN,18,037,Dubois County,H1
+IN,18,039,Elkhart County,H1
+IN,18,041,Fayette County,H1
+IN,18,043,Floyd County,H1
+IN,18,045,Fountain County,H1
+IN,18,047,Franklin County,H1
+IN,18,049,Fulton County,H1
+IN,18,051,Gibson County,H1
+IN,18,053,Grant County,H1
+IN,18,055,Greene County,H1
+IN,18,057,Hamilton County,H1
+IN,18,059,Hancock County,H1
+IN,18,061,Harrison County,H1
+IN,18,063,Hendricks County,H1
+IN,18,065,Henry County,H1
+IN,18,067,Howard County,H1
+IN,18,069,Huntington County,H1
+IN,18,071,Jackson County,H1
+IN,18,073,Jasper County,H1
+IN,18,075,Jay County,H1
+IN,18,077,Jefferson County,H1
+IN,18,079,Jennings County,H1
+IN,18,081,Johnson County,H1
+IN,18,083,Knox County,H1
+IN,18,085,Kosciusko County,H1
+IN,18,087,LaGrange County,H1
+IN,18,089,Lake County,H1
+IN,18,091,LaPorte County,H1
+IN,18,093,Lawrence County,H1
+IN,18,095,Madison County,H1
+IN,18,097,Marion County,H6
+IN,18,099,Marshall County,H1
+IN,18,101,Martin County,H1
+IN,18,103,Miami County,H1
+IN,18,105,Monroe County,H1
+IN,18,107,Montgomery County,H1
+IN,18,109,Morgan County,H1
+IN,18,111,Newton County,H1
+IN,18,113,Noble County,H1
+IN,18,115,Ohio County,H1
+IN,18,117,Orange County,H1
+IN,18,119,Owen County,H1
+IN,18,121,Parke County,H1
+IN,18,123,Perry County,H1
+IN,18,125,Pike County,H1
+IN,18,127,Porter County,H1
+IN,18,129,Posey County,H1
+IN,18,131,Pulaski County,H1
+IN,18,133,Putnam County,H1
+IN,18,135,Randolph County,H1
+IN,18,137,Ripley County,H1
+IN,18,139,Rush County,H1
+IN,18,141,St. Joseph County,H1
+IN,18,143,Scott County,H1
+IN,18,145,Shelby County,H1
+IN,18,147,Spencer County,H1
+IN,18,149,Starke County,H1
+IN,18,151,Steuben County,H1
+IN,18,153,Sullivan County,H1
+IN,18,155,Switzerland County,H1
+IN,18,157,Tippecanoe County,H1
+IN,18,159,Tipton County,H1
+IN,18,161,Union County,H1
+IN,18,163,Vanderburgh County,H1
+IN,18,165,Vermillion County,H1
+IN,18,167,Vigo County,H1
+IN,18,169,Wabash County,H1
+IN,18,171,Warren County,H1
+IN,18,173,Warrick County,H1
+IN,18,175,Washington County,H1
+IN,18,177,Wayne County,H1
+IN,18,179,Wells County,H1
+IN,18,181,White County,H1
+IN,18,183,Whitley County,H1
+IA,19,001,Adair County,H1
+IA,19,003,Adams County,H1
+IA,19,005,Allamakee County,H1
+IA,19,007,Appanoose County,H1
+IA,19,009,Audubon County,H1
+IA,19,011,Benton County,H1
+IA,19,013,Black Hawk County,H1
+IA,19,015,Boone County,H1
+IA,19,017,Bremer County,H1
+IA,19,019,Buchanan County,H1
+IA,19,021,Buena Vista County,H1
+IA,19,023,Butler County,H1
+IA,19,025,Calhoun County,H1
+IA,19,027,Carroll County,H1
+IA,19,029,Cass County,H1
+IA,19,031,Cedar County,H1
+IA,19,033,Cerro Gordo County,H1
+IA,19,035,Cherokee County,H1
+IA,19,037,Chickasaw County,H1
+IA,19,039,Clarke County,H1
+IA,19,041,Clay County,H1
+IA,19,043,Clayton County,H1
+IA,19,045,Clinton County,H1
+IA,19,047,Crawford County,H1
+IA,19,049,Dallas County,H1
+IA,19,051,Davis County,H1
+IA,19,053,Decatur County,H1
+IA,19,055,Delaware County,H1
+IA,19,057,Des Moines County,H1
+IA,19,059,Dickinson County,H1
+IA,19,061,Dubuque County,H1
+IA,19,063,Emmet County,H1
+IA,19,065,Fayette County,H1
+IA,19,067,Floyd County,H1
+IA,19,069,Franklin County,H1
+IA,19,071,Fremont County,H1
+IA,19,073,Greene County,H1
+IA,19,075,Grundy County,H1
+IA,19,077,Guthrie County,H1
+IA,19,079,Hamilton County,H1
+IA,19,081,Hancock County,H1
+IA,19,083,Hardin County,H1
+IA,19,085,Harrison County,H1
+IA,19,087,Henry County,H1
+IA,19,089,Howard County,H1
+IA,19,091,Humboldt County,H1
+IA,19,093,Ida County,H1
+IA,19,095,Iowa County,H1
+IA,19,097,Jackson County,H1
+IA,19,099,Jasper County,H1
+IA,19,101,Jefferson County,H1
+IA,19,103,Johnson County,H1
+IA,19,105,Jones County,H1
+IA,19,107,Keokuk County,H1
+IA,19,109,Kossuth County,H1
+IA,19,111,Lee County,H1
+IA,19,113,Linn County,H1
+IA,19,115,Louisa County,H1
+IA,19,117,Lucas County,H1
+IA,19,119,Lyon County,H1
+IA,19,121,Madison County,H1
+IA,19,123,Mahaska County,H1
+IA,19,125,Marion County,H1
+IA,19,127,Marshall County,H1
+IA,19,129,Mills County,H1
+IA,19,131,Mitchell County,H1
+IA,19,133,Monona County,H1
+IA,19,135,Monroe County,H1
+IA,19,137,Montgomery County,H1
+IA,19,139,Muscatine County,H1
+IA,19,141,O'Brien County,H1
+IA,19,143,Osceola County,H1
+IA,19,145,Page County,H1
+IA,19,147,Palo Alto County,H1
+IA,19,149,Plymouth County,H1
+IA,19,151,Pocahontas County,H1
+IA,19,153,Polk County,H1
+IA,19,155,Pottawattamie County,H1
+IA,19,157,Poweshiek County,H1
+IA,19,159,Ringgold County,H1
+IA,19,161,Sac County,H1
+IA,19,163,Scott County,H1
+IA,19,165,Shelby County,H1
+IA,19,167,Sioux County,H1
+IA,19,169,Story County,H1
+IA,19,171,Tama County,H1
+IA,19,173,Taylor County,H1
+IA,19,175,Union County,H1
+IA,19,177,Van Buren County,H1
+IA,19,179,Wapello County,H1
+IA,19,181,Warren County,H1
+IA,19,183,Washington County,H1
+IA,19,185,Wayne County,H1
+IA,19,187,Webster County,H1
+IA,19,189,Winnebago County,H1
+IA,19,191,Winneshiek County,H1
+IA,19,193,Woodbury County,H1
+IA,19,195,Worth County,H1
+IA,19,197,Wright County,H1
+KS,20,001,Allen County,H1
+KS,20,003,Anderson County,H1
+KS,20,005,Atchison County,H1
+KS,20,007,Barber County,H1
+KS,20,009,Barton County,H1
+KS,20,011,Bourbon County,H1
+KS,20,013,Brown County,H1
+KS,20,015,Butler County,H1
+KS,20,017,Chase County,H1
+KS,20,019,Chautauqua County,H1
+KS,20,021,Cherokee County,H1
+KS,20,023,Cheyenne County,H1
+KS,20,025,Clark County,H1
+KS,20,027,Clay County,H1
+KS,20,029,Cloud County,H1
+KS,20,031,Coffey County,H1
+KS,20,033,Comanche County,H1
+KS,20,035,Cowley County,H1
+KS,20,037,Crawford County,H1
+KS,20,039,Decatur County,H1
+KS,20,041,Dickinson County,H1
+KS,20,043,Doniphan County,H1
+KS,20,045,Douglas County,H1
+KS,20,047,Edwards County,H1
+KS,20,049,Elk County,H1
+KS,20,051,Ellis County,H1
+KS,20,053,Ellsworth County,H1
+KS,20,055,Finney County,H1
+KS,20,057,Ford County,H1
+KS,20,059,Franklin County,H1
+KS,20,061,Geary County,H1
+KS,20,063,Gove County,H1
+KS,20,065,Graham County,H1
+KS,20,067,Grant County,H1
+KS,20,069,Gray County,H1
+KS,20,071,Greeley County,H1
+KS,20,073,Greenwood County,H1
+KS,20,075,Hamilton County,H1
+KS,20,077,Harper County,H1
+KS,20,079,Harvey County,H1
+KS,20,081,Haskell County,H1
+KS,20,083,Hodgeman County,H1
+KS,20,085,Jackson County,H1
+KS,20,087,Jefferson County,H1
+KS,20,089,Jewell County,H1
+KS,20,091,Johnson County,H1
+KS,20,093,Kearny County,H1
+KS,20,095,Kingman County,H1
+KS,20,097,Kiowa County,H1
+KS,20,099,Labette County,H1
+KS,20,101,Lane County,H1
+KS,20,103,Leavenworth County,H1
+KS,20,105,Lincoln County,H1
+KS,20,107,Linn County,H1
+KS,20,109,Logan County,H1
+KS,20,111,Lyon County,H1
+KS,20,113,McPherson County,H1
+KS,20,115,Marion County,H1
+KS,20,117,Marshall County,H1
+KS,20,119,Meade County,H1
+KS,20,121,Miami County,H1
+KS,20,123,Mitchell County,H1
+KS,20,125,Montgomery County,H1
+KS,20,127,Morris County,H1
+KS,20,129,Morton County,H1
+KS,20,131,Nemaha County,H1
+KS,20,133,Neosho County,H1
+KS,20,135,Ness County,H1
+KS,20,137,Norton County,H1
+KS,20,139,Osage County,H1
+KS,20,141,Osborne County,H1
+KS,20,143,Ottawa County,H1
+KS,20,145,Pawnee County,H1
+KS,20,147,Phillips County,H1
+KS,20,149,Pottawatomie County,H1
+KS,20,151,Pratt County,H1
+KS,20,153,Rawlins County,H1
+KS,20,155,Reno County,H1
+KS,20,157,Republic County,H1
+KS,20,159,Rice County,H1
+KS,20,161,Riley County,H1
+KS,20,163,Rooks County,H1
+KS,20,165,Rush County,H1
+KS,20,167,Russell County,H1
+KS,20,169,Saline County,H1
+KS,20,171,Scott County,H1
+KS,20,173,Sedgwick County,H1
+KS,20,175,Seward County,H1
+KS,20,177,Shawnee County,H1
+KS,20,179,Sheridan County,H1
+KS,20,181,Sherman County,H1
+KS,20,183,Smith County,H1
+KS,20,185,Stafford County,H1
+KS,20,187,Stanton County,H1
+KS,20,189,Stevens County,H1
+KS,20,191,Sumner County,H1
+KS,20,193,Thomas County,H1
+KS,20,195,Trego County,H1
+KS,20,197,Wabaunsee County,H1
+KS,20,199,Wallace County,H1
+KS,20,201,Washington County,H1
+KS,20,203,Wichita County,H1
+KS,20,205,Wilson County,H1
+KS,20,207,Woodson County,H1
+KS,20,209,Wyandotte County,H6
+KY,21,001,Adair County,H1
+KY,21,003,Allen County,H1
+KY,21,005,Anderson County,H1
+KY,21,007,Ballard County,H1
+KY,21,009,Barren County,H1
+KY,21,011,Bath County,H1
+KY,21,013,Bell County,H1
+KY,21,015,Boone County,H1
+KY,21,017,Bourbon County,H1
+KY,21,019,Boyd County,H1
+KY,21,021,Boyle County,H1
+KY,21,023,Bracken County,H1
+KY,21,025,Breathitt County,H1
+KY,21,027,Breckinridge County,H1
+KY,21,029,Bullitt County,H1
+KY,21,031,Butler County,H1
+KY,21,033,Caldwell County,H1
+KY,21,035,Calloway County,H1
+KY,21,037,Campbell County,H1
+KY,21,039,Carlisle County,H1
+KY,21,041,Carroll County,H1
+KY,21,043,Carter County,H1
+KY,21,045,Casey County,H1
+KY,21,047,Christian County,H1
+KY,21,049,Clark County,H1
+KY,21,051,Clay County,H1
+KY,21,053,Clinton County,H1
+KY,21,055,Crittenden County,H1
+KY,21,057,Cumberland County,H1
+KY,21,059,Daviess County,H1
+KY,21,061,Edmonson County,H1
+KY,21,063,Elliott County,H1
+KY,21,065,Estill County,H1
+KY,21,067,Fayette County,H6
+KY,21,069,Fleming County,H1
+KY,21,071,Floyd County,H1
+KY,21,073,Franklin County,H1
+KY,21,075,Fulton County,H1
+KY,21,077,Gallatin County,H1
+KY,21,079,Garrard County,H1
+KY,21,081,Grant County,H1
+KY,21,083,Graves County,H1
+KY,21,085,Grayson County,H1
+KY,21,087,Green County,H1
+KY,21,089,Greenup County,H1
+KY,21,091,Hancock County,H1
+KY,21,093,Hardin County,H1
+KY,21,095,Harlan County,H1
+KY,21,097,Harrison County,H1
+KY,21,099,Hart County,H1
+KY,21,101,Henderson County,H1
+KY,21,103,Henry County,H1
+KY,21,105,Hickman County,H1
+KY,21,107,Hopkins County,H1
+KY,21,109,Jackson County,H1
+KY,21,111,Jefferson County,H1
+KY,21,113,Jessamine County,H1
+KY,21,115,Johnson County,H1
+KY,21,117,Kenton County,H1
+KY,21,119,Knott County,H1
+KY,21,121,Knox County,H1
+KY,21,123,Larue County,H1
+KY,21,125,Laurel County,H1
+KY,21,127,Lawrence County,H1
+KY,21,129,Lee County,H1
+KY,21,131,Leslie County,H1
+KY,21,133,Letcher County,H1
+KY,21,135,Lewis County,H1
+KY,21,137,Lincoln County,H1
+KY,21,139,Livingston County,H1
+KY,21,141,Logan County,H1
+KY,21,143,Lyon County,H1
+KY,21,145,McCracken County,H1
+KY,21,147,McCreary County,H1
+KY,21,149,McLean County,H1
+KY,21,151,Madison County,H1
+KY,21,153,Magoffin County,H1
+KY,21,155,Marion County,H1
+KY,21,157,Marshall County,H1
+KY,21,159,Martin County,H1
+KY,21,161,Mason County,H1
+KY,21,163,Meade County,H1
+KY,21,165,Menifee County,H1
+KY,21,167,Mercer County,H1
+KY,21,169,Metcalfe County,H1
+KY,21,171,Monroe County,H1
+KY,21,173,Montgomery County,H1
+KY,21,175,Morgan County,H1
+KY,21,177,Muhlenberg County,H1
+KY,21,179,Nelson County,H1
+KY,21,181,Nicholas County,H1
+KY,21,183,Ohio County,H1
+KY,21,185,Oldham County,H1
+KY,21,187,Owen County,H1
+KY,21,189,Owsley County,H1
+KY,21,191,Pendleton County,H1
+KY,21,193,Perry County,H1
+KY,21,195,Pike County,H1
+KY,21,197,Powell County,H1
+KY,21,199,Pulaski County,H1
+KY,21,201,Robertson County,H1
+KY,21,203,Rockcastle County,H1
+KY,21,205,Rowan County,H1
+KY,21,207,Russell County,H1
+KY,21,209,Scott County,H1
+KY,21,211,Shelby County,H1
+KY,21,213,Simpson County,H1
+KY,21,215,Spencer County,H1
+KY,21,217,Taylor County,H1
+KY,21,219,Todd County,H1
+KY,21,221,Trigg County,H1
+KY,21,223,Trimble County,H1
+KY,21,225,Union County,H1
+KY,21,227,Warren County,H1
+KY,21,229,Washington County,H1
+KY,21,231,Wayne County,H1
+KY,21,233,Webster County,H1
+KY,21,235,Whitley County,H1
+KY,21,237,Wolfe County,H1
+KY,21,239,Woodford County,H1
+LA,22,001,Acadia Parish,H1
+LA,22,003,Allen Parish,H1
+LA,22,005,Ascension Parish,H1
+LA,22,007,Assumption Parish,H1
+LA,22,009,Avoyelles Parish,H1
+LA,22,011,Beauregard Parish,H1
+LA,22,013,Bienville Parish,H1
+LA,22,015,Bossier Parish,H1
+LA,22,017,Caddo Parish,H1
+LA,22,019,Calcasieu Parish,H1
+LA,22,021,Caldwell Parish,H1
+LA,22,023,Cameron Parish,H1
+LA,22,025,Catahoula Parish,H1
+LA,22,027,Claiborne Parish,H1
+LA,22,029,Concordia Parish,H1
+LA,22,031,De Soto Parish,H1
+LA,22,033,East Baton Rouge Parish,H1
+LA,22,035,East Carroll Parish,H1
+LA,22,037,East Feliciana Parish,H1
+LA,22,039,Evangeline Parish,H1
+LA,22,041,Franklin Parish,H1
+LA,22,043,Grant Parish,H1
+LA,22,045,Iberia Parish,H1
+LA,22,047,Iberville Parish,H1
+LA,22,049,Jackson Parish,H1
+LA,22,051,Jefferson Parish,H1
+LA,22,053,Jefferson Davis Parish,H1
+LA,22,055,Lafayette Parish,H1
+LA,22,057,Lafourche Parish,H1
+LA,22,059,La Salle Parish,H1
+LA,22,061,Lincoln Parish,H1
+LA,22,063,Livingston Parish,H1
+LA,22,065,Madison Parish,H1
+LA,22,067,Morehouse Parish,H1
+LA,22,069,Natchitoches Parish,H1
+LA,22,071,Orleans Parish,H6
+LA,22,073,Ouachita Parish,H1
+LA,22,075,Plaquemines Parish,H1
+LA,22,077,Pointe Coupee Parish,H1
+LA,22,079,Rapides Parish,H1
+LA,22,081,Red River Parish,H1
+LA,22,083,Richland Parish,H1
+LA,22,085,Sabine Parish,H1
+LA,22,087,St. Bernard Parish,H1
+LA,22,089,St. Charles Parish,H1
+LA,22,091,St. Helena Parish,H1
+LA,22,093,St. James Parish,H1
+LA,22,095,St. John the Baptist Parish,H1
+LA,22,097,St. Landry Parish,H1
+LA,22,099,St. Martin Parish,H1
+LA,22,101,St. Mary Parish,H1
+LA,22,103,St. Tammany Parish,H1
+LA,22,105,Tangipahoa Parish,H1
+LA,22,107,Tensas Parish,H1
+LA,22,109,Terrebonne Parish,H1
+LA,22,111,Union Parish,H1
+LA,22,113,Vermilion Parish,H1
+LA,22,115,Vernon Parish,H1
+LA,22,117,Washington Parish,H1
+LA,22,119,Webster Parish,H1
+LA,22,121,West Baton Rouge Parish,H1
+LA,22,123,West Carroll Parish,H1
+LA,22,125,West Feliciana Parish,H1
+LA,22,127,Winn Parish,H1
+ME,23,001,Androscoggin County,H1
+ME,23,003,Aroostook County,H1
+ME,23,005,Cumberland County,H1
+ME,23,007,Franklin County,H1
+ME,23,009,Hancock County,H1
+ME,23,011,Kennebec County,H1
+ME,23,013,Knox County,H1
+ME,23,015,Lincoln County,H1
+ME,23,017,Oxford County,H1
+ME,23,019,Penobscot County,H1
+ME,23,021,Piscataquis County,H1
+ME,23,023,Sagadahoc County,H1
+ME,23,025,Somerset County,H1
+ME,23,027,Waldo County,H1
+ME,23,029,Washington County,H1
+ME,23,031,York County,H1
+MD,24,001,Allegany County,H1
+MD,24,003,Anne Arundel County,H1
+MD,24,005,Baltimore County,H1
+MD,24,009,Calvert County,H1
+MD,24,011,Caroline County,H1
+MD,24,013,Carroll County,H1
+MD,24,015,Cecil County,H1
+MD,24,017,Charles County,H1
+MD,24,019,Dorchester County,H1
+MD,24,021,Frederick County,H1
+MD,24,023,Garrett County,H1
+MD,24,025,Harford County,H1
+MD,24,027,Howard County,H1
+MD,24,029,Kent County,H1
+MD,24,031,Montgomery County,H1
+MD,24,033,Prince George's County,H1
+MD,24,035,Queen Anne's County,H1
+MD,24,037,St. Mary's County,H1
+MD,24,039,Somerset County,H1
+MD,24,041,Talbot County,H1
+MD,24,043,Washington County,H1
+MD,24,045,Wicomico County,H1
+MD,24,047,Worcester County,H1
+MD,24,510,Baltimore city,C7
+MA,25,001,Barnstable County,H1
+MA,25,003,Berkshire County,H4
+MA,25,005,Bristol County,H1
+MA,25,007,Dukes County,H1
+MA,25,009,Essex County,H4
+MA,25,011,Franklin County,H4
+MA,25,013,Hampden County,H4
+MA,25,015,Hampshire County,H4
+MA,25,017,Middlesex County,H4
+MA,25,019,Nantucket County,H4
+MA,25,021,Norfolk County,H1
+MA,25,023,Plymouth County,H1
+MA,25,025,Suffolk County,H4
+MA,25,027,Worcester County,H4
+MI,26,001,Alcona County,H1
+MI,26,003,Alger County,H1
+MI,26,005,Allegan County,H1
+MI,26,007,Alpena County,H1
+MI,26,009,Antrim County,H1
+MI,26,011,Arenac County,H1
+MI,26,013,Baraga County,H1
+MI,26,015,Barry County,H1
+MI,26,017,Bay County,H1
+MI,26,019,Benzie County,H1
+MI,26,021,Berrien County,H1
+MI,26,023,Branch County,H1
+MI,26,025,Calhoun County,H1
+MI,26,027,Cass County,H1
+MI,26,029,Charlevoix County,H1
+MI,26,031,Cheboygan County,H1
+MI,26,033,Chippewa County,H1
+MI,26,035,Clare County,H1
+MI,26,037,Clinton County,H1
+MI,26,039,Crawford County,H1
+MI,26,041,Delta County,H1
+MI,26,043,Dickinson County,H1
+MI,26,045,Eaton County,H1
+MI,26,047,Emmet County,H1
+MI,26,049,Genesee County,H1
+MI,26,051,Gladwin County,H1
+MI,26,053,Gogebic County,H1
+MI,26,055,Grand Traverse County,H1
+MI,26,057,Gratiot County,H1
+MI,26,059,Hillsdale County,H1
+MI,26,061,Houghton County,H1
+MI,26,063,Huron County,H1
+MI,26,065,Ingham County,H1
+MI,26,067,Ionia County,H1
+MI,26,069,Iosco County,H1
+MI,26,071,Iron County,H1
+MI,26,073,Isabella County,H1
+MI,26,075,Jackson County,H1
+MI,26,077,Kalamazoo County,H1
+MI,26,079,Kalkaska County,H1
+MI,26,081,Kent County,H1
+MI,26,083,Keweenaw County,H1
+MI,26,085,Lake County,H1
+MI,26,087,Lapeer County,H1
+MI,26,089,Leelanau County,H1
+MI,26,091,Lenawee County,H1
+MI,26,093,Livingston County,H1
+MI,26,095,Luce County,H1
+MI,26,097,Mackinac County,H1
+MI,26,099,Macomb County,H1
+MI,26,101,Manistee County,H1
+MI,26,103,Marquette County,H1
+MI,26,105,Mason County,H1
+MI,26,107,Mecosta County,H1
+MI,26,109,Menominee County,H1
+MI,26,111,Midland County,H1
+MI,26,113,Missaukee County,H1
+MI,26,115,Monroe County,H1
+MI,26,117,Montcalm County,H1
+MI,26,119,Montmorency County,H1
+MI,26,121,Muskegon County,H1
+MI,26,123,Newaygo County,H1
+MI,26,125,Oakland County,H1
+MI,26,127,Oceana County,H1
+MI,26,129,Ogemaw County,H1
+MI,26,131,Ontonagon County,H1
+MI,26,133,Osceola County,H1
+MI,26,135,Oscoda County,H1
+MI,26,137,Otsego County,H1
+MI,26,139,Ottawa County,H1
+MI,26,141,Presque Isle County,H1
+MI,26,143,Roscommon County,H1
+MI,26,145,Saginaw County,H1
+MI,26,147,St. Clair County,H1
+MI,26,149,St. Joseph County,H1
+MI,26,151,Sanilac County,H1
+MI,26,153,Schoolcraft County,H1
+MI,26,155,Shiawassee County,H1
+MI,26,157,Tuscola County,H1
+MI,26,159,Van Buren County,H1
+MI,26,161,Washtenaw County,H1
+MI,26,163,Wayne County,H1
+MI,26,165,Wexford County,H1
+MN,27,001,Aitkin County,H1
+MN,27,003,Anoka County,H1
+MN,27,005,Becker County,H1
+MN,27,007,Beltrami County,H1
+MN,27,009,Benton County,H1
+MN,27,011,Big Stone County,H1
+MN,27,013,Blue Earth County,H1
+MN,27,015,Brown County,H1
+MN,27,017,Carlton County,H1
+MN,27,019,Carver County,H1
+MN,27,021,Cass County,H1
+MN,27,023,Chippewa County,H1
+MN,27,025,Chisago County,H1
+MN,27,027,Clay County,H1
+MN,27,029,Clearwater County,H1
+MN,27,031,Cook County,H1
+MN,27,033,Cottonwood County,H1
+MN,27,035,Crow Wing County,H1
+MN,27,037,Dakota County,H1
+MN,27,039,Dodge County,H1
+MN,27,041,Douglas County,H1
+MN,27,043,Faribault County,H1
+MN,27,045,Fillmore County,H1
+MN,27,047,Freeborn County,H1
+MN,27,049,Goodhue County,H1
+MN,27,051,Grant County,H1
+MN,27,053,Hennepin County,H1
+MN,27,055,Houston County,H1
+MN,27,057,Hubbard County,H1
+MN,27,059,Isanti County,H1
+MN,27,061,Itasca County,H1
+MN,27,063,Jackson County,H1
+MN,27,065,Kanabec County,H1
+MN,27,067,Kandiyohi County,H1
+MN,27,069,Kittson County,H1
+MN,27,071,Koochiching County,H1
+MN,27,073,Lac qui Parle County,H1
+MN,27,075,Lake County,H1
+MN,27,077,Lake of the Woods County,H1
+MN,27,079,Le Sueur County,H1
+MN,27,081,Lincoln County,H1
+MN,27,083,Lyon County,H1
+MN,27,085,McLeod County,H1
+MN,27,087,Mahnomen County,H1
+MN,27,089,Marshall County,H1
+MN,27,091,Martin County,H1
+MN,27,093,Meeker County,H1
+MN,27,095,Mille Lacs County,H1
+MN,27,097,Morrison County,H1
+MN,27,099,Mower County,H1
+MN,27,101,Murray County,H1
+MN,27,103,Nicollet County,H1
+MN,27,105,Nobles County,H1
+MN,27,107,Norman County,H1
+MN,27,109,Olmsted County,H1
+MN,27,111,Otter Tail County,H1
+MN,27,113,Pennington County,H1
+MN,27,115,Pine County,H1
+MN,27,117,Pipestone County,H1
+MN,27,119,Polk County,H1
+MN,27,121,Pope County,H1
+MN,27,123,Ramsey County,H1
+MN,27,125,Red Lake County,H1
+MN,27,127,Redwood County,H1
+MN,27,129,Renville County,H1
+MN,27,131,Rice County,H1
+MN,27,133,Rock County,H1
+MN,27,135,Roseau County,H1
+MN,27,137,St. Louis County,H1
+MN,27,139,Scott County,H1
+MN,27,141,Sherburne County,H1
+MN,27,143,Sibley County,H1
+MN,27,145,Stearns County,H1
+MN,27,147,Steele County,H1
+MN,27,149,Stevens County,H1
+MN,27,151,Swift County,H1
+MN,27,153,Todd County,H1
+MN,27,155,Traverse County,H1
+MN,27,157,Wabasha County,H1
+MN,27,159,Wadena County,H1
+MN,27,161,Waseca County,H1
+MN,27,163,Washington County,H1
+MN,27,165,Watonwan County,H1
+MN,27,167,Wilkin County,H1
+MN,27,169,Winona County,H1
+MN,27,171,Wright County,H1
+MN,27,173,Yellow Medicine County,H1
+MS,28,001,Adams County,H1
+MS,28,003,Alcorn County,H1
+MS,28,005,Amite County,H1
+MS,28,007,Attala County,H1
+MS,28,009,Benton County,H1
+MS,28,011,Bolivar County,H1
+MS,28,013,Calhoun County,H1
+MS,28,015,Carroll County,H1
+MS,28,017,Chickasaw County,H1
+MS,28,019,Choctaw County,H1
+MS,28,021,Claiborne County,H1
+MS,28,023,Clarke County,H1
+MS,28,025,Clay County,H1
+MS,28,027,Coahoma County,H1
+MS,28,029,Copiah County,H1
+MS,28,031,Covington County,H1
+MS,28,033,DeSoto County,H1
+MS,28,035,Forrest County,H1
+MS,28,037,Franklin County,H1
+MS,28,039,George County,H1
+MS,28,041,Greene County,H1
+MS,28,043,Grenada County,H1
+MS,28,045,Hancock County,H1
+MS,28,047,Harrison County,H1
+MS,28,049,Hinds County,H1
+MS,28,051,Holmes County,H1
+MS,28,053,Humphreys County,H1
+MS,28,055,Issaquena County,H1
+MS,28,057,Itawamba County,H1
+MS,28,059,Jackson County,H1
+MS,28,061,Jasper County,H1
+MS,28,063,Jefferson County,H1
+MS,28,065,Jefferson Davis County,H1
+MS,28,067,Jones County,H1
+MS,28,069,Kemper County,H1
+MS,28,071,Lafayette County,H1
+MS,28,073,Lamar County,H1
+MS,28,075,Lauderdale County,H1
+MS,28,077,Lawrence County,H1
+MS,28,079,Leake County,H1
+MS,28,081,Lee County,H1
+MS,28,083,Leflore County,H1
+MS,28,085,Lincoln County,H1
+MS,28,087,Lowndes County,H1
+MS,28,089,Madison County,H1
+MS,28,091,Marion County,H1
+MS,28,093,Marshall County,H1
+MS,28,095,Monroe County,H1
+MS,28,097,Montgomery County,H1
+MS,28,099,Neshoba County,H1
+MS,28,101,Newton County,H1
+MS,28,103,Noxubee County,H1
+MS,28,105,Oktibbeha County,H1
+MS,28,107,Panola County,H1
+MS,28,109,Pearl River County,H1
+MS,28,111,Perry County,H1
+MS,28,113,Pike County,H1
+MS,28,115,Pontotoc County,H1
+MS,28,117,Prentiss County,H1
+MS,28,119,Quitman County,H1
+MS,28,121,Rankin County,H1
+MS,28,123,Scott County,H1
+MS,28,125,Sharkey County,H1
+MS,28,127,Simpson County,H1
+MS,28,129,Smith County,H1
+MS,28,131,Stone County,H1
+MS,28,133,Sunflower County,H1
+MS,28,135,Tallahatchie County,H1
+MS,28,137,Tate County,H1
+MS,28,139,Tippah County,H1
+MS,28,141,Tishomingo County,H1
+MS,28,143,Tunica County,H1
+MS,28,145,Union County,H1
+MS,28,147,Walthall County,H1
+MS,28,149,Warren County,H1
+MS,28,151,Washington County,H1
+MS,28,153,Wayne County,H1
+MS,28,155,Webster County,H1
+MS,28,157,Wilkinson County,H1
+MS,28,159,Winston County,H1
+MS,28,161,Yalobusha County,H1
+MS,28,163,Yazoo County,H1
+MO,29,001,Adair County,H1
+MO,29,003,Andrew County,H1
+MO,29,005,Atchison County,H1
+MO,29,007,Audrain County,H1
+MO,29,009,Barry County,H1
+MO,29,011,Barton County,H1
+MO,29,013,Bates County,H1
+MO,29,015,Benton County,H1
+MO,29,017,Bollinger County,H1
+MO,29,019,Boone County,H1
+MO,29,021,Buchanan County,H1
+MO,29,023,Butler County,H1
+MO,29,025,Caldwell County,H1
+MO,29,027,Callaway County,H1
+MO,29,029,Camden County,H1
+MO,29,031,Cape Girardeau County,H1
+MO,29,033,Carroll County,H1
+MO,29,035,Carter County,H1
+MO,29,037,Cass County,H1
+MO,29,039,Cedar County,H1
+MO,29,041,Chariton County,H1
+MO,29,043,Christian County,H1
+MO,29,045,Clark County,H1
+MO,29,047,Clay County,H1
+MO,29,049,Clinton County,H1
+MO,29,051,Cole County,H1
+MO,29,053,Cooper County,H1
+MO,29,055,Crawford County,H1
+MO,29,057,Dade County,H1
+MO,29,059,Dallas County,H1
+MO,29,061,Daviess County,H1
+MO,29,063,DeKalb County,H1
+MO,29,065,Dent County,H1
+MO,29,067,Douglas County,H1
+MO,29,069,Dunklin County,H1
+MO,29,071,Franklin County,H1
+MO,29,073,Gasconade County,H1
+MO,29,075,Gentry County,H1
+MO,29,077,Greene County,H1
+MO,29,079,Grundy County,H1
+MO,29,081,Harrison County,H1
+MO,29,083,Henry County,H1
+MO,29,085,Hickory County,H1
+MO,29,087,Holt County,H1
+MO,29,089,Howard County,H1
+MO,29,091,Howell County,H1
+MO,29,093,Iron County,H1
+MO,29,095,Jackson County,H1
+MO,29,097,Jasper County,H1
+MO,29,099,Jefferson County,H1
+MO,29,101,Johnson County,H1
+MO,29,103,Knox County,H1
+MO,29,105,Laclede County,H1
+MO,29,107,Lafayette County,H1
+MO,29,109,Lawrence County,H1
+MO,29,111,Lewis County,H1
+MO,29,113,Lincoln County,H1
+MO,29,115,Linn County,H1
+MO,29,117,Livingston County,H1
+MO,29,119,McDonald County,H1
+MO,29,121,Macon County,H1
+MO,29,123,Madison County,H1
+MO,29,125,Maries County,H1
+MO,29,127,Marion County,H1
+MO,29,129,Mercer County,H1
+MO,29,131,Miller County,H1
+MO,29,133,Mississippi County,H1
+MO,29,135,Moniteau County,H1
+MO,29,137,Monroe County,H1
+MO,29,139,Montgomery County,H1
+MO,29,141,Morgan County,H1
+MO,29,143,New Madrid County,H1
+MO,29,145,Newton County,H1
+MO,29,147,Nodaway County,H1
+MO,29,149,Oregon County,H1
+MO,29,151,Osage County,H1
+MO,29,153,Ozark County,H1
+MO,29,155,Pemiscot County,H1
+MO,29,157,Perry County,H1
+MO,29,159,Pettis County,H1
+MO,29,161,Phelps County,H1
+MO,29,163,Pike County,H1
+MO,29,165,Platte County,H1
+MO,29,167,Polk County,H1
+MO,29,169,Pulaski County,H1
+MO,29,171,Putnam County,H1
+MO,29,173,Ralls County,H1
+MO,29,175,Randolph County,H1
+MO,29,177,Ray County,H1
+MO,29,179,Reynolds County,H1
+MO,29,181,Ripley County,H1
+MO,29,183,St. Charles County,H1
+MO,29,185,St. Clair County,H1
+MO,29,186,Ste. Genevieve County,H1
+MO,29,187,St. Francois County,H1
+MO,29,189,St. Louis County,H1
+MO,29,195,Saline County,H1
+MO,29,197,Schuyler County,H1
+MO,29,199,Scotland County,H1
+MO,29,201,Scott County,H1
+MO,29,203,Shannon County,H1
+MO,29,205,Shelby County,H1
+MO,29,207,Stoddard County,H1
+MO,29,209,Stone County,H1
+MO,29,211,Sullivan County,H1
+MO,29,213,Taney County,H1
+MO,29,215,Texas County,H1
+MO,29,217,Vernon County,H1
+MO,29,219,Warren County,H1
+MO,29,221,Washington County,H1
+MO,29,223,Wayne County,H1
+MO,29,225,Webster County,H1
+MO,29,227,Worth County,H1
+MO,29,229,Wright County,H1
+MO,29,510,St. Louis city,C7
+MT,30,001,Beaverhead County,H1
+MT,30,003,Big Horn County,H1
+MT,30,005,Blaine County,H1
+MT,30,007,Broadwater County,H1
+MT,30,009,Carbon County,H1
+MT,30,011,Carter County,H1
+MT,30,013,Cascade County,H1
+MT,30,015,Chouteau County,H1
+MT,30,017,Custer County,H1
+MT,30,019,Daniels County,H1
+MT,30,021,Dawson County,H1
+MT,30,023,Deer Lodge County,H6
+MT,30,025,Fallon County,H1
+MT,30,027,Fergus County,H1
+MT,30,029,Flathead County,H1
+MT,30,031,Gallatin County,H1
+MT,30,033,Garfield County,H1
+MT,30,035,Glacier County,H1
+MT,30,037,Golden Valley County,H1
+MT,30,039,Granite County,H1
+MT,30,041,Hill County,H1
+MT,30,043,Jefferson County,H1
+MT,30,045,Judith Basin County,H1
+MT,30,047,Lake County,H1
+MT,30,049,Lewis and Clark County,H1
+MT,30,051,Liberty County,H1
+MT,30,053,Lincoln County,H1
+MT,30,055,McCone County,H1
+MT,30,057,Madison County,H1
+MT,30,059,Meagher County,H1
+MT,30,061,Mineral County,H1
+MT,30,063,Missoula County,H1
+MT,30,065,Musselshell County,H1
+MT,30,067,Park County,H1
+MT,30,069,Petroleum County,H1
+MT,30,071,Phillips County,H1
+MT,30,073,Pondera County,H1
+MT,30,075,Powder River County,H1
+MT,30,077,Powell County,H1
+MT,30,079,Prairie County,H1
+MT,30,081,Ravalli County,H1
+MT,30,083,Richland County,H1
+MT,30,085,Roosevelt County,H1
+MT,30,087,Rosebud County,H1
+MT,30,089,Sanders County,H1
+MT,30,091,Sheridan County,H1
+MT,30,093,Silver Bow County,H6
+MT,30,095,Stillwater County,H1
+MT,30,097,Sweet Grass County,H1
+MT,30,099,Teton County,H1
+MT,30,101,Toole County,H1
+MT,30,103,Treasure County,H1
+MT,30,105,Valley County,H1
+MT,30,107,Wheatland County,H1
+MT,30,109,Wibaux County,H1
+MT,30,111,Yellowstone County,H1
+NE,31,001,Adams County,H1
+NE,31,003,Antelope County,H1
+NE,31,005,Arthur County,H1
+NE,31,007,Banner County,H1
+NE,31,009,Blaine County,H1
+NE,31,011,Boone County,H1
+NE,31,013,Box Butte County,H1
+NE,31,015,Boyd County,H1
+NE,31,017,Brown County,H1
+NE,31,019,Buffalo County,H1
+NE,31,021,Burt County,H1
+NE,31,023,Butler County,H1
+NE,31,025,Cass County,H1
+NE,31,027,Cedar County,H1
+NE,31,029,Chase County,H1
+NE,31,031,Cherry County,H1
+NE,31,033,Cheyenne County,H1
+NE,31,035,Clay County,H1
+NE,31,037,Colfax County,H1
+NE,31,039,Cuming County,H1
+NE,31,041,Custer County,H1
+NE,31,043,Dakota County,H1
+NE,31,045,Dawes County,H1
+NE,31,047,Dawson County,H1
+NE,31,049,Deuel County,H1
+NE,31,051,Dixon County,H1
+NE,31,053,Dodge County,H1
+NE,31,055,Douglas County,H1
+NE,31,057,Dundy County,H1
+NE,31,059,Fillmore County,H1
+NE,31,061,Franklin County,H1
+NE,31,063,Frontier County,H1
+NE,31,065,Furnas County,H1
+NE,31,067,Gage County,H1
+NE,31,069,Garden County,H1
+NE,31,071,Garfield County,H1
+NE,31,073,Gosper County,H1
+NE,31,075,Grant County,H1
+NE,31,077,Greeley County,H1
+NE,31,079,Hall County,H1
+NE,31,081,Hamilton County,H1
+NE,31,083,Harlan County,H1
+NE,31,085,Hayes County,H1
+NE,31,087,Hitchcock County,H1
+NE,31,089,Holt County,H1
+NE,31,091,Hooker County,H1
+NE,31,093,Howard County,H1
+NE,31,095,Jefferson County,H1
+NE,31,097,Johnson County,H1
+NE,31,099,Kearney County,H1
+NE,31,101,Keith County,H1
+NE,31,103,Keya Paha County,H1
+NE,31,105,Kimball County,H1
+NE,31,107,Knox County,H1
+NE,31,109,Lancaster County,H1
+NE,31,111,Lincoln County,H1
+NE,31,113,Logan County,H1
+NE,31,115,Loup County,H1
+NE,31,117,McPherson County,H1
+NE,31,119,Madison County,H1
+NE,31,121,Merrick County,H1
+NE,31,123,Morrill County,H1
+NE,31,125,Nance County,H1
+NE,31,127,Nemaha County,H1
+NE,31,129,Nuckolls County,H1
+NE,31,131,Otoe County,H1
+NE,31,133,Pawnee County,H1
+NE,31,135,Perkins County,H1
+NE,31,137,Phelps County,H1
+NE,31,139,Pierce County,H1
+NE,31,141,Platte County,H1
+NE,31,143,Polk County,H1
+NE,31,145,Red Willow County,H1
+NE,31,147,Richardson County,H1
+NE,31,149,Rock County,H1
+NE,31,151,Saline County,H1
+NE,31,153,Sarpy County,H1
+NE,31,155,Saunders County,H1
+NE,31,157,Scotts Bluff County,H1
+NE,31,159,Seward County,H1
+NE,31,161,Sheridan County,H1
+NE,31,163,Sherman County,H1
+NE,31,165,Sioux County,H1
+NE,31,167,Stanton County,H1
+NE,31,169,Thayer County,H1
+NE,31,171,Thomas County,H1
+NE,31,173,Thurston County,H1
+NE,31,175,Valley County,H1
+NE,31,177,Washington County,H1
+NE,31,179,Wayne County,H1
+NE,31,181,Webster County,H1
+NE,31,183,Wheeler County,H1
+NE,31,185,York County,H1
+NV,32,001,Churchill County,H1
+NV,32,003,Clark County,H1
+NV,32,005,Douglas County,H1
+NV,32,007,Elko County,H1
+NV,32,009,Esmeralda County,H1
+NV,32,011,Eureka County,H1
+NV,32,013,Humboldt County,H1
+NV,32,015,Lander County,H1
+NV,32,017,Lincoln County,H1
+NV,32,019,Lyon County,H1
+NV,32,021,Mineral County,H1
+NV,32,023,Nye County,H1
+NV,32,027,Pershing County,H1
+NV,32,029,Storey County,H1
+NV,32,031,Washoe County,H1
+NV,32,033,White Pine County,H1
+NV,32,510,Carson City,C7
+NH,33,001,Belknap County,H1
+NH,33,003,Carroll County,H1
+NH,33,005,Cheshire County,H1
+NH,33,007,Coos County,H1
+NH,33,009,Grafton County,H1
+NH,33,011,Hillsborough County,H1
+NH,33,013,Merrimack County,H1
+NH,33,015,Rockingham County,H1
+NH,33,017,Strafford County,H1
+NH,33,019,Sullivan County,H1
+NJ,34,001,Atlantic County,H1
+NJ,34,003,Bergen County,H1
+NJ,34,005,Burlington County,H1
+NJ,34,007,Camden County,H1
+NJ,34,009,Cape May County,H1
+NJ,34,011,Cumberland County,H1
+NJ,34,013,Essex County,H1
+NJ,34,015,Gloucester County,H1
+NJ,34,017,Hudson County,H1
+NJ,34,019,Hunterdon County,H1
+NJ,34,021,Mercer County,H1
+NJ,34,023,Middlesex County,H1
+NJ,34,025,Monmouth County,H1
+NJ,34,027,Morris County,H1
+NJ,34,029,Ocean County,H1
+NJ,34,031,Passaic County,H1
+NJ,34,033,Salem County,H1
+NJ,34,035,Somerset County,H1
+NJ,34,037,Sussex County,H1
+NJ,34,039,Union County,H1
+NJ,34,041,Warren County,H1
+NM,35,001,Bernalillo County,H1
+NM,35,003,Catron County,H1
+NM,35,005,Chaves County,H1
+NM,35,006,Cibola County,H1
+NM,35,007,Colfax County,H1
+NM,35,009,Curry County,H1
+NM,35,011,De Baca County,H1
+NM,35,013,Dona Ana County,H1
+NM,35,015,Eddy County,H1
+NM,35,017,Grant County,H1
+NM,35,019,Guadalupe County,H1
+NM,35,021,Harding County,H1
+NM,35,023,Hidalgo County,H1
+NM,35,025,Lea County,H1
+NM,35,027,Lincoln County,H1
+NM,35,028,Los Alamos County,H1
+NM,35,029,Luna County,H1
+NM,35,031,McKinley County,H1
+NM,35,033,Mora County,H1
+NM,35,035,Otero County,H1
+NM,35,037,Quay County,H1
+NM,35,039,Rio Arriba County,H1
+NM,35,041,Roosevelt County,H1
+NM,35,043,Sandoval County,H1
+NM,35,045,San Juan County,H1
+NM,35,047,San Miguel County,H1
+NM,35,049,Santa Fe County,H1
+NM,35,051,Sierra County,H1
+NM,35,053,Socorro County,H1
+NM,35,055,Taos County,H1
+NM,35,057,Torrance County,H1
+NM,35,059,Union County,H1
+NM,35,061,Valencia County,H1
+NY,36,001,Albany County,H1
+NY,36,003,Allegany County,H1
+NY,36,005,Bronx County,H6
+NY,36,007,Broome County,H1
+NY,36,009,Cattaraugus County,H1
+NY,36,011,Cayuga County,H1
+NY,36,013,Chautauqua County,H1
+NY,36,015,Chemung County,H1
+NY,36,017,Chenango County,H1
+NY,36,019,Clinton County,H1
+NY,36,021,Columbia County,H1
+NY,36,023,Cortland County,H1
+NY,36,025,Delaware County,H1
+NY,36,027,Dutchess County,H1
+NY,36,029,Erie County,H1
+NY,36,031,Essex County,H1
+NY,36,033,Franklin County,H1
+NY,36,035,Fulton County,H1
+NY,36,037,Genesee County,H1
+NY,36,039,Greene County,H1
+NY,36,041,Hamilton County,H1
+NY,36,043,Herkimer County,H1
+NY,36,045,Jefferson County,H1
+NY,36,047,Kings County,H6
+NY,36,049,Lewis County,H1
+NY,36,051,Livingston County,H1
+NY,36,053,Madison County,H1
+NY,36,055,Monroe County,H1
+NY,36,057,Montgomery County,H1
+NY,36,059,Nassau County,H1
+NY,36,061,New York County,H6
+NY,36,063,Niagara County,H1
+NY,36,065,Oneida County,H1
+NY,36,067,Onondaga County,H1
+NY,36,069,Ontario County,H1
+NY,36,071,Orange County,H1
+NY,36,073,Orleans County,H1
+NY,36,075,Oswego County,H1
+NY,36,077,Otsego County,H1
+NY,36,079,Putnam County,H1
+NY,36,081,Queens County,H6
+NY,36,083,Rensselaer County,H1
+NY,36,085,Richmond County,H6
+NY,36,087,Rockland County,H1
+NY,36,089,St. Lawrence County,H1
+NY,36,091,Saratoga County,H1
+NY,36,093,Schenectady County,H1
+NY,36,095,Schoharie County,H1
+NY,36,097,Schuyler County,H1
+NY,36,099,Seneca County,H1
+NY,36,101,Steuben County,H1
+NY,36,103,Suffolk County,H1
+NY,36,105,Sullivan County,H1
+NY,36,107,Tioga County,H1
+NY,36,109,Tompkins County,H1
+NY,36,111,Ulster County,H1
+NY,36,113,Warren County,H1
+NY,36,115,Washington County,H1
+NY,36,117,Wayne County,H1
+NY,36,119,Westchester County,H1
+NY,36,121,Wyoming County,H1
+NY,36,123,Yates County,H1
+NC,37,001,Alamance County,H1
+NC,37,003,Alexander County,H1
+NC,37,005,Alleghany County,H1
+NC,37,007,Anson County,H1
+NC,37,009,Ashe County,H1
+NC,37,011,Avery County,H1
+NC,37,013,Beaufort County,H1
+NC,37,015,Bertie County,H1
+NC,37,017,Bladen County,H1
+NC,37,019,Brunswick County,H1
+NC,37,021,Buncombe County,H1
+NC,37,023,Burke County,H1
+NC,37,025,Cabarrus County,H1
+NC,37,027,Caldwell County,H1
+NC,37,029,Camden County,H1
+NC,37,031,Carteret County,H1
+NC,37,033,Caswell County,H1
+NC,37,035,Catawba County,H1
+NC,37,037,Chatham County,H1
+NC,37,039,Cherokee County,H1
+NC,37,041,Chowan County,H1
+NC,37,043,Clay County,H1
+NC,37,045,Cleveland County,H1
+NC,37,047,Columbus County,H1
+NC,37,049,Craven County,H1
+NC,37,051,Cumberland County,H1
+NC,37,053,Currituck County,H1
+NC,37,055,Dare County,H1
+NC,37,057,Davidson County,H1
+NC,37,059,Davie County,H1
+NC,37,061,Duplin County,H1
+NC,37,063,Durham County,H1
+NC,37,065,Edgecombe County,H1
+NC,37,067,Forsyth County,H1
+NC,37,069,Franklin County,H1
+NC,37,071,Gaston County,H1
+NC,37,073,Gates County,H1
+NC,37,075,Graham County,H1
+NC,37,077,Granville County,H1
+NC,37,079,Greene County,H1
+NC,37,081,Guilford County,H1
+NC,37,083,Halifax County,H1
+NC,37,085,Harnett County,H1
+NC,37,087,Haywood County,H1
+NC,37,089,Henderson County,H1
+NC,37,091,Hertford County,H1
+NC,37,093,Hoke County,H1
+NC,37,095,Hyde County,H1
+NC,37,097,Iredell County,H1
+NC,37,099,Jackson County,H1
+NC,37,101,Johnston County,H1
+NC,37,103,Jones County,H1
+NC,37,105,Lee County,H1
+NC,37,107,Lenoir County,H1
+NC,37,109,Lincoln County,H1
+NC,37,111,McDowell County,H1
+NC,37,113,Macon County,H1
+NC,37,115,Madison County,H1
+NC,37,117,Martin County,H1
+NC,37,119,Mecklenburg County,H1
+NC,37,121,Mitchell County,H1
+NC,37,123,Montgomery County,H1
+NC,37,125,Moore County,H1
+NC,37,127,Nash County,H1
+NC,37,129,New Hanover County,H1
+NC,37,131,Northampton County,H1
+NC,37,133,Onslow County,H1
+NC,37,135,Orange County,H1
+NC,37,137,Pamlico County,H1
+NC,37,139,Pasquotank County,H1
+NC,37,141,Pender County,H1
+NC,37,143,Perquimans County,H1
+NC,37,145,Person County,H1
+NC,37,147,Pitt County,H1
+NC,37,149,Polk County,H1
+NC,37,151,Randolph County,H1
+NC,37,153,Richmond County,H1
+NC,37,155,Robeson County,H1
+NC,37,157,Rockingham County,H1
+NC,37,159,Rowan County,H1
+NC,37,161,Rutherford County,H1
+NC,37,163,Sampson County,H1
+NC,37,165,Scotland County,H1
+NC,37,167,Stanly County,H1
+NC,37,169,Stokes County,H1
+NC,37,171,Surry County,H1
+NC,37,173,Swain County,H1
+NC,37,175,Transylvania County,H1
+NC,37,177,Tyrrell County,H1
+NC,37,179,Union County,H1
+NC,37,181,Vance County,H1
+NC,37,183,Wake County,H1
+NC,37,185,Warren County,H1
+NC,37,187,Washington County,H1
+NC,37,189,Watauga County,H1
+NC,37,191,Wayne County,H1
+NC,37,193,Wilkes County,H1
+NC,37,195,Wilson County,H1
+NC,37,197,Yadkin County,H1
+NC,37,199,Yancey County,H1
+ND,38,001,Adams County,H1
+ND,38,003,Barnes County,H1
+ND,38,005,Benson County,H1
+ND,38,007,Billings County,H1
+ND,38,009,Bottineau County,H1
+ND,38,011,Bowman County,H1
+ND,38,013,Burke County,H1
+ND,38,015,Burleigh County,H1
+ND,38,017,Cass County,H1
+ND,38,019,Cavalier County,H1
+ND,38,021,Dickey County,H1
+ND,38,023,Divide County,H1
+ND,38,025,Dunn County,H1
+ND,38,027,Eddy County,H1
+ND,38,029,Emmons County,H1
+ND,38,031,Foster County,H1
+ND,38,033,Golden Valley County,H1
+ND,38,035,Grand Forks County,H1
+ND,38,037,Grant County,H1
+ND,38,039,Griggs County,H1
+ND,38,041,Hettinger County,H1
+ND,38,043,Kidder County,H1
+ND,38,045,LaMoure County,H1
+ND,38,047,Logan County,H1
+ND,38,049,McHenry County,H1
+ND,38,051,McIntosh County,H1
+ND,38,053,McKenzie County,H1
+ND,38,055,McLean County,H1
+ND,38,057,Mercer County,H1
+ND,38,059,Morton County,H1
+ND,38,061,Mountrail County,H1
+ND,38,063,Nelson County,H1
+ND,38,065,Oliver County,H1
+ND,38,067,Pembina County,H1
+ND,38,069,Pierce County,H1
+ND,38,071,Ramsey County,H1
+ND,38,073,Ransom County,H1
+ND,38,075,Renville County,H1
+ND,38,077,Richland County,H1
+ND,38,079,Rolette County,H1
+ND,38,081,Sargent County,H1
+ND,38,083,Sheridan County,H1
+ND,38,085,Sioux County,H1
+ND,38,087,Slope County,H1
+ND,38,089,Stark County,H1
+ND,38,091,Steele County,H1
+ND,38,093,Stutsman County,H1
+ND,38,095,Towner County,H1
+ND,38,097,Traill County,H1
+ND,38,099,Walsh County,H1
+ND,38,101,Ward County,H1
+ND,38,103,Wells County,H1
+ND,38,105,Williams County,H1
+OH,39,001,Adams County,H1
+OH,39,003,Allen County,H1
+OH,39,005,Ashland County,H1
+OH,39,007,Ashtabula County,H1
+OH,39,009,Athens County,H1
+OH,39,011,Auglaize County,H1
+OH,39,013,Belmont County,H1
+OH,39,015,Brown County,H1
+OH,39,017,Butler County,H1
+OH,39,019,Carroll County,H1
+OH,39,021,Champaign County,H1
+OH,39,023,Clark County,H1
+OH,39,025,Clermont County,H1
+OH,39,027,Clinton County,H1
+OH,39,029,Columbiana County,H1
+OH,39,031,Coshocton County,H1
+OH,39,033,Crawford County,H1
+OH,39,035,Cuyahoga County,H1
+OH,39,037,Darke County,H1
+OH,39,039,Defiance County,H1
+OH,39,041,Delaware County,H1
+OH,39,043,Erie County,H1
+OH,39,045,Fairfield County,H1
+OH,39,047,Fayette County,H1
+OH,39,049,Franklin County,H1
+OH,39,051,Fulton County,H1
+OH,39,053,Gallia County,H1
+OH,39,055,Geauga County,H1
+OH,39,057,Greene County,H1
+OH,39,059,Guernsey County,H1
+OH,39,061,Hamilton County,H1
+OH,39,063,Hancock County,H1
+OH,39,065,Hardin County,H1
+OH,39,067,Harrison County,H1
+OH,39,069,Henry County,H1
+OH,39,071,Highland County,H1
+OH,39,073,Hocking County,H1
+OH,39,075,Holmes County,H1
+OH,39,077,Huron County,H1
+OH,39,079,Jackson County,H1
+OH,39,081,Jefferson County,H1
+OH,39,083,Knox County,H1
+OH,39,085,Lake County,H1
+OH,39,087,Lawrence County,H1
+OH,39,089,Licking County,H1
+OH,39,091,Logan County,H1
+OH,39,093,Lorain County,H1
+OH,39,095,Lucas County,H1
+OH,39,097,Madison County,H1
+OH,39,099,Mahoning County,H1
+OH,39,101,Marion County,H1
+OH,39,103,Medina County,H1
+OH,39,105,Meigs County,H1
+OH,39,107,Mercer County,H1
+OH,39,109,Miami County,H1
+OH,39,111,Monroe County,H1
+OH,39,113,Montgomery County,H1
+OH,39,115,Morgan County,H1
+OH,39,117,Morrow County,H1
+OH,39,119,Muskingum County,H1
+OH,39,121,Noble County,H1
+OH,39,123,Ottawa County,H1
+OH,39,125,Paulding County,H1
+OH,39,127,Perry County,H1
+OH,39,129,Pickaway County,H1
+OH,39,131,Pike County,H1
+OH,39,133,Portage County,H1
+OH,39,135,Preble County,H1
+OH,39,137,Putnam County,H1
+OH,39,139,Richland County,H1
+OH,39,141,Ross County,H1
+OH,39,143,Sandusky County,H1
+OH,39,145,Scioto County,H1
+OH,39,147,Seneca County,H1
+OH,39,149,Shelby County,H1
+OH,39,151,Stark County,H1
+OH,39,153,Summit County,H1
+OH,39,155,Trumbull County,H1
+OH,39,157,Tuscarawas County,H1
+OH,39,159,Union County,H1
+OH,39,161,Van Wert County,H1
+OH,39,163,Vinton County,H1
+OH,39,165,Warren County,H1
+OH,39,167,Washington County,H1
+OH,39,169,Wayne County,H1
+OH,39,171,Williams County,H1
+OH,39,173,Wood County,H1
+OH,39,175,Wyandot County,H1
+OK,40,001,Adair County,H1
+OK,40,003,Alfalfa County,H1
+OK,40,005,Atoka County,H1
+OK,40,007,Beaver County,H1
+OK,40,009,Beckham County,H1
+OK,40,011,Blaine County,H1
+OK,40,013,Bryan County,H1
+OK,40,015,Caddo County,H1
+OK,40,017,Canadian County,H1
+OK,40,019,Carter County,H1
+OK,40,021,Cherokee County,H1
+OK,40,023,Choctaw County,H1
+OK,40,025,Cimarron County,H1
+OK,40,027,Cleveland County,H1
+OK,40,029,Coal County,H1
+OK,40,031,Comanche County,H1
+OK,40,033,Cotton County,H1
+OK,40,035,Craig County,H1
+OK,40,037,Creek County,H1
+OK,40,039,Custer County,H1
+OK,40,041,Delaware County,H1
+OK,40,043,Dewey County,H1
+OK,40,045,Ellis County,H1
+OK,40,047,Garfield County,H1
+OK,40,049,Garvin County,H1
+OK,40,051,Grady County,H1
+OK,40,053,Grant County,H1
+OK,40,055,Greer County,H1
+OK,40,057,Harmon County,H1
+OK,40,059,Harper County,H1
+OK,40,061,Haskell County,H1
+OK,40,063,Hughes County,H1
+OK,40,065,Jackson County,H1
+OK,40,067,Jefferson County,H1
+OK,40,069,Johnston County,H1
+OK,40,071,Kay County,H1
+OK,40,073,Kingfisher County,H1
+OK,40,075,Kiowa County,H1
+OK,40,077,Latimer County,H1
+OK,40,079,Le Flore County,H1
+OK,40,081,Lincoln County,H1
+OK,40,083,Logan County,H1
+OK,40,085,Love County,H1
+OK,40,087,McClain County,H1
+OK,40,089,McCurtain County,H1
+OK,40,091,McIntosh County,H1
+OK,40,093,Major County,H1
+OK,40,095,Marshall County,H1
+OK,40,097,Mayes County,H1
+OK,40,099,Murray County,H1
+OK,40,101,Muskogee County,H1
+OK,40,103,Noble County,H1
+OK,40,105,Nowata County,H1
+OK,40,107,Okfuskee County,H1
+OK,40,109,Oklahoma County,H1
+OK,40,111,Okmulgee County,H1
+OK,40,113,Osage County,H1
+OK,40,115,Ottawa County,H1
+OK,40,117,Pawnee County,H1
+OK,40,119,Payne County,H1
+OK,40,121,Pittsburg County,H1
+OK,40,123,Pontotoc County,H1
+OK,40,125,Pottawatomie County,H1
+OK,40,127,Pushmataha County,H1
+OK,40,129,Roger Mills County,H1
+OK,40,131,Rogers County,H1
+OK,40,133,Seminole County,H1
+OK,40,135,Sequoyah County,H1
+OK,40,137,Stephens County,H1
+OK,40,139,Texas County,H1
+OK,40,141,Tillman County,H1
+OK,40,143,Tulsa County,H1
+OK,40,145,Wagoner County,H1
+OK,40,147,Washington County,H1
+OK,40,149,Washita County,H1
+OK,40,151,Woods County,H1
+OK,40,153,Woodward County,H1
+OR,41,001,Baker County,H1
+OR,41,003,Benton County,H1
+OR,41,005,Clackamas County,H1
+OR,41,007,Clatsop County,H1
+OR,41,009,Columbia County,H1
+OR,41,011,Coos County,H1
+OR,41,013,Crook County,H1
+OR,41,015,Curry County,H1
+OR,41,017,Deschutes County,H1
+OR,41,019,Douglas County,H1
+OR,41,021,Gilliam County,H1
+OR,41,023,Grant County,H1
+OR,41,025,Harney County,H1
+OR,41,027,Hood River County,H1
+OR,41,029,Jackson County,H1
+OR,41,031,Jefferson County,H1
+OR,41,033,Josephine County,H1
+OR,41,035,Klamath County,H1
+OR,41,037,Lake County,H1
+OR,41,039,Lane County,H1
+OR,41,041,Lincoln County,H1
+OR,41,043,Linn County,H1
+OR,41,045,Malheur County,H1
+OR,41,047,Marion County,H1
+OR,41,049,Morrow County,H1
+OR,41,051,Multnomah County,H1
+OR,41,053,Polk County,H1
+OR,41,055,Sherman County,H1
+OR,41,057,Tillamook County,H1
+OR,41,059,Umatilla County,H1
+OR,41,061,Union County,H1
+OR,41,063,Wallowa County,H1
+OR,41,065,Wasco County,H1
+OR,41,067,Washington County,H1
+OR,41,069,Wheeler County,H1
+OR,41,071,Yamhill County,H1
+PA,42,001,Adams County,H1
+PA,42,003,Allegheny County,H1
+PA,42,005,Armstrong County,H1
+PA,42,007,Beaver County,H1
+PA,42,009,Bedford County,H1
+PA,42,011,Berks County,H1
+PA,42,013,Blair County,H1
+PA,42,015,Bradford County,H1
+PA,42,017,Bucks County,H1
+PA,42,019,Butler County,H1
+PA,42,021,Cambria County,H1
+PA,42,023,Cameron County,H1
+PA,42,025,Carbon County,H1
+PA,42,027,Centre County,H1
+PA,42,029,Chester County,H1
+PA,42,031,Clarion County,H1
+PA,42,033,Clearfield County,H1
+PA,42,035,Clinton County,H1
+PA,42,037,Columbia County,H1
+PA,42,039,Crawford County,H1
+PA,42,041,Cumberland County,H1
+PA,42,043,Dauphin County,H1
+PA,42,045,Delaware County,H1
+PA,42,047,Elk County,H1
+PA,42,049,Erie County,H1
+PA,42,051,Fayette County,H1
+PA,42,053,Forest County,H1
+PA,42,055,Franklin County,H1
+PA,42,057,Fulton County,H1
+PA,42,059,Greene County,H1
+PA,42,061,Huntingdon County,H1
+PA,42,063,Indiana County,H1
+PA,42,065,Jefferson County,H1
+PA,42,067,Juniata County,H1
+PA,42,069,Lackawanna County,H1
+PA,42,071,Lancaster County,H1
+PA,42,073,Lawrence County,H1
+PA,42,075,Lebanon County,H1
+PA,42,077,Lehigh County,H1
+PA,42,079,Luzerne County,H1
+PA,42,081,Lycoming County,H1
+PA,42,083,McKean County,H1
+PA,42,085,Mercer County,H1
+PA,42,087,Mifflin County,H1
+PA,42,089,Monroe County,H1
+PA,42,091,Montgomery County,H1
+PA,42,093,Montour County,H1
+PA,42,095,Northampton County,H1
+PA,42,097,Northumberland County,H1
+PA,42,099,Perry County,H1
+PA,42,101,Philadelphia County,H6
+PA,42,103,Pike County,H1
+PA,42,105,Potter County,H1
+PA,42,107,Schuylkill County,H1
+PA,42,109,Snyder County,H1
+PA,42,111,Somerset County,H1
+PA,42,113,Sullivan County,H1
+PA,42,115,Susquehanna County,H1
+PA,42,117,Tioga County,H1
+PA,42,119,Union County,H1
+PA,42,121,Venango County,H1
+PA,42,123,Warren County,H1
+PA,42,125,Washington County,H1
+PA,42,127,Wayne County,H1
+PA,42,129,Westmoreland County,H1
+PA,42,131,Wyoming County,H1
+PA,42,133,York County,H1
+RI,44,001,Bristol County,H4
+RI,44,003,Kent County,H4
+RI,44,005,Newport County,H4
+RI,44,007,Providence County,H4
+RI,44,009,Washington County,H4
+SC,45,001,Abbeville County,H1
+SC,45,003,Aiken County,H1
+SC,45,005,Allendale County,H1
+SC,45,007,Anderson County,H1
+SC,45,009,Bamberg County,H1
+SC,45,011,Barnwell County,H1
+SC,45,013,Beaufort County,H1
+SC,45,015,Berkeley County,H1
+SC,45,017,Calhoun County,H1
+SC,45,019,Charleston County,H1
+SC,45,021,Cherokee County,H1
+SC,45,023,Chester County,H1
+SC,45,025,Chesterfield County,H1
+SC,45,027,Clarendon County,H1
+SC,45,029,Colleton County,H1
+SC,45,031,Darlington County,H1
+SC,45,033,Dillon County,H1
+SC,45,035,Dorchester County,H1
+SC,45,037,Edgefield County,H1
+SC,45,039,Fairfield County,H1
+SC,45,041,Florence County,H1
+SC,45,043,Georgetown County,H1
+SC,45,045,Greenville County,H1
+SC,45,047,Greenwood County,H1
+SC,45,049,Hampton County,H1
+SC,45,051,Horry County,H1
+SC,45,053,Jasper County,H1
+SC,45,055,Kershaw County,H1
+SC,45,057,Lancaster County,H1
+SC,45,059,Laurens County,H1
+SC,45,061,Lee County,H1
+SC,45,063,Lexington County,H1
+SC,45,065,McCormick County,H1
+SC,45,067,Marion County,H1
+SC,45,069,Marlboro County,H1
+SC,45,071,Newberry County,H1
+SC,45,073,Oconee County,H1
+SC,45,075,Orangeburg County,H1
+SC,45,077,Pickens County,H1
+SC,45,079,Richland County,H1
+SC,45,081,Saluda County,H1
+SC,45,083,Spartanburg County,H1
+SC,45,085,Sumter County,H1
+SC,45,087,Union County,H1
+SC,45,089,Williamsburg County,H1
+SC,45,091,York County,H1
+SD,46,003,Aurora County,H1
+SD,46,005,Beadle County,H1
+SD,46,007,Bennett County,H1
+SD,46,009,Bon Homme County,H1
+SD,46,011,Brookings County,H1
+SD,46,013,Brown County,H1
+SD,46,015,Brule County,H1
+SD,46,017,Buffalo County,H1
+SD,46,019,Butte County,H1
+SD,46,021,Campbell County,H1
+SD,46,023,Charles Mix County,H1
+SD,46,025,Clark County,H1
+SD,46,027,Clay County,H1
+SD,46,029,Codington County,H1
+SD,46,031,Corson County,H1
+SD,46,033,Custer County,H1
+SD,46,035,Davison County,H1
+SD,46,037,Day County,H1
+SD,46,039,Deuel County,H1
+SD,46,041,Dewey County,H1
+SD,46,043,Douglas County,H1
+SD,46,045,Edmunds County,H1
+SD,46,047,Fall River County,H1
+SD,46,049,Faulk County,H1
+SD,46,051,Grant County,H1
+SD,46,053,Gregory County,H1
+SD,46,055,Haakon County,H1
+SD,46,057,Hamlin County,H1
+SD,46,059,Hand County,H1
+SD,46,061,Hanson County,H1
+SD,46,063,Harding County,H1
+SD,46,065,Hughes County,H1
+SD,46,067,Hutchinson County,H1
+SD,46,069,Hyde County,H1
+SD,46,071,Jackson County,H1
+SD,46,073,Jerauld County,H1
+SD,46,075,Jones County,H1
+SD,46,077,Kingsbury County,H1
+SD,46,079,Lake County,H1
+SD,46,081,Lawrence County,H1
+SD,46,083,Lincoln County,H1
+SD,46,085,Lyman County,H1
+SD,46,087,McCook County,H1
+SD,46,089,McPherson County,H1
+SD,46,091,Marshall County,H1
+SD,46,093,Meade County,H1
+SD,46,095,Mellette County,H1
+SD,46,097,Miner County,H1
+SD,46,099,Minnehaha County,H1
+SD,46,101,Moody County,H1
+SD,46,103,Pennington County,H1
+SD,46,105,Perkins County,H1
+SD,46,107,Potter County,H1
+SD,46,109,Roberts County,H1
+SD,46,111,Sanborn County,H1
+SD,46,113,Shannon County,H1
+SD,46,115,Spink County,H1
+SD,46,117,Stanley County,H1
+SD,46,119,Sully County,H1
+SD,46,121,Todd County,H1
+SD,46,123,Tripp County,H1
+SD,46,125,Turner County,H1
+SD,46,127,Union County,H1
+SD,46,129,Walworth County,H1
+SD,46,135,Yankton County,H1
+SD,46,137,Ziebach County,H1
+TN,47,001,Anderson County,H1
+TN,47,003,Bedford County,H1
+TN,47,005,Benton County,H1
+TN,47,007,Bledsoe County,H1
+TN,47,009,Blount County,H1
+TN,47,011,Bradley County,H1
+TN,47,013,Campbell County,H1
+TN,47,015,Cannon County,H1
+TN,47,017,Carroll County,H1
+TN,47,019,Carter County,H1
+TN,47,021,Cheatham County,H1
+TN,47,023,Chester County,H1
+TN,47,025,Claiborne County,H1
+TN,47,027,Clay County,H1
+TN,47,029,Cocke County,H1
+TN,47,031,Coffee County,H1
+TN,47,033,Crockett County,H1
+TN,47,035,Cumberland County,H1
+TN,47,037,Davidson County,H6
+TN,47,039,Decatur County,H1
+TN,47,041,DeKalb County,H1
+TN,47,043,Dickson County,H1
+TN,47,045,Dyer County,H1
+TN,47,047,Fayette County,H1
+TN,47,049,Fentress County,H1
+TN,47,051,Franklin County,H1
+TN,47,053,Gibson County,H1
+TN,47,055,Giles County,H1
+TN,47,057,Grainger County,H1
+TN,47,059,Greene County,H1
+TN,47,061,Grundy County,H1
+TN,47,063,Hamblen County,H1
+TN,47,065,Hamilton County,H1
+TN,47,067,Hancock County,H1
+TN,47,069,Hardeman County,H1
+TN,47,071,Hardin County,H1
+TN,47,073,Hawkins County,H1
+TN,47,075,Haywood County,H1
+TN,47,077,Henderson County,H1
+TN,47,079,Henry County,H1
+TN,47,081,Hickman County,H1
+TN,47,083,Houston County,H1
+TN,47,085,Humphreys County,H1
+TN,47,087,Jackson County,H1
+TN,47,089,Jefferson County,H1
+TN,47,091,Johnson County,H1
+TN,47,093,Knox County,H1
+TN,47,095,Lake County,H1
+TN,47,097,Lauderdale County,H1
+TN,47,099,Lawrence County,H1
+TN,47,101,Lewis County,H1
+TN,47,103,Lincoln County,H1
+TN,47,105,Loudon County,H1
+TN,47,107,McMinn County,H1
+TN,47,109,McNairy County,H1
+TN,47,111,Macon County,H1
+TN,47,113,Madison County,H1
+TN,47,115,Marion County,H1
+TN,47,117,Marshall County,H1
+TN,47,119,Maury County,H1
+TN,47,121,Meigs County,H1
+TN,47,123,Monroe County,H1
+TN,47,125,Montgomery County,H1
+TN,47,127,Moore County,H6
+TN,47,129,Morgan County,H1
+TN,47,131,Obion County,H1
+TN,47,133,Overton County,H1
+TN,47,135,Perry County,H1
+TN,47,137,Pickett County,H1
+TN,47,139,Polk County,H1
+TN,47,141,Putnam County,H1
+TN,47,143,Rhea County,H1
+TN,47,145,Roane County,H1
+TN,47,147,Robertson County,H1
+TN,47,149,Rutherford County,H1
+TN,47,151,Scott County,H1
+TN,47,153,Sequatchie County,H1
+TN,47,155,Sevier County,H1
+TN,47,157,Shelby County,H1
+TN,47,159,Smith County,H1
+TN,47,161,Stewart County,H1
+TN,47,163,Sullivan County,H1
+TN,47,165,Sumner County,H1
+TN,47,167,Tipton County,H1
+TN,47,169,Trousdale County,H6
+TN,47,171,Unicoi County,H1
+TN,47,173,Union County,H1
+TN,47,175,Van Buren County,H1
+TN,47,177,Warren County,H1
+TN,47,179,Washington County,H1
+TN,47,181,Wayne County,H1
+TN,47,183,Weakley County,H1
+TN,47,185,White County,H1
+TN,47,187,Williamson County,H1
+TN,47,189,Wilson County,H1
+TX,48,001,Anderson County,H1
+TX,48,003,Andrews County,H1
+TX,48,005,Angelina County,H1
+TX,48,007,Aransas County,H1
+TX,48,009,Archer County,H1
+TX,48,011,Armstrong County,H1
+TX,48,013,Atascosa County,H1
+TX,48,015,Austin County,H1
+TX,48,017,Bailey County,H1
+TX,48,019,Bandera County,H1
+TX,48,021,Bastrop County,H1
+TX,48,023,Baylor County,H1
+TX,48,025,Bee County,H1
+TX,48,027,Bell County,H1
+TX,48,029,Bexar County,H1
+TX,48,031,Blanco County,H1
+TX,48,033,Borden County,H1
+TX,48,035,Bosque County,H1
+TX,48,037,Bowie County,H1
+TX,48,039,Brazoria County,H1
+TX,48,041,Brazos County,H1
+TX,48,043,Brewster County,H1
+TX,48,045,Briscoe County,H1
+TX,48,047,Brooks County,H1
+TX,48,049,Brown County,H1
+TX,48,051,Burleson County,H1
+TX,48,053,Burnet County,H1
+TX,48,055,Caldwell County,H1
+TX,48,057,Calhoun County,H1
+TX,48,059,Callahan County,H1
+TX,48,061,Cameron County,H1
+TX,48,063,Camp County,H1
+TX,48,065,Carson County,H1
+TX,48,067,Cass County,H1
+TX,48,069,Castro County,H1
+TX,48,071,Chambers County,H1
+TX,48,073,Cherokee County,H1
+TX,48,075,Childress County,H1
+TX,48,077,Clay County,H1
+TX,48,079,Cochran County,H1
+TX,48,081,Coke County,H1
+TX,48,083,Coleman County,H1
+TX,48,085,Collin County,H1
+TX,48,087,Collingsworth County,H1
+TX,48,089,Colorado County,H1
+TX,48,091,Comal County,H1
+TX,48,093,Comanche County,H1
+TX,48,095,Concho County,H1
+TX,48,097,Cooke County,H1
+TX,48,099,Coryell County,H1
+TX,48,101,Cottle County,H1
+TX,48,103,Crane County,H1
+TX,48,105,Crockett County,H1
+TX,48,107,Crosby County,H1
+TX,48,109,Culberson County,H1
+TX,48,111,Dallam County,H1
+TX,48,113,Dallas County,H1
+TX,48,115,Dawson County,H1
+TX,48,117,Deaf Smith County,H1
+TX,48,119,Delta County,H1
+TX,48,121,Denton County,H1
+TX,48,123,DeWitt County,H1
+TX,48,125,Dickens County,H1
+TX,48,127,Dimmit County,H1
+TX,48,129,Donley County,H1
+TX,48,131,Duval County,H1
+TX,48,133,Eastland County,H1
+TX,48,135,Ector County,H1
+TX,48,137,Edwards County,H1
+TX,48,139,Ellis County,H1
+TX,48,141,El Paso County,H1
+TX,48,143,Erath County,H1
+TX,48,145,Falls County,H1
+TX,48,147,Fannin County,H1
+TX,48,149,Fayette County,H1
+TX,48,151,Fisher County,H1
+TX,48,153,Floyd County,H1
+TX,48,155,Foard County,H1
+TX,48,157,Fort Bend County,H1
+TX,48,159,Franklin County,H1
+TX,48,161,Freestone County,H1
+TX,48,163,Frio County,H1
+TX,48,165,Gaines County,H1
+TX,48,167,Galveston County,H1
+TX,48,169,Garza County,H1
+TX,48,171,Gillespie County,H1
+TX,48,173,Glasscock County,H1
+TX,48,175,Goliad County,H1
+TX,48,177,Gonzales County,H1
+TX,48,179,Gray County,H1
+TX,48,181,Grayson County,H1
+TX,48,183,Gregg County,H1
+TX,48,185,Grimes County,H1
+TX,48,187,Guadalupe County,H1
+TX,48,189,Hale County,H1
+TX,48,191,Hall County,H1
+TX,48,193,Hamilton County,H1
+TX,48,195,Hansford County,H1
+TX,48,197,Hardeman County,H1
+TX,48,199,Hardin County,H1
+TX,48,201,Harris County,H1
+TX,48,203,Harrison County,H1
+TX,48,205,Hartley County,H1
+TX,48,207,Haskell County,H1
+TX,48,209,Hays County,H1
+TX,48,211,Hemphill County,H1
+TX,48,213,Henderson County,H1
+TX,48,215,Hidalgo County,H1
+TX,48,217,Hill County,H1
+TX,48,219,Hockley County,H1
+TX,48,221,Hood County,H1
+TX,48,223,Hopkins County,H1
+TX,48,225,Houston County,H1
+TX,48,227,Howard County,H1
+TX,48,229,Hudspeth County,H1
+TX,48,231,Hunt County,H1
+TX,48,233,Hutchinson County,H1
+TX,48,235,Irion County,H1
+TX,48,237,Jack County,H1
+TX,48,239,Jackson County,H1
+TX,48,241,Jasper County,H1
+TX,48,243,Jeff Davis County,H1
+TX,48,245,Jefferson County,H1
+TX,48,247,Jim Hogg County,H1
+TX,48,249,Jim Wells County,H1
+TX,48,251,Johnson County,H1
+TX,48,253,Jones County,H1
+TX,48,255,Karnes County,H1
+TX,48,257,Kaufman County,H1
+TX,48,259,Kendall County,H1
+TX,48,261,Kenedy County,H1
+TX,48,263,Kent County,H1
+TX,48,265,Kerr County,H1
+TX,48,267,Kimble County,H1
+TX,48,269,King County,H1
+TX,48,271,Kinney County,H1
+TX,48,273,Kleberg County,H1
+TX,48,275,Knox County,H1
+TX,48,277,Lamar County,H1
+TX,48,279,Lamb County,H1
+TX,48,281,Lampasas County,H1
+TX,48,283,La Salle County,H1
+TX,48,285,Lavaca County,H1
+TX,48,287,Lee County,H1
+TX,48,289,Leon County,H1
+TX,48,291,Liberty County,H1
+TX,48,293,Limestone County,H1
+TX,48,295,Lipscomb County,H1
+TX,48,297,Live Oak County,H1
+TX,48,299,Llano County,H1
+TX,48,301,Loving County,H1
+TX,48,303,Lubbock County,H1
+TX,48,305,Lynn County,H1
+TX,48,307,McCulloch County,H1
+TX,48,309,McLennan County,H1
+TX,48,311,McMullen County,H1
+TX,48,313,Madison County,H1
+TX,48,315,Marion County,H1
+TX,48,317,Martin County,H1
+TX,48,319,Mason County,H1
+TX,48,321,Matagorda County,H1
+TX,48,323,Maverick County,H1
+TX,48,325,Medina County,H1
+TX,48,327,Menard County,H1
+TX,48,329,Midland County,H1
+TX,48,331,Milam County,H1
+TX,48,333,Mills County,H1
+TX,48,335,Mitchell County,H1
+TX,48,337,Montague County,H1
+TX,48,339,Montgomery County,H1
+TX,48,341,Moore County,H1
+TX,48,343,Morris County,H1
+TX,48,345,Motley County,H1
+TX,48,347,Nacogdoches County,H1
+TX,48,349,Navarro County,H1
+TX,48,351,Newton County,H1
+TX,48,353,Nolan County,H1
+TX,48,355,Nueces County,H1
+TX,48,357,Ochiltree County,H1
+TX,48,359,Oldham County,H1
+TX,48,361,Orange County,H1
+TX,48,363,Palo Pinto County,H1
+TX,48,365,Panola County,H1
+TX,48,367,Parker County,H1
+TX,48,369,Parmer County,H1
+TX,48,371,Pecos County,H1
+TX,48,373,Polk County,H1
+TX,48,375,Potter County,H1
+TX,48,377,Presidio County,H1
+TX,48,379,Rains County,H1
+TX,48,381,Randall County,H1
+TX,48,383,Reagan County,H1
+TX,48,385,Real County,H1
+TX,48,387,Red River County,H1
+TX,48,389,Reeves County,H1
+TX,48,391,Refugio County,H1
+TX,48,393,Roberts County,H1
+TX,48,395,Robertson County,H1
+TX,48,397,Rockwall County,H1
+TX,48,399,Runnels County,H1
+TX,48,401,Rusk County,H1
+TX,48,403,Sabine County,H1
+TX,48,405,San Augustine County,H1
+TX,48,407,San Jacinto County,H1
+TX,48,409,San Patricio County,H1
+TX,48,411,San Saba County,H1
+TX,48,413,Schleicher County,H1
+TX,48,415,Scurry County,H1
+TX,48,417,Shackelford County,H1
+TX,48,419,Shelby County,H1
+TX,48,421,Sherman County,H1
+TX,48,423,Smith County,H1
+TX,48,425,Somervell County,H1
+TX,48,427,Starr County,H1
+TX,48,429,Stephens County,H1
+TX,48,431,Sterling County,H1
+TX,48,433,Stonewall County,H1
+TX,48,435,Sutton County,H1
+TX,48,437,Swisher County,H1
+TX,48,439,Tarrant County,H1
+TX,48,441,Taylor County,H1
+TX,48,443,Terrell County,H1
+TX,48,445,Terry County,H1
+TX,48,447,Throckmorton County,H1
+TX,48,449,Titus County,H1
+TX,48,451,Tom Green County,H1
+TX,48,453,Travis County,H1
+TX,48,455,Trinity County,H1
+TX,48,457,Tyler County,H1
+TX,48,459,Upshur County,H1
+TX,48,461,Upton County,H1
+TX,48,463,Uvalde County,H1
+TX,48,465,Val Verde County,H1
+TX,48,467,Van Zandt County,H1
+TX,48,469,Victoria County,H1
+TX,48,471,Walker County,H1
+TX,48,473,Waller County,H1
+TX,48,475,Ward County,H1
+TX,48,477,Washington County,H1
+TX,48,479,Webb County,H1
+TX,48,481,Wharton County,H1
+TX,48,483,Wheeler County,H1
+TX,48,485,Wichita County,H1
+TX,48,487,Wilbarger County,H1
+TX,48,489,Willacy County,H1
+TX,48,491,Williamson County,H1
+TX,48,493,Wilson County,H1
+TX,48,495,Winkler County,H1
+TX,48,497,Wise County,H1
+TX,48,499,Wood County,H1
+TX,48,501,Yoakum County,H1
+TX,48,503,Young County,H1
+TX,48,505,Zapata County,H1
+TX,48,507,Zavala County,H1
+UT,49,001,Beaver County,H1
+UT,49,003,Box Elder County,H1
+UT,49,005,Cache County,H1
+UT,49,007,Carbon County,H1
+UT,49,009,Daggett County,H1
+UT,49,011,Davis County,H1
+UT,49,013,Duchesne County,H1
+UT,49,015,Emery County,H1
+UT,49,017,Garfield County,H1
+UT,49,019,Grand County,H1
+UT,49,021,Iron County,H1
+UT,49,023,Juab County,H1
+UT,49,025,Kane County,H1
+UT,49,027,Millard County,H1
+UT,49,029,Morgan County,H1
+UT,49,031,Piute County,H1
+UT,49,033,Rich County,H1
+UT,49,035,Salt Lake County,H1
+UT,49,037,San Juan County,H1
+UT,49,039,Sanpete County,H1
+UT,49,041,Sevier County,H1
+UT,49,043,Summit County,H1
+UT,49,045,Tooele County,H1
+UT,49,047,Uintah County,H1
+UT,49,049,Utah County,H1
+UT,49,051,Wasatch County,H1
+UT,49,053,Washington County,H1
+UT,49,055,Wayne County,H1
+UT,49,057,Weber County,H1
+VT,50,001,Addison County,H1
+VT,50,003,Bennington County,H1
+VT,50,005,Caledonia County,H1
+VT,50,007,Chittenden County,H1
+VT,50,009,Essex County,H1
+VT,50,011,Franklin County,H1
+VT,50,013,Grand Isle County,H1
+VT,50,015,Lamoille County,H1
+VT,50,017,Orange County,H1
+VT,50,019,Orleans County,H1
+VT,50,021,Rutland County,H1
+VT,50,023,Washington County,H1
+VT,50,025,Windham County,H1
+VT,50,027,Windsor County,H1
+VA,51,001,Accomack County,H1
+VA,51,003,Albemarle County,H1
+VA,51,005,Alleghany County,H1
+VA,51,007,Amelia County,H1
+VA,51,009,Amherst County,H1
+VA,51,011,Appomattox County,H1
+VA,51,013,Arlington County,H1
+VA,51,015,Augusta County,H1
+VA,51,017,Bath County,H1
+VA,51,019,Bedford County,H1
+VA,51,021,Bland County,H1
+VA,51,023,Botetourt County,H1
+VA,51,025,Brunswick County,H1
+VA,51,027,Buchanan County,H1
+VA,51,029,Buckingham County,H1
+VA,51,031,Campbell County,H1
+VA,51,033,Caroline County,H1
+VA,51,035,Carroll County,H1
+VA,51,036,Charles City County,H1
+VA,51,037,Charlotte County,H1
+VA,51,041,Chesterfield County,H1
+VA,51,043,Clarke County,H1
+VA,51,045,Craig County,H1
+VA,51,047,Culpeper County,H1
+VA,51,049,Cumberland County,H1
+VA,51,051,Dickenson County,H1
+VA,51,053,Dinwiddie County,H1
+VA,51,057,Essex County,H1
+VA,51,059,Fairfax County,H1
+VA,51,061,Fauquier County,H1
+VA,51,063,Floyd County,H1
+VA,51,065,Fluvanna County,H1
+VA,51,067,Franklin County,H1
+VA,51,069,Frederick County,H1
+VA,51,071,Giles County,H1
+VA,51,073,Gloucester County,H1
+VA,51,075,Goochland County,H1
+VA,51,077,Grayson County,H1
+VA,51,079,Greene County,H1
+VA,51,081,Greensville County,H1
+VA,51,083,Halifax County,H1
+VA,51,085,Hanover County,H1
+VA,51,087,Henrico County,H1
+VA,51,089,Henry County,H1
+VA,51,091,Highland County,H1
+VA,51,093,Isle of Wight County,H1
+VA,51,095,James City County,H1
+VA,51,097,King and Queen County,H1
+VA,51,099,King George County,H1
+VA,51,101,King William County,H1
+VA,51,103,Lancaster County,H1
+VA,51,105,Lee County,H1
+VA,51,107,Loudoun County,H1
+VA,51,109,Louisa County,H1
+VA,51,111,Lunenburg County,H1
+VA,51,113,Madison County,H1
+VA,51,115,Mathews County,H1
+VA,51,117,Mecklenburg County,H1
+VA,51,119,Middlesex County,H1
+VA,51,121,Montgomery County,H1
+VA,51,125,Nelson County,H1
+VA,51,127,New Kent County,H1
+VA,51,131,Northampton County,H1
+VA,51,133,Northumberland County,H1
+VA,51,135,Nottoway County,H1
+VA,51,137,Orange County,H1
+VA,51,139,Page County,H1
+VA,51,141,Patrick County,H1
+VA,51,143,Pittsylvania County,H1
+VA,51,145,Powhatan County,H1
+VA,51,147,Prince Edward County,H1
+VA,51,149,Prince George County,H1
+VA,51,153,Prince William County,H1
+VA,51,155,Pulaski County,H1
+VA,51,157,Rappahannock County,H1
+VA,51,159,Richmond County,H1
+VA,51,161,Roanoke County,H1
+VA,51,163,Rockbridge County,H1
+VA,51,165,Rockingham County,H1
+VA,51,167,Russell County,H1
+VA,51,169,Scott County,H1
+VA,51,171,Shenandoah County,H1
+VA,51,173,Smyth County,H1
+VA,51,175,Southampton County,H1
+VA,51,177,Spotsylvania County,H1
+VA,51,179,Stafford County,H1
+VA,51,181,Surry County,H1
+VA,51,183,Sussex County,H1
+VA,51,185,Tazewell County,H1
+VA,51,187,Warren County,H1
+VA,51,191,Washington County,H1
+VA,51,193,Westmoreland County,H1
+VA,51,195,Wise County,H1
+VA,51,197,Wythe County,H1
+VA,51,199,York County,H1
+VA,51,510,Alexandria city,C7
+VA,51,515,Bedford city,C7
+VA,51,520,Bristol city,C7
+VA,51,530,Buena Vista city,C7
+VA,51,540,Charlottesville city,C7
+VA,51,550,Chesapeake city,C7
+VA,51,570,Colonial Heights city,C7
+VA,51,580,Covington city,C7
+VA,51,590,Danville city,C7
+VA,51,595,Emporia city,C7
+VA,51,600,Fairfax city,C7
+VA,51,610,Falls Church city,C7
+VA,51,620,Franklin city,C7
+VA,51,630,Fredericksburg city,C7
+VA,51,640,Galax city,C7
+VA,51,650,Hampton city,C7
+VA,51,660,Harrisonburg city,C7
+VA,51,670,Hopewell city,C7
+VA,51,678,Lexington city,C7
+VA,51,680,Lynchburg city,C7
+VA,51,683,Manassas city,C7
+VA,51,685,Manassas Park city,C7
+VA,51,690,Martinsville city,C7
+VA,51,700,Newport News city,C7
+VA,51,710,Norfolk city,C7
+VA,51,720,Norton city,C7
+VA,51,730,Petersburg city,C7
+VA,51,735,Poquoson city,C7
+VA,51,740,Portsmouth city,C7
+VA,51,750,Radford city,C7
+VA,51,760,Richmond city,C7
+VA,51,770,Roanoke city,C7
+VA,51,775,Salem city,C7
+VA,51,790,Staunton city,C7
+VA,51,800,Suffolk city,C7
+VA,51,810,Virginia Beach city,C7
+VA,51,820,Waynesboro city,C7
+VA,51,830,Williamsburg city,C7
+VA,51,840,Winchester city,C7
+WA,53,001,Adams County,H1
+WA,53,003,Asotin County,H1
+WA,53,005,Benton County,H1
+WA,53,007,Chelan County,H1
+WA,53,009,Clallam County,H1
+WA,53,011,Clark County,H1
+WA,53,013,Columbia County,H1
+WA,53,015,Cowlitz County,H1
+WA,53,017,Douglas County,H1
+WA,53,019,Ferry County,H1
+WA,53,021,Franklin County,H1
+WA,53,023,Garfield County,H1
+WA,53,025,Grant County,H1
+WA,53,027,Grays Harbor County,H1
+WA,53,029,Island County,H1
+WA,53,031,Jefferson County,H1
+WA,53,033,King County,H1
+WA,53,035,Kitsap County,H1
+WA,53,037,Kittitas County,H1
+WA,53,039,Klickitat County,H1
+WA,53,041,Lewis County,H1
+WA,53,043,Lincoln County,H1
+WA,53,045,Mason County,H1
+WA,53,047,Okanogan County,H1
+WA,53,049,Pacific County,H1
+WA,53,051,Pend Oreille County,H1
+WA,53,053,Pierce County,H1
+WA,53,055,San Juan County,H1
+WA,53,057,Skagit County,H1
+WA,53,059,Skamania County,H1
+WA,53,061,Snohomish County,H1
+WA,53,063,Spokane County,H1
+WA,53,065,Stevens County,H1
+WA,53,067,Thurston County,H1
+WA,53,069,Wahkiakum County,H1
+WA,53,071,Walla Walla County,H1
+WA,53,073,Whatcom County,H1
+WA,53,075,Whitman County,H1
+WA,53,077,Yakima County,H1
+WV,54,001,Barbour County,H1
+WV,54,003,Berkeley County,H1
+WV,54,005,Boone County,H1
+WV,54,007,Braxton County,H1
+WV,54,009,Brooke County,H1
+WV,54,011,Cabell County,H1
+WV,54,013,Calhoun County,H1
+WV,54,015,Clay County,H1
+WV,54,017,Doddridge County,H1
+WV,54,019,Fayette County,H1
+WV,54,021,Gilmer County,H1
+WV,54,023,Grant County,H1
+WV,54,025,Greenbrier County,H1
+WV,54,027,Hampshire County,H1
+WV,54,029,Hancock County,H1
+WV,54,031,Hardy County,H1
+WV,54,033,Harrison County,H1
+WV,54,035,Jackson County,H1
+WV,54,037,Jefferson County,H1
+WV,54,039,Kanawha County,H1
+WV,54,041,Lewis County,H1
+WV,54,043,Lincoln County,H1
+WV,54,045,Logan County,H1
+WV,54,047,McDowell County,H1
+WV,54,049,Marion County,H1
+WV,54,051,Marshall County,H1
+WV,54,053,Mason County,H1
+WV,54,055,Mercer County,H1
+WV,54,057,Mineral County,H1
+WV,54,059,Mingo County,H1
+WV,54,061,Monongalia County,H1
+WV,54,063,Monroe County,H1
+WV,54,065,Morgan County,H1
+WV,54,067,Nicholas County,H1
+WV,54,069,Ohio County,H1
+WV,54,071,Pendleton County,H1
+WV,54,073,Pleasants County,H1
+WV,54,075,Pocahontas County,H1
+WV,54,077,Preston County,H1
+WV,54,079,Putnam County,H1
+WV,54,081,Raleigh County,H1
+WV,54,083,Randolph County,H1
+WV,54,085,Ritchie County,H1
+WV,54,087,Roane County,H1
+WV,54,089,Summers County,H1
+WV,54,091,Taylor County,H1
+WV,54,093,Tucker County,H1
+WV,54,095,Tyler County,H1
+WV,54,097,Upshur County,H1
+WV,54,099,Wayne County,H1
+WV,54,101,Webster County,H1
+WV,54,103,Wetzel County,H1
+WV,54,105,Wirt County,H1
+WV,54,107,Wood County,H1
+WV,54,109,Wyoming County,H1
+WI,55,001,Adams County,H1
+WI,55,003,Ashland County,H1
+WI,55,005,Barron County,H1
+WI,55,007,Bayfield County,H1
+WI,55,009,Brown County,H1
+WI,55,011,Buffalo County,H1
+WI,55,013,Burnett County,H1
+WI,55,015,Calumet County,H1
+WI,55,017,Chippewa County,H1
+WI,55,019,Clark County,H1
+WI,55,021,Columbia County,H1
+WI,55,023,Crawford County,H1
+WI,55,025,Dane County,H1
+WI,55,027,Dodge County,H1
+WI,55,029,Door County,H1
+WI,55,031,Douglas County,H1
+WI,55,033,Dunn County,H1
+WI,55,035,Eau Claire County,H1
+WI,55,037,Florence County,H1
+WI,55,039,Fond du Lac County,H1
+WI,55,041,Forest County,H1
+WI,55,043,Grant County,H1
+WI,55,045,Green County,H1
+WI,55,047,Green Lake County,H1
+WI,55,049,Iowa County,H1
+WI,55,051,Iron County,H1
+WI,55,053,Jackson County,H1
+WI,55,055,Jefferson County,H1
+WI,55,057,Juneau County,H1
+WI,55,059,Kenosha County,H1
+WI,55,061,Kewaunee County,H1
+WI,55,063,La Crosse County,H1
+WI,55,065,Lafayette County,H1
+WI,55,067,Langlade County,H1
+WI,55,069,Lincoln County,H1
+WI,55,071,Manitowoc County,H1
+WI,55,073,Marathon County,H1
+WI,55,075,Marinette County,H1
+WI,55,077,Marquette County,H1
+WI,55,078,Menominee County,H1
+WI,55,079,Milwaukee County,H1
+WI,55,081,Monroe County,H1
+WI,55,083,Oconto County,H1
+WI,55,085,Oneida County,H1
+WI,55,087,Outagamie County,H1
+WI,55,089,Ozaukee County,H1
+WI,55,091,Pepin County,H1
+WI,55,093,Pierce County,H1
+WI,55,095,Polk County,H1
+WI,55,097,Portage County,H1
+WI,55,099,Price County,H1
+WI,55,101,Racine County,H1
+WI,55,103,Richland County,H1
+WI,55,105,Rock County,H1
+WI,55,107,Rusk County,H1
+WI,55,109,St. Croix County,H1
+WI,55,111,Sauk County,H1
+WI,55,113,Sawyer County,H1
+WI,55,115,Shawano County,H1
+WI,55,117,Sheboygan County,H1
+WI,55,119,Taylor County,H1
+WI,55,121,Trempealeau County,H1
+WI,55,123,Vernon County,H1
+WI,55,125,Vilas County,H1
+WI,55,127,Walworth County,H1
+WI,55,129,Washburn County,H1
+WI,55,131,Washington County,H1
+WI,55,133,Waukesha County,H1
+WI,55,135,Waupaca County,H1
+WI,55,137,Waushara County,H1
+WI,55,139,Winnebago County,H1
+WI,55,141,Wood County,H1
+WY,56,001,Albany County,H1
+WY,56,003,Big Horn County,H1
+WY,56,005,Campbell County,H1
+WY,56,007,Carbon County,H1
+WY,56,009,Converse County,H1
+WY,56,011,Crook County,H1
+WY,56,013,Fremont County,H1
+WY,56,015,Goshen County,H1
+WY,56,017,Hot Springs County,H1
+WY,56,019,Johnson County,H1
+WY,56,021,Laramie County,H1
+WY,56,023,Lincoln County,H1
+WY,56,025,Natrona County,H1
+WY,56,027,Niobrara County,H1
+WY,56,029,Park County,H1
+WY,56,031,Platte County,H1
+WY,56,033,Sheridan County,H1
+WY,56,035,Sublette County,H1
+WY,56,037,Sweetwater County,H1
+WY,56,039,Teton County,H1
+WY,56,041,Uinta County,H1
+WY,56,043,Washakie County,H1
+WY,56,045,Weston County,H1
+AS,60,010,Eastern District,H1
+AS,60,020,Manu'a District,H1
+AS,60,030,Rose Island,H4
+AS,60,040,Swains Island,H4
+AS,60,050,Western District,H1
+GU,66,010,Guam,H4
+MP,69,085,Northern Islands Municipality,H1
+MP,69,100,Rota Municipality,H1
+MP,69,110,Saipan Municipality,H1
+MP,69,120,Tinian Municipality,H1
+PR,72,001,Adjuntas Municipio,H1
+PR,72,003,Aguada Municipio,H1
+PR,72,005,Aguadilla Municipio,H1
+PR,72,007,Aguas Buenas Municipio,H1
+PR,72,009,Aibonito Municipio,H1
+PR,72,011,Anasco Municipio,H1
+PR,72,013,Arecibo Municipio,H1
+PR,72,015,Arroyo Municipio,H1
+PR,72,017,Barceloneta Municipio,H1
+PR,72,019,Barranquitas Municipio,H1
+PR,72,021,Bayamon Municipio,H1
+PR,72,023,Cabo Rojo Municipio,H1
+PR,72,025,Caguas Municipio,H1
+PR,72,027,Camuy Municipio,H1
+PR,72,029,Canovanas Municipio,H1
+PR,72,031,Carolina Municipio,H1
+PR,72,033,Catano Municipio,H1
+PR,72,035,Cayey Municipio,H1
+PR,72,037,Ceiba Municipio,H1
+PR,72,039,Ciales Municipio,H1
+PR,72,041,Cidra Municipio,H1
+PR,72,043,Coamo Municipio,H1
+PR,72,045,Comerio Municipio,H1
+PR,72,047,Corozal Municipio,H1
+PR,72,049,Culebra Municipio,H1
+PR,72,051,Dorado Municipio,H1
+PR,72,053,Fajardo Municipio,H1
+PR,72,054,Florida Municipio,H1
+PR,72,055,Guanica Municipio,H1
+PR,72,057,Guayama Municipio,H1
+PR,72,059,Guayanilla Municipio,H1
+PR,72,061,Guaynabo Municipio,H1
+PR,72,063,Gurabo Municipio,H1
+PR,72,065,Hatillo Municipio,H1
+PR,72,067,Hormigueros Municipio,H1
+PR,72,069,Humacao Municipio,H1
+PR,72,071,Isabela Municipio,H1
+PR,72,073,Jayuya Municipio,H1
+PR,72,075,Juana Diaz Municipio,H1
+PR,72,077,Juncos Municipio,H1
+PR,72,079,Lajas Municipio,H1
+PR,72,081,Lares Municipio,H1
+PR,72,083,Las Marias Municipio,H1
+PR,72,085,Las Piedras Municipio,H1
+PR,72,087,Loiza Municipio,H1
+PR,72,089,Luquillo Municipio,H1
+PR,72,091,Manati Municipio,H1
+PR,72,093,Maricao Municipio,H1
+PR,72,095,Maunabo Municipio,H1
+PR,72,097,Mayaguez Municipio,H1
+PR,72,099,Moca Municipio,H1
+PR,72,101,Morovis Municipio,H1
+PR,72,103,Naguabo Municipio,H1
+PR,72,105,Naranjito Municipio,H1
+PR,72,107,Orocovis Municipio,H1
+PR,72,109,Patillas Municipio,H1
+PR,72,111,Penuelas Municipio,H1
+PR,72,113,Ponce Municipio,H1
+PR,72,115,Quebradillas Municipio,H1
+PR,72,117,Rincon Municipio,H1
+PR,72,119,Rio Grande Municipio,H1
+PR,72,121,Sabana Grande Municipio,H1
+PR,72,123,Salinas Municipio,H1
+PR,72,125,San German Municipio,H1
+PR,72,127,San Juan Municipio,H1
+PR,72,129,San Lorenzo Municipio,H1
+PR,72,131,San Sebastian Municipio,H1
+PR,72,133,Santa Isabel Municipio,H1
+PR,72,135,Toa Alta Municipio,H1
+PR,72,137,Toa Baja Municipio,H1
+PR,72,139,Trujillo Alto Municipio,H1
+PR,72,141,Utuado Municipio,H1
+PR,72,143,Vega Alta Municipio,H1
+PR,72,145,Vega Baja Municipio,H1
+PR,72,147,Vieques Municipio,H1
+PR,72,149,Villalba Municipio,H1
+PR,72,151,Yabucoa Municipio,H1
+PR,72,153,Yauco Municipio,H1
+UM,74,300,Midway Islands,H4
+VI,78,010,St. Croix Island,H4
+VI,78,020,St. John Island,H4
+VI,78,030,St. Thomas Island,H4
diff --git a/src/org/ohdsi/whiteRabbit/fakeDataGenerator/FakeDataGenerator.java b/src/org/ohdsi/whiteRabbit/fakeDataGenerator/FakeDataGenerator.java
new file mode 100644
index 00000000..9de2f607
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/fakeDataGenerator/FakeDataGenerator.java
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.fakeDataGenerator;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import org.ohdsi.databases.DbType;
+import org.ohdsi.databases.RichConnection;
+import org.ohdsi.utilities.files.Row;
+import org.ohdsi.whiteRabbit.DbSettings;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.Database;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.Field;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.Table;
+import org.ohdsi.whiteRabbit.utilities.ETLUtils;
+
+public class FakeDataGenerator {
+
+ private RichConnection connection;
+ private DbType dbType;
+
+ public static int ROWS_PER_TABLE = 1000;
+
+ public static void main(String[] args) {
+ FakeDataGenerator fakeDataGenerator = new FakeDataGenerator();
+
+ DbSettings dbSettings = new DbSettings();
+// dbSettings.dataType = DbSettings.DATABASE;
+// dbSettings.dbType = DbType.MYSQL;
+// dbSettings.server = "127.0.0.1";
+// dbSettings.database = "fake_data";
+// dbSettings.user = "root";
+// dbSettings.password = "F1r3starter";
+// fakeDataGenerator.generateData(dbSettings, "S:/Data/THIN/ScanReport.xlsx",true);
+
+ dbSettings.dataType = DbSettings.DATABASE;
+ dbSettings.dbType = DbType.MSSQL;
+ dbSettings.server = "RNDUSRDHIT03.jnj.com";
+ dbSettings.database = "CDM_THIN";
+ fakeDataGenerator.generateData(dbSettings, "S:/Data/THIN/ScanReport.xlsx",false);
+ }
+
+ private void generateData(DbSettings dbSettings, String filename, boolean createDatabase) {
+ System.out.println("Loading scan report from " + filename);
+ Database database = Database.generateModelFromScanReport(filename);
+
+ dbType = dbSettings.dbType;
+ if (createDatabase && ETLUtils.databaseAlreadyExists(dbSettings))
+ return;
+ connection = new RichConnection(dbSettings.server, dbSettings.domain, dbSettings.user, dbSettings.password, dbSettings.dbType);
+ if (createDatabase)
+ connection.execute("CREATE DATABASE IF NOT EXISTS `" + dbSettings.database + "`");
+ connection.use(dbSettings.database);
+
+ for (Table table : database.getTables()) {
+ System.out.println("Generating table " + table.getName());
+ createTable(table);
+ populateTable(table);
+ }
+
+ connection.close();
+ }
+
+ private void populateTable(Table table) {
+ String[] fieldNames = new String[table.getFields().size()];
+ ValueGenerator[] valueGenerators = new ValueGenerator[table.getFields().size()];
+ for (int i = 0; i < table.getFields().size(); i++) {
+ Field field = table.getFields().get(i);
+ fieldNames[i] = field.getName();
+ if (fieldNames[i].equals("data1"))
+ System.out.println("asdf");
+ valueGenerators[i] = new ValueGenerator(field);
+ }
+ List rows = new ArrayList();
+ for (int i = 0; i < ROWS_PER_TABLE; i++) {
+ Row row = new Row();
+ for (int j = 0; j < fieldNames.length; j++) {
+ row.add(fieldNames[j], valueGenerators[j].generate());
+ }
+ rows.add(row);
+ }
+ connection.insertIntoTable(rows.iterator(), table.getName(), false);
+ }
+
+ private void createTable(Table table) {
+ StringBuilder sql = new StringBuilder();
+ sql.append("CREATE TABLE " + table.getName() + " (\n");
+ for (int i = 0; i < table.getFields().size(); i++) {
+ Field field = table.getFields().get(i);
+ sql.append(" " + field.getName() + " " + correctType(field));
+ if (i < table.getFields().size() - 1)
+ sql.append(",\n");
+ }
+ sql.append("\n);");
+ connection.execute(sql.toString());
+ }
+
+ private String correctType(Field field) {
+ if (field.getType().equals("VarChar"))
+ return "VARCHAR(" + field.getMaxLength() + ")";
+ else if (field.getType().equals("Integer"))
+ return "BIGINT";
+ else if (field.getType().equals("Date"))
+ return "DATE";
+ else if (field.getType().equals("Real"))
+ return "DOUBLE";
+ else if (field.getType().equals("Empty"))
+ return "VARCHAR(255)";
+
+ return null;
+ }
+
+ private class ValueGenerator {
+
+ private String[] values;
+ private int[] cumulativeFrequency;
+ private int totalFrequency;
+ private String type;
+
+ private boolean randomGenerate;
+
+ private int length;
+
+ private Random random = new Random();
+
+ public ValueGenerator(Field field) {
+ String[][] valueCounts = field.getValueCounts();
+ type = field.getType();
+ if (valueCounts[0][0].equals("List truncated...")) {
+ randomGenerate = true;
+ length = field.getMaxLength();
+ } else {
+ randomGenerate = false;
+ int length = valueCounts.length;
+ if (valueCounts[length - 1][1].equals("")) // Last value could be "List truncated..."
+ length--;
+
+ values = new String[length];
+ cumulativeFrequency = new int[length];
+ totalFrequency = 0;
+ for (int i = 0; i < length; i++) {
+ int frequency = (int) (Double.parseDouble(valueCounts[i][1]));
+ totalFrequency += frequency;
+
+ values[i] = valueCounts[i][0];
+ cumulativeFrequency[i] = totalFrequency;
+ }
+ }
+ }
+
+ public String generate() {
+ if (randomGenerate) { // Random generate a string:
+ if (type.equals("VarChar")) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++)
+ sb.append(Character.toChars(65 + random.nextInt(26)));
+ return sb.toString();
+ } else if (type.equals("Integer")) {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < length; i++)
+ sb.append(Character.toChars(48 + random.nextInt(10)));
+ return sb.toString();
+ } else if (type.equals("Date")) // todo: add code
+ return "";
+ else if (type.equals("Real")) // todo: add code
+ return "";
+ else if (type.equals("Empty"))
+ return "";
+ else
+ return "";
+ } else { // Sample from values:
+ int index = random.nextInt(totalFrequency);
+ int i = 0;
+ while (i < values.length - 1 && cumulativeFrequency[i] < index)
+ i++;
+ if (!type.equals("VarChar") && values[i].trim().length() == 0)
+ return "";
+ return values[i];
+ }
+ }
+ }
+
+}
diff --git a/src/org/ohdsi/whiteRabbit/interactiveMapping/Arrow.java b/src/org/ohdsi/whiteRabbit/interactiveMapping/Arrow.java
new file mode 100644
index 00000000..1c3c82dc
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/interactiveMapping/Arrow.java
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.interactiveMapping;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Polygon;
+
+public class Arrow implements MappingComponent {
+
+ public static float thickness = 5;
+ public static int headThickness = 15;
+ public static Color color = new Color(128, 128, 128, 128);
+ private static BasicStroke dashed = new BasicStroke(2.0f,
+ BasicStroke.CAP_BUTT,
+ BasicStroke.JOIN_MITER,
+ 10.0f,
+ new float[] { 10.f },
+ 0.0f);
+
+ private int x1;
+ private int y1;
+ private int x2;
+ private int y2;
+ private LabeledRectangle source = null;
+ private LabeledRectangle target = null;
+
+ private int width;
+ private int height;
+
+ private Polygon polygon;
+
+ private boolean isSelected = false;
+ private boolean isVisible = true; ;
+
+ public Arrow(LabeledRectangle source) {
+ this.source = source;
+ }
+
+ public Arrow(int x1, int y1, int x2, int y2) {
+ this.x1 = x1;
+ this.y1 = y1;
+ this.x2 = x2;
+ this.y2 = y2;
+
+ this.width = Math.abs(x1 - x2);
+ this.height = Math.abs(y1 - y2);
+ }
+
+ public Arrow(LabeledRectangle source, LabeledRectangle target) {
+ this.source = source;
+ this.target = target;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public LabeledRectangle getSource() {
+ return source;
+ }
+
+ public void setTargetPoint(Point point) {
+ if (point == null) {
+ x2 = source.getX() + source.getWidth() + Arrow.headThickness;
+ y2 = source.getY() + source.getHeight() / 2;
+ } else {
+ x2 = point.x;
+ y2 = point.y;
+ }
+ }
+
+ public void paint(Graphics g) {
+ if (!isVisible)
+ return;
+ Graphics2D g2d = (Graphics2D) g;
+
+ if (source != null) {
+ x1 = source.getX() + source.getWidth();
+ y1 = source.getY() + source.getHeight() / 2;
+ width = Math.abs(x1 - x2);
+ height = Math.abs(y1 - y2);
+ }
+ if (target != null) {
+ x2 = target.getX();
+ y2 = target.getY() + target.getHeight() / 2;
+ width = Math.abs(x1 - x2);
+ height = Math.abs(y1 - y2);
+ }
+ int nPoints = 25;
+ int[] xPoints = new int[nPoints * 2 + 3];
+ int[] yPoints = new int[nPoints * 2 + 3];
+ float widthMinHead = getWidth() - headThickness;
+ float stepSize = widthMinHead / (float) (nPoints - 1);
+
+ for (int i = 0; i < nPoints; i++) {
+ float x = x1 + stepSize * i;
+ float y = (float) (y1 + (Math.cos(Math.PI * i / (float) nPoints) / 2d - 0.5)
+ * (y1 - y2));
+ xPoints[i] = Math.round(x);
+ yPoints[i] = Math.round(y - thickness);
+ xPoints[nPoints * 2 + 3 - i - 1] = Math.round(x);
+ yPoints[nPoints * 2 + 3 - i - 1] = Math.round(y + thickness);
+ }
+ xPoints[nPoints] = x2 - headThickness;
+ yPoints[nPoints] = y2 - headThickness;
+ xPoints[nPoints + 1] = x2;
+ yPoints[nPoints + 1] = y2;
+ xPoints[nPoints + 2] = x2 - headThickness;
+ yPoints[nPoints + 2] = y2 + headThickness;
+ polygon = new Polygon(xPoints, yPoints, nPoints * 2 + 3);
+
+ g2d.setColor(color);
+ g2d.fillPolygon(polygon);
+
+ if (isSelected) {
+ g2d.setColor(Color.BLACK);
+ g2d.setStroke(dashed);
+ g2d.drawPolygon(polygon);
+ }
+ }
+
+ public static void drawArrowHead(Graphics2D g2d, int x, int y) {
+ int nPoints = 3;
+ int[] xPoints = new int[nPoints];
+ int[] yPoints = new int[nPoints];
+ xPoints[0] = x - headThickness;
+ yPoints[0] = y - headThickness;
+ xPoints[1] = x;
+ yPoints[1] = y;
+ xPoints[2] = x - headThickness;
+ yPoints[2] = y + headThickness;
+ g2d.setColor(color);
+ g2d.fillPolygon(xPoints, yPoints, nPoints);
+ }
+
+ public void setTarget(LabeledRectangle target) {
+ this.target = target;
+ }
+
+ public LabeledRectangle getTarget() {
+ return target;
+ }
+
+ public boolean isSelected() {
+ return isSelected;
+ }
+
+ public void setSelected(boolean isSelected) {
+ this.isSelected = isSelected;
+ }
+
+ public boolean contains(Point point) {
+ return polygon.contains(point);
+ }
+
+ public void setVisible(boolean value) {
+ isVisible = value;
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/interactiveMapping/DetailsListener.java b/src/org/ohdsi/whiteRabbit/interactiveMapping/DetailsListener.java
new file mode 100644
index 00000000..bdbae74e
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/interactiveMapping/DetailsListener.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.interactiveMapping;
+
+public interface DetailsListener {
+ public void showDetails(Object object);
+}
diff --git a/src/org/ohdsi/whiteRabbit/interactiveMapping/DetailsPanel.java b/src/org/ohdsi/whiteRabbit/interactiveMapping/DetailsPanel.java
new file mode 100644
index 00000000..4de36701
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/interactiveMapping/DetailsPanel.java
@@ -0,0 +1,403 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.interactiveMapping;
+
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextArea;
+import javax.swing.UIManager;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.TableModel;
+
+import org.ohdsi.utilities.StringUtilities;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.Field;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.ItemToItemMap;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.Table;
+
+public class DetailsPanel extends JPanel implements DetailsListener {
+
+ public static Font font = new Font("default", Font.PLAIN, 18);
+
+ private static final long serialVersionUID = 4477553676983048468L;
+ private TablePanel tablePanel;
+ private FieldPanel fieldPanel;
+ private ItemToItemMapPanel itemToItemMapPanel;
+ private CardLayout cardLayout = new CardLayout();
+
+ public DetailsPanel() {
+ UIManager.put("Label.font", font);
+
+ setLayout(cardLayout);
+
+ tablePanel = new TablePanel();
+ add(tablePanel, Table.class.getName());
+
+ fieldPanel = new FieldPanel();
+ add(fieldPanel, Field.class.getName());
+
+ itemToItemMapPanel = new ItemToItemMapPanel();
+ add(itemToItemMapPanel, ItemToItemMap.class.getName());
+
+ JPanel nullPanel = new JPanel();
+ add(nullPanel, "");
+
+ cardLayout.show(this, "");
+ }
+
+ @Override
+ public void showDetails(Object object) {
+ if (object instanceof Table) {
+ tablePanel.showTable((Table) object);
+ cardLayout.show(this, Table.class.getName());
+ } else if (object instanceof Field) {
+ fieldPanel.showField((Field) object);
+ cardLayout.show(this, Field.class.getName());
+ } else if (object instanceof ItemToItemMap) {
+ itemToItemMapPanel.showItemToItemMap((ItemToItemMap) object);
+ cardLayout.show(this, ItemToItemMap.class.getName());
+ } else
+ cardLayout.show(this, "");
+ }
+
+ private class TablePanel extends JPanel implements DocumentListener {
+
+ private static final long serialVersionUID = -4393026616049677944L;
+ private Table table;
+ private JLabel nameLabel = new JLabel("");
+ private JLabel rowCountLabel = new JLabel("");
+ private SimpleTableModel fieldTable = new SimpleTableModel("Field", "Type");
+ private JTextArea commentsArea = new JTextArea();
+
+ public TablePanel() {
+ setLayout(new BorderLayout());
+
+ JPanel generalInfoPanel = new JPanel();
+ generalInfoPanel.setLayout(new GridLayout(0, 2));
+ generalInfoPanel.setBorder(BorderFactory.createTitledBorder("General information"));
+
+ generalInfoPanel.add(new JLabel("Table name: "));
+ generalInfoPanel.add(nameLabel);
+
+ generalInfoPanel.add(new JLabel("Number of rows: "));
+ generalInfoPanel.add(rowCountLabel);
+ add(generalInfoPanel, BorderLayout.NORTH);
+
+ JTable table = new JTable(fieldTable);
+ JScrollPane fieldListPanel = new JScrollPane(table);
+ table.setFont(font);
+ table.setRowHeight(24);
+ fieldListPanel.setBorder(BorderFactory.createTitledBorder("Fields"));
+ add(fieldListPanel, BorderLayout.CENTER);
+
+ // JScrollPane commentsPanel = new JScrollPane(commentsArea);
+ // commentsArea.setFont(font);
+ // commentsArea.getDocument().addDocumentListener(this);
+ // commentsArea.setWrapStyleWord(true);
+ // commentsArea.setLineWrap(true);
+ //
+ // commentsPanel.setBorder(BorderFactory.createTitledBorder("Comments"));
+ // commentsPanel.setPreferredSize(new Dimension(100, 200));
+ // add(commentsPanel, BorderLayout.SOUTH);
+
+ }
+
+ public void showTable(Table table) {
+ this.table = table;
+ nameLabel.setText(table.getName());
+ DecimalFormat formatter = new DecimalFormat("#,###");
+ rowCountLabel.setText(formatter.format(table.getRowCount()));
+ fieldTable.clear();
+ for (Field field : table.getFields())
+ fieldTable.add(field.getName(), field.getType());
+ commentsArea.setText(table.getComment());
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ table.setComment(commentsArea.getText());
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ table.setComment(commentsArea.getText());
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ table.setComment(commentsArea.getText());
+ }
+ }
+
+ private class FieldPanel extends JPanel implements DocumentListener {
+
+ private static final long serialVersionUID = -4393026616049677944L;
+ private JLabel nameLabel = new JLabel("");
+ private JLabel rowCountLabel = new JLabel("");
+ private SimpleTableModel valueTable = new SimpleTableModel("Value", "Frequency");
+ private JTextArea commentsArea = new JTextArea();
+ private Field field;
+
+ public FieldPanel() {
+ setLayout(new BorderLayout());
+
+ JPanel generalInfoPanel = new JPanel();
+ generalInfoPanel.setLayout(new GridLayout(0, 2));
+ generalInfoPanel.setBorder(BorderFactory.createTitledBorder("General information"));
+
+ generalInfoPanel.add(new JLabel("Field name: "));
+ generalInfoPanel.add(nameLabel);
+
+ generalInfoPanel.add(new JLabel("Field type: "));
+ generalInfoPanel.add(rowCountLabel);
+
+ add(generalInfoPanel, BorderLayout.NORTH);
+
+ JTable table = new JTable(valueTable);
+ JScrollPane fieldListPanel = new JScrollPane(table);
+ table.setFont(font);
+ table.setRowHeight(24);
+ fieldListPanel.setBorder(BorderFactory.createTitledBorder("Fields"));
+ add(fieldListPanel, BorderLayout.CENTER);
+
+ JScrollPane commentsPanel = new JScrollPane(commentsArea);
+ commentsArea.setFont(font);
+ commentsArea.getDocument().addDocumentListener(this);
+ commentsArea.setWrapStyleWord(true);
+ commentsArea.setLineWrap(true);
+
+ commentsPanel.setBorder(BorderFactory.createTitledBorder("Comments"));
+ commentsPanel.setPreferredSize(new Dimension(100, 200));
+
+ add(commentsPanel, BorderLayout.SOUTH);
+ }
+
+ public void showField(Field field) {
+ this.field = field;
+ nameLabel.setText(field.getName());
+ rowCountLabel.setText(field.getType());
+ valueTable.clear();
+ if (field.getValueCounts() != null) {
+ DecimalFormat formatter = new DecimalFormat("#,###");
+ for (String[] valueCount : field.getValueCounts()) {
+ String nr = valueCount[1];
+ if (StringUtilities.isNumber(nr)) {
+ double number = Double.parseDouble(nr);
+ nr = formatter.format(number);
+ }
+ valueTable.add(valueCount[0], nr);
+ }
+ }
+ commentsArea.setText(field.getComment());
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ field.setComment(commentsArea.getText());
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ field.setComment(commentsArea.getText());
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ field.setComment(commentsArea.getText());
+ }
+
+ }
+
+ private class ItemToItemMapPanel extends JPanel implements DocumentListener {
+
+ private static final long serialVersionUID = -4393026616049677944L;
+ private JLabel sourceLabel = new JLabel("");
+ private JLabel targetLabel = new JLabel("");
+ private JTextArea logicArea = new JTextArea();
+ private JTextArea commentsArea = new JTextArea();
+ // private FlexTable testTable = new FlexTable();
+ private ItemToItemMap itemToItemMap;
+
+ public ItemToItemMapPanel() {
+ setLayout(new BorderLayout());
+
+ JPanel generalInfoPanel = new JPanel();
+ generalInfoPanel.setLayout(new GridLayout(0, 2));
+ generalInfoPanel.setBorder(BorderFactory.createTitledBorder("General information"));
+
+ generalInfoPanel.add(new JLabel("Source: "));
+ generalInfoPanel.add(sourceLabel);
+
+ generalInfoPanel.add(new JLabel("Target: "));
+ generalInfoPanel.add(targetLabel);
+
+ add(generalInfoPanel, BorderLayout.NORTH);
+
+ JScrollPane logicPanel = new JScrollPane(logicArea);
+ logicArea.setFont(font);
+ logicArea.getDocument().addDocumentListener(this);
+ logicArea.setWrapStyleWord(true);
+ logicArea.setLineWrap(true);
+
+ logicPanel.setBorder(BorderFactory.createTitledBorder("Logic"));
+ logicPanel.setPreferredSize(new Dimension(100, 200));
+
+ add(logicPanel, BorderLayout.CENTER);
+
+ JScrollPane commentsPanel = new JScrollPane(commentsArea);
+ commentsArea.setFont(font);
+ commentsArea.getDocument().addDocumentListener(this);
+ commentsArea.setWrapStyleWord(true);
+ commentsArea.setLineWrap(true);
+
+ commentsPanel.setBorder(BorderFactory.createTitledBorder("Comments"));
+ commentsPanel.setPreferredSize(new Dimension(100, 200));
+
+ add(commentsPanel, BorderLayout.SOUTH);
+
+ // testTable.setMinimumSize(new Dimension(200, 200));
+ // JScrollPane testPanel = new JScrollPane(testTable);
+ // testPanel.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ // add(testPanel, BorderLayout.SOUTH);
+ }
+
+ public void showItemToItemMap(ItemToItemMap itemToItemMap) {
+ this.itemToItemMap = itemToItemMap;
+ sourceLabel.setText(itemToItemMap.getSourceItem().toString());
+ targetLabel.setText(itemToItemMap.getCdmItem().toString());
+ logicArea.setText(itemToItemMap.getLogic());
+ commentsArea.setText(itemToItemMap.getComment());
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ if (e.getDocument() == logicArea.getDocument())
+ itemToItemMap.setLogic(logicArea.getText());
+ else
+ itemToItemMap.setComment(commentsArea.getText());
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ if (e.getDocument() == logicArea.getDocument())
+ itemToItemMap.setLogic(logicArea.getText());
+ else
+ itemToItemMap.setComment(commentsArea.getText());
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ if (e.getDocument() == logicArea.getDocument())
+ itemToItemMap.setLogic(logicArea.getText());
+ else
+ itemToItemMap.setComment(commentsArea.getText());
+ }
+
+ }
+
+ private class SimpleTableModel implements TableModel {
+
+ private List listeners = new ArrayList();
+ private List> data = new ArrayList>();
+ private String[] columnNames;
+
+ public void clear() {
+ data.clear();
+ notifyListeners();
+ }
+
+ private void notifyListeners() {
+ for (TableModelListener listener : listeners)
+ listener.tableChanged(new TableModelEvent(this));
+ }
+
+ public void add(String... values) {
+ List row = new ArrayList(values.length);
+ for (int i = 0; i < values.length; i++)
+ row.add(values[i]);
+ data.add(row);
+ notifyListeners();
+ }
+
+ public SimpleTableModel(String... columnNames) {
+ this.columnNames = columnNames;
+ }
+
+ @Override
+ public void addTableModelListener(TableModelListener l) {
+ listeners.add(l);
+ }
+
+ @Override
+ public Class> getColumnClass(int columnIndex) {
+ return String.class;
+ }
+
+ @Override
+ public int getColumnCount() {
+ return columnNames.length;
+ }
+
+ @Override
+ public String getColumnName(int columnIndex) {
+ return columnNames[columnIndex];
+ }
+
+ @Override
+ public int getRowCount() {
+ return data.size();
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ return data.get(rowIndex).get(columnIndex);
+ }
+
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return false;
+ }
+
+ @Override
+ public void removeTableModelListener(TableModelListener l) {
+ listeners.remove(l);
+ }
+
+ @Override
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ }
+
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/interactiveMapping/ETLDocumentGenerator.java b/src/org/ohdsi/whiteRabbit/interactiveMapping/ETLDocumentGenerator.java
new file mode 100644
index 00000000..fb145cdf
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/interactiveMapping/ETLDocumentGenerator.java
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.interactiveMapping;
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.zip.GZIPInputStream;
+
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.xwpf.usermodel.BreakType;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFRun;
+import org.apache.poi.xwpf.usermodel.XWPFTable;
+import org.apache.poi.xwpf.usermodel.XWPFTableCell;
+import org.apache.poi.xwpf.usermodel.XWPFTableRow;
+import org.ohdsi.ooxml.CustomXWPFDocument;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.ETL;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.Field;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.ItemToItemMap;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.MappableItem;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.Mapping;
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.Table;
+
+public class ETLDocumentGenerator {
+ public static void main(String[] args) throws IOException, ClassNotFoundException {
+ FileInputStream fileOutputStream = new FileInputStream("C:/home/Research/EMIF WP12/HCUP//HCUP_final.etl");
+ GZIPInputStream gzipOutputStream = new GZIPInputStream(fileOutputStream);
+ ObjectInputStream out = new ObjectInputStream(gzipOutputStream);
+ ETL etl = (ETL) out.readObject();
+ out.close();
+ generate(etl, "C:/Users/mschuemi/Desktop/test.docx");
+ }
+
+ public static void generate(ETL etl, String filename) {
+ try {
+ CustomXWPFDocument document = new CustomXWPFDocument();
+
+ addTableLevelSection(document, etl);
+
+ for (Table cdmTable : etl.getCDMDatabase().getTables())
+ addCDMTableSection(document, etl, cdmTable);
+
+ addSourceTablesAppendix(document, etl);
+
+ document.write(new FileOutputStream(new File(filename)));
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (InvalidFormatException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private static void addSourceTablesAppendix(CustomXWPFDocument document, ETL etl) {
+ XWPFParagraph paragraph = document.createParagraph();
+ XWPFRun run = paragraph.createRun();
+ run.addBreak(BreakType.PAGE);
+ run.setText("Appendix: source tables");
+ run.setFontSize(18);
+
+ for (Table sourceTable : etl.getSourceDatabase().getTables()) {
+ paragraph = document.createParagraph();
+ run = paragraph.createRun();
+ run.setText("Table: " + sourceTable.getName());
+ run.setFontSize(14);
+
+ if (!sourceTable.getComment().equals("")) {
+ paragraph = document.createParagraph();
+ run = paragraph.createRun();
+ run.setText(sourceTable.getComment());
+ }
+
+ XWPFTable table = document.createTable(sourceTable.getFields().size() + 1, 4);
+ // table.setWidth(2000);
+ XWPFTableRow header = table.getRow(0);
+ setTextAndHeaderShading(header.getCell(0), "Field");
+ setTextAndHeaderShading(header.getCell(1), "Type");
+ setTextAndHeaderShading(header.getCell(2), "Most freq. value");
+ setTextAndHeaderShading(header.getCell(3), "Comment");
+ int rowNr = 1;
+ for (Field sourceField : sourceTable.getFields()) {
+ XWPFTableRow row = table.getRow(rowNr++);
+ row.getCell(0).setText(sourceField.getName());
+ row.getCell(1).setText(sourceField.getType());
+ if (sourceField.getValueCounts() != null)
+ row.getCell(2).setText(sourceField.getValueCounts()[0][0]);
+ row.getCell(3).setText(sourceField.getComment());
+ }
+
+ }
+
+ run.setFontSize(18);
+ }
+
+ private static void addCDMTableSection(CustomXWPFDocument document, ETL etl, Table cdmTable) throws InvalidFormatException, FileNotFoundException {
+ XWPFParagraph paragraph = document.createParagraph();
+ XWPFRun run = paragraph.createRun();
+ run.addBreak(BreakType.PAGE);
+
+ run.setText("Table name: " + cdmTable.getName());
+ run.setFontSize(18);
+
+ if (!cdmTable.getComment().equals("")) {
+ paragraph = document.createParagraph();
+ run = paragraph.createRun();
+ run.setText(cdmTable.getComment());
+ }
+
+ for (ItemToItemMap tableToTableMap : etl.getTableToTableMapping().getSourceToCdmMaps())
+ if (tableToTableMap.getCdmItem() == cdmTable) {
+ Table sourceTable = (Table) tableToTableMap.getSourceItem();
+ Mapping fieldtoFieldMapping = etl.getFieldToFieldMapping(sourceTable, cdmTable);
+
+ paragraph = document.createParagraph();
+ run = paragraph.createRun();
+ run.setText("Reading from " + tableToTableMap.getSourceItem());
+ run.setFontSize(14);
+
+ if (!tableToTableMap.getLogic().equals("")) {
+ paragraph = document.createParagraph();
+ run = paragraph.createRun();
+ run.setText(tableToTableMap.getLogic());
+ }
+
+ if (!tableToTableMap.getComment().equals("")) {
+ paragraph = document.createParagraph();
+ run = paragraph.createRun();
+ run.setText(tableToTableMap.getComment());
+ }
+
+ // Add picture of field to field mapping
+ MappingPanel mappingPanel = new MappingPanel(fieldtoFieldMapping);
+ mappingPanel.setShowOnlyConnectedItems(true);
+ int height = mappingPanel.getMinimumSize().height;
+ mappingPanel.setSize(800, height);
+
+ BufferedImage im = new BufferedImage(800, height, BufferedImage.TYPE_INT_ARGB);
+ im.getGraphics().setColor(Color.WHITE);
+ im.getGraphics().fillRect(0, 0, im.getWidth(), im.getHeight());
+ mappingPanel.paint(im.getGraphics());
+ document.addPicture(im, 600, height * 6 / 8);
+
+ // Add table of field to field mapping
+ XWPFTable table = document.createTable(fieldtoFieldMapping.getCdmItems().size() + 1, 4);
+ // table.setWidth(2000);
+ XWPFTableRow header = table.getRow(0);
+ setTextAndHeaderShading(header.getCell(0), "Destination Field");
+ setTextAndHeaderShading(header.getCell(1), "Source Field");
+ setTextAndHeaderShading(header.getCell(2), "Logic");
+ setTextAndHeaderShading(header.getCell(3), "Comment");
+ int rowNr = 1;
+ for (MappableItem cdmField : fieldtoFieldMapping.getCdmItems()) {
+ XWPFTableRow row = table.getRow(rowNr++);
+ row.getCell(0).setText(cdmField.getName());
+
+ StringBuilder source = new StringBuilder();
+ StringBuilder logic = new StringBuilder();
+ StringBuilder comment = new StringBuilder();
+ for (ItemToItemMap fieldToFieldMap : fieldtoFieldMapping.getSourceToCdmMaps())
+ if (fieldToFieldMap.getCdmItem() == cdmField) {
+ if (source.length() != 0)
+ source.append("\n");
+ source.append(fieldToFieldMap.getSourceItem().getName());
+
+ if (logic.length() != 0)
+ logic.append("\n");
+ logic.append(fieldToFieldMap.getLogic());
+
+ if (comment.length() != 0)
+ comment.append("\n");
+ comment.append(fieldToFieldMap.getComment());
+ }
+ for (Field field : cdmTable.getFields())
+ if (field.getName().equals(cdmField.getName())) {
+ if (comment.length() != 0)
+ comment.append("\n");
+ comment.append(field.getComment());
+ }
+
+ row.getCell(1).setText(source.toString());
+ row.getCell(2).setText(logic.toString());
+ row.getCell(3).setText(comment.toString());
+ }
+ }
+
+ }
+
+ private static void setTextAndHeaderShading(XWPFTableCell cell, String text) {
+ cell.setText(text);
+
+ cell.setColor("AAAAFF");
+ // CTShd ctshd = cell.getCTTc().addNewTcPr().addNewShd();
+ // ctshd.setColor("FFFFFF");
+ // ctshd.setVal(STShd.CLEAR);
+ // ctshd.setFill("6666BB");
+
+ }
+
+ private static void addTableLevelSection(CustomXWPFDocument document, ETL etl) throws InvalidFormatException, FileNotFoundException {
+ XWPFParagraph tmpParagraph = document.createParagraph();
+ XWPFRun tmpRun = tmpParagraph.createRun();
+
+ tmpRun.setText("Source Data Mapping Approach");
+ tmpRun.setFontSize(18);
+
+ MappingPanel mappingPanel = new MappingPanel(etl.getTableToTableMapping());
+ mappingPanel.setShowOnlyConnectedItems(true);
+ int height = mappingPanel.getMinimumSize().height;
+ mappingPanel.setSize(800, height);
+
+ BufferedImage im = new BufferedImage(800, height, BufferedImage.TYPE_INT_ARGB);
+ im.getGraphics().setColor(Color.WHITE);
+ im.getGraphics().fillRect(0, 0, im.getWidth(), im.getHeight());
+ mappingPanel.paint(im.getGraphics());
+ document.addPicture(im, 600, height * 6 / 8);
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/interactiveMapping/FetchCDMModelFromServer.java b/src/org/ohdsi/whiteRabbit/interactiveMapping/FetchCDMModelFromServer.java
new file mode 100644
index 00000000..2faf11ab
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/interactiveMapping/FetchCDMModelFromServer.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.interactiveMapping;
+
+import org.ohdsi.databases.DbType;
+import org.ohdsi.databases.RichConnection;
+import org.ohdsi.utilities.files.Row;
+import org.ohdsi.utilities.files.WriteCSVFileWithHeader;
+
+public class FetchCDMModelFromServer {
+
+ public static void main(String[] args) {
+ RichConnection connection = new RichConnection("127.0.0.1", null, "root", "F1r3starter", DbType.MYSQL);
+ connection.use("cdm_v4");
+
+ WriteCSVFileWithHeader out = new WriteCSVFileWithHeader("c:/temp/CDMV4Model.csv");
+ String query = "SELECT table_name,column_name,is_nullable,column_type FROM information_schema.columns WHERE table_schema = 'cdm_v4';";
+ for (Row row : connection.query(query))
+ out.write(row);
+ out.close();
+
+ }
+
+}
diff --git a/src/org/ohdsi/whiteRabbit/interactiveMapping/FlexTable.java b/src/org/ohdsi/whiteRabbit/interactiveMapping/FlexTable.java
new file mode 100644
index 00000000..68436528
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/interactiveMapping/FlexTable.java
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.interactiveMapping;
+
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.swing.JComponent;
+import javax.swing.JOptionPane;
+import javax.swing.JTable;
+import javax.swing.KeyStroke;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.TableModel;
+
+public class FlexTable extends JTable implements ActionListener {
+
+ private static final long serialVersionUID = 3017125804758269739L;
+
+ private String rowstring, value;
+ private Clipboard system;
+ private StringSelection stsel;
+ private FlexTableModel model = new FlexTableModel();
+
+ public FlexTable() {
+ super();
+ setModel(model);
+ model.addTableModelListener(this);
+ KeyStroke copy = KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK, false);
+ KeyStroke paste = KeyStroke.getKeyStroke(KeyEvent.VK_V, ActionEvent.CTRL_MASK, false);
+ registerKeyboardAction(this, "Copy", copy, JComponent.WHEN_FOCUSED);
+ registerKeyboardAction(this, "Paste", paste, JComponent.WHEN_FOCUSED);
+ system = Toolkit.getDefaultToolkit().getSystemClipboard();
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ if (e.getActionCommand().compareTo("Copy") == 0) {
+ StringBuilder stringBuilder = new StringBuilder();
+ int numcols = getSelectedColumnCount();
+ int numrows = getSelectedRowCount();
+ int[] rowsselected = getSelectedRows();
+ int[] colsselected = getSelectedColumns();
+ if (!((numrows - 1 == rowsselected[rowsselected.length - 1] - rowsselected[0] && numrows == rowsselected.length) && (numcols - 1 == colsselected[colsselected.length - 1]
+ - colsselected[0] && numcols == colsselected.length))) {
+ JOptionPane.showMessageDialog(null, "Invalid Copy Selection", "Invalid Copy Selection", JOptionPane.ERROR_MESSAGE);
+ return;
+ }
+ for (int i = 0; i < numrows; i++) {
+ for (int j = 0; j < numcols; j++) {
+ stringBuilder.append(getValueAt(rowsselected[i], colsselected[j]));
+ if (j < numcols - 1)
+ stringBuilder.append("\t");
+ }
+ stringBuilder.append("\n");
+ }
+ stsel = new StringSelection(stringBuilder.toString());
+ system = Toolkit.getDefaultToolkit().getSystemClipboard();
+ system.setContents(stsel, stsel);
+ }
+ if (e.getActionCommand().compareTo("Paste") == 0) {
+ int startRow = (getSelectedRows())[0];
+ int startCol = (getSelectedColumns())[0];
+ try {
+ String trstring = (String) (system.getContents(this).getTransferData(DataFlavor.stringFlavor));
+ StringTokenizer tokenizer = new StringTokenizer(trstring, "\n");
+ for (int i = 0; tokenizer.hasMoreTokens(); i++) {
+ rowstring = tokenizer.nextToken();
+ StringTokenizer tokenizer2 = new StringTokenizer(rowstring, "\t");
+ for (int j = 0; tokenizer2.hasMoreTokens(); j++) {
+ value = (String) tokenizer2.nextToken();
+ setValueAt(value, startRow + i, startCol + j);
+ }
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ private class FlexTableModel implements TableModel {
+ private List listeners = new ArrayList();
+ private List> rows = new ArrayList>();
+ private int columnCount = 0;
+
+ private void notifyListeners() {
+ for (TableModelListener listener : listeners)
+ listener.tableChanged(new TableModelEvent(this, TableModelEvent.HEADER_ROW));
+ }
+
+ @Override
+ public void addTableModelListener(TableModelListener l) {
+ listeners.add(l);
+ }
+
+ @Override
+ public Class> getColumnClass(int columnIndex) {
+ return String.class;
+ }
+
+ @Override
+ public int getColumnCount() {
+ return columnCount + 1;
+ }
+
+ @Override
+ public String getColumnName(int columnIndex) {
+ return null;
+ }
+
+ @Override
+ public int getRowCount() {
+ return rows.size() + 1;
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ if (rowIndex >= rows.size())
+ return "";
+ List row = rows.get(rowIndex);
+ if (row.size() <= columnIndex)
+ return "";
+ else
+ return row.get(columnIndex);
+ }
+
+ @Override
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return true;
+ }
+
+ @Override
+ public void removeTableModelListener(TableModelListener l) {
+ listeners.remove(l);
+ }
+
+ @Override
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ for (int i = rows.size(); i <= rowIndex; i++)
+ rows.add(new ArrayList());
+ List row = rows.get(rowIndex);
+ for (int i = row.size(); i <= columnIndex; i++)
+ row.add("");
+
+ row.set(columnIndex, aValue.toString());
+ if (columnIndex >= columnCount)
+ columnCount = columnIndex + 1;
+ notifyListeners();
+ }
+
+ }
+}
diff --git a/src/org/ohdsi/whiteRabbit/interactiveMapping/LabeledRectangle.java b/src/org/ohdsi/whiteRabbit/interactiveMapping/LabeledRectangle.java
new file mode 100644
index 00000000..b8fc6a8d
--- /dev/null
+++ b/src/org/ohdsi/whiteRabbit/interactiveMapping/LabeledRectangle.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright 2014 Observational Health Data Sciences and Informatics
+ *
+ * This file is part of WhiteRabbit
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author Observational Health Data Sciences and Informatics
+ * @author Martijn Schuemie
+ ******************************************************************************/
+package org.ohdsi.whiteRabbit.interactiveMapping;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Stroke;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.event.ChangeListener;
+
+import org.ohdsi.whiteRabbit.interactiveMapping.dataModel.MappableItem;
+
+public class LabeledRectangle implements MappingComponent {
+
+ public static int FONT_SIZE = 18;
+
+ private static Stroke stroke = new BasicStroke(2);
+ private static BasicStroke dashed = new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, new float[] { 10.f }, 0.0f);
+ private List changeListeners = new ArrayList