/* * 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 . * The Jalview Authors are detailed in the 'AUTHORS' file. */ package jalview.io; import static org.testng.AssertJUnit.assertTrue; import jalview.analysis.CrossRef; import jalview.api.AlignmentViewPanel; import jalview.datamodel.AlignedCodonFrame; import jalview.datamodel.AlignmentI; import jalview.datamodel.AlignmentTest; import jalview.datamodel.SequenceI; import jalview.gui.AlignFrame; import jalview.gui.CrossRefAction; import jalview.gui.Desktop; import jalview.gui.Jalview2XML; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.IdentityHashMap; import java.util.List; import org.testng.Assert; import org.testng.annotations.Test; @Test(singleThreaded = true) public class CrossRef2xmlTests extends Jalview2xmlBase { /** * test store and recovery of expanded views * * @throws Exception */ @Test(groups = { "Operational" }, enabled = true) public void testRetrieveAndShowCrossref() throws Exception { // for every set of db queries // retrieve db query // verify presence of expected xrefs // show xrefs - verify expected type of frame is shown for each xref // show xrefs again // - verify original -> xref -> xref(original) recovers frame containing at // least the first retrieved sequence // store // 1. whole project // 2. individual frames // 3. load each one back and verify // . aligned sequences (.toString() ) // . xrefs (.toString() ) // . codonframes // // HashMap dbtoviewBit = new HashMap(); List keyseq = new ArrayList(); HashMap savedProjects = new HashMap(); for (String[] did : new String[][] { { "UNIPROT", "P01731" } }) { // pass counters - 0 - first pass, 1 means retrieve project rather than // perform action int pass1 = 0, pass2 = 0, pass3 = 0; // each do loop performs two iterations in the first outer loop pass, but // only performs one iteration on the second outer loop // ie. pass 1 = 0 {pass 2= 0 { pass 3 = 0,1 }, pass 2=1 { pass 3 = 0 }}, 1 // { pass 2 = 0 { pass 3 = 0 } } do { String first = did[0] + " " + did[1]; AlignFrame af = null; if (pass1 == 0) { // retrieve dbref keyseq.add(first); af = jalview.gui.SequenceFetcher.fetchAndShow(did[0], did[1]) .get(0); assertTrue("Didn't retrieve " + first, af != null); // verify references for retrieved data AlignmentTest.verifyAlignmentDatasetRefs(af.getViewport() .getAlignment(), true); // store project to recover on next pass stringify(dbtoviewBit, savedProjects, first, af.alignPanel); } else { Desktop.instance.closeAll_actionPerformed(null); // recover stored project af = new FileLoader(false).LoadFileWaitTillLoaded(savedProjects .get(first).toString(), FormatAdapter.FILE); // verify references for recovered data AlignmentTest.verifyAlignmentDatasetRefs(af.getViewport() .getAlignment(), true); } boolean dna = af.getViewport().getAlignment().isNucleotide(); AlignmentI retral = af.getViewport().getAlignment(); AlignmentI dataset = retral.getDataset(); SequenceI[] seqs = retral.getSequencesArray(); List ptypes = (seqs == null || seqs.length == 0) ? null : new CrossRef(seqs, dataset) .findXrefSourcesForSequences(dna); /* * map between a view, and views generated after retrieving xrefs */ IdentityHashMap> viewxrefview = new IdentityHashMap>(); /* * map between a particular view and it's originating dbref path */ IdentityHashMap viewsourcedb = new IdentityHashMap(); viewsourcedb.put(af.alignPanel, first); for (String db : ptypes) { pass2 = 0; do // second cross ref and recover crossref loop { // counter for splitframe views retrieved via crossref int p = 0; // build next key so we an retrieve all views String nextxref = first + " -> " + db + "{" + p + "}"; // perform crossref action, or retrieve stored project List cra_views = new ArrayList(); CrossRefAction cra = null; if (pass2 == 0) { // retrieve and show cross-refs in this thread cra = new CrossRefAction(af, seqs, dna, db); cra.run(); Assert.assertTrue(cra.getXrefViews().size() > 0, "No crossrefs retrieved for " + db); cra_views = cra.getXrefViews(); viewxrefview.put(af.alignPanel, cra.getXrefViews()); } else { Desktop.instance.closeAll_actionPerformed(null); // recover stored project AlignFrame af2 = new FileLoader(false) .LoadFileWaitTillLoaded(savedProjects.get(nextxref) .toString(), FormatAdapter.FILE); // gymnastics to recover the alignPanel/Complementary alignPanel if (af2.getViewport().isNucleotide()) { // top view, then bottom cra_views.add(af2.getViewport().getAlignPanel()); cra_views.add(((jalview.gui.AlignViewport) af2 .getViewport().getCodingComplement()) .getAlignPanel()); } else { // bottom view, then top cra_views.add(((jalview.gui.AlignViewport) af2 .getViewport().getCodingComplement()) .getAlignPanel()); cra_views.add(af2.getViewport().getAlignPanel()); } } for (AlignmentViewPanel avp : cra_views) { // verify references for this panel AlignmentTest.verifyAlignmentDatasetRefs(avp.getAlignment(), true); SequenceI[] xrseqs = avp.getAlignment().getSequencesArray(); nextxref = first + " -> " + db + "{" + p++ + "}"; viewsourcedb.put(avp, nextxref); stringify(dbtoviewBit, savedProjects, nextxref, avp); keyseq.add(nextxref); List xrptypes = (seqs == null || seqs.length == 0) ? null : new CrossRef(xrseqs, dataset) .findXrefSourcesForSequences(avp .getAlignViewport().isNucleotide()); for (String xrefdb : xrptypes) { pass3 = 0; do // 3rd cross ref and recover crossref loop { List cra_views2 = new ArrayList(); int q = 0; String nextnextxref = "{" + p + "}" + nextxref + " -> " + xrefdb + "{" + q + "}"; AlignFrame nextaf = Desktop.getAlignFrameFor(avp .getAlignViewport()); if (pass3 == 0) { cra = new CrossRefAction(nextaf, xrseqs, avp .getAlignViewport().isNucleotide(), xrefdb); cra.run(); Assert.assertTrue(cra.getXrefViews().size() > 0, "No crossrefs found for '" + nextxref + "' to " + xrefdb + " via '" + nextaf.getTitle() + "'"); cra_views2 = cra.getXrefViews(); } else { Desktop.instance.closeAll_actionPerformed(null); // recover stored project AlignFrame af2 = new FileLoader(false) .LoadFileWaitTillLoaded( savedProjects.get(nextnextxref) .toString(), FormatAdapter.FILE); // gymnastics to recover the alignPanel/Complementary // alignPanel if (af2.getViewport().isNucleotide()) { // top view, then bottom cra_views2.add(af2.getViewport().getAlignPanel()); cra_views2.add(((jalview.gui.AlignViewport) af2 .getViewport().getCodingComplement()) .getAlignPanel()); } else { // bottom view, then top cra_views2.add(((jalview.gui.AlignViewport) af2 .getViewport().getCodingComplement()) .getAlignPanel()); cra_views2.add(af2.getViewport().getAlignPanel()); } Assert.assertEquals(cra_views2.size(), 2); Assert.assertNotNull(cra_views2.get(0)); Assert.assertNotNull(cra_views2.get(1)); } for (AlignmentViewPanel nextavp : cra_views2) { nextnextxref = "{" + p + "}" + nextxref + " -> " + xrefdb + "{" + q++ + "}"; // verify references for this panel AlignmentTest.verifyAlignmentDatasetRefs( nextavp.getAlignment(), true); viewsourcedb.put(nextavp, nextnextxref); stringify(dbtoviewBit, savedProjects, nextnextxref, nextavp); keyseq.add(nextnextxref); } } while (pass3++ < 2 && pass2 < 1); } } } while (pass2++ < 2 && pass1 < 1); } } while (++pass1 < 2); } } /** * first time called, record strings derived from alignment and * alignedcodonframes, and save view to a project file. Second time called, * compare strings to existing ones. org.testng.Assert.assertTrue on * stringmatch * * @param dbtoviewBit * map between xrefpath and view string * @param savedProjects * - map from xrefpath to saved project filename (createTempFile) * @param xrefpath * - xrefpath - unique ID for this context (composed of sequence of * db-fetch/cross-ref actions preceeding state) * @param avp * - viewpanel to store (for viewpanels in splitframe, the same * project should be written for both panels, only one needs * recovering for comparison on the next stringify call, but each * viewpanel needs to be called with a distinct xrefpath to ensure * each one's strings are compared) */ private void stringify(HashMap dbtoviewBit, HashMap savedProjects, String xrefpath, AlignmentViewPanel avp) { if (savedProjects != null) { if (savedProjects.get(xrefpath) == null) { // write a project file for this view. On the second pass, this will be // recovered and cross-references verified try { File prfile = File.createTempFile("crossRefTest", ".jvp"); AlignFrame af = Desktop.getAlignFrameFor(avp.getAlignViewport()); new Jalview2XML(false).saveAlignment(af, prfile.toString(), af.getTitle()); System.out.println("Written view from '" + xrefpath + "' as '" + prfile.getAbsolutePath() + "'"); savedProjects.put(xrefpath, prfile); } catch (IOException q) { Assert.fail("Unexpected IO Exception", q); } } else { System.out.println("Stringify check on view from '" + xrefpath + "' [ possibly retrieved from '" + savedProjects.get(xrefpath).getAbsolutePath() + "' ]"); } } StringBuilder sbr = new StringBuilder(); sbr.append(avp.getAlignment().toString()); sbr.append("\n"); sbr.append(""); sbr.append("\n"); sbr.append(avp.getAlignment().getDataset()); sbr.append("\n"); sbr.append(""); sbr.append("\n"); int p = 0; if (avp.getAlignment().getCodonFrames() != null) { for (AlignedCodonFrame ac : avp.getAlignment().getCodonFrames()) { sbr.append(""); sbr.append("\n"); sbr.append(ac.toString()); sbr.append("\n"); } } String dbt = dbtoviewBit.get(xrefpath); if (dbt == null) { dbtoviewBit.put(xrefpath, sbr.toString()); } else { Assert.assertEquals(sbr.toString(), dbt, "stringify mismatch for " + xrefpath); } } }