/* * Copyright 2015-2016 OpenCB * * 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. */ package org.opencb.opencga.storage.core.alignment.json; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.ObjectMapper; import org.opencb.biodata.models.alignment.AlignmentRegion; import org.opencb.biodata.models.alignment.stats.MeanCoverage; import org.opencb.biodata.models.alignment.stats.RegionCoverage; import org.opencb.biodata.models.core.Region; import org.opencb.commons.io.DataReader; import org.slf4j.LoggerFactory; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.file.Paths; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.zip.GZIPInputStream; /** * Date 26/08/14. * * @author Jacobo Coll Moragon <jcoll@ebi.ac.uk> * <p> * This class reads CoverageFiles generated by AlignmentCoverajeJsonDataWriter * building empty AlignmentRegion with RegionCoverage and MeanCoverage. * <p> * CoverageFileName : <name>.coverage.json.gz * MeanCoverageFileName : <name>.mean-coverage.json.gz */ public class AlignmentCoverageJsonDataReader implements DataReader<AlignmentRegion> { public static final int REGION_SIZE = 100000; private final String coverageFilename; private final String meanCoverageFilename; private InputStream coverageStream; private InputStream meanCoverageStream; private final JsonFactory factory; private final ObjectMapper jsonObjectMapper; private JsonParser coverageParser; private JsonParser meanCoverageParser; private MeanCoverage meanCoverage; private boolean readRegionCoverage = true; private boolean readMeanCoverage = true; protected static org.slf4j.Logger logger = LoggerFactory.getLogger(AlignmentCoverageJsonDataReader.class); public AlignmentCoverageJsonDataReader(String coverageFilename, String meanCoverageFilename) { this.coverageFilename = coverageFilename; this.meanCoverageFilename = meanCoverageFilename; this.factory = new JsonFactory(); this.jsonObjectMapper = new ObjectMapper(this.factory); } @Override public boolean open() { try { if (Paths.get(coverageFilename).toFile().exists()) { readRegionCoverage = true; coverageStream = new FileInputStream(coverageFilename); if (coverageFilename.endsWith(".gz")) { coverageStream = new GZIPInputStream(coverageStream); } } else { readRegionCoverage = false; } if (Paths.get(meanCoverageFilename).toFile().exists()) { readMeanCoverage = true; meanCoverageStream = new FileInputStream(meanCoverageFilename); if (meanCoverageFilename.endsWith(".gz")) { meanCoverageStream = new GZIPInputStream(meanCoverageStream); } } else { readMeanCoverage = false; } } catch (IOException e) { e.printStackTrace(); logger.error(e.toString(), e); return false; } return true; } @Override public boolean close() { try { if (coverageStream != null) { coverageStream.close(); } if (meanCoverageStream != null) { meanCoverageStream.close(); } } catch (IOException e) { e.printStackTrace(); logger.error(e.toString(), e); return false; } return true; } @Override public boolean pre() { try { coverageParser = factory.createParser(coverageStream); meanCoverageParser = factory.createParser(meanCoverageStream); } catch (IOException e) { e.printStackTrace(); logger.error(e.toString(), e); return false; } return true; } @Override public boolean post() { return true; } private MeanCoverage readMeanCoverage() { MeanCoverage meanCoverage = null; try { meanCoverage = meanCoverageParser.readValueAs(MeanCoverage.class); } catch (IOException e) { // logger.error(e.toString(), e); } return meanCoverage; } public AlignmentRegion readElem() { RegionCoverage regionCoverage = null; List<MeanCoverage> meanCoverageList = null; String chromosome = null; long start = 0; long end = 0; if (!readMeanCoverage && !readRegionCoverage) { return null; } if (readRegionCoverage) { try { regionCoverage = coverageParser.readValueAs(RegionCoverage.class); } catch (IOException e) { // logger.error(e.toString(), e); //e.printStackTrace(); return null; } chromosome = regionCoverage.getChromosome(); start = regionCoverage.getStart(); end = regionCoverage.getEnd(); } if (readMeanCoverage) { if (meanCoverage == null) { meanCoverage = readMeanCoverage(); if (meanCoverage == null) { return null; } } if (chromosome == null) { chromosome = meanCoverage.getRegion().getChromosome(); start = meanCoverage.getRegion().getStart(); end = meanCoverage.getRegion().getStart() + REGION_SIZE; } meanCoverageList = new LinkedList<>(); while (meanCoverage != null) { Region region = meanCoverage.getRegion(); if (!(region.getChromosome().equals(chromosome) && region.getStart() < end)) { break; } meanCoverageList.add(meanCoverage); meanCoverage = readMeanCoverage(); } } logger.info("Read : " + chromosome + ":" + start + "-" + end + ", length = " + (end - start)); AlignmentRegion alignmentRegion = new AlignmentRegion(chromosome, start, end); alignmentRegion.setCoverage(regionCoverage); alignmentRegion.setMeanCoverage(meanCoverageList); return alignmentRegion; } @Override public List<AlignmentRegion> read() { return Arrays.asList(readElem()); } @Override public List<AlignmentRegion> read(int batchSize) { List<AlignmentRegion> alignmentRegions = new LinkedList<>(); for (int i = 0; i < batchSize; i++) { AlignmentRegion alignmentRegion = readElem(); if (alignmentRegion == null) { return alignmentRegions; } alignmentRegions.add(alignmentRegion); } if (alignmentRegions.isEmpty()) { return null; } return alignmentRegions; } public boolean isReadRegionCoverage() { return readRegionCoverage; } public void setReadRegionCoverage(boolean readRegionCoverage) { this.readRegionCoverage = readRegionCoverage; } public boolean isReadMeanCoverage() { return readMeanCoverage; } public void setReadMeanCoverage(boolean readMeanCoverage) { this.readMeanCoverage = readMeanCoverage; } }