TraceLab Component Library
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties
PCAScript.cs
Go to the documentation of this file.
1 // TraceLab Component Library
2 // Copyright © 2012-2013 SEMERU
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 using RPlugin.Core;
18 using RPlugin.Exceptions;
19 using System;
20 using System.Collections.Generic;
21 using System.IO;
22 using System.Reflection;
23 using System.Text;
24 using TraceLab.Components.RPlugin.Properties;
25 using TraceLabSDK.Types;
26 
27 namespace TraceLab.Components.DevelopmentKit.Metrics.Traceability
28 {
32  public class PCAScript : RScript
33  {
34  private readonly string _baseScript = Settings.Default.Resources + "PCA.R";
35  private readonly string[] _requiredPackages = new string[] { "psych", "GPArotation" };
36 
37  private TLSimilarityMatrix[] _matrices;
38  private string _outputFile;
39 
43  public override string BaseScript
44  {
45  get
46  {
47  return _baseScript;
48  }
49  }
50 
54  public override string[] RequiredPackages
55  {
56  get
57  {
58  return _requiredPackages;
59  }
60  }
61 
66  public PCAScript(params TLSimilarityMatrix[] matrices) : base()
67  {
68  _matrices = matrices;
69  }
70 
74  public override void PreCompute()
75  {
76  RUtil.RegisterScript(Assembly.GetExecutingAssembly(), _baseScript);
77  string tableFile = CreateTable(_matrices);
78  _outputFile = RUtil.ReserveCacheFile("PCA.out");
79  _arguments = new List<object>();
80  _arguments.Add(tableFile);
81  _arguments.Add(_outputFile);
82  }
83 
89  public override object ImportResults(RScriptResult result)
90  {
91  List<double> pca = new List<double>();
92  TextReader file = new StreamReader(_outputFile);
93  file.ReadLine();
94  string line = String.Empty;
95  while ((line = file.ReadLine()) != null)
96  {
97  string[] entries = line.Split(',');
98  if (entries.Length != 3)
99  {
100  throw new RDataException("Error in PCA output.");
101  }
102  pca.Add(Convert.ToDouble(entries[2]));
103  }
104  if (pca.Count != _matrices.Length)
105  {
106  throw new RDataException("PCA returned the incorrect number of entries.");
107  }
108  return pca.ToArray();
109  }
110 
116  private string CreateTable(params TLSimilarityMatrix[] matrices)
117  {
118  if (matrices.Length < 2)
119  {
120  throw new RDataException("Must have at least 2 matrices.");
121  }
122  FileStream tableFile = RUtil.CreateCacheFile("PCA.table");
123  TextWriter tableWriter = new StreamWriter(tableFile);
124  tableWriter.Write("M1");
125  for (int i = 1; i < matrices.Length; i++)
126  {
127  if (matrices[i].Count != matrices[0].Count)
128  {
129  throw new RDataException("Matrices have different count of links.");
130  }
131  tableWriter.Write(String.Format("\tM{0}", i + 1));
132  }
133  tableWriter.WriteLine();
134  foreach (TLSingleLink link in matrices[0].AllLinks)
135  {
136  tableWriter.Write(String.Format("{0}_{1}\t{2}",
137  link.SourceArtifactId,
138  link.TargetArtifactId,
139  link.Score
140  ));
141  for (int i = 1; i < matrices.Length; i++)
142  {
143  tableWriter.Write(String.Format("\t{0}", matrices[i].GetScoreForLink(link.SourceArtifactId, link.TargetArtifactId)));
144  }
145  tableWriter.WriteLine();
146  }
147  tableWriter.Flush();
148  tableWriter.Close();
149  return tableFile.Name;
150  }
151  }
152 }