
org.biopax.paxtools.io.sif.level2.ControlRule Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sif-converter Show documentation
Show all versions of sif-converter Show documentation
Converts a BioPAX model to binary SIF (simple interaction format) or extended binary SIF by inferring the interactions in the model and describing them in terms of simple interactions. This includes a set of BioPAX-specific inference rules implemented on top of paxtools-core.
The newest version!
package org.biopax.paxtools.io.sif.level2;
import org.biopax.paxtools.io.sif.BinaryInteractionType;
import org.biopax.paxtools.io.sif.InteractionSet;
import org.biopax.paxtools.io.sif.SimpleInteraction;
import org.biopax.paxtools.model.Model;
import org.biopax.paxtools.model.level2.*;
import java.util.*;
import static org.biopax.paxtools.io.sif.BinaryInteractionType.METABOLIC_CATALYSIS;
import static org.biopax.paxtools.io.sif.BinaryInteractionType.STATE_CHANGE;
/**
* A controls a conversion which B is at left or right or both. -
* Controls.StateChange (B at both sides (one side may be as a member of a
* complex), or B is complex) - Controls.MetabolicChange (B at one side only)
* @author Ozgun Babur Date: Dec 29, 2007 Time: 1:27:55 AM
*/
public class ControlRule extends InteractionRuleL2Adaptor
{
/**
* Supported interaction types.
*/
private static List binaryInteractionTypes =
Arrays.asList(METABOLIC_CATALYSIS, STATE_CHANGE);
/**
* Option to mine METABOLIC_CHANGE type.
*/
private boolean mineMetabolicChange;
/**
* Option to mine STATE_CHANGE type.
*/
private boolean mineStateChange;
/**
* Initializes option.
* @param options options map
*/
@Override public void initOptionsNotNull(Map options)
{
mineStateChange = !options.containsKey(STATE_CHANGE) ||
options.get(STATE_CHANGE).equals(Boolean.TRUE);
mineMetabolicChange = !options.containsKey(METABOLIC_CATALYSIS) ||
options.get(METABOLIC_CATALYSIS).equals(Boolean.TRUE);
}
/**
* When options map is null, then all rules are generated. Otherwise only rules
* that are contained in the options map as a key are generated.
* @param interactionSet set to fill in
* @param A first physical entity
* @param model biopax graph - may be null, has no use here
*/
public void inferInteractionsFromPE(InteractionSet interactionSet, physicalEntity A, Model model)
{
// Iterate over all associated controls
for (control cont : A.getAllInteractions(control.class))
{
// Iterate over all affected conversions of this control
for (conversion conv : getAffectedConversions(cont, null))
{
Set presenceSet = collectEntities(conv.getLEFT(), null);
collectEntities(conv.getRIGHT(), presenceSet);
// Collect left and right simple physical entities of conversion in lists
List left = collectSimpleEntities(conv.getLEFT());
List right = collectSimpleEntities(conv.getRIGHT());
// Detect physical entities which appear on both sides.
List bothsided = new ArrayList();
for (physicalEntity B : left)
{
if (right.contains(B))
{
bothsided.add(B);
}
}
// Create simple interactions
// Try creating a rule for each physical entity in presence list.
for (physicalEntity B : presenceSet)
{
// Consider only molecules that is changed by the conversion
if (!entityHasAChange(B, conv))
{
continue;
}
// Affecting a complex is accepted as type of state change.
// If it is simple, then we check if it is also on both sides, regarding the
// possibility that it may be nested in a complex.
if (B instanceof complex || bothsided.contains(B))
{
if (mineStateChange)
{
SimpleInteraction sc = new SimpleInteraction(A, B, STATE_CHANGE);
sc.addMediator(cont);
sc.addMediator(conv);
interactionSet.add(sc);
}
}
// Else it is a simple molecule appearing on one side of conversion. This means
// it is metabolic change.
else
{
if (mineMetabolicChange)
{
SimpleInteraction mc = new SimpleInteraction(A, B, METABOLIC_CATALYSIS);
mc.addMediator(cont);
mc.addMediator(conv);
interactionSet.add(mc);
}
}
}
}
}
}
/**
* Creates a list of conversions on which this control has an effect. If the
* control controls another control, then it is traversed recursively to find
* the affected conversions.
* @param cont control
* @param convList list of affected conversions
* @return list of affected conversions
*/
private List getAffectedConversions(control cont, List convList)
{
if (convList == null)
{
convList = new ArrayList();
}
for (process prcss : cont.getCONTROLLED())
{
if (prcss instanceof conversion)
{
convList.add((conversion) prcss);
} else if (prcss instanceof control)
{
getAffectedConversions((control) prcss, convList);
}
}
return convList;
}
/**
* Collects the associated physical entities of the given participant set.
* @param partics participants
* @param peSet physical entity set to collect in
* @return associated physical entities
*/
private Set collectEntities(Set partics, Set peSet)
{
if (peSet == null)
{
peSet = new HashSet();
}
for (physicalEntityParticipant partic : partics)
{
peSet.add(partic.getPHYSICAL_ENTITY());
}
return peSet;
}
/**
* Collects the associated non-complex physical entities of the given
* participant set. This means we are not interested in complexes, but their
* members, at any nesting.
* @param partics participants
* @return associated physical entities
*/
private List collectSimpleEntities(Set partics)
{
List peList = new ArrayList();
for (physicalEntityParticipant partic : partics)
{
physicalEntity pe = partic.getPHYSICAL_ENTITY();
if (pe instanceof complex)
{
collectSimpleMembersOfComplex(peList, (complex) pe);
} else
{
peList.add(pe);
}
}
return peList;
}
/**
* Recursive method for collecting simple members of the given complex in the
* given list.
* @param list where to collect
* @param comp complex to collect members
*/
private void collectSimpleMembersOfComplex(List list, complex comp)
{
for (physicalEntityParticipant pep : comp.getCOMPONENTS())
{
physicalEntity pe = pep.getPHYSICAL_ENTITY();
if (pe instanceof complex)
{
collectSimpleMembersOfComplex(list, (complex) pe);
} else
{
list.add(pe);
}
}
}
/**
* Sometimes an entity is both an input and output to a conversion without any state change.
* Normally this phenomena should be modeled using controller property of conversion. In other
* cases this method detects entities that goes in and out without any change.
* @param entity entity to check
* @param conv conversion that the entity is participant
* @return true if entity has a change in conversion
*/
private boolean entityHasAChange(physicalEntity entity, conversion conv)
{
Set leftonly = new HashSet();
Set rightonly = new HashSet();
Set both = new HashSet();
for (physicalEntityParticipant pep : conv.getLEFT())
{
if (pep.getPHYSICAL_ENTITY() == entity)
{
leftonly.add(new StateWrapper(pep));
}
}
for (physicalEntityParticipant pep : conv.getRIGHT())
{
if (pep.getPHYSICAL_ENTITY() == entity)
{
StateWrapper sw = new StateWrapper(pep);
if (leftonly.contains(sw))
{
leftonly.remove(sw);
both.add(sw);
} else if (!both.contains(sw))
{
rightonly.add(sw);
}
}
}
return !leftonly.isEmpty() || !rightonly.isEmpty();
}
/**
* Gets supported interaction types.
* @return supported interaction types
*/
public List getRuleTypes()
{
return binaryInteractionTypes;
}
/**
* This wrapper is used for using state equality of participants in sets.
*/
private class StateWrapper
{
/**
* Wrapped participant.
*/
final physicalEntityParticipant pep;
/**
* Constructor with the wrapped participant.
* @param pep wrapped participant
*/
private StateWrapper(physicalEntityParticipant pep)
{
this.pep = pep;
}
/**
* Generates hash code for the state of the participant.
* @return hash code
*/
public int hashCode()
{
return pep.stateCode();
}
/**
* Checks if two participants are in equivalent state.
* @param obj other participant
* @return true if they are in equivalent state
*/
public boolean equals(Object obj)
{
if (obj instanceof StateWrapper)
{
StateWrapper sw = (StateWrapper) obj;
return pep.isInEquivalentState(sw.pep);
}
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy