Newer
Older
import java.util.List;
import java.util.ArrayList;

Peter Wagenhuber
committed
import java.lang.Math;
private List<Channel> chanlist;
private List<Droplet> dropletList;
public Nloc (List<Channel> chanlist) {
this.chanlist = chanlist;
this.dropletList = new ArrayList<Droplet>();
}
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// public List<List<SequenceTuple>> sanitizeSequences(
// List<List<SequenceTuple>> possibleSequences) {
//
// List<List<SequenceTuple>> tmpSeqs =
// new ArrayList<List<SequenceTuple>>();
//
// for(List<SequenceTuple> seqTupList: possibleSequences) {
//
// List<SequenceTuple> tmpStl = new ArrayList<SequenceTuple>(seqTupList);
//
// for (SequenceTuple seqTup: seqTupList) {
//
// if (seqTup.getDroplet().getType() != DropletType.PAYLOAD) {
//
// List<Channel> hPath = seqTup.getPath();
//
// // generate sublist for comaparison containing the rest of the
// // sequence tuples
// List<SequenceTuple> compList =
// seqTupList.sublist(seqTupList.indexOf(seqTup),
// seqTupList.size() - 1);
//
// for (SequenceTuple compTuple: compList) {
// List<Channel> cPath = compTuple.getPath();
//
// if (seqTup.overlaps(compTuple)) {
// // check if path is the same
// // if so then merge the droplets to one
// // if not adjust the min and max position
// // if the adjustment is not possible remove the sequence
// if (hPath.equals(cPath)) {
// SequenceTuple newTup = SequenceTuple.merge(seqTup,compTuple);
// tmpStl.remove(seqTup);
// tmpStl.remove(compTuple);
// tmpStl.add(newTup);
// } // end paths are equal
// else {
// int hMin = seqTup.getMinPos();
// int hMax = seqTup.getMaxPos();
// int cMin = compTuple.getMaxPos();
// int cMax = compTuple.getMaxPos();
// if (hMin == hMax && cMin == cMax) {
// tmpStl.clear();
// } else if ((hMax - hMin) < (cMax - cMin)) {
// if (hMax < cMax) {
// compTuple.setMinPos(hMax + 1);
// } else {
// compTuple.setMaxPos(hMin - 1);
// }
// } else if ((hMax - hMin) > (cMax - cMin)) {
// if (cMax < hMax) {
// seqTup.setMinPos(cMax + 1);
// } else {
// seqTup.setMaxPos(cMin - 1);
// }
// } else if ((hMax - hMin) > (cMax - cMin)) {
// if (hMin == cMin) {
//
// } else if (hMin < cMin) {
// seqTup.setMaxPos(cMin - 1);
// } else {
// compTuple.setMaxPos(hMin - 1);
// }
// }
//
// } // end paths are not equal
//
// } // typles overlap
// } // end iter restlist
// } // payload droplet
// } // end iter sequence
// if (!tmpStl.isEmpty()) {
// tmpSeqs.add(tmpStl);
// }
// } // end iter possibleSequences
// return tmpSeqs;
// }

Peter Wagenhuber
committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//ListIterator<SequenceTuple> seqIter = currentSeq.ListIterator();
//while (seqIter.hasNext()) {
// SequenceTuple currentSeqTuple = seqIter.next();
// int minPos = currentSeqTuple.getMinPos();
// int maxPos = currentSeqTuple.getMaxPos();
// Position initialDropletPosition = new Position(pump, minPos);
// Droplet currentDroplet = currentSeqTuple.getDroplet();
//
// if (position.alreadyOccupied(dropletSequence)) {
// // if occupied first try to increase position until max is reached
// // if max is also occupied then step back one droplet in list
// // and increase its position
// // if all fails return null pump indicating that no sequence could
// // be found
// for (int i = minPos; i <= maxPos; i++) {
// }
// } else {
// currentDroplet.setPosition(initialDropletPosition);
// dropletSequence.add(currentDroplet);
// }
//}
public Pump getShortestSequence(String[] modulesToVisit) {

Peter Wagenhuber
committed
Pump pump = this.getPump();
try {
List<List<SequenceTuple>> possibleSequences =
getPossibleSequences(modulesToVisit);
// sort the list of possible sequences according to the sequences length
possibleSequences.sort((a,b) -> a.size() - b.size());

Peter Wagenhuber
committed
List<SequenceTuple> currentSeq = possibleSequences.get(0);

Peter Wagenhuber
committed
int min = 0, max = 0;

Peter Wagenhuber
committed
for (SequenceTuple stl: currentSeq) {

Peter Wagenhuber
committed
int tmp = stl.getMinPos();
if (tmp > max) max = tmp;
if (tmp < min) min = tmp;
}
int span = max - min;
pump.setSteps(span);
possibleSequences = setTuplePumpoffsetToPumpPosition(possibleSequences,
min);

Peter Wagenhuber
committed
List<Droplet> dropletSequence = generateDropletListRecursive(new ArrayList<Droplet>(), currentSeq, currentSeq.get(0).getMinPos());

Peter Wagenhuber
committed
} catch(NoSuchModuleException nsme) {
System.out.println(nsme.getMessage());
}

Peter Wagenhuber
committed
return pump;

Peter Wagenhuber
committed
public List<List<SequenceTuple>> setTuplePumpoffsetToPumpPosition(
List<List<SequenceTuple>> possibleSequences, int minOffset) {
for (List<SequenceTuple> stl: possibleSequences) {
for (SequenceTuple stup: stl) {
int pumpOffsetMin = stup.getMinPos();
stup.setMinPos(pumpOffsetMin + Math.abs(minOffset));
int pumpOffsetMax = stup.getMaxPos();
stup.setMaxPos(pumpOffsetMax + Math.abs(minOffset));
}
}
return possibleSequences;
}

Peter Wagenhuber
committed
private List<Droplet> generateDropletListRecursive(
List<Droplet> dropletList, List<SequenceTuple> currentSequence,
int currentPos) {
if (dropletList.size() == currentSequence.size()) {
return dropletList;
} else {
if (dropletList.isEmpty() ||
!Position.isOccupied(dropletList, currentPos)) {
SequenceTuple tmpTup = currentSequence.get(dropletList.size());
Droplet tmpDr = tmpTup.getDroplet();
tmpDr.setPosition(new Position(this.getPump(), currentPos));
Channel pumpOutlet = tmpTup.getPumpOutlet();
tmpDr.setPumpOutlet(pumpOutlet);

Peter Wagenhuber
committed
dropletList.add(tmpDr);
// set current pos to minimum of the following sequence tuple
if (dropletList.size() < currentSequence.size()) {
currentPos =
currentSequence.get(dropletList.size()).getMinPos();
}
return generateDropletListRecursive(dropletList, currentSequence,
currentPos);
} else {
SequenceTuple tmpTup = currentSequence.get(dropletList.size());
if (currentPos < tmpTup.getMaxPos()) {
currentPos++;
return generateDropletListRecursive(dropletList, currentSequence,
currentPos);
} else {
ListIterator<Droplet> revIter = dropletList.listIterator(
dropletList.size());
boolean found = false;
while (!found && revIter.hasPrevious()) {
Droplet tmpDr = revIter.previous();
revIter.remove();
SequenceTuple tmpTup1 = currentSequence.get(dropletList.size() - 1);
if (tmpDr.getPosition().getSteps() == currentPos &&
currentPos < tmpTup1.getMaxPos()) {
found = true;
}
}
if (found) {
currentPos++;
return generateDropletListRecursive(dropletList, currentSequence,
currentPos);
} else {
return dropletList;
}

Peter Wagenhuber
committed
}
}
}
}
public List<List<SequenceTuple>> getPossibleSequences(
String[] modulesToVisit) throws NoSuchModuleException {
Droplet payloadDroplet = new Droplet(DropletType.PAYLOAD,"p");
List<List<SequenceTuple>> sequences = new ArrayList<List<SequenceTuple>>();
List<List<Channel>> pathlist = this.getAllPaths();
try {
// Create initial list of possilbe sequences
List<Channel> moduleChanList =
this.getModulesByName(Arrays.asList(modulesToVisit));
List<Channel> payloadPath = this.getDesiredPath(moduleChanList, pathlist);
SequenceTuple plt = new SequenceTuple(payloadDroplet,payloadPath,0,0);
List<SequenceTuple> s1 = new ArrayList<SequenceTuple>();
s1.add(plt);
sequences.add(s1);
List<Channel> bifurcationList = this.getBifurcationList(payloadPath);
// actually compile list of sequences going through the bifurcations from
// "end" to "start"
for (int i = bifurcationList.size() - 1; i >= 0; --i) {
Channel currentBifurcation = bifurcationList.get(i);
List<List<SequenceTuple>> tmpSeqs = new ArrayList<List<SequenceTuple>>();
for (List<SequenceTuple> stl: sequences) {
tmpSeqs.addAll(
this.getSequencesAtBifurcation(stl, currentBifurcation));
}
sequences = tmpSeqs;
}
} catch (Exception e) {
System.out.println( e.getMessage());
}
return sequences;
}
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);

Peter Wagenhuber
committed
public List<Channel> getBifurcationList(List<Channel> desiredPath) {

Peter Wagenhuber
committed
List<Channel> bfList = new ArrayList<Channel>();
for (Channel ch: desiredPath) {

Peter Wagenhuber
committed
bfList.add(ch);

Peter Wagenhuber
committed
}

Peter Wagenhuber
committed
}
return bfList;

Peter Wagenhuber
committed
}
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;
}

Peter Wagenhuber
committed
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) throws NoSuchModuleException {
Channel found = null;
for (Channel ch: chanlist) {
if (ch.getName().equals(name)) {
found = ch;
}
}
if (found == null) throw new NoSuchModuleException(name);
return found;
}
public List<Channel> getModulesByName(List<String> names)
throws NoSuchModuleException {
List<Channel> ret = new ArrayList<Channel>();
for (String name : names) {
Channel ch = getModuleByName(name);
if (name != null) {
ret.add(ch);
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);
private void getAllPathsRecursive(Channel chan, Channel end, List<Channel> path, List<List<Channel>> pathlist) {
if (chan.equals(end)) {
pathlist.add(path);
} else {
for (Channel ch : chan.getChildrenList()) {
getAllPathsRecursive(ch, end, new ArrayList<Channel>(path), pathlist);

Peter Wagenhuber
committed
public List<List<SequenceTuple>> getSequencesAtBifurcation(

Peter Wagenhuber
committed
List<SequenceTuple> seqTup, Channel currentBifurcation) {

Peter Wagenhuber
committed

Peter Wagenhuber
committed
List<List<SequenceTuple>> seqTupList = new ArrayList<List<SequenceTuple>>();

Peter Wagenhuber
committed
SequenceTuple currentSeqTup = seqTup.get(0);

Peter Wagenhuber
committed
getSequencesAtBifurcationRecursive(seqTup, currentSeqTup, seqTupList,
currentBifurcation);
return seqTupList;
}
private void getSequencesAtBifurcationRecursive(

Peter Wagenhuber
committed
List<SequenceTuple> seqTupList, SequenceTuple currentSeqTup,
List<List<SequenceTuple>> possibleSequences, Channel currentBifurcation) {

Peter Wagenhuber
committed
// 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);

Peter Wagenhuber
committed
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) {

Peter Wagenhuber
committed
System.out.println("At last sequence tuple and adding header droplet(s) to: " + currentSeqTup.getDroplet().getName() + ": " + currentSeqTup.getMinPos());
System.out.println("");

Peter Wagenhuber
committed
// we need header droplet

Peter Wagenhuber
committed
// cirst check all possible paths of header droplets

Peter Wagenhuber
committed
Channel defaultChan = currentBifurcation.getChildrenList().get(0);

Peter Wagenhuber
committed
List<List<Channel>> pathList =

Peter Wagenhuber
committed
this.getAllPathsFromTo(dropletPath.get(0), defaultChan);

Peter Wagenhuber
committed

Peter Wagenhuber
committed
for (List<Channel> path: pathList) {
List<SequenceTuple> tmp = new ArrayList<SequenceTuple>(seqTupList);

Peter Wagenhuber
committed
SequenceTuple tmpTuple =

Peter Wagenhuber
committed
new SequenceTuple(new Droplet(DropletType.HEADER,"h"),path);

Peter Wagenhuber
committed
tmp.add(tmpTuple);

Peter Wagenhuber
committed

Peter Wagenhuber
committed
// calculate and set pump offsets

Peter Wagenhuber
committed
int minPos = currentSeqTup.getMinPos();
int maxPos = currentSeqTup.getMaxPos();
List<Channel> pathToCurrentBifurcation =
dropletPath.subList(0,dropletPath.indexOf(currentBifurcation) + 1);

Peter Wagenhuber
committed
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);

Peter Wagenhuber
committed
int newTupleMinPos =
minPos - (pathLenCurrDroplet - minPathLenNewDroplet);
int newTupleMaxPos =
maxPos - (pathLenCurrDroplet - maxPathLenNewDroplet);

Peter Wagenhuber
committed
tmpTuple.setMinPos(newTupleMinPos);
tmpTuple.setMaxPos(newTupleMaxPos);

Peter Wagenhuber
committed
possibleSequences.add(tmp);
}

Peter Wagenhuber
committed
} 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);

Peter Wagenhuber
committed
}

Peter Wagenhuber
committed
if (dropletPath.contains(currentBifurcation) && prio > 0) {

Peter Wagenhuber
committed
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("");

Peter Wagenhuber
committed
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
// 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 - maxPathLenNewDroplet);

Peter Wagenhuber
committed
tmpTuple.setMinPos(newTupleMinPos);
tmpTuple.setMaxPos(newTupleMaxPos);
getSequencesAtBifurcationRecursive(tmp,
seqTupList.get(seqTupList.indexOf(currentSeqTup) + 1),
possibleSequences, currentBifurcation);
}

Peter Wagenhuber
committed
} 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);

Peter Wagenhuber
committed
}