<commit_before>/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.maizegenetics.dna.map;

import cern.colt.GenericSorting;
import cern.colt.Swapper;
import cern.colt.function.IntComparator;
import net.maizegenetics.dna.tag.AbstractTags;
import net.maizegenetics.dna.BaseEncoder;
import net.maizegenetics.dna.snp.GenotypeTableUtils;
import net.maizegenetics.dna.snp.NucleotideAlignmentConstants;
import net.maizegenetics.dna.map.Chromosome;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * Abstract TagsOnPhysicalMap object.  Abstract alignment is implemented by two types of TOPM classes
 * {@link TagsOnPhysicalMap} and {@link TagsOnPhysMapHDF5}.   TagsOnPhysicalMap is fully loaded into memory when
 * read, and it can only support one mapping position (the files are either binary or text).  TagsOnPhysMapHDF5
 * can support a large number of mapping position, and only a portion of the data is loaded into memory.
 *
 * In most cases, TagsOnPhysMapHDF5 should be preferred going forward.
 *
 * @author edbuckler
 */
public abstract class AbstractTagsOnPhysicalMap extends AbstractTags implements TOPMInterface {
    protected int[] bestChr; // 4 bytes
    // 4 bytes
    //if these disagree with the location, then set the p to negative
    // 1+4+1+4+4+1+8+8+1+1 = 33 bytes per position + 16 bytes for a two long tag + 1 byte for tagLength in bases = 50 bytes
    // ~50 bytes per position.  If we have 10 million tags then this will be at 500M byte data structure.
    protected int[] indicesOfSortByPosition;
    protected int myMaxVariants = 8;
    protected byte[] multimaps; // number of locations this tagSet maps to; unknown = Byte.MIN_VALUE; multiple, but unknown number = 99
    // number of locations this tagSet maps to; unknown = Byte.MIN_VALUE; multiple, but unknown number = 99
    protected int[] bestStartPos; // chromosomal position of the barcoded end of the tag  // 4 bytes
    // chromosomal position of the barcoded end of the tag  // 4 bytes
    protected byte[] bestStrand; // 1 = same sense as reference FASTA file.  -1 = opposite sense.  unknown = Byte.MIN_VALUE  // 1 byte
    // 1 = same sense as reference FASTA file.  -1 = opposite sense.  unknown = Byte.MIN_VALUE  // 1 byte
    protected int myNumTags = 0;
    //TODO
//    public int tagNum;  //remove this and set to above
//    public int maxVariants;
    
    protected byte[][] variantDefs; // allele state - A, C, G, T or some indel definition  // myMaxVariants bytes [tag][variant]
    // allele state - A, C, G, T or some indel definition  // myMaxVariants bytes [tag][variant]
    protected byte[][] variantOffsets; // offset from position minimum, maximum number of variants is defined above  // myMaxVariants bytes [tag][variant]
    // offset from position minimum, maximum number of variants is defined above  // myMaxVariants bytes [tag][variant]
    protected int[] myChromosomes = null; //sort ascending
    protected int[][] myUniquePositions = null; //dimensions [chromosome][positions] note ragged, and sort ascending

    public AbstractTagsOnPhysicalMap() {
    }

    
    @Override
    public int getMaxNumVariants() {
        return myMaxVariants;
    }
    
    @Override
    public byte getMultiMaps(int index) {
        return multimaps[index];
    }
    
    @Override
    public int getChromosome(int index) {
        return bestChr[index];
    }

    @Override
    public int getSize() {
        return myNumTags;
    }

    @Override
    public int getStartPosition(int index) {
        return bestStartPos[index];
    }

    @Override
    public byte getStrand(int tagIndex) {
        return bestStrand[tagIndex];
    }

    public byte[][] getVariantDef() {
        byte[][] result = new byte[getTagCount()][myMaxVariants];
        for (int i = 0; i < getTagCount(); i++) {
            for (int j = 0; j < myMaxVariants; j++) {
                result[i][j] = getVariantDef(i, j);
            }
        }
        return result;
    }
    
    /**
     * Provides the reference
     * @return 
     */
    protected byte[][] getVariantDefByReference() {
        return variantDefs;
    }
    
    protected byte[][] getVariantOffByReference() {
        return variantOffsets;
    }
    

    @Override
    public byte getVariantDef(int tagIndex, int variantIndex) {
        if((variantDefs[tagIndex]==null)||(variantDefs[tagIndex].length<=variantIndex)) return TOPMInterface.BYTE_MISSING;
        return variantDefs[tagIndex][variantIndex];
    }

    /**
     * Returns an array containing all variant definitions for the tag at the
     * supplied index.
     */
    @Override
    public byte[] getVariantDefArray(int tagIndex) {
        return variantDefs[tagIndex];
//        if(variantDefs[tagIndex]==null) return null;
//        byte[] result = new byte[variantDefs[tagIndex].length];
//        for (int i = 0; i < variantDefs[tagIndex].length; i++) {
//            result[i] = getVariantDef(tagIndex, i);
//        }
//        return result;
    }

    @Override
    public byte[][] getVariantOff() {
        byte[][] result = new byte[getTagCount()][];
        for (int i = 0; i < getTagCount(); i++) {
            for (int j = 0; j < myMaxVariants; j++) {
                result[i][j] = getVariantPosOff(i, j);
            }
        }
        return result;
    }

    @Override
    public byte getVariantPosOff(int tagIndex, int variantIndex) {
        if((variantOffsets[tagIndex]==null)||(variantOffsets[tagIndex].length<=variantIndex)) return TOPMInterface.BYTE_MISSING;
        return variantOffsets[tagIndex][variantIndex];
    }

    /**
     * Returns an array containing all variant position offsets for the tag at<commit_msg>Fixed getVariantOff() so that it works with ragged arrays (additional change)<commit_after>/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.maizegenetics.dna.map;

import cern.colt.GenericSorting;
import cern.colt.Swapper;
import cern.colt.function.IntComparator;
import net.maizegenetics.dna.tag.AbstractTags;
import net.maizegenetics.dna.BaseEncoder;
import net.maizegenetics.dna.snp.GenotypeTableUtils;
import net.maizegenetics.dna.snp.NucleotideAlignmentConstants;
import net.maizegenetics.dna.map.Chromosome;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * Abstract TagsOnPhysicalMap object.  Abstract alignment is implemented by two types of TOPM classes
 * {@link TagsOnPhysicalMap} and {@link TagsOnPhysMapHDF5}.   TagsOnPhysicalMap is fully loaded into memory when
 * read, and it can only support one mapping position (the files are either binary or text).  TagsOnPhysMapHDF5
 * can support a large number of mapping position, and only a portion of the data is loaded into memory.
 *
 * In most cases, TagsOnPhysMapHDF5 should be preferred going forward.
 *
 * @author edbuckler
 */
public abstract class AbstractTagsOnPhysicalMap extends AbstractTags implements TOPMInterface {
    protected int[] bestChr; // 4 bytes
    // 4 bytes
    //if these disagree with the location, then set the p to negative
    // 1+4+1+4+4+1+8+8+1+1 = 33 bytes per position + 16 bytes for a two long tag + 1 byte for tagLength in bases = 50 bytes
    // ~50 bytes per position.  If we have 10 million tags then this will be at 500M byte data structure.
    protected int[] indicesOfSortByPosition;
    protected int myMaxVariants = 8;
    protected byte[] multimaps; // number of locations this tagSet maps to; unknown = Byte.MIN_VALUE; multiple, but unknown number = 99
    // number of locations this tagSet maps to; unknown = Byte.MIN_VALUE; multiple, but unknown number = 99
    protected int[] bestStartPos; // chromosomal position of the barcoded end of the tag  // 4 bytes
    // chromosomal position of the barcoded end of the tag  // 4 bytes
    protected byte[] bestStrand; // 1 = same sense as reference FASTA file.  -1 = opposite sense.  unknown = Byte.MIN_VALUE  // 1 byte
    // 1 = same sense as reference FASTA file.  -1 = opposite sense.  unknown = Byte.MIN_VALUE  // 1 byte
    protected int myNumTags = 0;
    //TODO
//    public int tagNum;  //remove this and set to above
//    public int maxVariants;
    
    protected byte[][] variantDefs; // allele state - A, C, G, T or some indel definition  // myMaxVariants bytes [tag][variant]
    // allele state - A, C, G, T or some indel definition  // myMaxVariants bytes [tag][variant]
    protected byte[][] variantOffsets; // offset from position minimum, maximum number of variants is defined above  // myMaxVariants bytes [tag][variant]
    // offset from position minimum, maximum number of variants is defined above  // myMaxVariants bytes [tag][variant]
    protected int[] myChromosomes = null; //sort ascending
    protected int[][] myUniquePositions = null; //dimensions [chromosome][positions] note ragged, and sort ascending

    public AbstractTagsOnPhysicalMap() {
    }

    
    @Override
    public int getMaxNumVariants() {
        return myMaxVariants;
    }
    
    @Override
    public byte getMultiMaps(int index) {
        return multimaps[index];
    }
    
    @Override
    public int getChromosome(int index) {
        return bestChr[index];
    }

    @Override
    public int getSize() {
        return myNumTags;
    }

    @Override
    public int getStartPosition(int index) {
        return bestStartPos[index];
    }

    @Override
    public byte getStrand(int tagIndex) {
        return bestStrand[tagIndex];
    }

    public byte[][] getVariantDef() {
        byte[][] result = new byte[getTagCount()][myMaxVariants];
        for (int i = 0; i < getTagCount(); i++) {
            for (int j = 0; j < myMaxVariants; j++) {
                result[i][j] = getVariantDef(i, j);
            }
        }
        return result;
    }
    
    /**
     * Provides the reference
     * @return 
     */
    protected byte[][] getVariantDefByReference() {
        return variantDefs;
    }
    
    protected byte[][] getVariantOffByReference() {
        return variantOffsets;
    }
    

    @Override
    public byte getVariantDef(int tagIndex, int variantIndex) {
        if((variantDefs[tagIndex]==null)||(variantDefs[tagIndex].length<=variantIndex)) return TOPMInterface.BYTE_MISSING;
        return variantDefs[tagIndex][variantIndex];
    }

    /**
     * Returns an array containing all variant definitions for the tag at the
     * supplied index.
     */
    @Override
    public byte[] getVariantDefArray(int tagIndex) {
        return variantDefs[tagIndex];
//        if(variantDefs[tagIndex]==null) return null;
//        byte[] result = new byte[variantDefs[tagIndex].length];
//        for (int i = 0; i < variantDefs[tagIndex].length; i++) {
//            result[i] = getVariantDef(tagIndex, i);
//        }
//        return result;
    }

    @Override
    public byte[][] getVariantOff() {
        byte[][] result = new byte[getTagCount()][myMaxVariants];
        for (int i = 0; i < getTagCount(); i++) {
            for (int j = 0; j < myMaxVariants; j++) {
                result[i][j] = getVariantPosOff(i, j);
            }
        }
        return result;
    }

    @Override
    public byte getVariantPosOff(int tagIndex, int variantIndex) {
        if((variantOffsets[tagIndex]==null)||(variantOffsets[tagIndex].length<=variantIndex)) return TOPMInterface.BYTE_MISSING;
        return variantOffsets[tagIndex][variantIndex];
    }

    /**
     * Returns an array containing all variant position offsets for the tag at
{'fraction_non_alphanumeric': 0.09924888176217403, 'fraction_numerical': 0.008101949531606043, 'mean_word_length': 2.938185443668993, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2141076', 'n_tokens_mistral': 3566, 'n_tokens_neox': 3382, 'n_words': 1125}