Java tutorial
/** * Copyright (c) 2009 International Health Terminology Standards Development * Organisation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.ihtsdo.classifier; import au.csiro.snorocket.core.IFactory_123; import au.csiro.snorocket.snapi.I_Snorocket_123.I_Callback; import au.csiro.snorocket.snapi.I_Snorocket_123.I_EquivalentCallback; import au.csiro.snorocket.snapi.Snorocket_123; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; import org.apache.log4j.Logger; import org.ihtsdo.classifier.model.*; import org.ihtsdo.classifier.utils.GetDescendants; import org.ihtsdo.classifier.utils.I_Constants; import java.io.*; import java.util.*; /** * The Class ClassificationRunner. * This class is responsible to classify stated relationships from RF2 format using snorocket reasoner. * Output results are inferred relationships composed of taxonomy and attributes. * Inferred relationships are saved in file which is a parameter of class constructor. * * @author Alejandro Rodriguez. * * @version 1.0 */ public class ClassificationRunner { /** The prev inferred rels. */ private List<String> previousInferredRelationships; /** The output tmp. */ private File tempRelationshipStore; private File config; public ClassificationRunner() { logger = Logger.getLogger("org.ihtsdo.classifier.ClassificationRunner"); } /** * Instantiates a new classification runner. * * @param module the module * @param releaseDate the release date * @param conceptFilePaths the concepts * @param statedRelationshipFilePaths the stated rels * @param previousInferredRelationshipFilePaths the prev inferred rels * @param inferredRelationshipOutputFilePath the output rels * @param equivalencyReportOutputFilePath the equiv concept file */ public ClassificationRunner(String module, String releaseDate, List<String> conceptFilePaths, List<String> statedRelationshipFilePaths, List<String> previousInferredRelationshipFilePaths, String inferredRelationshipOutputFilePath, String equivalencyReportOutputFilePath) { this(); this.module = module; this.releaseDate = releaseDate; this.concepts = conceptFilePaths; this.statedRelationships = statedRelationshipFilePaths; this.newInferredRelationships = inferredRelationshipOutputFilePath; this.equivalencyReport = equivalencyReportOutputFilePath; this.previousInferredRelationships = previousInferredRelationshipFilePaths; File outputFile = new File(newInferredRelationships); tempRelationshipStore = new File(outputFile.getParentFile(), "Tmp_" + outputFile.getName()); } /** * Instantiates a new classification runner. * * @param module the module * @param releaseDate the release date * @param concepts the concepts * @param statedRelationships the stated rels * @param previousInferredRelationships the prev inferred rels * @param newInferredRelationships the output rels * @param equivalencyReport the equiv concept file */ public ClassificationRunner(String module, String releaseDate, String[] concepts, String[] statedRelationships, String[] previousInferredRelationships, String newInferredRelationships, String equivalencyReport) { this(); this.module = module; this.releaseDate = releaseDate; this.concepts = new ArrayList<String>(); Collections.addAll(this.concepts, concepts); this.statedRelationships = new ArrayList<String>(); Collections.addAll(this.statedRelationships, statedRelationships); this.newInferredRelationships = newInferredRelationships; this.equivalencyReport = equivalencyReport; this.previousInferredRelationships = new ArrayList<String>(); Collections.addAll(this.previousInferredRelationships, previousInferredRelationships); File outputFile = new File(newInferredRelationships); tempRelationshipStore = new File(outputFile.getParentFile(), "Tmp_" + outputFile.getName()); } public ClassificationRunner(File config) throws ConfigurationException { this(); this.config = config; getParams(); File outputFile = new File(newInferredRelationships); tempRelationshipStore = new File(outputFile.getParentFile(), "Tmp_" + outputFile.getName()); } /** The edited snomed concepts. */ private ArrayList<StringIDConcept> cEditSnoCons; /** The edit snomed rels. */ private ArrayList<Relationship> cEditRelationships; /** The con ref list. */ private HashMap<Integer, String> conRefList; /** The con str list. */ private HashMap<String, Integer> conStrList; /** The logger. */ private Logger logger; /** The c rocket sno rels. */ private ArrayList<Relationship> cRocketRelationships; /** The isa. */ private Integer isa; /** The concept module. */ private HashMap<Integer, String> conceptModule; //params /** The module. */ private String module; /** The release date. */ private String releaseDate; /** The concepts. */ private List<String> concepts; /** The stated rels. */ private List<String> statedRelationships; /** The output rels. */ private String newInferredRelationships; /** The equiv concept file. */ private String equivalencyReport; /** The retired set. */ private HashSet<String> retiredSet; private XMLConfiguration xmlConfig; /** * Execute the classification. */ public void execute() throws IOException, ClassificationException { logger.info("\r\n::: [Test Snorocket] execute() -- begin"); cEditSnoCons = new ArrayList<StringIDConcept>(); cEditRelationships = new ArrayList<Relationship>(); conRefList = new HashMap<Integer, String>(); conStrList = new HashMap<String, Integer>(); loadConceptFilesTomap(concepts, false); HashSet<String> parentConcepts = new HashSet<String>(); parentConcepts.add(I_Constants.ATTRIBUTE_ROOT_CONCEPT); //concept model attribute int[] roles = getRoles(parentConcepts); int ridx = roles.length; if (roles.length > 100) { String errStr = "Role types exceeds 100. This will cause a memory issue. " + "Please check that role root is set to 'Concept mode attribute'"; logger.error(errStr); throw new ClassificationException(errStr); } final int reserved = 2; int cidx = reserved; int margin = cEditSnoCons.size() >> 2; // Add 50% int[] intArray = new int[cEditSnoCons.size() + margin + reserved]; intArray[IFactory_123.TOP_CONCEPT] = IFactory_123.TOP; intArray[IFactory_123.BOTTOM_CONCEPT] = IFactory_123.BOTTOM; Collections.sort(cEditSnoCons); if (cEditSnoCons.get(0).id <= Integer.MIN_VALUE + reserved) { throw new ClassificationException("::: SNOROCKET: TOP & BOTTOM nids NOT reserved"); } for (Concept sc : cEditSnoCons) { intArray[cidx++] = sc.id; } // Fill array to make binary search work correctly. Arrays.fill(intArray, cidx, intArray.length, Integer.MAX_VALUE); int root = conStrList.get(I_Constants.SNOMED_ROOT_CONCEPT); Snorocket_123 rocket_123 = new Snorocket_123(intArray, cidx, roles, ridx, root); // SnomedMetadata :: ISA isa = conStrList.get(GetDescendants.ISA_SCTID); rocket_123.setIsaNid(isa); // SnomedMetadata :: ROLE_ROOTS rocket_123.setRoleRoot(isa, true); // @@@ int roleRoot = conStrList.get(I_Constants.ATTRIBUTE_ROOT_CONCEPT); rocket_123.setRoleRoot(roleRoot, false); // SET DEFINED CONCEPTS for (int i = 0; i < cEditSnoCons.size(); i++) { if (cEditSnoCons.get(i).isDefined) { rocket_123.setConceptIdxAsDefined(i + reserved); } } cEditSnoCons = null; // :MEMORY: loadRelationshipFilesTomap(statedRelationships); // ADD RELATIONSHIPS Collections.sort(cEditRelationships); for (Relationship sr : cEditRelationships) { int err = rocket_123.addRelationship(sr.sourceId, sr.typeId, sr.destinationId, sr.group); if (err > 0) { StringBuilder sb = new StringBuilder(); if ((err & 1) == 1) { sb.append(" --UNDEFINED_C1-- "); } if ((err & 2) == 2) { sb.append(" --UNDEFINED_ROLE-- "); } if ((err & 4) == 4) { sb.append(" --UNDEFINED_C2-- "); } logger.info("\r\n::: " + sb /* :!!!: + dumpSnoRelStr(sr) */); } } cEditRelationships = null; // :MEMORY: conStrList = null; // :MEMORY: System.gc(); // RUN CLASSIFIER long startTime = System.currentTimeMillis(); logger.info("::: Starting Classifier... "); rocket_123.classify(); logger.info("::: Time to classify (ms): " + (System.currentTimeMillis() - startTime)); // GET CLASSIFER EQUIVALENTS logger.info("::: GET EQUIVALENT CONCEPTS..."); startTime = System.currentTimeMillis(); ProcessEquiv pe = new ProcessEquiv(); rocket_123.getEquivalents(pe); logger.info("\r\n::: [SnorocketMojo] ProcessEquiv() count=" + pe.countConSet + " time= " + toStringLapseSec(startTime)); pe.getEquivalentClasses(); EquivalentClasses.writeEquivConcept(pe.getEquivalentClasses(), equivalencyReport); // GET CLASSIFER RESULTS cRocketRelationships = new ArrayList<Relationship>(); logger.info("::: GET CLASSIFIER RESULTS..."); startTime = System.currentTimeMillis(); ProcessResults pr = new ProcessResults(cRocketRelationships); rocket_123.getDistributionFormRelationships(pr); logger.info("\r\n::: [SnorocketMojo] GET CLASSIFIER RESULTS count=" + pr.countRel + " time= " + toStringLapseSec(startTime)); pr = null; // :MEMORY: rocket_123 = null; // :MEMORY: System.gc(); System.gc(); // GET CLASSIFIER_PATH RELS startTime = System.currentTimeMillis(); cEditRelationships = new ArrayList<Relationship>(); cEditSnoCons = new ArrayList<StringIDConcept>(); conRefList = new HashMap<Integer, String>(); conStrList = new HashMap<String, Integer>(); loadConceptFilesTomap(concepts, true); cEditSnoCons = null; if (previousInferredRelationships != null && !previousInferredRelationships.isEmpty()) { loadRelationshipFilesTomap(previousInferredRelationships); } conStrList = null; // FILTER RELATIONSHIPS // int last = cEditRelationships.size(); // for (int idx = last - 1; idx > -1; idx--) { // if (Arrays.binarySearch(intArray, cEditRelationships.get(idx).destinationId) < 0) { // cEditRelationships.remove(idx); // } // } // WRITEBACK RESULTS startTime = System.currentTimeMillis(); if (previousInferredRelationships == null || !previousInferredRelationships.isEmpty()) { writeInferredRel(cRocketRelationships); } else { logger.info(compareAndWriteBack(cEditRelationships, cRocketRelationships)); logger.info("\r\n::: *** WRITEBACK *** LAPSED TIME =\t" + toStringLapseSec(startTime) + "\t ***"); consolidateRels(); } logger.info("\r\n::: *** WROTE *** LAPSED TIME =\t" + toStringLapseSec(startTime) + "\t ***"); } /** * Consolidate rels. * * @throws Exception the exception */ private void consolidateRels() throws IOException { FileOutputStream fos = new FileOutputStream(newInferredRelationships); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); BufferedWriter bw = new BufferedWriter(osw); FileInputStream rfis = new FileInputStream(tempRelationshipStore); InputStreamReader risr = new InputStreamReader(rfis, "UTF-8"); BufferedReader rbr = new BufferedReader(risr); String line; while ((line = rbr.readLine()) != null) { bw.append(line); bw.append("\r\n"); } rbr.close(); rbr = null; rfis = null; risr = null; String[] spl; for (String relFile : previousInferredRelationships) { rfis = new FileInputStream(relFile); risr = new InputStreamReader(rfis, "UTF-8"); rbr = new BufferedReader(risr); rbr.readLine(); while ((line = rbr.readLine()) != null) { spl = line.split("\t", -1); if (retiredSet.contains(spl[0])) { continue; } bw.append(line); bw.append("\r\n"); } rbr.close(); rbr = null; rfis = null; risr = null; } bw.close(); tempRelationshipStore.delete(); } /** * To string lapse sec. * * @param startTime the start time * @return the string */ private String toStringLapseSec(long startTime) { StringBuilder s = new StringBuilder(); long stopTime = System.currentTimeMillis(); long lapseTime = stopTime - startTime; s.append((float) lapseTime / 1000).append(" (seconds)"); return s.toString(); } /** * Gets the roles. * * @param parentConcepts the parent concepts * @return the roles * @throws Exception the exception */ private int[] getRoles(HashSet<String> parentConcepts) throws IOException, ClassificationException { HashSet<String> roles = new HashSet<String>(); for (String statedRel : statedRelationships) { File relationshipFile = new File(statedRel); GetDescendants getDesc = new GetDescendants(parentConcepts, relationshipFile, null); getDesc.execute(); roles.addAll(getDesc.getDescendants()); getDesc = null; } roles.add(GetDescendants.ISA_SCTID); int[] result = new int[roles.size()]; int resIdx = 0; for (String role : roles) { Integer integer = conStrList.get(role); if (integer != null) { result[resIdx] = integer; } else { throw new ClassificationException("No entry for " + role + " in conStrList."); } resIdx++; } roles = null; Arrays.sort(result); return result; } /** * Load concept files to map. * * @param concepts the concept file * @param mapToModule the map to module * @throws java.io.IOException Signals that an I/O exception has occurred. */ public void loadConceptFilesTomap(List<String> concepts, boolean mapToModule) throws IOException { if (mapToModule) { conceptModule = new HashMap<Integer, String>(); } int cont = Integer.MIN_VALUE + 3; String line; String[] spl; boolean definitionStatusId; for (String concept : concepts) { FileInputStream rfis = new FileInputStream(concept); InputStreamReader risr = new InputStreamReader(rfis, "UTF-8"); BufferedReader rbr = new BufferedReader(risr); rbr.readLine(); while ((line = rbr.readLine()) != null) { spl = line.split("\t", -1); if (!conStrList.containsKey(spl[0])) { cont++; conRefList.put(cont, spl[0]); conStrList.put(spl[0], cont); if (mapToModule) { if (spl[0].equals(I_Constants.META_SCTID)) { conceptModule.put(cont, module); } else { conceptModule.put(cont, spl[3]); } } if (spl[2].equals("1")) { definitionStatusId = (spl[4].equals(I_Constants.FULLY_DEFINED)); StringIDConcept conStr = new StringIDConcept(cont, spl[0], definitionStatusId); cEditSnoCons.add(conStr); } } } rbr.close(); rbr = null; } } /** * Load relationship files tomap. * * @param relationshipFiles the relationship file * @throws java.io.IOException Signals that an I/O exception has occurred. */ public void loadRelationshipFilesTomap(List<String> relationshipFiles) throws IOException, ClassificationException { String line; String[] spl; for (String relFile : relationshipFiles) { FileInputStream rfis = new FileInputStream(relFile); InputStreamReader risr = new InputStreamReader(rfis, "UTF-8"); BufferedReader rbr = new BufferedReader(risr); rbr.readLine(); while ((line = rbr.readLine()) != null) { spl = line.split("\t", -1); if (spl[2].equals("1") && (spl[8].equals(I_Constants.INFERRED) || spl[8].equals(I_Constants.STATED))) { Integer c1 = conStrList.get(spl[4]); Integer c2 = conStrList.get(spl[5]); Integer rg = Integer.parseInt(spl[6]); Integer ty = conStrList.get(spl[7]); if (c1 == null) { throw new ClassificationException("Relationship source concept missing:" + spl[4]); } else if (c2 == null) { throw new ClassificationException("Relationship destinationconcept missing:" + spl[5]); } else if (rg == null) { throw new ClassificationException("Relationship role type concept missing:" + rg); } else if (ty == null) { throw new ClassificationException("Relationship group concept missing:" + spl[7]); } else { Relationship rel = new Relationship(c1, c2, ty, rg, spl[0]); cEditRelationships.add(rel); } } } rbr.close(); rbr = null; } } /** * The Class ProcessResults. */ private class ProcessResults implements I_Callback { /** The snorels. */ private List<Relationship> snorels; /** The count rel. */ private int countRel = 0; // STATISTICS COUNTER /** * Instantiates a new process results. * * @param snorels the snorels */ public ProcessResults(List<Relationship> snorels) { this.snorels = snorels; this.countRel = 0; } /* (non-Javadoc) * @see au.csiro.snorocket.snapi.I_Snorocket_123.I_Callback#addRelationship(int, int, int, int) */ public void addRelationship(int conceptId1, int roleId, int conceptId2, int group) { countRel++; Relationship relationship = new Relationship(conceptId1, conceptId2, roleId, group); snorels.add(relationship); if (countRel % 25000 == 0) { // ** GUI: ProcessResults logger.info("rels processed " + countRel); } } } /** * The Class ProcessEquiv. */ private class ProcessEquiv implements I_EquivalentCallback { /** The count con set. */ private int countConSet = 0; // STATISTICS COUNTER /** The equiv concept. */ private EquivalentClasses equivalentClasses; /** * Instantiates a new process equiv. */ public ProcessEquiv() { equivalentClasses = new EquivalentClasses(); } /* (non-Javadoc) * @see au.csiro.snorocket.snapi.I_Snorocket_123.I_EquivalentCallback#equivalent(java.util.ArrayList) */ public void equivalent(ArrayList<Integer> equivalentConcepts) { equivalentClasses.add(new ConceptGroup(equivalentConcepts)); countConSet += 1; } /** * Gets the equiv concept. * * @return the equiv concept */ public EquivalentClasses getEquivalentClasses() { return equivalentClasses; } } /** * Write inferred rel. * * @param infRels the inf rels * @throws java.io.IOException Signals that an I/O exception has occurred. */ private void writeInferredRel(List<Relationship> infRels) throws IOException { // STATISTICS COUNTERS int countConSeen = 0; FileOutputStream fos = new FileOutputStream(newInferredRelationships); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); BufferedWriter bw = new BufferedWriter(osw); bw.append("id"); bw.append("\t"); bw.append("effectiveTime"); bw.append("\t"); bw.append("active"); bw.append("\t"); bw.append("moduleId"); bw.append("\t"); bw.append("sourceId"); bw.append("\t"); bw.append("destinationId"); bw.append("\t"); bw.append("relationshipGroup"); bw.append("\t"); bw.append("typeId"); bw.append("\t"); bw.append("characteristicTypeId"); bw.append("\t"); bw.append("modifierId"); bw.append("\r\n"); Collections.sort(infRels); // Typically, B is the SnoRocket Results Set (for newly inferred) Iterator<Relationship> itRel = infRels.iterator(); Relationship infRel = null; boolean done = false; if (itRel.hasNext()) { infRel = itRel.next(); } else { done = true; } // BY SORT ORDER, LOWER NUMBER ADVANCES FIRST while (!done) { if (++countConSeen % 25000 == 0) { logger.info("::: [Snorocket] write inferred rels @ #\t" + countConSeen); } writeRel(bw, infRel); if (itRel.hasNext()) { infRel = itRel.next(); } else { done = true; } } bw.close(); bw = null; osw = null; fos = null; } /** * Write rel. * * @param bw the bw * @param infRel the inf rel * @throws java.io.IOException Signals that an I/O exception has occurred. */ private void writeRel(BufferedWriter bw, Relationship infRel) throws IOException { String moduleC1 = conceptModule.get(infRel.sourceId); if (moduleC1 == null) { moduleC1 = module; } writeRF2TypeLine(bw, "null", releaseDate, "1", moduleC1, conRefList.get(infRel.sourceId), conRefList.get(infRel.destinationId), infRel.group, conRefList.get(infRel.typeId), I_Constants.INFERRED, I_Constants.SOMEMODIFIER); } /** * Write r f2 type line. * * @param bw the bw * @param relationshipId the relationship id * @param effectiveTime the effective time * @param active the active * @param moduleId the module id * @param sourceId the source id * @param destinationId the destination id * @param relationshipGroup the relationship group * @param relTypeId the rel type id * @param characteristicTypeId the characteristic type id * @param modifierId the modifier id * @throws java.io.IOException Signals that an I/O exception has occurred. */ public void writeRF2TypeLine(BufferedWriter bw, String relationshipId, String effectiveTime, String active, String moduleId, String sourceId, String destinationId, int relationshipGroup, String relTypeId, String characteristicTypeId, String modifierId) throws IOException { bw.append(relationshipId + "\t" + effectiveTime + "\t" + active + "\t" + moduleId + "\t" + sourceId + "\t" + destinationId + "\t" + relationshipGroup + "\t" + relTypeId + "\t" + characteristicTypeId + "\t" + modifierId); bw.append("\r\n"); } /** * Compare and write back. * * @param snorelA the snorel a * @param snorelB the snorel b * @return the string * @throws java.io.IOException Signals that an I/O exception has occurred. */ private String compareAndWriteBack(List<Relationship> snorelA, List<Relationship> snorelB) throws IOException { retiredSet = new HashSet<String>(); // STATISTICS COUNTERS int countConSeen = 0; int countSame = 0; int countSameISA = 0; int countA_Diff = 0; int countA_DiffISA = 0; int countA_Total = 0; int countB_Diff = 0; int countB_DiffISA = 0; int countB_Total = 0; FileOutputStream fos = new FileOutputStream(tempRelationshipStore); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); BufferedWriter bw = new BufferedWriter(osw); bw.append("id"); bw.append("\t"); bw.append("effectiveTime"); bw.append("\t"); bw.append("active"); bw.append("\t"); bw.append("moduleId"); bw.append("\t"); bw.append("sourceId"); bw.append("\t"); bw.append("destinationId"); bw.append("\t"); bw.append("relationshipGroup"); bw.append("\t"); bw.append("typeId"); bw.append("\t"); bw.append("characteristicTypeId"); bw.append("\t"); bw.append("modifierId"); bw.append("\r\n"); long startTime = System.currentTimeMillis(); Collections.sort(snorelA); Collections.sort(snorelB); // Typically, A is the Classifier Path (for previously inferred) // Typically, B is the SnoRocket Results Set (for newly inferred) Iterator<Relationship> itA = snorelA.iterator(); Iterator<Relationship> itB = snorelB.iterator(); Relationship rel_A = null; boolean done_A = false; if (itA.hasNext()) { rel_A = itA.next(); } else { done_A = true; } Relationship rel_B = null; boolean done_B = false; if (itB.hasNext()) { rel_B = itB.next(); } else { done_B = true; } logger.info("\r\n::: [SnorocketMojo]" + "\r\n::: snorelA.size() = \t" + snorelA.size() + "\r\n::: snorelB.size() = \t" + snorelB.size()); // BY SORT ORDER, LOWER NUMBER ADVANCES FIRST while (!done_A && !done_B) { if (++countConSeen % 25000 == 0) { logger.info("::: [SnorocketMojo] compareAndWriteBack @ #\t" + countConSeen); } if (rel_A.sourceId == rel_B.sourceId) { // COMPLETELY PROCESS ALL C1 FOR BOTH IN & OUT // PROCESS C1 WITH GROUP == 0 int thisC1 = rel_A.sourceId; // PROCESS WHILE BOTH HAVE GROUP 0 while (rel_A.sourceId == thisC1 && rel_B.sourceId == thisC1 && rel_A.group == 0 && rel_B.group == 0 && !done_A && !done_B) { // PROGESS GROUP ZERO switch (compareSnoRel(rel_A, rel_B)) { case 1: // SAME // GATHER STATISTICS countA_Total++; countB_Total++; countSame++; // NOTHING TO WRITE IN THIS CASE if (rel_A.typeId == isa) { countSameISA++; } if (itA.hasNext()) { rel_A = itA.next(); } else { done_A = true; } if (itB.hasNext()) { rel_B = itB.next(); } else { done_B = true; } break; case 2: // REL_A > REL_B -- B has extra stuff // WRITEBACK REL_B (Classifier Results) AS CURRENT countB_Diff++; countB_Total++; if (rel_B.typeId == isa) { countB_DiffISA++; } writeRel(bw, rel_B); if (itB.hasNext()) { rel_B = itB.next(); } else { done_B = true; } break; case 3: // REL_A < REL_B -- A has extra stuff // WRITEBACK REL_A (Classifier Input) AS RETIRED // GATHER STATISTICS countA_Diff++; countA_Total++; if (rel_A.typeId == isa) { countA_DiffISA++; } writeBackRetired(bw, rel_A); if (itA.hasNext()) { rel_A = itA.next(); } else { done_A = true; } break; } // switch } // REMAINDER LIST_A GROUP 0 FOR C1 while (rel_A.sourceId == thisC1 && rel_A.group == 0 && !done_A) { countA_Diff++; countA_Total++; if (rel_A.typeId == isa) { countA_DiffISA++; } writeBackRetired(bw, rel_A); if (itA.hasNext()) { rel_A = itA.next(); } else { done_A = true; break; } } // REMAINDER LIST_B GROUP 0 FOR C1 while (rel_B.sourceId == thisC1 && rel_B.group == 0 && !done_B) { countB_Diff++; countB_Total++; if (rel_B.typeId == isa) { countB_DiffISA++; } writeRel(bw, rel_B); if (itB.hasNext()) { rel_B = itB.next(); } else { done_B = true; break; } } // ** SEGMENT GROUPS ** RelationshipGroupList groupList_A = new RelationshipGroupList(); RelationshipGroupList groupList_B = new RelationshipGroupList(); RelationshipGroup groupA = null; RelationshipGroup groupB = null; // SEGMENT GROUPS IN LIST_A int prevGroup = Integer.MIN_VALUE; while (rel_A.sourceId == thisC1 && !done_A) { if (rel_A.group != prevGroup) { groupA = new RelationshipGroup(); groupList_A.add(groupA); } groupA.add(rel_A); prevGroup = rel_A.group; if (itA.hasNext()) { rel_A = itA.next(); } else { done_A = true; } } // SEGMENT GROUPS IN LIST_B prevGroup = Integer.MIN_VALUE; while (rel_B.sourceId == thisC1 && !done_B) { if (rel_B.group != prevGroup) { groupB = new RelationshipGroup(); groupList_B.add(groupB); } groupB.add(rel_B); prevGroup = rel_B.group; if (itB.hasNext()) { rel_B = itB.next(); } else { done_B = true; } } // FIND GROUPS IN GROUPLIST_A WITHOUT AN EQUAL IN GROUPLIST_B // WRITE THESE GROUPED RELS AS "RETIRED" RelationshipGroupList groupList_NotEqual; if (groupList_A.size() > 0) { groupList_NotEqual = groupList_A.whichNotEqual(groupList_B); for (RelationshipGroup sg : groupList_NotEqual) { for (Relationship sr_A : sg) { writeBackRetired(bw, sr_A); } } countA_Total += groupList_A.countRels(); countA_Diff += groupList_NotEqual.countRels(); } // FIND GROUPS IN GROUPLIST_B WITHOUT AN EQUAL IN GROUPLIST_A // WRITE THESE GROUPED RELS AS "NEW, CURRENT" int rgNum = 0; // USED TO DETERMINE "AVAILABLE" ROLE GROUP NUMBERS if (groupList_B.size() > 0) { groupList_NotEqual = groupList_B.whichNotEqual(groupList_A); for (RelationshipGroup sg : groupList_NotEqual) { if (sg.get(0).group != 0) { rgNum = nextRoleGroupNumber(groupList_A, rgNum); for (Relationship sr_B : sg) { sr_B.group = rgNum; writeRel(bw, sr_B); } } else { for (Relationship sr_B : sg) { writeRel(bw, sr_B); } } } countB_Total += groupList_A.countRels(); countB_Diff += groupList_NotEqual.countRels(); } } else if (rel_A.sourceId > rel_B.sourceId) { // CASE 2: LIST_B HAS CONCEPT NOT IN LIST_A // COMPLETELY *ADD* ALL THIS C1 FOR REL_B AS NEW, CURRENT int thisC1 = rel_B.sourceId; while (rel_B.sourceId == thisC1) { countB_Diff++; countB_Total++; if (rel_B.typeId == isa) { countB_DiffISA++; } writeRel(bw, rel_B); if (itB.hasNext()) { rel_B = itB.next(); } else { done_B = true; break; } } } else { // CASE 3: LIST_A HAS CONCEPT NOT IN LIST_B // COMPLETELY *RETIRE* ALL THIS C1 FOR REL_A int thisC1 = rel_A.sourceId; while (rel_A.sourceId == thisC1) { countA_Diff++; countA_Total++; if (rel_A.typeId == isa) { countA_DiffISA++; } writeBackRetired(bw, rel_A); if (itA.hasNext()) { rel_A = itA.next(); } else { done_A = true; break; } } } } // AT THIS POINT, THE PREVIOUS C1 HAS BE PROCESSED COMPLETELY // AND, EITHER REL_A OR REL_B HAS BEEN COMPLETELY PROCESSED // AND, ANY REMAINDER IS ONLY ON REL_LIST_A OR ONLY ON REL_LIST_B // AND, THAT REMAINDER HAS A "STANDALONE" C1 VALUE // THEREFORE THAT REMAINDER WRITEBACK COMPLETELY // AS "NEW CURRENT" OR "OLD RETIRED" // // LASTLY, IF .NOT.DONE_A THEN THE NEXT REL_A IN ALREADY IN PLACE while (!done_A) { countA_Diff++; countA_Total++; if (rel_A.typeId == isa) { countA_DiffISA++; } // COMPLETELY UPDATE ALL REMAINING REL_A AS RETIRED writeBackRetired(bw, rel_A); if (itA.hasNext()) { rel_A = itA.next(); } else { done_A = true; break; } } while (!done_B) { countB_Diff++; countB_Total++; if (rel_B.typeId == isa) { countB_DiffISA++; } // COMPLETELY UPDATE ALL REMAINING REL_B AS NEW, CURRENT writeRel(bw, rel_B); if (itB.hasNext()) { rel_B = itB.next(); } else { done_B = true; break; } } bw.close(); bw = null; osw = null; fos = null; // CHECKPOINT DATABASE StringBuilder s = new StringBuilder(); s.append("\r\n::: [Snorocket] compareAndWriteBack()"); long lapseTime = System.currentTimeMillis() - startTime; s.append("\r\n::: [Time] Sort/Compare Input & Output: \t").append(lapseTime); s.append("\t(mS)\t").append(((float) lapseTime / 1000) / 60).append("\t(min)"); s.append("\r\n"); s.append("\r\n::: "); s.append("\r\n::: countSame: \t").append(countSame); s.append("\r\n::: countSameISA: \t").append(countSameISA); s.append("\r\n::: A == Classifier Output Path"); s.append("\r\n::: countA_Diff: \t").append(countA_Diff); s.append("\r\n::: countA_DiffISA:\t").append(countA_DiffISA); s.append("\r\n::: countA_Total: \t").append(countA_Total); s.append("\r\n::: B == Classifier Solution Set"); s.append("\r\n::: countB_Diff: \t").append(countB_Diff); s.append("\r\n::: countB_DiffISA:\t").append(countB_DiffISA); s.append("\r\n::: countB_Total: \t").append(countB_Total); s.append("\r\n::: "); return s.toString(); } /** * Write back retired. * * @param bw the bw * @param rel_A the rel_ a * @throws java.io.IOException Signals that an I/O exception has occurred. */ private void writeBackRetired(BufferedWriter bw, Relationship rel_A) throws IOException { retiredSet.add(rel_A.getRelId()); String moduleC1 = conceptModule.get(rel_A.sourceId); if (moduleC1 == null) { moduleC1 = module; } writeRF2TypeLine(bw, rel_A.getRelId(), releaseDate, "0", moduleC1, conRefList.get(rel_A.sourceId), conRefList.get(rel_A.destinationId), rel_A.group, conRefList.get(rel_A.typeId), I_Constants.INFERRED, I_Constants.SOMEMODIFIER); } /** * Compare sno rel. * * @param inR the in r * @param outR the out r * @return the int */ private static int compareSnoRel(Relationship inR, Relationship outR) { if ((inR.sourceId == outR.sourceId) && (inR.group == outR.group) && (inR.typeId == outR.typeId) && (inR.destinationId == outR.destinationId)) { return 1; // SAME } else if (inR.sourceId > outR.sourceId) { return 2; // ADDED } else if ((inR.sourceId == outR.sourceId) && (inR.group > outR.group)) { return 2; // ADDED } else if ((inR.sourceId == outR.sourceId) && (inR.group == outR.group) && (inR.typeId > outR.typeId)) { return 2; // ADDED } else if ((inR.sourceId == outR.sourceId) && (inR.group == outR.group) && (inR.typeId == outR.typeId) && (inR.destinationId > outR.destinationId)) { return 2; // ADDED } else { return 3; // DROPPED } } // compareSnoRel /** * Next role group number. * * @param sgl the sgl * @param gnum the gnum * @return the int */ private static int nextRoleGroupNumber(RelationshipGroupList sgl, int gnum) { int testNum = gnum + 1; int sglSize = sgl.size(); int trial = 0; while (trial <= sglSize) { boolean exists = false; for (int i = 0; i < sglSize; i++) { if (sgl.get(i).get(0).group == testNum) { exists = true; } } if (exists == false) { return testNum; } else { testNum++; trial++; } } return testNum; } @SuppressWarnings("unchecked") private void getParams() throws ConfigurationException { try { xmlConfig = new XMLConfiguration(config); } catch (ConfigurationException e) { logger.info("ClassificationRunner - Error happened getting params file." + e.getMessage()); throw e; } this.module = xmlConfig.getString(I_Constants.MODULEID); this.releaseDate = xmlConfig.getString(I_Constants.RELEASEDATE); this.equivalencyReport = xmlConfig.getString(I_Constants.EQUIVALENT_CONCEPTS_OUTPUT_FILE); this.newInferredRelationships = xmlConfig.getString(I_Constants.INFERRED_RELATIONSHIPS_OUTPUT_FILE); concepts = xmlConfig.getList(I_Constants.CONCEPT_SNAPSHOT_FILES); statedRelationships = xmlConfig.getList(I_Constants.RELATIONSHIP_SNAPSHOT_FILES); previousInferredRelationships = xmlConfig.getList(I_Constants.PREVIOUS_INFERRED_RELATIONSHIP_FILES); logger.info("Classification - Parameters:"); logger.info("Module = " + module); logger.info("Release date = " + releaseDate); logger.info("Equivalent Concept Output file = " + equivalencyReport); logger.info("Previous Inferred Relationship file = " + previousInferredRelationships); logger.info("Inferred Relationship Output file = " + newInferredRelationships); logger.info("Concept files : "); for (String concept : concepts) { logger.info(concept); } logger.info("Stated Relationship files : "); for (String relFile : statedRelationships) { logger.info(relFile); } logger.info("Previous Relationship files : "); if (previousInferredRelationships != null) { for (String relFile : previousInferredRelationships) { logger.info(relFile); } } } }