Ignore:
Timestamp:
01/02/17 14:06:38 (6 years ago)
Author:
jzenisek
Message:

#2719 added datastream type; updated the optimizer view and control functionality

Location:
branches/HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4
Files:
5 added
5 edited

Legend:

Unmodified
Added
Removed
  • branches/HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/DatastreamAnalysisOptimizer.cs

    r14488 r14536  
    11#region License Information
     2
    23/* HeuristicLab
    34 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
     
    1819 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
    1920 */
     21
    2022#endregion
    2123
    2224using System;
    2325using System.Collections.Generic;
     26using System.Diagnostics;
    2427using System.Drawing;
    2528using System.Linq;
     29using System.Threading;
     30using System.Threading.Tasks;
     31using HeuristicLab.Analysis;
     32using HeuristicLab.Collections;
    2633using HeuristicLab.Common;
    2734using HeuristicLab.Core;
     35using HeuristicLab.Data;
    2836using HeuristicLab.Optimization;
    2937using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     
    3139
    3240namespace HeuristicLab.DatastreamAnalysis {
    33   internal enum DatastreamAnalysisOptimizerAction { None, Prepare, Start, Stop, Pause }
     41  internal enum DatastreamAnalysisOptimizerAction {
     42    None,
     43    Prepare,
     44    Start,
     45    Stop,
     46    Pause
     47  }
    3448
    3549  [StorableClass]
    36   [Item("DatastreamAnalysis Optimizer", "The main loop for evaluating ensemble models against a incoming datastream of time series fashion.")]
    37   [Creatable("Algorithms")]
    38   public class DatastreamAnalysisOptimizer : NamedItem, IOptimizer, IStorableContent {
    39 
    40     // TODO: introduce members -> ensembles, datastream
    41 
    42 
    43     // VAR 1: datastream = problem data
    44     [Storable]
    45     private IRegressionProblemData problemData;
    46 
    47     public IRegressionProblemData ProblemData {
    48       get { return problemData; }
     50  [Item("DatastreamAnalysis Optimizer",
     51     "The main loop for evaluating ensemble models against a incoming datastream of time series fashion.")]
     52  [Creatable(CreatableAttribute.Categories.Algorithms)]
     53  public class DatastreamAnalysisOptimizer : Executable, IOptimizer, IStorableContent {
     54    #region properties
     55    public string Filename { get; set; }
     56
     57    private DatastreamAnalysisOptimizerAction daoAction;
     58
     59    public IEnumerable<IOptimizer> NestedOptimizers { get; }
     60
     61
     62    [Storable]
     63    protected ILog log;
     64    public ILog Log {
     65      get { return log; }
     66    }
     67
     68    [Storable]
     69    private ResultCollection results;
     70
     71    public ResultCollection Results {
     72      get { return results; }
     73    }
     74
     75    private CancellationTokenSource cancellationTokenSource;
     76    private bool stopPending;
     77    private DateTime lastUpdateTime;
     78
     79    [Storable]
     80    protected int runsCounter;
     81
     82    [Storable]
     83    private RunCollection runs;
     84
     85    public RunCollection Runs
     86    {
     87      get { return runs; }
     88      protected set
     89      {
     90        if (value == null) throw new ArgumentNullException();
     91        if (runs != value) {
     92          if (runs != null) DeregisterRunsEvents();
     93          runs = value;
     94          if (runs != null) RegisterRunsEvents();
     95        }
     96      }
     97    }
     98
     99
     100    [Storable]
     101    private IItemList<RegressionEnsembleModel> ensembles;
     102
     103    public IItemList<RegressionEnsembleModel> Ensembles {
     104      get { return ensembles; }
    49105      set {
    50         if (value == null || value == problemData)
     106        if (value == null || value == ensembles)
    51107          return;
    52108
    53         problemData = value;
    54       }
    55     }
    56 
    57     // VAR 2: datastream = external source (webservice, AMQP-Queue, etc.)
    58     // TODO
     109        ensembles = value;
     110      }
     111    }
     112
     113
     114    // VAR 1: datastream ~= problem data, VAR 2 (TODO): datastream = external source e.g. webservice, AMQP-Queue, etc.
     115    [Storable]
     116    private Datastream datastream;
     117
     118    public Datastream Datastream {
     119      get { return datastream; }
     120      set {
     121        if (value == null || value == datastream)
     122          return;
     123
     124        datastream = value;
     125      }
     126    }
     127
     128    #endregion properties
     129
     130    #region ResultsProperties
     131    private double ResultsBestQuality
     132    {
     133      get { return ((DoubleValue)Results["Best Quality"].Value).Value; }
     134      set { ((DoubleValue)Results["Best Quality"].Value).Value = value; }
     135    }
     136    private DataTable ResultsQualities
     137    {
     138      get { return ((DataTable)Results["Qualities"].Value); }
     139    }
     140    #endregion
     141
     142    #region constructors, cloner,...
    59143
    60144    public DatastreamAnalysisOptimizer() {
    61       Name = "Datastream Analysis";
     145      name = "Datastream Analysis";
     146      log = new Log();
     147      results = new ResultCollection();
     148      ensembles = new ItemList<RegressionEnsembleModel>();
     149      datastream = new Datastream();
     150      runsCounter = 0;
     151      runs = new RunCollection();
     152      Initialize();
    62153    }
    63154
    64155    [StorableConstructor]
    65     protected DatastreamAnalysisOptimizer(bool deserializing) : base(deserializing) { }
     156    protected DatastreamAnalysisOptimizer(bool deserializing) : base(deserializing) {
     157    }
    66158
    67159    [StorableHook(HookType.AfterDeserialization)]
     
    71163
    72164    protected DatastreamAnalysisOptimizer(DatastreamAnalysisOptimizer original, Cloner cloner) : base(original, cloner) {
    73       // TODO: clone members (ensembles, datastream)
    74       this.ProblemData = (IRegressionProblemData)original.ProblemData.Clone(cloner);
     165      name = original.name;
     166      log = cloner.Clone(original.log);
     167      results = cloner.Clone(original.results);
     168      ensembles = (ItemList<RegressionEnsembleModel>) original.Ensembles.Clone(cloner);
     169      datastream = (Datastream) original.Datastream.Clone(cloner);
     170      runsCounter = original.runsCounter;
     171      runs = cloner.Clone(original.runs);
     172      Initialize();
    75173    }
    76174
    77175    public override IDeepCloneable Clone(Cloner cloner) {
    78       return  new DatastreamAnalysisOptimizer(this, cloner);
    79     }
    80 
    81 
    82     // TODO: introduce EventHandler for EnsemblesChanged, DatastreamChanged
    83 
    84     public EventHandler ProblemDataChanged;
    85     private void OnProblemDataChanged() {
    86       var changed = ProblemDataChanged;
     176      return new DatastreamAnalysisOptimizer(this, cloner);
     177    }
     178
     179    private void Initialize() {
     180      if (runs != null) RegisterRunsEvents();
     181    }
     182    #endregion
     183
     184    #region control actions
     185
     186    public override void Prepare() {
     187      if (ensembles == null || datastream == null) return;
     188      Prepare(true);
     189    }
     190
     191    public void Prepare(bool clearRuns) {
     192      if (ensembles == null || datastream == null) return;
     193      base.Prepare();
     194      if (clearRuns) results.Clear();
     195      OnPrepared();
     196    }
     197
     198    public override void Start() {
     199      if (ensembles == null || datastream == null) return;
     200      base.Start();
     201      cancellationTokenSource = new CancellationTokenSource();
     202      stopPending = false;
     203
     204      Task task = Task.Factory.StartNew(Run, cancellationTokenSource.Token, cancellationTokenSource.Token);
     205      task.ContinueWith(t => {
     206        try {
     207          t.Wait();
     208        }
     209        catch (AggregateException ex) {
     210          try {
     211            ex.Flatten().Handle(x => x is OperationCanceledException);
     212          } catch (AggregateException remaining) {
     213            if(remaining.InnerExceptions.Count == 1) OnExceptionOccurred(remaining.InnerExceptions[0]);
     214            else OnExceptionOccurred(remaining);
     215          }
     216        }
     217        cancellationTokenSource.Dispose();
     218        cancellationTokenSource = null;
     219
     220        // handle stop/pause
     221        if(stopPending) { }
     222        if(!Datastream.SlidingWindowMovementPossible) OnStopped();
     223        else OnPaused();
     224      });
     225
     226    }
     227
     228    public override void Pause() {
     229      if (ensembles == null || datastream == null) return;
     230      base.Pause();
     231      cancellationTokenSource.Cancel();
     232    }
     233
     234    public override void Stop() {
     235      if (ensembles == null || datastream == null) return;
     236      base.Stop();
     237      if (ExecutionState == ExecutionState.Paused) {
     238        OnStopped();
     239      } else {
     240        stopPending = true;
     241        cancellationTokenSource.Cancel();
     242      }
     243    }
     244
     245    protected override void OnPrepared() {
     246      Log.LogMessage("Datastream analysis prepared");
     247      base.OnPrepared();
     248    }
     249
     250    protected override void OnStarted() {
     251      Log.LogMessage("Datastream analysis started");
     252      base.OnStarted();
     253    }
     254
     255    protected override void OnPaused() {
     256      Log.LogMessage("Datastream analysis paused");
     257      base.OnPaused();
     258    }
     259
     260    protected override void OnStopped() {
     261      Log.LogMessage("Datastream analysis stopped");
     262      base.OnStopped();
     263    }
     264
     265    #endregion
     266
     267
     268    private void Run(object state) {
     269      CancellationToken cancellationToken = (CancellationToken) state;
     270      OnStarted();
     271      lastUpdateTime = DateTime.UtcNow;
     272      System.Timers.Timer timer = new System.Timers.Timer(250);
     273      timer.AutoReset = true;
     274      timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
     275      timer.Start();
     276
     277      try {
     278        Run(cancellationToken);
     279      }
     280      finally {
     281        timer.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed);
     282        timer.Stop();
     283        ExecutionTime += DateTime.UtcNow - lastUpdateTime;
     284      }
     285
     286      cancellationToken.ThrowIfCancellationRequested();
     287    }
     288
     289    protected void Run(CancellationToken cancellationToken) {
     290
     291      // setup results
     292      var slidingWindowMovements = new IntValue(0);
     293      Results.Add(new Result("Sliding Window Movements", slidingWindowMovements));
     294
     295      var qtable = new DataTable("Qualities");
     296      qtable.Rows.Add(new DataRow("R²"));
     297      qtable.Rows.Add(new DataRow("Pearson"));
     298      Results.Add(new Result("Qualities", qtable));
     299
     300      var curLoss = new DoubleValue();
     301      Results.Add(new Result("R²", curLoss));
     302      Results.Add(new Result("Best Quality", curLoss));
     303
     304
     305      // init algorithm
     306      var problemData = Datastream.ProblemData;
     307      var targetVarName = problemData.TargetVariable;
     308      var activeVariables = problemData.AllowedInputVariables;
     309      Random rnd = new Random();
     310
     311      try {
     312        while (Datastream.SlidingWindowMovementPossible) {
     313          cancellationToken.ThrowIfCancellationRequested();
     314
     315          Task.Delay(Datastream.SlidingWindowMovementInterval.Value);
     316
     317          Datastream.MoveSlidingWindow();
     318
     319          // TODO do the window evaluation
     320
     321          // TODO: collect results and display them
     322
     323          curLoss.Value = rnd.Next(100);
     324          qtable.Rows["R²"].Values.Add(curLoss.Value);
     325          qtable.Rows["Pearson"].Values.Add(curLoss.Value % 10);
     326
     327          slidingWindowMovements.Value++;
     328        }
     329
     330        // TODO: collect runs (c.f. goal seeking)
     331      }
     332      catch (Exception ex) {
     333        if (ex is ArgumentOutOfRangeException) throw ex;
     334        if (ex is OperationCanceledException) throw ex;
     335      }
     336      finally {
     337        // reset everything
     338        //Prepare(true);
     339      }
     340    }
     341
     342    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
     343      System.Timers.Timer timer = (System.Timers.Timer)sender;
     344      timer.Enabled = false;
     345      DateTime now = DateTime.UtcNow;
     346      ExecutionTime += now - lastUpdateTime;
     347      lastUpdateTime = now;
     348      timer.Enabled = true;
     349    }
     350
     351    public void CollectResultValues(IDictionary<string, IItem> values) {
     352      values.Add("Execution Time", new TimeSpanValue(ExecutionTime));
     353      Results.CollectResultValues(values);
     354    }
     355
     356    #region events
     357
     358    public EventHandler EnsemblesChanged;
     359    public EventHandler DatastreamChanged;
     360
     361    protected virtual void DeregisterRunsEvents() {
     362      runs.CollectionReset -= new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
     363    }
     364
     365    protected virtual void RegisterRunsEvents() {
     366      runs.CollectionReset += new CollectionItemsChangedEventHandler<IRun>(Runs_CollectionReset);
     367    }
     368
     369    protected virtual void Runs_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
     370      runsCounter = runs.Count;
     371    }
     372
     373    #region event handling
     374
     375    private void OnEnsemblesChanged() {
     376      var changed = EnsemblesChanged;
    87377      if (changed != null)
    88378        changed(this, EventArgs.Empty);
    89379    }
    90380
    91 
    92     public void Prepare() {
    93       Prepare(false);
    94     }
    95 
    96     public void Start() {
    97       if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused))
    98         throw new InvalidOperationException(string.Format("Start not allowed in execution state \"{0}\".", ExecutionState));
    99     }
    100 
    101     public void Pause() {
    102       if (ExecutionState != ExecutionState.Started)
    103         throw new InvalidOperationException(string.Format("Pause not allowed in execution state \"{0}\".", ExecutionState));
    104     }
    105 
    106     public void Stop() {
    107       if ((ExecutionState != ExecutionState.Started) && (ExecutionState != ExecutionState.Paused))
    108         throw new InvalidOperationException(string.Format("Stop not allowed in execution state \"{0}\".", ExecutionState));
    109     }
    110 
    111     public void Prepare(bool clearRuns) {
    112       if ((ExecutionState != ExecutionState.Prepared) && (ExecutionState != ExecutionState.Paused) && (ExecutionState != ExecutionState.Stopped))
    113         throw new InvalidOperationException(string.Format("Prepare not allowed in execution state \"{0}\".", ExecutionState));
    114     }
    115 
    116 
    117     [Storable]
    118     private TimeSpan executionTime;
    119     public TimeSpan ExecutionTime {
    120       get { return executionTime; }
    121       private set {
    122         executionTime = value;
    123         OnExecutionTimeChanged();
    124       }
    125     }
    126 
    127     public RunCollection Runs {
    128       get {
    129         return new RunCollection();
    130       }
    131     }
    132 
    133     public IEnumerable<IOptimizer> NestedOptimizers { get; }
    134     public string Filename { get; set; }
    135 
    136     public new static Image StaticItemImage
    137     {
    138       get { return HeuristicLab.Common.Resources.VSImageLibrary.Event; }
    139     }
    140 
    141     public override Image ItemImage {
    142       get {
    143         if (ExecutionState == ExecutionState.Prepared)
    144           return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPrepared;
    145         else if (ExecutionState == ExecutionState.Started)
    146           return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStarted;
    147         else if (ExecutionState == ExecutionState.Paused) return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunPaused;
    148         else if (ExecutionState == ExecutionState.Stopped)
    149           return HeuristicLab.Common.Resources.VSImageLibrary.BatchRunStopped;
    150         else return base.ItemImage;
    151       }
    152     }
    153 
    154     #region Events
    155 
    156     public ExecutionState ExecutionState { get; private set; }
    157     public event EventHandler ExecutionStateChanged;
    158     public event EventHandler ExecutionTimeChanged;
    159     public event EventHandler Prepared;
    160     public event EventHandler Started;
    161     public event EventHandler Paused;
    162     public event EventHandler Stopped;
    163     public event EventHandler<EventArgs<Exception>> ExceptionOccurred;
    164 
    165 
    166     #region event firing
    167 
    168     protected override void OnNameChanged() {
    169       base.OnNameChanged();
    170     }
    171 
    172     private void OnExecutionStateChanged() {
    173       EventHandler handler = ExecutionStateChanged;
     381    private void OnDatastreamChanged() {
     382      var changed = DatastreamChanged;
     383      if (changed != null)
     384        changed(this, EventArgs.Empty);
     385    }
     386
     387    #endregion
     388
     389    #endregion
     390
     391    #region nameditem
     392
     393    [Storable] protected string name;
     394
     395    /// <inheritdoc/>
     396    /// <remarks>Calls <see cref="OnNameChanging"/> and also <see cref="OnNameChanged"/>
     397    /// eventually in the setter.</remarks>
     398    public string Name {
     399      get { return name; }
     400      set {
     401        if (!CanChangeName) throw new NotSupportedException("Name cannot be changed.");
     402        if (!(name.Equals(value) || (value == null) && (name == string.Empty))) {
     403          CancelEventArgs<string> e = value == null
     404            ? new CancelEventArgs<string>(string.Empty)
     405            : new CancelEventArgs<string>(value);
     406          OnNameChanging(e);
     407          if (!e.Cancel) {
     408            name = value == null ? string.Empty : value;
     409            OnNameChanged();
     410          }
     411        }
     412      }
     413    }
     414
     415    public virtual bool CanChangeName {
     416      get { return true; }
     417    }
     418
     419    [Storable] protected string description;
     420
     421    public string Description {
     422      get { return description; }
     423      set {
     424        if (!CanChangeDescription) throw new NotSupportedException("Description cannot be changed.");
     425        if (!(description.Equals(value) || (value == null) && (description == string.Empty))) {
     426          description = value == null ? string.Empty : value;
     427          OnDescriptionChanged();
     428        }
     429      }
     430    }
     431
     432    public virtual bool CanChangeDescription {
     433      get { return true; }
     434    }
     435
     436    /// <summary>
     437    /// Gets the string representation of the current instance in the format: <c>Name: [null|Value]</c>.
     438    /// </summary>
     439    /// <returns>The current instance as a string.</returns>
     440    public override string ToString() {
     441      return Name;
     442    }
     443
     444    /// <inheritdoc/>
     445    public event EventHandler<CancelEventArgs<string>> NameChanging;
     446
     447    /// <summary>
     448    /// Fires a new <c>NameChanging</c> event.
     449    /// </summary>
     450    /// <param name="e">The event arguments of the changing.</param>
     451    protected virtual void OnNameChanging(CancelEventArgs<string> e) {
     452      var handler = NameChanging;
     453      if (handler != null) handler(this, e);
     454    }
     455
     456    /// <inheritdoc/>
     457    public event EventHandler NameChanged;
     458
     459    /// <summary>
     460    /// Fires a new <c>NameChanged</c> event.
     461    /// </summary>
     462    /// <remarks>Calls <see cref="ItemBase.OnChanged"/>.</remarks>
     463    protected virtual void OnNameChanged() {
     464      var handler = NameChanged;
    174465      if (handler != null) handler(this, EventArgs.Empty);
    175     }
    176 
    177     private void OnExecutionTimeChanged() {
    178       EventHandler handler = ExecutionTimeChanged;
     466      OnToStringChanged();
     467    }
     468
     469    /// <inheritdoc/>
     470    public event EventHandler DescriptionChanged;
     471
     472    /// <summary>
     473    /// Fires a new <c>DescriptionChanged</c> event.
     474    /// </summary>
     475    /// <remarks>Calls <see cref="ItemBase.OnChanged"/>.</remarks>
     476    protected virtual void OnDescriptionChanged() {
     477      var handler = DescriptionChanged;
    179478      if (handler != null) handler(this, EventArgs.Empty);
    180479    }
    181480
    182     private void OnPrepared() {
    183       ExecutionState = ExecutionState.Prepared;
    184       EventHandler handler = Prepared;
    185       if (handler != null) handler(this, EventArgs.Empty);
    186     }
    187 
    188     private void OnStarted() {
    189       ExecutionState = ExecutionState.Started;
    190       EventHandler handler = Started;
    191       if (handler != null) handler(this, EventArgs.Empty);
    192     }
    193 
    194     private void OnPaused() {
    195       ExecutionState = ExecutionState.Paused;
    196       EventHandler handler = Paused;
    197       if (handler != null) handler(this, EventArgs.Empty);
    198     }
    199 
    200     private void OnStopped() {
    201       ExecutionState = ExecutionState.Stopped;
    202       EventHandler handler = Stopped;
    203       if (handler != null) handler(this, EventArgs.Empty);
    204     }
    205 
    206     private void OnExceptionOccurred(Exception exception) {
    207       EventHandler<EventArgs<Exception>> handler = ExceptionOccurred;
    208       if (handler != null) handler(this, new EventArgs<Exception>(exception));
    209     }
    210 
    211     #endregion
    212 
    213 
    214     #endregion
    215 
     481    #endregion nameditem
    216482  }
    217483}
  • branches/HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/HeuristicLab.DatastreamAnalysis.csproj

    r14491 r14536  
    102102  </ItemGroup>
    103103  <ItemGroup>
     104    <Compile Include="AnalysisBase.cs" />
     105    <Compile Include="Datastream.cs" />
    104106    <Compile Include="DatastreamAnalysisOptimizer.cs" />
     107    <Compile Include="DatastreamAnalysisUtil.cs" />
     108    <Compile Include="IAnalysisBase.cs" />
     109    <Compile Include="IDatastream.cs" />
    105110    <Compile Include="Plugin.cs" />
    106111    <Compile Include="Properties\AssemblyInfo.cs" />
  • branches/HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/HeuristicLab.DatastreamAnalysis.csproj.user

    r14488 r14536  
    44    <StartAction>Program</StartAction>
    55    <StartProgram>C:\dev\workspaces\hl-core\trunk\sources\bin\HeuristicLab 3.3.exe</StartProgram>
     6    <StartArguments>/hidestarter /start:Optimizer</StartArguments>
    67  </PropertyGroup>
    78  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
    89    <StartAction>Program</StartAction>
    910    <StartProgram>C:\dev\workspaces\hl-core\trunk\sources\bin\HeuristicLab 3.3.exe</StartProgram>
     11    <StartArguments>/hidestarter /start:Optimizer</StartArguments>
    1012  </PropertyGroup>
    1113</Project>
  • branches/HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Plugin.cs

    r14491 r14536  
    2323
    2424namespace HeuristicLab.DatastreamAnalysis {
    25   [Plugin("HeuristicLab.DatastreamAnalysis", "3.4.14.14488")]
     25  [Plugin("HeuristicLab.DatastreamAnalysis", "3.4.14.14491")]
    2626  [PluginFile("HeuristicLab.DatastreamAnalysis-3.4.dll", PluginFileType.Assembly)]
    2727  [PluginDependency("HeuristicLab.Collections", "3.3")]
  • branches/HeuristicLab.DatastreamAnalysis/HeuristicLab.DatastreamAnalysis/3.4/Properties/AssemblyInfo.cs

    r14491 r14536  
    5454// [assembly: AssemblyVersion("1.0.*")]
    5555[assembly: AssemblyVersion("3.4.0.0")]
    56 [assembly: AssemblyFileVersion("3.4.14.14488")]
     56[assembly: AssemblyFileVersion("3.4.14.14491")]
Note: See TracChangeset for help on using the changeset viewer.