package nloc; import java.util.List; import java.util.ArrayList; import java.util.ListIterator; import java.util.Arrays; public class Nloc { public static final int MIN_TIMEDIFF = 0; private List<Channel> chanlist; private List<Droplet> dropletList; public Nloc (List<Channel> chanlist) { this.chanlist = chanlist; this.dropletList = new ArrayList<Droplet>(); } // public void addChannel(Channel chan) { // chanlist.add(chan); // } // public void addChannel(Channel chan) { chanlist.add(chan); } public Sink getSink() { Sink sink = null; for (Channel chan : chanlist) { if (chan instanceof Sink) sink = (Sink)chan; } return sink; } public Pump getPump() { Pump pump = null; for (Channel chan : chanlist) { if (chan instanceof Pump) pump = (Pump)chan; } return pump; } public boolean simulate() { boolean works = true; while (!allDropletsInSink()) { try { this.moveDroplets(); } catch (CoalescedDropletException e) { works = false; System.out.println(e.getDroplet()); break; } } return works; } public List<Droplet> getDropletList() { return dropletList; } public void moveDroplets() throws CoalescedDropletException { for (Droplet dr : dropletList) { dr.move(); } for (Droplet dr: dropletList) { if (dr.coalesce()) throw new CoalescedDropletException(dr); } } public List<Channel> getBifurcationList(List<Channel> desiredPath) { List<Channel> bfList = new ArrayList<Channel>(); for (Channel ch: desiredPath) { if (ch.isBifurcation()) { bfList.add(ch); } } return bfList; } public static int getPayloadPathlength(List<Channel> path) { int len = 0; for (Channel ch: path) { len += ch.getPSteps(); } return len; } public static int getHeaderPathlength(List<Channel> path) { int len = 0; for (Channel ch: path) { len += ch.getHSteps(); } return len; } public boolean allDropletsInSink() { boolean allInSink = true; for (Droplet dr : dropletList) { allInSink &= dr.isInSink(); } return allInSink; } public List<Channel> getDesiredPath(List<Channel> modules, List<List<Channel>> pathlist) throws NlocStructureException { List<Channel> found = new ArrayList<Channel>(); for (List<Channel> path : pathlist) { List<Channel> modlist = new ArrayList<Channel>(); for (Channel ch: path) { if (ch instanceof Module) { modlist.add(ch); } } if (modules.equals(modlist) && found.isEmpty()) { found = path; } else if (modules.equals(modlist) && !found.isEmpty()) { throw new NlocStructureException("Paths are not unique!"); } } if (found.isEmpty()) { throw new NlocStructureException("No path found that covers all given Modules"); } return found; } public Channel getModuleByName(String name) { Channel found = null; for (Channel ch: chanlist) { if (ch.getName().equals(name)) { found = ch; } } return found; } public List<Channel> getModulesByName(List<String> names) { List<Channel> ret = new ArrayList<Channel>(); for (String name : names) { Channel ch = getModuleByName(name); if (name != null) { ret.add(ch); } } return ret; } public List<List<Channel>> getAllPathsFromTo(Channel from, Channel to) { List<List<Channel>> pl = new ArrayList<List<Channel>>(); List<Channel> path = new ArrayList<Channel>(); getAllPathsRecursive(from, to, path, pl); return pl; } public List<List<Channel>> getAllPaths() { List<List<Channel>> pl = new ArrayList<List<Channel>>(); List<Channel> path = new ArrayList<Channel>(); getAllPathsRecursive(this.getPump(), this.getSink(), path, pl); return pl; } private void getAllPathsRecursive(Channel chan, Channel end, List<Channel> path, List<List<Channel>> pathlist) { path.add(chan); if (chan.equals(end)) { pathlist.add(path); } else { for (Channel ch : chan.getChildrenList()) { getAllPathsRecursive(ch, end, new ArrayList<Channel>(path), pathlist); } } } //public List<List<SequenceTuple>> getSequencesAtBifurcation( // List<SequenceTuple> seqTup, SequenceTuple currentSeqTup, // Channel currentBifurcation) { public List<List<SequenceTuple>> getSequencesAtBifurcation( List<SequenceTuple> seqTup, Channel currentBifurcation) { List<List<SequenceTuple>> seqTupList = new ArrayList<List<SequenceTuple>>(); SequenceTuple currentSeqTup = seqTup.get(0); getSequencesAtBifurcationRecursive(seqTup, currentSeqTup, seqTupList, currentBifurcation); return seqTupList; } private void getSequencesAtBifurcationRecursive( List<SequenceTuple> seqTupList, SequenceTuple currentSeqTup, List<List<SequenceTuple>> possibleSequences, Channel currentBifurcation) { // check if header droplet is needed List<Channel> dropletPath = currentSeqTup.getPath(); Channel bifurcSuccessor = dropletPath.get(dropletPath.indexOf(currentBifurcation) + 1); // bifurcation priority: prio = 0 if default channel; prio >= 1 if not // default and threrfore header droplet needed int prio = currentBifurcation.getChildrenList().indexOf(bifurcSuccessor); if (currentSeqTup.equals(seqTupList.get(seqTupList.size() - 1))) { // if at last sequence tuple add another header droplet tuple if needed // and add the list of sequence tuples to the possible sequences list if (dropletPath.contains(currentBifurcation) && prio > 0) { System.out.println("At last sequence tuple and adding header droplet(s) to: " + currentSeqTup.getDroplet().getName() + ": " + currentSeqTup.getMinPos()); System.out.println(""); // we need header droplet // cirst check all possible paths of header droplets Channel defaultChan = currentBifurcation.getChildrenList().get(0); List<List<Channel>> pathList = this.getAllPathsFromTo(dropletPath.get(0), defaultChan); for (List<Channel> path: pathList) { List<SequenceTuple> tmp = new ArrayList<SequenceTuple>(seqTupList); SequenceTuple tmpTuple = new SequenceTuple(new Droplet(DropletType.HEADER,"h"),path); tmp.add(tmpTuple); // calculate and set pump offsets int minPos = currentSeqTup.getMinPos(); int maxPos = currentSeqTup.getMaxPos(); List<Channel> pathToCurrentBifurcation = dropletPath.subList(0,dropletPath.indexOf(currentBifurcation) + 1); int pathLenCurrDroplet = 0; if (currentSeqTup.getDroplet().getType() == DropletType.HEADER) { pathLenCurrDroplet = getHeaderPathlength(pathToCurrentBifurcation); } else { pathLenCurrDroplet = getPayloadPathlength(pathToCurrentBifurcation); } int maxPathLenNewDroplet = getHeaderPathlength(path); int minPathLenNewDroplet = maxPathLenNewDroplet - defaultChan.getHSteps() + 1; //System.out.println("minPos: " + minPos + " pathLenCurrDroplet: " + // pathLenCurrDroplet + " minPathLenNewDroplet: " + minPathLenNewDroplet); int newTupleMinPos = minPos - (pathLenCurrDroplet - minPathLenNewDroplet); int newTupleMaxPos = maxPos - (pathLenCurrDroplet - minPathLenNewDroplet); tmpTuple.setMinPos(newTupleMinPos); tmpTuple.setMaxPos(newTupleMaxPos); possibleSequences.add(tmp); } } else { System.out.println("At last sequence tuple and NOT adding header droplet(s) to: " + currentSeqTup.getDroplet().getName() + ": " + currentSeqTup.getMinPos()); System.out.println(""); possibleSequences.add(seqTupList); } } else { // TODO if (dropletPath.contains(currentBifurcation) && prio > 0) { System.out.println("NOT at last sequence tuple and "); System.out.println("Adding header droplet(s) to: " + currentSeqTup.getDroplet().getName() + ": " + currentSeqTup.getMinPos()); System.out.println(""); // we need header droplet // cirst check all possible paths of header droplets Channel defaultChan = currentBifurcation.getChildrenList().get(0); List<List<Channel>> pathList = this.getAllPathsFromTo(dropletPath.get(0), defaultChan); for (List<Channel> path: pathList) { List<SequenceTuple> tmp = new ArrayList<SequenceTuple>(seqTupList); SequenceTuple tmpTuple = new SequenceTuple(new Droplet(DropletType.HEADER,"h"),path); tmp.add(seqTupList.indexOf(currentSeqTup) + 1, tmpTuple); // calculate and set pump offsets int minPos = currentSeqTup.getMinPos(); int maxPos = currentSeqTup.getMaxPos(); List<Channel> pathToCurrentBifurcation = dropletPath.subList(0,dropletPath.indexOf(currentBifurcation) + 1); int pathLenCurrDroplet = 0; if (currentSeqTup.getDroplet().getType() == DropletType.HEADER) { pathLenCurrDroplet = getHeaderPathlength(pathToCurrentBifurcation); } else { pathLenCurrDroplet = getPayloadPathlength(pathToCurrentBifurcation); } int maxPathLenNewDroplet = getHeaderPathlength(path); int minPathLenNewDroplet = maxPathLenNewDroplet - defaultChan.getHSteps() + 1; //System.out.println("minPos: " + minPos + " pathLenCurrDroplet: " + // pathLenCurrDroplet + " minPathLenNewDroplet: " + minPathLenNewDroplet); int newTupleMinPos = minPos - (pathLenCurrDroplet - minPathLenNewDroplet); int newTupleMaxPos = maxPos - (pathLenCurrDroplet - minPathLenNewDroplet); tmpTuple.setMinPos(newTupleMinPos); tmpTuple.setMaxPos(newTupleMaxPos); getSequencesAtBifurcationRecursive(tmp, seqTupList.get(seqTupList.indexOf(currentSeqTup) + 1), possibleSequences, currentBifurcation); } } else { System.out.println("NOT at last sequence tuple and NOT adding header droplets to: " + currentSeqTup.getDroplet().getName() + ": " + currentSeqTup.getMinPos()); System.out.println(""); getSequencesAtBifurcationRecursive(seqTupList, seqTupList.get(seqTupList.indexOf(currentSeqTup) + 1), possibleSequences, currentBifurcation); } } } }