// // CRI-MAP file generation // // Important notes about the gen files: // // 1. A gen file contains data for ONE chromosome. // 2. Marker names consists of at most 15 characters. // 3. Family names must be unique, but there are no limit on the number of characters. // 4. Individual id's must be unique numbers. // 5. Individuals must have 0 or 2 parents, which means that the unknown parent for an // individual with only on known parent must be generated. // 6. Unknown parents and alleles are coded as 0. // 7. Allele id's must be numbers. // 8. All males must have their second (non existing) allele on the X chromosome coded // as a dummy allele, e.g. 99. // package se.arexis.agdb.util.FileExport; import java.io.*; import java.util.*; import java.sql.*; import se.arexis.agdb.db.DbDataFile; import se.arexis.agdb.db.DbException; import se.arexis.agdb.util.*; public class GenCRIMAP extends GenFormat //Thread { /** * This class hols information about an individual */ class IndDataRec { /** The crimap id of the individual */ public String n; /** The id of the SU the individual belong to */ public int su; /** The name of the family the individual belong to */ public String family; /** The id of the individual */ public String iid; /** The identity of the individual */ public String identity; /** The alias of the individual */ public String alias; public String father; public String mother; /** The sex of the individual */ public String sex; /** The birthdate of the individual */ public String birth_date; /** * Creates a new IndDataRec instance. * */ public IndDataRec () { this.n = null; this.su = 0; this.family = null; this.iid = null; this.identity = null;; this.alias = null;; this.father = null; this.mother = null; this.sex = null; this.birth_date = null; } } class RelDataRec { public String sid; public String suid; public String suname; public String fid; public String fname; public String gql; public String filter; public String gsid; public RelDataRec () { this.sid = null;; this.suid = null; this.suname = null;; this.fid = null; this.fname = null; this.gql = null; this.filter = null; this.gsid = null; } } class AllelesRec { public String name; public int n; public AllelesRec () { this.name = null; this.n = 0; } } class MidDataRec { public String cid; public String cname; public String mid; public String mname; public Vector alleles; public MidDataRec () { this.cid = null; this.cname = null; this.mid = null; this.mname = null; this.alleles = null; } } class GenFileRec { public String cid; public String file_name; public int file_dfid; public FileWriter file; public GenFileRec () { this.cid = null; this.file_name = null; this.file_dfid = 0; this.file = null; } } // Constructor parameters private static int fgid = 0; private static String directory = null; private static String DB_URL = null; private static String DB_UID = null; private static String DB_PWD = null; private static String NULL_CHAR = null; // File generation parameters private String fgname = null; private String pid = null; private String pname = null; private String id = null; private String uname = null; private String mode = null; private String msid = null; private String msname = null; private boolean multiFiles = false; // Counters private int fcounter = 0; private int icounter = 0; private int dcounter = 0; private int maxInd = 0; // Vectors private Vector rels = null; /** The ids of the selected markers */ private Vector mids = null; /** The ids of the selected individuals */ private Vector inds = null; /** Missing individuals which has been created */ private Vector dummys = null; // Files private Vector gens = null; private int log_dfid = 0; //private String log_name = "log.txt"; private String log_name = ""; private int map_dfid = 0; private FileWriter map_file = null; // private String map_name = "mapping.txt"; private String map_name = ""; private PreparedStatement mstmt = null; private PreparedStatement umstmt = null; private PreparedStatement uastmt = null; private PreparedStatement astmt = null; //private CallableStatement pstmt = null; // Constants private static int UPDATE_INTERVAL = 10; private static int ISTART = 1000; //------------------------------------------------------------------------------- public GenCRIMAP(int fgid, String directory, String driver, String dburl, String uid, String pwd, boolean multiFiles) throws SQLException { this.fgid = fgid; this.directory = directory; this.DB_URL = dburl; this.DB_UID = uid; this.DB_PWD = pwd; this.multiFiles = multiFiles; // The output file names are extended with the fgid for result import. this.log_name = "log_" + fgid + ".txt"; this.map_name = "mapping_" + fgid + ".txt"; this.pid = null; this.pname = null; this.id = null; this.uname = null; this.mode = null; this.msid = null; this.msname = null; this.rels = new Vector(1); this.mids = new Vector(100); this.inds = new Vector(1000); this.dummys = new Vector(100); this.gens = new Vector(25); this.fcounter = 0; this.icounter = 0; this.dcounter = 0; // this.log_name = "data" + fgid + ".txt"; try { //DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); //Class.forName("oracle.jdbc.driver.OracleDriver"); Class.forName(driver); this.conn = DriverManager.getConnection(DB_URL, DB_UID, DB_PWD); this.conn.setAutoCommit(false); } catch (Exception e) {} } //------------------------------------------------------------------------------- public void run() { int i = 0; try { Errors.logDebug("GenCrimap.run() started"); DbDataFile df = new DbDataFile(); log_file = createPhysicalFile(directory, log_name); Errors.logDebug("before readFileGenParams"); readFileGenerationParameters(); Errors.logDebug("after readFileGenParams"); readRelationParameters(); log_dfid = df.createDataFile(conn, fgid, log_name, id); map_file = createPhysicalFile(directory, map_name); map_dfid = df.createDataFile(conn, fgid, map_name, id); prepareSQL(); Errors.logDebug("Before single or multi"); if (mode.equals("S")) singleMode(); else multiMode(); Errors.logDebug("After single or multi"); conn.commit(); } catch (Exception e) { e.printStackTrace(System.err); try { conn.rollback(); } catch (Exception ignore) {} } finally { closePhysicalFile(log_file); closePhysicalFile(map_file); for (i=0; i < gens.size(); i++) closePhysicalFile(((GenFileRec) gens.elementAt(i)).file); } Errors.logDebug("GenCrimap.run() ended"); } //------------------------------------------------------------------------------- public void singleMode() throws Exception { int i = 0; int j = 0; long t0 = System.currentTimeMillis(); long t1 = 0; try { Errors.logDebug("SingleMode started"); writeLogFileHeader(); setProgress(log_dfid, 0, 1, 50, 100); readMids(); Errors.logDebug("After readMids"); // createGenFiles(); writeLogFileSU(0); readInds(0); writeGenFileHeaders(); for (i=0; i < inds.size(); i++) checkForMissingParents(i); writeMapFile(); setProgress(map_dfid, 0, 1, 100, 100); for (i=0; i < inds.size(); i++) { Errors.logDebug("singleMode i="+i); if (firstInFamily(i)) writeFamilyData(i); writeIndData(i); writeGenotypes(i); if (lastInFamily(i)) writeDummys(i); if ((i % UPDATE_INTERVAL) == 0) { for (j=0; j < gens.size(); j++) setProgress(((GenFileRec) gens.elementAt(j)).file_dfid, 0, 1, i, inds.size()); if (aborted()) { writeLogFileError("Generation aborted by user"); break; } } yield(); // Give other threads a chance to run } for (j=0; j < gens.size(); j++) setProgress(((GenFileRec) gens.elementAt(j)).file_dfid, 0, 1, 100, 100); } catch (Exception e) { e.printStackTrace(System.err); for (j=0; j < gens.size(); j++) setProgress(((GenFileRec) gens.elementAt(j)).file_dfid, 0, 1, PROGRESS_ERROR, 100); } finally { t1 = System.currentTimeMillis(); writeLogFileFooter((int) (t1-t0)/1000); setProgress(log_dfid, 0, 1, 100, 100); } } //------------------------------------------------------------------------------- public void multiMode() throws Exception { int su = 0; int i = 0; int j = 0; long t0 = System.currentTimeMillis(); long t1 = 0; try { writeLogFileHeader(); setProgress(log_dfid, 0, 1, 50, 100); readUMids(); createGenFiles(); for (su=0; su < rels.size(); su++) readInds(su); writeGenFileHeaders(); for (i=0; i < inds.size(); i++) { if (firstInSamplingUnit(i)) { IndDataRec ind = (IndDataRec) inds.elementAt(i); writeLogFileSU(ind.su); checkForMissingMarkerMappings(ind.su); } checkForMissingParents(i); } writeMapFile(); setProgress(map_dfid, 0, 1, 100, 100); for (i=0; i < inds.size(); i++) { if (firstInFamily(i)) writeFamilyData(i); writeIndData(i); writeUGenotypes(i); if (lastInFamily(i)) writeDummys(i); if ((i % UPDATE_INTERVAL) == 0) { for (j=0; j < gens.size(); j++) setProgress(((GenFileRec) gens.elementAt(j)).file_dfid, 0, 1, i, inds.size()); if (aborted()) { writeLogFileError("Generation aborted by user"); break; } } yield(); // Give other threads a chance to run } for (j=0; j < gens.size(); j++) setProgress(((GenFileRec) gens.elementAt(j)).file_dfid, 0, 1, 100, 100); } catch (Exception e) { e.printStackTrace(System.err); for (j=0; j < gens.size(); j++) setProgress(((GenFileRec) gens.elementAt(j)).file_dfid, 0, 1, PROGRESS_ERROR, 100); } finally { t1 = System.currentTimeMillis(); writeLogFileFooter((int) (t1-t0)/1000); setProgress(log_dfid, 0, 1, 100, 100); } } //-------------------------------------------------------------------------------- private FileWriter createPhysicalFile(String directory, String file_name) throws IOException { return new FileWriter(new File(directory + "/" + file_name)); } //-------------------------------------------------------------------------------- private void closePhysicalFile(FileWriter fw) { try { if (fw != null) fw.close(); } catch (IOException ioe) {} } //-------------------------------------------------------------------------------- /* private int createDataFile(int fgid, String name, String id) throws SQLException, IOException { CallableStatement s = null; String message = null; int dfid = 0; if (name.length()>20) throw new DbException("Name exceeds 20 characters"); try { dfid = getNextID(conn,"Data_Files_Seq"); -- Find DFID begin if l_ok then select Data_Files_Seq.nextval into p_dfid from dual; end if; exception when others then p_message := 'Failed to increment file id. ' || 'ORACLE error: ' || SQLERRM; l_ok := false; end; -- Create the data file row begin if l_ok then insert into Data_Files Values( p_dfid, p_fgid, p_name, p_status, p_comm, p_id, sysdate); end if; exception when others then p_message := 'Failed to create the data file row. ' || 'ORACLE error: ' || SQLERRM; l_ok := false; end; s = conn.prepareCall("{CALL GDBP.CREATE_DATA_FILE(?,?,?,?,?,?,?)}"); s.registerOutParameter(1, java.sql.Types.NUMERIC); s.registerOutParameter(7, java.sql.Types.VARCHAR); s.setNull(1, java.sql.Types.NUMERIC); s.setInt(2, fgid); s.setString(3, name); s.setString(4, "0 %"); s.setNull(5, java.sql.Types.VARCHAR); s.setInt(6, Integer.parseInt(id)); s.setNull(7, java.sql.Types.VARCHAR); s.execute(); message = s.getString(7); dfid = s.getInt(1); s.close(); if (message != null && !message.equals("")) throw new SQLException(name); } catch (SQLException sqle) { writeLogFileError("SQL ERROR [" + message + "]"); throw sqle; } conn.commit(); return dfid; } */ //-------------------------------------------------------------------------------- private void readFileGenerationParameters() throws SQLException, IOException { Statement s = null; ResultSet r = null; String q = null; try { q = "SELECT FG.NAME as FGNAME, P.PID, P.NAME as PNAME, U.ID, U.NAME as UNAME, FG.MODE_," + " FG.XMSID, FG.XVSID" + " FROM V_PROJECTS_1 P, V_USERS_1 U, V_FILE_GENERATIONS_1 FG" + " WHERE FG.PID = P.PID AND FG.ID = U.ID AND FGID = " + fgid; s = conn.createStatement(); r = s.executeQuery(q); if (r.next()) { fgname = r.getString("FGNAME"); pid = r.getString("PID"); pname = r.getString("PNAME"); id = r.getString("ID"); uname = r.getString("UNAME"); mode = r.getString("MODE_"); msid = r.getString("XMSID"); if (r.wasNull()) msid = null; } else throw new SQLException("No file generation found with fgid = " + fgid); } catch (SQLException sqle) { sqle.printStackTrace(); writeLogFileError("SQL ERROR [" + q + "]"); throw sqle; } finally { if (r != null) r.close(); if (s != null) s.close(); } if (msid != null) { try { if (mode.equals("S")) q = "SELECT NAME FROM V_MARKER_SETS_1" + " WHERE MSID = " + msid; else q = "SELECT NAME FROM V_U_MARKER_SETS_1" + " WHERE UMSID = " + msid; s = conn.createStatement(); r = s.executeQuery(q); if (r.next()) { msname = r.getString("NAME"); } else throw new SQLException("No (unified) marker set found with (u)msid = " + msid); } catch (SQLException sqle) { writeLogFileError("SQL ERROR [" + q + "]"); throw sqle; } finally { if (r != null) r.close(); if (s != null) s.close(); } } } //------------------------------------------------------------------------------- public void readRelationParameters() throws SQLException, IOException { Statement s = null; ResultSet r = null; String q = null; RelDataRec relData = null; GqlTranslator trans = null; try { q = "SELECT R.SID, R.SUID, R.NAME as SUNAME, R.FID, F.NAME as FNAME, R.EXPRESSION, R.GSID" + " FROM V_R_FG_FLT_1 R, V_FILTERS_1 F" + " WHERE R.FID = F.FID AND FGID = " + fgid; s = conn.createStatement(); r = s.executeQuery(q); while (r.next()) { Errors.logDebug("ReadRelationParameters..."); relData = new RelDataRec(); relData.sid = r.getString("SID"); relData.suid = r.getString("SUID"); relData.suname = r.getString("SUNAME"); relData.fid = r.getString("FID"); relData.fname = r.getString("FNAME"); relData.gql = r.getString("EXPRESSION"); relData.gsid = r.getString("GSID"); trans = new GqlTranslator(pid, relData.suid, relData.gsid, relData.gql, conn); trans.translate(); relData.filter = trans.getFilter(); relData.gsid = r.getString("GSID"); rels.addElement(relData); } } catch (SQLException sqle) { writeLogFileError("SQL ERROR [" + q + "]"); throw sqle; } finally { if (r != null) r.close(); if (s != null) s.close(); } } //------------------------------------------------------------------------------- public void readInds(int su) throws SQLException, IOException { Statement s = null; ResultSet r = null; IndDataRec ind = null; RelDataRec rel = (RelDataRec) rels.elementAt(su); try { s = conn.createStatement(); r = s.executeQuery("SELECT " + "grp.GNAME, " + "ind.IID, " + "ind.IDENTITY, " + "ind.ALIAS, " + "ind.FIDENTITY, " + "ind.MIDENTITY, " + "ind.SEX, " + "to_char(ind.BIRTH_DATE, 'YYYY-MM-DD') as BD " + rel.filter + " ORDER BY grp.GNAME"); while (r.next()) { icounter++; if (ind == null || !ind.family.equals(r.getString("GNAME"))) fcounter++; ind = new IndDataRec(); // annars ta ny siffra, (obs dummys) (Multiple???) //ind.n = "" + (ISTART + icounter); ind.su = su; ind.family = r.getString("GNAME"); ind.iid = r.getString("IID"); ind.identity = r.getString("IDENTITY"); //System.err.println("identity:"+ind.identity); // determine if name is an integer or we need to rename //ind.n = "" + (ISTART + icounter); int newValue = getMappingName(ind.identity); if (newValue > 0 && !occupied(newValue,inds)) ind.n = "" + newValue; else ind.n = null; // Keep track of highest nr found if(ind.n != null && ind.n != "") { if(Integer.parseInt(ind.n) > maxInd) { maxInd = Integer.parseInt(ind.n); } } //--------- ind.alias = r.getString("ALIAS"); if (r.wasNull()) ind.alias = null; ind.father = r.getString("FIDENTITY"); if (r.wasNull()) ind.father = null; ind.mother = r.getString("MIDENTITY"); if (r.wasNull()) ind.mother = null; ind.sex = r.getString("SEX"); if (r.wasNull()) ind.sex = null; ind.birth_date = r.getString("BD"); if (r.wasNull()) ind.birth_date = null; inds.addElement(ind); yield(); // Give other threads a chance to run } // rename all indnames that was not integer value for (int i=0; i<icounter;i++) { IndDataRec tempInd = (IndDataRec)inds.elementAt(i); if(tempInd.n == null || tempInd.equals("")) { maxInd ++; tempInd.n= "" + maxInd; inds.removeElementAt(i); inds.insertElementAt(tempInd,i); } } //Dummys??? } catch (SQLException sqle) { writeLogFileError("SQL ERROR [" + rel.filter + "]"); throw sqle; } finally { if (r != null) r.close(); if (s != null) s.close(); } } //------------------------------------------------------------------------------- private int getMappingName(String identity) { //Encode integers as integers... int identityAsInteger; try { identityAsInteger =Integer.parseInt(identity); // Do we catch parse execption if an integer was not "found"?? } catch (Exception e) { // we could not retrieve an integer identityAsInteger =-1; } return identityAsInteger; } private boolean occupied(int intValue, Vector allInds) { String strValue = ""+intValue; //look for value in vector for (int i=0; i<allInds.size();i++) { IndDataRec tempInd = (IndDataRec)inds.elementAt(i); String tmp = tempInd.n; if(tmp !=null && tmp.equals(strValue)) { return true; } } return false; } public boolean indExist(int su, String identity) { int i = 0; while (i < inds.size()) { IndDataRec ind = (IndDataRec) inds.elementAt(i); if (su == ind.su && identity.equals(ind.identity)) return true; i++; } return false; } /** * Checks if an individual is a member of a given SU and given family. * * @param samplingUnitId The id of the SU to look for individual in. * @param individualId The id of the individual to look for. * @param familyName The name of the family to look for individual in. * @return True if individual is member of familiy * False if individual is not member of family */ public boolean indInFamily(int samplingUnitId, String individualId, String familyName) { IndDataRec currentInd; // Loop all individuals int i = 0; while (i < inds.size()) { // Get current individual and check if it is the one we are // looking for currentInd = (IndDataRec) inds.elementAt(i); if (samplingUnitId == currentInd.su && individualId.equals(currentInd.identity) && familyName.equals(currentInd.family)) { return true; } i++; } return false; } /** * Look for an individual within a given SU and a given family and * return the N value (crimap id) of the individual. * * @param samplingUnitId The SU to look for individual in. * @param individualId The id of the individual to look for. * @param familyName The family name to look for individual in. * @return The crimap individual id. */ public String getN(int samplingUnitId, String individualId, String familyName) { if (individualId == null) { return "0"; } IndDataRec currentInd; // Look for individual in inds array for (int i = 0; i < inds.size(); i++) { // if current individual has correct su, family name and // individual id, return its N-value currentInd = (IndDataRec) inds.elementAt(i); if (samplingUnitId == currentInd.su && individualId.equals(currentInd.identity) && familyName.equals(currentInd.family)) { return currentInd.n; } } // Individual not found, look for individual in dummys array for (int i = 0; i<dummys.size(); i++) { // if corrent su, family name and id, return N-value of individual currentInd = (IndDataRec) dummys.elementAt(i); if (samplingUnitId == currentInd.su && individualId.equals(currentInd.identity) && familyName.equals(currentInd.family)) { return currentInd.n; } } return "0"; } //------------------------------------------------------------------------------- public String createDummy(int su, String fam, String sex) { IndDataRec dummy = null; dcounter++; dummy = new IndDataRec(); //dummy.n = "" + (ISTART + icounter + dcounter); maxInd ++; dummy.n = "" + (maxInd); dummy.su = su; dummy.family = fam; dummy.iid = null; dummy.identity = "<..." + dummy.n + "...>"; dummy.alias = null; dummy.father = null; dummy.mother = null; dummy.sex = sex; dummy.birth_date = null; dummys.addElement(dummy); return dummy.identity; } //------------------------------------------------------------------------------- public void checkForMissingParents(int indnr) { IndDataRec ind = (IndDataRec) inds.elementAt(indnr); if (ind.father != null) { if (!indExist(ind.su, ind.father)) { writeLogFileWarning("Father (" + ind.father + ") for " + "individual ("+ ind.identity + ")" + " is not selected by filter and family grouping"); ind.father = null; } else if (!indInFamily(ind.su, ind.father, ind.family)) { writeLogFileWarning("Father (" + ind.father + ") for " + "individual ("+ ind.identity + ")" + " is not a member of the family"); ind.father = null; } } if (ind.mother != null) { if (!indExist(ind.su, ind.mother)) { writeLogFileWarning("Mother (" + ind.mother + ") for " + "individual ("+ ind.identity + ")" + " is not selected by filter and family grouping"); ind.mother = null; } else if (!indInFamily(ind.su, ind.mother, ind.family)) { writeLogFileWarning("Mother (" + ind.mother + ") for " + "individual ("+ ind.identity + ")" + " is not a member of the family"); ind.mother = null; } } if (ind.father == null && ind.mother != null) ind.father = createDummy(ind.su, ind.family, "M"); if (ind.father != null && ind.mother == null) ind.mother = createDummy(ind.su, ind.family, "F"); } //------------------------------------------------------------------------------- public void checkForMissingMarkerMappings(int su) throws SQLException { Statement s = null; ResultSet r = null; RelDataRec rel = (RelDataRec) rels.elementAt(su); int i = 0; for (i=0; i < mids.size(); i++) { String umid = ((MidDataRec) mids.elementAt(i)).mid; String umname = ((MidDataRec) mids.elementAt(i)).mname; s = conn.createStatement(); r = s.executeQuery("SELECT MID " + " FROM V_R_UMID_MID_1 " + " WHERE SUID = " + rel.suid + " AND UMID = " + umid); if (! r.next()) writeLogFileWarning("No mapping for unified marker " + umname); if (r != null) r.close(); if (s != null) s.close(); } } //------------------------------------------------------------------------------- public boolean firstInSamplingUnit(int i) { if (i == 0) return true; else { IndDataRec curr = (IndDataRec) inds.elementAt(i); IndDataRec prev = (IndDataRec) inds.elementAt(i-1); return curr.su != prev.su; } } //------------------------------------------------------------------------------- public boolean firstInFamily(int i) { if (i == 0) return true; else { IndDataRec curr = (IndDataRec) inds.elementAt(i); IndDataRec prev = (IndDataRec) inds.elementAt(i-1); return !(curr.su == prev.su && curr.family.equals(prev.family)); } } //------------------------------------------------------------------------------- public boolean lastInFamily(int i) { if (i == inds.size()-1) return true; else { IndDataRec curr = (IndDataRec) inds.elementAt(i); IndDataRec next = (IndDataRec) inds.elementAt(i+1); return !(curr.su == next.su && curr.family.equals(next.family)); } } //------------------------------------------------------------------------------- public Vector renumberAlleles(Vector a) { int i = 0; int imax = 0; Errors.logDebug("renumberAlleles, a.size="+a.size()); //Encode integers as integers... for (i=0; i<a.size(); i++){ try { AllelesRec ar = (AllelesRec) a.elementAt(i); ar.n = Integer.parseInt(ar.name); if (ar.n > imax) { imax = ar.n; } } catch (Exception e) { } } Errors.logDebug("imax="+imax+", a.size="+a.size()); //Encode non positive integers as positive integers... for (i=0; i<a.size(); i++) { AllelesRec ar = (AllelesRec) a.elementAt(i); if (ar.n <= 0) ar.n = ++imax; } Errors.logDebug("imax="+imax+", a.size="+a.size()); /* *This section is outcommented due to a serious bug. Never ending loop. * ... TH // Fill out the holes... for (i=0; i<a.size(); i++) { AllelesRec ar = (AllelesRec) a.elementAt(i); Errors.logDebug("Alleles="+ar.name+", i="+i+", ar.n="+ar.n); if (ar.n != i + 1) { AllelesRec nar = new AllelesRec(); nar.n = i + 1; nar.name = ""; a.insertElementAt(nar, i); } } */ Errors.logDebug("renumberAlleles done"); return a; } //------------------------------------------------------------------------------- public Vector readAlleles(String mid, String mname) throws SQLException { Statement s = null; ResultSet r = null; String q = null; AllelesRec ar = null; Vector alleles = new Vector(); try { q = "SELECT NAME" + " FROM V_ALLELES_1" + " WHERE MID = " + mid + " ORDER BY TO_POSITIVE_NUMBER_ELSE_NULL(NAME), NAME"; s = conn.createStatement(); r = s.executeQuery(q); while (r.next()) { Errors.logDebug("readAlleles loop [mid="+mid+", mname="+mname+",aname="+r.getString("NAME")+"]"); ar = new AllelesRec(); ar.name = r.getString("NAME"); if (!ar.name.equals("0")) // Temporary fix for Uppsala! alleles.addElement(ar); else log_file.write("WARNING: Allele 0 for marker " + mname + " treated as NULL\n"); } } catch (SQLException sqle) { writeLogFileError("SQL ERROR [" + q + "]"); throw sqle; } catch (IOException ioe) { } finally { if (r != null) r.close(); if (s != null) s.close(); } return renumberAlleles(alleles); } //------------------------------------------------------------------------------- public Vector readUAlleles(String mid, String mname) throws SQLException { Statement s = null; ResultSet r = null; String q = null; AllelesRec ar = null; Vector alleles = new Vector(); try { q = "SELECT NAME" + " FROM V_U_ALLELES_1" + " WHERE UMID = " + mid + " ORDER BY TO_POSITIVE_NUMBER_ELSE_NULL(NAME), NAME"; s = conn.createStatement(); r = s.executeQuery(q); while (r.next()) { ar = new AllelesRec(); ar.name = r.getString("NAME"); if (!ar.name.equals("0")) // Temporary fix for Uppsala! alleles.addElement(ar); else log_file.write("WARNING: Allele 0 for marker " + mname + " treated as NULL\n"); } } catch (SQLException sqle) { writeLogFileError("SQL ERROR [" + q + "]"); throw sqle; } catch (IOException ioe) { } finally { if (r != null) r.close(); if (s != null) s.close(); } return renumberAlleles(alleles); } //------------------------------------------------------------------------------- public void readMids() throws SQLException, IOException { Statement s = null; ResultSet r = null; String q = null; MidDataRec mid = null; if (msid != null) try { q = "SELECT CID, CNAME, MID, MNAME" + " FROM V_POSITIONS_2" + " WHERE MSID = " + msid + " ORDER BY CNAME, POSITION, MNAME"; s = conn.createStatement(); r = s.executeQuery(q); while (r.next()) { Errors.logDebug("readMids loop"); mid = new MidDataRec(); mid.cid = r.getString("CID"); mid.cname = r.getString("CNAME"); mid.mid = r.getString("MID"); mid.mname = r.getString("MNAME"); if (mid.mname.length() > 15) writeLogFileError("Marker name (" + mid.mname + ") too long!"); mid.alleles = readAlleles(mid.mid, mid.mname); mids.addElement(mid); } // we only want one uotput file. // No nead to handle different chromosomes, we name them the same if (!multiFiles) { MidDataRec tmpMid; for (int i=0; i<mids.size();i++) { tmpMid=(MidDataRec) mids.elementAt(i); mids.removeElementAt(i); tmpMid.cid="_"; tmpMid.cname="_"; mids.insertElementAt(tmpMid,i); } } } catch (SQLException sqle) { writeLogFileError("SQL ERROR [" + q + "]"); throw sqle; } finally { if (r != null) r.close(); if (s != null) s.close(); } } //------------------------------------------------------------------------------- public void readUMids() throws SQLException, IOException { Statement s = null; ResultSet r = null; String q = null; MidDataRec mid = null; if (msid != null) try { q = "SELECT CID, CNAME, UMID, UMNAME" + " FROM V_U_POSITIONS_2" + " WHERE UMSID = " + msid + " ORDER BY CNAME, POSITION, UMNAME"; s = conn.createStatement(); r = s.executeQuery(q); while (r.next()) { mid = new MidDataRec(); mid.cid = r.getString("CID"); mid.cname = r.getString("CNAME"); mid.mid = r.getString("UMID"); mid.mname = r.getString("UMNAME"); if (mid.mname.length() > 15) writeLogFileError("Marker name (" + mid.mname + ") too long!"); mid.alleles = readUAlleles(mid.mid, mid.mname); mids.addElement(mid); } // we only want one uotput file. // No nead to handle different chromosomes, we name them the same if (!multiFiles) { MidDataRec tmpMid; for (int i=0; i<mids.size();i++) { tmpMid=(MidDataRec) mids.elementAt(i); mids.removeElementAt(i); tmpMid.cid="_"; tmpMid.cname="_"; mids.insertElementAt(tmpMid,i); } } } catch (SQLException sqle) { writeLogFileError("SQL ERROR [" + q + "]"); throw sqle; } finally { if (r != null) r.close(); if (s != null) s.close(); } } //------------------------------------------------------------------------------- public void createGenFiles() throws SQLException, IOException, DbException { GenFileRec gfr = null; GenFileRec tmpGfr = null; MidDataRec mid = null; String lcname = null; int i = 0; DbDataFile df = new DbDataFile(); for (i=0; i < mids.size(); i++) { mid = (MidDataRec) mids.elementAt(i); if (lcname == null || !lcname.equals(mid.cname)) { gfr = new GenFileRec(); gfr.cid = mid.cid; gfr.file_name = "chr" + mid.cname + ".gen"; gfr.file = createPhysicalFile(directory, gfr.file_name); gfr.file_dfid = df.createDataFile(conn, fgid, gfr.file_name, id); gens.addElement(gfr); lcname = mid.cname; } } } //------------------------------------------------------------------------------- public int countMarkers(String cid) { int i = 0; int counter = 0; for (i=0; i < mids.size(); i++) { if (cid.equals(((MidDataRec) mids.elementAt(i)).cid)) counter++; } return counter; } //------------------------------------------------------------------------------- private void writeGenFileHeaders() throws IOException { int i = 0; for (i=0; i < gens.size(); i++) { GenFileRec gen = (GenFileRec) gens.elementAt(i); gen.file.write(fcounter + "\n"); gen.file.write(countMarkers(gen.cid) + "\n"); writeMarkers(gen); gen.file.write("\n"); } } //------------------------------------------------------------------------------- private void writeMarkers(GenFileRec gen) throws IOException { int j = 0; for (j=0; j < mids.size(); j++) if (gen.cid.equals(((MidDataRec) mids.elementAt(j)).cid)) gen.file.write(((MidDataRec) mids.elementAt(j)).mname + " "); } //------------------------------------------------------------------------------- public int countFamilyMembers(int su, String fam) { int i = 0; int counter = 0; for (i=0; i<inds.size(); i++) { IndDataRec ind = (IndDataRec) inds.elementAt(i); if (su == ind.su && fam.equals(ind.family)) counter++; } for (i=0; i<dummys.size(); i++) { IndDataRec ind = (IndDataRec) dummys.elementAt(i); if (su == ind.su && fam.equals(ind.family)) counter++; } return counter; } //------------------------------------------------------------------------------- private void writeFamilyData(int i) throws IOException { IndDataRec ind = (IndDataRec) inds.elementAt(i); RelDataRec rel = (RelDataRec) rels.elementAt(ind.su); int j = 0; int members = countFamilyMembers(ind.su, ind.family); for (j=0; j < gens.size(); j++) { FileWriter file = ((GenFileRec) gens.elementAt(j)).file; file.write("\n"); if (mode.equals("M")) file.write(rel.suname + "/"); file.write(ind.family + "\n"); file.write(members + "\n"); } } //------------------------------------------------------------------------------- private void writeIndData(int i) throws Exception { IndDataRec ind = (IndDataRec) inds.elementAt(i); int j = 0; for (j=0; j < gens.size(); j++) { FileWriter file = ((GenFileRec) gens.elementAt(j)).file; file.write(ind.n + " "); file.write(getN(ind.su, ind.mother, ind.family) + " "); file.write(getN(ind.su, ind.father, ind.family) + " "); if (ind.sex.equals("F")) file.write("0"); else if (ind.sex.equals("M")) file.write("1"); else file.write("3"); file.write("\n"); } } //------------------------------------------------------------------------------- private void writeDummys(int indnr) throws Exception { String fam = ((IndDataRec) inds.elementAt(indnr)).family; int su = ((IndDataRec) inds.elementAt(indnr)).su; IndDataRec ind = null;; MidDataRec mid = null;; int i = 0; int j = 0; int k = 0; for (j=0; j < gens.size(); j++) { GenFileRec gen = ((GenFileRec) gens.elementAt(j)); for (i=0; i< dummys.size(); i++) { ind = (IndDataRec) dummys.elementAt(i); if (su == ind.su && fam.equals(ind.family)) { gen.file.write(ind.n + " "); gen.file.write("0 "); gen.file.write("0 "); if (ind.sex.equals("F")) gen.file.write("0"); else if (ind.sex.equals("M")) gen.file.write("1"); else gen.file.write("3"); gen.file.write("\n"); for (k=0; k < mids.size(); k++) { mid = (MidDataRec) mids.elementAt(k); if (gen.cid.equals(mid.cid)) gen.file.write("0 " + replaceIfMaleX(ind, mid, "0") + " "); } gen.file.write("\n"); } } } } //------------------------------------------------------------------------------- public FileWriter getFile(String cid) { int i = 0; for (i=0; i<gens.size(); i++) { GenFileRec gen = (GenFileRec) gens.elementAt(i); if (cid.equals(gen.cid)) return gen.file; } return null; } /** * Renumbers an allele in a given marker. * * @param markerId The marker to look for allele in. * @param alleleNr The allele number. * @return The new number of the allele. */ public String renumberAllele(int markerId, String alleleNr) { if (alleleNr == null) { return null; } // Get the alleles of the current marker Vector alleles = ((MidDataRec) mids.elementAt(markerId)).alleles; // Loop all alleles and look for the one with the given number. When // found, calculate the new number and return it. for (int i = 0; i < alleles.size(); i++) { AllelesRec ar = (AllelesRec) alleles.elementAt(i); if (alleleNr.equals(ar.name)) return "" + ar.n; /* if (alleleNr.equals( ( (AllelesRec) alleles.elementAt(i)).name)) { return "" + (i+1); } */ } return null; } //------------------------------------------------------------------------------- public String replaceIfMaleX(IndDataRec ind, MidDataRec mid, String allele) { if (ind.sex.equals("M") && (mid.cname.equals("x") || mid.cname.equals("X"))) return "" + (mid.alleles.size()+10); else return allele; } //------------------------------------------------------------------------------- private void writeGenotypes(int indnr) throws SQLException, IOException { ResultSet rset = null; IndDataRec ind = (IndDataRec) inds.elementAt(indnr); MidDataRec mid = null; String a1name = null; String a2name = null; FileWriter fw = null; int i = 0; try { mstmt.clearParameters(); mstmt.setInt(1, Integer.parseInt(ind.iid)); rset = mstmt.executeQuery(); while (rset.next()) { String dbmid = rset.getString("MID"); while (! dbmid.equals(((MidDataRec) mids.elementAt(i)).mid)) { mid = (MidDataRec) mids.elementAt(i); fw = getFile(mid.cid); fw.write("0 " + replaceIfMaleX(ind, mid, "0") + " "); i++; } mid = (MidDataRec) mids.elementAt(i); fw = getFile(mid.cid); a1name = rset.getString("A1NAME"); a2name = rset.getString("A2NAME"); a1name = renumberAllele(i, a1name); a2name = renumberAllele(i, a2name); a2name = replaceIfMaleX(ind, mid, a2name); fw.write(replaceIfNull(a1name) + " " + replaceIfNull(a2name) + " "); i++; } while (i < mids.size()) { mid = (MidDataRec) mids.elementAt(i); fw = getFile(mid.cid); fw.write("0 " + replaceIfMaleX(ind, mid, "0") + " "); i++; } for (i=0; i<gens.size(); i++) { GenFileRec gen = (GenFileRec) gens.elementAt(i); gen.file.write("\n"); } } catch (SQLException sqle) { writeLogFileError("writeGenotypes: Fatal SQL Error (iid=" + ind.iid + ")"); throw sqle; } catch (IOException ioe) { writeLogFileError("writeGenotypes: Fatal IO Error (iid=" + ind.iid + ")"); ioe.printStackTrace(System.err); throw ioe; } } //------------------------------------------------------------------------------- private void writeUGenotypes(int indnr) throws SQLException, IOException { ResultSet rset = null; IndDataRec ind = (IndDataRec) inds.elementAt(indnr); MidDataRec mid = null; String a1name = null; String a2name = null; RelDataRec rel = (RelDataRec) rels.elementAt(ind.su); FileWriter fw = null; int i = 0; try { umstmt.clearParameters(); umstmt.setInt(1, Integer.parseInt(rel.suid)); umstmt.setInt(2, Integer.parseInt(ind.iid)); rset = umstmt.executeQuery(); while (rset.next()) { String dbmid = rset.getString("UMID"); while (! dbmid.equals(((MidDataRec) mids.elementAt(i)).mid)) { mid = (MidDataRec) mids.elementAt(i); fw = getFile(mid.cid); fw.write("0 " + replaceIfMaleX(ind, mid, "0") + " "); i++; } mid = (MidDataRec) mids.elementAt(i); fw = getFile(mid.cid); a1name = translateAllele(i, rset.getString("AID1"), ind.identity); a2name = translateAllele(i, rset.getString("AID2"), ind.identity); a1name = renumberAllele(i, a1name); a2name = renumberAllele(i, a2name); a2name = replaceIfMaleX(ind, mid, a2name); fw.write(replaceIfNull(a1name) + " " + replaceIfNull(a2name) + " "); i++; } while (i < mids.size()) { mid = (MidDataRec) mids.elementAt(i); fw = getFile(mid.cid); fw.write("0 " + replaceIfMaleX(ind, mid, "0") + " "); i++; } for (i=0; i<gens.size(); i++) { GenFileRec gen = (GenFileRec) gens.elementAt(i); gen.file.write("\n"); } } catch (SQLException sqle) { writeLogFileError("writeUGenotypes: Fatal SQL Error (iid=" + ind.iid + ")"); throw sqle; } catch (IOException ioe) { writeLogFileError("writeUGenotypes: Fatal IO Error (iid=" + ind.iid + ")"); ioe.printStackTrace(System.err); throw ioe; } } //------------------------------------------------------------------------------- private String translateAllele(int midnr, String aid, String identity) throws SQLException, IOException { ResultSet rset = null; String name = null; String umid = ((MidDataRec) mids.elementAt(midnr)).mid; String umname = ((MidDataRec) mids.elementAt(midnr)).mname; if (aid == null) return aid; else { uastmt.clearParameters(); uastmt.setInt(1, Integer.parseInt(umid)); uastmt.setInt(2, Integer.parseInt(aid)); rset = uastmt.executeQuery(); if (rset.next()) name = rset.getString("NAME"); else writeTranslationError(umname, aid, identity); return name; } } //------------------------------------------------------------------------------- private void writeTranslationError(String umname, String aid, String identity) { Statement s = null; ResultSet r = null; String q = null; String mname = null; String aname = null; try { q = "SELECT MNAME, NAME" + " FROM V_ALLELES_3" + " WHERE AID = " + aid; s = conn.createStatement(); r = s.executeQuery(q); if (r.next()) { mname = r.getString("MNAME"); aname = r.getString("NAME"); } if (r != null) r.close(); if (s != null) s.close(); } catch (Exception e) { e.printStackTrace(System.err); } writeLogFileError("Individual " + identity + ", no mapping for allele " + aname + " (marker: " + mname + ", unified marker: " + umname + ")"); } //------------------------------------------------------------------------------- private void writeLogFileHeader() throws IOException { try { log_file.write("#\n"); log_file.write("# File generation log file\n"); log_file.write("#\n"); log_file.write("Project: " + pname + "\n"); log_file.write("User: " + uname + "\n"); log_file.write("Generation: " + fgname + "\n"); log_file.write("Format: CRI-MAP\n"); if (mode.equals("S")) { log_file.write("Mode: Single\n"); log_file.write("Marker Set: " + msname + "\n"); } else { log_file.write("Mode: Multi\n"); log_file.write("Unified Marker Set: " + msname + "\n"); } } catch (IOException e) { e.printStackTrace(System.err); throw e; } } //------------------------------------------------------------------------------- private void writeLogFileSU(int su) throws IOException { RelDataRec rel = (RelDataRec) rels.elementAt(su); try { log_file.write("---------------------------------------------\n"); log_file.write("Sampling unit: " + rel.suname + "\n"); log_file.write("Filter: " + rel.fname + "\n"); log_file.write("Expression: " + rel.gql + "\n"); } catch (IOException e) { e.printStackTrace(System.err); throw e; } } //------------------------------------------------------------------------------- private void writeLogFileFooter(int secs) { try { log_file.write("---------------------------------------------\n"); log_file.write("Total generation time:\t" + secs + " seconds.\n"); } catch (IOException e) { e.printStackTrace(System.err); } } //------------------------------------------------------------------------------- public void writeLogFileWarning(String message) { try { log_file.write("WARNING: " + message + "\n"); } catch (IOException e) { e.printStackTrace(System.err); } } //------------------------------------------------------------------------------- public void writeLogFileError(String message) { try { log_file.write("ERROR: " + message + "\n"); } catch (IOException e) { e.printStackTrace(System.err); } } //------------------------------------------------------------------------------- private void writeMapFile() throws IOException { int i = 0; int j = 0; int max = 0; for (i=0; i<mids.size(); i++) if (((MidDataRec) mids.elementAt(i)).alleles.size() > max) max = ((MidDataRec) mids.elementAt(i)).alleles.size(); map_file.write("#\n"); map_file.write("# File generation mapping file\n"); map_file.write("#\n"); map_file.write("\n"); map_file.write("Remapped Individuals :\n"); map_file.write("====================\n"); if (mode.equals("S")) { map_file.write("Identity\tNumber\n"); map_file.write("--------\t------\n"); for (i=0; i<inds.size(); i++) { IndDataRec ind = (IndDataRec) inds.elementAt(i); if(!(ind.identity.equals(ind.n))) { map_file.write(ind.identity + "\t" + ind.n + "\n"); } } } else { map_file.write("Sampling Unit\tIdentity\tNumber\n"); map_file.write("-------------\t--------\t------\n"); for (i=0; i<inds.size(); i++) { IndDataRec ind = (IndDataRec) inds.elementAt(i); RelDataRec rel = (RelDataRec) rels.elementAt(ind.su); if(!(ind.identity.equals(ind.n))) { map_file.write(rel.suname + "\t" + ind.identity + "\t" + ind.n + "\n"); } } } map_file.write("\n"); map_file.write("Synthesized Inividuals: "); if (dummys.size() > 0) { map_file.write(((IndDataRec) dummys.elementAt(0)).n); if (dummys.size() > 1) { map_file.write(".."); map_file.write(((IndDataRec) dummys.elementAt(dummys.size()-1)).n); } map_file.write("\n"); } else { map_file.write("-\n"); } map_file.write("\n"); map_file.write("Allele mappings:\n"); map_file.write("================\n"); map_file.write("Allele:"); for (i=0; i<max; i++) map_file.write("\t" + (i+1)); map_file.write("\n"); map_file.write("------"); for (i=0; i<max; i++) map_file.write("\t---"); map_file.write("\n"); for (i=0; i<mids.size(); i++) { MidDataRec mid = (MidDataRec) mids.elementAt(i); map_file.write(mid.mname); for (j=0; j<mid.alleles.size(); j++) map_file.write("\t" + ((AllelesRec) mid.alleles.elementAt(j)).name); map_file.write("\n"); } } //------------------------------------------------------------------------------- private void prepareSQL() throws SQLException { mstmt = conn.prepareStatement("SELECT P.MID, G.A1NAME, G.A2NAME, G.RAW1, G.RAW2" + " FROM V_POSITIONS_2 P, V_GENOTYPES_3 G" + " WHERE P.MSID=" + msid + " AND P.MID=G.MID" + " AND G.IID=?" + " ORDER BY P.CNAME, P.POSITION, P.MNAME"); umstmt = conn.prepareStatement("SELECT P.UMID, G.AID1, G.AID2, G.A1NAME, G.A2NAME, G.RAW1, G.RAW2" + " FROM V_U_POSITIONS_2 P, V_R_UMID_MID_1 M, V_GENOTYPES_3 G" + " WHERE P.UMSID=" + msid + " AND P.UMID=M.UMID" + " AND M.SUID=?" + " AND M.MID=G.MID" + " AND G.IID=?" + " ORDER BY P.CNAME, P.POSITION, P.UMNAME"); uastmt = conn.prepareStatement("SELECT A.NAME" + " FROM V_R_UAID_AID_1 M, V_U_ALLELES_1 A" + " WHERE M.UMID=?" + " AND M.AID=?" + " AND M.UAID=A.UAID"); astmt = conn.prepareStatement("SELECT ABORT_" + " FROM V_FILE_GENERATIONS_1" + " WHERE FGID = " + fgid); //pstmt = conn.prepareCall("{CALL GDBP.SET_DATA_FILE_STATUS(?,?,?)}"); } //------------------------------------------------------------------------------- public boolean aborted() throws SQLException { ResultSet rset = null; boolean a = false; astmt.clearParameters(); rset = astmt.executeQuery(); rset.next(); a = (rset.getInt("ABORT_") != 0); rset.close(); return a; } //------------------------------------------------------------------------------- private String replaceIfNull(String val) { if (val != null) return val; else return "0"; } }