Merge branch 'develop' into bug/JAL-2154projectMappings
authorJim Procter <jprocter@issues.jalview.org>
Tue, 23 Aug 2016 10:17:42 +0000 (11:17 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Tue, 23 Aug 2016 10:17:42 +0000 (11:17 +0100)
Conflicts:
 src/jalview/gui/AlignFrame.java
  - pushed raise warning dialog to CrossRefAction
 test/jalview/analysis/AlignmentUtilsTests.java
  - simple merge
 test/jalview/io/Jalview2xmlTests.java
  - pushed updated BeforeClass setup to Jalview2xmlBase

1  2 
src/jalview/gui/CrossRefAction.java
test/jalview/io/Jalview2xmlBase.java
test/jalview/io/Jalview2xmlTests.java

index cb315d6,0000000..f0b0891
mode 100644,000000..100644
--- /dev/null
@@@ -1,305 -1,0 +1,311 @@@
 +/*
 + * 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.gui;
 +
 +import jalview.analysis.AlignmentUtils;
 +import jalview.analysis.CrossRef;
 +import jalview.api.AlignmentViewPanel;
 +import jalview.api.FeatureSettingsModelI;
 +import jalview.bin.Cache;
 +import jalview.datamodel.Alignment;
 +import jalview.datamodel.AlignmentI;
 +import jalview.datamodel.DBRefSource;
 +import jalview.datamodel.SequenceI;
 +import jalview.io.gff.SequenceOntologyI;
 +import jalview.structure.StructureSelectionManager;
 +import jalview.util.MessageManager;
 +import jalview.ws.SequenceFetcher;
 +
 +import java.util.ArrayList;
 +import java.util.List;
 +
++import javax.swing.JOptionPane;
++
 +/**
 + * Factory constructor and runnable for discovering and displaying
 + * cross-references for a set of aligned sequences
 + * 
 + * @author jprocter
 + *
 + */
 +public class CrossRefAction implements Runnable
 +{
 +  private AlignFrame alignFrame;
 +
 +  private SequenceI[] sel;
 +
 +  private boolean _odna;
 +
 +  private String source;
 +
 +  List<AlignmentViewPanel> xrefViews = new ArrayList<AlignmentViewPanel>();
 +
 +  public List<jalview.api.AlignmentViewPanel> getXrefViews()
 +  {
 +    return xrefViews;
 +  }
 +
 +  @Override
 +  public void run()
 +  {
 +    final long sttime = System.currentTimeMillis();
 +    alignFrame.setProgressBar(
 +            MessageManager.formatMessage(
 +                    "status.searching_for_sequences_from",
 +                    new Object[] { source }), sttime);
 +    try
 +    {
 +      AlignmentI alignment = alignFrame.getViewport().getAlignment();
 +      AlignmentI dataset = alignment.getDataset() == null ? alignment
 +              : alignment.getDataset();
 +      boolean dna = alignment.isNucleotide();
 +      if (_odna != dna)
 +      {
 +        System.err
 +                .println("Conflict: showProducts for alignment originally "
 +                        + "thought to be " + (_odna ? "DNA" : "Protein")
 +                        + " now searching for " + (dna ? "DNA" : "Protein")
 +                        + " Context.");
 +      }
 +      AlignmentI xrefs = new CrossRef(sel, dataset).findXrefSequences(
 +              source, dna);
 +      if (xrefs == null)
 +      {
 +        return;
 +      }
 +      /*
 +       * get display scheme (if any) to apply to features
 +       */
 +      FeatureSettingsModelI featureColourScheme = new SequenceFetcher()
 +              .getFeatureColourScheme(source);
 +
 +      AlignmentI xrefsAlignment = makeCrossReferencesAlignment(dataset,
 +              xrefs);
 +      if (!dna)
 +      {
 +        xrefsAlignment = AlignmentUtils.makeCdsAlignment(
 +                xrefsAlignment.getSequencesArray(), dataset, sel);
 +        xrefsAlignment.alignAs(alignment);
 +      }
 +
 +      /*
 +       * If we are opening a splitframe, make a copy of this alignment (sharing the same dataset
 +       * sequences). If we are DNA, drop introns and update mappings
 +       */
 +      AlignmentI copyAlignment = null;
 +
 +      if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
 +      {
 +        boolean copyAlignmentIsAligned = false;
 +        if (dna)
 +        {
 +          copyAlignment = AlignmentUtils.makeCdsAlignment(sel, dataset,
 +                  xrefsAlignment.getSequencesArray());
 +          if (copyAlignment.getHeight() == 0)
 +          {
++            JOptionPane.showMessageDialog(alignFrame,
++                    MessageManager.getString("label.cant_map_cds"),
++                    MessageManager.getString("label.operation_failed"),
++                    JOptionPane.OK_OPTION);
 +            System.err.println("Failed to make CDS alignment");
 +          }
 +
 +          /*
 +           * pending getting Embl transcripts to 'align', 
 +           * we are only doing this for Ensembl
 +           */
 +          // TODO proper criteria for 'can align as cdna'
 +          if (DBRefSource.ENSEMBL.equalsIgnoreCase(source)
 +                  || AlignmentUtils.looksLikeEnsembl(alignment))
 +          {
 +            copyAlignment.alignAs(alignment);
 +            copyAlignmentIsAligned = true;
 +          }
 +        }
 +        else
 +        {
 +          copyAlignment = AlignmentUtils.makeCopyAlignment(sel,
 +                  xrefs.getSequencesArray(), dataset);
 +        }
 +        copyAlignment
 +                .setGapCharacter(alignFrame.viewport.getGapCharacter());
 +
 +        StructureSelectionManager ssm = StructureSelectionManager
 +                .getStructureSelectionManager(Desktop.instance);
 +
 +        /*
 +         * register any new mappings for sequence mouseover etc
 +         * (will not duplicate any previously registered mappings)
 +         */
 +        ssm.registerMappings(dataset.getCodonFrames());
 +
 +        if (copyAlignment.getHeight() <= 0)
 +        {
 +          System.err.println("No Sequences generated for xRef type "
 +                  + source);
 +          return;
 +        }
 +        /*
 +         * align protein to dna
 +         */
 +        if (dna && copyAlignmentIsAligned)
 +        {
 +          xrefsAlignment.alignAs(copyAlignment);
 +        }
 +        else
 +        {
 +          /*
 +           * align cdna to protein - currently only if 
 +           * fetching and aligning Ensembl transcripts!
 +           */
 +          // TODO: generalise for other sources of locus/transcript/cds data
 +          if (dna && DBRefSource.ENSEMBL.equalsIgnoreCase(source))
 +          {
 +            copyAlignment.alignAs(xrefsAlignment);
 +          }
 +        }
 +      }
 +      /*
 +       * build AlignFrame(s) according to available alignment data
 +       */
 +      AlignFrame newFrame = new AlignFrame(xrefsAlignment,
 +              AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
 +      if (Cache.getDefault("HIDE_INTRONS", true))
 +      {
 +        newFrame.hideFeatureColumns(SequenceOntologyI.EXON, false);
 +      }
 +      String newtitle = String.format("%s %s %s", MessageManager
 +              .getString(dna ? "label.proteins" : "label.nucleotides"),
 +              MessageManager.getString("label.for"), alignFrame.getTitle());
 +      newFrame.setTitle(newtitle);
 +
 +      if (copyAlignment == null)
 +      {
 +        /*
 +         * split frame display is turned off in preferences file
 +         */
 +        Desktop.addInternalFrame(newFrame, newtitle,
 +                AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
 +        xrefViews.add(newFrame.alignPanel);
 +        return; // via finally clause
 +      }
 +      AlignFrame copyThis = new AlignFrame(copyAlignment,
 +              AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
 +      copyThis.setTitle(alignFrame.getTitle());
 +
 +      boolean showSequenceFeatures = alignFrame.getViewport()
 +              .isShowSequenceFeatures();
 +      newFrame.setShowSeqFeatures(showSequenceFeatures);
 +      copyThis.setShowSeqFeatures(showSequenceFeatures);
 +      FeatureRenderer myFeatureStyling = alignFrame.alignPanel
 +              .getSeqPanel().seqCanvas.getFeatureRenderer();
 +
 +      /*
 +       * copy feature rendering settings to split frame
 +       */
 +      newFrame.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
 +              .transferSettings(myFeatureStyling);
 +      copyThis.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
 +              .transferSettings(myFeatureStyling);
 +
 +      /*
 +       * apply 'database source' feature configuration
 +       * if any was found
 +       */
 +      // TODO is this the feature colouring for the original
 +      // alignment or the fetched xrefs? either could be Ensembl
 +      newFrame.getViewport().applyFeaturesStyle(featureColourScheme);
 +      copyThis.getViewport().applyFeaturesStyle(featureColourScheme);
 +
 +      SplitFrame sf = new SplitFrame(dna ? copyThis : newFrame,
 +              dna ? newFrame : copyThis);
 +      newFrame.setVisible(true);
 +      copyThis.setVisible(true);
 +      String linkedTitle = MessageManager
 +              .getString("label.linked_view_title");
 +      Desktop.addInternalFrame(sf, linkedTitle, -1, -1);
 +      sf.adjustDivider();
 +
 +      // finally add the top, then bottom frame to the view list
 +      xrefViews.add(dna ? copyThis.alignPanel : newFrame.alignPanel);
 +      xrefViews.add(!dna ? copyThis.alignPanel : newFrame.alignPanel);
 +
 +    } catch (OutOfMemoryError e)
 +    {
 +      new OOMWarning("whilst fetching crossreferences", e);
 +    } catch (Throwable e)
 +    {
 +      Cache.log.error("Error when finding crossreferences", e);
 +    } finally
 +    {
 +      alignFrame.setProgressBar(MessageManager.formatMessage(
 +              "status.finished_searching_for_sequences_from",
 +              new Object[] { source }), sttime);
 +    }
 +  }
 +
 +  /**
 +   * Makes an alignment containing the given sequences, and adds them to the
 +   * given dataset, which is also set as the dataset for the new alignment
 +   * 
 +   * TODO: refactor to DatasetI method
 +   * 
 +   * @param dataset
 +   * @param seqs
 +   * @return
 +   */
 +  protected AlignmentI makeCrossReferencesAlignment(AlignmentI dataset,
 +          AlignmentI seqs)
 +  {
 +    SequenceI[] sprods = new SequenceI[seqs.getHeight()];
 +    for (int s = 0; s < sprods.length; s++)
 +    {
 +      sprods[s] = (seqs.getSequenceAt(s)).deriveSequence();
 +      if (dataset.getSequences() == null
 +              || !dataset.getSequences().contains(
 +                      sprods[s].getDatasetSequence()))
 +      {
 +        dataset.addSequence(sprods[s].getDatasetSequence());
 +      }
 +      sprods[s].updatePDBIds();
 +    }
 +    Alignment al = new Alignment(sprods);
 +    al.setDataset(dataset);
 +    return al;
 +  }
 +
 +  public CrossRefAction(AlignFrame alignFrame, SequenceI[] sel,
 +          boolean _odna, String source)
 +  {
 +    this.alignFrame = alignFrame;
 +    this.sel = sel;
 +    this._odna = _odna;
 +    this.source = source;
 +  }
 +
 +  public static CrossRefAction showProductsFor(final SequenceI[] sel,
 +          final boolean _odna, final String source,
 +          final AlignFrame alignFrame)
 +  {
 +    return new CrossRefAction(alignFrame, sel, _odna, source);
 +  }
 +
 +}
index 3ce5c4f,0000000..379fd68
mode 100644,000000..100644
--- /dev/null
@@@ -1,69 -1,0 +1,76 @@@
 +package jalview.io;
 +
 +import jalview.bin.Cache;
++import jalview.bin.Jalview;
 +import jalview.datamodel.AlignmentAnnotation;
 +import jalview.datamodel.SequenceI;
 +import jalview.gui.Desktop;
 +
- import java.time.Instant;
 +import java.util.Date;
 +
 +import org.testng.annotations.AfterClass;
 +import org.testng.annotations.BeforeClass;
 +import org.testng.annotations.BeforeTest;
 +
 +public class Jalview2xmlBase
 +{
 +
 +  /**
 +   * @throws java.lang.Exception
 +   */
 +  @BeforeClass(alwaysRun = true)
 +  public static void setUpBeforeClass() throws Exception
 +  {
-     jalview.bin.Jalview.main(new String[] { "-props",
-         "test/jalview/io/testProps_nodas.jvprops" });
-     jalview.bin.Cache.setProperty(
-             "JALVIEW_NEWS_RSS_LASTMODIFIED",
-             Cache.date_format.format(Date.from(Instant.now().plusSeconds(
-                     3600))));
++    /*
++     * use read-only test properties file
++     */
++    Cache.loadProperties("test/jalview/io/testProps.jvprops");
++
++    /*
++     * set news feed last read to a future time to ensure no
++     * 'unread' news item is displayed
++     */
++    Date oneHourFromNow = new Date(System.currentTimeMillis() + 3600 * 1000);
++    Cache.setDateProperty("JALVIEW_NEWS_RSS_LASTMODIFIED", oneHourFromNow);
++
++    Jalview.main(new String[] {});
 +  }
 +
 +  /**
 +   * @throws java.lang.Exception
 +   */
 +  @AfterClass(alwaysRun = true)
 +  public static void tearDownAfterClass() throws Exception
 +  {
 +    jalview.gui.Desktop.instance.closeAll_actionPerformed(null);
 +  }
 +
 +  @BeforeTest(alwaysRun = true)
 +  public static void clearDesktop()
 +  {
 +    if (Desktop.instance != null && Desktop.getAlignFrames() != null)
 +    {
 +      Desktop.instance.closeAll_actionPerformed(null);
 +    }
 +  }
 +
 +  public int countDsAnn(jalview.viewmodel.AlignmentViewport avp)
 +  {
 +    int numdsann = 0;
 +    for (SequenceI sq : avp.getAlignment().getDataset().getSequences())
 +    {
 +      if (sq.getAnnotation() != null)
 +      {
 +        for (AlignmentAnnotation dssa : sq.getAnnotation())
 +        {
 +          if (dssa.isValidStruc())
 +          {
 +            numdsann++;
 +          }
 +        }
 +      }
 +    }
 +    return numdsann;
 +  }
 +
 +}
Simple merge