Here is a program for converting Impute2 files into MaCH format (related to genetics).
Source files include one xxx_haps file and one xxx_samples file, for example:
// chromosome21.gen_haps
--- rs62224609 16051249 T C 0 0 0 0 0 0
--- rs62224610 16051347 G C 0 1 0 1 1 0
--- rs143503259 16051453 A C 0 0 0 0 0 0
--- rs192339082 16051477 C A 1 0 0 0 0 0
--- rs191139082 16052477 ACCTT A 1 0 0 0 0 0
--- rs191139082 16052478 G GCCGG 0 1 0 0 0 0
// chromosome21.gen_samples
ID_1 ID_2 missing father mother sex plink_pheno
0 0 0 D D D B
RS3 10051 0 0 0 2 -9
RS3 10052 0 0 0 2 -9
RS3 10068 0 0 0 2 -9
Output should be two MaCH files, one xxx.mach.out and one xxx.data.dat, for example, the above input files should be converted to:
// chromosome21.mach.out
RS3->10051 HAPL01 TGAADR
RS3->10051 HAPL02 TCACRI
RS3->10052 HAPL01 TGACRR
RS3->10052 HAPL02 TCACRR
RS3->10068 HAPL01 TCACRR
RS3->10068 HAPL02 TGACRR
// chromosome21.data.dat
M rs62224609
M rs62224610
M rs143503259
M rs192339082
M rs191139082
M rs191139082
Java code:
import com.beust.jcommander.JCommander;
import com.google.common.base.Joiner;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) throws Exception {
ArgParser argParser = new ArgParser();
new JCommander(argParser, args);
if (argParser.debug) {
System.out.printf("Debugging mode on\n%-22s%s\n%-22s%s\n",
"File to convert:",
argParser.file,
"Output folder:",
argParser.outDirString);
}
Pattern pattern = Pattern.compile("_haps\\.gz$");
String fileStem = pattern.matcher(argParser.file).replaceAll("");
System.out.println("File stem: " + fileStem);
System.out.println("File : " + argParser.file);
File outDir;
File machOutFile = new File(fileStem + ".mach.out");
File snpsOutFile = new File(fileStem + ".data.dat");
if(!argParser.outDirString.isEmpty()) {
outDir = new File(argParser.outDirString);
if(!outDir.exists()) {
outDir.mkdir();
}
machOutFile = new File(outDir.toString(), machOutFile.getName().toString());
snpsOutFile = new File(outDir.toString(), snpsOutFile.getName().toString());
}
// Read the _samples file
File sampleFile = new File(fileStem + "_samples");
BufferedReader sampleBuffer = new BufferedReader(new FileReader(sampleFile));
String sampleLine;
ArrayList<String> fidiidList = new ArrayList<String>();
sampleBuffer.readLine();
sampleBuffer.readLine();
while ((sampleLine = sampleBuffer.readLine()) != null) {
String[] cols = sampleLine.split(" +", 3);
String combinedLine = cols[0] + "->" + cols[1];
fidiidList.add(combinedLine);
fidiidList.add(combinedLine);
}
sampleBuffer.close();
String[] fidiid = fidiidList.toArray(new String[fidiidList.size()]);
// get the HAPL01 / HAPL02 rows
String[] hapl = new String[fidiid.length];
for(int i=0; i<hapl.length; i++) {
if(i % 2 == 0) {
hapl[i] = "HAPL01";
} else {
hapl[i] = "HAPL02";
}
}
ArrayList<String[]> outputLines = new ArrayList<String[]>();
outputLines.add(fidiid);
outputLines.add(hapl);
// read the _haps file
File hapsFile = new File(fileStem + "_haps");
BufferedReader hapsBuffer = new BufferedReader(new FileReader(hapsFile));
ArrayList<String> snps = new ArrayList<String>();
String hapsLine;
String tmpGen;
while((hapsLine = hapsBuffer.readLine()) != null) {
String[] cols = hapsLine.split(" +");
String snp = "M\t" + cols[1];
snps.add(snp);
String refGen = cols[3];
String mutGen = cols[4];
String[] genCols = Arrays.copyOfRange(cols, 5, cols.length);
String[] genColsTrans = new String[genCols.length];
if(refGen.length() == 1 && mutGen.length() == 1) {
for(int i=0; i<genCols.length; i++) {
genColsTrans[i] = (genCols[i].equals("0")) ? refGen : mutGen;
}
} else if(refGen.length() > 1 && mutGen.length() == 1) {
for(int i=0; i<genCols.length; i++) {
genColsTrans[i] = (genCols[i].equals("0")) ? "R" : "D";
}
} else if(refGen.length() == 1 && mutGen.length() > 1) {
for(int i=0; i<genCols.length; i++) {
genColsTrans[i] = (genCols[i].equals("0")) ? "R" : "I";
}
} else {
throw new Exception("Impute2 file mal-formatted.");
}
outputLines.add(genColsTrans);
}
// Transpose the output matrix
int nSnp = outputLines.size();
int nObserve = fidiid.length;
String[][] outputTranspose = new String[nObserve][nSnp];
for(int i=0; i<nSnp; i++) {
for(int j=0; j<nObserve; j++) {
outputTranspose[j][i] = outputLines.get(i)[j];
}
}
// get rows of strings
String[] outputStrings = new String[nObserve];
for(int i=0; i<nObserve; i++) {
String[] idAndHapl = Arrays.copyOfRange(outputTranspose[i], 0, 2);
String idAndHaplString = Joiner.on(" ").join(idAndHapl);
String[] genotypes = Arrays.copyOfRange(outputTranspose[i], 2, outputTranspose[i].length);
String genotypesString = Joiner.on("").join(genotypes);
outputStrings[i] = idAndHaplString + " " + genotypesString;
}
String machOutString = Joiner.on("\n").join(outputStrings);
BufferedWriter machOutBuffer = null;
try {
machOutBuffer = new BufferedWriter(new FileWriter(machOutFile));
machOutBuffer.write(machOutString);
} catch (Exception e) {
e.printStackTrace();
} finally {
machOutBuffer.close();
}
String snpsString = Joiner.on("\n").join(snps);
BufferedWriter snpsOutBuffer = null;
try {
snpsOutBuffer = new BufferedWriter(new FileWriter(snpsOutFile));
snpsOutBuffer.write(snpsString);
} catch (Exception e) {
e.printStackTrace();
} finally {
snpsOutBuffer.close();
}
}
}
// parsing commandline args in java, (options, similar to argparse for python)
import com.beust.jcommander.Parameter;
import com.beust.jcommander.internal.Lists;
import java.util.List;
public class ArgParser {
@Parameter
public List<String> parameters = Lists.newArrayList();
@Parameter(names = "-file", description = "_haps.gz file to convert")
public String file;
@Parameter(names="-outDir", description = "Output folder")
public String outDirString;
@Parameter(names="-debug", description = "Debug mode")
public boolean debug = false;
}