Advanced configuration
Writing a basic ArupCompute calculation is not much different from writing a .NET function, here are now some additional features/gotchas that ArupCompute offers that you can add to your library.
You can see all the examples below in the sample repo https://github.com/arup-group/arupcompute-sample-library.
Project Structure
As mentioned earlier, the tree structure of the methods in the ArupCompute menu is derived from the namespaces where your classes live.
Your project structure (folders and .cs files) should follow the namespace structure.
Input Attribute
Input names, are automatically nicely formatted when your Input
attributes have the Latex field filled in. Here is a quick cheat sheet. Same goes for units.
See the example below:
[Calculation("Input sample", "Example of how to format input variables.", "[email protected]", Arup.Compute.DotNetSdk.Enums.LevelOfReview.Complete)]
public static double InputSample(
[Input("alpha", "First number", "MPa", "\\alpha")]
double a,
[Input("beta", "Second number", "MPa", "\\beta")]
double b)
{
//...
}
You'll need a double backslash \ as the first escapes the latter in C#.
Will display as:
Optional inputs
ArupCompute supports the use of optional inputs. These require no ArupCompute-specific setup and it can be setup in the normal C# way:
[Calculation("Input sample", "Example of how to format input variables.", "[email protected]", Arup.Compute.DotNetSdk.Enums.LevelOfReview.Complete)]
public static double InputSample(
[Input("alpha", "First number", "MPa", "\\alpha")]
double a,
[Input("beta", "Second number", "MPa", "\\beta")]
double b = 10.2)
{
//...
}
This will set the input b
as an optional input.
ArupCompute also supports nullable inputs. However, ArupCompute does not support inputs that are both nullable and optional. If a nullable, optional, input is supplied then ArupCompute will treat this input as only optional.
Output Attribute
Similarly to inputs, you'll need to describe what the outputs of your calculations are in more detail by using the Output
attribute. This needs to be placed on the method itself.
If returning multiple items you will need multiple Output
attributes, where the symbol between the attribute and the ResultItem
match.
These attributes are needed to advertise what your calculation returns before running it. This enables things like the Grasshopper and Dynamo components to build themselves, as well as allowing the Excel client to advertise to users what options they will have.
Results
A few conventions are in place to display nice results in the ArupCompute Web UI. You are not forced to follow them, ArupCompute will do its best to display your result anyway!
If your method returns a simple type (double
, int
, string
...) that will be displayed in the result box, but no quick report or other fancy feature will be available. To support them, your method will have to return an object
and implement the fields mentioned below, the type of this object is up to you, it could be a generic object or extend the ArupComputeResult class as outlined below.
The ArupComputeResult Class
To facilitate consistency in results we have written the ArupComputeResult
class provided as part of the ArupCompute .NET SDK.
It's not mandatory to implement it, but recommended.
This class has predefined fields you can use to return your outputs, to use it add the using Arup.Compute.DotNetSdk;
directive to your classes.
ArupComputeResultItems
This field on the class is used to return consistent results so that they can be used in the various clients in a similar way. It also allows to output multiple results.
A sample implementation is the one below:
[Calculation("Multiple Result", "Example of how to write a calculation that returns multiple results. This function takes in some text and returns one result containg the numbers found in the text and in another the other carachters. ", "[email protected]", Arup.Compute.DotNetSdk.Enums.LevelOfReview.Complete)]
public static ArupComputeResult SplitNumbersAndText(string text)
{
var numbers = "";
var others = "";
foreach (var l in text)
{
if (Char.IsNumber(l))
{
numbers += l;
}
else
{
others += l;
}
}
ArupComputeResultItem r1 = new ArupComputeResultItem();
r1.Description = "Numbers found in the input text";
r1.Value = numbers;
ArupComputeResultItem r2 = new ArupComputeResultItem();
r2.Description = "Other characters found in the input text";
r2.Value = others;
ArupComputeResult result = new ArupComputeResult();
result.ArupComputeResultItems = new List<ArupComputeResultItem>();
result.ArupComputeResultItems.Add(r1);
result.ArupComputeResultItems.Add(r2);
return result;
}
The ArupComputeResult.ArupComputeReport_HTML field
Is used to enable the Quick Report in the Web UI, it can contain almost any HTML tag, so you can easily embed tables and SVG graphics. For example:
[Calculation("Sample SVG", "This function shows how to add custom HTML to your function output. It can contain most HTML tags, as for instance SVG, make sure to click he Quick Report button below!", "[email protected]", Arup.Compute.DotNetSdk.Enums.LevelOfReview.Complete)]
public static ArupComputeResult SVG(string text)
{
var result = new ArupComputeResult();
result.ArupComputeReport_HTML = text + @"<br /><br /><svg xmlns=""http://www.w3.org/2000/svg"" width=""24"" height=""24"" viewBox=""0 0 24 24""><path d=""M12 0c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm0 2c3.691 0 6.915 2.016 8.647 5h-17.294c1.732-2.984 4.956-5 8.647-5zm0 20c-5.514 0-10-4.486-10-10 0-1.045.163-2.052.461-3h1.859c.606 1.518 1.929 3 3.986 3 2.477 0 2.153-2.31 3.694-2.31s1.218 2.31 3.695 2.31c2.055 0 3.379-1.482 3.984-3h1.86c.298.948.461 1.955.461 3 0 5.514-4.486 10-10 10zm5.508-8.059l.492.493c-1.127 1.72-3.199 3.566-5.999 3.566-2.801 0-4.874-1.846-6.001-3.566l.492-.493c1.513 1.195 3.174 1.931 5.509 1.931 2.333 0 3.994-.736 5.507-1.931z""/></svg>";
return result;
}
Pretty Formulas
To display pretty formulas inside your quick report, you need to write them using the KaTeX notation and wrap each line in dollars $$
.
For instance, the following code:
[Calculation("Pretty formula", "This is how to add pretty formuas to your report, make sure to click the Quick Report button below!",
"[email protected]", Arup.Compute.DotNetSdk.Enums.LevelOfReview.Complete)]
public static ArupComputeResult PrettyFormula()
{
var result = new ArupComputeResult();
result.ArupComputeReport_HTML = @"$$c = \pm\sqrt{a^2 + b^2}$$";
return result;
}
Will render as:
Error, Warnings, Remarks fields
Errors, warnings and remarks, should be stored respectively inside the Errors
, Warnings
, Remarks
fields as List<string>
.
[Calculation("Errors Warings & Remarks", "Shows how to use Errors, Warnings and Remarks. If the input number is < 0 will output an error, if < 5 a warning, if > 10 a remark.","[email protected]", Arup.Compute.DotNetSdk.Enums.LevelOfReview.Complete)]
public static ArupComputeResult ErrorsWaringsRemarks(double n)
{
var result = new ArupComputeResult();
result.ArupComputeReport_HTML = "<h1>Report:</h1></br>";
if (n < 0)
{
result.Errors = new List<string>();
result.Errors.Add("n is too low!");
result.Errors.Add("You forgot to buy milk today!");
result.ArupComputeReport_HTML += "<h3>Errors:</h3>";
result.ArupComputeReport_HTML += string.Join(" </br> ", result.Errors);
}
else if (n < 5)
{
result.Warnings = new List<string>();
result.Warnings.Add("n is quite low, but I'll let it pass for today...");
result.ArupComputeReport_HTML += "<h3>Warnings:</h3>";
result.ArupComputeReport_HTML += string.Join(" </br> ", result.Warnings);
}
else if (n > 10)
{
result.Remarks = new List<string>();
result.Remarks.Add("Good job, you picked a gread n value!");
result.Remarks.Add("Remember to buy milk today!");
result.ArupComputeReport_HTML += "<h3>Remarks:</h3>";
result.ArupComputeReport_HTML += string.Join(" </br> ", result.Remarks);
}
return result;
}
Using Environment Variables
The environment variables used by a library must be registered with ArupCompute ahead of publishing the library. Registration is initiated by sending the variable name and value to an ArupCompute administrator. If they contain secrets, then share the details by Outlook encrypted email, password manager or by phone only. To encrypt a new email in Outlook, select "Options" then "Encrypt:
Variable names must be in uppercase, prefixed with "AC_" and contain only ascii digits (0-9), letters (A-Z) and underscore. Consecutive underscores are not allowed.
The code below shows how to access an environment variable named AC_APP_SECRET:
var secret = Environment.GetEnvironmentVariable("AC_APP_SECRET");