// Copyright 2012 Georg-August-Universität Göttingen, Germany
//
// 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 de.ugoe.cs.autoquest.tasktrees.temporalrelation;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import de.ugoe.cs.autoquest.CommandHelpers;
import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithm;
import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.AlignmentAlgorithmFactory;
import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.Match;
import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.MatchOccurence;
import de.ugoe.cs.autoquest.tasktrees.alignment.algorithms.NumberSequence;
import de.ugoe.cs.autoquest.tasktrees.alignment.matrix.ObjectDistanceSubstitionMatrix;
import de.ugoe.cs.autoquest.tasktrees.taskequality.TaskEquality;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IIterationInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptional;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequenceInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskBuilder;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskFactory;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
import de.ugoe.cs.autoquest.usageprofiles.SymbolMap;
import de.ugoe.cs.util.StopWatch;
import de.ugoe.cs.util.console.Console;
import de.ugoe.cs.util.console.GlobalDataContainer;
/**
*
* This class implements the major rule for creating task trees based on a set
* of recorded user sessions. For this, it first harmonizes all tasks. This
* eases later comparison. Then it searches the sessions for iterations and
* replaces them accordingly. Then it searches for sub sequences being the
* longest and occurring most often. For each found sub sequence, it replaces
* the occurrences by creating appropriate {@link ISequence}s. Afterwards, again
* searches for iterations and then again for sub sequences until no more
* replacements are done.
*
*
*
*
* @author Patrick Harms
*/
public class SequenceForTaskDetectionRuleAlignment implements ISessionScopeRule {
public static int nThreads = Runtime.getRuntime().availableProcessors()-1;
private int iteration = 0;
/**
*
* the task factory to be used for creating substructures for the temporal
* relationships identified during rul application
*
*/
private ITaskFactory taskFactory;
/**
*
* the task builder to be used for creating substructures for the temporal
* relationships identified during rule application
*
*/
private ITaskBuilder taskBuilder;
/**
*
* the task handling strategy to be used for comparing tasks for
* preparation, i.e., before the tasks are harmonized
*
*/
private TaskHandlingStrategy preparationTaskHandlingStrategy;
/**
*
* instantiates the rule and initializes it with a task equality to be
* considered when comparing tasks as well as a task factory and builder to
* be used for creating task structures.
*
*
* @param minimalTaskEquality
* the task equality to be considered when comparing tasks
* @param taskFactory
* the task factory to be used for creating substructures
* @param taskBuilder
* the task builder to be used for creating substructures
*/
SequenceForTaskDetectionRuleAlignment(TaskEquality minimalTaskEquality,
ITaskFactory taskFactory, ITaskBuilder taskBuilder) {
this.taskFactory = taskFactory;
this.taskBuilder = taskBuilder;
this.preparationTaskHandlingStrategy = new TaskHandlingStrategy(
minimalTaskEquality);
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "SequenceForTaskDetectionRuleAlignment";
}
public void saveAppData(String name) {
String objectName = name;
String filename = name + ".dat";
Object dataObject = GlobalDataContainer.getInstance().getData(
objectName);
if (dataObject == null) {
CommandHelpers.objectNotFoundMessage(objectName);
}
FileOutputStream fos = null;
ObjectOutputStream out = null;
try {
fos = new FileOutputStream(filename);
out = new ObjectOutputStream(fos);
out.writeObject(dataObject);
out.close();
} catch (IOException ex) {
Console.logException(ex);
}
}
public RuleApplicationData loadAppData(String name) {
String objectName = name;
String filename = name + ".dat";
Object data = null;
FileInputStream fis = null;
ObjectInputStream in = null;
try {
fis = new FileInputStream(filename);
in = new ObjectInputStream(fis);
data = in.readObject();
in.close();
} catch (IOException ex) {
Console.logException(ex);
} catch (ClassNotFoundException ex) {
Console.logException(ex);
}
if (GlobalDataContainer.getInstance().addData(objectName, data)) {
CommandHelpers.dataOverwritten(objectName);
}
return (RuleApplicationData) GlobalDataContainer.getInstance().getData(name);
}
/*
* (non-Javadoc)
*
* @see
* de.ugoe.cs.autoquest.tasktrees.temporalrelation.ISessionScopeRule#apply
* (java.util.List)
*/
@Override
public RuleApplicationResult apply(List sessions) {
RuleApplicationData appData = new RuleApplicationData(sessions);
//File harmonized = new File("harmonized.dat");
//if(harmonized.exists() && !harmonized.isDirectory()) {
// Console.traceln(Level.INFO,"loading harmonized sessions from file");
// appData = loadAppData("harmonized");
//}
//else {
//appData.getStopWatch().start("harmonization");
harmonizeEventTaskInstancesModel(appData);
//appData.getStopWatch().stop("harmonization");
GlobalDataContainer.getInstance().addData("harmonized", appData);
//Saving intermediate results to file
Console.traceln(Level.INFO,"saving substitution matrix to file");
//saveAppData("harmonized");
//}
//File substitution = new File("substitution.dat");
//if(!(substitution.exists() && !substitution.isDirectory())) {
Console.traceln(Level.INFO, "generating substitution matrix from " + appData.getUniqueTasks().size() + " unique tasks");
appData.getStopWatch().start("substitution matrix");
appData.getSubmat().generate(appData.getUniqueTasks());
appData.getStopWatch().stop("substitution matrix");
// GlobalDataContainer.getInstance().addData("substitution", appData);
// saveAppData("substitution");
//}
//else {
// Console.traceln(Level.INFO,"loading substitution matrix from file");
// appData = loadAppData("substitution");
//}
Console.traceln(Level.INFO, "Starting main loop");
do {
Console.traceln(Level.INFO, "Iteration Number: " + iteration);
iteration++;
appData.detectedAndReplacedTasks = false;
appData.getStopWatch().start("whole loop");
detectAndReplaceIterations(appData);
appData.getStopWatch().start("task replacement");
appData.updateSubstitutionMatrix();
detectAndReplaceTasks(appData); //
appData.getStopWatch().stop("task replacement");
appData.getStopWatch().stop("whole loop");
appData.getStopWatch().dumpStatistics(System.out);
appData.getStopWatch().reset();
} while (appData.detectedAndReplacedTasks());
Console.println("created "
+ appData.getResult().getNewlyCreatedTasks().size()
+ " new tasks and "
+ appData.getResult().getNewlyCreatedTaskInstances().size()
+ " appropriate instances\n");
if ((appData.getResult().getNewlyCreatedTasks().size() > 0)
|| (appData.getResult().getNewlyCreatedTaskInstances().size() > 0)) {
appData.getResult().setRuleApplicationStatus(
RuleApplicationStatus.FINISHED);
}
return appData.getResult();
}
private ArrayList createNumberSequences(
RuleApplicationData appData) {
ArrayList result = new ArrayList();
for (int i = 0; i < appData.getSessions().size(); i++) {
IUserSession session = appData.getSessions().get(i);
NumberSequence templist = new NumberSequence(session.size());
for (int j = 0; j < session.size(); j++) {
ITaskInstance taskInstance = session.get(j);
templist.getSequence()[j] = taskInstance.getTask().getId();
}
// Each NumberSequence is identified by its id, beginning to count
// at zero
templist.setId(i);
result.add(templist);
}
return result;
}
/**
*
* harmonizes the event task instances by unifying tasks. This is done, as
* initially the event tasks being equal with respect to the considered task
* equality are distinct objects. The comparison of these distinct objects
* is more time consuming than comparing the object references.
*
*
* @param appData
* the rule application data combining all data used for applying
* this rule
* @return Returns the unique tasks symbol map
*/
private void harmonizeEventTaskInstancesModel(RuleApplicationData appData) {
Console.traceln(Level.INFO,
"harmonizing task model of event task instances");
appData.getStopWatch().start("harmonizing event tasks");
SymbolMap uniqueTasks = preparationTaskHandlingStrategy
.createSymbolMap();
TaskInstanceComparator comparator = preparationTaskHandlingStrategy
.getTaskComparator();
int unifiedTasks = 0;
ITask task;
List sessions = appData.getSessions();
for (int j = 0; j < sessions.size(); j++) {
IUserSession session = sessions.get(j);
for (int i = 0; i < session.size(); i++) {
ITaskInstance taskInstance = session.get(i);
task = uniqueTasks.getValue(taskInstance);
if (task == null) {
uniqueTasks.addSymbol(taskInstance, taskInstance.getTask());
appData.getUniqueTasks().add(taskInstance.getTask());
appData.getNumber2Task().put(
taskInstance.getTask().getId(),
taskInstance.getTask());
} else {
taskBuilder.setTask(taskInstance, task);
unifiedTasks++;
}
}
comparator.clearBuffers();
}
appData.getStopWatch().stop("harmonizing event tasks");
Console.traceln(Level.INFO, "harmonized " + unifiedTasks
+ " task occurrences (still " + appData.getUniqueTasks().size()
+ " different tasks)");
appData.getStopWatch().dumpStatistics(System.out);
appData.getStopWatch().reset();
}
/**
*
* searches for direct iterations of single tasks in all sequences and
* replaces them with {@link IIteration}s, respectively appropriate
* instances. Also all single occurrences of a task that is iterated
* somewhen are replaced with iterations to have again an efficient way for
* task comparisons.
*
*
* @param appData
* the rule application data combining all data used for applying
* this rule
*/
private void detectAndReplaceIterations(RuleApplicationData appData) {
Console.traceln(Level.FINE, "detecting iterations");
appData.getStopWatch().start("detecting iterations");
List sessions = appData.getSessions();
Set iteratedTasks = searchIteratedTasks(sessions);
if (iteratedTasks.size() > 0) {
replaceIterationsOf(iteratedTasks, sessions, appData);
}
appData.getStopWatch().stop("detecting iterations");
Console.traceln(Level.INFO, "replaced " + iteratedTasks.size()
+ " iterated tasks");
}
/**
*
* searches the provided sessions for task iterations. If a task is
* iterated, it is added to the returned set.
*
*
* @param the
* session to search for iterations in
*
* @return a set of tasks being iterated somewhere
*/
private Set searchIteratedTasks(List sessions) {
Set iteratedTasks = new HashSet();
for (IUserSession session : sessions) {
for (int i = 0; i < (session.size() - 1); i++) {
// we prepared the task instances to refer to unique tasks, if
// they are treated
// as equal. Therefore, we just compare the identity of the
// tasks of the task
// instances
if (session.get(i).getTask() == session.get(i + 1).getTask()) {
iteratedTasks.add(session.get(i).getTask());
}
}
}
return iteratedTasks;
}
/**
*
* replaces all occurrences of all tasks provided in the set with iterations
*
*
* @param iteratedTasks
* the tasks to be replaced with iterations
* @param sessions
* the sessions in which the tasks are to be replaced
* @param appData
* the rule application data combining all data used for applying
* this rule
*/
private void replaceIterationsOf(Set iteratedTasks,
List sessions, RuleApplicationData appData) {
Map iterations = new HashMap();
Map> iterationInstances = new HashMap>();
for (ITask iteratedTask : iteratedTasks) {
IIteration iteration = taskFactory.createNewIteration();
appData.newTaskCreated(iteration);
iterations.put(iteratedTask, iteration);
iterationInstances.put(iteration,
new LinkedList());
}
IIterationInstance iterationInstance;
for (IUserSession session : sessions) {
int index = 0;
iterationInstance = null;
while (index < session.size()) {
// we prepared the task instances to refer to unique tasks, if
// they are treated
// as equal. Therefore, we just compare the identity of the
// tasks of the task
// instances
ITask currentTask = session.get(index).getTask();
IIteration iteration = iterations.get(currentTask);
if (iteration != null) {
if ((iterationInstance == null)
|| (iterationInstance.getTask() != iteration)) {
iterationInstance = taskFactory
.createNewTaskInstance(iteration);
iterationInstances.get(iteration)
.add(iterationInstance);// TODO:: Don't create
// TaskInstances here,
// use a set of tasks
// instead
taskBuilder.addTaskInstance(session, index,
iterationInstance);
index++;
}
taskBuilder.addChild(iterationInstance, session.get(index));
taskBuilder.removeTaskInstance(session, index);
} else {
if (iterationInstance != null) {
iterationInstance = null;
}
index++;
}
}
}
for (Map.Entry> entry : iterationInstances
.entrySet()) {
harmonizeIterationInstancesModel(entry.getKey(), entry.getValue());
}
}
/**
*
* TODO clarify why this is done
*
*/
private void harmonizeIterationInstancesModel(IIteration iteration,
List iterationInstances) {
List iteratedTaskVariants = new LinkedList();
TaskInstanceComparator comparator = preparationTaskHandlingStrategy
.getTaskComparator();
// merge the lexically different variants of iterated task to a unique
// list
for (IIterationInstance iterationInstance : iterationInstances) {
for (ITaskInstance executionVariant : iterationInstance) {
ITask candidate = executionVariant.getTask();
boolean found = false;
for (ITask taskVariant : iteratedTaskVariants) {
if (comparator.areLexicallyEqual(taskVariant, candidate)) {
taskBuilder.setTask(executionVariant, taskVariant);
found = true;
break;
}
}
if (!found) {
iteratedTaskVariants.add(candidate);
}
}
}
// if there are more than one lexically different variant of iterated
// tasks, adapt the
// iteration model to be a selection of different variants. In this case
// also adapt
// the generated iteration instances to correctly contain selection
// instances. If there
// is only one variant of an iterated task, simply set this as the
// marked task of the
// iteration. In this case, the instances can be preserved as is
if (iteratedTaskVariants.size() > 1) {
ISelection selection = taskFactory.createNewSelection();
for (ITask variant : iteratedTaskVariants) {
taskBuilder.addChild(selection, variant);
}
taskBuilder.setMarkedTask(iteration, selection);
for (IIterationInstance instance : iterationInstances) {
for (int i = 0; i < instance.size(); i++) {
ISelectionInstance selectionInstance = taskFactory
.createNewTaskInstance(selection);
taskBuilder.setChild(selectionInstance, instance.get(i));
taskBuilder.setTaskInstance(instance, i, selectionInstance);
}
}
} else {
taskBuilder.setMarkedTask(iteration, iteratedTaskVariants.get(0));
}
}
/**
* @param appData
* @param m
* @return
*/
public ISequence matchAsSequence(RuleApplicationData appData, Match m) {
ISequence sequence = taskFactory.createNewSequence();
appData.newTaskCreated(sequence);
int[] first = m.getFirstSequence().getSequence();
int[] second = m.getSecondSequence().getSequence();
// Both sequences of a match are equally long
for (int i = 0; i < m.getFirstSequence().size(); i++) {
// Two gaps aligned to each other: Have not seen it happening so
// far, just to handle it
if (first[i] == -1 && second[i] == -1) {
// Do nothing here.
}
// Both events are equal, we can simply add the task referring to
// the number
else if (first[i] == second[i]) {
taskBuilder.addChild(sequence,
appData.getNumber2Task().get(first[i]));
}
// We have a gap in the first sequence, we need to add the task of
// the second sequence as optional
else if (first[i] == -1 && second[i] != -1) {
IOptional optional = taskFactory.createNewOptional();
appData.newTaskCreated(optional);
taskBuilder.setMarkedTask(optional, appData.getNumber2Task()
.get(second[i]));
taskBuilder.addChild(sequence, optional);
}
// We have a gap in the second sequence, we need to add the task of
// the first sequence as optional
else if (first[i] != -1 && second[i] == -1) {
IOptional optional = taskFactory.createNewOptional();
appData.newTaskCreated(optional);
taskBuilder.setMarkedTask(optional, appData.getNumber2Task()
.get(first[i]));
taskBuilder.addChild(sequence, optional);
}
// Both tasks are not equal, we need to insert a selection here.
// Check if the next position is not a selection
else if (i < first.length - 1) {
if ((first[i] != second[i])
&& ((first[i + 1] == second[i + 1]
|| first[i + 1] == -1 || second[i + 1] == -1))) {
ISelection selection = taskFactory.createNewSelection();
appData.newTaskCreated(selection);
taskBuilder.addChild(selection, appData.getNumber2Task()
.get(first[i]));
taskBuilder.addChild(selection, appData.getNumber2Task()
.get(second[i]));
taskBuilder.addChild(sequence, selection);
} else {
boolean selectionfound = true;
ISelection selection = taskFactory.createNewSelection();
appData.newTaskCreated(selection);
ISequence subsequence1 = taskFactory.createNewSequence();
appData.newTaskCreated(subsequence1);
ISequence subsequence2 = taskFactory.createNewSequence();
appData.newTaskCreated(subsequence2);
taskBuilder.addChild(selection, subsequence1);
taskBuilder.addChild(selection, subsequence2);
taskBuilder.addChild(sequence,selection);
while (i < first.length - 1 && selectionfound) {
selectionfound = false;
taskBuilder.addChild(subsequence1, appData
.getNumber2Task().get(first[i]));
taskBuilder.addChild(subsequence2, appData
.getNumber2Task().get(second[i]));
if (first[i + 1] != second[i + 1] && first[i + 1] != -1
&& second[i + 1] != -1) {
selectionfound = true;
}
else{
continue;
}
i++;
}
if(i==first.length-1 && selectionfound) {
taskBuilder.addChild(subsequence1, appData
.getNumber2Task().get(first[i]));
taskBuilder.addChild(subsequence2, appData
.getNumber2Task().get(second[i]));
}
}
}
else {
if ((first[i] != second[i])) {
ISelection selection = taskFactory.createNewSelection();
appData.newTaskCreated(selection);
taskBuilder.addChild(selection, appData.getNumber2Task()
.get(first[i]));
taskBuilder.addChild(selection, appData.getNumber2Task()
.get(second[i]));
taskBuilder.addChild(sequence, selection);
}
}
}
return sequence;
}
/**
*
* @param appData
* the rule application data combining all data used for applying
* this rule
*/
private void detectAndReplaceTasks(RuleApplicationData appData) {
Console.traceln(Level.FINE, "detecting and replacing tasks");
appData.getStopWatch().start("detecting tasks");
// Create NumberSequences
appData.setNumberSequences(this.createNumberSequences(appData));
// Generate pairwise alignments
//appData.setMatchseqs(generatePairwiseAlignments(appData));
generatePairwiseAlignments(appData);
//Searching each match in all other sessions, counting its occurences
searchMatchesInAllSessions(appData);
// Sort results to get the most occurring results
Console.traceln(Level.INFO, "sorting " + appData.getMatchseqs().size() + " results");
Comparator comparator = new Comparator() {
public int compare(Match m1, Match m2) {
return m2.occurenceCount() - m1.occurenceCount();
}
};
Collections.sort(appData.getMatchseqs(), comparator);
appData.getStopWatch().stop("detecting tasks");
// Replace matches in the sessions
Console.traceln(Level.INFO, "Replacing matches in sessions");
appData.getStopWatch().start("replacing tasks");
HashMap> replacedOccurences = new HashMap>();
for (int i = 0; i < appData.getMatchseqs().size(); i++) {
// Every pattern consists of 2 sequences, therefore the minimum
// occurrences here is 2.
// We just need the sequences also occurring in other sequences as
// well
if (appData.getMatchseqs().get(i).occurenceCount() > 2) {
appData.detectedAndReplacedTasks = true;
ISequence task = matchAsSequence(appData, appData.getMatchseqs().get(i));
invalidOccurence: for (Iterator it = appData.getMatchseqs()
.get(i).getOccurences().iterator(); it.hasNext();) {
MatchOccurence oc = it.next();
// Check if nothing has been replaced in the sequence we
// want to replace
if (replacedOccurences.get(oc.getSequenceId()) == null) {
replacedOccurences.put(oc.getSequenceId(),
new LinkedList());
} else {
// check if we have any replaced occurence with indexes
// smaller than ours. If so, we need to adjust our start
// and endpoints
// of the replacement.
// Also do a check if we have replaced this specific
// MatchOccurence in this sequence already. Jump to the
// next occurence if this is the case.
// This is no more neccessary once the matches are
// harmonized.
for (Iterator jt = replacedOccurences
.get(oc.getSequenceId()).iterator(); jt
.hasNext();) {
MatchOccurence tmpOC = jt.next();
if (oc.getStartindex() >= tmpOC.getStartindex()
&& oc.getStartindex() <= tmpOC
.getEndindex()) {
continue invalidOccurence;
}
if (oc.getEndindex() >= tmpOC.getStartindex()) {
continue invalidOccurence;
} else if (oc.getStartindex() > tmpOC.getEndindex()) {
int diff = tmpOC.getEndindex()
- tmpOC.getStartindex();
// Just to be sure.
if (diff > 0) {
oc.setStartindex(oc.getStartindex() - diff
+ 1);
oc.setEndindex(oc.getEndindex() - diff + 1);
} else {
Console.traceln(Level.WARNING,
"End index of a Match before start. This should never happen");
}
}
}
}
System.out.println("Replacing in sequence" + oc.getSequenceId());
ISequenceInstance sequenceInstances = RuleUtils
.createNewSubSequenceInRange(appData.getSessions()
.get(oc.getSequenceId()), oc
.getStartindex(), oc.getEndindex(), task,
taskFactory, taskBuilder);
// Adjust the length of the match regarding to the length of
// instance. (OptionalInstances may be shorter)
oc.setEndindex(oc.getStartindex()
+ sequenceInstances.size()
- RuleUtils.missedOptionals);
replacedOccurences.get(oc.getSequenceId()).add(oc);
}
}
}
//appData.setMatchseqs(null);
appData.getStopWatch().stop("replacing tasks");
}
private void searchMatchesInAllSessions(RuleApplicationData appData) {
Console.traceln(Level.INFO, "searching for patterns occuring most with " + nThreads + " threads");
//Prepare parallel search of matchseqs
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
int matchSeqSize=appData.getMatchseqs().size();
int interval = Math.round(matchSeqSize/nThreads);
int rest = matchSeqSize % nThreads;
for(int i =0;i100) {
if((count%(size/100)==0)) {
//Console.traceln(Level.INFO,("Thread" + Thread.currentThread().getName() + ": " + Math.round((float) count/size*100))+ "%");
System.out.println("Thread" + Thread.currentThread().getName() + ": " + Math.round((float) count/size*100)+ "%");
}
}
else {
//Console.traceln(Level.INFO,("Thread" + Thread.currentThread().getName() + ": " +Math.round((float) count/size*100))+ "%");
System.out.println("Thread" + Thread.currentThread().getName() + ": " +Math.round((float) count/size*100)+ "%");
}
}
private class ParallelMatchOcurrencesFinder implements Runnable {
private final RuleApplicationData appData;
private final int from;
private final int to;
ParallelMatchOcurrencesFinder(RuleApplicationData appData, int from, int to) {
this.appData = appData;
this.from = from;
this.to = to;
}
@Override
public void run() {
int count = 0;
int size=to-from;
for (int i=from; i pattern
.getFirstSequence().size())
continue;
for (int j = 0; j < appData.getNumberSequences().size(); j++) {
LinkedList startpositions = appData
.getNumberSequences().get(j).containsPattern(pattern);
if (startpositions.size() > 0) {
for (Iterator jt = startpositions.iterator(); jt
.hasNext();) {
int start = jt.next();
pattern.addOccurence(new MatchOccurence(start, start
+ pattern.size(), j));
}
}
}
}
}
}
private class ParallelPairwiseAligner implements Runnable {
private final RuleApplicationData appData;
private final int from;
private final int to;
ParallelPairwiseAligner(RuleApplicationData appData, int from, int to) {
this.appData = appData;
this.from = from;
this.to = to;
}
@Override
public void run() {
int count = 0;
int size=to-from;
for (int i=from; i generatePairwiseAlignments(RuleApplicationData appData) {
private void generatePairwiseAlignments(RuleApplicationData appData) {
int numberSeqSize = appData.getNumberSequences().size();
appData.matchseqs = new LinkedList();
//Checking if i have an already calculated file result of this action in the working directory
//File aligned = new File("aligned" + iteration + ".dat");
//if(!(aligned.exists() && !aligned.isDirectory())) {
Console.traceln(Level.INFO, "generating pairwise alignments from " + numberSeqSize + " sessions with " + nThreads + " threads");
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
int interval = Math.round(numberSeqSize/nThreads);
int rest = numberSeqSize % nThreads;
for (int i = 0; i < numberSeqSize-interval; i+=interval) {
int offset = 0;
if(rest!=0) {
offset=1;
rest--;
}
int from = i;
int to = i+interval+offset;
System.out.println("Creating thread for sessions " + from + " till " + to);
ParallelPairwiseAligner aligner = new ParallelPairwiseAligner(appData,from,to);
executor.execute(aligner);
}
executor.shutdown();
try {
executor.awaitTermination(10, TimeUnit.MINUTES);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//GlobalDataContainer.getInstance().addData("aligned" + iteration, appData);
//saveAppData("aligned" + iteration);
// return result;
}
//else {
// Console.traceln(Level.INFO,"loading matches from file");
// appData = loadAppData("aligned"+iteration);
// return appData.getMatchseqs();
//}
/**
*
*/
private static class RuleApplicationData implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7559657686755522960L;
private HashMap number2task;
// TODO: We Actually just need number2task here, this structure can be removed in the future.
private HashSet uniqueTasks;
ObjectDistanceSubstitionMatrix submat;
LinkedList matchseqs;
private ArrayList numberseqs;
private LinkedList newTasks;
/**
*
*/
private List sessions;
/**
*
*/
private boolean detectedAndReplacedTasks;
/**
*
*/
private RuleApplicationResult result;
/**
*
*/
private StopWatch stopWatch;
/**
*
*/
private RuleApplicationData(List sessions) {
this.sessions = sessions;
numberseqs = new ArrayList();
uniqueTasks = new HashSet();
number2task = new HashMap();
stopWatch = new StopWatch();
result = new RuleApplicationResult();
submat= new ObjectDistanceSubstitionMatrix(6,-3,false);
newTasks = new LinkedList();
this.detectedAndReplacedTasks = true;
}
public LinkedList getMatchseqs() {
return matchseqs;
}
private ObjectDistanceSubstitionMatrix getSubmat() {
return submat;
}
private void resetNewlyCreatedTasks() {
uniqueTasks.addAll(newTasks);
newTasks.clear();
}
private void newTaskCreated(ITask task) {
number2task.put(task.getId(), task);
newTasks.add(task);
}
/**
* @return the UserSessions as List.
*/
private List getSessions() {
return sessions;
}
private HashSet getUniqueTasks() {
return uniqueTasks;
}
private void setNumberSequences(ArrayList numberseqs) {
this.numberseqs = numberseqs;
}
private ArrayList getNumberSequences() {
return numberseqs;
}
private void updateSubstitutionMatrix() {
submat.update(getNewTasks());
resetNewlyCreatedTasks();
}
/**
*
*/
private boolean detectedAndReplacedTasks() {
return detectedAndReplacedTasks;
}
/**
* @return the result
*/
private RuleApplicationResult getResult() {
return result;
}
public LinkedList getNewTasks() {
return newTasks;
}
/**
* @return the stopWatch
*/
private StopWatch getStopWatch() {
return stopWatch;
}
private HashMap getNumber2Task() {
return number2task;
}
}
}