Changeset 1733 for branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskModel.java
- Timestamp:
- 09/05/14 19:33:12 (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/autoquest-core-tasktrees-alignment/src/main/java/de/ugoe/cs/autoquest/tasktrees/treeimpl/TaskModel.java
r1494 r1733 43 43 * <p> 44 44 * this is the default implementation of the interface {@link ITaskModel}. It 45 * does not do anything fancy except implementing the interface. It also calculates on 46 * initialisations the measures for diverse metrics of the task belonging to the model 45 * does not do anything fancy except implementing the interface. It also 46 * calculates on initialisations the measures for diverse metrics of the task 47 * belonging to the model 47 48 * </p> 48 49 * … … 50 51 */ 51 52 class TaskModel implements ITaskModel { 52 53 /** 54 * <p> 55 * default serial version UID 56 * </p> 57 */ 58 private static final long serialVersionUID = 1L; 59 60 /** 61 * <p> 62 * all metrics calculated by this type of task model 63 * </p> 64 */ 65 private static final TaskMetric[] taskMetrics = new TaskMetric[] 66 { TaskMetric.COUNT, 67 TaskMetric.DEPTH, 68 TaskMetric.EVENT_COVERAGE, 69 TaskMetric.EVENT_COVERAGE_RATIO, 70 TaskMetric.EVENT_COVERAGE_QUANTILE }; 71 72 /** 73 * <p> 74 * the user sessions belonging to the model 75 * </p> 76 */ 77 private List<IUserSession> userSessions; 78 79 /** 80 * <p> 81 * index for effectively accessing the model and calculating statistics about it 82 * </p> 83 */ 84 private transient TaskModelIndex index = null; 85 86 /** 87 * <p> 88 * initializes the task model with the user sessions out of which the tasks are extracted 89 * </p> 90 * 91 * @param userSessions as described 92 */ 93 TaskModel(List<IUserSession> userSessions) { 94 if ((userSessions == null) || (userSessions.size() == 0)) { 95 throw new IllegalArgumentException("user sessions must not be null"); 96 } 97 98 this.userSessions = userSessions; 99 } 100 101 102 /* (non-Javadoc) 103 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getUserSessions() 104 */ 105 @Override 106 public List<IUserSession> getUserSessions() { 107 ensureInitialized(); 108 return Collections.unmodifiableList(userSessions); 109 } 110 111 112 /* (non-Javadoc) 113 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTasks() 114 */ 115 @Override 116 public Collection<ITask> getTasks() { 117 ensureInitialized(); 118 return Collections.unmodifiableCollection(index.taskMap.keySet()); 119 } 120 121 122 /* (non-Javadoc) 123 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTaskInfo(ITask) 124 */ 125 @Override 126 public ITaskInfo getTaskInfo(ITask task) { 127 ensureInitialized(); 128 return index.taskMap.get(task); 129 } 130 131 /* (non-Javadoc) 132 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getAllMetrics() 133 */ 134 @Override 135 public TaskMetric[] getAllMetrics() { 136 return taskMetrics; 137 } 138 139 140 /* (non-Javadoc) 141 * @see java.lang.Object#clone() 142 */ 143 @Override 144 public TaskModel clone() { 145 return new TaskModel(userSessions); 146 } 147 148 /** 149 * <p> 150 * internal convenience method that initializes the internal index and calculates all measures 151 * for metrics available for the tasks 152 * </p> 153 */ 154 private synchronized void ensureInitialized() { 155 if (index == null) { 156 index = new TaskModelIndex(); 157 158 for (IUserSession session : this.userSessions) { 159 for (ITaskInstance taskInstance : session) { 160 index.handleTaskInstance(taskInstance, null); 161 } 162 } 163 164 // count all events covered 165 int allEventsCovered = 0; 166 Collection<ITask> tasks = getTasks(); 167 for (ITask task : tasks) { 168 if (task instanceof IEventTask) { 169 allEventsCovered += task.getInstances().size(); 170 } 171 } 172 173 int[] eventCoverageRatios = new int[tasks.size()]; 174 int i = 0; 175 176 // add some further measures 177 for (ITask task : tasks) { 178 TaskInfo info = index.taskMap.get(task); 179 info.addMeasure(TaskMetric.EVENT_COVERAGE_RATIO); 180 181 int coveredEvents = info.getMeasureValue(TaskMetric.EVENT_COVERAGE); 182 int coverageRatio = 0; 183 184 if (allEventsCovered > 0) { 185 coverageRatio = (coveredEvents * 1000) / allEventsCovered; 186 } 187 188 eventCoverageRatios[i++] = coverageRatio; 189 info.setCount(TaskMetric.EVENT_COVERAGE_RATIO, null, coverageRatio); 190 } 191 192 Arrays.sort(eventCoverageRatios); 193 194 // add some further measures 195 for (ITask task : tasks) { 196 TaskInfo info = index.taskMap.get(task); 197 info.addMeasure(TaskMetric.EVENT_COVERAGE_QUANTILE); 198 int quantile = Arrays.binarySearch 199 (eventCoverageRatios, info.getMeasureValue(TaskMetric.EVENT_COVERAGE_RATIO)); 200 201 quantile = 1000 * quantile / eventCoverageRatios.length; 202 203 info.setCount(TaskMetric.EVENT_COVERAGE_QUANTILE, null, quantile); 204 } 205 206 //index.dumpToCSV(System.out); 207 /*try { 208 OutputStream stream = new FileOutputStream(new File("tasks.csv")); 209 index.dumpToCSV(new PrintStream(stream)); 210 stream.close(); 211 } 212 catch (FileNotFoundException e) { 213 e.printStackTrace(); 214 }*/ 215 } 216 217 } 218 219 /** 220 * <p> 221 * the index of task infos used internally. The index is created once and while that filled 222 * with task infos for each observed task containing all measures for metrics belonging 223 * to the tasks. 224 * </p> 225 * 226 * @author Patrick Harms 227 */ 228 private static class TaskModelIndex { 229 230 /** 231 * <p> 232 * the tasks contained in the user session belonging to the model as well as statistical 233 * infos about them 234 * </p> 235 */ 236 private Map<ITask, TaskInfo> taskMap = new HashMap<ITask, TaskInfo>(); 237 238 /** 239 * <p> 240 * called on initialization to fill the index with infos about the given task instance 241 * as well as to calculate the appropriate metrics 242 * </p> 243 */ 244 private int[] handleTaskInstance(ITaskInstance taskInstance, ITask context) { 245 int eventTaskInstancesCovered = 0; 246 int depth = 0; 247 248 if (taskInstance instanceof ITaskInstanceList) { 249 for (ITaskInstance child : (ITaskInstanceList) taskInstance) { 250 int[] measures = handleTaskInstance(child, taskInstance.getTask()); 251 eventTaskInstancesCovered += measures[0]; 252 depth = Math.max(depth, measures[1]); 253 } 254 255 if ((((ITaskInstanceList) taskInstance).size() == 0) && 256 (taskInstance instanceof IIterationInstance)) 257 { 258 // ensure also empty task infos for unselected variants 259 ensureTaskInfo(((IIteration) taskInstance.getTask()).getMarkedTask(), context); 260 } 261 } 262 else if (taskInstance instanceof ISelectionInstance) { 263 ITaskInstance child = ((ISelectionInstance) taskInstance).getChild(); 264 int[] measures = handleTaskInstance(child, taskInstance.getTask()); 265 eventTaskInstancesCovered += measures[0]; 266 depth = Math.max(depth, measures[1]); 267 268 // ensure also empty task infos for unselected variants 269 for (ITask otherChildTask : ((ISelection) taskInstance.getTask()).getChildren()) { 270 ensureTaskInfo(otherChildTask, context); 271 } 272 } 273 else if (taskInstance instanceof IOptionalInstance) { 274 ITaskInstance child = ((IOptionalInstance) taskInstance).getChild(); 275 if (child != null) { 276 int[] measures = handleTaskInstance(child, taskInstance.getTask()); 277 eventTaskInstancesCovered += measures[0]; 278 depth = Math.max(depth, measures[1]); 279 } 280 else { 281 // ensure also empty task infos for unselected variants 282 ensureTaskInfo(((IOptional) taskInstance.getTask()).getMarkedTask(), context); 283 } 284 } 285 else if (taskInstance instanceof IEventTaskInstance) { 286 eventTaskInstancesCovered = 1; 287 } 288 289 depth++; 290 291 ensureTaskInfo(taskInstance.getTask(), context, eventTaskInstancesCovered, depth); 292 293 return new int[] { eventTaskInstancesCovered, depth }; 294 } 295 296 /** 297 * <p> 298 * internal convenience method to build the task model during initialization 299 * </p> 300 */ 301 private void ensureTaskInfo(ITask task, ITask context) { 302 ensureTaskInfo(task, context, 0, 0); 303 304 if (task instanceof IStructuringTemporalRelationship) { 305 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 306 ensureTaskInfo(child, task); 307 } 308 } 309 else if (task instanceof IMarkingTemporalRelationship) { 310 ensureTaskInfo(((IMarkingTemporalRelationship) task).getMarkedTask(), task); 311 } 312 313 } 314 315 /** 316 * <p> 317 * internal convenience method to build the task model during initialization. Adds a new 318 * task info object to the map for the provided task and fills it with measures. If there 319 * are already some task infos for the task, the contained measures are updated according 320 * to the parameters. 321 * </p> 322 */ 323 private void ensureTaskInfo(ITask task, 324 ITask context, 325 int eventTaskInstancesCovered, 326 int depth) 327 { 328 TaskInfo taskInfo = taskMap.get(task); 329 330 if (taskInfo == null) { 331 taskInfo = new TaskInfo(task); 332 taskInfo.addMeasure(TaskMetric.COUNT); 333 taskInfo.addMeasure(TaskMetric.EVENT_COVERAGE); 334 taskInfo.addMeasure(TaskMetric.DEPTH); 335 taskMap.put(task, taskInfo); 336 337 taskInfo.setCount(TaskMetric.DEPTH, null, getDepth(task)); 338 } 339 340 taskInfo.increaseCount(TaskMetric.COUNT, context, 1); 341 taskInfo.increaseCount(TaskMetric.EVENT_COVERAGE, context, eventTaskInstancesCovered); 342 343 taskInfo.setCount(TaskMetric.DEPTH, context, depth); 344 } 345 346 /** 347 * <p> 348 * internal convenience method to calculate the maximum depth of a task 349 * </p> 350 */ 351 private int getDepth(ITask task) { 352 if (task instanceof IMarkingTemporalRelationship) { 353 return getDepth(((IMarkingTemporalRelationship) task).getMarkedTask()) + 1; 354 } 355 else if (task instanceof IStructuringTemporalRelationship) { 356 int maxDepth = 0; 357 358 for (ITask child : ((IStructuringTemporalRelationship) task).getChildren()) { 359 maxDepth = Math.max(maxDepth, getDepth(child)); 360 } 361 362 return maxDepth + 1; 363 } 364 else { 365 // event tasks 366 return 1; 367 } 368 } 369 370 /** 371 * 372 */ 373 /*private void dumpToCSV(PrintStream out) { 374 out.println("taskid;depth;count;eventcoverage;eventcoverageratio"); 375 376 for (Map.Entry<ITask, TaskInfo> entry : taskMap.entrySet()) { 377 out.print(entry.getKey().getId()); 378 out.print(';'); 379 out.print(entry.getValue().getMeasureValue(TaskMetric.DEPTH)); 380 out.print(';'); 381 out.print(entry.getValue().getMeasureValue(TaskMetric.COUNT)); 382 out.print(';'); 383 out.print(entry.getValue().getMeasureValue(TaskMetric.EVENT_COVERAGE)); 384 out.print(';'); 385 out.print(entry.getValue().getMeasureValue(TaskMetric.EVENT_COVERAGE_RATIO)); 386 out.println(); 387 } 388 }*/ 389 390 } 391 53 54 /** 55 * <p> 56 * the index of task infos used internally. The index is created once and 57 * while that filled with task infos for each observed task containing all 58 * measures for metrics belonging to the tasks. 59 * </p> 60 * 61 * @author Patrick Harms 62 */ 63 private static class TaskModelIndex { 64 65 /** 66 * <p> 67 * the tasks contained in the user session belonging to the model as 68 * well as statistical infos about them 69 * </p> 70 */ 71 private final Map<ITask, TaskInfo> taskMap = new HashMap<ITask, TaskInfo>(); 72 73 /** 74 * <p> 75 * internal convenience method to build the task model during 76 * initialization 77 * </p> 78 */ 79 private void ensureTaskInfo(ITask task, ITask context) { 80 ensureTaskInfo(task, context, 0, 0); 81 82 if (task instanceof IStructuringTemporalRelationship) { 83 for (final ITask child : ((IStructuringTemporalRelationship) task) 84 .getChildren()) { 85 ensureTaskInfo(child, task); 86 } 87 } else if (task instanceof IMarkingTemporalRelationship) { 88 ensureTaskInfo( 89 ((IMarkingTemporalRelationship) task).getMarkedTask(), 90 task); 91 } 92 93 } 94 95 /** 96 * <p> 97 * internal convenience method to build the task model during 98 * initialization. Adds a new task info object to the map for the 99 * provided task and fills it with measures. If there are already some 100 * task infos for the task, the contained measures are updated according 101 * to the parameters. 102 * </p> 103 */ 104 private void ensureTaskInfo(ITask task, ITask context, 105 int eventTaskInstancesCovered, int depth) { 106 TaskInfo taskInfo = taskMap.get(task); 107 108 if (taskInfo == null) { 109 taskInfo = new TaskInfo(task); 110 taskInfo.addMeasure(TaskMetric.COUNT); 111 taskInfo.addMeasure(TaskMetric.EVENT_COVERAGE); 112 taskInfo.addMeasure(TaskMetric.DEPTH); 113 taskMap.put(task, taskInfo); 114 115 taskInfo.setCount(TaskMetric.DEPTH, null, getDepth(task)); 116 } 117 118 taskInfo.increaseCount(TaskMetric.COUNT, context, 1); 119 taskInfo.increaseCount(TaskMetric.EVENT_COVERAGE, context, 120 eventTaskInstancesCovered); 121 122 taskInfo.setCount(TaskMetric.DEPTH, context, depth); 123 } 124 125 /** 126 * <p> 127 * internal convenience method to calculate the maximum depth of a task 128 * </p> 129 */ 130 private int getDepth(ITask task) { 131 if (task instanceof IMarkingTemporalRelationship) { 132 return getDepth(((IMarkingTemporalRelationship) task) 133 .getMarkedTask()) + 1; 134 } else if (task instanceof IStructuringTemporalRelationship) { 135 int maxDepth = 0; 136 137 for (final ITask child : ((IStructuringTemporalRelationship) task) 138 .getChildren()) { 139 maxDepth = Math.max(maxDepth, getDepth(child)); 140 } 141 142 return maxDepth + 1; 143 } else { 144 // event tasks 145 return 1; 146 } 147 } 148 149 /** 150 * <p> 151 * called on initialization to fill the index with infos about the given 152 * task instance as well as to calculate the appropriate metrics 153 * </p> 154 */ 155 private int[] handleTaskInstance(ITaskInstance taskInstance, 156 ITask context) { 157 int eventTaskInstancesCovered = 0; 158 int depth = 0; 159 160 if (taskInstance instanceof ITaskInstanceList) { 161 for (final ITaskInstance child : (ITaskInstanceList) taskInstance) { 162 final int[] measures = handleTaskInstance(child, 163 taskInstance.getTask()); 164 eventTaskInstancesCovered += measures[0]; 165 depth = Math.max(depth, measures[1]); 166 } 167 168 if ((((ITaskInstanceList) taskInstance).size() == 0) 169 && (taskInstance instanceof IIterationInstance)) { 170 // ensure also empty task infos for unselected variants 171 ensureTaskInfo( 172 ((IIteration) taskInstance.getTask()) 173 .getMarkedTask(), 174 context); 175 } 176 } else if (taskInstance instanceof ISelectionInstance) { 177 final ITaskInstance child = ((ISelectionInstance) taskInstance) 178 .getChild(); 179 final int[] measures = handleTaskInstance(child, 180 taskInstance.getTask()); 181 eventTaskInstancesCovered += measures[0]; 182 depth = Math.max(depth, measures[1]); 183 184 // ensure also empty task infos for unselected variants 185 for (final ITask otherChildTask : ((ISelection) taskInstance 186 .getTask()).getChildren()) { 187 ensureTaskInfo(otherChildTask, context); 188 } 189 } else if (taskInstance instanceof IOptionalInstance) { 190 final ITaskInstance child = ((IOptionalInstance) taskInstance) 191 .getChild(); 192 if (child != null) { 193 final int[] measures = handleTaskInstance(child, 194 taskInstance.getTask()); 195 eventTaskInstancesCovered += measures[0]; 196 depth = Math.max(depth, measures[1]); 197 } else { 198 // ensure also empty task infos for unselected variants 199 ensureTaskInfo( 200 ((IOptional) taskInstance.getTask()) 201 .getMarkedTask(), 202 context); 203 } 204 } else if (taskInstance instanceof IEventTaskInstance) { 205 eventTaskInstancesCovered = 1; 206 } 207 208 depth++; 209 210 ensureTaskInfo(taskInstance.getTask(), context, 211 eventTaskInstancesCovered, depth); 212 213 return new int[] { eventTaskInstancesCovered, depth }; 214 } 215 216 /** 217 * 218 */ 219 /* 220 * private void dumpToCSV(PrintStream out) { 221 * out.println("taskid;depth;count;eventcoverage;eventcoverageratio"); 222 * 223 * for (Map.Entry<ITask, TaskInfo> entry : taskMap.entrySet()) { 224 * out.print(entry.getKey().getId()); out.print(';'); 225 * out.print(entry.getValue().getMeasureValue(TaskMetric.DEPTH)); 226 * out.print(';'); 227 * out.print(entry.getValue().getMeasureValue(TaskMetric.COUNT)); 228 * out.print(';'); 229 * out.print(entry.getValue().getMeasureValue(TaskMetric. 230 * EVENT_COVERAGE)); out.print(';'); 231 * out.print(entry.getValue().getMeasureValue 232 * (TaskMetric.EVENT_COVERAGE_RATIO)); out.println(); } } 233 */ 234 235 } 236 237 /** 238 * <p> 239 * default serial version UID 240 * </p> 241 */ 242 private static final long serialVersionUID = 1L; 243 244 /** 245 * <p> 246 * all metrics calculated by this type of task model 247 * </p> 248 */ 249 private static final TaskMetric[] taskMetrics = new TaskMetric[] { 250 TaskMetric.COUNT, TaskMetric.DEPTH, TaskMetric.EVENT_COVERAGE, 251 TaskMetric.EVENT_COVERAGE_RATIO, TaskMetric.EVENT_COVERAGE_QUANTILE }; 252 253 /** 254 * <p> 255 * the user sessions belonging to the model 256 * </p> 257 */ 258 private final List<IUserSession> userSessions; 259 260 /** 261 * <p> 262 * index for effectively accessing the model and calculating statistics 263 * about it 264 * </p> 265 */ 266 private transient TaskModelIndex index = null; 267 268 /** 269 * <p> 270 * initializes the task model with the user sessions out of which the tasks 271 * are extracted 272 * </p> 273 * 274 * @param userSessions 275 * as described 276 */ 277 TaskModel(List<IUserSession> userSessions) { 278 if ((userSessions == null) || (userSessions.size() == 0)) { 279 throw new IllegalArgumentException("user sessions must not be null"); 280 } 281 282 this.userSessions = userSessions; 283 } 284 285 /* 286 * (non-Javadoc) 287 * 288 * @see java.lang.Object#clone() 289 */ 290 @Override 291 public TaskModel clone() { 292 return new TaskModel(userSessions); 293 } 294 295 /** 296 * <p> 297 * internal convenience method that initializes the internal index and 298 * calculates all measures for metrics available for the tasks 299 * </p> 300 */ 301 private synchronized void ensureInitialized() { 302 if (index == null) { 303 index = new TaskModelIndex(); 304 305 for (final IUserSession session : this.userSessions) { 306 for (final ITaskInstance taskInstance : session) { 307 index.handleTaskInstance(taskInstance, null); 308 } 309 } 310 311 // count all events covered 312 int allEventsCovered = 0; 313 final Collection<ITask> tasks = getTasks(); 314 for (final ITask task : tasks) { 315 if (task instanceof IEventTask) { 316 allEventsCovered += task.getInstances().size(); 317 } 318 } 319 320 final int[] eventCoverageRatios = new int[tasks.size()]; 321 int i = 0; 322 323 // add some further measures 324 for (final ITask task : tasks) { 325 final TaskInfo info = index.taskMap.get(task); 326 info.addMeasure(TaskMetric.EVENT_COVERAGE_RATIO); 327 328 final int coveredEvents = info 329 .getMeasureValue(TaskMetric.EVENT_COVERAGE); 330 int coverageRatio = 0; 331 332 if (allEventsCovered > 0) { 333 coverageRatio = (coveredEvents * 1000) / allEventsCovered; 334 } 335 336 eventCoverageRatios[i++] = coverageRatio; 337 info.setCount(TaskMetric.EVENT_COVERAGE_RATIO, null, 338 coverageRatio); 339 } 340 341 Arrays.sort(eventCoverageRatios); 342 343 // add some further measures 344 for (final ITask task : tasks) { 345 final TaskInfo info = index.taskMap.get(task); 346 info.addMeasure(TaskMetric.EVENT_COVERAGE_QUANTILE); 347 int quantile = Arrays.binarySearch(eventCoverageRatios, 348 info.getMeasureValue(TaskMetric.EVENT_COVERAGE_RATIO)); 349 350 quantile = (1000 * quantile) / eventCoverageRatios.length; 351 352 info.setCount(TaskMetric.EVENT_COVERAGE_QUANTILE, null, 353 quantile); 354 } 355 356 // index.dumpToCSV(System.out); 357 /* 358 * try { OutputStream stream = new FileOutputStream(new 359 * File("tasks.csv")); index.dumpToCSV(new PrintStream(stream)); 360 * stream.close(); } catch (FileNotFoundException e) { 361 * e.printStackTrace(); } 362 */ 363 } 364 365 } 366 367 /* 368 * (non-Javadoc) 369 * 370 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getAllMetrics() 371 */ 372 @Override 373 public TaskMetric[] getAllMetrics() { 374 return taskMetrics; 375 } 376 377 /* 378 * (non-Javadoc) 379 * 380 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTaskInfo(ITask) 381 */ 382 @Override 383 public ITaskInfo getTaskInfo(ITask task) { 384 ensureInitialized(); 385 return index.taskMap.get(task); 386 } 387 388 /* 389 * (non-Javadoc) 390 * 391 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getTasks() 392 */ 393 @Override 394 public Collection<ITask> getTasks() { 395 ensureInitialized(); 396 return Collections.unmodifiableCollection(index.taskMap.keySet()); 397 } 398 399 /* 400 * (non-Javadoc) 401 * 402 * @see de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskModel#getUserSessions() 403 */ 404 @Override 405 public List<IUserSession> getUserSessions() { 406 ensureInitialized(); 407 return Collections.unmodifiableList(userSessions); 408 } 392 409 393 410 }
Note: See TracChangeset
for help on using the changeset viewer.