001    package jcolibri.extensions.maintenance_evaluation;
002    
003    import java.io.BufferedWriter;
004    import java.io.FileWriter;
005    import java.io.IOException;
006    import java.io.PrintWriter;
007    import java.util.HashMap;
008    import java.util.LinkedList;
009    import java.util.List;
010    import java.util.Set;
011    import java.util.Vector;
012    
013    import jcolibri.cbrcore.CBRQuery;
014    import jcolibri.evaluation.EvaluationReport;
015    import jcolibri.method.maintenance.QueryResult;
016    
017    import org.apache.commons.logging.LogFactory;
018    
019    /**
020     * This class stores the result of each query in an evaluation. 
021     * It is configured and filled by an Evaluator.
022     * 
023     * @author Lisa Cummins.
024     */
025    public class DetailedEvaluationReport extends EvaluationReport 
026    {
027        /** Stores the query series info */
028        protected HashMap<String, List<QueryResult>> queryData;
029    
030        /**
031         * Creates a new report.
032         */
033        public DetailedEvaluationReport()
034        {   super();
035            queryData = new HashMap<String, List<QueryResult>>();
036        }
037            
038        /**
039         * Returns the evaluation info identified by the given label.
040         * @param label identifies the evaluation series.
041         * @return the evaluation info identified by the given label.
042         */
043        public List<QueryResult> getQuerySeries(String label)
044        {   return queryData.get(label);
045        }
046        
047        /**
048         * Sets the given evaluation series to be the series identified by the 
049         * given label.
050         * @param label identifier of the evaluation series.
051         * @param queryEvaluations the evaluation series. 
052         */
053        public void setSeries(String label, List<QueryResult> queryEvaluations)
054        {   queryData.put(label, queryEvaluations);
055        }
056        
057        /**
058         * Adds the given query and value to the series labelled by the given label.
059         * @param label the label whose series the query and value are being added to.
060         * @param query the query.
061         * @param value the query's value.
062         */
063        public void addDataToSeries(String label, CBRQuery query, Double value)
064        {   List<QueryResult> queries = queryData.get(label);
065            if(queries == null)
066            {       queries = new LinkedList<QueryResult>();
067            }
068            queries.add(new QueryResult(query, value));
069            queryData.put(label, queries);
070        }
071        
072        /** 
073         * Returns the names of the contained evaluation series.
074         * @return the names of the contained evaluation series.
075         */
076        public String[] getQuerySeriesLabels()
077        {   Set<String> set = queryData.keySet();
078            String[] res = new String[set.size()];
079            int i=0;
080            for( String e : set)
081                res[i++] = e;
082            return res;
083        }
084    
085        /**
086         * Prints the report to the given file.
087         * @param filename the file to print the report to.
088         */
089        public void printDetailedEvaluationReport(String filename)
090        {   PrintWriter pw = null;
091                    try
092                    {       pw = new PrintWriter(new BufferedWriter(new FileWriter(filename, true)));
093                    
094                            pw.println("Results:");
095                            String[] seriesLabels = getSeriesLabels();
096                            String[] querySeriesLabels = getQuerySeriesLabels();
097                            String[] otherLabels = getOtherLabels();
098                            
099                            for(int i=0; i<seriesLabels.length; i++)
100                            {       pw.println(seriesLabels[i]+ ":");
101                                    Vector<Double> results = getSeries(seriesLabels[i]);
102                                    String series = "";
103                                    for(Double result: results)
104                                        series += result + ","; 
105                                    pw.println(series.substring(0, series.length()-2));
106                                    pw.println("Average: " + getAverageOfDataSeries(seriesLabels[i]));
107                                    pw.println();
108                            }
109                            pw.println();
110            
111                            for(int i=0; i<querySeriesLabels.length; i++)
112                            {       pw.println(querySeriesLabels[i]+ ":");
113                                    List<QueryResult> results = getQuerySeries(querySeriesLabels[i]);
114                                    for(QueryResult qResult: results)
115                                        pw.println(qResult.getCase().getID() + ": " + qResult.getResult()); 
116                                    pw.println("Average: " + getAverageOfQueryDataSeries(querySeriesLabels[i]));
117                                    pw.println();
118                            }
119                            pw.println();
120                            
121                            for(int i=0; i<otherLabels.length; i++)
122                    {       pw.println(otherLabels[i]+ ": " + getOtherData(otherLabels[i]));
123                            pw.println();
124                    }
125                } catch(IOException ioe) {
126            }
127            finally 
128            {       if(pw != null)
129                            pw.close();
130            }
131        }
132            
133        /**
134         * Removes a data serie.
135         * @param label the label of the data series to remove.
136         */
137        public void removeDataSeries(String label)
138        {   data.remove(label);
139        }
140            
141        /**
142         * Removes some data.
143         * @param label the label of the data to remove.
144         */
145        public void removeOtherData(String label)
146        {   other.remove(label);
147        }
148    
149        /**
150         * Returns the average of the data series with the given label. If
151         * the label given is not the label of any data series, null will
152         * be returned and an error message will be printed.
153         * @param label the label of the data series.
154         * @return the average of the given data series.
155         */
156        public Double getAverageOfDataSeries(String label)
157        {   Vector<Double> v = data.get(label);
158            if(v == null)
159            {       LogFactory.getLog(this.getClass()).error("Data series by this label does not exist");
160                    return null;
161            }
162            if(v.size() == 0)
163            {       return 0.0;
164            }
165            double total = 0.0;
166            for(Double value: v)
167            {       total += value;             
168            }
169            return total / v.size();
170        }
171            
172        /**
173         * Returns the average of the query data series with the given label. If
174         * the label given is not the label of any data series, null will
175         * be returned and an error message will be printed.
176         * @param label the label of the query data series.
177         * @return the average of the given query data series.
178         */
179        public Double getAverageOfQueryDataSeries(String label)
180        {   List<QueryResult> results = queryData.get(label);
181            if(results == null)
182            {       LogFactory.getLog(this.getClass()).error("Data series by this label does not exist");
183                    return null;
184            }
185            if(results.size() == 0)
186            {       return 0.0;
187            }
188            double total = 0.0;
189            for(QueryResult result: results)
190            {       total += result.getResult();                
191            }
192            return total / results.size();
193        }
194            
195        /**
196         * Returns the String representation of this report.
197         * @return the String representation of this report. 
198         */
199        public String toString()
200        {
201            StringBuffer s = new StringBuffer();
202            s.append("Series:\n");
203            String[] series = this.getSeriesLabels();
204            for(int i=0; i<series.length; i++)
205            {       s.append("  "+series[i]+": \n    ");
206                    Vector<Double> v = this.getSeries(series[i]);
207                    for(Double d: v)
208                            s.append(d+",");
209                    s.append("\n");
210                    s.append("  Average: " + getAverageOfDataSeries(series[i]) + "\n\n");
211            }
212            
213            s.append("\nOther data:\n");
214            String[] other = this.getOtherLabels();
215            for(int i=0; i<other.length; i++)
216            {
217                    s.append("  "+other[i]+": "+ this.getOtherData(other[i])+"\n");
218            }
219            
220            s.append("\nNumber of Cycles: "+ this.getNumberOfCycles());
221            s.append("\nTime per Cycle:   "+ this.getTimePerCycle()+" ms");
222            s.append("\nTotal time:       "+ this.getTotalTime()+" ms");
223            
224            return s.toString();
225        }
226    }