All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pharmgkb.parser.vcf.model.AltStructuralVariant Maven / Gradle / Ivy

The newest version!
package org.pharmgkb.parser.vcf.model;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.pharmgkb.parser.vcf.VcfFormatException;


/**
 * A strictly validated VCF metadata ALT code of the form:
 * {@code
 *   ##ALT=
 * }
 * Where {@code ID} is a colon-delimited list of identifiers. Some of these identifiers are reserved, as coded in the
 * {@link ReservedStructuralVariantCode} class. The first identifier (at level 0) is required to be reserved.
 * As explicitly stated in the spec, these codes are case-sensitive.
 * 

* Example: *

{@code
 *   AltStructuralVariant alt = new AltStructuralVariant("INS:ME:LINE");
 *   alt.getReservedComponent(0); // ReservedStructuralVariantCode.Insertion
 *   alt.getReservedComponent(1); // ReservedStructuralVariantCode.MobileElement
 *   alt.getReservedComponent(2); // null, because it's not a reserved code
 *   alt.getComponent(); // "LINE"
 * }
 * 
* * @author Douglas Myers-Turnbull */ public class AltStructuralVariant { private static final Pattern sf_colon = Pattern.compile(":"); private final List m_components; /** * @param string The full code (e.g. INS:ME:LINE:type-a1) */ public AltStructuralVariant(@Nonnull String string) { if (string.isEmpty()) { // could be replaced with javax.validation.constraints.Size(min=1); throw new VcfFormatException("Structural variant code must not be empty"); } String[] components = sf_colon.split(string); m_components = new ArrayList<>(components.length); for (int level = 0; level < components.length; level++) { ReservedStructuralVariantCode type = ReservedStructuralVariantCode.fromId(components[level]); // Make sure the top-level code exists if (type == null && level == 0) { throw new VcfFormatException("Top-level structural variant code was " + components[level] + " but must be a top-level reserved code (e.g. DEL or CNV)"); } // If this is a reserved code, make sure the level matches if (type != null && level != type.getLevelInSpecification()) { throw new VcfFormatException("Structural variant code " + components[level] + " is a reserved code of level " + type.getLevelInSpecification() + ", not " + level); } // If this is a reserved code, make sure its parent is correct if (type != null && level > 0) { ReservedStructuralVariantCode realParent = ReservedStructuralVariantCode.fromId(m_components.get(level - 1)); if (realParent != null) { boolean foundMatch = false; for (ReservedStructuralVariantCode parent : type.getParentCodes()) { if (realParent == parent) { foundMatch = true; break; } } if (!foundMatch) { throw new VcfFormatException("Structural variant code " + components[level] + " was not a child of reserved code " + realParent.getId()); } } } // We're good! m_components.add(components[level]); } } /** * @return The list of codes in order from level 0 to level n; for example ("INS", "ME", "LINE") */ @Nonnull public List getComponents() { return m_components; } /** * @return The code at the specified level (e.g. CNV) * @throws ArrayIndexOutOfBoundsException */ @Nonnull public String getComponent(int level) { return m_components.get(level); } /** * @return The code at the specified level (e.g. CNV), or null if it is not a reserved code * @throws ArrayIndexOutOfBoundsException */ @Nullable public ReservedStructuralVariantCode getReservedComponent(int level) { return ReservedStructuralVariantCode.fromId(m_components.get(level)); } /** * @return The original string (e.g. INS:ME:LINE:type-a1) */ @Override @Nonnull public String toString() { StringBuilder sb = new StringBuilder(m_components.get(0)); for (int i = 1; i < m_components.size(); i++) { sb.append(":").append(m_components.get(i)); } return sb.toString(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy