webMathematica in the Gardening Industry

Rolf Mertig,

GluonVision GmbH, http://mertig.com, Berlin, Germany

Introduction

GluonVision is doing webMathematica projects, together with CANdiensten, the dutch reseller/consultancy provider from The Netherlands  .
In the last years the gardening industry discovered more and more the value of quantitative modeling and computabilty.
In this talk I will portrait one active consultancy project (The Ridder Group) and one prospective project (Green Formula), as well as a quick technology preview.

Furthermore I would like to share a few webMathematica best-practice ideas.

Gardening industry

Modern gardening industry needs greenhouses (at least in the colder parts of Europe, like The Netherlands).

Greenhouses in Westland, Netherlands.

Wikipedia:

Greenhouses began to be built in the Westland area of the Netherlands in the mid-nineteenth century. The addition of sand to bogs and clay soil created fertile soil for agriculture, and around 1850, grapes were grown in the first greenhouses, simple glass constructions with one of the sides consisting of solid wall. By the early 20th century, greenhouses began to be constructed of nothing but glass, and they began to be heated.

Greenhouses began to be built in the Westland area of the Netherlands in the mid-nineteenth century. The addition of sand to bogs and clay soil created fertile soil for agriculture, and around 1850, grapes were grown in the first greenhouses, simple glass constructions with one of the sides consisting of solid wall. By the early 20th century, greenhouses began to be constructed of nothing but glass, and they began to be heated.

Greenhouses in Westland, Netherlands.

Why webMathematica in gardening?

Greenhouses need a lot of custom-tailored technology.
Instead of selling and specifying the technology like motors and drive systems through static catalogues (paper in the past) Ridder Drive Systems started an interactive web-site system for their customers already years ago, using a Mathcad calculation server to calculate the right dimensions of the machinery needed in dependence of the green-house specifications.

Customer benefins are: tailored ordering procedure. Ridders benefits: streamlines the process, improves customer relations.

Problem: the web-Mathcad is not being supported by the new owner (PTZ) anymore and does not run sufficiently robust.

Ridder Drive Systems

Ridder Group company

The Ridder Group produces machinery for horticulture and agriculture.

The old model (Mathcad)

First page of the Mathcad output of an evaluated worksheet:

The translated model (Mathematica)

webMathematica realization

Input page ( with HTML frame)

Input page (just JSP)

Output (numbers and graphics):

PDF generation

A simple example of webMathematica workflow - “best practice”

Goal: do development and debugging as much as possible in a Mathematica notebook and not inside webMathematica.

Use Flash (MSPManipulate) to illustrate the procedure:

generate a notebook

SetDirectory @ NotebookDirectory[];

examplenb = Notebook[{

Cell[CellGroupData[{
Cell[TextData[{
 "Example of (web)",
 StyleBox["Mathematica",
  FontSlant->"Italic"],
 " code"
}], "Title",
 CellChangeTimes->{{3.5279583690035*^9, 3.5279583711070004`*^9}, 
   3.5279585479344997`*^9, 3.5279587266565*^9, {3.5279590135905*^9, 
   3.527959020382*^9}},
 $CellContext`InitializationGroup -> True],

Cell[TextData[{
 "All input cells which should also run in ",
 Cell[BoxData[
  FormBox[
   RowBox[{"web", 
    StyleBox[
     AdjustmentBox["Mathematica",
      BoxMargins->{{-0.175, 0}, {0, 0}}],
     FontSlant->"Italic"]}], TextForm]]],
 " should be initialization cells.\nHere the Title cell has the Cell \
Property Initialization Group."
}], "Text",
 CellChangeTimes->{{3.52795870387*^9, 3.5279587115594997`*^9}, {
  3.527958934124*^9, 3.5279590465355*^9}}],

Cell[CellGroupData[{

Cell["WebMathematicaQ", "Section",
 CellChangeTimes->{{3.5279583771175003`*^9, 3.5279583829565*^9}}],

Cell[BoxData[
 RowBox[{
  RowBox[{
   RowBox[{"WebMathematicaQ", "::", "usage"}], "=", 
   "\"\<WebMathematicaQ gives True in a webMathematica environment \
and False otherwise.\>\""}], ";"}]], "Input",
 CellChangeTimes->{{3.527958388668*^9, 3.5279584311505003`*^9}}],

Cell["Simple check: see if KernelTools` is loaded:", "Text",
 CellChangeTimes->{{3.5279584366724997`*^9, 3.52795846613*^9}}],

Cell[BoxData[{
 RowBox[{
  RowBox[{
   RowBox[{"WebMathematicaQ", "[", "]"}], " ", ":=", " ", 
   RowBox[{"MemberQ", "[", 
    RowBox[{"$Packages", ",", " ", "\"\<KernelTools`\>\""}], "]"}]}], 
  ";"}], "\n", 
 RowBox[{
  RowBox[{
   RowBox[{"If", "[", " ", 
    RowBox[{
     RowBox[{"!", " ", 
      RowBox[{"WebMathematicaQ", "[", "]"}]}], ",", 
     "
", "  ", 
     RowBox[{
      RowBox[{"SetOptions", "[", 
       RowBox[{
        RowBox[{"EvaluationNotebook", "[", "]"}], ",", 
        RowBox[{"AutoGeneratedPackage", "->", "Automatic"}]}], 
       "]"}], ";", "\n", "        ", 
      RowBox[{
      "ToExpression", "[", 
       "\"\<HTMLTableForm[(m_)?MatrixQ] := Grid[m];  \n               \
                         SetAttributes[MSPManipulate, HoldAll]; \n    \
                                    MSPManipulate[a__, OutputSize -> \
_, r_Rule] := Manipulate[a, r];\n                                     \
   MSPManipulate[a__]:=Manipulate[a];\n                               \
      \>\"", "]"}]}]}], "\n", "  ", "]"}], ";"}], " ", "\n", 
  RowBox[{"(*", " ", 
   RowBox[{
    RowBox[{"rend", " ", "=", " ", 
     RowBox[{
     "ControlsRendering", " ", "->", " ", 
      "\"\<FrontEnd.Windows\>\""}]}], ";"}], " ", 
   "*)"}]}], "
", 
 RowBox[{
  RowBox[{
   RowBox[{"rend", " ", "=", " ", 
    RowBox[{
    "ControlsRendering", " ", "->", " ", 
     "\"\<FrontEnd.Macintosh\>\""}]}], ";"}], "
", 
  RowBox[{"(*", " ", 
   RowBox[{"global", " ", "Style", " ", 
    RowBox[{"settings", ":"}]}], " ", "*)"}]}], "\n", 
 RowBox[{
  RowBox[{"$basestyle", " ", "=", " ", 
   RowBox[{"{", 
    RowBox[{
     RowBox[{"FontSize", " ", "->", " ", "18"}], ",", " ", "Bold", 
     ",", " ", 
     RowBox[{
     "FontFamily", " ", "->", " ", "\"\<Times New Roman\>\""}]}], 
    "}"}]}], ";"}], "\n", 
 RowBox[{
  RowBox[{"mystyle", " ", "=", " ", 
   RowBox[{
    RowBox[{"Style", "[", 
     RowBox[{"#", ",", " ", 
      RowBox[{"FontSize", " ", "->", " ", "18"}], ",", " ", "Bold", 
      ",", " ", 
      RowBox[{
      "FontFamily", " ", "->", " ", "\"\<Times New Roman\>\""}]}], 
     "]"}], " ", "&"}]}], ";"}], "\n", 
 RowBox[{
  RowBox[{"mystyle3", " ", "=", " ", 
   RowBox[{
    RowBox[{"Style", "[", 
     RowBox[{"#", ",", " ", 
      RowBox[{"FontSize", " ", "->", " ", "14"}], ",", " ", 
      RowBox[{
      "FontFamily", " ", "->", " ", "\"\<Times New Roman\>\""}]}], 
     "]"}], " ", "&"}]}], ";"}]}], "Input",
 CellChangeTimes->{
  3.527956538454*^9, {3.527958354396*^9, 3.527958360521*^9}, {
   3.527958496216*^9, 3.527958530448*^9}, {3.527958884061*^9, 
   3.52795889799*^9}}],

Cell[BoxData[
 RowBox[{
  RowBox[{"(*", 
   RowBox[{"algemene", " ", "sinusfunctie"}], "*)"}], "\n", "\n", 
  RowBox[{
   RowBox[{"doit", "[", "1", "]"}], " ", "=", " ", 
   RowBox[{"MSPManipulate", "[", "\n", "  ", "\n", "  ", 
    RowBox[{
     RowBox[{"Show", "[", "\n", "      ", 
      RowBox[{
       RowBox[{"Plot", "[", 
        RowBox[{
         RowBox[{"Sin", "[", "x", "]"}], ",", " ", 
         RowBox[{"{", 
          RowBox[{"x", ",", " ", 
           RowBox[{
            RowBox[{"-", "2"}], " ", "Pi"}], ",", " ", 
           RowBox[{"4", " ", "Pi"}]}], "}"}], ",", " ", 
         RowBox[{"ImageSize", " ", "->", " ", "500"}], ",", " ", "\n",
          "        ", 
         RowBox[{"PlotStyle", " ", "->", " ", 
          RowBox[{"Directive", "[", 
           RowBox[{"Red", ",", " ", 
            RowBox[{"Thickness", "[", "0.004", "]"}]}], "]"}]}], ",", 
         " ", "\n", "        ", 
         RowBox[{"AxesStyle", " ", "->", " ", "\n", "          ", 
          RowBox[{"Directive", "[", 
           RowBox[{
            RowBox[{"Thickness", "[", "0.002", "]"}], ",", " ", 
            RowBox[{"FontSize", " ", "->", " ", "10"}], ",", " ", 
            "\n", "            ", 
            RowBox[{"FontFamily", " ", "->", " ", "\"\<Arial\>\""}], 
            ",", " ", 
            RowBox[{"FontWeight", " ", "->", " ", "Bold"}]}], "]"}]}],
          ",", " ", "\n", "        ", 
         RowBox[{"AxesLabel", " ", "->", " ", 
          RowBox[{"{", 
           RowBox[{"\"\<x\>\"", ",", " ", 
            RowBox[{"mystyle", "[", 
             RowBox[{"NumberForm", "[", 
              RowBox[{
               RowBox[{
                RowBox[{"a", " ", 
                 RowBox[{"Sin", "[", 
                  RowBox[{"b", " ", "*", 
                   RowBox[{"(", 
                    RowBox[{"\"\<x\>\"", " ", "-", " ", "c"}], 
                    ")"}]}], "]"}]}], " ", "+", " ", "d"}], ",", " ", 
               RowBox[{"{", 
                RowBox[{"3", ",", " ", "1"}], "}"}]}], "]"}], "]"}]}],
            "  ", "}"}]}], " ", ",", " ", "\n", "        ", 
         RowBox[{"PlotRange", " ", "->", " ", "10"}], ",", " ", "\n", 
         "        ", 
         RowBox[{"Ticks", " ", "->", " ", 
          RowBox[{"{", 
           RowBox[{
            RowBox[{"{", 
             RowBox[{
              RowBox[{
               RowBox[{"-", "2"}], " ", "Pi"}], ",", " ", 
              RowBox[{
               RowBox[{"(", 
                RowBox[{
                 RowBox[{"-", "3"}], " ", "Pi"}], ")"}], "/", "2"}], 
              ",", " ", 
              RowBox[{"-", "Pi"}], ",", " ", 
              RowBox[{
               RowBox[{"-", "Pi"}], "/", "2"}], ",", " ", "0", ",", 
              " ", 
              RowBox[{"Pi", "/", "2"}], ",", " ", "Pi", ",", " ", 
              RowBox[{
               RowBox[{"(", 
                RowBox[{"3", " ", "Pi"}], ")"}], "/", "2"}], ",", " ",
               "\n", "              ", 
              RowBox[{"2", " ", "Pi"}], ",", " ", 
              RowBox[{
               RowBox[{"(", 
                RowBox[{"5", " ", "Pi"}], ")"}], "/", "2"}], ",", " ", 
              RowBox[{"3", " ", "Pi"}], ",", " ", 
              RowBox[{
               RowBox[{"(", 
                RowBox[{"7", " ", "Pi"}], ")"}], "/", "2"}], ",", " ", 
              RowBox[{"4", " ", "Pi"}]}], "}"}], ",", " ", 
            RowBox[{"{", 
             RowBox[{
              RowBox[{"-", "10"}], ",", " ", 
              RowBox[{"-", "8"}], ",", " ", 
              RowBox[{"-", "6"}], ",", " ", 
              RowBox[{"-", "4"}], ",", " ", 
              RowBox[{"-", "2"}], ",", " ", "0", ",", "\n", 
              "               ", "2", ",", " ", "4", ",", " ", "6", 
              ",", " ", "8", ",", " ", "10"}], "}"}]}], "}"}]}]}], 
        "]"}], ",", "\n", "       ", 
       RowBox[{"Plot", "[", 
        RowBox[{
         RowBox[{
          RowBox[{"a", " ", 
           RowBox[{"Sin", "[", 
            RowBox[{"b", " ", 
             RowBox[{"(", 
              RowBox[{"x", " ", "-", " ", "c"}], ")"}]}], "]"}]}], 
          " ", "+", " ", "d"}], ",", " ", 
         RowBox[{"{", 
          RowBox[{"x", ",", " ", 
           RowBox[{
            RowBox[{"-", "2"}], " ", "Pi"}], ",", " ", 
           RowBox[{"4", " ", "Pi"}]}], "}"}], ",", "  ", 
         RowBox[{"ImageSize", " ", "->", " ", "500"}], ",", " ", "\n",
          "        ", 
         RowBox[{"PlotStyle", " ", "->", " ", 
          RowBox[{"Directive", "[", 
           RowBox[{"Blue", ",", " ", 
            RowBox[{"Thickness", "[", "0.004", "]"}]}], "]"}]}], ",", 
         " ", "\n", "        ", 
         RowBox[{"AxesStyle", " ", "->", " ", "\n", "          ", 
          RowBox[{"Directive", "[", 
           RowBox[{
            RowBox[{"Thickness", "[", "0.002", "]"}], ",", " ", 
            RowBox[{"FontSize", " ", "->", " ", "10"}], ",", " ", 
            "\n", "            ", 
            RowBox[{"FontFamily", " ", "->", " ", "\"\<Arial\>\""}], 
            ",", " ", 
            RowBox[{"FontWeight", " ", "->", " ", "Bold"}]}], "]"}]}],
          ",", " ", "\n", "        ", 
         RowBox[{"AxesLabel", " ", "->", " ", 
          RowBox[{"{", 
           RowBox[{"x", ",", " ", 
            RowBox[{"mystyle", "[", 
             RowBox[{
              RowBox[{"a", " ", 
               RowBox[{"Sin", "[", 
                RowBox[{"b", " ", 
                 RowBox[{"(", 
                  RowBox[{"x", " ", "-", " ", "c"}], ")"}]}], "]"}]}],
               " ", "+", " ", "d"}], "]"}]}], "}"}]}], " ", ",", " ", 
         "\n", "        ", 
         RowBox[{"PlotRange", " ", "->", " ", "10"}], ",", " ", 
         RowBox[{"AspectRatio", " ", "->", " ", "1"}]}], "]"}]}], 
      "]"}], "\n", "  ", ",", "\n", "    ", 
     RowBox[{"{", 
      RowBox[{
       RowBox[{"{", 
        RowBox[{"a", ",", " ", "1", ",", " ", 
         RowBox[{"mystyle", "[", "\"\<amplitude\>\"", "]"}]}], "}"}], 
       ",", "  ", "0.5", ",", " ", "5", ",", " ", "rend"}], "}"}], 
     ",", " ", "\n", "    ", 
     RowBox[{"{", 
      RowBox[{
       RowBox[{"{", 
        RowBox[{"b", ",", " ", "1", ",", " ", 
         RowBox[{"mystyle", "[", "\"\<pulsation\>\"", "]"}]}], "}"}], 
       ",", " ", "0.5", ",", " ", "10", ",", " ", "rend"}], "}"}], 
     ",", " ", "\n", "    ", 
     RowBox[{"{", 
      RowBox[{
       RowBox[{"{", 
        RowBox[{"c", ",", " ", "0", ",", " ", 
         RowBox[{"mystyle", "[", "\"\<phase\>\"", "]"}]}], "}"}], ",",
        " ", 
       RowBox[{"-", "7"}], ",", " ", "7", ",", " ", "rend"}], "}"}], 
     "  ", ",", " ", "\n", "    ", 
     RowBox[{"{", 
      RowBox[{
       RowBox[{"{", 
        RowBox[{"d", ",", " ", "0", ",", " ", 
         RowBox[{"mystyle", "[", "\"\<intercept\>\"", "]"}]}], "}"}], 
       ",", " ", 
       RowBox[{"-", "7"}], ",", " ", "7", ",", " ", "rend"}], "}"}], 
     "  ", ",", "\n", "    ", 
     RowBox[{"ControlPlacement", " ", "->", "  ", "Left"}], ",", " ", 
     RowBox[{"OutputSize", " ", "->", " ", 
      RowBox[{"{", 
       RowBox[{"1000", ",", " ", "600"}], "}"}]}]}], 
    "]"}]}]}]], "Input",
 CellChangeTimes->{{3.5279566366844997`*^9, 3.5279566786429996`*^9}, {
   3.5279567225295*^9, 3.527956729598*^9}, {3.527956854124*^9, 
   3.5279568959425*^9}, {3.5279569557679996`*^9, 
   3.5279569697955*^9}, {3.5279583543975*^9, 
   3.5279583605264997`*^9}, {3.5280730746435003`*^9, 
   3.528073133066*^9}, 3.5280731854484997`*^9, {3.528073261145*^9, 
   3.5280732634230003`*^9}, {3.5280733012305*^9, 
   3.5280733036359997`*^9}}]
}, Open  ]]
}, Open  ]]
},
AutoGeneratedPackage->Automatic,
WindowSize->{1197, 638},
WindowMargins->{{21, Automatic}, {Automatic, 0}},
FrontEndVersion->"8.0 for Microsoft Windows (64-bit) (February 23, \
2011)",
StyleDefinitions->"Default.nb"
];

NotebookEvaluate[example=#1,InsertResults->True]&[SetSelectedNotebook[NotebookPut[examplenb]]];

NotebookSave[example,"example.nb"]

This generates in the same directory example.m  :

(* ::Package:: *)

(************************************************************************)
(* This file was generated automatically by the Mathematica front end.  *)
(* It contains Initialization cells from a Notebook file, which         *)
(* typically will have the same name as this file except ending in      *)
(* ".nb" instead of ".m".                                               *)
(*                                                                      *)
(* This file is intended to be loaded into the Mathematica kernel using *)
(* the package loading commands Get or Needs.  Doing so is equivalent   *)
(* to using the Evaluate Initialization Cells menu command in the front *)
(* end.                                                                 *)
(*                                                                      *)
(* DO NOT EDIT THIS FILE.  This entire file is regenerated              *)
(* automatically each time the parent Notebook file is saved in the     *)
(* Mathematica front end.  Any changes you make to this file will be    *)
(* overwritten.                                                         *)
(************************************************************************)



WebMathematicaQ::usage="WebMathematicaQ gives True in a webMathematica environment and False otherwise.";


WebMathematicaQ[] := MemberQ[$Packages, "KernelTools`"];
If[ ! WebMathematicaQ[],
  SetOptions[EvaluationNotebook[],AutoGeneratedPackage->Automatic];
        ToExpression["HTMLTableForm[(m_)?MatrixQ] := Grid[m];  
                                        SetAttributes[MSPManipulate, HoldAll]; 
                                        MSPManipulate[a__, OutputSize -> _, r_Rule] := Manipulate[a, r];
                                        MSPManipulate[a__]:=Manipulate[a];
                                     "]
  ]; 
(* rend = ControlsRendering -> "FrontEnd.Windows"; *)
rend = ControlsRendering -> "FrontEnd.Macintosh";
(* global Style settings: *)
$basestyle = {FontSize -> 18, Bold, FontFamily -> "Times New Roman"};
mystyle = Style[#, FontSize -> 18, Bold, FontFamily -> "Times New Roman"] &;
mystyle3 = Style[#, FontSize -> 14, FontFamily -> "Times New Roman"] &;


(*algemene sinusfunctie*)

doit[1] = MSPManipulate[
  
  Show[
      Plot[Sin[x], {x, -2 Pi, 4 Pi}, ImageSize -> 500, 
        PlotStyle -> Directive[Red, Thickness[0.004]], 
        AxesStyle -> 
          Directive[Thickness[0.002], FontSize -> 10, 
            FontFamily -> "Arial", FontWeight -> Bold], 
        AxesLabel -> {x, mystyle[NumberForm[a Sin[b *(x - c)] + d, {3, 1}]]  } , 
        PlotRange -> 10, 
        Ticks -> {{-2 Pi, (-3 Pi)/2, -Pi, -Pi/2, 0, Pi/2, Pi, (3 Pi)/2, 
              2 Pi, (5 Pi)/2, 3 Pi, (7 Pi)/2, 4 Pi}, {-10, -8, -6, -4, -2, 0,
               2, 4, 6, 8, 10}}],
       Plot[a Sin[b (x - c)] + d, {x, -2 Pi, 4 Pi},  ImageSize -> 500, 
        PlotStyle -> Directive[Blue, Thickness[0.004]], 
        AxesStyle -> 
          Directive[Thickness[0.002], FontSize -> 10, 
            FontFamily -> "Arial", FontWeight -> Bold], 
        AxesLabel -> {x, mystyle[a Sin[b (x - c)] + d]} , 
        PlotRange -> 10, AspectRatio -> 1]]
  ,
    {{a, 1, mystyle[amplitude]},  0.5, 5, rend}, 
    {{b, 1, mystyle[pulsatie]}, 0.5, 10, rend}, 
    {{c, 0, mystyle[fase]}, -7, 7, rend}  , 
    {{d, 0, mystyle[intercept]}, -7, 7, rend}  ,
    ControlPlacement ->  Left, OutputSize -> {1000, 600}]

The needed JSP file for webMathematica is then very simple and uses the same code as the (development / debugging) notebook:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<%@ taglib uri="http://www.wolfram.com/msp" prefix="msp" %>

<!-- example  -->

<msp:evaluate> 
	Needs["MSPManipulate`"]; 
</msp:evaluate>
<html>  
<head> 
<msp:evaluate> MSPManipulateHeader[$$updateArgs, $$manipulateNumber] </msp:evaluate> </head>
<body>

<msp:evaluate>
	SetDirectory @ MSPPageDirectory[];
    Get["example.m"];
</msp:evaluate>

<h3> Example </h3>

<msp:evaluate> doit @ 1 </msp:evaluate>
<msp:evaluate> (* doit @ 2 *) </msp:evaluate>

</body>
</html>

A similar idea is to write use DynamicModule, InputField, PopupMenu etc. to create a Notebook version of the functionality. Assign each dynmaic UI-widget to a variable. Then, with some extra custom-made translation code of the Dynamic variables to $$-webMathematica variables (there is a 1 to 1 correspondence) the 
UI-widgets are translated into the corresponding webMathematica HTML-fields, tables, etc. The details are somewhat involved, but it works and provides a nice way for the customer to change details of the model only in Mathematica. The JSP page does only have to be written once and is used for presenation (Model-View-Controller idea).

Future project: Green Formula ( JSP / CDF - generation )

GreenFormula Description

Mission:

Green Formula produces tailor made formulas so complex climate systems can be controlled easily.

Vision:

Green Formula is using the progressive way (using Mathematica web/CDF) to show all different climate management scenario’s.

This results in a perfect climate in all different circumstances, in which relations and effects are quantified on detail level.

The service and support of Green Formula is providing the high-tech grower with high profits.

Direct results are healthier crops, higher production and a more efficient use of energy and labour.

Technical realization idea:

Matheamtica code runs continuously on a webMathematica server, producing size-optimized (Graphics not throuh heavy JPEgs but by Interpolation)
customer-downloadable CDF documents.

Best practice lesson:

Use all of Mathematica for efficiency and clarity: CDF generated reports are quite interesting, even if there is some (quick) dynamic calculation for generation of graphics.

Alternative JSF/RichFaces/JLink FrontEnd

Work in progress: Use JLink from a Java Server Faces page with RichFaces (JBoss) opensource (AJAX/JavaScript generating) component libraries:

Conclusion

webMathematica can be used in unexpected environments like gardening

webMathematica is not that hard to use when following some best practices

alternative non-JSP webMathematica-like user interaces on the web are possible today (with JSF & GlassFish & RichFaces from JBoss)

GluonVision can help you realize your webMathematica site