Skip to content

Commit

Permalink
Version information now is incorporated into output *.clns and *.vdjc…
Browse files Browse the repository at this point in the history
…a files. Special action added to retrieve this information (versionInfo).

This fixes #17
  • Loading branch information
dbolotin committed Oct 23, 2015
1 parent c16688c commit 2153440
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
import static com.milaboratory.core.io.util.IOUtil.*;

public final class AssemblerEventLogger {
static final int MAX_BUFFER_SIZE = 10_000;
static final int MAX_BUFFER_SIZE = 30_000;
final AtomicBoolean closed = new AtomicBoolean(false);
final File file;
final OutputStream os;
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/com/milaboratory/mixcr/basictypes/CloneSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
* Created by poslavsky on 10/07/14.
*/
public final class CloneSet implements Iterable<Clone> {
String versionInfo;
final GeneFeature[] assemblingFeatures;
final EnumMap<GeneType, GeneFeature> alignedFeatures;
final List<Allele> usedAlleles;
Expand Down Expand Up @@ -117,6 +118,10 @@ public long getTotalCount() {
return totalCount;
}

public String getVersionInfo() {
return versionInfo;
}

@Override
public Iterator<Clone> iterator() {
return clones.iterator();
Expand Down
52 changes: 33 additions & 19 deletions src/main/java/com/milaboratory/mixcr/basictypes/CloneSetIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,21 @@
import com.milaboratory.mixcr.reference.AlleleResolver;
import com.milaboratory.mixcr.reference.GeneFeature;
import com.milaboratory.mixcr.reference.GeneType;
import com.milaboratory.mixcr.util.VersionInfoProvider;
import com.milaboratory.primitivio.PrimitivI;
import com.milaboratory.primitivio.PrimitivO;
import com.milaboratory.util.CanReportProgressAndStage;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumMap;
import java.util.List;

public final class CloneSetIO {
static final String MAGIC = "MiXCR.CLNS.V02";
static final String MAGIC_V2 = "MiXCR.CLNS.V02";
static final String MAGIC_V3 = "MiXCR.CLNS.V03";
static final String MAGIC = MAGIC_V3;
static final int MAGIC_LENGTH = 14;
static final byte[] MAGIC_BYTES = MAGIC.getBytes(StandardCharsets.US_ASCII);

Expand Down Expand Up @@ -85,7 +87,14 @@ public boolean isFinished() {
}

public void write() {
// Writing magic bytes
output.write(MAGIC_BYTES);

// Writing version information
output.writeUTF(
VersionInfoProvider.getVersionString(
VersionInfoProvider.OutputType.ToFile));

output.writeObject(cloneSet.getAssemblingFeatures());
IO.writeGT2GFMap(output, cloneSet.alignedFeatures);
IOUtil.writeAlleleReferences(output, cloneSet.getUsedAlleles(), new GT2GFAdapter(cloneSet.alignedFeatures));
Expand All @@ -104,31 +113,22 @@ public void close() {
}
}

public static void read(CloneSet cloneSet, File file) throws IOException {
public static void write(CloneSet cloneSet, File file) throws IOException {
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(file), 32768)) {
write(cloneSet, os);
}
}

public static void read(CloneSet cloneSet, String fileName) throws IOException {
public static void write(CloneSet cloneSet, String fileName) throws IOException {
try (OutputStream os = new BufferedOutputStream(new FileOutputStream(fileName), 32768)) {
write(cloneSet, os);
}
}

public static void write(CloneSet cloneSet, OutputStream outputStream) {
PrimitivO output = new PrimitivO(outputStream);

// Writing magic bytes
output.write(MAGIC_BYTES);
output.writeObject(cloneSet.getAssemblingFeatures());
IO.writeGT2GFMap(output, cloneSet.alignedFeatures);
IOUtil.writeAlleleReferences(output, cloneSet.getUsedAlleles(), new GT2GFAdapter(cloneSet.alignedFeatures));

output.writeInt(cloneSet.getClones().size());

for (Clone clone : cloneSet)
output.writeObject(clone);
try(CloneSetWriter writer = new CloneSetWriter(cloneSet, outputStream)){
writer.write();
}
}

public static CloneSet read(String fileName, AlleleResolver alleleResolver) throws IOException {
Expand All @@ -147,8 +147,19 @@ public static CloneSet read(InputStream inputStream, AlleleResolver alleleResolv
byte[] magicBytes = new byte[MAGIC_LENGTH];
input.readFully(magicBytes);

if (!Arrays.equals(magicBytes, MAGIC_BYTES))
throw new RuntimeException("Unsupported file format; .clns file of version " + new String(magicBytes) + " while you are running MiXCR " + MAGIC);
String magicString = new String(magicBytes);

switch (magicString) {
case MAGIC_V2:
case MAGIC:
break;
default:
throw new RuntimeException("Unsupported file format; .clns file of version " + magicString + " while you are running MiXCR " + MAGIC);
}

String versionInfo = null;
if (magicString.compareTo(MAGIC_V3) >= 0)
versionInfo = input.readUTF();

GeneFeature[] assemblingFeatures = input.readObject(GeneFeature[].class);
EnumMap<GeneType, GeneFeature> alignedFeatures = IO.readGF2GTMap(input);
Expand All @@ -158,7 +169,10 @@ public static CloneSet read(InputStream inputStream, AlleleResolver alleleResolv
for (int i = 0; i < count; i++)
clones.add(input.readObject(Clone.class));

return new CloneSet(clones, alleles, alignedFeatures, assemblingFeatures);
CloneSet cloneSet = new CloneSet(clones, alleles, alignedFeatures, assemblingFeatures);
cloneSet.versionInfo = versionInfo;

return cloneSet;
}

private static class GT2GFAdapter implements HasFeatureToAlign {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class VDJCAlignmentsReader implements OutputPortCloseable<VDJCAlignments>
List<Allele> usedAlleles;
final PrimitivI input;
final AlleleResolver alleleResolver;
String versionInfo;
long numberOfReads = -1;
boolean closed = false;
long counter = 0;
Expand Down Expand Up @@ -91,12 +92,16 @@ public void init() {
case MAGIC_V3:
CompatibilityIO.registerV3Serializers(input.getSerializersManager());
break;
case MAGIC_V4:
case MAGIC:
break;
default:
throw new RuntimeException("Unsupported file format; .vdjca file of version " + new String(magic) + " while you are running MiXCR " + MAGIC);
}

if (magicString.compareTo(MAGIC_V5) >= 0)
versionInfo = input.readUTF();

parameters = input.readObject(VDJCAlignerParameters.class);

this.usedAlleles = IOUtil.readAlleleReferences(input, alleleResolver, parameters);
Expand All @@ -112,6 +117,15 @@ public synchronized List<Allele> getUsedAlleles() {
return usedAlleles;
}

/**
* Returns information about version of MiXCR which produced this file.
*
* @return information about version of MiXCR which produced this file
*/
public String getVersionInfo() {
return versionInfo;
}

public long getNumberOfReads() {
return numberOfReads;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
package com.milaboratory.mixcr.basictypes;

import com.milaboratory.mixcr.reference.Allele;
import com.milaboratory.mixcr.util.VersionInfoProvider;
import com.milaboratory.mixcr.vdjaligners.VDJCAligner;
import com.milaboratory.mixcr.vdjaligners.VDJCAlignerParameters;
import com.milaboratory.primitivio.PrimitivO;
Expand All @@ -41,7 +42,9 @@

public final class VDJCAlignmentsWriter implements AutoCloseable {
static final String MAGIC_V3 = "MiXCR.VDJC.V03";
static final String MAGIC = "MiXCR.VDJC.V04";
static final String MAGIC_V4 = "MiXCR.VDJC.V04";
static final String MAGIC_V5 = "MiXCR.VDJC.V05";
static final String MAGIC = MAGIC_V5;
static final int MAGIC_LENGTH = 14;
static final byte[] MAGIC_BYTES = MAGIC.getBytes(StandardCharsets.US_ASCII);
final PrimitivO output;
Expand Down Expand Up @@ -79,6 +82,11 @@ public void header(VDJCAlignerParameters parameters, List<Allele> alleles) {
assert MAGIC_BYTES.length == MAGIC_LENGTH;
output.write(MAGIC_BYTES);

// Writing version information
output.writeUTF(
VersionInfoProvider.getVersionString(
VersionInfoProvider.OutputType.ToFile));

// Writing parameters
output.writeObject(parameters);

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/milaboratory/mixcr/cli/ActionInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,14 @@ public static FilesType getType(String fileName) {
throw new ParameterException("Unknown file type: " + fileName);
}
}

public interface AlignmentInfoProvider {
String header();

String result();

void onInit(VDJCAlignmentsReader reader);

void onScan(VDJCAlignments alignment);
}
}
19 changes: 6 additions & 13 deletions src/main/java/com/milaboratory/mixcr/cli/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
package com.milaboratory.mixcr.cli;

import com.milaboratory.mitools.cli.JCommanderBasedMain;
import com.milaboratory.util.VersionInfo;
import com.milaboratory.mixcr.util.VersionInfoProvider;

public class Main {
public static void main(String... args) throws Exception {
Expand All @@ -45,23 +45,16 @@ public static void main(String... args) throws Exception {
new ActionPrettyAlignments(),
new ActionAlignmentsStat(),
new ActionMergeAlignments(),
new ActionInfo());
new ActionInfo(),
new VersionInfoAction());

// Adding version info callback
main.setVersionInfoCallback(new Runnable() {
@Override
public void run() {
VersionInfo milib = VersionInfo.getVersionInfoForArtifact("milib");
VersionInfo mitools = VersionInfo.getVersionInfoForArtifact("mitools");
VersionInfo mixcr = VersionInfo.getVersionInfoForArtifact("mixcr");
System.err.println("MiXCR v" + mixcr.getVersion() +
" (built " + mixcr.getTimestamp() + "; rev=" + mixcr.getRevision() +
"; branch=" + mixcr.getBranch() + ")");
System.err.println("Libraries: ");
System.err.println("MiLib v" + milib.getVersion() + " (rev=" + milib.getRevision() +
"; branch=" + milib.getBranch() + ")");
System.err.println("MiTools v" + mitools.getVersion() + " (rev=" + mitools.getRevision() +
"; branch=" + mitools.getBranch() + ")");
System.err.println(
VersionInfoProvider.getVersionString(
VersionInfoProvider.OutputType.ToConsole));
}
});

Expand Down
89 changes: 89 additions & 0 deletions src/main/java/com/milaboratory/mixcr/cli/VersionInfoAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (c) 2014-2015, Bolotin Dmitry, Chudakov Dmitry, Shugay Mikhail
* (here and after addressed as Inventors)
* All Rights Reserved
*
* Permission to use, copy, modify and distribute any part of this program for
* educational, research and non-profit purposes, by non-profit institutions
* only, without fee, and without a written agreement is hereby granted,
* provided that the above copyright notice, this paragraph and the following
* three paragraphs appear in all copies.
*
* Those desiring to incorporate this work into commercial products or use for
* commercial purposes should contact the Inventors using one of the following
* email addresses: chudakovdm@mail.ru, chudakovdm@gmail.com
*
* IN NO EVENT SHALL THE INVENTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
* ARISING OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE INVENTORS HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE SOFTWARE PROVIDED HEREIN IS ON AN "AS IS" BASIS, AND THE INVENTORS HAS
* NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
* MODIFICATIONS. THE INVENTORS MAKES NO REPRESENTATIONS AND EXTENDS NO
* WARRANTIES OF ANY KIND, EITHER IMPLIED OR EXPRESS, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
* PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY
* PATENT, TRADEMARK OR OTHER RIGHTS.
*/
package com.milaboratory.mixcr.cli;

import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameters;
import com.milaboratory.mitools.cli.Action;
import com.milaboratory.mitools.cli.ActionHelper;
import com.milaboratory.mitools.cli.ActionParameters;
import com.milaboratory.mixcr.basictypes.CloneSet;
import com.milaboratory.mixcr.basictypes.CloneSetIO;
import com.milaboratory.mixcr.basictypes.VDJCAlignmentsReader;
import com.milaboratory.mixcr.reference.LociLibraryManager;

import java.util.List;

public class VersionInfoAction implements Action {
final AParameters parameters = new AParameters();

@Override
public void go(ActionHelper helper) throws Exception {
String inputFile = parameters.getInputFile();
String i = inputFile.toLowerCase();
if (i.endsWith(".vdjca.gz") || i.endsWith(".vdjca")) {
try (VDJCAlignmentsReader reader = new VDJCAlignmentsReader(inputFile, LociLibraryManager.getDefault())) {
reader.init();
System.out.println(reader.getVersionInfo());
}
} else if (i.endsWith(".clns.gz") || i.endsWith(".clns")) {
CloneSet cs = CloneSetIO.read(inputFile, LociLibraryManager.getDefault());
System.out.println(cs.getVersionInfo());
} else
throw new ParameterException("Wrong file type.");
}

@Override
public String command() {
return "versionInfo";
}

@Override
public ActionParameters params() {
return parameters;
}

@Parameters(commandDescription = "Outputs information about MiXCR version which generated the file.",
optionPrefixes = "-")
private static class AParameters extends ActionParameters {
@Parameter(description = "binary_file{.vdjca|.clns}[.gz]")
public List<String> input;

public String getInputFile() {
return input.get(0);
}

@Override
public void validate() {
if (input.size() != 1)
throw new ParameterException("Wrong number of parameters.");
}
}
}

0 comments on commit 2153440

Please sign in to comment.