/*
* 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.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.assertAlignmentDatasetRefs(af.getViewport()
.getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
+ pass3 + "): Fetch " + first + ":");
// 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.assertAlignmentDatasetRefs(af.getViewport()
.getAlignment(), "Pass (" + pass1 + "," + pass2 + ","
+ pass3 + "): Recover " + first + ":");
}
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);
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();
}
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)
{
nextxref = first + " -> " + db + "{" + p++ + "}";
// verify references for this panel
AlignmentTest.assertAlignmentDatasetRefs(avp.getAlignment(),
"" + "Pass (" + pass1 + "," + pass2 + "): For "
+ nextxref + ":");
SequenceI[] xrseqs = avp.getAlignment().getSequencesArray();
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.assertAlignmentDatasetRefs(
nextavp.getAlignment(), "" + "Pass (" + pass1
+ "," + pass2 + "): For "
+ 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);
}
}
}