Merge branch 'feature/JAL-3469clinvarVCF' into spike/clinvar
[jalview.git] / src / jalview / io / vcf / VCFLoader.java
index cbdd66c..1abe638 100644 (file)
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
 package jalview.io.vcf;
 
 import jalview.analysis.Dna;
@@ -28,6 +48,7 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
@@ -236,9 +257,9 @@ public class VCFLoader
   private Set<String> badData;
 
   /**
-   * Constructor given a VCF file
+   * Constructor given a path to a VCF file
    * 
-   * @param alignment
+   * @param vcfFile
    */
   public VCFLoader(String vcfFile)
   {
@@ -549,7 +570,7 @@ public class VCFLoader
   {
     for (Pattern p : filters)
     {
-      if (p.matcher(id.toUpperCase()).matches())
+      if (p.matcher(id.toUpperCase(Locale.ROOT)).matches())
       {
         return true;
       }
@@ -643,7 +664,7 @@ public class VCFLoader
     {
       try
       {
-      patterns.add(Pattern.compile(token.toUpperCase()));
+      patterns.add(Pattern.compile(token.toUpperCase(Locale.ROOT)));
       } catch (PatternSyntaxException e)
       {
         System.err.println("Invalid pattern ignored: " + token);
@@ -892,7 +913,7 @@ public class VCFLoader
          * RuntimeException throwable by htsjdk
          */
         String msg = String.format("Error reading VCF for %s:%d-%d: %s ",
-                map.chromosome, vcfStart, vcfEnd);
+                map.chromosome, vcfStart, vcfEnd,e.getLocalizedMessage());
         Cache.log.error(msg);
       }
     }
@@ -901,7 +922,11 @@ public class VCFLoader
   }
 
   /**
-   * A convenience method to get an attribute value for an alternate allele
+   * A convenience method to get an attribute value for an alternate allele.
+   * {@code alleleIndex} is the position in the list of values for the allele.
+   * If {@alleleIndex == -1} then all values are concatenated (comma-separated).
+   * This is the case for fields declared with "Number=." i.e. values are not
+   * related to specific alleles.
    * 
    * @param variant
    * @param attributeName
@@ -913,16 +938,25 @@ public class VCFLoader
   {
     Object att = variant.getAttribute(attributeName);
 
+    String result = null;
     if (att instanceof String)
     {
-      return (String) att;
+      result = (String) att;
     }
-    else if (att instanceof ArrayList)
+    else if (att instanceof List<?>)
     {
-      return ((List<String>) att).get(alleleIndex);
+      List<String> theList = (List<String>) att;
+      if (alleleIndex == -1)
+      {
+        result = StringUtils.listToDelimitedString(theList, ",");
+      }
+      else
+      {
+        result = theList.get(alleleIndex);
+      }
     }
 
-    return null;
+    return result;
   }
 
   /**
@@ -1311,6 +1345,10 @@ public class VCFLoader
          */
         index++;
       }
+      else if (number == VCFHeaderLineCount.UNBOUNDED) // .
+      {
+        index = -1;
+      }
       else if (number != VCFHeaderLineCount.A)
       {
         /*