<commit_before>package com.bina.varsim.util;

//--- Java imports ---

import com.bina.varsim.types.ChrString;
import com.bina.varsim.types.FlexSeq;
import com.bina.varsim.types.Sequence;
import com.bina.varsim.types.VCFInfo;
import com.bina.varsim.types.variant.Variant;
import com.bina.varsim.types.variant.alt.Alt;
import org.apache.log4j.Logger;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.rmi.UnexpectedException;
import java.util.*;
import java.util.regex.Pattern;

import static com.bina.varsim.constants.Constant.MAX_WARNING_REPEAT;
import static com.bina.varsim.types.VCFInfo.getType;

public class VCFparser extends GzFileParser<Variant> {
    public static final String DEFAULT_FILTER = "."; //default value for many columns
    private final static Logger log = Logger.getLogger(VCFparser.class.getName());

    private Random random = null;

    private int sampleIndex = -1;

    public String getSampleId() {
        return sampleId;
    }

    private String sampleId = null;
    private boolean isPassFilterRequired = false;
    private boolean chromLineSeen = false;
    private int illegalPhasingWarningCount = 0;

    public VCFparser() {
        sampleIndex = 10; // the first sample
    }

    /**
     * Reads a VCF file line by line
     *
     * @param fileName VCF file, doesn't have to be sorted or indexed
     * @param id       ID of individual, essentially selects a column, null to use first ID column
     * @param pass     If true, only output pass lines
     */
    public VCFparser(String fileName, String id, boolean pass, Random rand) {
        this(new File(fileName), id, pass, rand);
        log.info("Reading " + fileName);
    }


    public VCFparser(File file, String id, boolean pass, Random rand) {
        random = rand;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(decompressStream(file)));
            readLine();
        } catch (Exception ex) {
            log.error("Can't open file " + file.getName());
            log.error(ex.toString());
        }
        sampleId = id;
        isPassFilterRequired = pass;

        if (sampleId == null) {
            sampleIndex = 10; // the first sample
        }
    }

    /**
     * Reads a VCF file line by line
     *
     * @param fileName VCF file, doesn't have to be sorted or indexed
     * @param id       ID of individual, essentially selects a column, null to use first ID column
     * @param pass     If true, only output pass lines
     */
    public VCFparser(String fileName, String id, boolean pass) {
        this(fileName, id, pass, null);
    }

    public VCFparser(File file, String id, boolean pass) {
        this(file, id, pass, null);
    }

    //TODO: remove unused constructor
    /**
     * Reads a VCF file line by line, if there are multiple individuals, takes the first one
     *
     * @param fileName VCF file, doesn't have to be sorted or indexed
     * @param pass     If true, only output pass lines
     */
    public VCFparser(String fileName, boolean pass, Random rand) {
        this(fileName, null, pass, rand);
    }

    //TODO: remove unused constructor
    /**
     * Reads a VCF file line by line, if there are multiple individuals, takes the first one
     *
     * @param fileName VCF file, doesn't have to be sorted or indexed
     * @param pass     If true, only output pass lines
     */
    public VCFparser(String fileName, boolean pass) {
        this(fileName, null, pass, null);
    }

    public VCFparser(File file, boolean pass) {
        this(file, null, pass, null);
    }

    /**
     * finds where "GT" or similar is in the VCF string so that the genotype can be read
     *
     * @param record The column in VCF that contains GT, CN, etc..
     * @param key    The key to be found "GT" or "CN" or other
     * @return the index of the key
     */
    private int getFormatKeyIndex(final String record, final String key) {
        StringTokenizer words = new StringTokenizer(record, ":");
        int ret = 0;
        while (words.hasMoreTokens()) {
            if (words.nextToken().equals(key))
                return ret;
            else
                ret++;
        }
        return -1;
    }

    /**
     * Takes genotype string and splits it into alleles, supports a maximum of two
     *
     * @param geno genotype string corresponding to the GT tag (field index 9)
     * @param vals Return the genotypes read here [paternal,maternal]
     * @param chr  chromosome we are dealing with, some are haploid, need to assign parent
     * @return true if the variant is phased
     */
    boolean isPhased(String geno, byte[] vals, ChrString chr) {
        boolean isPhased = false;

        geno = geno.trim();
        boolean strangePhase = false;

        if (StringUtilities.isNonNegativeInteger(geno)) {
            // phase is only a single number, for haploid chromosomes
            byte val = (byte) StringUtilities.parseInt(geno);
            if (chr.isX()) {
                vals[1] = val; // maternal
                isPhased = true;
            } else if (chr.isY()) {
                vals[0] = val; // paternal
                isPhased = true;
            } else if (chr.isMT()) {
                vals[1] = val;
                isPhased = true;
            } else {
                vals[0] = vals[1] = val;
            }
        } else if (geno.length() >= 3) {
            // this is the case where phase looks like "1|0" or "10|4"
            String[] ll = StringUtilities.fastSplit(geno, "/|");
            int c1 = -1;
            int c2 = -1;
            char phasing = '/';<commit_msg>add missing genotype for haploid case<commit_after>package com.bina.varsim.util;

//--- Java imports ---

import com.bina.varsim.types.ChrString;
import com.bina.varsim.types.FlexSeq;
import com.bina.varsim.types.Sequence;
import com.bina.varsim.types.VCFInfo;
import com.bina.varsim.types.variant.Variant;
import com.bina.varsim.types.variant.alt.Alt;
import org.apache.log4j.Logger;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.rmi.UnexpectedException;
import java.util.*;
import java.util.regex.Pattern;

import static com.bina.varsim.constants.Constant.MAX_WARNING_REPEAT;
import static com.bina.varsim.types.VCFInfo.getType;

public class VCFparser extends GzFileParser<Variant> {
    public static final String DEFAULT_FILTER = "."; //default value for many columns
    private final static Logger log = Logger.getLogger(VCFparser.class.getName());

    private Random random = null;

    private int sampleIndex = -1;

    public String getSampleId() {
        return sampleId;
    }

    private String sampleId = null;
    private boolean isPassFilterRequired = false;
    private boolean chromLineSeen = false;
    private int illegalPhasingWarningCount = 0;

    public VCFparser() {
        sampleIndex = 10; // the first sample
    }

    /**
     * Reads a VCF file line by line
     *
     * @param fileName VCF file, doesn't have to be sorted or indexed
     * @param id       ID of individual, essentially selects a column, null to use first ID column
     * @param pass     If true, only output pass lines
     */
    public VCFparser(String fileName, String id, boolean pass, Random rand) {
        this(new File(fileName), id, pass, rand);
        log.info("Reading " + fileName);
    }


    public VCFparser(File file, String id, boolean pass, Random rand) {
        random = rand;
        try {
            bufferedReader = new BufferedReader(new InputStreamReader(decompressStream(file)));
            readLine();
        } catch (Exception ex) {
            log.error("Can't open file " + file.getName());
            log.error(ex.toString());
        }
        sampleId = id;
        isPassFilterRequired = pass;

        if (sampleId == null) {
            sampleIndex = 10; // the first sample
        }
    }

    /**
     * Reads a VCF file line by line
     *
     * @param fileName VCF file, doesn't have to be sorted or indexed
     * @param id       ID of individual, essentially selects a column, null to use first ID column
     * @param pass     If true, only output pass lines
     */
    public VCFparser(String fileName, String id, boolean pass) {
        this(fileName, id, pass, null);
    }

    public VCFparser(File file, String id, boolean pass) {
        this(file, id, pass, null);
    }

    //TODO: remove unused constructor
    /**
     * Reads a VCF file line by line, if there are multiple individuals, takes the first one
     *
     * @param fileName VCF file, doesn't have to be sorted or indexed
     * @param pass     If true, only output pass lines
     */
    public VCFparser(String fileName, boolean pass, Random rand) {
        this(fileName, null, pass, rand);
    }

    //TODO: remove unused constructor
    /**
     * Reads a VCF file line by line, if there are multiple individuals, takes the first one
     *
     * @param fileName VCF file, doesn't have to be sorted or indexed
     * @param pass     If true, only output pass lines
     */
    public VCFparser(String fileName, boolean pass) {
        this(fileName, null, pass, null);
    }

    public VCFparser(File file, boolean pass) {
        this(file, null, pass, null);
    }

    /**
     * finds where "GT" or similar is in the VCF string so that the genotype can be read
     *
     * @param record The column in VCF that contains GT, CN, etc..
     * @param key    The key to be found "GT" or "CN" or other
     * @return the index of the key
     */
    private int getFormatKeyIndex(final String record, final String key) {
        StringTokenizer words = new StringTokenizer(record, ":");
        int ret = 0;
        while (words.hasMoreTokens()) {
            if (words.nextToken().equals(key))
                return ret;
            else
                ret++;
        }
        return -1;
    }

    /**
     * Takes genotype string and splits it into alleles, supports a maximum of two
     *
     * @param geno genotype string corresponding to the GT tag (field index 9)
     * @param vals Return the genotypes read here [paternal,maternal]
     * @param chr  chromosome we are dealing with, some are haploid, need to assign parent
     * @return true if the variant is phased
     */
    boolean isPhased(String geno, byte[] vals, ChrString chr) {
        boolean isPhased = false;

        geno = geno.trim();
        boolean strangePhase = false;

        if (StringUtilities.isNonNegativeInteger(geno)) {
            // phase is only a single number, for haploid chromosomes
            byte val = (byte) StringUtilities.parseInt(geno);
            if (chr.isX()) {
                vals[0] = -1; //paternal missing
                vals[1] = val; // maternal
                isPhased = true;
            } else if (chr.isY()) {
                vals[0] = val; // paternal
                vals[1] = -1; //maternal missing
                isPhased = true;
            } else if (chr.isMT()) {
                vals[0] = -1; //paternal missing
                vals[1] = val;
                isPhased = true;
            } else {
                vals[0] = vals[1] = val;
            }
        } else if (geno.length() >= 3) {
            // this is the case where phase looks like "1|0" or "10|4"
            String[] ll = StringUtilities.fastSplit(geno, "/|");
            int c1 = -1;
            int c2 = -1;
            char phasing = '/';
{'fraction_non_alphanumeric': 0.09691438504997828, 'fraction_numerical': 0.004867448935245545, 'mean_word_length': 2.1575192096597147, 'pattern_counts': {'":': 2, '<': 5, '<?xml version=': 0, '>': 7, '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': '3742747', 'n_tokens_mistral': 3375, 'n_tokens_neox': 3250, 'n_words': 1145}