/** * First step of overhang assignment - enforce numeric place holders for overhangs, ie no overhang * redundancy in any step * */ private void assignBioBricksOverhangs( ArrayList<RGraph> optimalGraphs, HashMap<Integer, Vector> stageVectors) { // Initialize fields that record information to save complexity for future steps _rootBasicNodeHash = new HashMap<RNode, ArrayList<RNode>>(); HashMap<Integer, RVector> stageRVectors = new HashMap<Integer, RVector>(); for (Integer stage : stageVectors.keySet()) { RVector vec = ClothoReader.vectorImportClotho(stageVectors.get(stage)); stageRVectors.put(stage, vec); } // If the stageVector hash is empty, make a new default vector if (stageRVectors.size() == 1) { if (stageRVectors.get(1) == null) { stageRVectors.put(0, new RVector("EX", "SP", -1, "pSK1A2", null)); } } // Loop through each optimal graph and grab the root node to prime for the traversal for (RGraph graph : optimalGraphs) { RNode root = graph.getRootNode(); RVector vector = stageRVectors.get(root.getStage() % stageRVectors.size()); RVector rootVector = new RVector("EX", "SP", -1, vector.getName(), null); root.setVector(rootVector); root.setLOverhang("EX"); root.setROverhang("SP"); ArrayList<RNode> l0nodes = new ArrayList<RNode>(); _rootBasicNodeHash.put(root, l0nodes); ArrayList<RNode> neighbors = root.getNeighbors(); assignBioBricksOverhangsHelper(root, neighbors, root, stageRVectors); } // Determine which nodes impact which level to form the stageDirectionAssignHash for (RGraph graph : optimalGraphs) { RNode root = graph.getRootNode(); ArrayList<String> rootDir = new ArrayList<String>(); ArrayList<String> direction = root.getDirection(); rootDir.addAll(direction); ArrayList<RNode> l0Nodes = _rootBasicNodeHash.get(root); // Determine which levels each basic node impacts for (int i = 0; i < l0Nodes.size(); i++) { // Determine direction of basic level 0 nodes RNode l0Node = l0Nodes.get(i); String l0Direction = rootDir.get(0); if (l0Node.getComposition().size() == 1) { ArrayList<String> l0Dir = new ArrayList<String>(); l0Dir.add(l0Direction); l0Node.setDirection(l0Dir); } int size = l0Node.getDirection().size(); rootDir.subList(0, size).clear(); } } }
/** Overhang scars helper * */ private ArrayList<String> assignScarsHelper(RNode parent, ArrayList<RNode> children) { ArrayList<String> scars = new ArrayList<String>(); // Loop through each one of the children to assign rule-instructed overhangs... enumerated // numbers currently for (int i = 0; i < children.size(); i++) { RNode child = children.get(i); if (i > 0) { if (child.getLOverhang().isEmpty()) { scars.add("_"); } scars.add("BB"); } // Make recursive call if (child.getStage() > 0) { // Remove the current parent from the list ArrayList<RNode> grandChildren = new ArrayList<RNode>(); grandChildren.addAll(child.getNeighbors()); if (grandChildren.contains(parent)) { grandChildren.remove(parent); } ArrayList<String> childScars = assignScarsHelper(child, grandChildren); scars.addAll(childScars); } else { ArrayList<String> childScars = new ArrayList<String>(); if (child.getComposition().size() > 1) { if (!child.getScars().isEmpty()) { childScars.addAll(child.getScars()); } else { for (int j = 0; j < child.getComposition().size() - 1; j++) { childScars.add("_"); } child.setScars(childScars); } } scars.addAll(childScars); } } // Keep scars for re-used parts with scars if (!scars.isEmpty()) { parent.setScars(scars); return scars; } else { return parent.getScars(); } }
/** * This helper method executes the loops necessary to enforce overhangs for each graph in * enforceOverhangRules * */ private void assignBioBricksOverhangsHelper( RNode parent, ArrayList<RNode> children, RNode root, HashMap<Integer, RVector> stageRVectors) { // Loop through each one of the children to assign rule-instructed overhangs... enumerated // numbers currently for (int i = 0; i < children.size(); i++) { RNode child = children.get(i); // Give biobricks overhangs RVector vector = stageRVectors.get(child.getStage() % stageRVectors.size()); RVector newVector = new RVector("EX", "SP", -1, vector.getName(), null); child.setVector(newVector); child.setLOverhang("EX"); child.setROverhang("SP"); // Make recursive call if (child.getStage() > 0) { ArrayList<RNode> grandChildren = new ArrayList<RNode>(); grandChildren.addAll(child.getNeighbors()); // Remove the current parent from the list if (grandChildren.contains(parent)) { grandChildren.remove(parent); } assignBioBricksOverhangsHelper(child, grandChildren, root, stageRVectors); // Or record the level zero parts } else { ArrayList<RNode> l0nodes = _rootBasicNodeHash.get(root); l0nodes.add(child); _rootBasicNodeHash.put(root, l0nodes); } } }