EMMA Coverage Report (generated Sun Feb 05 10:43:15 CET 2012)
[all classes][de.uka.ipd.sdq.reliability.solver.pcm2markov]

COVERAGE SUMMARY FOR SOURCE FILE [MarkovTransformationResult.java]

nameclass, %method, %block, %line, %
MarkovTransformationResult.java0%   (0/1)0%   (0/17)0%   (0/600)0%   (0/136)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MarkovTransformationResult0%   (0/1)0%   (0/17)0%   (0/600)0%   (0/136)
<static initializer> 0%   (0/1)0%   (0/5)0%   (0/3)
MarkovTransformationResult (PCMSolverWorkflowRunConfiguration, MarkovTransfor... 0%   (0/1)0%   (0/47)0%   (0/14)
addPhysicalStateResults (MarkovChain, double [][], double): void 0%   (0/1)0%   (0/320)0%   (0/72)
getCumulatedFailureTypeProbabilities (): Map 0%   (0/1)0%   (0/3)0%   (0/1)
getCumulatedPhysicalStateProbability (): double 0%   (0/1)0%   (0/3)0%   (0/1)
getFailureType (String): MarkovFailureType 0%   (0/1)0%   (0/32)0%   (0/6)
getLogHeadings (): String 0%   (0/1)0%   (0/50)0%   (0/9)
getLogSingleResults (double, double): String 0%   (0/1)0%   (0/60)0%   (0/8)
getNumberOfPhysicalSystemStates (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getPhysicalStateEvaluationCount (): long 0%   (0/1)0%   (0/3)0%   (0/1)
getResultChain (): MarkovChain 0%   (0/1)0%   (0/3)0%   (0/1)
getScenario (): UsageScenario 0%   (0/1)0%   (0/3)0%   (0/1)
getSuccessProbability (): double 0%   (0/1)0%   (0/3)0%   (0/1)
hasRequiredAccuracy (int): boolean 0%   (0/1)0%   (0/17)0%   (0/4)
isDoApproximate (): boolean 0%   (0/1)0%   (0/23)0%   (0/4)
resolveFile (String): String 0%   (0/1)0%   (0/21)0%   (0/7)
setApproximate (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)

1package de.uka.ipd.sdq.reliability.solver.pcm2markov;
2 
3import java.io.BufferedWriter;
4import java.io.File;
5import java.io.FileWriter;
6import java.io.IOException;
7import java.net.URL;
8import java.util.HashMap;
9import java.util.List;
10import java.util.Map;
11 
12import org.apache.log4j.Logger;
13import org.eclipse.core.runtime.FileLocator;
14 
15import de.uka.ipd.sdq.markov.MarkovChain;
16import de.uka.ipd.sdq.markov.State;
17import de.uka.ipd.sdq.pcm.usagemodel.UsageScenario;
18import de.uka.ipd.sdq.pcmsolver.runconfig.PCMSolverWorkflowRunConfiguration;
19import de.uka.ipd.sdq.reliability.core.MarkovFailureType;
20 
21/**
22 * Aggregates the results of a PCM2MarkovTransformation.
23 * 
24 * @author brosch
25 * 
26 */
27public class MarkovTransformationResult {
28 
29        /**
30         * A logger to give detailed information about the PCM instance
31         * transformation.
32         */
33        private static Logger logger = Logger
34                        .getLogger(MarkovTransformationResult.class.getName());
35 
36        /**
37         * Indicates if an approximation scheme shall be used for printing of
38         * probabilities.
39         */
40        private boolean approximate;
41 
42        /**
43         * Configuration options of the transformation.
44         */
45        private PCMSolverWorkflowRunConfiguration configuration;
46 
47        /**
48         * Overall failure type probabilities, accumulated over all considered
49         * physical system states.
50         */
51        private Map<MarkovFailureType, Double> cumulatedFailureTypeProbabilities = new HashMap<MarkovFailureType, Double>();
52 
53        /**
54         * Overall physical state probability, accumulated over all considered
55         * physical system states.
56         */
57        private double cumulatedPhysicalStateProbability;
58 
59        /**
60         * Overall success probability, accumulated over all considered physical
61         * system states.
62         */
63        private double cumulatedSuccessProbability;
64 
65        /**
66         * The list of potential failure types.
67         */
68        private List<MarkovFailureType> failureTypes;
69 
70        /**
71         * A helper class providing functionality for Markov chains.
72         */
73        private MarkovBuilder markovBuilder;
74 
75        /**
76         * Holds state information required during the PCM2MarkovTransformation.
77         */
78        private MarkovTransformationSource markovSource;
79 
80        /**
81         * Indicates the number of physical system states (which is n^2 for n
82         * resources).
83         */
84        private long numberOfPhysicalSystemStates;
85 
86        /**
87         * Counts the evaluated physical system states.
88         */
89        private long physicalStateEvaluationCount;
90 
91        /**
92         * Holds the Makov chain that results from the transformation.
93         */
94        private MarkovChain resultChain;
95 
96        /**
97         * The usage scenario which has been evaluated.
98         */
99        private UsageScenario scenario;
100 
101        /**
102         * Creates a new Markov results aggregator.
103         * 
104         * @param configuration
105         *            configuration options of the transformation
106         * @param markovSource
107         *            the Markov state holder
108         * @param scenario
109         *            the usage scenario to evaluate
110         * @param failureTypes
111         *            the list of potential failure types
112         */
113        public MarkovTransformationResult(
114                        final PCMSolverWorkflowRunConfiguration configuration,
115                        final MarkovTransformationSource markovSource,
116                        final UsageScenario scenario,
117                        final List<MarkovFailureType> failureTypes) {
118                this.configuration = configuration;
119                this.cumulatedPhysicalStateProbability = 0.0;
120                this.cumulatedSuccessProbability = 0.0;
121                this.markovBuilder = new MarkovBuilder(false);
122                this.markovSource = markovSource;
123                this.physicalStateEvaluationCount = 0;
124                this.numberOfPhysicalSystemStates = (long) Math.pow(2, markovSource
125                                .getUnreliableResourceDescriptors().size());
126                this.resultChain = null;
127                this.scenario = scenario;
128                this.failureTypes = failureTypes;
129        }
130 
131        /**
132         * Adds the results of the evaluation of a single physical system state
133         * during the PCM2Markov transformation.
134         * 
135         * @param resultChain
136         *            the Markov chain resulting from the evaluation of the physical
137         *            system state
138         * @param markovProbabilityMatrix
139         *            the matrix with the probabilities to get from state i to state
140         *            j in the Markov chain
141         * @param physicalStateProbability
142         *            the probability of the evaluated physical system state to
143         *            occur
144         */
145        public void addPhysicalStateResults(final MarkovChain resultChain,
146                        final double[][] markovProbabilityMatrix,
147                        final double physicalStateProbability) {
148 
149                // Check plausibility of input parameters:
150                if (physicalStateProbability < 0.0 || physicalStateProbability > 1.0) {
151                        throw new MarkovException("Illegal physical state probability ("
152                                        + physicalStateProbability
153                                        + "). The value must be in [0,1].");
154                }
155 
156                // Store the first resulting Markov Chain:
157                if (physicalStateEvaluationCount == 0) {
158                        this.resultChain = resultChain;
159                }
160 
161                // Get the indices of the Start and Success States:
162                int indexStart = markovBuilder.indexOf(resultChain, markovBuilder
163                                .getStartState(resultChain));
164                int indexSuccess = markovBuilder.indexOf(resultChain, markovBuilder
165                                .getSuccessState(resultChain));
166 
167                // Check plausibility of Markov probabilities:
168                double successProbability = markovProbabilityMatrix[indexStart][indexSuccess];
169                if (successProbability < 0.0 || successProbability > 1.0) {
170                        // It should never happen that the success probability is outside
171                        // [0,1].
172                        // The only feasible explanation is a rounding error (which has been
173                        // observed for certain sample PCM instances):
174                        double correctedSuccessProbability = (successProbability < 0.5) ? 0.0
175                                        : 1.0;
176                        logger.warn("Illegal success probability " + successProbability
177                                        + " outside [0,1]. Assuming a rounding error. "
178                                        + "Setting success probability to "
179                                        + correctedSuccessProbability);
180                        successProbability = correctedSuccessProbability;
181                }
182 
183                // Accumulate results:
184                cumulatedPhysicalStateProbability += physicalStateProbability;
185                cumulatedSuccessProbability += physicalStateProbability
186                                * successProbability;
187 
188                // Consider also the failure type probabilities:
189                List<State> failureStates = markovBuilder.getFailureStates(resultChain);
190                for (int i = 0; i < failureStates.size(); i++) {
191 
192                        // Check plausibility of Markov probabilities:
193                        double failureTypeProbability = markovProbabilityMatrix[indexStart][markovBuilder
194                                        .indexOf(resultChain, failureStates.get(i))];
195                        if (failureTypeProbability < 0.0 || failureTypeProbability > 1.0) {
196                                throw new MarkovException("Illegal failure type probability ("
197                                                + failureTypeProbability
198                                                + "). The value must be in [0,1].");
199                        }
200 
201                        // Determine the failure type probability for this physical system
202                        // state:
203                        double failureTypeProbabilityDelta = physicalStateProbability
204                                        * failureTypeProbability;
205 
206                        // Add the failure type probability to the already existing value:
207                        String failureTypeId = markovBuilder.getFailureTypeId(failureStates
208                                        .get(i));
209                        MarkovFailureType failureType = getFailureType(failureTypeId);
210 
211                        Double failureProbability = cumulatedFailureTypeProbabilities
212                                        .get(failureType);
213                        cumulatedFailureTypeProbabilities.put(failureType,
214                                        ((failureProbability == null) ? 0.0 : failureProbability)
215                                                        + failureTypeProbabilityDelta);
216                }
217 
218                // Increase the counter of evaluated physical system states:
219                physicalStateEvaluationCount++;
220 
221                // Do the logging:
222                if (configuration.isPrintMarkovSingleResults()) {
223                        // yes - write output to log file
224                        BufferedWriter out = null;
225                        String filePath = resolveFile(configuration.getLogFile());
226                        try {
227                                if (physicalStateEvaluationCount == 1) {
228                                        File f = new File(filePath);
229                                        // if the file exists, we will delete it and create a new,
230                                        // empty one
231                                        // (i.e., overwrite the existing file) once, and then
232                                        // repeatedly append
233                                        // to this file
234                                        if (f.exists()) {
235                                                f.delete(); // delete current ("old") file
236                                                f.createNewFile(); // create a new, empty file
237                                        }
238                                        out = new BufferedWriter(new FileWriter(filePath, true));
239                                        logger
240                                                        .info("Logging results of all Markov transformation runs to: "
241                                                                        + filePath);
242                                        out.append(getLogHeadings()
243                                                        + System.getProperty("line.separator"));
244                                        out.flush();
245                                        out.close();
246                                }
247                                out = new BufferedWriter(new FileWriter(filePath, true));
248                                out.append(getLogSingleResults(successProbability,
249                                                physicalStateProbability)
250                                                + System.getProperty("line.separator"));
251                                out.flush();
252                        } catch (IOException e) {
253                                e.printStackTrace();
254                        } finally {
255                                try {
256                                        if (out != null) {
257                                                out.flush();
258                                                out.close();
259                                        }
260                                } catch (IOException e) {
261                                        e.printStackTrace();
262                                }
263                        }
264                }
265        }
266 
267        /**
268         * Gets the overall failure type probabilities, accumulated over all
269         * considered physical system states.
270         * 
271         * @return the overall failure type probabilities
272         */
273        public Map<MarkovFailureType, Double> getCumulatedFailureTypeProbabilities() {
274                return cumulatedFailureTypeProbabilities;
275        }
276 
277        /**
278         * Gets the overall physical state probability, accumulated over all
279         * considered physical system states.
280         * 
281         * @return the overall physical state probability
282         */
283        public double getCumulatedPhysicalStateProbability() {
284                return cumulatedPhysicalStateProbability;
285        }
286 
287        /**
288         * Retrieves the failure type with the given id.
289         * 
290         * @param failureTypeId
291         *            the failure type id
292         * @return the failure type
293         */
294        private MarkovFailureType getFailureType(String failureTypeId) {
295                for (MarkovFailureType failureType : failureTypes) {
296                        if (failureType.getId().equals(failureTypeId)) {
297                                return failureType;
298                        }
299                }
300                throw new IllegalArgumentException(
301                                "MarkovTransformationResult: Failure type with ID \""
302                                                + failureTypeId + "\" not found!");
303        }
304 
305        /**
306         * Builds the headings string for Markov transformation logging.
307         * 
308         * @return the log headings string
309         */
310        private String getLogHeadings() {
311 
312                // Build a result string:
313                StringBuilder resultString = new StringBuilder();
314 
315                // Append state number heading:
316                resultString.append("physical system state number;");
317 
318                // Append resource state headings:
319                for (ProcessingResourceDescriptor descriptor : markovSource
320                                .getUnreliableResourceDescriptors()) {
321                        resultString.append(descriptor.getResourceContainerName() + " - "
322                                        + descriptor.getType().getName() + ";");
323                }
324 
325                // Append success probability heading:
326                resultString.append("success probability;");
327 
328                // Append state probability heading:
329                resultString.append("physical state probability");
330 
331                // Return the result:
332                return resultString.toString();
333        }
334 
335        /**
336         * Builds the results string for Markov transformation logging.
337         * 
338         * @param successProbability
339         *            success probability of the current physical system state
340         * @param physicalStateProbability
341         *            occurrence probability of the current physical system state
342         * @return the results string
343         */
344        private String getLogSingleResults(final double successProbability,
345                        final double physicalStateProbability) {
346 
347                // Build a result string:
348                StringBuilder resultString = new StringBuilder();
349 
350                // Append state number:
351                resultString.append(physicalStateEvaluationCount + ";");
352 
353                // Append resource states:
354                for (ProcessingResourceDescriptor descriptor : markovSource
355                                .getUnreliableResourceDescriptors()) {
356                        resultString.append(descriptor.getCurrentState().name() + ";");
357                }
358 
359                // Append success probability:
360                resultString.append(successProbability + ";");
361 
362                // Append state probability:
363                resultString.append(physicalStateProbability);
364 
365                // Return the result:
366                return resultString.toString();
367        }
368 
369        /**
370         * Retrieves the number of physical system states.
371         * 
372         * @return the number of physical system states
373         */
374        public long getNumberOfPhysicalSystemStates() {
375                return numberOfPhysicalSystemStates;
376        }
377 
378        /**
379         * Retrieves the current number of evaluated physical system states.
380         * 
381         * @return the current number of evaluated physical system states
382         */
383        public long getPhysicalStateEvaluationCount() {
384                return physicalStateEvaluationCount;
385        }
386 
387        /**
388         * Retrieves the Markov chain that results from the transformation.
389         * 
390         * @return the Markov chain that results from the transformation
391         */
392        public MarkovChain getResultChain() {
393                return resultChain;
394        }
395 
396        /**
397         * Gets the usage scenario which has been evaluated
398         * 
399         * @return the usage scenario
400         */
401        public UsageScenario getScenario() {
402                return scenario;
403        }
404 
405        /**
406         * Retrieves the overall success probability.
407         * 
408         * @return the success probability
409         */
410        public double getSuccessProbability() {
411                return cumulatedSuccessProbability;
412        }
413 
414        /**
415         * Determines if the calculated success probability conforms to a given
416         * required accuracy.
417         * 
418         * @param requiredAccuracy
419         *            the required accuracy in decimal places
420         * @return true if the required accuracy has been reached
421         */
422        public boolean hasRequiredAccuracy(final int requiredAccuracy) {
423 
424                // Create an approximation for the accumulated success probability:
425                MarkovResultApproximation approximation = new MarkovResultApproximation(
426                                cumulatedSuccessProbability, cumulatedSuccessProbability
427                                                + (1.0 - cumulatedPhysicalStateProbability));
428 
429                // Check for the required accuracy:
430                return approximation.hasRequiredAccuracy(requiredAccuracy);
431        }
432 
433        /**
434         * Indicates if an approximation scheme shall be used for printing of
435         * probabilities.
436         * 
437         * @return <code>true</code>, if an approximation scheme shall be used for
438         *         printing probabilities, <code>false</code> otherwise.
439         */
440        public boolean isDoApproximate() {
441                return (configuration.isIterationOverPhysicalSystemStatesEnabled())
442                                && approximate
443                                && (physicalStateEvaluationCount < Math.pow(markovSource
444                                                .getUnreliableResourceDescriptors().size(), 2));
445        }
446 
447        /**
448         * Resolves a file's path in case it starts with "platform:/" and returns
449         * the entire absolute path to the file, including the file's name.
450         * 
451         * @param fileURL
452         *            the path to a file, including the file's name (and its
453         *            extension)
454         * @return the absolute path to the file, including the file's name
455         */
456        private String resolveFile(String fileURL) {
457                // if this is a platform URL, first resolve it to an absolute path
458                if (fileURL.startsWith("platform:")) {
459                        try {
460                                URL solvedURL = FileLocator.resolve(new URL(fileURL));
461                                fileURL = solvedURL.getPath();
462                        } catch (Exception e) {
463                                e.printStackTrace();
464                                return "";
465                        }
466                }
467                return fileURL;
468        }
469 
470        /**
471         * Method for setting a value responsible for telling if an approximation
472         * scheme shall be used for printing probabilities.
473         * 
474         * @param approximate
475         *            the value indicating if an approximation scheme shall be used
476         *            for printing probabilities
477         */
478        public void setApproximate(boolean approximate) {
479                this.approximate = approximate;
480        }
481}

[all classes][de.uka.ipd.sdq.reliability.solver.pcm2markov]
EMMA 2.0.9414 (unsupported private build) (C) Vladimir Roubtsov