X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=Code%2FProjects%2FSmartPlugDetector%2Fsrc%2Fmain%2Fjava%2Fedu%2Fuci%2Fiotproject%2FMain.java;h=00b0b9b748c43c303a853a25cf7e4140cef3f67f;hb=8902443b788ba75f769b5fa11d2e37f37106ad0a;hp=98b4c270e94a305d9a3de81fe68055bfeca058a2;hpb=1fb088ef51ce9121ab70e242681e4e4c523b47dc;p=pingpong.git diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java index 98b4c27..00b0b9b 100644 --- a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java +++ b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/Main.java @@ -2,14 +2,15 @@ package edu.uci.iotproject; import static edu.uci.iotproject.analysis.UserAction.Type; -import edu.uci.iotproject.analysis.TcpConversationUtils; -import edu.uci.iotproject.analysis.TrafficLabeler; -import edu.uci.iotproject.analysis.TriggerTrafficExtractor; -import edu.uci.iotproject.analysis.UserAction; +import edu.uci.iotproject.analysis.*; import edu.uci.iotproject.comparison.seqalignment.ExtractedSequence; import edu.uci.iotproject.comparison.seqalignment.SequenceAlignment; import edu.uci.iotproject.comparison.seqalignment.SequenceExtraction; import edu.uci.iotproject.io.TriggerTimesFileReader; +import edu.uci.iotproject.util.PcapPacketUtils; +import edu.uci.iotproject.util.PrintUtils; +import org.apache.commons.math3.stat.clustering.Cluster; +import org.apache.commons.math3.stat.clustering.DBSCANClusterer; import org.pcap4j.core.*; import org.pcap4j.packet.namednumber.DataLinkType; @@ -20,6 +21,8 @@ import java.net.UnknownHostException; import java.time.Instant; import java.util.*; import java.util.concurrent.TimeoutException; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** * This is a system that reads PCAP files to compare @@ -39,23 +42,23 @@ public class Main { // ------------ # Code for extracting traffic generated by a device within x seconds of a trigger # ------------ // Paths to input and output files (consider supplying these as arguments instead) and IP of the device for // which traffic is to be extracted: -// String path = "/scratch/July-2018"; // Rahmadi - String path = "/Users/varmarken/temp/UCI IoT Project/experiments"; // Janus + String path = "/scratch/July-2018"; // Rahmadi +// String path = "/Users/varmarken/temp/UCI IoT Project/experiments"; // Janus boolean verbose = true; final String onPairsPath = "/scratch/July-2018/on.txt"; final String offPairsPath = "/scratch/July-2018/off.txt"; // 1) D-Link July 26 experiment -// final String inputPcapFile = path + "/2018-07/dlink/dlink.wlan1.local.pcap"; -// final String outputPcapFile = path + "/2018-07/dlink/dlink-processed.pcap"; -// final String triggerTimesFile = path + "/2018-07/dlink/dlink-july-26-2018.timestamps"; -// final String deviceIp = "192.168.1.246"; // .246 == phone; .199 == dlink plug? + final String inputPcapFile = path + "/2018-07/dlink/dlink.wlan1.local.pcap"; + final String outputPcapFile = path + "/2018-07/dlink/dlink-processed.pcap"; + final String triggerTimesFile = path + "/2018-07/dlink/dlink-july-26-2018.timestamps"; + final String deviceIp = "192.168.1.199"; // .246 == phone; .199 == dlink plug? // 2) TP-Link July 25 experiment - final String inputPcapFile = path + "/2018-07/tplink/tplink.wlan1.local.pcap"; - final String outputPcapFile = path + "/2018-07/tplink/tplink-processed.pcap"; - final String triggerTimesFile = path + "/2018-07/tplink/tplink-july-25-2018.timestamps"; - final String deviceIp = "192.168.1.159"; +// final String inputPcapFile = path + "/2018-07/tplink/tplink.wlan1.local.pcap"; +// final String outputPcapFile = path + "/2018-07/tplink/tplink-processed.pcap"; +// final String triggerTimesFile = path + "/2018-07/tplink/tplink-july-25-2018.timestamps"; +// final String deviceIp = "192.168.1.159"; // 2b) TP-Link July 25 experiment TRUNCATED: // Only contains "true local" events, i.e., before the behavior changes to remote-like behavior. @@ -87,7 +90,7 @@ public class Main { // final String inputPcapFile = path + "/2018-08/tplink-bulb/tplinkbulb.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-08/tplink-bulb/tplinkbulb-processed.pcap"; // final String triggerTimesFile = path + "/2018-08/tplink-bulb/tplink-bulb-aug-3-2018.timestamps"; -// final String deviceIp = "192.168.1.246"; +// final String deviceIp = "192.168.1.140"; // .246 == phone; .140 == TP-Link bulb // 7) Kwikset Doorlock August 6 experiment // final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock.wlan1.local.pcap"; @@ -95,6 +98,13 @@ public class Main { // final String triggerTimesFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock-aug-6-2018.timestamps"; // final String deviceIp = "192.168.1.246"; // .246 == phone; .142 == SmartThings Hub (note: use eth0 capture for this!) + // September 12, 2018 - includes both wlan1 and eth1 interfaces + //final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3.wlan1.local.pcap"; +// final String inputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3.eth1.local.pcap"; +// final String outputPcapFile = path + "/2018-08/kwikset-doorlock/kwikset3-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/kwikset-doorlock/kwikset-doorlock-sept-12-2018.timestamps"; +// final String deviceIp = "192.168.1.142"; // .246 == phone; .142 == SmartThings Hub (note: use eth0 capture for this!) + // 8) Hue Bulb August 7 experiment // final String inputPcapFile = path + "/2018-08/hue-bulb/hue-bulb.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-08/hue-bulb/hue-bulb-processed.pcap"; @@ -105,7 +115,7 @@ public class Main { // final String inputPcapFile = path + "/2018-08/lifx-bulb/lifx-bulb.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-08/lifx-bulb/lifx-bulb-processed.pcap"; // final String triggerTimesFile = path + "/2018-08/lifx-bulb/lifx-bulb-aug-8-2018.timestamps"; -// final String deviceIp = "192.168.1.231"; // .246 == phone; .231 == Lifx +// final String deviceIp = "192.168.1.246"; // .246 == phone; .231 == Lifx // 10) Amcrest Camera August 9 experiment // final String inputPcapFile = path + "/2018-08/amcrest-camera/amcrest-camera.wlan1.local.pcap"; @@ -125,7 +135,7 @@ public class Main { // final String triggerTimesFile = path + "/2018-08/blossom/blossom-aug-13-2018.timestamps"; // final String deviceIp = "192.168.1.246"; // .246 == phone; .229 == sprinkler - // 13) DLink siren August 14 experiment +// // 13) DLink siren August 14 experiment // final String inputPcapFile = path + "/2018-08/dlink-siren/dlink-siren.wlan1.local.pcap"; // final String outputPcapFile = path + "/2018-08/dlink-siren/dlink-siren-processed.pcap"; // final String triggerTimesFile = path + "/2018-08/dlink-siren/dlink-siren-aug-14-2018.timestamps"; @@ -148,6 +158,12 @@ public class Main { // final String triggerTimesFile = path + "/2018-08/alexa/alexa-aug-17-2018.timestamps"; // final String deviceIp = "192.168.1.225"; // .246 == phone; .225 == Alexa + // September 17 +// final String inputPcapFile = path + "/2018-08/noise/noise.eth1.pcap"; +// final String outputPcapFile = path + "/2018-08/noise/noise-processed.pcap"; +// final String triggerTimesFile = path + "/2018-08/noise/noise-sept-17-2018.timestamps"; +// final String deviceIp = "192.168.1.142"; // .142 == SmartThings Hub; .199 == dlink plug; .183 == siren + TriggerTimesFileReader ttfr = new TriggerTimesFileReader(); List triggerTimes = ttfr.readTriggerTimes(triggerTimesFile, false); // Tag each trigger with "ON" or "OFF", assuming that the first trigger is an "ON" and that they alternate. @@ -201,6 +217,12 @@ public class Main { + /* + * NOTE: no need to generate these more complex on/off maps that also contain mappings from hostname and + * sequence identifiers as we do not care about hostnames and sequences during clustering. + * We can simply use the UserAction->List map to generate ON/OFF groupings of conversations. + */ + /* // Contains all ON events: hostname -> sequence identifier -> list of conversations with that sequence Map>> ons = new HashMap<>(); // Contains all OFF events: hostname -> sequence identifier -> list of conversations with that sequence @@ -219,12 +241,102 @@ public class Main { }); }); }); + */ + + // ================================================ CLUSTERING ================================================ + // Note: no need to use the more convoluted on/off maps; can simply use the UserAction->List map + // when don't care about hostnames and sequences (see comment earlier). + List onConversations = userActionToConversations.entrySet().stream(). + filter(e -> e.getKey().getType() == Type.TOGGLE_ON). // drop all OFF events from stream + map(e -> e.getValue()). // no longer interested in the UserActions + flatMap(List::stream). // flatten List> to a List + collect(Collectors.toList()); + List offConversations = userActionToConversations.entrySet().stream(). + filter(e -> e.getKey().getType() == Type.TOGGLE_OFF). + map(e -> e.getValue()). + flatMap(List::stream). + collect(Collectors.toList()); + //Collections.sort(onConversations, (c1, c2) -> c1.getPackets().) + + List onPairs = onConversations.stream(). + map(c -> c.isTls() ? TcpConversationUtils.extractTlsAppDataPacketPairs(c) : + TcpConversationUtils.extractPacketPairs(c)). + flatMap(List::stream). // flatten List> to List<> + collect(Collectors.toList()); + List offPairs = offConversations.stream(). + map(c -> c.isTls() ? TcpConversationUtils.extractTlsAppDataPacketPairs(c) : + TcpConversationUtils.extractPacketPairs(c)). + flatMap(List::stream). // flatten List> to List<> + collect(Collectors.toList()); + // Note: need to update the DnsMap of all PcapPacketPairs if we want to use the IP/hostname-sensitive distance. + Stream.concat(Stream.of(onPairs), Stream.of(offPairs)).flatMap(List::stream).forEach(p -> p.setDnsMap(dnsMap)); + // Perform clustering on conversation logged as part of all ON events. + DBSCANClusterer onClusterer = new DBSCANClusterer<>(10.0, 45); + List> onClusters = onClusterer.cluster(onPairs); + // Perform clustering on conversation logged as part of all OFF events. + DBSCANClusterer offClusterer = new DBSCANClusterer<>(10.0, 45); + List> offClusters = offClusterer.cluster(offPairs); + // Sort the conversations as reference + List sortedAllConversation = TcpConversationUtils.sortConversationList(allConversations); + // Output clusters + System.out.println("========================================"); + System.out.println(" Clustering results for ON "); + System.out.println(" Number of clusters: " + onClusters.size()); + int count = 0; + List>> ppListOfListReadOn = new ArrayList<>(); + List>> ppListOfListListOn = new ArrayList<>(); + for (Cluster c : onClusters) { + System.out.println(String.format("<<< Cluster #%02d (%03d points) >>>", ++count, c.getPoints().size())); + System.out.print(PrintUtils.toSummaryString(c)); + if(c.getPoints().size() > 45 && c.getPoints().size() < 55) { + // Print to file + List> ppListOfList = PcapPacketUtils.clusterToListOfPcapPackets(c); + ppListOfListListOn.add(ppListOfList); + } + } + // TODO: Merging test + PcapPacketUtils.mergeSignatures(ppListOfListListOn, sortedAllConversation); + PcapPacketUtils.sortSignatures(ppListOfListListOn); + count = 0; + for (List> ll : ppListOfListListOn) { + PrintUtils.serializeClustersIntoFile("./onSignature" + ++count + ".sig", ll); + ppListOfListReadOn.add(PrintUtils.deserializeClustersFromFile("./onSignature" + count + ".sig")); + } + System.out.println("========================================"); + System.out.println(" Clustering results for OFF "); + System.out.println(" Number of clusters: " + offClusters.size()); + count = 0; + List>> ppListOfListReadOff = new ArrayList<>(); + List>> ppListOfListListOff = new ArrayList<>(); + for (Cluster c : offClusters) { + System.out.println(String.format("<<< Cluster #%03d (%06d points) >>>", ++count, c.getPoints().size())); + System.out.print(PrintUtils.toSummaryString(c)); + if(c.getPoints().size() > 45 && c.getPoints().size() < 55) { + // Print to file + List> ppListOfList = PcapPacketUtils.clusterToListOfPcapPackets(c); + ppListOfListListOff.add(ppListOfList); + } + } + // TODO: Merging test + PcapPacketUtils.mergeSignatures(ppListOfListListOff, sortedAllConversation); + PcapPacketUtils.sortSignatures(ppListOfListListOff); + count = 0; + for (List> ll : ppListOfListListOff) { + PrintUtils.serializeClustersIntoFile("./offSignature" + ++count + ".sig", ll); + ppListOfListReadOff.add(PrintUtils.deserializeClustersFromFile("./offSignature" + count + ".sig")); + } + System.out.println("========================================"); + // ============================================================================================================ + /* + System.out.println("==== ON ===="); // Print out all the pairs into a file for ON events File fileOnEvents = new File(onPairsPath); PrintWriter pwOn = null; try { + + pwOn = new PrintWriter(fileOnEvents); } catch(Exception ex) { ex.printStackTrace(); @@ -238,59 +350,16 @@ public class Main { for(Conversation conv : listConv) { // Process only if it is a TLS packet if (conv.isTls()) { - List tlsAppDataList = conv.getTlsApplicationDataPackets(); - // Loop and print out packets - int count = 0; - // The direction of the first packet - Conversation.Direction firstDir = null; - // The length of the first packet - int firstLen = 0; - for (PcapPacket pcap : tlsAppDataList) { - boolean isPair = false; - if (count % 2 == 0) { - firstDir = conv.getDirection(pcap); - firstLen = pcap.length(); - } else {// count%2 == 1 - if(conv.getDirection(pcap) != firstDir) { - isPair = true; - pwOn.println(firstLen + ", " + pcap.length()); - //System.out.println(firstDir + ", " + conv.getDirection(pcap)); - //System.out.println(firstLen + ", " + pcap.length()); - } - } - count++; - // If we can't create a pair then just pad it with 0 - if (count == tlsAppDataList.size() && !isPair) { - pwOn.println(firstLen + ", 0"); - } + List tlsAppDataList = TcpConversationUtils.extractTlsAppDataPacketPairs(conv); + for(PcapPacketPair pair: tlsAppDataList) { + System.out.println(PrintUtils.toCsv(pair, dnsMap)); + pwOn.println(PrintUtils.toCsv(pair, dnsMap)); } } else { // Non-TLS conversations - List packetList = conv.getPackets(); - // Loop and print out packets - int count = 0; - // The direction of the first packet - Conversation.Direction firstDir = null; - // The length of the first packet - int firstLen = 0; - for (PcapPacket pcap : packetList) { - System.out.println(pcap.length() + ", " + conv.getDirection(pcap)); - boolean isPair = false; - if (count % 2 == 0) { - firstDir = conv.getDirection(pcap); - firstLen = pcap.length(); - } else {// count%2 == 1 - if(conv.getDirection(pcap) != firstDir) { - isPair = true; - pwOn.println(firstLen + ", " + pcap.length()); - //System.out.println(firstDir + ", " + conv.getDirection(pcap)); - //System.out.println(firstLen + ", " + pcap.length()); - } - } - count++; - // If we can't create a pair then just pad it with 0 - if (count == packetList.size() && !isPair) { - pwOn.println(firstLen + ", 0"); - } + List packetList = TcpConversationUtils.extractPacketPairs(conv); + for(PcapPacketPair pair: packetList) { + System.out.println(PrintUtils.toCsv(pair, dnsMap)); + pwOn.println(PrintUtils.toCsv(pair, dnsMap)); } } } @@ -298,6 +367,7 @@ public class Main { } pwOn.close(); + System.out.println("==== OFF ===="); // Print out all the pairs into a file for ON events File fileOffEvents = new File(offPairsPath); PrintWriter pwOff = null; @@ -315,120 +385,76 @@ public class Main { for(Conversation conv : listConv) { // Process only if it is a TLS packet if (conv.isTls()) { - List tlsAppDataList = conv.getTlsApplicationDataPackets(); - // Loop and print out packets - int count = 0; - // The direction of the first packet - Conversation.Direction firstDir = null; - // The length of the first packet - int firstLen = 0; - for (PcapPacket pcap : tlsAppDataList) { - boolean isPair = false; - if (count % 2 == 0) { - firstDir = conv.getDirection(pcap); - firstLen = pcap.length(); - } else {// count%2 == 1 - if(conv.getDirection(pcap) != firstDir) { - isPair = true; - pwOff.println(firstLen + ", " + pcap.length()); - System.out.println(firstDir + ", " + conv.getDirection(pcap)); - System.out.println(firstLen + ", " + pcap.length()); - } - } - count++; - // If we can't create a pair then just pad it with 0 - if (count == tlsAppDataList.size() && !isPair) { - pwOff.println(firstLen + ", 0"); - } - + List tlsAppDataList = TcpConversationUtils.extractTlsAppDataPacketPairs(conv); + for(PcapPacketPair pair: tlsAppDataList) { + System.out.println(PrintUtils.toCsv(pair, dnsMap)); + pwOff.println(PrintUtils.toCsv(pair, dnsMap)); } } else { // Non-TLS conversations - List packetList = conv.getPackets(); - // Loop and print out packets - int count = 0; - // The direction of the first packet - Conversation.Direction firstDir = null; - // The length of the first packet - int firstLen = 0; - for (PcapPacket pcap : packetList) { - System.out.println(pcap.length() + ", " + conv.getDirection(pcap)); - boolean isPair = false; - if (count % 2 == 0) { - firstDir = conv.getDirection(pcap); - firstLen = pcap.length(); - } else {// count%2 == 1 - if(conv.getDirection(pcap) != firstDir) { - isPair = true; - pwOff.println(firstLen + ", " + pcap.length()); - System.out.println(firstDir + ", " + conv.getDirection(pcap)); - System.out.println(firstLen + ", " + pcap.length()); - } - } - count++; - // If we can't create a pair then just pad it with 0 - if (count == packetList.size() && !isPair) { - pwOff.println(firstLen + ", 0"); - } + List packetList = TcpConversationUtils.extractPacketPairs(conv); + for (PcapPacketPair pair : packetList) { + System.out.println(PrintUtils.toCsv(pair, dnsMap)); + pwOff.println(PrintUtils.toCsv(pair, dnsMap)); } } } } } pwOff.close(); - - - // ================================================================================================ - // <<< Some work-in-progress/explorative code that extracts a "representative" sequence >>> - // - // Currently need to know relevant hostname in advance :( - String hostname = "events.tplinkra.com"; -// String hostname = "rfe-us-west-1.dch.dlink.com"; - // Conversations with 'hostname' for ON events. - List onsForHostname = new ArrayList<>(); - // Conversations with 'hostname' for OFF events. - List offsForHostname = new ArrayList<>(); - // "Unwrap" sequence groupings in ons/offs maps. - ons.get(hostname).forEach((k,v) -> onsForHostname.addAll(v)); - offs.get(hostname).forEach((k,v) -> offsForHostname.addAll(v)); - - - Map> onsForHostnameGroupedByTlsAppDataSequence = TcpConversationUtils.groupConversationsByTlsApplicationDataPacketSequence(onsForHostname); - - - // Extract representative sequence for ON and OFF by providing the list of conversations with - // 'hostname' observed for each event type (the training data). - SequenceExtraction seqExtraction = new SequenceExtraction(); -// ExtractedSequence extractedSequenceForOn = seqExtraction.extract(onsForHostname); -// ExtractedSequence extractedSequenceForOff = seqExtraction.extract(offsForHostname); - - ExtractedSequence extractedSequenceForOn = seqExtraction.extractByTlsAppData(onsForHostname); - ExtractedSequence extractedSequenceForOff = seqExtraction.extractByTlsAppData(offsForHostname); - - // Let's check how many ONs align with OFFs and vice versa (that is, how many times an event is incorrectly - // labeled). - int onsLabeledAsOff = 0; - Integer[] representativeOnSeq = TcpConversationUtils.getPacketLengthSequence(extractedSequenceForOn.getRepresentativeSequence()); - Integer[] representativeOffSeq = TcpConversationUtils.getPacketLengthSequence(extractedSequenceForOff.getRepresentativeSequence()); - SequenceAlignment seqAlg = seqExtraction.getAlignmentAlgorithm(); - for (Conversation c : onsForHostname) { - Integer[] onSeq = TcpConversationUtils.getPacketLengthSequence(c); - if (seqAlg.calculateAlignment(representativeOffSeq, onSeq) <= extractedSequenceForOff.getMaxAlignmentCost()) { - onsLabeledAsOff++; - } - } - int offsLabeledAsOn = 0; - for (Conversation c : offsForHostname) { - Integer[] offSeq = TcpConversationUtils.getPacketLengthSequence(c); - if (seqAlg.calculateAlignment(representativeOnSeq, offSeq) <= extractedSequenceForOn.getMaxAlignmentCost()) { - offsLabeledAsOn++; - } - } - System.out.println(""); - // ================================================================================================ - - - // ------------------------------------------------------------------------------------------------------------- - // ------------------------------------------------------------------------------------------------------------- + */ + +// // ================================================================================================ +// // <<< Some work-in-progress/explorative code that extracts a "representative" sequence >>> +// // +// // Currently need to know relevant hostname in advance :( +// String hostname = "events.tplinkra.com"; +//// String hostname = "rfe-us-west-1.dch.dlink.com"; +// // Conversations with 'hostname' for ON events. +// List onsForHostname = new ArrayList<>(); +// // Conversations with 'hostname' for OFF events. +// List offsForHostname = new ArrayList<>(); +// // "Unwrap" sequence groupings in ons/offs maps. +// ons.get(hostname).forEach((k,v) -> onsForHostname.addAll(v)); +// offs.get(hostname).forEach((k,v) -> offsForHostname.addAll(v)); +// +// +// Map> onsForHostnameGroupedByTlsAppDataSequence = TcpConversationUtils.groupConversationsByTlsApplicationDataPacketSequence(onsForHostname); +// +// +// // Extract representative sequence for ON and OFF by providing the list of conversations with +// // 'hostname' observed for each event type (the training data). +// SequenceExtraction seqExtraction = new SequenceExtraction(); +//// ExtractedSequence extractedSequenceForOn = seqExtraction.extract(onsForHostname); +//// ExtractedSequence extractedSequenceForOff = seqExtraction.extract(offsForHostname); +// +// ExtractedSequence extractedSequenceForOn = seqExtraction.extractByTlsAppData(onsForHostname); +// ExtractedSequence extractedSequenceForOff = seqExtraction.extractByTlsAppData(offsForHostname); +// +// // Let's check how many ONs align with OFFs and vice versa (that is, how many times an event is incorrectly +// // labeled). +// int onsLabeledAsOff = 0; +// Integer[] representativeOnSeq = TcpConversationUtils.getPacketLengthSequence(extractedSequenceForOn.getRepresentativeSequence()); +// Integer[] representativeOffSeq = TcpConversationUtils.getPacketLengthSequence(extractedSequenceForOff.getRepresentativeSequence()); +// SequenceAlignment seqAlg = seqExtraction.getAlignmentAlgorithm(); +// for (Conversation c : onsForHostname) { +// Integer[] onSeq = TcpConversationUtils.getPacketLengthSequence(c); +// if (seqAlg.calculateAlignment(representativeOffSeq, onSeq) <= extractedSequenceForOff.getMaxAlignmentCost()) { +// onsLabeledAsOff++; +// } +// } +// int offsLabeledAsOn = 0; +// for (Conversation c : offsForHostname) { +// Integer[] offSeq = TcpConversationUtils.getPacketLengthSequence(c); +// if (seqAlg.calculateAlignment(representativeOnSeq, offSeq) <= extractedSequenceForOn.getMaxAlignmentCost()) { +// offsLabeledAsOn++; +// } +// } +// System.out.println(""); +// // ================================================================================================ +// +// +// // ------------------------------------------------------------------------------------------------------------- +// // ------------------------------------------------------------------------------------------------------------- } }