Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin

Contents

3
Panel
Panel
borderStylesolid
Page Tree
rootTOOLS:Tutorial
startDepth
scrollbar

Exercise outline

The goal of this exercise is to create a simple hydrological volume model. In the end, it should be possible to run the volume model and inspect some (dummyvery simple) spatio-temporal output results.

Create a new model class

Add a new folder to the plugin project project a new folder named Models. In this folder, create a new class named VolumeModel.cs and add the following codeadapt the contents as shown below:

Code Block
using System;
using System.Linq;
using DelftTools.Functions;
using DelftTools.Functions.Generic;
using DelftTools.Hydro;
using DelftTools.Shell.Core.Workflow;
using DelftTools.Shell.Core.Workflow.DataItems;
using log4net;
using NetTopologySuite.Extensions.Coverages;

namespace DeltaShell.PluginPlugins.DemoAppVolumeModel.Models
{
    public class VolumeModel : ModelBase
    {
        private static readonly ILog Log = LogManager.GetLogger(typeof(VolumeModel)); // Handle for writing log messages

        private readonly DrainageBasin basin;
        private readonly TimeSeries precipitation;
        private readonly FeatureCoverage volume;

        /// <summary>
        /// Creates a volume model
        /// </summary>
        public VolumeModel()
        {
            // Create the input items of the volume model
            basin = new DrainageBasin();
            precipitation = new TimeSeries { Components = { new Variable<double>("Precipitation") } };

            // Create the output item of the volume model
            volume = new FeatureCoverage("Output data")
                {
                    IsTimeDependent = true,
                Arguments = {  Arguments = { new Variable<Catchment>("Catchment") { FixedSize = 0 } },
                    Components = { new Variable<double>("Volume") },
                };

            // ActuallyWrap addfields theas input/output items to the model after wrapping them with data items
            DataItems.Add(new DataItem(basinprecipitation, "BasinPrecipitation", typeof(DrainageBasinTimeSeries), DataItemRole.Input, "BasinTagPrecipitationTag"));
            DataItems.Add(new DataItem(precipitationbasin, "PrecipitationBasin", typeof(TimeSeriesDrainageBasin), DataItemRole.Input, "PrecipitationTagBasinTag"));
            DataItems.Add(new DataItem(volume, "Volume", typeof(FeatureCoverage), DataItemRole.Output, "VolumeTag"));
        }

        /// <summary>
        /// The basin precipitation time series: P = P(t) [L/T]. Input of the volume model.
        /// </summary>
        public DrainageBasinTimeSeries Precipitation
 Basin { get { return basin; } }{

        /// <summary>
   get { return precipitation; }
 /// The precipitation time series of the volume model}

        /// </summary><summary>
        public TimeSeries Precipitation { get { return precipitation; } }
/// The drainage basin (set of catchments). Input of the model.
        /// <summary></summary>
        ///public TheDrainageBasin initializationBasin
  of model runs
    {
    /// </summary>
       get protected{ overridereturn void OnInitialize()basin; }
        {}

            /// Clear<summary>
 any previous output
      /// Time-dependent feature coverage containing the volume.Clear();

     of water per catchment: V = V(t, c) [L3/T]. Output of the model.
        /// Ensure</summary>
 the coordinate system of the volume output ispublic theFeatureCoverage sameVolume
 as the    catchments input (basin){
            volume.CoordinateSystem = basin.CoordinateSystem;

get { return volume; }
        }

        /// <summary>
 Check if at least one catchment is present
/// The initialization of model runs
       if (!basin.Catchments.Any()) /// </summary>
        protected override void  {OnInitialize()
          {
      Log.Error("At least one catchment should be present");

     // Clear any previous output
            Status = ActivityStatus.Failed; // Cancels the model run
volume.Clear();

            // Ensure the coordinate system }

of the volume output is the same as the catchments input (basin)
 // Check if at least one precipitation value is present
  volume.CoordinateSystem = basin.CoordinateSystem;

        if (precipitation.Time.Values.Count == 0)
 // Ensure at least one catchment and one precipitation value is {present
            ValidateInputData();

     Log.Error("At least one precipitation value should be present");

      // Initialize the output feature coverage
           Status = ActivityStatus.Failed; // Cancels the model run
 volume.Features.AddRange(basin.Catchments);
            volume.FeatureVariable.FixedSize    }
= basin.Catchments.Count;
            if (Status == ActivityStatus.Failed)volume.FeatureVariable.AddValues(basin.Catchments);
        }

    {
    /// <summary>
        /// The actual return;
calculation during model run
         }
/// </summary>
        protected override bool OnExecute()
 // Initialize the volume output feature  coverage{
            // Loop  volume.Features.AddRange(basin.Catchments);
all times
             volume.FeatureVariable.FixedSize = basin.Catchments.Count;foreach (var time in precipitation.Time.Values)
            volume.FeatureVariable.AddValues(basin.Catchments);{
        }

        /// <summary>
Obtain the precipitation      /// The actual calculation during the model runsvalue for the current time
        /// </summary>
       var protectedp override bool= OnExecute(double) precipitation[time];

        {
        // Calculate a volume value for every //catchment Obtainbased allon timescatchment ofarea theand precipitation value
   time series
            var timesvolumes = precipitationbasin.TimeCatchments.GetValues(Select(c => c.AreaSize * p);

                // LoopAdd allthe times
calculated volume values to the output feature coverage
     foreach (var time in times)
       volume[time] = volumes;
   {
         }

       // Obtain the precipitation value forreturn thetrue;
 current time
      }

        private  var timeSeriesValue = (double) precipitation[time];

void ValidateInputData()
        {
         // Loop all catchmentsvar andhasCatchments calculate= (a dummy) volume value based on catchment area and precipitation value
basin.Catchments.Any();
            var hasPrecipitationData         var volumeValues = basin.Catchments.Select(c => c.AreaSize * timeSeriesValue= precipitation.Time.Values.Any();

            if (!hasCatchments && !hasPrecipitationData)
  // Add the calculated volume values to the output feature coverage{
                volume[time] = volumeValuesthrow new InvalidOperationException("At least one catchment and one precipitation value should be present");
            }

            return true;
if (!hasCatchments)
            }{
    }
}

                throw new InvalidOperationException("At least one catchment should be present");
            }

            if (!hasPrecipitationData)
            {
                throw new InvalidOperationException("At least one precipitation value should be present");
            }
        }
    }
}
Info

The model class is derived from

Info

The model class derives the ModelBase class in order to automatically implement some basic time dependent modeling logic.

Furthermore, the The comments in the code should explain the different parts of the model implementation.

Note

The model uses some basic data stuctures structures like data items, (feature) coverages and timeseries (functions). A description on the backgrounds background and usage of these data structures is not part of this tutorial.

Wiki Markup
*\[TODO\]*
Add links to some wiki pages?

Register the model in the application plugin class

Register the model in the application plugin by adding the following code to VolumeModelApplicationPlugin.cs:

Code Block

using DeltaShell.Plugin.DemoApp.Models;

and

Code Block
        public override IEnumerable<ModelInfo> GetModelInfos()
        {
            yield return new ModelInfo
            {
                Name = "Volume Model",
                Category = "DemoAppVolume models",
                CreateModel = o => new Models.VolumeModel()
            };
        }

Delta Shell should now be able to detect, create and run volume models.

Exercise results

First of all, obtain download the following WaterML2 XML file: WaterML2_precipitation_data.XML. Also obtain and download and unzip the following shape files contained in the following archive: Gemeenten.7z.zip. You will use all these data along the exercise.

Next, Then run the application and start creating a new model item (right click on project | Add | New Model ...). Ensure the new model is visible in the model selection dialog like shown in the following image:

Wiki Markup
*\[TODO\]*
Add screenshot of the model selection dialog

. Make sure that the new model is selected in the dialog:

Image Added

If you now click on OKAfter selecting the volume model, a new model item should be added to the project with a structure like as shown in the following image:

Wiki Markup
*\[TODO\]*
Add screenshot of the model items in the project explorer

Run Image Added

Try to run the model (right click on the volume model item | Run Model) and check the Messages window; some . The following error messages should be present like shown in the following image:

Wiki Markup
*\[TODO\]*
Add screenshot of Messages window with error messages

In order to perform a successfull model run, some precipitation and catchment input data needs to be imported.

will be generated:

Image Added

As indicated in the error messages, some precipitation and catchment input data must be available in order to successfully run the model.

First, start importing some WaterML2 data on the precipitation time series item (right click the precipitation item | Import...). A file selection dialog automatically pops up. Select the previously downloaded WaterML2 XML file.

After finishing the import, the precipitation item should contain data as shown in the following image (double click the precipitation item in the Project window):

Image Added

Next, start importing a shape file on the basin item (right click the basin First, start importing some WaterML2 data on the precipitation time series item (right click the precipitation item | Import...). A file selection dialog automatically pops up. Select the obtained WaterML2 XML file.

After finishing the import action, the precipitation item should contain data like shown in the following image:

Wiki Markup
*\[TODO\]*
Add screenshot of the imported WaterML2 data

Secondly, start importing a shape file on the basin item (right click the basin item | Import...). A GIS import wizard automatically pops up. Walk through the wizard like shown in the following images:

Wiki Markup
*\[TODO\]*
Screenshot of page 1 of the wizard

Wiki Markup
*\[TODO\]*
Screenshot of page 2 of the wizard
=> Catchments
=> File
=> Click "Add to import list"
=> Part of import list

Wiki Markup
*\[TODO\]*
Screenshot of page 3 of the wizard
=> GM_NAAM

Wiki Markup
*\[TODO\]*
Screenshot of page 4 of the wizard

Wiki Markup
*\[TODO\]*
Screenshot of page 5 of the wizard

After finishing the import action, the basin item should contain data like shown in the following image:

Wiki Markup
*\[TODO\]*
Add screenshot of the imported catchment data

Run the model again and check the Messages window; no error messages should be present.

Open the volume output and ensure the model results are like shown in the following image:

GIS import wizard automatically pops up. Press on Next to enter the wizard:

Image Added

Now, you have to specify what type of feature you are going to import and from where. In the drop down menu for Features, select the type Catchments (1). Next, click on the ...  button (2) and browse to select the shape file at the location where you have previously unzipped it (3). Once this selection has been made, you need to add the combination of feature type and source file to the import list (4). The list will be updated with the previous selection (5). At this step, you could continue adding more features from other files to the import list. We don't need to do this, so simply continue with the wizard pressing the Next button (6).

Image Added

You can now map the different properties of the imported GIS data into the model features. Map the Name property to GM_NAAM and continue with the import wizard.

Image Added

In general, there can be some small differences between the coordinates of different features which are actually located in the same position. The snapping precision specifies the magnitude of this margin. Simply, leave it as default and continue with the wizard.

Image Added

By clicking on Finish, the wizard will be completed and the import will be started.

Image Added

After finishing the import, the basin item should contain data as shown in the following image (double click on the basin item in the Project window):

Image Added

Now, run the model again and notice that, this time, no new error messages have been sent to the Messages window.

Open the volume output (double click the volume item in the Project window and select the Map view) and check that the model results agree with the ones shown in the following image:

Image Added

Wiki Markup
*\[TODO\]*
Add screenshot of volume model output

Info

In order to inspect time dependent (output) data, open the Time Navigator window and move the slider or click one of the auto play buttons.:

Image Added



scrollbar