X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fanalysis%2FFinder.java;h=191f6e832ae0dd24176b8705d6c65dd09cec9283;hb=3d0101179759ef157b088ea135423cd909512d9f;hp=2fa09aa730be1bcc7c89831f6712607b7ac9bded;hpb=7bc226b58110fa26d9dbd3f0c78095d06909ffc3;p=jalview.git diff --git a/src/jalview/analysis/Finder.java b/src/jalview/analysis/Finder.java index 2fa09aa..191f6e8 100644 --- a/src/jalview/analysis/Finder.java +++ b/src/jalview/analysis/Finder.java @@ -1,308 +1,398 @@ -package jalview.analysis; - -import java.util.*; - -import jalview.datamodel.*; - -public class Finder -{ - /** - * Implements the search algorithms for the Find dialog box. - */ - SearchResults searchResults; - AlignmentI alignment; - jalview.datamodel.SequenceGroup selection = null; - Vector idMatch = null; - boolean caseSensitive = false; - boolean findAll = false; - com.stevesoft.pat.Regex regex = null; - /** - * hold's last-searched position between calles to find(false) - */ - int seqIndex = 0, resIndex = 0; - public Finder(AlignmentI alignment, SequenceGroup selection) - { - this.alignment = alignment; - this.selection = selection; - } - - public Finder(AlignmentI alignment, SequenceGroup selectionGroup, - int seqIndex, int resIndex) - { - this(alignment, selectionGroup); - this.seqIndex = seqIndex; - this.resIndex = resIndex; - } - - public boolean find(String searchString) - { - boolean hasResults = false; - if (!caseSensitive) - { - searchString = searchString.toUpperCase(); - } - regex = new com.stevesoft.pat.Regex(searchString); - searchResults = new SearchResults(); - idMatch = new Vector(); - Sequence seq; - String item = null; - boolean found = false; - - ////// is the searchString a residue number? - try - { - int res = Integer.parseInt(searchString); - found = true; - if (selection == null || selection.getSize() < 1) - { - seq = (Sequence) alignment.getSequenceAt(0); - } - else - { - seq = (Sequence) (selection.getSequenceAt(0)); - } - - searchResults.addResult(seq, res, res); - hasResults = true; - } - catch (NumberFormatException ex) - { - } - - /////////////////////////////////////////////// - - int end = alignment.getHeight(); - - if (selection != null) - { - if ( (selection.getSize() < 1) || - ( (selection.getEndRes() - selection.getStartRes()) < 2)) - { - selection = null; - } - } - - while (!found && (seqIndex < end)) - { - seq = (Sequence) alignment.getSequenceAt(seqIndex); - - if ( (selection != null) && !selection.getSequences(null).contains(seq)) - { - seqIndex++; - resIndex = 0; - - continue; - } - - item = seq.getSequenceAsString(); - // JBPNote - check if this toUpper which is present in the application implementation makes a difference - //if(!caseSensitive) - // item = item.toUpperCase(); - - if ( (selection != null) && - (selection.getEndRes() < alignment.getWidth() - 1)) - { - item = item.substring(0, selection.getEndRes() + 1); - } - - ///Shall we ignore gaps???? - JBPNote: Add Flag for forcing this or not - StringBuffer noGapsSB = new StringBuffer(); - int insertCount = 0; - Vector spaces = new Vector(); - - for (int j = 0; j < item.length(); j++) - { - if (!jalview.util.Comparison.isGap(item.charAt(j))) - { - noGapsSB.append(item.charAt(j)); - spaces.addElement(new Integer(insertCount)); - } - else - { - insertCount++; - } - } - - String noGaps = noGapsSB.toString(); - - for (int r = resIndex; r < noGaps.length(); r++) - { - - if (regex.searchFrom(noGaps, r)) - { - resIndex = regex.matchedFrom(); - - if ( (selection != null) && - ( (resIndex + - Integer.parseInt(spaces.elementAt(resIndex).toString())) < - selection.getStartRes())) - { - continue; - } - - int sres = seq.findPosition(resIndex + - Integer.parseInt(spaces.elementAt( - resIndex) - .toString())); - int eres = seq.findPosition(regex.matchedTo() - 1 + - Integer.parseInt(spaces.elementAt(regex. - matchedTo() - - 1).toString())); - - searchResults.addResult(seq, sres, eres); - hasResults = true; - if (!findAll) - { - // thats enough, break and display the result - found = true; - resIndex++; - - break; - } - - r = resIndex; - } - else - { - break; - } - } - - if (!found) - { - seqIndex++; - resIndex = 0; - } - } - - for (int id = 0; id < alignment.getHeight(); id++) - { - if (regex.search(alignment.getSequenceAt(id).getName())) - { - idMatch.addElement(alignment.getSequenceAt(id)); - hasResults = true; - } - } - return hasResults; - } - - /** - * @return the alignment - */ - public AlignmentI getAlignment() - { - return alignment; - } - - /** - * @param alignment the alignment to set - */ - public void setAlignment(AlignmentI alignment) - { - this.alignment = alignment; - } - - /** - * @return the caseSensitive - */ - public boolean isCaseSensitive() - { - return caseSensitive; - } - - /** - * @param caseSensitive the caseSensitive to set - */ - public void setCaseSensitive(boolean caseSensitive) - { - this.caseSensitive = caseSensitive; - } - - /** - * @return the findAll - */ - public boolean isFindAll() - { - return findAll; - } - - /** - * @param findAll the findAll to set - */ - public void setFindAll(boolean findAll) - { - this.findAll = findAll; - } - - /** - * @return the selection - */ - public jalview.datamodel.SequenceGroup getSelection() - { - return selection; - } - - /** - * @param selection the selection to set - */ - public void setSelection(jalview.datamodel.SequenceGroup selection) - { - this.selection = selection; - } - - /** - * @return the idMatch - */ - public Vector getIdMatch() - { - return idMatch; - } - - /** - * @return the regex - */ - public com.stevesoft.pat.Regex getRegex() - { - return regex; - } - - /** - * @return the searchResults - */ - public SearchResults getSearchResults() - { - return searchResults; - } - - /** - * @return the resIndex - */ - public int getResIndex() - { - return resIndex; - } - - /** - * @param resIndex the resIndex to set - */ - public void setResIndex(int resIndex) - { - this.resIndex = resIndex; - } - - /** - * @return the seqIndex - */ - public int getSeqIndex() - { - return seqIndex; - } - - /** - * @param seqIndex the seqIndex to set - */ - public void setSeqIndex(int seqIndex) - { - this.seqIndex = seqIndex; - } -} +/* + * 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.analysis; + +import jalview.datamodel.AlignmentI; +import jalview.datamodel.SearchResultMatchI; +import jalview.datamodel.SearchResults; +import jalview.datamodel.SearchResultsI; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.util.Comparison; + +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + +import com.stevesoft.pat.Regex; + +public class Finder +{ + /** + * Implements the search algorithms for the Find dialog box. + */ + SearchResultsI searchResults; + + AlignmentI alignment; + + SequenceGroup selection = null; + + Vector idMatch = null; + + boolean caseSensitive = false; + + private boolean includeDescription = false; + + boolean findAll = false; + + Regex regex = null; + + /** + * holds last-searched position between calls to find(false) + */ + int seqIndex = 0, resIndex = -1; + + public Finder(AlignmentI alignment, SequenceGroup selection) + { + this.alignment = alignment; + this.selection = selection; + } + + /** + * restart search at given sequence and residue on alignment and (optionally) + * contained in selection + * + * @param alignment + * @param selectionGroup + * @param seqIndex + * @param resIndex + */ + public Finder(AlignmentI alignment, SequenceGroup selectionGroup, + int seqIndex, int resIndex) + { + this(alignment, selectionGroup); + this.seqIndex = seqIndex; + this.resIndex = resIndex; + } + + public boolean find(String searchString) + { + boolean hasResults = false; + if (!caseSensitive) + { + searchString = searchString.toUpperCase(); + } + regex = new Regex(searchString); + regex.setIgnoreCase(!caseSensitive); + searchResults = new SearchResults(); + idMatch = new Vector(); + String item = null; + boolean found = false; + int end = alignment.getHeight(); + + // ///////////////////////////////////////////// + + if (selection != null) + { + if ((selection.getSize() < 1) + || ((selection.getEndRes() - selection.getStartRes()) < 2)) + { + selection = null; + } + } + SearchResultMatchI lastm = null; + + while (!found && (seqIndex < end)) + { + SequenceI seq = alignment.getSequenceAt(seqIndex); + + if ((selection != null && selection.getSize() > 0) + && !selection.getSequences(null).contains(seq)) + { + seqIndex++; + resIndex = -1; + + continue; + } + if (resIndex < 0) + { + resIndex = 0; + // test for one off matches - sequence position and sequence ID + // //// is the searchString a residue number? + try + { + int res = Integer.parseInt(searchString); + // possibly a residue number - check if valid for seq + if (seq.getEnd() >= res) + { + searchResults.addResult(seq, res, res); + hasResults = true; + // resIndex=seq.getLength(); + // seqIndex++; + if (!findAll) + { + found = true; + break; + } + } + } catch (NumberFormatException ex) + { + } + + if (regex.search(seq.getName()) && !idMatch.contains(seq)) + { + idMatch.addElement(seq); + hasResults = true; + if (!findAll) + { + // stop and return the match + found = true; + break; + } + } + + if (isIncludeDescription() && seq.getDescription() != null + && regex.search(seq.getDescription()) + && !idMatch.contains(seq)) + { + idMatch.addElement(seq); + hasResults = true; + if (!findAll) + { + // stop and return the match + found = true; + break; + } + } + } + item = seq.getSequenceAsString(); + + if ((selection != null) + && (selection.getEndRes() < alignment.getWidth() - 1)) + { + item = item.substring(0, selection.getEndRes() + 1); + } + + // /Shall we ignore gaps???? - JBPNote: Add Flag for forcing this or not + StringBuilder noGapsSB = new StringBuilder(); + int insertCount = 0; + List spaces = new ArrayList(); + + for (int j = 0; j < item.length(); j++) + { + if (!Comparison.isGap(item.charAt(j))) + { + noGapsSB.append(item.charAt(j)); + spaces.add(Integer.valueOf(insertCount)); + } + else + { + insertCount++; + } + } + + String noGaps = noGapsSB.toString(); + for (int r = resIndex; r < noGaps.length(); r++) + { + + if (regex.searchFrom(noGaps, r)) + { + resIndex = regex.matchedFrom(); + + if ((selection != null && selection.getSize() > 0) && (resIndex + + spaces.get(resIndex) < selection.getStartRes())) + { + continue; + } + // if invalid string used, then regex has no matched to/from + int sres = seq.findPosition(resIndex + spaces.get(resIndex)); + int eres = seq.findPosition(regex.matchedTo() - 1 + + (spaces.get(regex.matchedTo() - 1))); + // only add result if not contained in previous result + if (lastm == null || (lastm.getSequence() != seq + || (!(lastm.getStart() <= sres + && lastm.getEnd() >= eres)))) + { + lastm = searchResults.addResult(seq, sres, eres); + } + hasResults = true; + if (!findAll) + { + // thats enough, break and display the result + found = true; + resIndex++; + + break; + } + + r = resIndex; + } + else + { + break; + } + } + + if (!found) + { + seqIndex++; + resIndex = -1; + } + } + + /** + * We now search the Id string in the main search loop. for (int id = 0; id + * < alignment.getHeight(); id++) { if + * (regex.search(alignment.getSequenceAt(id).getName())) { + * idMatch.addElement(alignment.getSequenceAt(id)); hasResults = true; } } + */ + return hasResults; + } + + /** + * @return the alignment + */ + public AlignmentI getAlignment() + { + return alignment; + } + + /** + * @param alignment + * the alignment to set + */ + public void setAlignment(AlignmentI alignment) + { + this.alignment = alignment; + } + + /** + * @return the caseSensitive + */ + public boolean isCaseSensitive() + { + return caseSensitive; + } + + /** + * @param caseSensitive + * the caseSensitive to set + */ + public void setCaseSensitive(boolean caseSensitive) + { + this.caseSensitive = caseSensitive; + } + + /** + * @return the findAll + */ + public boolean isFindAll() + { + return findAll; + } + + /** + * @param findAll + * the findAll to set + */ + public void setFindAll(boolean findAll) + { + this.findAll = findAll; + } + + /** + * @return the selection + */ + public jalview.datamodel.SequenceGroup getSelection() + { + return selection; + } + + /** + * @param selection + * the selection to set + */ + public void setSelection(jalview.datamodel.SequenceGroup selection) + { + this.selection = selection; + } + + /** + * Returns the (possibly empty) list of matching sequences (when search + * includes searching sequence names) + * + * @return + */ + public Vector getIdMatch() + { + return idMatch; + } + + /** + * @return the regex + */ + public com.stevesoft.pat.Regex getRegex() + { + return regex; + } + + /** + * @return the searchResults + */ + public SearchResultsI getSearchResults() + { + return searchResults; + } + + /** + * @return the resIndex + */ + public int getResIndex() + { + return resIndex; + } + + /** + * @param resIndex + * the resIndex to set + */ + public void setResIndex(int resIndex) + { + this.resIndex = resIndex; + } + + /** + * @return the seqIndex + */ + public int getSeqIndex() + { + return seqIndex; + } + + /** + * @param seqIndex + * the seqIndex to set + */ + public void setSeqIndex(int seqIndex) + { + this.seqIndex = seqIndex; + } + + public boolean isIncludeDescription() + { + return includeDescription; + } + + public void setIncludeDescription(boolean includeDescription) + { + this.includeDescription = includeDescription; + } +}