<classpathentry kind="lib" path="lib/VARNAv3-93.jar"/>
<classpathentry kind="lib" path="lib/jfreesvg-2.1.jar"/>
<classpathentry kind="lib" path="lib/quaqua-filechooser-only-8.0.jar"/>
- <classpathentry kind="lib" path="lib/htsjdk-1.133.jar"/>
+ <classpathentry kind="lib" path="lib/VAqua4.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin"/>
<classpathentry kind="lib" path="lib/xml-apis.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
<classpathentry kind="lib" path="lib/biojava-core-4.1.0.jar"/>
<classpathentry kind="lib" path="lib/biojava-ontology-4.1.0.jar"/>
+ <classpathentry kind="lib" path="lib/htsjdk-2.12.0.jar"/>
<classpathentry kind="lib" path="lib/groovy-all-2.4.12-indy.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="output" path="classes"/>
label.about = About...
label.show_sequence_limits = Show Sequence Limits
action.feature_settings = Feature Settings...
-label.feature_settings = Feature Settings
label.all_columns = All Columns
label.all_sequences = All Sequences
label.selected_columns = Selected Columns
label.chimera_failed = Error opening Chimera - is it installed?\nCheck path in Preferences, Structure
label.min_colour = Minimum Colour
label.max_colour = Maximum Colour
+label.no_colour = No Colour
label.use_original_colours = Use Original Colours
label.threshold_minmax = Threshold is min/max
label.represent_group_with = Represent Group with {0}
label.group_colour = Group Colour
label.sequence = Sequence
label.view_pdb_structure = View PDB Structure
-label.min = Min:
-label.max = Max:
-label.colour_by_label = Colour by label
+label.min_value = Min value
+label.max_value = Max value
+label.no_value = No value
label.new_feature = New Feature
label.match_case = Match Case
label.view_alignment_editor = View in alignment editor
label.seq_sort_by_score = Sequence sort by Score
label.load_colours = Load Colours
label.save_colours = Save Colours
+label.load_colours_tooltip = Load feature colours and filters from file
+label.save_colours_tooltip = Save feature colours and filters to file
label.fetch_das_features = Fetch DAS Features
label.selected_database_to_fetch_from = Selected {0} database {1} to fetch from {2}
label.database_param = Database: {0}
label.enter_view_name = Enter View Name
label.enter_label = Enter label
label.enter_label_for_the_structure = Enter a label for the structure
- label.pdb_entry_is_already_displayed = {0} is already displayed.\nDo you want to re-use this viewer ?
- label.map_sequences_to_visible_window = Map Sequences to Visible Window: {0}
- label.add_pdbentry_to_view = Do you want to add {0} to the view called\n{1}\n
- label.align_to_existing_structure_view = Align to existing structure view
label.pdb_entries_couldnt_be_retrieved = The following pdb entries could not be retrieved from the PDB\:\n{0}\nPlease retry, or try downloading them manually.
label.couldnt_load_file = Couldn't load file
label.couldnt_find_pdb_id_in_file = Couldn't find a PDB id in the file supplied. Please enter an Id to identify this structure.
label.view_full_application = View in Full Application
label.load_associated_tree = Load Associated Tree...
label.load_features_annotations = Load Features/Annotations...
+label.load_vcf = Load SNP variants from plain text or indexed VCF data
+label.load_vcf_file = Load VCF File
+label.searching_vcf = Loading VCF variants...
+label.added_vcf = Added {0} VCF variants to {1} sequence(s)
label.export_features = Export Features...
label.export_annotations = Export Annotations...
label.to_upper_case = To Upper Case
label.threshold_feature_below_threshold = Below Threshold
label.adjust_threshold = Adjust threshold
label.toggle_absolute_relative_display_threshold = Toggle between absolute and relative display threshold.
-label.display_features_same_type_different_label_using_different_colour = Display features of the same type with a different label using a different colour. (e.g. domain features)
label.select_colour_minimum_value = Select Colour for Minimum Value
label.select_colour_maximum_value = Select Colour for Maximum Value
label.open_url_param = Open URL {0}
label.original_data_for_params = Original Data for {0}
label.points_for_params = Points for {0}
label.transformed_points_for_params = Transformed points for {0}
-label.graduated_color_for_params = Graduated Feature Colour for {0}
+label.variable_color_for = Variable Feature Colour for {0}
label.select_background_colour = Select Background Colour
label.invalid_font = Invalid Font
label.separate_multiple_accession_ids = Enter one or more accession IDs separated by a semi-colon ";"
label.service_called_is_not_seq_search_service = The Service called \n{0}\nis not a \nSequence Search Service\!
label.seq_search_service_is_unknown = The Sequence Search Service named {0} is unknown
label.feature_type = Feature Type
-label.display = Display
+label.show = Show
label.service_url = Service URL
label.copied_sequences = Copied sequences
label.cut_sequences = Cut Sequences
label.result = result
label.results = results
label.structure_chooser = Structure Chooser
- label.select = Select :
label.invert = Invert
label.select_pdb_file = Select PDB File
info.select_filter_option = Select Filter Option/Manual Entry
label.overview = Overview
label.reset_to_defaults = Reset to defaults
label.oview_calc = Recalculating overview...
+label.feature_details = Feature details
+label.matchCondition_contains = Contains
+label.matchCondition_notcontains = Does not contain
+label.matchCondition_matches = Matches
+label.matchCondition_notmatches = Does not match
+label.matchCondition_present = Is present
+label.matchCondition_notpresent = Is not present
+label.matchCondition_eq = =
+label.matchCondition_ne = not =
+label.matchCondition_lt = <
+label.matchCondition_le = <=
+label.matchCondition_gt = >
+label.matchCondition_ge = >=
+label.numeric_required = The value should be numeric
+label.filter = Filter
+label.filters = Filters
+label.join_conditions = Join conditions with
+label.score = Score
+label.colour_by_label = Colour by label
+label.variable_colour = Variable colour...
+label.select_colour = Select colour
option.enable_disable_autosearch = When ticked, search is performed automatically
option.autosearch = Autosearch
label.retrieve_ids = Retrieve IDs
+label.display_settings_for = Display settings for {0} features
+label.simple = Simple
+label.simple_colour = Simple Colour
+label.colour_by_text = Colour by text
+label.graduated_colour = Graduated Colour
+label.by_text_of = By text of
+label.by_range_of = By range of
+label.filters_tooltip = Click to set or amend filters
+label.or = Or
+label.and = And
+label.sequence_feature_colours = Sequence Feature Colours
label.best_quality = Best Quality
label.best_resolution = Best Resolution
label.most_protein_chain = Most Protein Chain
label.documentation = Documentación
label.about = Acerca de...
label.show_sequence_limits = Mostrar los límites de la secuencia
-label.feature_settings = Ajustar funciones...
label.all_columns = Todas las columnas
label.all_sequences = Todas las secuencias
label.selected_columns = Columnas seleccionadas
label.autocalculated_annotation = Anotación autocalculada
label.min_colour = Color mínimo
label.max_colour = Color máximo
+label.no_colour = Sin color
label.use_original_colours = Usar colores originales
label.threshold_minmax = El umbral es mín/máx
label.represent_group_with = Representar al grupo con
label.group_colour = Color del grupo
label.sequence = Secuencia
label.view_pdb_structure = Ver estructura PDB
-label.min = Mín:
-label.max = Máx:
+label.max_value = Valor máximo
+label.min_value = Valor mínimo
+label.no_value = Sin valor
label.colour_by_label = Color por etiquetas
label.new_feature = Nueva función
label.match_case = Hacer corresponder mayúsculas y minúsculas
label.seq_sort_by_score = Ordenar las secuencias por puntuación
label.load_colours = Cargar colores
label.save_colours = Guardar colores
+label.load_colours_tooltip = Cargar colores y filtros desde fichero
+label.save_colours_tooltip = Guardar colores y filtros en fichero
label.fetch_das_features = Recuperar funciones DAS
label.selected_database_to_fetch_from = Seleccionada {0} Base de datos {1} para buscar de {2}
label.database_param = Base de datos: {0}
label.enter_view_name = Introduzca un nombre para la vista
label.enter_label = Introducir etiqueta
label.enter_label_for_the_structure = Introducir una etiqueta para la estructura
- label.pdb_entry_is_already_displayed = {0} Ya est\u00E1 mostrado.\nQuieres volver a usar este visor?
- label.map_sequences_to_visible_window = Mapa de secuencias en ventana visible: {0}
- label.add_pdbentry_to_view = Quieres a\u00F1adir {0} a la vista llamada\n{1}\n
- label.align_to_existing_structure_view = Alinear a una estructura ya existente
label.pdb_entries_couldnt_be_retrieved = Las siguientes entradas pdb no pueden ser extra\u00EDdas del PDB\:\n{0}\nPor favor, prueba descarg\u00E1ndolas manualmente.
label.couldnt_load_file = No se pudo cargar el fichero
label.couldnt_find_pdb_id_in_file = No se pudo encontrar un Id PDB en el fichero suministrado. Por favor, introduzca un Id para identificar esta estructura.
label.view_full_application = Ver en la aplicación completa
label.load_associated_tree = Cargar árbol asociado ...
label.load_features_annotations = Cargar características/anotaciones ...
+label.load_vcf = Cargar variantes SNP desde fichero VCF texto o tab-indexado
+label.load_vcf_file = Cargar fichero VCF
+label.searching_vcf = Cargando variantes VCF...
+label.added_vcf= {0} variantes VCF añadidas a {1} secuencia(s)
label.export_features = Exportar características...
label.export_annotations = Exportar anotaciones ...
label.to_upper_case = Pasar a mayúsculas
label.threshold_feature_below_threshold = Por debajo del umbral
label.adjust_threshold = Ajustar umbral
label.toggle_absolute_relative_display_threshold = Cambiar entre mostrar el umbral absoluto y el relativo.
-label.display_features_same_type_different_label_using_different_colour = Mostrar las características del mismo tipo con una etiqueta diferente y empleando un color distinto (p.e. características del dominio)
label.select_colour_minimum_value = Seleccionar el color para el valor mínimo
label.select_colour_maximum_value = Seleccionar el color para el valor máximo
label.open_url_param = Abrir URL {0}
label.original_data_for_params = Datos originales de {0}
label.points_for_params = Puntos de {0}
label.transformed_points_for_params = Puntos transformados de {0}
-label.graduated_color_for_params = Color graduado para la característica de {0}
+label.variable_color_for = Color variable para la característica de {0}
label.select_background_colour = Seleccionar color de fondo
label.invalid_font = Fuente no válida
label.separate_multiple_accession_ids = Separar los accession id con un punto y coma ";"
label.service_called_is_not_seq_search_service = El Servicio llamando \n{0}\nno es un \nServicio de B\u00FAsqueda de Secuencias\!
label.seq_search_service_is_unknown = El Servicio de Búsqueda de Sencuencias llamado {0} es desconocido
label.feature_type = Tipo de característisca
-label.display = Representación
+label.show = Mostrar
label.service_url = URL del servicio
label.copied_sequences = Secuencias copiadas
label.cut_sequences = Cortar secuencias
label.scale_protein_to_cdna=Adaptar proteína a cDNA
label.scale_protein_to_cdna_tip=Hacer a los residuos de proteínas de la misma anchura que los codones en ventanas divididas
status.loading_cached_pdb_entries=Cargando Entradas PDB en Caché
- label.select=Seleccionar :
label.select_by_annotation=Seleccionar/Ocultar Columnas por Anotación
action.select_by_annotation=Seleccionar/Ocultar Columnas por Anotación...
action.export_features=Exportar Características
label.overview = Resumen
label.reset_to_defaults = Restablecen a los predeterminados
label.oview_calc = Recalculando resumen
+label.feature_details = Detalles de característica
+label.matchCondition_contains = Contiene
+label.matchCondition_notcontains = No contiene
+label.matchCondition_matches = Es igual a
+label.matchCondition_notmatches = No es igual a
+label.matchCondition_present = Está presente
+label.matchCondition_notpresent = No está presente
+label.matchCondition_eq = =
+label.matchCondition_ne = not =
+label.matchCondition_lt = <
+label.matchCondition_le = <=
+label.matchCondition_gt = >
+label.matchCondition_ge = >=
+label.numeric_required = Valor numérico requerido
+label.filter = Filtro
+label.filters = Filtros
+label.join_conditions = Combinar condiciones con
+label.score = Puntuación
+label.colour_by_label = Colorear por texto
+label.variable_colour = Color variable...
+label.select_colour = Seleccionar color
option.enable_disable_autosearch = Marcar para buscar automáticamente
option.autosearch = Auto búsqueda
label.retrieve_ids = Recuperar IDs
+label.display_settings_for = Visualización de características {0}
+label.simple = Simple
+label.simple_colour = Color simple
+label.colour_by_text = Colorear por texto
+label.graduated_colour = Color graduado
+label.by_text_of = Por texto de
+label.by_range_of = Por rango de
+label.filters_tooltip = Haga clic para configurar o modificar los filtros
+label.or = O
+label.and = Y
+label.sequence_feature_colours = Colores de características de las secuencias
label.best_quality = Mejor Calidad
label.best_resolution = Mejor Resolución
label.most_protein_chain = Más Cadena de Proteína
menuItem.removeActionListener(menuItem.getActionListeners()[0]);
}
windowMenu.remove(menuItem);
-
- System.gc();
};
});
{
ssm.resetAll();
}
- System.gc();
}
@Override
{
Cache.setProperty(EXPERIMENTAL_FEATURES, Boolean.toString(selected));
}
+
+ /**
+ * Answers a (possibly empty) list of any structure viewer frames (currently
+ * for either Jmol or Chimera) which are currently open. This may optionally
+ * be restricted to viewers of a specified class, or viewers linked to a
+ * specified alignment panel.
+ *
+ * @param apanel
+ * if not null, only return viewers linked to this panel
+ * @param structureViewerClass
+ * if not null, only return viewers of this class
+ * @return
+ */
+ public List<StructureViewerBase> getStructureViewers(
+ AlignmentPanel apanel,
+ Class<? extends StructureViewerBase> structureViewerClass)
+ {
+ List<StructureViewerBase> result = new ArrayList<>();
+ JInternalFrame[] frames = Desktop.instance.getAllFrames();
+
+ for (JInternalFrame frame : frames)
+ {
+ if (frame instanceof StructureViewerBase)
+ {
+ if (structureViewerClass == null
+ || structureViewerClass.isInstance(frame))
+ {
+ if (apanel == null
+ || ((StructureViewerBase) frame).isLinkedWith(apanel))
+ {
+ result.add((StructureViewerBase) frame);
+ }
+ }
+ }
+ }
+ return result;
+ }
}
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class SeqPanel extends JPanel
implements MouseListener, MouseMotionListener, MouseWheelListener,
SequenceListener, SelectionListener
-
{
- /** DOCUMENT ME!! */
+ private static final int MAX_TOOLTIP_LENGTH = 300;
+
public SeqCanvas seqCanvas;
- /** DOCUMENT ME!! */
public AlignmentPanel ap;
/*
SearchResultsI lastSearchResults;
/**
- * Creates a new SeqPanel object.
+ * Creates a new SeqPanel object
*
- * @param avp
- * DOCUMENT ME!
- * @param p
- * DOCUMENT ME!
+ * @param viewport
+ * @param alignPanel
*/
- public SeqPanel(AlignViewport av, AlignmentPanel ap)
+ public SeqPanel(AlignViewport viewport, AlignmentPanel alignPanel)
{
linkImageURL = getClass().getResource("/images/link.gif");
seqARep = new SequenceAnnotationReport(linkImageURL.toString());
ToolTipManager.sharedInstance().registerComponent(this);
ToolTipManager.sharedInstance().setInitialDelay(0);
ToolTipManager.sharedInstance().setDismissDelay(10000);
- this.av = av;
+ this.av = viewport;
setBackground(Color.white);
- seqCanvas = new SeqCanvas(ap);
+ seqCanvas = new SeqCanvas(alignPanel);
setLayout(new BorderLayout());
add(seqCanvas, BorderLayout.CENTER);
- this.ap = ap;
+ this.ap = alignPanel;
- if (!av.isDataset())
+ if (!viewport.isDataset())
{
addMouseMotionListener(this);
addMouseListener(this);
addMouseWheelListener(this);
- ssm = av.getStructureSelectionManager();
+ ssm = viewport.getStructureSelectionManager();
ssm.addStructureViewerListener(this);
ssm.addSelectionListener(this);
}
List<SequenceFeature> features = ap.getFeatureRenderer()
.findFeaturesAtColumn(sequence, column + 1);
seqARep.appendFeatures(tooltipText, pos, features,
- this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
+ this.ap.getSeqPanel().seqCanvas.fr);
}
if (tooltipText.length() == 6) // <html>
{
}
else
{
+ if (tooltipText.length() > MAX_TOOLTIP_LENGTH) // constant
+ {
+ tooltipText.setLength(MAX_TOOLTIP_LENGTH);
+ tooltipText.append("...");
+ }
String textString = tooltipText.toString();
if (lastTooltip == null || !lastTooltip.equals(textString))
{
final int column = findColumn(evt);
final int seq = findSeq(evt);
SequenceI sequence = av.getAlignment().getSequenceAt(seq);
- List<SequenceFeature> allFeatures = ap.getFeatureRenderer()
+ List<SequenceFeature> features = ap.getFeatureRenderer()
.findFeaturesAtColumn(sequence, column + 1);
- List<String> links = new ArrayList<>();
- for (SequenceFeature sf : allFeatures)
- {
- if (sf.links != null)
- {
- for (String link : sf.links)
- {
- links.add(link);
- }
- }
- }
- PopupMenu pop = new PopupMenu(ap, null, links);
+ PopupMenu pop = new PopupMenu(ap, null, features);
pop.show(this, evt.getX(), evt.getY());
}
return true;
}
+
+ /**
+ *
+ * @return null or last search results handled by this panel
+ */
+ public SearchResultsI getLastSearchResults()
+ {
+ return lastSearchResults;
+ }
}
{
int hashCode = 31 * fromRatio;
hashCode = 31 * hashCode + toRatio;
- hashCode = 31 * hashCode + fromShifts.toArray().hashCode();
- hashCode = 31 * hashCode + toShifts.toArray().hashCode();
+ for (int[] shift : fromShifts)
+ {
+ hashCode = 31 * hashCode + shift[0];
+ hashCode = 31 * hashCode + shift[1];
+ }
+ for (int[] shift : toShifts)
+ {
+ hashCode = 31 * hashCode + shift[0];
+ hashCode = 31 * hashCode + shift[1];
+ }
+
return hashCode;
}
*/
public boolean isFromForwardStrand()
{
+ return isForwardStrand(getFromRanges());
+ }
+
+ /**
+ * Returns true if mapping is to forward strand, false if to reverse strand.
+ * Result is just based on the first 'to' range that is not a single position.
+ * Default is true unless proven to be false. Behaviour is not well defined if
+ * the mapping has a mixture of forward and reverse ranges.
+ *
+ * @return
+ */
+ public boolean isToForwardStrand()
+ {
+ return isForwardStrand(getToRanges());
+ }
+
+ /**
+ * A helper method that returns true unless at least one range has start > end.
+ * Behaviour is undefined for a mixture of forward and reverse ranges.
+ *
+ * @param ranges
+ * @return
+ */
+ private boolean isForwardStrand(List<int[]> ranges)
+ {
boolean forwardStrand = true;
- for (int[] range : getFromRanges())
+ for (int[] range : ranges)
{
if (range[1] > range[0])
{
|| (fromRatio == 3 && toRatio == 1);
}
+ /**
+ * Returns a map which is the composite of this one and the input map. That
+ * is, the output map has the fromRanges of this map, and its toRanges are the
+ * toRanges of this map as transformed by the input map.
+ * <p>
+ * Returns null if the mappings cannot be traversed (not all toRanges of this
+ * map correspond to fromRanges of the input), or if this.toRatio does not
+ * match map.fromRatio.
+ *
+ * <pre>
+ * Example 1:
+ * this: from [1-100] to [501-600]
+ * input: from [10-40] to [60-90]
+ * output: from [10-40] to [560-590]
+ * Example 2 ('reverse strand exons'):
+ * this: from [1-100] to [2000-1951], [1000-951] // transcript to loci
+ * input: from [1-50] to [41-90] // CDS to transcript
+ * output: from [10-40] to [1960-1951], [1000-971] // CDS to gene loci
+ * </pre>
+ *
+ * @param map
+ * @return
+ */
+ public MapList traverse(MapList map)
+ {
+ if (map == null)
+ {
+ return null;
+ }
+
+ /*
+ * compound the ratios by this rule:
+ * A:B with M:N gives A*M:B*N
+ * reduced by greatest common divisor
+ * so 1:3 with 3:3 is 3:9 or 1:3
+ * 1:3 with 3:1 is 3:3 or 1:1
+ * 1:3 with 1:3 is 1:9
+ * 2:5 with 3:7 is 6:35
+ */
+ int outFromRatio = getFromRatio() * map.getFromRatio();
+ int outToRatio = getToRatio() * map.getToRatio();
+ int gcd = MathUtils.gcd(outFromRatio, outToRatio);
+ outFromRatio /= gcd;
+ outToRatio /= gcd;
+
+ List<int[]> toRanges = new ArrayList<>();
+ for (int[] range : getToRanges())
+ {
+ int[] transferred = map.locateInTo(range[0], range[1]);
+ if (transferred == null)
+ {
+ return null;
+ }
+ toRanges.add(transferred);
+ }
+
+ return new MapList(getFromRanges(), toRanges, outFromRatio, outToRatio);
+ }
+
}
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertSame;
import static org.testng.Assert.assertTrue;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureColourI;
import jalview.api.ViewStyleI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.PDBEntry.Type;
import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.datamodel.features.FeatureMatcher;
+import jalview.datamodel.features.FeatureMatcherSet;
+import jalview.datamodel.features.FeatureMatcherSetI;
import jalview.gui.AlignFrame;
import jalview.gui.AlignViewport;
import jalview.gui.AlignmentPanel;
import jalview.gui.Desktop;
+import jalview.gui.FeatureRenderer;
import jalview.gui.Jalview2XML;
import jalview.gui.JvOptionPane;
import jalview.gui.PopupMenu;
import jalview.schemes.BuriedColourScheme;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
+import jalview.schemes.FeatureColour;
import jalview.schemes.JalviewColourScheme;
import jalview.schemes.RNAHelicesColour;
import jalview.schemes.StrandColourScheme;
import jalview.schemes.TCoffeeColourScheme;
import jalview.structure.StructureImportSettings;
+import jalview.util.matcher.Condition;
import jalview.viewmodel.AlignmentViewport;
+import java.awt.Color;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
}
+ /**
+ * Test for JAL-2223 - multiple mappings in View Mapping report
+ *
+ * @throws Exception
+ */
+ @Test(groups = { "Functional" })
+ public void noDuplicatePdbMappingsMade() throws Exception
+ {
+ StructureImportSettings.setProcessSecondaryStructure(true);
+ StructureImportSettings.setVisibleChainAnnotation(true);
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/exampleFile_2_7.jar", DataSourceType.FILE);
+ assertNotNull(af, "Didn't read in the example file correctly.");
+
+ // locate Jmol viewer
+ // count number of PDB mappings the structure selection manager holds -
+ String pdbFile = af.getCurrentView().getStructureSelectionManager()
+ .findFileForPDBId("1A70");
+ assertEquals(
+ af.getCurrentView().getStructureSelectionManager()
+ .getMapping(pdbFile).length,
+ 2, "Expected only two mappings for 1A70");
+
+ }
+
@Test(groups = { "Functional" })
public void viewRefPdbAnnotation() throws Exception
{
assertTrue(rs.conservationApplied());
assertEquals(rs.getConservationInc(), 30);
}
+
+ /**
+ * Test save and reload of feature colour schemes and filter settings
+ *
+ * @throws IOException
+ */
+ @Test(groups = { "Functional" })
+ public void testSaveLoadFeatureColoursAndFilters() throws IOException
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ ">Seq1\nACDEFGHIKLM", DataSourceType.PASTE);
+ SequenceI seq1 = af.getViewport().getAlignment().getSequenceAt(0);
+
+ /*
+ * add some features to the sequence
+ */
+ int score = 1;
+ addFeatures(seq1, "type1", score++);
+ addFeatures(seq1, "type2", score++);
+ addFeatures(seq1, "type3", score++);
+ addFeatures(seq1, "type4", score++);
+ addFeatures(seq1, "type5", score++);
+
+ /*
+ * set colour schemes for features
+ */
+ FeatureRenderer fr = af.getFeatureRenderer();
+ fr.findAllFeatures(true);
+
+ // type1: red
+ fr.setColour("type1", new FeatureColour(Color.red));
+
+ // type2: by label
+ FeatureColourI byLabel = new FeatureColour();
+ byLabel.setColourByLabel(true);
+ fr.setColour("type2", byLabel);
+
+ // type3: by score above threshold
+ FeatureColourI byScore = new FeatureColour(Color.BLACK, Color.BLUE, 1,
+ 10);
+ byScore.setAboveThreshold(true);
+ byScore.setThreshold(2f);
+ fr.setColour("type3", byScore);
+
+ // type4: by attribute AF
+ FeatureColourI byAF = new FeatureColour();
+ byAF.setColourByLabel(true);
+ byAF.setAttributeName("AF");
+ fr.setColour("type4", byAF);
+
+ // type5: by attribute CSQ:PolyPhen below threshold
+ FeatureColourI byPolyPhen = new FeatureColour(Color.BLACK, Color.BLUE,
+ 1, 10);
+ byPolyPhen.setBelowThreshold(true);
+ byPolyPhen.setThreshold(3f);
+ byPolyPhen.setAttributeName("CSQ", "PolyPhen");
+ fr.setColour("type5", byPolyPhen);
+
+ /*
+ * set filters for feature types
+ */
+
+ // filter type1 features by (label contains "x")
+ FeatureMatcherSetI filterByX = new FeatureMatcherSet();
+ filterByX.and(FeatureMatcher.byLabel(Condition.Contains, "x"));
+ fr.setFeatureFilter("type1", filterByX);
+
+ // filter type2 features by (score <= 2.4 and score > 1.1)
+ FeatureMatcherSetI filterByScore = new FeatureMatcherSet();
+ filterByScore.and(FeatureMatcher.byScore(Condition.LE, "2.4"));
+ filterByScore.and(FeatureMatcher.byScore(Condition.GT, "1.1"));
+ fr.setFeatureFilter("type2", filterByScore);
+
+ // filter type3 features by (AF contains X OR CSQ:PolyPhen != 0)
+ FeatureMatcherSetI filterByXY = new FeatureMatcherSet();
+ filterByXY
+ .and(FeatureMatcher.byAttribute(Condition.Contains, "X", "AF"));
+ filterByXY.or(FeatureMatcher.byAttribute(Condition.NE, "0", "CSQ",
+ "PolyPhen"));
+ fr.setFeatureFilter("type3", filterByXY);
+
+ /*
+ * save as Jalview project
+ */
+ File tfile = File.createTempFile("JalviewTest", ".jvp");
+ tfile.deleteOnExit();
+ String filePath = tfile.getAbsolutePath();
+ assertTrue(af.saveAlignment(filePath, FileFormat.Jalview),
+ "Failed to store as a project.");
+
+ /*
+ * close current alignment and load the saved project
+ */
+ af.closeMenuItem_actionPerformed(true);
+ af = null;
+ af = new FileLoader()
+ .LoadFileWaitTillLoaded(filePath, DataSourceType.FILE);
+ assertNotNull(af, "Failed to import new project");
+
+ /*
+ * verify restored feature colour schemes and filters
+ */
+ fr = af.getFeatureRenderer();
+ FeatureColourI fc = fr.getFeatureStyle("type1");
+ assertTrue(fc.isSimpleColour());
+ assertEquals(fc.getColour(), Color.red);
+ fc = fr.getFeatureStyle("type2");
+ assertTrue(fc.isColourByLabel());
+ fc = fr.getFeatureStyle("type3");
+ assertTrue(fc.isGraduatedColour());
+ assertNull(fc.getAttributeName());
+ assertTrue(fc.isAboveThreshold());
+ assertEquals(fc.getThreshold(), 2f);
+ fc = fr.getFeatureStyle("type4");
+ assertTrue(fc.isColourByLabel());
+ assertTrue(fc.isColourByAttribute());
+ assertEquals(fc.getAttributeName(), new String[] { "AF" });
+ fc = fr.getFeatureStyle("type5");
+ assertTrue(fc.isGraduatedColour());
+ assertTrue(fc.isColourByAttribute());
+ assertEquals(fc.getAttributeName(), new String[] { "CSQ", "PolyPhen" });
+ assertTrue(fc.isBelowThreshold());
+ assertEquals(fc.getThreshold(), 3f);
+
+ assertEquals(fr.getFeatureFilter("type1").toStableString(),
+ "Label Contains x");
+ assertEquals(fr.getFeatureFilter("type2").toStableString(),
+ "(Score LE 2.4) AND (Score GT 1.1)");
+ assertEquals(fr.getFeatureFilter("type3").toStableString(),
+ "(AF Contains X) OR (CSQ:PolyPhen NE 0.0)");
+ }
+
+ private void addFeature(SequenceI seq, String featureType, int score)
+ {
+ SequenceFeature sf = new SequenceFeature(featureType, "desc", 1, 2,
+ score, "grp");
+ sf.setValue("AF", score);
+ sf.setValue("CSQ", new HashMap<String, String>()
+ {
+ {
+ put("PolyPhen", Integer.toString(score));
+ }
+ });
+ seq.addSequenceFeature(sf);
+ }
+
+ /**
+ * Adds two features of the given type to the given sequence, also setting the
+ * score as the value of attribute "AF" and sub-attribute "CSQ:PolyPhen"
+ *
+ * @param seq
+ * @param featureType
+ * @param score
+ */
+ private void addFeatures(SequenceI seq, String featureType, int score)
+ {
+ addFeature(seq, featureType, score++);
+ addFeature(seq, featureType, score);
+ }
}
MapList ml7 = new MapList(codons, protein, 3, 1); // toShifts differ
assertTrue(ml.equals(ml));
+ assertEquals(ml.hashCode(), ml.hashCode());
assertTrue(ml.equals(ml1));
+ assertEquals(ml.hashCode(), ml1.hashCode());
assertTrue(ml1.equals(ml));
assertFalse(ml.equals(null));
assertEquals(1, merged.size());
assertArrayEquals(new int[] { 9, 0 }, merged.get(0));
}
+
+ /**
+ * Test the method that compounds ('traverses') two mappings
+ */
+ @Test(groups = "Functional")
+ public void testTraverse()
+ {
+ /*
+ * simple 1:1 plus 1:1 forwards
+ */
+ MapList ml1 = new MapList(new int[] { 3, 4, 8, 12 }, new int[] { 5, 8,
+ 11, 13 }, 1, 1);
+ MapList ml2 = new MapList(new int[] { 1, 50 }, new int[] { 40, 45, 70,
+ 75, 90, 127 }, 1, 1);
+ MapList compound = ml1.traverse(ml2);
+
+ assertEquals(compound.getFromRatio(), 1);
+ assertEquals(compound.getToRatio(), 1);
+ List<int[]> fromRanges = compound.getFromRanges();
+ assertEquals(fromRanges.size(), 2);
+ assertArrayEquals(new int[] { 3, 4 }, fromRanges.get(0));
+ assertArrayEquals(new int[] { 8, 12 }, fromRanges.get(1));
+ List<int[]> toRanges = compound.getToRanges();
+ assertEquals(toRanges.size(), 2);
+ // 5-8 maps to 44-45,70-71
+ // 11-13 maps to 74-75,90
+ assertArrayEquals(new int[] { 44, 45, 70, 71 }, toRanges.get(0));
+ assertArrayEquals(new int[] { 74, 75, 90, 90 }, toRanges.get(1));
+
+ /*
+ * 1:1 over 1:1 backwards ('reverse strand')
+ */
+ ml1 = new MapList(new int[] { 1, 50 }, new int[] { 70, 119 }, 1, 1);
+ ml2 = new MapList(new int[] { 1, 500 },
+ new int[] { 1000, 901, 600, 201 }, 1, 1);
+ compound = ml1.traverse(ml2);
+
+ assertEquals(compound.getFromRatio(), 1);
+ assertEquals(compound.getToRatio(), 1);
+ fromRanges = compound.getFromRanges();
+ assertEquals(fromRanges.size(), 1);
+ assertArrayEquals(new int[] { 1, 50 }, fromRanges.get(0));
+ toRanges = compound.getToRanges();
+ assertEquals(toRanges.size(), 1);
+ assertArrayEquals(new int[] { 931, 901, 600, 582 }, toRanges.get(0));
+
+ /*
+ * 1:1 plus 1:3 should result in 1:3
+ */
+ ml1 = new MapList(new int[] { 1, 30 }, new int[] { 11, 40 }, 1, 1);
+ ml2 = new MapList(new int[] { 1, 100 }, new int[] { 1, 50, 91, 340 },
+ 1, 3);
+ compound = ml1.traverse(ml2);
+
+ assertEquals(compound.getFromRatio(), 1);
+ assertEquals(compound.getToRatio(), 3);
+ fromRanges = compound.getFromRanges();
+ assertEquals(fromRanges.size(), 1);
+ assertArrayEquals(new int[] { 1, 30 }, fromRanges.get(0));
+ // 11-40 maps to 31-50,91-160
+ toRanges = compound.getToRanges();
+ assertEquals(toRanges.size(), 1);
+ assertArrayEquals(new int[] { 31, 50, 91, 160 }, toRanges.get(0));
+
+ /*
+ * 3:1 plus 1:1 should result in 3:1
+ */
+ ml1 = new MapList(new int[] { 1, 30 }, new int[] { 11, 20 }, 3, 1);
+ ml2 = new MapList(new int[] { 1, 100 }, new int[] { 1, 15, 91, 175 },
+ 1, 1);
+ compound = ml1.traverse(ml2);
+
+ assertEquals(compound.getFromRatio(), 3);
+ assertEquals(compound.getToRatio(), 1);
+ fromRanges = compound.getFromRanges();
+ assertEquals(fromRanges.size(), 1);
+ assertArrayEquals(new int[] { 1, 30 }, fromRanges.get(0));
+ // 11-20 maps to 11-15, 91-95
+ toRanges = compound.getToRanges();
+ assertEquals(toRanges.size(), 1);
+ assertArrayEquals(new int[] { 11, 15, 91, 95 }, toRanges.get(0));
+
+ /*
+ * 1:3 plus 3:1 should result in 1:1
+ */
+ ml1 = new MapList(new int[] { 21, 40 }, new int[] { 13, 72 }, 1, 3);
+ ml2 = new MapList(new int[] { 1, 300 }, new int[] { 51, 70, 121, 200 },
+ 3, 1);
+ compound = ml1.traverse(ml2);
+
+ assertEquals(compound.getFromRatio(), 1);
+ assertEquals(compound.getToRatio(), 1);
+ fromRanges = compound.getFromRanges();
+ assertEquals(fromRanges.size(), 1);
+ assertArrayEquals(new int[] { 21, 40 }, fromRanges.get(0));
+ // 13-72 maps 3:1 to 55-70, 121-124
+ toRanges = compound.getToRanges();
+ assertEquals(toRanges.size(), 1);
+ assertArrayEquals(new int[] { 55, 70, 121, 124 }, toRanges.get(0));
+
+ /*
+ * 3:1 plus 1:3 should result in 1:1
+ */
+ ml1 = new MapList(new int[] { 31, 90 }, new int[] { 13, 32 }, 3, 1);
+ ml2 = new MapList(new int[] { 11, 40 }, new int[] { 41, 50, 71, 150 },
+ 1, 3);
+ compound = ml1.traverse(ml2);
+
+ assertEquals(compound.getFromRatio(), 1);
+ assertEquals(compound.getToRatio(), 1);
+ fromRanges = compound.getFromRanges();
+ assertEquals(fromRanges.size(), 1);
+ assertArrayEquals(new int[] { 31, 90 }, fromRanges.get(0));
+ // 13-32 maps to 47-50,71-126
+ toRanges = compound.getToRanges();
+ assertEquals(toRanges.size(), 1);
+ assertArrayEquals(new int[] { 47, 50, 71, 126 }, toRanges.get(0));
+
+ /*
+ * method returns null if not all regions are mapped through
+ */
+ ml1 = new MapList(new int[] { 1, 50 }, new int[] { 101, 150 }, 1, 1);
+ ml2 = new MapList(new int[] { 131, 180 }, new int[] { 201, 250 }, 1, 3);
+ compound = ml1.traverse(ml2);
+ assertNull(compound);
+ }
+
+ /**
+ * Test that method that inspects for the (first) forward or reverse 'to' range.
+ * Single position ranges are ignored.
+ */
+ @Test(groups = { "Functional" })
+ public void testIsToForwardsStrand()
+ {
+ // [3-9] declares forward strand
+ MapList ml = new MapList(new int[] { 20, 11 },
+ new int[]
+ { 2, 2, 3, 9, 12, 11 }, 1, 1);
+ assertTrue(ml.isToForwardStrand());
+
+ // [11-5] declares reverse strand ([13-14] is ignored)
+ ml = new MapList(new int[] { 20, 11 },
+ new int[]
+ { 2, 2, 11, 5, 13, 14 }, 1, 1);
+ assertFalse(ml.isToForwardStrand());
+
+ // all single position ranges - defaults to forward strand
+ ml = new MapList(new int[] { 3, 1 }, new int[] { 2, 2, 4, 4, 6, 6 }, 1,
+ 1);
+ assertTrue(ml.isToForwardStrand());
+ }
}