/* * BioJava development code * * This code may be freely distributed and modified under the * terms of the GNU Lesser General Public Licence. This should * be distributed with the code. If you do not have a copy, * see: * * http://www.gnu.org/copyleft/lesser.html * * Copyright for this code is held jointly by the individual * authors. These should be listed in @author doc comments. * * For more information on the BioJava project and its aims, * or to join the biojava-l mailing list, visit the home page * at: * * http://www.biojava.org/ * */ package org.biojava.bio.molbio; import java.util.ArrayList; import java.util.List; import org.biojava.bio.seq.Sequence; import org.biojava.bio.seq.SequenceAnnotator; import org.biojava.bio.seq.impl.ViewSequence; import org.biojava.utils.ThreadPool; /** *

RestrictionMapper is a class for annotating * Sequences with Features which represent * restriction sites. Calling annotate(Sequence sequence) * will annotate the Sequence with the sites of any * RestrictionEnzymes which have been added to the * RestrictionMapper. The returned Sequence * is a ViewSequence wrapping the original.

* *

The Features created are * RestrictionSites which have a flyweight * Annotation containing a single String * property "dbxref" whose value is "REBASE:" plus name of the enzyme * (e.g. EcoRI).

* *

The mapper will by default map only those sites which have both * their recognition sites and their cut sites within the * Sequence. This behaviour may be changed to map all * sites which have their recognition sites within the * Sequence using the setMapAll(boolean * on) method.

* *

The current implementation requires that * RestrictionEnzymes to be searched must first be * registered with the RestrictionEnzymeManager.

* * @author Keith James * @since 1.3 */ public class RestrictionMapper implements SequenceAnnotator { /** * SITE_FEATURE_SOURCE the source String * used by RestrictionMapper when creating * restriction site Features. This is the * String which is returned when a * Feature's getSource() method is * called. */ public static final String SITE_FEATURE_SOURCE = "regex"; /** * SITE_FEATURE_TYPE the type String * used by RestrictionMapper when creating * restriction site Features. This is the * String which is returned when a * Feature's getType() method is called. */ public static final String SITE_FEATURE_TYPE = "misc_binding"; private List restrictionEnzymes; private boolean mapAll; private ThreadPool threadPool; /** *

Creates a new RestrictionMapper which will use * the specified ThreadPool. Do not share one pool * between a number of RestrictionMappers because * annotate(Sequence sequence) waits for all threads * in the pool to finish work before returning and this will lead * to a race condition between mappers. One mapper could end up * waiting for another mapper's threads before returning.

* * @param threadPool a ThreadPool. */ public RestrictionMapper(ThreadPool threadPool) { restrictionEnzymes = new ArrayList(); mapAll = false; this.threadPool = threadPool; } /** * annotate adds Features which * represent restriction sites. * * @param sequence a Sequence. * * @return a Sequence view with restriction sites * marked. */ public Sequence annotate(Sequence sequence) { Sequence mapped = new ViewSequence(sequence); for (int i = 0; i < restrictionEnzymes.size(); i++) { RestrictionEnzyme enzyme = (RestrictionEnzyme) restrictionEnzymes.get(i); threadPool.addRequest(new RestrictionSiteFinder(enzyme, mapAll, mapped)); } // Threads will finish work and become idle threadPool.waitForThreads(); return mapped; } /** * getMapAll returns whether all sites should be * marked, including those which have recognition sites within the * sequence, but cut outside it. The default is false, indicating * only sites which can actually be cut are mapped. * * @return a boolean. */ public boolean getMapAll() { return mapAll; } /** * setMapAll sets whether all sites should be marked, * including those which have recognition sites within the * sequence, but cut outside it. The default is false, indicating * only sites which can actually be cut are mapped. * * @param on a boolean. */ public void setMapAll(boolean on) { mapAll = on; } /** * addEnzyme adds an enzyme to be searched for in the * Sequence. * * @param enzyme a RestrictionEnzyme. */ public void addEnzyme(RestrictionEnzyme enzyme) { if (restrictionEnzymes.contains(enzyme)) throw new IllegalArgumentException("RestrictionMapper is already mapping '" + enzyme + "'"); restrictionEnzymes.add(enzyme); } /** * removeEnzyme removes an enzyme from those to be * searched for in the Sequence. * * @param enzyme a RestrictionEnzyme. */ public void removeEnzyme(RestrictionEnzyme enzyme) { if (! restrictionEnzymes.contains(enzyme)) throw new IllegalArgumentException("RestrictionMapper is not mapping '" + enzyme + "'"); restrictionEnzymes.remove(enzyme); } /** * clearEnzymes removes all enzymes from those to be * searched for in the Sequence. */ public void clearEnzymes() { restrictionEnzymes.clear(); } }