/** * */ package outputter.process; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; import java.util.Set; import org.apache.log4j.Logger; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.xpath.XPath; import outputter.Utilities; import outputter.XML2EQ; import outputter.data.EQProposals; import outputter.data.Entity; import outputter.data.EntityProposals; import outputter.data.NegatedQuality; import outputter.data.Quality; import outputter.data.QualityProposals; import outputter.data.RelationalQuality; import outputter.knowledge.Dictionary; import outputter.knowledge.TermOutputerUtilities; import outputter.prep.XMLNormalizer; /** * @author updates * parse out Entities and Qualities, form EQ directly without access state statements as they are just binary values, i.e., T/F. (not two different vaules, but binary values) */ public class BinaryCharacterStatementParser extends StateStatementParser { private static final Logger LOGGER = Logger.getLogger(BinaryCharacterStatementParser.class); //public String characterlabel; private int binaryType = 0; /** * @param ontologyIRIs */ static XPath pathstructure; static XPath pathrelation; static{ try{ pathstructure = XPath.newInstance(".//structure"); pathrelation = XPath.newInstance(".//relation"); }catch(Exception e){ LOGGER.error("", e); } } public BinaryCharacterStatementParser(TermOutputerUtilities ontoutil, String characterlabel, int btype) { super(ontoutil, null, null,characterlabel); this.binaryType = btype; //this.characterlabel=characterlabel; } /** * @param statement: the character statement in a binary statement */ /*public void parse(Element statement, Element root){ ArrayList<EQStatementProposals> negativestatements = new ArrayList<EQStatementProposals>(); super.parseMetadata(statement, root); super.parseRelationsFormEQ(statement, root); super.parseCharactersFormEQ(statement, root); if(this.EQStatements.size()==0){ //try { //checkandfilterstructuredquality(statement,root);//checks standalone structure for quality values and detach them. parseStandaloneStructures(statement, root); //} catch (JDOMException e) { // TODO Auto-generated catch block // LOGGER.error("", e); //} } for(EQStatementProposals eqp: this.EQStatements){ for(EQStatement eq: eqp.getProposals()){ //update q for all eq candidates int flag=0;; Quality q = eq.getQuality(); if(q instanceof RelationalQuality) flag=1;// This will help us to print relational quality properly if(q==null){ //create q //q = "present" q = new Quality(); q.setString("present"); q.setLabel("PATO:present"); q.setId("PATO:0000467"); q.setConfidenceScore((float)1.0); eq.setQuality(q);//update q //create absent quality Quality absent = new Quality(); absent.setString("absent"); absent.setLabel("PATO:absent"); absent.setId("PATO:0000462"); absent.setConfidenceScore((float)1.0); EQStatement falseeq = eq.clone(); falseeq.setQuality(absent); EQStatementProposals negativeproposals = new EQStatementProposals(); negativeproposals.add(falseeq); negativestatements.add(negativeproposals); }else{ //generate negated quality if(flag==0) { if(q.getId()!=null) { @SuppressWarnings("static-access") String [] parentinfo = ontoutil.retreiveParentInfoFromPATO(q.getId()); if(parentinfo!=null) { Quality parentquality = new Quality(); parentquality.setString(parentinfo[1]); parentquality.setLabel(parentinfo[1]); parentquality.setId(parentinfo[0]); NegatedQuality nq = new NegatedQuality(q, parentquality); EQStatement falseeq = eq.clone(); falseeq.setQuality(nq); EQStatementProposals negativeproposals = new EQStatementProposals(); negativeproposals.add(falseeq); negativestatements.add(negativeproposals); } } } else { QualityProposals qp = ((RelationalQuality)q).relationalquality; EntityProposals relatedentity = ((RelationalQuality)q).relatedentity; QualityProposals nqp = new QualityProposals(); for(Quality q1:qp.proposals) { if(q1.getId()!=null) { @SuppressWarnings("static-access") String complementQuality = Dictionary.complementRelations.get(q1.getLabel()); if(complementQuality==null) { String [] parentinfo = ontoutil.retreiveParentInfoFromPATO(q1.getId()); if(parentinfo!=null) { Quality parentquality = new Quality(); parentquality.setString(parentinfo[1]); parentquality.setLabel(parentinfo[1]); parentquality.setId(parentinfo[0]); NegatedQuality nq = new NegatedQuality(q1, parentquality); nqp.proposals.add(nq); } } else { complementQuality = Utilities.removeprepositions(complementQuality); Hashtable<String,String> cq = Dictionary.relationalqualities.get(complementQuality); Set<String> keys = cq.keySet(); for(String key:keys) { Quality negated =new Quality(); negated.setLabel(key); negated.setId(cq.get(key)); negated.setString(key); nqp.proposals.add(negated); } } } } RelationalQuality rq = new RelationalQuality(nqp,relatedentity); EQStatement falseeq = eq.clone(); falseeq.setQuality(rq); EQStatementProposals negativeproposals = new EQStatementProposals(); negativeproposals.add(falseeq); negativestatements.add(negativeproposals); } } } } this.EQStatements.addAll(negativestatements); }*/ /** * A ventral_to B =>from super: E: A Q: ventral_to B * expected final results: * Yes: A, ventral_to B * No: A, not ventral_to B * * A ventral_to B =>E: A Q: ventral_to B * present: A ventral_to B, present * absent: A ventral_to B, absent * * red flowers =>E: red flowers Q: null * Yes: red flowers, present * No: red flowers, absent * * red flowers =>E: red flowers Q: null * present: red flowers, present * absent: red flowers, absent * * flowers red =>E: flowers Q: red * yes: flowers, red * no: flowers, not red * * flowers red =>E: flowers Q: red * present: flowers, red * absent: flowers, not red * * * @param statement a character statement that is a binary statement * @param root the root element of the parent xml document * @param posempty the postive EQProposals holding metadata and original text * @param negempty the negative EQProposals holding metadata and original text */ public void parse(Element statement, Element root, EQProposals posempty, EQProposals negempty){ ArrayList<EQProposals> negativestatements = new ArrayList<EQProposals>(); //super.parseMetadata(statement, root, posempty); super.parseRelationsFormEQ(statement, root, posempty); super.parseCharactersFormEQ(statement, root, posempty); if(this.EQStatements.size()==0){ parseStandaloneStructures(statement, root, posempty); } for(EQProposals eqp: this.EQStatements){ QualityProposals qp = eqp.getQuality(); if(qp==null){//no qp, create qp presentAbsentQuality(negempty, negativestatements, eqp); }else{//has q, generate and add negated quality for(Quality q: qp.getProposals()){ if(q instanceof RelationalQuality) //relational, generate and add negated quality { boolean postcomposed = false; // 1: present/absent; 2: yes/no if(this.binaryType==1) postcomposed = postcomposeRelationalQuality(negempty, negativestatements, eqp, q); if(this.binaryType==2 || !postcomposed) negateRelationalQuality(negempty, negativestatements, eqp, q); // a ventral to b: yes => }else{ //not relational, generate and add the negated quality negateQuality(negempty, negativestatements, eqp, q); } } } } //} this.EQStatements.addAll(negativestatements); //if(XML2EQ.isRecordperformance()) populateStateLabel(this.EQStatements,root); } /** * A ventral_to B =>E: A Q: ventral_to B * return: * present: A ventral_to B, present * absent: A ventral_to B, absent * * post-compose Q to Entities, update eqp, and add negated to the negative EQProposals * @param negativestatements * @param q * @return postcomposition success or not */ private boolean postcomposeRelationalQuality(EQProposals negempty, ArrayList<EQProposals> negativestatements, EQProposals eqp, Quality q) { ArrayList<EntityProposals> entities = new ArrayList<EntityProposals>(); if(eqp.getEntity()==null) return false; entities.add(eqp.getEntity()); ArrayList<QualityProposals> qualities = new ArrayList<QualityProposals>(); QualityProposals qp = new QualityProposals(); qp.add(q); qualities.add(qp); boolean success = Utilities.postcompose(entities, qualities); //postcompose if(!success) return success; //update eqp eqp.setEntity(entities.get(0)); qp = new QualityProposals(); qp.setPhrase("present"); Quality present = Dictionary.present; present.setSearchString(""); present.setString("present"); present.setConfidenceScore((float)1.0); qp.add(present); eqp.setQuality(qp);//update qp //create negaged qp = new QualityProposals(); qp.setPhrase("absent"); Quality absent = Dictionary.absent; present.setSearchString(""); present.setString("absent"); present.setConfidenceScore((float)1.0); qp.add(absent); EQProposals falseeq = eqp.clone(); falseeq.setStateId(negempty.getStateId()); falseeq.setStateText(negempty.getStateText()); falseeq.setQuality(qp); negativestatements.add(falseeq); return success; } private void presentAbsentQuality(EQProposals negempty, ArrayList<EQProposals> negativestatements, EQProposals eqp) { QualityProposals qp; //q = "present" qp = new QualityProposals(); Quality q = Dictionary.present; q.setSearchString(""); q.setString("present"); q.setConfidenceScore((float)1.0); qp.add(q); eqp.setQuality(qp);//update qp //check for any positive state statement present(yes,true etc.), if so assign that state to it //create absent quality Quality absent = Dictionary.absent; absent.setSearchString(""); absent.setString("absent"); absent.setConfidenceScore((float)1.0); qp = new QualityProposals(); qp.add(absent); EQProposals falseeq = eqp.clone(); falseeq.setStateId(negempty.getStateId()); falseeq.setStateText(negempty.getStateText()); falseeq.setQuality(qp); negativestatements.add(falseeq); //handle negative statements at the last } private void negateQuality(EQProposals negempty, ArrayList<EQProposals> negativestatements, EQProposals eqp, Quality q) { if(q.getId()!=null) { QualityProposals negativeqp = new QualityProposals(); String [] parentinfo = TermOutputerUtilities.retreiveParentInfoFromPATO(q.getId()); if(parentinfo!=null) { Quality parentquality = new Quality(); parentquality.setSearchString(""); parentquality.setString(parentinfo[1]); parentquality.setLabel(parentinfo[1]); parentquality.setId(parentinfo[0]); NegatedQuality nq = new NegatedQuality(q, parentquality); negativeqp.add(nq); EQProposals falseeq = eqp.clone(); falseeq.setQuality(negativeqp); falseeq.setStateId(negempty.getStateId()); falseeq.setStateText(negempty.getStateText()); negativestatements.add(falseeq); } } } private void negateRelationalQuality(EQProposals negempty, ArrayList<EQProposals> negativestatements, EQProposals eqp, Quality q) { QualityProposals negativeqp = new QualityProposals(); QualityProposals thisqp = ((RelationalQuality)q).getQuality(); EntityProposals relatedentity = ((RelationalQuality)q).getRelatedEntity(); QualityProposals nqp = new QualityProposals(); for(Quality q1:thisqp.getProposals()) { if(q1.getId()!=null) { String [] parentinfo = TermOutputerUtilities.retreiveParentInfoFromPATO(q1.getId()); if(parentinfo!=null) { Quality parentquality = new Quality(); parentquality.setSearchString(""); parentquality.setString(parentinfo[1]); parentquality.setLabel(parentinfo[1]); parentquality.setId(parentinfo[0]); NegatedQuality nq = new NegatedQuality(q1, parentquality); nqp.getProposals().add(nq); } } } RelationalQuality rq = new RelationalQuality(nqp,relatedentity); negativeqp.add(rq); EQProposals falseeq = eqp.clone(); falseeq.setQuality(negativeqp); falseeq.setStateId(negempty.getStateId()); falseeq.setStateText(negempty.getStateText()); negativestatements.add(falseeq); } /* * * This method populates the state statement for all binary statements * The first binary state statement id and label will be populated */ /* private void populateStateLabel(ArrayList<EQProposals> eqstatements,Element root) { try { Element state = (Element) XMLNormalizer.pathStateStatement.selectSingleNode(root); Element Text = (Element) XMLNormalizer.pathText.selectSingleNode(state); String stateid = state.getAttributeValue("state_id"); String text = Text.getTextTrim(); System.out.println(text); for(EQProposals eqp:eqstatements) { eqp.setDescription(text); eqp.setStateId(stateid); } } catch (JDOMException e) { e.printStackTrace(); } }*/ /* * * This method populates the state statement for all binary statements * */ @SuppressWarnings("unchecked") /*private void populateStateLabel(ArrayList<EQProposals> eqstatements,Element root) { try { List<Element> states = XMLNormalizer.pathStateStatement.selectNodes(root); Hashtable<String,String> binary = new Hashtable<String,String>(); //Stores the information about positive and negative states for (Element state : states) { Element text = (Element) pathText2.selectSingleNode(state); String value = text.getTextTrim(); if(value.matches("(" + Dictionary.binaryTvalues + ")")) { binary.put("positive", state.getAttributeValue("state_id")+"@@"+value); } if(value.matches("(" + Dictionary.binaryFvalues + ")")) { binary.put("negative", state.getAttributeValue("state_id")+"@@"+value); } } //Checks if the quality proposal is a negated quality or false values for(EQProposals eqp:eqstatements) { QualityProposals qp = eqp.getQuality(); for(Quality q:qp.getProposals()) { if((q!=null)&&(q.getLabel()!=null)) { if((q instanceof NegatedQuality)||(q.getLabel().matches(".*(" + Dictionary.binaryFvalues + ")"))) { eqp.setStateId(binary.get("negative")!=null?binary.get("negative").split("@@")[0]:(binary.get("positive")!=null?binary.get("positive").split("@@")[0]:"")); eqp.setStateText(binary.get("negative")!=null?binary.get("negative").split("@@")[1]:(binary.get("positive")!=null?binary.get("positive").split("@@")[1]:"")); break; }else { eqp.setStateId(binary.get("positive")!=null?binary.get("positive").split("@@")[0]:(binary.get("negative")!=null?binary.get("negative").split("@@")[0]:"")); eqp.setStateText(binary.get("positive")!=null?binary.get("positive").split("@@")[1]:(binary.get("negative")!=null?binary.get("negative").split("@@")[1]:"")); break; } } } } } catch (JDOMException e) { e.printStackTrace(); } }*/ /* private void populateStateLabel(ArrayList<EQProposals> eqstatements,Element root) { try { ArrayList<Element> states = (ArrayList<Element>) XMLNormalizer.pathStateStatement.selectNodes(root); String assigned=""; for(EQProposals eqp:eqstatements) { QualityProposals quality = eqp.getQuality(); for(Quality q:quality.proposals) { int flag=0; for(Element state:states) { Element Text = (Element) XMLNormalizer.pathText.selectSingleNode(state); String text = Text.getTextTrim(); if((assigned.equals("present")==false)||((text.matches("("+Dictionary.binaryTvalues +")")==true)&&(q.getLabel().matches("("+Dictionary.binaryTvalues +")")==true))) { eqp.setStateId(state.getAttributeValue("state_id")); eqp.setDescription(text); flag=1; assigned="present"; break; } if((assigned.equals("absent")==false)||(text.matches("("+Dictionary.binaryFvalues +")")==true)&&(q.getLabel().matches("("+Dictionary.binaryFvalues +")")==true))) { eqp.setStateId(state.getAttributeValue("state_id")); eqp.setDescription(text); assigned="absent"; flag=1; break; } } if(flag==1) break; } } } catch (JDOMException e) { e.printStackTrace(); } }*/ /** * construct EQstatement from standalone <structure>, as in "anal fin/absent|present" * @param statement * @param root */ private void parseStandaloneStructures(Element statement, Element root, EQProposals empty) { try{ ArrayList<EntityProposals> entities = new ArrayList<EntityProposals>(); ArrayList<Structure2Quality> s2qs = new ArrayList<Structure2Quality>(); String checked = ""; List<Element> structures = XMLNormalizer.pathNonWholeOrganismStructure.selectNodes(statement); ArrayList<String> RelatedStructures = new ArrayList<String>(); //keep a record on related entities, which should not be processed again for(Element structure: structures){ String structureid = structure.getAttributeValue("id"); if(!checked.contains(structureid+",")){ String parents = Utilities.getIdsOnPartOfChain(root, structureid); String structurename = Utilities.getStructureName(root, structureid); EntityParser ep = new EntityParser(statement, root, structureid, structurename, null, true); if(ep.getEntity()!=null) entities.addAll(ep.getEntity()); if(ep.getQualityStrategy()!=null) s2qs.add(ep.getQualityStrategy()); checked += structureid+","+parents+","; } } resolve(entities, s2qs, statement, root); //after resolution, entities holds good entities /*for(EntityProposals entityp: entities){ EQStatementProposals eqp= new EQStatementProposals(); for(Entity entity: entityp.getProposals()){ EQStatement eq = new EQStatement(); eq.setEntity(entity); eq.setSource(super.src); eq.setCharacterId(super.characterid); eq.setStateId(super.stateid); eq.setDescription(super.text); eq.setType("character"); eqp.add(eq); } this.EQStatements.add(eqp); }*/ for(EntityProposals entityp: entities){ //EQProposals eqp= new EQProposals(); EQProposals eqp= empty.clone(); eqp.setEntity(entityp); //eqp.setSource(super.src); //eqp.setCharacterId(super.characterid); //eqp.setStateId(super.stateid); eqp.setStateText(statement.getChildText("text")); eqp.setType("character"); //eqp.setCharacterlabel(super.characterlabel); this.EQStatements.add(eqp); } }catch(Exception e){ LOGGER.error("", e); } /*EntityParser ep = new EntityParser(statement, root, true); ArrayList<EntityProposals> entities = ep.getEntities(); for(EntityProposals entityp: entities){ EQStatementProposals eqp= new EQStatementProposals(); for(Entity entity: entityp.getProposals()){ EQStatement eq = new EQStatement(); eq.setEntity(entity); eq.setSource(super.src); eq.setCharacterId(super.characterid); eq.setStateId(super.stateid); eq.setDescription(super.text); eq.setType("character"); eqp.add(eq); //this.EQStatements.add(eq); } this.EQStatements.add(eqp); } */ } /** * TODO * 1. determine keyentities, post-compose entities with quality 2. approve/disapprove structure2quality results * 3. constructure EQ for non-key entities * @param entities * @param s2qs * @param statement * @param root */ private void resolve(ArrayList<EntityProposals> entities, ArrayList<Structure2Quality> s2qs, Element statement, Element root) { // TODO Auto-generated method stub //if a s2q is approved, use the quality and call s2q.cleanHandledStructures //Decision should be made based on confidence score } /*private void checkandfilterstructuredquality(Element statement,Element root) throws JDOMException { String structname; String structid; List<Element> structures = pathstructure.selectNodes(statement); //Get all the structures and individually check, if each are qualities for(Element structure:structures) { structname = structure.getAttributeValue("name"); structid = structure.getAttributeValue("id"); Structure2Quality rq = new Structure2Quality(root, structname, structid, null); rq.handle(); //If any structure is a quality detach all the structures containing the structure id if(rq.qualities.size()>0) structure.detach(); //no need to detach relations because the StateStatementParser was already called (the relations are handled there) } }*/ /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub } }