Free cookie consent management tool by TermsFeed Policy Generator

Changeset 9350


Ignore:
Timestamp:
04/10/13 13:29:24 (12 years ago)
Author:
fschoepp
Message:

#1888:

  • Added input parameters to the run class. They will be populated by the back-end and returned to the web pages which renders them.
  • Added a ParameterMapper class which converts HL specific model classes to OaaS independent classes. The conversion gets delegated to IParameterHandler which have to be implemented manually and registered for a certain Type before. All parameters which can be converted to IStringConvertible, IStringConvertibleMatrix, IString* will be converted into a OaaS-StringValue instance.
  • Added IParameterHandlers for PathTSPTour and PermutationType (required for TSP).
  • AlgorithmConverter now makes sure that the id of a run is unique. (All runs of a RunList will be shown now.)
  • Web pages are capable of rendering both the results of a run and their input parameters (added a accordion to wrap their content).
  • Renamed "Traveling Salesman Problem" to "Genetic Algorithm - TSP".
  • Changed js-files to render both input and result parameters of a Run.
Location:
branches/OaaS
Files:
6 added
11 edited

Legend:

Unmodified
Added
Removed
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs

    r9324 r9350  
    2121using System.Data;
    2222using HeuristicLab.Services.Optimization.ControllerService.General;
     23using HeuristicLab.Services.Optimization.ControllerService.Parameters.HL;
    2324
    2425namespace HeuristicLab.Services.Optimization.ControllerService {
    25   public class ScenarioEntity : TableServiceEntity {
    26 
     26  public class ScenarioEntity : TableServiceEntity {   
    2727    public ScenarioEntity() {
    2828    }
     
    4141
    4242  public class HiveScenarioManager : IScenarioManager {
     43    private static HLParameterMapper parameterMapper = new HLParameterMapper();
    4344    private static IScenarioMapper tspMapper;
    4445    private static object lockable;
     
    297298              var value = run.Results[key];             
    298299              Parameter result = MapHiveDataType(key, value);
    299               resultValues.Add(result);
     300              resultValues.Add(result);             
    300301            }
    301302            taskRun.Results = resultValues;
     303            IList<Parameter> inputParameters = new List<Model.Parameter>();
     304            foreach (var key in run.Parameters.Keys) {
     305              var value = run.Parameters[key];
     306              Parameter param = MapHiveDataType(key, value);
     307              inputParameters.Add(param);
     308            }
     309            // crawl the copied experiment of the job
     310            //taskRun.Experiment = dal.JobDao.FindByJobId(id);
     311            taskRun.InputParameters = inputParameters;
    302312            runs.Add(taskRun);
    303313          }
     
    310320   
    311321    private Parameter MapHiveDataType(string name, IItem item) {
    312       Parameter result = new Parameter();
     322
     323      if (parameterMapper.IsHandlerAvailable(item)) {
     324        return parameterMapper.Map(name, item);
     325      }
     326
     327      var result = new Parameter();
    313328      result.Type = ParameterType.String;
    314329      //TODO: How shall we handle dll specific datatypes?     
     
    349364            matrixValue[i][j] = matrix[j, i];
    350365          }
    351         }       
     366        }
     367        matrixValue = transpose(matrixValue);
    352368        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.DecimalMatrix() { Name = name, Value = matrixValue, RowNames = (matrix.ColumnNames.Count() > 0 ? matrix.ColumnNames.ToArray() : null) };
    353369      }
     
    408424      }
    409425      else {
    410         result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = "Cannot be displayed as string" };
     426        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = item.ItemName != null ? item.ItemName + " (Cannot be displayed properly as string)" : "Cannot be displayed properly as string" };
    411427      }
    412428      // TODO: Add workaround for TSP
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/HeuristicLab.Services.Optimization.ControllerService.csproj

    r9305 r9350  
    179179    <Compile Include="Mockup\MockupDAL.cs" />
    180180    <Compile Include="Mockup\MockupScenarioManager.cs" />
     181    <Compile Include="Parameters\HL\HLParameterHandler.cs" />
     182    <Compile Include="Parameters\HL\PathTSPParameterHandler.cs" />
     183    <Compile Include="Parameters\HL\PermutationTypeHandler.cs" />
     184    <Compile Include="Parameters\ParameterHandler.cs" />
    181185    <Compile Include="Parsers\AlgorithmConverter.cs" />
    182186    <Compile Include="PlaceholderControllerService.cs" />
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/DAL.cs

    r9324 r9350  
    3939    IScenarioDao ScenarioDao { get; }
    4040    IBlobDao BlobDao { get; }
    41     IExperimentDao ExperimentDao { get; }   
     41    IExperimentDao ExperimentDao { get; }
    4242  }
    4343
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/Model/ControllerModel.cs

    r9305 r9350  
    480480    [DataMember]
    481481    public IList<Parameter> Results { get; set; }
     482
     483    [DataMember]
     484    public IList<Parameter> InputParameters { get; set; }
    482485  }
    483486
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupDAL.cs

    r9215 r9350  
    253253      }     
    254254    }
    255 
    256255  }
    257256}
  • branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs

    r9324 r9350  
    189189      jrun["name"] = run.Name;
    190190      jrun["results"] = ConvertParametersToJson(run.Results);
     191      jrun["params"] = ConvertParametersToJson(run.InputParameters);
    191192      return jrun;
    192193    }
     
    196197      foreach (var run in runs)
    197198        jarray.Add(ConvertRunToJson(run));
     199     
     200     
     201      // if there are multiple different jobs to execute and they have the same id, we must change it here manually
     202      var maxId = new Dictionary<string,int>();
     203      for (int i = 0; i < jarray.Count; i++) {
     204        for (int j = i + 1; j < jarray.Count; j++) {
     205          if (jarray[i]["id"].ToString() == jarray[j]["id"].ToString()) {
     206            int max;
     207            if (!maxId.TryGetValue(jarray[i]["id"].ToString(), out max)) {
     208              max = 1;
     209              maxId[jarray[i]["id"].ToString()] = max;             
     210            }
     211            maxId[jarray[i]["id"].ToString()]++;
     212            // change j's entry
     213            jarray[j]["id"] = jarray[j]["id"].ToString() + " (" + max + ")";
     214            jarray[j]["name"] = jarray[j]["name"] + " (" + max + ")";
     215          }
     216        }
     217      }
    198218      return jarray;
    199219    }
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.view.js

    r9335 r9350  
    824824            var datatableSelect = $('.datatableOptions', ele);
    825825
    826             var names = _.reduce(this.model.models, function (arr, model) {
    827                 return _.union(arr, _.map(model.get('results'), function (elem) { return elem.Name }));
    828             }, []);
    829 
     826            var names = [];
     827            var previouslyFound = { results: {}, params: {} };
     828            _.each(this.model.models, function (model) {
     829                _.each(model.get('results'), function (res) {
     830                    if (!previouslyFound['results'][res.Name]) {
     831                        previouslyFound['results'][res.Name] = true;
     832                        names.push({ name: res.Name, source: 'results' });
     833                    }
     834                });
     835                _.each(model.get('params'), function (res) {
     836                    if (!previouslyFound['params'][res.Name]) {
     837                        previouslyFound['params'][res.Name] = true;
     838                        names.push({ name: res.Name, source: 'params' });
     839                    }
     840                });
     841            });
     842            previouslyFound = {};
     843            this.options.modelMapping = names;
    830844            this.bubbleSelect = $('select[class="bubbleSize"]', ele);
    831845
    832             _.each(names, function (name) {
    833                 var option = $("<option />", { value: name, text: name });
     846            _.each(names, function (entry) {
     847                var option = $("<option />", { value: entry.name, text: entry.name });
    834848                option.clone().appendTo(xAxisSelect);
    835849                option.clone().appendTo(yAxisSelect);
     
    837851                var rowNames = null;
    838852                var foundModel = _.find(self.model.models, function (model) {
    839                     var entry = _.find(model.get('results'), function (entry) { return entry.Name == name && entry.RowNames });
    840                     if (entry)
    841                         rowNames = entry.RowNames;
    842                     return entry && entry.RowNames;
     853                    var e = _.find(model.get(entry.source), function (e) { return e.Name == entry.name && e.RowNames });
     854                    if (e)
     855                        rowNames = e.RowNames;
     856                    return e && e.RowNames;
    843857                });
    844858                if (rowNames) {
    845                     self.options.datatables[name] = rowNames;
    846                     $('<option />', { value: name, text: name }).appendTo(datatableSelect);
     859                    self.options.datatables[entry.name] = rowNames;
     860                    $('<option />', { value: entry.name, text: entry.name }).appendTo(datatableSelect);
    847861                }
    848862            });
     
    852866            this.options.xAxis = this.model.models[0].get('results')[0].Name;
    853867            this.options.yAxis = this.options.xAxis;
     868            this.options.selectedXIndex = 0;
     869            this.options.selectedYIndex = 0;
    854870            this.options.plot = 'Boxplot';
    855871            $('div[class="bubbleSlider"]', ele).slider({
     
    909925        xAxisSelected: function (evt) {
    910926            var target = $(evt.target);
     927            this.options.selectedXIndex = target.prop("selectedIndex");
    911928            this.options.xAxis = target.val();
    912929            this.createPlot();
     
    914931        yAxisSelected: function (evt) {
    915932            var target = $(evt.target);
     933            this.options.selectedYIndex = target.prop("selectedIndex");
    916934            this.options.yAxis = target.val();
    917935            this.createPlot();
     
    967985        createBoxplot: function () {
    968986            var self = this;
    969 
     987            var parameterXSource = this.options.modelMapping[this.options.selectedXIndex].source; // either 'params' or 'results'
     988            var parameterYSource = this.options.modelMapping[this.options.selectedYIndex].source; // either 'params' or 'results'
    970989            // prepare data for boxplot
    971990            var values = {};
    972991            for (var i = 0; i < this.model.models.length; i++) {
    973                 var xlabel = _.find(this.model.models[i].get('results'), function (itm) { return itm.Name == self.options.xAxis });
     992                var xlabel = _.find(this.model.models[i].get(parameterXSource), function (itm) { return itm.Name == self.options.xAxis });
    974993                if (!xlabel)
    975994                    continue;
    976995
    977996                if ($.isArray(xlabel.Value))
    978                     values[xlabel.Name + ' = ' + xlabel.Value[0]] = [];
     997                    values[parameterXSource + '.' + xlabel.Name + ' = ' + xlabel.Value[0]] = [];
    979998                else
    980                     values[xlabel.Name + ' = ' + xlabel.Value] = [];
     999                    values[parameterXSource + '.' + xlabel.Name + ' = ' + xlabel.Value] = [];
    9811000            }
    9821001
    9831002            for (var i = 0; i < this.model.models.length; i++) {
    984                 var xlabel = _.find(this.model.models[i].get('results'), function (itm) { return itm.Name == self.options.xAxis });
    985                 var entry = _.find(this.model.models[i].get('results'), function (itm) { return itm.Name == self.options.yAxis });
     1003                var xlabel = _.find(this.model.models[i].get(parameterXSource), function (itm) { return itm.Name == self.options.xAxis });
     1004                var entry = _.find(this.model.models[i].get(parameterYSource), function (itm) { return itm.Name == self.options.yAxis });
    9861005                if (!xlabel || !entry || !entry.Value)
    9871006                    continue;
    9881007
    989                 var index = xlabel.Name + ' = ' + ($.isArray(xlabel.Value) ? xlabel.Value[0] : xlabel.Value);
     1008                var index = parameterXSource + '.' + xlabel.Name + ' = ' + ($.isArray(xlabel.Value) ? xlabel.Value[0] : xlabel.Value);
    9901009
    9911010                if ($.isArray(entry.Value))
     
    10031022        createBubblechart: function () {
    10041023            var self = this;
    1005 
     1024            var parameterXSource = this.options.modelMapping[this.options.selectedXIndex].source; // either 'params' or 'results'
     1025            var parameterYSource = this.options.modelMapping[this.options.selectedYIndex].source; // either 'params' or 'results'
    10061026            // prepare data for bubble chart
    10071027            var values = [];
    10081028            var autoscaleBubbles = this.bubbleSelect.val() != 'Constant';
    10091029            for (var i = 0; i < this.model.models.length; i++) {
    1010                 var xValue = _.find(this.model.models[i].get('results'), function (itm) { return itm.Name == self.options.xAxis });
    1011                 var yValue = _.find(this.model.models[i].get('results'), function (itm) { return itm.Name == self.options.yAxis });
     1030                var xValue = _.find(this.model.models[i].get(parameterXSource), function (itm) { return itm.Name == self.options.xAxis });
     1031                var yValue = _.find(this.model.models[i].get(parameterYSource), function (itm) { return itm.Name == self.options.yAxis });
    10121032                if (!xValue || !yValue)
    10131033                    continue;
     
    10191039                } else {
    10201040                    var valueProvider = _.find(this.model.models[i].get('results'), function (itm) { return itm.Name == self.bubbleSelect.val(); });
    1021                     if (!valueProvider) {
     1041                    if (!valueProvider)
     1042                        valueProvider = _.find(this.model.models[i].get('params'), function (itm) { return itm.Name == self.bubbleSelect.val(); });
     1043
     1044                    if (!valueProvider) {                       
    10221045                        size = this.options.bubbleSize;
    10231046                    } else {
     
    10551078            for (var i = 0; i < this.model.models.length; i++) {
    10561079                var table = _.find(this.model.models[i].get('results'), function (itm) { return itm.Name == self.options.selectedDatatable });
     1080                if (!table)
     1081                    table = _.find(this.model.models[i].get('params'), function (itm) { return itm.Name == self.options.selectedDatatable });
     1082
    10571083                if (!table)
    10581084                    continue;
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.model.js

    r9324 r9350  
    3737        poll: function () {
    3838            var self = this;
    39             this.fetch({ cache: false, update: true, success: function () {
     39            this.fetch({ cache: false, reset: true, success: function () {
    4040                self._poll();
    4141            }
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.view.js

    r9335 r9350  
    1616        initialize: function () {
    1717            this.collection.bind('remove', this.render, this);
    18             //this.collection.bind('a', this.render, this);
    1918        },
    2019        render: function () {
     
    8988            rcv.render();
    9089            for (var i = 0; i < this.model.models.length; i++) {
     90                $('<h3></h3>').text(this.model.models[i].get('name')).appendTo(this.$el);
    9191                var rev = new my.ResultEntryView({ model: this.model.models[i], el: this.$el });
    9292                rev.render();
     
    150150        initialize: function () {
    151151            this.plotted = {};
     152            this.plotted['params'] = {};
     153            this.plotted['results'] = {};
    152154        },
    153155        render: function () {
    154156            this.template = _.template($('#runTemplate').html());
    155157            var table = $(this.template(this.model.attributes));
    156             var body = $("tbody", table);
     158            var body = $('tbody[class="results"]', table);
    157159            table.appendTo(this.$el);
     160            // render the results of the model
    158161            var results = this.model.get('results');
    159162            for (var i = 0; i < results.length; i++) {
    160                 var row = $('<tr/>').attr('data-index', i);
    161                 $('<td/>').text(results[i].Name).appendTo(row);
    162                 if ($.isArray(results[i].Value)) {
    163                     var col = $('<td/>').appendTo(row);
    164                     var tevDiv = $('<div/>');
    165                     var plotDiv = $('<div/>').appendTo($('#tmp'));;
    166                     this.plotted[i] = {};
    167                     var tv = new my.TabView({
    168                         model: [
    169                           { name: 'Table', content: tevDiv },
    170                           { name: 'Plot', content: plotDiv },
    171                         ],
    172                         el: col
    173                     });
    174                     this.listenTo(tv, 'tab-activated', this.tabActivated);
    175                     tv.render();
    176 
    177                 }
    178                 else {
    179                     $('<td/>').text(results[i].Value).appendTo(row);
    180                 }
    181                 row.appendTo(body);
    182             }
     163                this.renderModelEntry(results[i], i, body, 'results');
     164            }
     165
     166            var inputs = this.model.get('params');
     167            body = $('tbody[class="inputs"]', table);
     168            for (var i = 0; i < inputs.length; i++) {
     169                this.renderModelEntry(inputs[i], i, body, 'params');
     170            }
     171
     172            var av = new my.AccordionView({el: $(table)});
     173            av.render();
     174        },
     175        renderModelEntry: function(entry, index, body, attribute) {         
     176            var row = $('<tr/>').attr('data-index', index).attr('data-attribute', attribute);
     177            $('<td/>').text(entry.Name).appendTo(row);
     178            if ($.isArray(entry.Value)) {
     179                var col = $('<td/>').appendTo(row);
     180                var tevDiv = $('<div/>');
     181                var plotDiv = $('<div/>').appendTo($('#tmp'));                               
     182                this.plotted[attribute][index] = {};
     183                var tv = new my.TabView({
     184                    model: [
     185                        { name: 'Table', content: tevDiv },
     186                        { name: 'Plot', content: plotDiv },
     187                    ],
     188                    el: col
     189                });
     190                this.listenTo(tv, 'tab-activated', this.tabActivated);
     191                tv.render();
     192            }
     193            else {
     194                $('<td/>').text(entry.Value).appendTo(row);
     195            }
     196            row.appendTo(body);
    183197        },
    184198        tabActivated: function (evt) {
    185199            var index = parseInt(evt.element.parents('tr').attr('data-index'));
    186             if (evt.name == 'Plot' && !this.plotted[index].Plot) {
    187                 this.plotted[index].Plot = true;
     200            var attribute = evt.element.parents('tr').attr('data-attribute');
     201            if (evt.name == 'Plot' && !this.plotted[attribute][index].Plot) {
     202                this.plotted[attribute][index].Plot = true;
    188203                var plotDiv = $('<div/>').appendTo($('#tmp'));
    189                 var pv = new my.PlotView({ model: this.model.get('results')[index], el: plotDiv, transpose: true });
     204                var pv = new my.PlotView({ model: this.model.get(attribute)[index], el: plotDiv, transpose: true });
    190205                pv.render();
    191206                plotDiv.appendTo(evt.element);
     
    198213                });
    199214                rv.render();
    200             } else if (evt.name == 'Table' && !this.plotted[index].Table) {
    201                 this.plotted[index].Table = true;
    202                 var tevDiv = $('<div/>');
    203                 var tev = new my.TableEditView({ model: this.model.get('results')[index].Value, rowNames: this.model.get('results')[index].RowNames, useDatatable: true, el: tevDiv });
     215                plotDiv.width(rv.$el.width());
     216                plotDiv.height(rv.$el.height());
     217                pv.refresh();
     218            } else if (evt.name == 'Table' && !this.plotted[attribute][index].Table) {
     219                this.plotted[attribute][index].Table = true;
     220                var tevDiv = $('<div/>').css('overflow', 'scroll');
     221                var tev = new my.TableEditView({ model: this.model.get(attribute)[index].Value, rowNames: this.model.get(attribute)[index].RowNames, useDatatable: true, el: tevDiv });
    204222                tev.render();
    205223                tevDiv.appendTo(evt.element)
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Mappings/tsp.xml

    r9166 r9350  
    11<?xml version='1.0'?>
    22<scenario xmlns="urn:scenario-schema">
    3   <name>Traveling Salesman Problem</name>
     3  <name>Genetic Algorithm - TSP</name>
    44  <algorithm mapper="HeuristicLab.Mappers.TSPScenarioMapper">
    55    <parameters>
  • branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Job/Index.cshtml

    r9335 r9350  
    5959
    6060<script type="text/template" id="runTemplate">
    61   <h3><%= name %></h3>
    62   <div>
     61  <div class="accordion">
     62    <h3>Results</h3>
     63    <div>
    6364    <table>
    64       <thead>
     65        <thead>
    6566        <tr>
    66           <td>Key</td>
    67           <td>Value</td>
     67            <td>Key</td>
     68            <td>Value</td>
    6869        </tr>
    69       </thead>
    70       <tbody>
    71       </tbody>
     70        </thead>
     71        <tbody class="results">
     72        </tbody>
    7273    </table>
    73   </div>
     74    </div>
     75    <h3>Inputs</h3>
     76    <div>
     77    <table>
     78        <thead>
     79        <tr>
     80            <td>Key</td>
     81            <td>Value</td>
     82        </tr>
     83        </thead>
     84        <tbody class="inputs">
     85        </tbody>
     86    </table>
     87    </div>
     88</div>
    7489</script>
    7590
Note: See TracChangeset for help on using the changeset viewer.