JAL-2792 capture feature metadata and render in Feature Details
[jalview.git] / src / jalview / io / vcf / VCFLoader.java
index 85bf7ef..5adc55c 100644 (file)
@@ -6,6 +6,7 @@ import htsjdk.variant.variantcontext.VariantContext;
 import htsjdk.variant.vcf.VCFHeader;
 import htsjdk.variant.vcf.VCFHeaderLine;
 import htsjdk.variant.vcf.VCFHeaderLineCount;
+import htsjdk.variant.vcf.VCFHeaderLineType;
 import htsjdk.variant.vcf.VCFInfoHeaderLine;
 
 import jalview.analysis.AlignmentUtils;
@@ -17,6 +18,9 @@ import jalview.datamodel.GeneLociI;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureAttributeType;
+import jalview.datamodel.features.FeatureSource;
+import jalview.datamodel.features.FeatureSources;
 import jalview.ext.ensembl.EnsemblMap;
 import jalview.ext.htsjdk.VCFReader;
 import jalview.io.gff.Gff3Helper;
@@ -116,6 +120,12 @@ public class VCFLoader
   private int csqAlleleNumberFieldIndex = -1;
   private int csqFeatureFieldIndex = -1;
 
+  /*
+   * a unique identifier under which to save metadata about feature
+   * attributes (selected INFO field data)
+   */
+  private String sourceId;
+
   /**
    * Constructor given an alignment context
    * 
@@ -175,14 +185,18 @@ public class VCFLoader
       reader = new VCFReader(filePath);
 
       header = reader.getFileHeader();
-      VCFHeaderLine ref = header
-              .getOtherHeaderLine(VCFHeader.REFERENCE_KEY);
+
+      sourceId = filePath;
+
+      saveMetadata(sourceId);
 
       /*
        * get offset of CSQ ALLELE_NUM and Feature if declared
        */
       locateCsqFields();
 
+      VCFHeaderLine ref = header
+              .getOtherHeaderLine(VCFHeader.REFERENCE_KEY);
       String vcfAssembly = ref.getValue();
 
       int varCount = 0;
@@ -236,6 +250,47 @@ public class VCFLoader
   }
 
   /**
+   * Reads metadata (such as INFO field descriptions and datatypes) and saves
+   * them for future reference
+   * 
+   * @param sourceId
+   */
+  void saveMetadata(String sourceId)
+  {
+    FeatureSource metadata = new FeatureSource(sourceId);
+
+    for (VCFInfoHeaderLine info : header.getInfoHeaderLines())
+    {
+      String attributeId = info.getID();
+      String desc = info.getDescription();
+      VCFHeaderLineType type = info.getType();
+      FeatureAttributeType attType = null;
+      switch (type)
+      {
+      case Character:
+        attType = FeatureAttributeType.Character;
+        break;
+      case Flag:
+        attType = FeatureAttributeType.Flag;
+        break;
+      case Float:
+        attType = FeatureAttributeType.Float;
+        break;
+      case Integer:
+        attType = FeatureAttributeType.Integer;
+        break;
+      case String:
+        attType = FeatureAttributeType.String;
+        break;
+      }
+      metadata.setAttributeName(attributeId, desc);
+      metadata.setAttributeType(attributeId, attType);
+    }
+
+    FeatureSources.getInstance().addSource(sourceId, metadata);
+  }
+
+  /**
    * Records the position of selected fields defined in the CSQ INFO header (if
    * there is one). CSQ fields are declared in the CSQ INFO Description e.g.
    * <p>
@@ -614,6 +669,7 @@ public class VCFLoader
 
     SequenceFeature sf = new SequenceFeature(type, alleles, featureStart,
             featureEnd, score, FEATURE_GROUP_VCF);
+    sf.setSource(sourceId);
 
     sf.setValue(Gff3Helper.ALLELES, alleles);