001package org.biopax.paxtools.pattern.constraint; 002 003import org.biopax.paxtools.pattern.Match; 004import org.biopax.paxtools.model.BioPAXElement; 005import org.biopax.paxtools.model.level3.Conversion; 006import org.biopax.paxtools.model.level3.ConversionDirectionType; 007import org.biopax.paxtools.model.level3.Interaction; 008import org.biopax.paxtools.model.level3.PhysicalEntity; 009import org.biopax.paxtools.pattern.util.Blacklist; 010import org.biopax.paxtools.pattern.util.RelType; 011 012import java.util.Collection; 013import java.util.HashSet; 014 015/** 016 * Gets the related Conversion where the PhysicalEntity is input or output, whichever is desired. 017 * 018 * var0 is a PE 019 * var1 is a Conversion 020 * 021 * @author Ozgun Babur 022 */ 023public class ParticipatesInConv extends ConstraintAdapter 024{ 025 /** 026 * Input or output. 027 */ 028 private RelType type; 029 030 /** 031 * Constructor with parameters. 032 * @param type input or output conversion 033 * @param blacklist for detecting blacklisted small molecules 034 */ 035 public ParticipatesInConv(RelType type, Blacklist blacklist) 036 { 037 super(2, blacklist); 038 this.type = type; 039 } 040 041 /** 042 * Constructor with parameters. 043 * @param type input or output 044 * conversion 045 */ 046 public ParticipatesInConv(RelType type) 047 { 048 this(type, null); 049 } 050 051 /** 052 * This is a generative constraint. 053 * @return true 054 */ 055 @Override 056 public boolean canGenerate() 057 { 058 return true; 059 } 060 061 /** 062 * Identifies the conversion direction and gets the related participants. 063 * @param match current pattern match 064 * @param ind mapped indices 065 * @return input or output participants 066 */ 067 @Override 068 public Collection<BioPAXElement> generate(Match match, int... ind) 069 { 070 Collection<BioPAXElement> result = new HashSet<BioPAXElement>(); 071 072 PhysicalEntity pe = (PhysicalEntity) match.get(ind[0]); 073 074 for (Interaction inter : pe.getParticipantOf()) 075 { 076 if (inter instanceof Conversion) 077 { 078 Conversion cnv = (Conversion) inter; 079 ConversionDirectionType dir = getDirection(cnv); 080 081 // do not get blacklisted small molecules 082 if (blacklist != null && blacklist.isUbique(pe, cnv, dir, type)) continue; 083 084 if (dir == ConversionDirectionType.REVERSIBLE) 085 { 086 result.add(cnv); 087 } 088 else if (dir == ConversionDirectionType.RIGHT_TO_LEFT && 089 (type == RelType.INPUT ? cnv.getRight().contains(pe) : cnv.getLeft().contains(pe))) 090 { 091 result.add(cnv); 092 } 093 // Note that null direction is treated as if LEFT_TO_RIGHT. This is not a best 094 // practice, but it is a good approximation. 095 else if ((dir == ConversionDirectionType.LEFT_TO_RIGHT || dir == null) && 096 (type == RelType.INPUT ? cnv.getLeft().contains(pe) : cnv.getRight().contains(pe))) 097 { 098 result.add(cnv); 099 } 100 } 101 } 102 103 return result; 104 } 105}