Compare commits

...

11 Commits

Author SHA1 Message Date
e5bab28131 devel: Add ApiSurface test 2026-01-11 17:27:06 +01:00
e27d81202a fix: Update Arome to translate latlon to lambert
And again work with regular grids as they were before.
2026-01-05 17:04:21 +01:00
27d3183cca tmp: Remove .config
When using multiple nuget sources, and trying to build with nix, it
fails to finds these for some reason
2025-12-29 15:25:28 +01:00
3dcd775b0a wip: Stuff 2025-12-29 15:23:20 +01:00
b603b4d061 Add test for reading uv from tile coords 2025-12-18 16:51:00 +01:00
4e02b8e0d2 Delete build project 2025-12-18 16:50:32 +01:00
b6797b9ae9 Update arome rect struct 2025-12-18 16:50:06 +01:00
36b03d9d25 Refactor Arome.trySearchIndex into tryPick
Instead of while loop
2025-12-18 14:54:04 +01:00
010b6f6f25 feat: Update Arome to handle lat,lon grids 2025-12-18 14:51:41 +01:00
1b4c07337e fix: Create arome grid from lat lon grid
Instead of the x, y that was there before
2025-12-17 17:41:41 +01:00
afb3a9a724 fix: Add extra dimension to arome readUV 2025-12-17 17:41:11 +01:00
33 changed files with 1660 additions and 344 deletions

View File

@@ -1,69 +0,0 @@
open Fake.Core
open Fake.IO
open Farmer
open Farmer.Builders
open Helpers
initializeContext()
let srcPath = Path.getFullName "src"
let testPath = Path.getFullName "test"
let libPath = Some srcPath
let distPath = Path.getFullName "dist"
let packPath = Path.getFullName "packages"
let versionFile = Path.getFullName ".version"
Target.create "Clean" (fun _ -> Shell.cleanDir distPath)
Target.create "InstallClient" (fun _ ->
run bun "install" "."
run dotnet "tool restore" "."
)
Target.create "Bundle" (fun _ ->
run dotnet $"publish -c Release -o \"{distPath}\"" srcPath
)
Target.create "BundleDebug" (fun _ ->
run dotnet $"publish -c Debug -o \"{distPath}\"" srcPath
)
Target.create "Pack" (fun _ ->
match libPath with
| Some p -> run dotnet $"pack -c Release -o \"{packPath}\"" p
| None -> ()
)
Target.create "Format" (fun _ ->
run dotnet "fantomas . -r" "src"
)
Target.create "Test" (fun _ ->
if System.IO.Directory.Exists testPath then
run dotnet "run" testPath
else ()
)
open Fake.Core.TargetOperators
let dependencies = [
"Clean"
==> "InstallClient"
==> "Bundle"
"Clean"
==> "BundleDebug"
"Clean"
==> "Test"
"Clean"
==> "Pack"
]
[<EntryPoint>]
let main args = runOrDefault args

View File

@@ -1,105 +0,0 @@
module Helpers
open Fake.Core
let initializeContext () =
let execContext = Context.FakeExecutionContext.Create false "build.fsx" [ ]
Context.setExecutionContext (Context.RuntimeContext.Fake execContext)
module Proc =
module Parallel =
open System
let locker = obj()
let colors =
[| ConsoleColor.Blue
ConsoleColor.Yellow
ConsoleColor.Magenta
ConsoleColor.Cyan
ConsoleColor.DarkBlue
ConsoleColor.DarkYellow
ConsoleColor.DarkMagenta
ConsoleColor.DarkCyan |]
let print color (colored: string) (line: string) =
lock locker
(fun () ->
let currentColor = Console.ForegroundColor
Console.ForegroundColor <- color
Console.Write colored
Console.ForegroundColor <- currentColor
Console.WriteLine line)
let onStdout index name (line: string) =
let color = colors.[index % colors.Length]
if isNull line then
print color $"{name}: --- END ---" ""
else if String.isNotNullOrEmpty line then
print color $"{name}: " line
let onStderr name (line: string) =
let color = ConsoleColor.Red
if isNull line |> not then
print color $"{name}: " line
let redirect (index, (name, createProcess)) =
createProcess
|> CreateProcess.redirectOutputIfNotRedirected
|> CreateProcess.withOutputEvents (onStdout index name) (onStderr name)
let printStarting indexed =
for (index, (name, c: CreateProcess<_>)) in indexed do
let color = colors.[index % colors.Length]
let wd =
c.WorkingDirectory
|> Option.defaultValue ""
let exe = c.Command.Executable
let args = c.Command.Arguments.ToStartInfo
print color $"{name}: {wd}> {exe} {args}" ""
let run cs =
cs
|> Seq.toArray
|> Array.indexed
|> fun x -> printStarting x; x
|> Array.map redirect
|> Array.Parallel.map Proc.run
let createProcess exe arg dir =
CreateProcess.fromRawCommandLine exe arg
|> CreateProcess.withWorkingDirectory dir
|> CreateProcess.ensureExitCode
let dotnet = createProcess "dotnet"
let bun =
let bunPath =
match ProcessUtils.tryFindFileOnPath "bun" with
| Some path -> path
| None ->
"bun was not found in path. Please install it and make sure it's available from your path. " +
"See https://safe-stack.github.io/docs/quickstart/#install-pre-requisites for more info"
|> failwith
createProcess bunPath
let run proc arg dir =
proc arg dir
|> Proc.run
|> ignore
let runParallel processes =
processes
|> Proc.Parallel.run
|> ignore
let runOrDefault args =
try
match args with
| [| target |] -> Target.runOrDefault target
| _ ->
Target.runOrDefault "Pack"
0
with e ->
printfn "%A" e
1

View File

@@ -1,20 +0,0 @@
{
"version": 1,
"isRoot": true,
"tools": {
"fantomas": {
"version": "7.0.1",
"commands": [
"fantomas"
],
"rollForward": false
},
"dotnet-outdated-tool": {
"version": "4.6.7",
"commands": [
"dotnet-outdated"
],
"rollForward": false
}
}
}

4
.envrc
View File

@@ -1 +1,3 @@
use_nix
export NPINS_DIRECTORY="nix"
use_nix

View File

@@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include=".build/Helpers.fs" />
<Compile Include=".build/Build.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Fake.Core.Target" Version="6.1.3" />
<PackageReference Include="Fake.DotNet.Cli" Version="6.1.3" />
<PackageReference Include="Fake.IO.FileSystem" Version="6.1.3" />
<PackageReference Include="Farmer" Version="1.9.11" />
<PackageReference Update="FSharp.Core" Version="9.0.201" />
</ItemGroup>
</Project>

View File

@@ -9,8 +9,6 @@
<File Path="README.md" />
<File Path="shell.nix" />
</Folder>
<Folder Name="/submodules/" />
<Project Path="Build.fsproj" />
<Project Path="src/Oceanbox.FvcomKit.fsproj" />
<Project Path="test/Tests.fsproj" />
<Project Path="xtest/xtest.fsproj" />
</Solution>

19
default.nix Normal file
View File

@@ -0,0 +1,19 @@
{
sources ? import ./nix,
system ? builtins.currentSystem,
pkgs ? import sources.nixpkgs {
inherit system;
config = { };
overlays = [ ];
},
}:
let
sdk = pkgs.dotnetCorePackages.sdk_9_0;
sdslite = pkgs.callPackage ./nix/sdslite.nix { dotnet-sdk = sdk; };
projnetFsharp = pkgs.callPackage ./nix/projnet.fsharp.nix { dotnet-sdk = sdk; };
in
pkgs.callPackage ./src {
SDSLite = sdslite;
projnet = projnetFsharp;
dotnet-sdk = sdk;
}

146
nix/default.nix Normal file
View File

@@ -0,0 +1,146 @@
/*
This file is provided under the MIT licence:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the Software), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
# Generated by npins. Do not modify; will be overwritten regularly
let
data = builtins.fromJSON (builtins.readFile ./sources.json);
version = data.version;
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
range =
first: last: if first > last then [ ] else builtins.genList (n: first + n) (last - first + 1);
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
concatMapStrings = f: list: concatStrings (map f list);
concatStrings = builtins.concatStringsSep "";
# If the environment variable NPINS_OVERRIDE_${name} is set, then use
# the path directly as opposed to the fetched source.
# (Taken from Niv for compatibility)
mayOverride =
name: path:
let
envVarName = "NPINS_OVERRIDE_${saneName}";
saneName = stringAsChars (c: if (builtins.match "[a-zA-Z0-9]" c) == null then "_" else c) name;
ersatz = builtins.getEnv envVarName;
in
if ersatz == "" then
path
else
# this turns the string into an actual Nix path (for both absolute and
# relative paths)
builtins.trace "Overriding path of \"${name}\" with \"${ersatz}\" due to set \"${envVarName}\"" (
if builtins.substring 0 1 ersatz == "/" then
/. + ersatz
else
/. + builtins.getEnv "PWD" + "/${ersatz}"
);
mkSource =
name: spec:
assert spec ? type;
let
path =
if spec.type == "Git" then
mkGitSource spec
else if spec.type == "GitRelease" then
mkGitSource spec
else if spec.type == "PyPi" then
mkPyPiSource spec
else if spec.type == "Channel" then
mkChannelSource spec
else if spec.type == "Tarball" then
mkTarballSource spec
else
builtins.throw "Unknown source type ${spec.type}";
in
spec // { outPath = mayOverride name path; };
mkGitSource =
{
repository,
revision,
url ? null,
submodules,
hash,
branch ? null,
...
}:
assert repository ? type;
# At the moment, either it is a plain git repository (which has an url), or it is a GitHub/GitLab repository
# In the latter case, there we will always be an url to the tarball
if url != null && !submodules then
builtins.fetchTarball {
inherit url;
sha256 = hash; # FIXME: check nix version & use SRI hashes
}
else
let
url =
if repository.type == "Git" then
repository.url
else if repository.type == "GitHub" then
"https://github.com/${repository.owner}/${repository.repo}.git"
else if repository.type == "GitLab" then
"${repository.server}/${repository.repo_path}.git"
else
throw "Unrecognized repository type ${repository.type}";
urlToName =
url: rev:
let
matched = builtins.match "^.*/([^/]*)(\\.git)?$" url;
short = builtins.substring 0 7 rev;
appendShort = if (builtins.match "[a-f0-9]*" rev) != null then "-${short}" else "";
in
"${if matched == null then "source" else builtins.head matched}${appendShort}";
name = urlToName url revision;
in
builtins.fetchGit {
rev = revision;
inherit name;
# hash = hash;
inherit url submodules;
};
mkPyPiSource =
{ url, hash, ... }:
builtins.fetchurl {
inherit url;
sha256 = hash;
};
mkChannelSource =
{ url, hash, ... }:
builtins.fetchTarball {
inherit url;
sha256 = hash;
};
mkTarballSource =
{
url,
locked_url ? url,
hash,
...
}:
builtins.fetchTarball {
url = locked_url;
sha256 = hash;
};
in
if version == 5 then
builtins.mapAttrs mkSource data.pins
else
throw "Unsupported format version ${toString version} in sources.json. Try running `npins upgrade`"

29
nix/projnet.fsharp.nix Normal file
View File

@@ -0,0 +1,29 @@
{
dotnet-sdk,
fetchFromGitLab,
buildDotnetModule
}:
let
src = fetchFromGitLab {
owner = "oceanbox";
repo = "ProjNet.FSharp";
# tag = "v5.2.0";
rev = "722ce0c23fda6844a81e995afbb2d81cbd5f38ec";
private = true;
forceFetchGit = true;
hash = "sha256-Rvnnf/D2x90pwgvTbXz307MJVBlVPK/cCf1hqj2VosE=";
};
in
buildDotnetModule {
name = "ProjNet.FSharp";
src = src;
dotnet-sdk = dotnet-sdk;
projectFile = "src/ProjNet.FSharp.fsproj";
nugetDeps = "${src}/src/deps.json";
packNupkg = true;
executables = [ ];
}

29
nix/sdslite.nix Normal file
View File

@@ -0,0 +1,29 @@
{
dotnet-sdk,
fetchFromGitLab,
buildDotnetModule
}:
let
src = fetchFromGitLab {
owner = "oceanbox";
repo = "SDSlite";
# tag = "v2.8.0";
rev = "8c1a158206c37bc57a5bd726a792bd6a9cd2ec01";
private = true;
forceFetchGit = true;
hash = "sha256-i9pNrmH/VC0Q9FCldbWGdZHkqSL1cdYtAOs7vX+DlXM=";
};
in
buildDotnetModule {
name = "Oceanbox.SDSLite";
src = src;
dotnet-sdk = dotnet-sdk;
projectFile = "ScientificDataSet/ScientificDataSet.csproj";
nugetDeps = "${src}/ScientificDataSet/deps.json";
packNupkg = true;
executables = [ ];
}

23
nix/sources.json Normal file
View File

@@ -0,0 +1,23 @@
{
"pins": {
"nix-utils": {
"type": "Git",
"repository": {
"type": "Git",
"url": "https://git.sr.ht/~mrtz/nix-utils"
},
"branch": "trunk",
"submodules": false,
"revision": "098f594425d2b9dde0657becad0f6498d074f8b3",
"url": null,
"hash": "0hh52w1fkpr1xx6j8cjm6g88j2352yv2ysqm1q51j59y6f583vyb"
},
"nixpkgs": {
"type": "Channel",
"name": "nixpkgs-unstable",
"url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.05pre905319.f720de590661/nixexprs.tar.xz",
"hash": "07n4hhch0j6n69b0zchdjg0l80z2xrdk7k57ykv90cvhklim5dz1"
}
},
"version": 5
}

4
nix/sources.nix Normal file
View File

@@ -0,0 +1,4 @@
{
"ProjNet.FSharp" = "https://gitlab.com/api/v4/projects/35009572/packages/nuget/download";
"Oceanbox.SDSLite" = "https://gitlab.com/api/v4/projects/34025102/packages/nuget/download";
}

View File

@@ -1,13 +1,18 @@
with import <nixpkgs> { };
let
dotnet-sdk = dotnet-sdk_9;
sources = import ./nix;
pkgs = import sources.nixpkgs {};
dotnet-sdk = pkgs.dotnetCorePackages.sdk_9_0;
in
with import <nixpkgs> { };
mkShell rec {
packages = [
bun
dotnet-sdk
fsautocomplete
fantomas
npins
nixfmt
nuget-to-json
];
buildInputs = [
@@ -17,4 +22,4 @@ mkShell rec {
DOTNET_ROOT = "${dotnet-sdk}/share/dotnet";
LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs;
}
}

View File

@@ -139,6 +139,7 @@ let private genOobIdx (proj: IProj) (tree: KdTree<_, _>) (cullIdx: (int * int)[]
// cullIdx = cullIdx
// oobIdx = genOobIdx proj tree cullIdx fPos rPos
// }
let private mkFvcomAdjoint (proj: IProj) (fPos: PosVec) (bbox: BBox) ((rPos, wet): BiPos * Mask) =
let box = mkCropBox bbox
let pos' = reProject proj rPos
@@ -147,7 +148,9 @@ let private mkFvcomAdjoint (proj: IProj) (fPos: PosVec) (bbox: BBox) ((rPos, wet
let nearest =
fPos
|> Array.map (fun (x, y) -> tree.GetNearestNeighbours ([| x; y |], 1) |> Array.head |> (fun x -> x.Value))
{ adjoinIdx = nearest; cullIdx = cullIdx; oobIdx = genOobIdx proj tree cullIdx fPos rPos }
let oobIdx = genOobIdx proj tree cullIdx fPos rPos
{ adjoinIdx = nearest; cullIdx = cullIdx; oobIdx = oobIdx }
let inline float2 x = bimap float float x

View File

@@ -1,20 +1,103 @@
module Oceanbox.FvcomKit.Arome
open FSharpPlus
open System
open Microsoft.Research.Science.Data
open ProjNet.FSharp
open Serilog
open Types
[<Literal>]
let private regularGridEpsilon : float = 1E-4
let trans = makeTransform CoordSys.WGS84 (CoordSys.LCCMet ())
[<Struct>]
type Pointf = {
x: float
y: float
} with
static member Zero = { x = 0.0; y = 0.0 }
static member OfTuple (x, y) = { x = x; y = y }
static member OfStructTuple struct (x, y) = { x = x; y = y }
/// Single precision
[<Struct>]
type Points = {
x: single
y: single
} with
static member Zero = { x = 0.0f; y = 0.0f }
static member OfTuple (x, y) = { x = x; y = y }
static member OfStructTuple struct (x, y) = { x = x; y = y }
module Pointf =
let ofPoints (p: Points) : Pointf = { x = float p.x; y = float p.y }
let getBBox (points: Pointf array) : BBox =
let minX = points |> Array.minBy _.x |> _.x
let maxX = points |> Array.maxBy _.x |> _.x
let minY = points |> Array.minBy _.y |> _.y
let maxY = points |> Array.maxBy _.y |> _.y
let center = (minX + (maxX - minX)) / 2., (minY + (maxY - minY)) / 2.
{
minX = minX
maxX = maxX
minY = minY
maxY = maxY
center = center
}
module Points =
let getBBox (points: Points array) : BBox =
let minX = points |> Array.minBy _.x |> _.x
let maxX = points |> Array.maxBy _.x |> _.x
let minY = points |> Array.minBy _.y |> _.y
let maxY = points |> Array.maxBy _.y |> _.y
let center = float (minX + (maxX - minX)) / 2., float (minY + (maxY - minY)) / 2.
{
minX = float minX
maxX = float maxX
minY = float minY
maxY = float maxY
center = center
}
[<Struct>]
type Rect = {
min: Points
max: Points
} with
static member OfPoints p0 p1 = { min = p0; max = p1 }
module Rect =
let tupleWithin (rect: Rect) (x, y) : bool =
rect.min.x <= x && x <= rect.max.x
&& rect.min.y <= y && y <= rect.max.y
let pointWithin (rect: Rect) (p: Points) : bool =
rect.min.x <= p.x && p.x <= rect.max.x
&& rect.min.y <= p.y && p.y <= rect.max.y
[<Struct>]
type AromeRect = {
XIdx: int
YIdx: int
Rect: Rect
}
[<Struct>]
type SquareGrid = {
dimensions: int * int
BBox: BBox
squareSize: float
projection: ProjNet.CoordinateSystems.CoordinateSystem
points: Points array
} with
member this.getBoundingBox() = this.BBox
static member empty = {
@@ -22,15 +105,39 @@ type SquareGrid = {
BBox = BBox.empty
squareSize = 0.0
projection = CoordSys.LCCMet ()
points = Array.empty
}
let private square x = x * x
let haversineDistance (earthRadius: float) (x0: float) (y0: float) (x1: float) (y1: float) : float =
let mutable lat1 = y0
let mutable lat2 = y1
let lon1 = x0
let lon2 = x1
let dLat = Double.DegreesToRadians (lat2 - lat1)
let dLon = Double.DegreesToRadians (lon2 - lon1)
lat1 <- Double.DegreesToRadians lat1
lat2 <- Double.DegreesToRadians lat2
let a = square (Math.Sin (dLat / 2.0)) + Math.Cos lat1 * Math.Cos lat2 * square (Math.Sin (dLon / 2.0))
let c = 2.0 * Math.Asin (Math.Sqrt a)
let result = earthRadius * c
result
let inline sfst struct (x, _) = x
let inline ssnd struct (_, y) = y
let getBBox (xs: float array) (ys: float array) : BBox =
try
let minX = Array.min xs
let maxX = Array.max xs
let minY = Array.min ys
let maxY = Array.max ys
let center = float (minX + (maxX - minX)) / 2., float (minY + (maxY - minY)) / 2.
let minX = xs |> Array.min
let maxX = xs |> Array.max
let minY = ys |> Array.min
let maxY = ys |> Array.max
let center = (minX + (maxX - minX)) / 2., (minY + (maxY - minY)) / 2.
{
minX = minX
@@ -44,6 +151,63 @@ let getBBox (xs: float array) (ys: float array) : BBox =
BBox.empty
let getGrid (ds: DataSet) : Result<SquareGrid, string> =
try
let dimensions = ds.Dimensions["x"].Length, ds.Dimensions["y"].Length
let longs : float array2d = ds["longitude"].GetData () :?> float[,]
let lats : float array2d = ds["latitude"].GetData () :?> float[,]
// NOTE: The netcdf file dimensions are defined as (y, x)
let width = Array2D.length2 longs
let height = Array2D.length1 lats
let points : Points array =
let result = Array.create (width * height) Points.Zero
for i in 0 .. height - 1 do
for j in 0 .. width - 1 do
let lat = lats[i, j]
let lon = longs[i, j]
let p = lon, lat
// NOTE(simkir): Convert to lambert and undo all I've done... :(
let x, y = trans.project p
result[i * width + j] <- Points.OfTuple (single x, single y)
result
let bbox = Points.getBBox points
if points.Length < 2 then
Error "The dataset must contain at least 1 square"
else
let p0 = points[0 * width + 0]
let p1 = points[0 * width + 1]
let p2 = points[1 * width + 0]
let p3 = points[1 * width + 1]
let x1, x0 = if p1.x > p0.x then p1.x, p0.x else p0.x, p1.x
let y1, y0 = if p2.y > p1.y then p2.y, p1.y else p1.y, p2.y
let lengthX = x1 - x0
let lengthY = y1 - y0
let isSquare = lengthX = lengthY
if not isSquare then
Log.Warning (
"FvcomKit.Arome.getGrid grid is not square: {X1} - {X0} = {LengthX} = {LengthY} = {Y1} - {Y0}",
x1,
x0,
lengthX,
lengthY,
y1,
y0
)
Ok {
SquareGrid.empty with
dimensions = dimensions
BBox = bbox
squareSize = float lengthX
points = points
}
with exn ->
Log.Error (exn, "Sorcerer.Arome.getAromeSquareGrid exception")
Error $"Error reading arome grid: {exn.Message}"
let getSquareGrid (ds: DataSet) : Result<SquareGrid, string> =
try
let dimensions = ds.Dimensions["x"].Length, ds.Dimensions["y"].Length
let xs = (ds["x"].GetData () :?> single[]) |> Array.map float
@@ -77,27 +241,35 @@ let getGrid (ds: DataSet) : Result<SquareGrid, string> =
Log.Error (exn, "FvcomKit.Arome.getGrid exception")
Error $"Error reading arome grid: {exn.Message}"
let readUV (ds: DataSet) t x y =
let u = ds["x_wind_10m"].GetData ([| t; y; x |], [| 1; 1; 1 |]) :?> single[,,]
let v = ds["y_wind_10m"].GetData ([| t; y; x |], [| 1; 1; 1 |]) :?> single[,,]
u[0, 0, 0], v[0, 0, 0]
let readUV (ds: DataSet) (t: int) x y : single * single =
let xWind = ds["x_wind_10m"]
let yWind = ds["y_wind_10m"]
let origin = [| t; 0; y; x |]
let shape = [| 1; 1; 1; 1; |]
Log.Verbose("""Fetching NetCDF["x_wind_10m"]({Origin}, {Shape})""", origin, shape)
let us = xWind.GetData (origin, shape) :?> single[,,,]
let vs = yWind.GetData (origin, shape) :?> single[,,,]
us[0, 0, 0, 0], vs[0, 0, 0, 0]
/// Finds the index of a tile within a square grid, given its bounding box and square length
let tryFindIndex squareSize (wide, tall) (minX, minY) (maxX, maxY) (p0, p1) =
if (minX < p0 && p0 < maxX) && (minY < p1 && p1 < maxY) then
let dx = p0 - minX
let dy = p1 - minY
let xIdx = int (dx / squareSize)
let yIdx = int (dy / squareSize)
let tryFindIndex (grid: SquareGrid) (x0, y0) =
let wide, tall = grid.dimensions
let bbox = grid.BBox
if bbox.minX <= x0 && x0 < bbox.maxX && bbox.minY <= y0 && y0 < bbox.maxY then
let dx = x0 - bbox.minX
let dy = y0 - bbox.minY
let xIdx = int (dx / grid.squareSize)
let yIdx = int (dy / grid.squareSize)
if xIdx < wide && yIdx < tall then
Some (xIdx, yIdx)
else
Log.Warning (
"Got wrong indices within the bounding box of the archive: min {@Min}, max {@Max}, point {@Point}, delta {@Delta}m, indices {@Indices}",
(minX, minY),
(maxX, maxY),
(p0, p1),
(bbox.minX, bbox.minY),
(bbox.maxX, bbox.maxY),
(x0, y0),
(dx, dy),
(xIdx, yIdx)
)
@@ -105,17 +277,48 @@ let tryFindIndex squareSize (wide, tall) (minX, minY) (maxX, maxY) (p0, p1) =
else
None
let private createRects (grid: SquareGrid) : AromeRect array =
let width, height = grid.dimensions
[|
for i in 0 .. height - 1 do
for j in 0 .. width - 1 do
let k = i + 1
let l = j + 1
if k < height - 1 && l < width - 1 then
let min = grid.points[i * width + j]
let max = grid.points[k * width + l]
{
XIdx = j
YIdx = i
Rect = {
min = min
max = max
}
}
|]
let trySearchIndex (grid: SquareGrid) (p: single * single) : (int * int) option =
let rects = createRects grid
// TODO: Binary search
rects
|> Array.tryPick (fun rect ->
let within = Rect.tupleWithin rect.Rect p
if within then
Some (rect.XIdx, rect.YIdx)
else
None
)
/// Tries to get the closest x and y in the arome dataset based on position p
let tryFind (grid: SquareGrid) (p: float * float) : (int * int) option =
let min = grid.BBox.minX, grid.BBox.minY
let max = grid.BBox.maxX, grid.BBox.maxY
tryFindIndex grid p
tryFindIndex grid.squareSize grid.dimensions min max p
let tryFindWithProj (grid: SquareGrid) proj (p0: float, p1: float) : (int * int) option =
let trans = makeTransform proj grid.projection
let min = grid.BBox.minX, grid.BBox.minY
let max = grid.BBox.maxX, grid.BBox.maxY
let tryFindWithProj (proj: Projection) (grid: SquareGrid) (p0: float, p1: float) : (int * int) option =
let coordSys : ProjNet.CoordinateSystems.CoordinateSystem = Projection.ToCoordinateSystem proj
let trans = makeTransform coordSys grid.projection
let p = trans.project ((p0, p1))
tryFindIndex grid.squareSize grid.dimensions min max p
tryFindIndex grid p

View File

@@ -29,6 +29,7 @@ type FvcomGrid = {
member this.getVertices() = this.Nodes
member this.getCells() = this.Elem
member this.getBoundingBox() = this.BBox
static member empty = {
Elem = Array.empty
Nodes = Array.empty
@@ -39,6 +40,7 @@ type FvcomGrid = {
SiglayCenter = Array2D.zeroCreate 0 0
Siglev = Array2D.zeroCreate 0 0
}
member this.ToGrid() = { Elem = this.Elem; Nodes = this.Nodes; BBox = this.BBox }
let getNumFrames (ds: DataSet) =
@@ -76,7 +78,7 @@ let getTimeSpanSinceStart (ds: DataSet) n =
let days = ds["Itime"].GetData () :?> int[]
let msec = ds["Itime2"].GetData () :?> int[]
let t0 = TimeSpan.FromDays days[n]
let t1 = TimeSpan.FromMilliseconds msec[n]
let t1 = TimeSpan.FromMilliseconds (float msec[n])
t0 + t1 |> Some
with e ->
Log.Error $"getTimeInDays exception: {e.Message}"
@@ -526,7 +528,7 @@ module Singular =
Log.Error $"{err}"
0f, 0f
let readTemp (ds: DataSet) n t d =
let readTemp (ds: DataSet) n t d : single =
try
let t = ds["temp"].GetData ([| t; d; n |], [| 1; 1; 1 |]) :?> single[,,]
t[0, 0, 0]

View File

@@ -61,35 +61,35 @@ type NeighborIndex = {
} with
static member empty = { ElemsAroundNode = Map.empty; NodesAroundNode = Map.empty; ElemsAroundElem = Map.empty }
type private Ean = Map<NodeIdx, ElemIdx list>
// NOTE(SimenLK): The amount of items to be stored in the trees leafs
// let treeLeafSize = LeafNodeSize 64
let private createTree (points: Leaf<int> array) =
let tree = KdTree<float, int> (2, KdTree.Math.DoubleMath ())
points
|> Array.iter (fun a -> tree.Add ([| fst a.Pos; snd a.Pos |], a.Data) |> ignore)
do points |> Array.iter (fun a -> tree.Add ([| fst a.Pos; snd a.Pos |], a.Data) |> ignore)
if points.Length > 0 then
tree.Balance ()
do tree.Balance ()
else
Log.Warning $"Empty kd-tree"
do Log.Warning $"Empty kd-tree"
tree
type private Ean = Map<NodeIdx, ElemIdx array>
let private makeElemsSurroundingNodeMap (elem: Elem array) : ElemsAroundNode =
let addElIdx k v (nodes: Ean) =
Map.tryFind k nodes
|> Option.defaultWith (fun () -> [])
|> fun nds -> Map.add k (v :: nds) nodes
elem
|> Array.fold
(fun (n, acc) (a, b, c) ->
let acc' = acc |> addElIdx a n |> addElIdx b n |> addElIdx c n
n + 1, acc'
)
(0, Map.empty)
let addElIdx k v (nodes: Ean) : Ean =
let nds =
Map.tryFind k nodes
|> Option.defaultValue [||]
nodes |> Map.add k (Array.append [|v|] nds)
let folder (n, acc) (a, b, c) =
let acc' = acc |> addElIdx a n |> addElIdx b n |> addElIdx c n
n + 1, acc'
((0, Map.empty), elem)
||> Array.fold folder
|> snd
|> Map.mapValues toArray
let private makeElemsSurroundingNodeMap' (elem: Elem array) : ElemsAroundNode =
let addElemIdx k v nodes =
@@ -137,6 +137,7 @@ let getSurrounding (idx: Map<int, int[]>) (a, b, c) =
let makeNeighborIndex (grid: IGrid) =
let elem = grid.getCells ()
let ean = makeElemsSurroundingNodeMap elem
{
ElemsAroundNode = ean
NodesAroundNode = makeNodesSurroudingNodeMap ean elem

View File

@@ -21,9 +21,10 @@ let private calcInterpolationWeightedIdx (rn, fn) =
let nearestIdx = Array.map (fun fzi -> findNearestZ fzi rn) fn
nearestIdx
|> Array.mapi (fun i j ->
let last = Array.last rn
if fn[i] <= rn[0] then
(0, 0), (1.0, 0.0)
elif fn[i] >= rn[^0] then
elif fn[i] >= last then
(rn.Length - 1, 0), (1.0, 0.0)
elif abs (fn[i] - rn[j]) < 9.999999975e-07 then
(j, 0), (1.0, 0.0)

View File

@@ -1,18 +1,21 @@
module Oceanbox.FvcomKit.NorKyst
open System
open Thredds
let private getNorkystUrl (threddsUrl: string) (d: DateTime) =
let url = threddsUrl
let fmt (d: DateTime) =
$"{d.Year}%02d{d.Month}%02d{d.Day}T00Z.nc"
$"{url}/fou-hi/new_norkyst800m/his/ocean_his.an.{fmt d}"
let private getArchiveUrls urlf (t: DateTime) =
let t = t.ToUniversalTime ()
let now = DateTime.Now.ToUniversalTime ()
let dDay = (now.Date - t.Date).Days
if dDay < 0 then // no data available
[]
else
@@ -21,4 +24,4 @@ let private getArchiveUrls urlf (t: DateTime) =
let tryGetArchive (threddsUrl: string) (t: DateTime) =
getArchiveUrls (getNorkystUrl threddsUrl) t
|> tryOpenThredds
|> Option.bind (fun (_, ds) -> tryGetTimeIndex ds t |> Option.map (fun idx -> (ds, idx)))
|> Option.bind (fun (_, ds) -> tryGetTimeIndex ds t |> Option.map (fun idx -> ds, idx))

View File

@@ -10,12 +10,14 @@ let private getNorshelfUrl (threddsUrl: string) (kind: Kind) (mode: Mode) (date:
let fmt (d: DateTime) =
$"{d.Year}%02d{d.Month}%02d{d.Day}T00Z.nc"
let url = threddsUrl + "/sea_norshelf_files"
$"{url}/{date.Year}/%02d{date.Month}/norshelf_{kind}_{mode}_{fmt date}"
let private getArchiveUrls urlf (t: DateTime) =
let t = t.ToUniversalTime ()
let now = DateTime.Now.ToUniversalTime ()
let dDay = (now.Date - t.Date).Days
if dDay < -3 then // no data available
[]
elif dDay <= 0 then // forecast, count down from latest
@@ -27,6 +29,7 @@ let private getArchiveUrls urlf (t: DateTime) =
let tryGetArchive threddsUrl avg (t: DateTime) =
let kind = if avg then Avg else Qck
getArchiveUrls (getNorshelfUrl threddsUrl kind) t
|> tryOpenThredds
|> Option.bind (fun (fname, ds) -> tryGetTimeIndex ds t |> Option.map (fun idx -> (fname, ds, idx)))

View File

@@ -3,41 +3,47 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net9.0</TargetFramework>
<IsPackable>true</IsPackable>
<Company>Oceanbox AS</Company>
<Authors />
<PackageId>Oceanbox.FvcomKit</PackageId>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<Authors/>
<Company/>
<Version>5.13.0</Version>
<LangVersion>preview</LangVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Version>5.14.0</Version>
<RestorePackagesWithLockFile>false</RestorePackagesWithLockFile>
<IsPackable>true</IsPackable>
</PropertyGroup>
<ItemGroup>
<Compile Include="Types.fs"/>
<Compile Include="Grid.fs"/>
<Compile Include="Arome.fs"/>
<Compile Include="Fvcom.fs"/>
<Compile Include="Thredds.fs"/>
<Compile Include="Polygon.fs"/>
<Compile Include="Adjoin.fs"/>
<Compile Include="Interpol.fs"/>
<Compile Include="ROMS.fs"/>
<Compile Include="NorKyst.fs"/>
<Compile Include="NorShelf.fs"/>
<Compile Include="Smoothing.fs"/>
<Compile Include="Types.fs" />
<Compile Include="Grid.fs" />
<Compile Include="Arome.fs" />
<Compile Include="Fvcom.fs" />
<Compile Include="Thredds.fs" />
<Compile Include="Polygon.fs" />
<Compile Include="Adjoin.fs" />
<Compile Include="Interpol.fs" />
<Compile Include="ROMS.fs" />
<Compile Include="NorKyst.fs" />
<Compile Include="NorShelf.fs" />
<Compile Include="Smoothing.fs" />
<EmbeddedResource Include="version.json" />
<EmbeddedResource Include="SurfaceBaseline.txt"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="FSharp.Data" Version="6.4.1"/>
<PackageReference Include="FSharpPlus" Version="1.7.0"/>
<PackageReference Include="FsPickler" Version="5.3.2"/>
<PackageReference Include="KDTree" Version="1.4.1"/>
<PackageReference Include="MathNet.Numerics.FSharp" Version="5.0.0"/>
<PackageReference Include="MessagePack" Version="3.1.3"/>
<PackageReference Include="ProjNet.FSharp" Version="5.2.0"/>
<PackageReference Include="FSharp.Data" Version="6.4.1" />
<PackageReference Include="FSharpPlus" Version="1.7.0" />
<PackageReference Include="FsPickler" Version="5.3.2" />
<PackageReference Include="KDTree" Version="1.4.1" />
<PackageReference Include="MathNet.Numerics.FSharp" Version="5.0.0" />
<PackageReference Include="MessagePack" Version="3.1.3" />
<PackageReference Include="ProjNet.FSharp" Version="5.2.0" />
<PackageReference Include="Oceanbox.SDSLite" Version="2.8.0"/>
<PackageReference Include="Serilog" Version="4.2.0"/>
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0"/>
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0"/>
<PackageReference Include="Thoth.Json.Net" Version="12.0.0"/>
<PackageReference Update="FSharp.Core" Version="9.0.201"/>
<PackageReference Include="Serilog" Version="4.2.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.Seq" Version="9.0.0" />
<PackageReference Update="FSharp.Core" Version="9.0.303" />
</ItemGroup>
</Project>
<ItemGroup>
<PackageUpdate Include="ProjNet.FSharp" Version="*" Condition=" '$(ContinuousIntegrationBuild)'=='true' " />
<PackageUpdate Include="Oceanbox.SDSLite" Version="*" Condition=" '$(ContinuousIntegrationBuild)'=='true' " />
</ItemGroup>
</Project>

493
src/SurfaceBaseline.txt Normal file
View File

@@ -0,0 +1,493 @@
Oceanbox.FvcomKit.Adjoin inherit obj
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint inherit obj, implements Oceanbox.FvcomKit.Adjoin+FvcomAdjoint System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Adjoin+FvcomAdjoint System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint..ctor [constructor]: (int [], (int * int) [], int [])
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint.adjoinIdx [property]: [read-only] int []
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint.cullIdx [property]: [read-only] (int * int) []
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint.Equals [method]: (Oceanbox.FvcomKit.Adjoin+FvcomAdjoint, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint.get_adjoinIdx [method]: unit -> int []
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint.get_cullIdx [method]: unit -> (int * int) []
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint.get_oobIdx [method]: unit -> int []
Oceanbox.FvcomKit.Adjoin+FvcomAdjoint.oobIdx [property]: [read-only] int []
Oceanbox.FvcomKit.Adjoin.adjoinMatrix [static method]: Oceanbox.FvcomKit.Adjoin+FvcomAdjoint -> 'a [] -> 'a []
Oceanbox.FvcomKit.Adjoin.float2 [static method]: 'a -> 'b
Oceanbox.FvcomKit.Adjoin.float2$W [static method]: ('a -> ('c -> float) -> ('d -> float) -> FSharpPlus.Control.Bimap -> 'b, 'c -> float, 'd -> float, 'a) -> 'b
Oceanbox.FvcomKit.Adjoin.getCellBox [static method]: (float [], float []) -> ((int * int) * bool) [] -> ((float * float) [] * bool [])
Oceanbox.FvcomKit.Adjoin.getCellProps [static method]: float [] -> (int, int) -> (float * float * float * float)
Oceanbox.FvcomKit.Adjoin.getNearestCell [static method]: ProjNet.FSharp.Transform+IProj -> Oceanbox.FvcomKit.Grid+Grid -> ((float [] * float []), bool []) -> Oceanbox.FvcomKit.Adjoin+FvcomAdjoint
Oceanbox.FvcomKit.Adjoin.getNearestCellCorner [static method]: ((float [] * float []), bool []) -> (float * float) [] -> ((int * int) * bool) [] []
Oceanbox.FvcomKit.Adjoin.getNearestNode [static method]: ProjNet.FSharp.Transform+IProj -> Oceanbox.FvcomKit.Grid+Grid -> ((float [] * float []), bool []) -> Oceanbox.FvcomKit.Adjoin+FvcomAdjoint
Oceanbox.FvcomKit.Adjoin.getNearestUpperLeft' [static method]: KdTree.KdTree<float, (int * int)> -> ((float [] * float []), bool []) -> (float, float) -> ((int * int) * bool) []
Oceanbox.FvcomKit.Adjoin.makeNestTree [static method]: (float [], float []) -> KdTree.KdTree<float, (int * int)>
Oceanbox.FvcomKit.Arome inherit obj
Oceanbox.FvcomKit.Arome+AromeRect inherit System.ValueType, implements Oceanbox.FvcomKit.Arome+AromeRect System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Arome+AromeRect System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Arome+AromeRect..ctor [constructor]: (int, int, Oceanbox.FvcomKit.Arome+Rect)
Oceanbox.FvcomKit.Arome+AromeRect.Equals [method]: (Oceanbox.FvcomKit.Arome+AromeRect, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Arome+AromeRect.get_Rect [method]: unit -> Oceanbox.FvcomKit.Arome+Rect
Oceanbox.FvcomKit.Arome+AromeRect.get_XIdx [method]: unit -> int
Oceanbox.FvcomKit.Arome+AromeRect.get_YIdx [method]: unit -> int
Oceanbox.FvcomKit.Arome+AromeRect.Rect [property]: [read-only] Oceanbox.FvcomKit.Arome+Rect
Oceanbox.FvcomKit.Arome+AromeRect.XIdx [property]: [read-only] int
Oceanbox.FvcomKit.Arome+AromeRect.YIdx [property]: [read-only] int
Oceanbox.FvcomKit.Arome+Pointf inherit System.ValueType, implements Oceanbox.FvcomKit.Arome+Pointf System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Arome+Pointf System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Arome+Pointf..ctor [constructor]: (float, float)
Oceanbox.FvcomKit.Arome+Pointf.Equals [method]: (Oceanbox.FvcomKit.Arome+Pointf, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Arome+Pointf.get_x [method]: unit -> float
Oceanbox.FvcomKit.Arome+Pointf.get_y [method]: unit -> float
Oceanbox.FvcomKit.Arome+Pointf.get_Zero [static method]: unit -> Oceanbox.FvcomKit.Arome+Pointf
Oceanbox.FvcomKit.Arome+Pointf.OfStructTuple [static method]: struct (float * float) -> Oceanbox.FvcomKit.Arome+Pointf
Oceanbox.FvcomKit.Arome+Pointf.OfTuple [static method]: (float, float) -> Oceanbox.FvcomKit.Arome+Pointf
Oceanbox.FvcomKit.Arome+Pointf.x [property]: [read-only] float
Oceanbox.FvcomKit.Arome+Pointf.y [property]: [read-only] float
Oceanbox.FvcomKit.Arome+Pointf.Zero [static property]: [read-only] Oceanbox.FvcomKit.Arome+Pointf
Oceanbox.FvcomKit.Arome+PointfModule inherit obj
Oceanbox.FvcomKit.Arome+PointfModule.getBBox [static method]: Oceanbox.FvcomKit.Arome+Pointf [] -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Arome+PointfModule.ofPoints [static method]: Oceanbox.FvcomKit.Arome+Points -> Oceanbox.FvcomKit.Arome+Pointf
Oceanbox.FvcomKit.Arome+Points inherit System.ValueType, implements Oceanbox.FvcomKit.Arome+Points System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Arome+Points System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Arome+Points..ctor [constructor]: (single, single)
Oceanbox.FvcomKit.Arome+Points.Equals [method]: (Oceanbox.FvcomKit.Arome+Points, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Arome+Points.get_x [method]: unit -> single
Oceanbox.FvcomKit.Arome+Points.get_y [method]: unit -> single
Oceanbox.FvcomKit.Arome+Points.get_Zero [static method]: unit -> Oceanbox.FvcomKit.Arome+Points
Oceanbox.FvcomKit.Arome+Points.OfStructTuple [static method]: struct (single * single) -> Oceanbox.FvcomKit.Arome+Points
Oceanbox.FvcomKit.Arome+Points.OfTuple [static method]: (single, single) -> Oceanbox.FvcomKit.Arome+Points
Oceanbox.FvcomKit.Arome+Points.x [property]: [read-only] single
Oceanbox.FvcomKit.Arome+Points.y [property]: [read-only] single
Oceanbox.FvcomKit.Arome+Points.Zero [static property]: [read-only] Oceanbox.FvcomKit.Arome+Points
Oceanbox.FvcomKit.Arome+PointsModule inherit obj
Oceanbox.FvcomKit.Arome+PointsModule.getBBox [static method]: Oceanbox.FvcomKit.Arome+Points [] -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Arome+Rect inherit System.ValueType, implements Oceanbox.FvcomKit.Arome+Rect System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Arome+Rect System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Arome+Rect..ctor [constructor]: (Oceanbox.FvcomKit.Arome+Points, Oceanbox.FvcomKit.Arome+Points)
Oceanbox.FvcomKit.Arome+Rect.Equals [method]: (Oceanbox.FvcomKit.Arome+Rect, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Arome+Rect.get_max [method]: unit -> Oceanbox.FvcomKit.Arome+Points
Oceanbox.FvcomKit.Arome+Rect.get_min [method]: unit -> Oceanbox.FvcomKit.Arome+Points
Oceanbox.FvcomKit.Arome+Rect.max [property]: [read-only] Oceanbox.FvcomKit.Arome+Points
Oceanbox.FvcomKit.Arome+Rect.min [property]: [read-only] Oceanbox.FvcomKit.Arome+Points
Oceanbox.FvcomKit.Arome+Rect.OfPoints [static method]: Oceanbox.FvcomKit.Arome+Points -> Oceanbox.FvcomKit.Arome+Points -> Oceanbox.FvcomKit.Arome+Rect
Oceanbox.FvcomKit.Arome+RectModule inherit obj
Oceanbox.FvcomKit.Arome+RectModule.pointWithin [static method]: Oceanbox.FvcomKit.Arome+Rect -> Oceanbox.FvcomKit.Arome+Points -> bool
Oceanbox.FvcomKit.Arome+RectModule.tupleWithin [static method]: Oceanbox.FvcomKit.Arome+Rect -> (single, single) -> bool
Oceanbox.FvcomKit.Arome+SquareGrid inherit System.ValueType, implements Oceanbox.FvcomKit.Arome+SquareGrid System.IEquatable, System.Collections.IStructuralEquatable
Oceanbox.FvcomKit.Arome+SquareGrid..ctor [constructor]: ((int * int), Oceanbox.FvcomKit.Types+BBox, float, ProjNet.CoordinateSystems.CoordinateSystem, Oceanbox.FvcomKit.Arome+Points [])
Oceanbox.FvcomKit.Arome+SquareGrid.BBox [property]: [read-only] Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Arome+SquareGrid.dimensions [property]: [read-only] (int * int)
Oceanbox.FvcomKit.Arome+SquareGrid.empty [static property]: [read-only] Oceanbox.FvcomKit.Arome+SquareGrid
Oceanbox.FvcomKit.Arome+SquareGrid.Equals [method]: (Oceanbox.FvcomKit.Arome+SquareGrid, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Arome+SquareGrid.get_BBox [method]: unit -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Arome+SquareGrid.get_dimensions [method]: unit -> (int * int)
Oceanbox.FvcomKit.Arome+SquareGrid.get_empty [static method]: unit -> Oceanbox.FvcomKit.Arome+SquareGrid
Oceanbox.FvcomKit.Arome+SquareGrid.get_points [method]: unit -> Oceanbox.FvcomKit.Arome+Points []
Oceanbox.FvcomKit.Arome+SquareGrid.get_projection [method]: unit -> ProjNet.CoordinateSystems.CoordinateSystem
Oceanbox.FvcomKit.Arome+SquareGrid.get_squareSize [method]: unit -> float
Oceanbox.FvcomKit.Arome+SquareGrid.getBoundingBox [method]: unit -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Arome+SquareGrid.points [property]: [read-only] Oceanbox.FvcomKit.Arome+Points []
Oceanbox.FvcomKit.Arome+SquareGrid.projection [property]: [read-only] ProjNet.CoordinateSystems.CoordinateSystem
Oceanbox.FvcomKit.Arome+SquareGrid.squareSize [property]: [read-only] float
Oceanbox.FvcomKit.Arome.get_trans [static method]: unit -> ProjNet.FSharp.Transform+IProj
Oceanbox.FvcomKit.Arome.getBBox [static method]: float [] -> float [] -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Arome.getGrid [static method]: Microsoft.Research.Science.Data.DataSet -> Microsoft.FSharp.Core.FSharpResult<Oceanbox.FvcomKit.Arome+SquareGrid, string>
Oceanbox.FvcomKit.Arome.getSquareGrid [static method]: Microsoft.Research.Science.Data.DataSet -> Microsoft.FSharp.Core.FSharpResult<Oceanbox.FvcomKit.Arome+SquareGrid, string>
Oceanbox.FvcomKit.Arome.haversineDistance [static method]: float -> float -> float -> float -> float -> float
Oceanbox.FvcomKit.Arome.readUV [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int -> (single * single)
Oceanbox.FvcomKit.Arome.sfst [static method]: struct ('a * 'b) -> 'a
Oceanbox.FvcomKit.Arome.ssnd [static method]: struct ('a * 'b) -> 'b
Oceanbox.FvcomKit.Arome.trans [static property]: [read-only] ProjNet.FSharp.Transform+IProj
Oceanbox.FvcomKit.Arome.tryFind [static method]: Oceanbox.FvcomKit.Arome+SquareGrid -> (float, float) -> (int * int) option
Oceanbox.FvcomKit.Arome.tryFindIndex [static method]: Oceanbox.FvcomKit.Arome+SquareGrid -> (float, float) -> (int * int) option
Oceanbox.FvcomKit.Arome.tryFindWithProj [static method]: ProjNet.FSharp.Projections+Projection -> Oceanbox.FvcomKit.Arome+SquareGrid -> (float, float) -> (int * int) option
Oceanbox.FvcomKit.Arome.trySearchIndex [static method]: Oceanbox.FvcomKit.Arome+SquareGrid -> (single, single) -> (int * int) option
Oceanbox.FvcomKit.Fvcom inherit obj
Oceanbox.FvcomKit.Fvcom+FvcomGrid inherit obj, implements Oceanbox.FvcomKit.Fvcom+FvcomGrid System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Fvcom+FvcomGrid System.IComparable, System.IComparable, System.Collections.IStructuralComparable, Oceanbox.FvcomKit.Grid+IGrid
Oceanbox.FvcomKit.Fvcom+FvcomGrid..ctor [constructor]: ((int * int * int) [], (float * float) [], Oceanbox.FvcomKit.Types+BBox, (float * float) [], single [], single [], single [], single [])
Oceanbox.FvcomKit.Fvcom+FvcomGrid.Bathymetry [property]: [read-only] single []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.BBox [property]: [read-only] Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Fvcom+FvcomGrid.Cells [property]: [read-only] (float * float) []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.Elem [property]: [read-only] (int * int * int) []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.empty [static property]: [read-only] Oceanbox.FvcomKit.Fvcom+FvcomGrid
Oceanbox.FvcomKit.Fvcom+FvcomGrid.Equals [method]: (Oceanbox.FvcomKit.Fvcom+FvcomGrid, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_Bathymetry [method]: unit -> single []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_BBox [method]: unit -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_Cells [method]: unit -> (float * float) []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_Elem [method]: unit -> (int * int * int) []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_empty [static method]: unit -> Oceanbox.FvcomKit.Fvcom+FvcomGrid
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_Nodes [method]: unit -> (float * float) []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_Siglay [method]: unit -> single []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_SiglayCenter [method]: unit -> single []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.get_Siglev [method]: unit -> single []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.Nodes [property]: [read-only] (float * float) []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.Siglay [property]: [read-only] single []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.SiglayCenter [property]: [read-only] single []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.Siglev [property]: [read-only] single []
Oceanbox.FvcomKit.Fvcom+FvcomGrid.ToGrid [method]: unit -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Fvcom+Siglay inherit obj
Oceanbox.FvcomKit.Fvcom+Siglay.readSalinity [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom+Siglay.readSiglay [static method]: Microsoft.Research.Science.Data.DataSet -> single []
Oceanbox.FvcomKit.Fvcom+Siglay.readSiglayAtCenter [static method]: Microsoft.Research.Science.Data.DataSet -> single []
Oceanbox.FvcomKit.Fvcom+Siglay.readTemp [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom+Siglay.readUv [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> (single * single) []
Oceanbox.FvcomKit.Fvcom+Siglay.readUv' [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom+Siglay.readUvw [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> (single * single * single) []
Oceanbox.FvcomKit.Fvcom+Siglay.tryReadSiglay [static method]: Microsoft.Research.Science.Data.DataSet -> single [] option
Oceanbox.FvcomKit.Fvcom+Siglay.tryReadSiglayAtCenter [static method]: Microsoft.Research.Science.Data.DataSet -> single [] option
Oceanbox.FvcomKit.Fvcom+Singular inherit obj
Oceanbox.FvcomKit.Fvcom+Singular.readSalinity [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int -> single
Oceanbox.FvcomKit.Fvcom+Singular.readTemp [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int -> single
Oceanbox.FvcomKit.Fvcom+Singular.readUv [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int -> (single * single)
Oceanbox.FvcomKit.Fvcom+Singular.readZeta [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single
Oceanbox.FvcomKit.Fvcom.get_readSiglayCenter [static method]: unit -> (Microsoft.Research.Science.Data.DataSet -> int -> single [])
Oceanbox.FvcomKit.Fvcom.getBBox [static method]: Microsoft.Research.Science.Data.DataSet -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Fvcom.getGrid [static method]: Microsoft.Research.Science.Data.DataSet -> Oceanbox.FvcomKit.Fvcom+FvcomGrid
Oceanbox.FvcomKit.Fvcom.getGridLonLat [static method]: Microsoft.Research.Science.Data.DataSet -> Oceanbox.FvcomKit.Fvcom+FvcomGrid
Oceanbox.FvcomKit.Fvcom.getNbve [static method]: Microsoft.Research.Science.Data.DataSet -> int [] []
Oceanbox.FvcomKit.Fvcom.getNumFrames [static method]: Microsoft.Research.Science.Data.DataSet -> int
Oceanbox.FvcomKit.Fvcom.getNumSiglay [static method]: Microsoft.Research.Science.Data.DataSet -> int
Oceanbox.FvcomKit.Fvcom.getNumSiglev [static method]: Microsoft.Research.Science.Data.DataSet -> int
Oceanbox.FvcomKit.Fvcom.getTime [static method]: Microsoft.Research.Science.Data.DataSet -> int -> System.DateTime option
Oceanbox.FvcomKit.Fvcom.getTimeSpanSinceStart [static method]: Microsoft.Research.Science.Data.DataSet -> int -> System.TimeSpan option
Oceanbox.FvcomKit.Fvcom.projectFvcomGrid [static method]: ((float * float) -> (float * float)) -> Oceanbox.FvcomKit.Fvcom+FvcomGrid -> Oceanbox.FvcomKit.Fvcom+FvcomGrid
Oceanbox.FvcomKit.Fvcom.readArt1 [static method]: Microsoft.Research.Science.Data.DataSet -> single []
Oceanbox.FvcomKit.Fvcom.readBathymetry [static method]: Microsoft.Research.Science.Data.DataSet -> single []
Oceanbox.FvcomKit.Fvcom.readBathymetryAtCenter [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single
Oceanbox.FvcomKit.Fvcom.readBathymetryAtCenters [static method]: Microsoft.Research.Science.Data.DataSet -> single []
Oceanbox.FvcomKit.Fvcom.readOmega [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom.readOmegaBlock [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readOmegas [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int [] -> single []
Oceanbox.FvcomKit.Fvcom.readSalinity [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom.readSalinityBlock [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readSiglay [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readSiglayAtCenter [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readSiglayCenter [static property]: [read-only] Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readSiglev [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readSiglevAtCenter [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readTauc [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readTemp [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom.readTempBlock [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readU [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom.readUBlock [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readUV [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> (single * single) []
Oceanbox.FvcomKit.Fvcom.readUV' [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom.readUVRange [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int -> int -> (single * single) []
Oceanbox.FvcomKit.Fvcom.readUVs [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int [] -> (single * single) []
Oceanbox.FvcomKit.Fvcom.readUVW [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> (single * single * single) []
Oceanbox.FvcomKit.Fvcom.readUVWRange [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int -> int -> (single * single * single) []
Oceanbox.FvcomKit.Fvcom.readUVWs [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int [] -> (single * single * single) []
Oceanbox.FvcomKit.Fvcom.readV [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom.readVBlock [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readWw [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> single []
Oceanbox.FvcomKit.Fvcom.readWwBlock [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.readWws [static method]: Microsoft.Research.Science.Data.DataSet -> int -> int -> int [] -> single []
Oceanbox.FvcomKit.Fvcom.readZeta [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single []
Oceanbox.FvcomKit.Fvcom.tryReadBathymetry [static method]: Microsoft.Research.Science.Data.DataSet -> single [] option
Oceanbox.FvcomKit.Fvcom.tryReadSiglay [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single [] option
Oceanbox.FvcomKit.Fvcom.tryReadSiglayAtCenter [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single [] option
Oceanbox.FvcomKit.Fvcom.tryReadSiglev [static method]: Microsoft.Research.Science.Data.DataSet -> int -> single [] option
Oceanbox.FvcomKit.Grid inherit obj
Oceanbox.FvcomKit.Grid+BinGrid inherit obj, implements Oceanbox.FvcomKit.Grid+BinGrid System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Grid+BinGrid System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Grid+BinGrid..ctor [constructor]: (System.Byte [], (float * float) [], (int * int * int) [])
Oceanbox.FvcomKit.Grid+BinGrid.cells [property]: [read-only] (int * int * int) []
Oceanbox.FvcomKit.Grid+BinGrid.Equals [method]: (Oceanbox.FvcomKit.Grid+BinGrid, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Grid+BinGrid.get_cells [method]: unit -> (int * int * int) []
Oceanbox.FvcomKit.Grid+BinGrid.get_hash [method]: unit -> System.Byte []
Oceanbox.FvcomKit.Grid+BinGrid.get_vertices [method]: unit -> (float * float) []
Oceanbox.FvcomKit.Grid+BinGrid.hash [property]: [read-only] System.Byte []
Oceanbox.FvcomKit.Grid+BinGrid.toGrid [method]: unit -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Grid+BinGrid.vertices [property]: [read-only] (float * float) []
Oceanbox.FvcomKit.Grid+Boundary inherit obj
Oceanbox.FvcomKit.Grid+Boundary.getBoundaryNodesArray [static method]: Map<(int * int), int> -> int []
Oceanbox.FvcomKit.Grid+Boundary.makeBoundaryByEdgeMap [static method]: Oceanbox.FvcomKit.Grid+Grid -> Map<(int * int), int>
Oceanbox.FvcomKit.Grid+Boundary.makeBoundaryByElementMap [static method]: Map<(int * int), int> -> Map<int, (int * int)>
Oceanbox.FvcomKit.Grid+Boundary.makeBoundaryByNodeMap [static method]: Map<(int * int), int> -> Map<int, (int * int)>
Oceanbox.FvcomKit.Grid+Boundary.normalizeElement [static method]: ('a, 'a, 'a) -> ('a * 'a) []
Oceanbox.FvcomKit.Grid+ExtendedGrid inherit obj, implements Oceanbox.FvcomKit.Grid+IGrid
Oceanbox.FvcomKit.Grid+ExtendedGrid..ctor [constructor]: Oceanbox.FvcomKit.Grid+IGrid
Oceanbox.FvcomKit.Grid+ExtendedGrid.calcCircumCircle [method]: int -> (float * float * float)
Oceanbox.FvcomKit.Grid+ExtendedGrid.ElementTree [property]: [read-only] KdTree.KdTree<float, int> option
Oceanbox.FvcomKit.Grid+ExtendedGrid.get_ElementTree [method]: unit -> KdTree.KdTree<float, int> option
Oceanbox.FvcomKit.Grid+ExtendedGrid.get_Grid [method]: unit -> Oceanbox.FvcomKit.Grid+IGrid
Oceanbox.FvcomKit.Grid+ExtendedGrid.get_NeighborIndex [method]: unit -> Oceanbox.FvcomKit.Grid+NeighborIndex option
Oceanbox.FvcomKit.Grid+ExtendedGrid.get_NodeTree [method]: unit -> KdTree.KdTree<float, int> option
Oceanbox.FvcomKit.Grid+ExtendedGrid.getCentroids [method]: unit -> (float * float) []
Oceanbox.FvcomKit.Grid+ExtendedGrid.getElemsSurroundingElem [method]: int -> int []
Oceanbox.FvcomKit.Grid+ExtendedGrid.getElemsSurroundingNode [method]: int -> int []
Oceanbox.FvcomKit.Grid+ExtendedGrid.getHash [method]: unit -> System.Byte []
Oceanbox.FvcomKit.Grid+ExtendedGrid.getHashString [method]: unit -> string
Oceanbox.FvcomKit.Grid+ExtendedGrid.getNodesSurroundingElem [method]: int -> int []
Oceanbox.FvcomKit.Grid+ExtendedGrid.getNodesSurroundingNode [method]: int -> int []
Oceanbox.FvcomKit.Grid+ExtendedGrid.Grid [property]: [read-only] Oceanbox.FvcomKit.Grid+IGrid
Oceanbox.FvcomKit.Grid+ExtendedGrid.initElementTree [method]: unit -> unit
Oceanbox.FvcomKit.Grid+ExtendedGrid.initHash [method]: System.Byte [] -> unit
Oceanbox.FvcomKit.Grid+ExtendedGrid.initNeighborIndex [method]: string option -> unit
Oceanbox.FvcomKit.Grid+ExtendedGrid.initNodeTree [method]: unit -> unit
Oceanbox.FvcomKit.Grid+ExtendedGrid.loadElementTree [method]: string -> bool
Oceanbox.FvcomKit.Grid+ExtendedGrid.loadNeighborIndex [method]: string -> bool
Oceanbox.FvcomKit.Grid+ExtendedGrid.loadNodeTree [method]: string -> bool
Oceanbox.FvcomKit.Grid+ExtendedGrid.nearestNode [method]: (float, float) -> int option
Oceanbox.FvcomKit.Grid+ExtendedGrid.NeighborIndex [property]: [read-only] Oceanbox.FvcomKit.Grid+NeighborIndex option
Oceanbox.FvcomKit.Grid+ExtendedGrid.NodeTree [property]: [read-only] KdTree.KdTree<float, int> option
Oceanbox.FvcomKit.Grid+ExtendedGrid.saveElementTree [method]: string -> unit
Oceanbox.FvcomKit.Grid+ExtendedGrid.saveNeighborIndex [method]: string -> unit
Oceanbox.FvcomKit.Grid+ExtendedGrid.saveNodeTree [method]: string -> unit
Oceanbox.FvcomKit.Grid+ExtendedGrid.ToGrid [method]: unit -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Grid+ExtendedGrid.tryGetElement [method]: (float * float) -> int option
Oceanbox.FvcomKit.Grid+ExtendedGrid.tryGetElementSloppy [method]: (float * float) -> int option
Oceanbox.FvcomKit.Grid+ExtendedGrid.tryGetNode [method]: (float * float) -> int option
Oceanbox.FvcomKit.Grid+Grid inherit obj, implements Oceanbox.FvcomKit.Grid+Grid System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Grid+Grid System.IComparable, System.IComparable, System.Collections.IStructuralComparable, Oceanbox.FvcomKit.Grid+IGrid
Oceanbox.FvcomKit.Grid+Grid..ctor [constructor]: ((int * int * int) [], (float * float) [], Oceanbox.FvcomKit.Types+BBox)
Oceanbox.FvcomKit.Grid+Grid.BBox [property]: [read-only] Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Grid+Grid.Elem [property]: [read-only] (int * int * int) []
Oceanbox.FvcomKit.Grid+Grid.empty [static property]: [read-only] Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Grid+Grid.Equals [method]: (Oceanbox.FvcomKit.Grid+Grid, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Grid+Grid.get_BBox [method]: unit -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Grid+Grid.get_Elem [method]: unit -> (int * int * int) []
Oceanbox.FvcomKit.Grid+Grid.get_empty [static method]: unit -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Grid+Grid.get_Nodes [method]: unit -> (float * float) []
Oceanbox.FvcomKit.Grid+Grid.Nodes [property]: [read-only] (float * float) []
Oceanbox.FvcomKit.Grid+IGrid - interface with 6 member(s)
Oceanbox.FvcomKit.Grid+IGrid.getBoundingBox [method]: unit -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Grid+IGrid.getCell [method]: int -> (int * int * int)
Oceanbox.FvcomKit.Grid+IGrid.getCells [method]: unit -> (int * int * int) []
Oceanbox.FvcomKit.Grid+IGrid.getCellVertices [method]: int -> ((float * float) * (float * float) * (float * float))
Oceanbox.FvcomKit.Grid+IGrid.getVertex [method]: int -> (float * float)
Oceanbox.FvcomKit.Grid+IGrid.getVertices [method]: unit -> (float * float) []
Oceanbox.FvcomKit.Grid+Leaf`1 inherit obj, implements 'a Oceanbox.FvcomKit.Grid+Leaf System.IEquatable, System.Collections.IStructuralEquatable, 'a Oceanbox.FvcomKit.Grid+Leaf System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Grid+Leaf`1..ctor [constructor]: ((float * float), 'a)
Oceanbox.FvcomKit.Grid+Leaf`1.Data [property]: [read-only] 'a
Oceanbox.FvcomKit.Grid+Leaf`1.Equals [method]: ('a Oceanbox.FvcomKit.Grid+Leaf, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Grid+Leaf`1.get_Data [method]: unit -> 'a
Oceanbox.FvcomKit.Grid+Leaf`1.get_Pos [method]: unit -> (float * float)
Oceanbox.FvcomKit.Grid+Leaf`1.Pos [property]: [read-only] (float * float)
Oceanbox.FvcomKit.Grid+NeighborIndex inherit obj, implements Oceanbox.FvcomKit.Grid+NeighborIndex System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Grid+NeighborIndex System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Grid+NeighborIndex..ctor [constructor]: (Map<int, int []>, Map<int, int []>, Map<int, int []>)
Oceanbox.FvcomKit.Grid+NeighborIndex.ElemsAroundElem [property]: [read-only] Map<int, int []>
Oceanbox.FvcomKit.Grid+NeighborIndex.ElemsAroundNode [property]: [read-only] Map<int, int []>
Oceanbox.FvcomKit.Grid+NeighborIndex.empty [static property]: [read-only] Oceanbox.FvcomKit.Grid+NeighborIndex
Oceanbox.FvcomKit.Grid+NeighborIndex.Equals [method]: (Oceanbox.FvcomKit.Grid+NeighborIndex, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Grid+NeighborIndex.get_ElemsAroundElem [method]: unit -> Map<int, int []>
Oceanbox.FvcomKit.Grid+NeighborIndex.get_ElemsAroundNode [method]: unit -> Map<int, int []>
Oceanbox.FvcomKit.Grid+NeighborIndex.get_empty [static method]: unit -> Oceanbox.FvcomKit.Grid+NeighborIndex
Oceanbox.FvcomKit.Grid+NeighborIndex.get_NodesAroundNode [method]: unit -> Map<int, int []>
Oceanbox.FvcomKit.Grid+NeighborIndex.NodesAroundNode [property]: [read-only] Map<int, int []>
Oceanbox.FvcomKit.Grid+Util inherit obj
Oceanbox.FvcomKit.Grid+Util+Element inherit obj
Oceanbox.FvcomKit.Grid+Util+Element.calcArea [static method]: ((float * float), (float * float), (float * float)) -> float
Oceanbox.FvcomKit.Grid+Util+Element.calcCentroid [static method]: ((float * float), (float * float), (float * float)) -> (float * float)
Oceanbox.FvcomKit.Grid+Util+Element.calcCentroid [static method]: ((single * single), (single * single), (single * single)) -> (single * single)
Oceanbox.FvcomKit.Grid+Util+Element.calcCircumscribedCircle [static method]: ((float * float), (float * float), (float * float)) -> (float * float * float)
Oceanbox.FvcomKit.Grid+Util+Element.propToNodal [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> float [] -> float []
Oceanbox.FvcomKit.Grid+Util+Element.speedToNodal [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> (float * float) [] -> float []
Oceanbox.FvcomKit.Grid+Util+Element.velocityToNodal [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> (float * float) [] -> (float * float) []
Oceanbox.FvcomKit.Grid+Util+Node inherit obj
Oceanbox.FvcomKit.Grid+Util+Node.calcNodeArea [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+IGrid -> float []
Oceanbox.FvcomKit.Grid+Util+Node.calcNodeControlArea [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+IGrid -> float []
Oceanbox.FvcomKit.Grid+Util.buildNearestElementTree [static method]: Oceanbox.FvcomKit.Grid+IGrid -> KdTree.KdTree<float, int>
Oceanbox.FvcomKit.Grid+Util.buildNearestNodeTree [static method]: Oceanbox.FvcomKit.Grid+IGrid -> KdTree.KdTree<float, int>
Oceanbox.FvcomKit.Grid+Util.calcCentroids [static method]: Oceanbox.FvcomKit.Grid+IGrid -> (float * float) []
Oceanbox.FvcomKit.Grid+Util.isInsideTriangle [static method]: (('a * 'e), ('a * 'e), ('a * 'e)) -> ('b, 'f) -> bool
Oceanbox.FvcomKit.Grid+Util.isInsideTriangle$W [static method]: ('c -> 'd -> 'j, 'h -> 'g -> 'i, 'b -> 'a -> 'c) -> ('a -> 'a -> 'h, 'e -> 'e -> 'd) -> bool
Oceanbox.FvcomKit.Grid+Util.tryFindElement [static method]: Oceanbox.FvcomKit.Grid+IGrid -> KdTree.KdTree<float, int> -> (float, float) -> int option
Oceanbox.FvcomKit.Grid.bboxToLngLat [static method]: ProjNet.CoordinateSystems.CoordinateSystem -> Oceanbox.FvcomKit.Types+BBox -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Grid.calcBBox [static method]: (float * float) [] -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Grid.calcBBoxCenter [static method]: Oceanbox.FvcomKit.Types+BBox -> (float * float)
Oceanbox.FvcomKit.Grid.getElemsSurroundingElem [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+Grid -> int -> int []
Oceanbox.FvcomKit.Grid.getElemsSurroundingNode [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> int -> int []
Oceanbox.FvcomKit.Grid.getNodesSurroundingElem [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> int -> int []
Oceanbox.FvcomKit.Grid.getNodesSurroundingNode [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> int -> int []
Oceanbox.FvcomKit.Grid.getSurrounding [static method]: Map<int, int []> -> (int, int, int) -> int []
Oceanbox.FvcomKit.Grid.makeNeighborIndex [static method]: Oceanbox.FvcomKit.Grid+IGrid -> Oceanbox.FvcomKit.Grid+NeighborIndex
Oceanbox.FvcomKit.Grid.printBBox [static method]: Oceanbox.FvcomKit.Grid+Grid -> unit
Oceanbox.FvcomKit.Grid.projectBBox [static method]: ((float * float) -> (float * float)) -> Oceanbox.FvcomKit.Types+BBox -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Grid.projectGrid [static method]: ((float * float) -> (float * float)) -> Oceanbox.FvcomKit.Grid+Grid -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Grid.readGrdFile [static method]: string -> Oceanbox.FvcomKit.Grid+Grid option
Oceanbox.FvcomKit.Grid.readObcFile [static method]: string -> int [] option
Oceanbox.FvcomKit.Grid.rescaleGrid [static method]: float -> Oceanbox.FvcomKit.Grid+Grid -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Grid.toLonLat [static method]: ProjNet.CoordinateSystems.CoordinateSystem -> Oceanbox.FvcomKit.Grid+Grid -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Grid.toWebMercator [static method]: ProjNet.CoordinateSystems.CoordinateSystem -> Oceanbox.FvcomKit.Grid+Grid -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Grid.translateGrid [static method]: (float, float) -> Oceanbox.FvcomKit.Grid+Grid -> Oceanbox.FvcomKit.Grid+Grid
Oceanbox.FvcomKit.Interpol inherit obj
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs inherit obj, implements Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs..ctor [constructor]: (((int * int) * (float * float)) [] [], ((int * int) * (float * float)) [] [], ((int * int) * (float * float)) [] [])
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs.Equals [method]: (Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs.get_iRho [method]: unit -> ((int * int) * (float * float)) [] []
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs.get_iU [method]: unit -> ((int * int) * (float * float)) [] []
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs.get_iV [method]: unit -> ((int * int) * (float * float)) [] []
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs.iRho [property]: [read-only] ((int * int) * (float * float)) [] []
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs.iU [property]: [read-only] ((int * int) * (float * float)) [] []
Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs.iV [property]: [read-only] ((int * int) * (float * float)) [] []
Oceanbox.FvcomKit.Interpol.genBilinearInterpolationWgts [static method]: (float, float) -> ((float * float), (float * float), (float * float), (float * float)) -> (bool, bool, bool, bool) -> (float * float * float * float) option
Oceanbox.FvcomKit.Interpol.hInterpolNearestProp [static method]: float [] [] -> float [] []
Oceanbox.FvcomKit.Interpol.interpCoefs [static method]: ((float [] * float []), bool []) -> (float * float) [] -> ((int * int) [] [] * (float * float * float * float) option [])
Oceanbox.FvcomKit.Interpol.interpolateCells [static method]: (float * float * float * float) option [] -> (float * float * float * float) [] -> float option []
Oceanbox.FvcomKit.Interpol.interpolateProp [static method]: ((float [] * float []), bool []) -> (float * float) [] -> float [] -> Oceanbox.FvcomKit.Grid+Grid -> bool -> float []
Oceanbox.FvcomKit.Interpol.interpProp [static method]: (int * int) [] [] -> (float * float * float * float) option [] -> float [] -> Oceanbox.FvcomKit.Grid+Grid -> bool -> float []
Oceanbox.FvcomKit.Interpol.makeBiWeights [static method]: (float * float) [] -> ((float * float) * (float * float) * (float * float) * (float * float)) [] -> (bool * bool * bool * bool) [] -> (float * float * float * float) option []
Oceanbox.FvcomKit.Interpol.mkDepthInterpolCoefs [static method]: single [] -> float [] -> float [] [] -> ((int * int) * (float * float)) [] []
Oceanbox.FvcomKit.Interpol.zInterpolProp [static method]: ((int * int) * (float * float)) [] [] -> float [] [] -> float []
Oceanbox.FvcomKit.NorKyst inherit obj
Oceanbox.FvcomKit.NorKyst.tryGetArchive [static method]: string -> System.DateTime -> (Microsoft.Research.Science.Data.DataSet * int) option
Oceanbox.FvcomKit.NorShelf inherit obj
Oceanbox.FvcomKit.NorShelf.readArchive [static method]: string -> (Microsoft.Research.Science.Data.DataSet -> 'a) -> 'a option
Oceanbox.FvcomKit.NorShelf.readRomsGrid [static method]: string -> Oceanbox.FvcomKit.ROMS+RomsGrid option
Oceanbox.FvcomKit.NorShelf.readRomsProps [static method]: string -> int -> Oceanbox.FvcomKit.ROMS+RomsProps option
Oceanbox.FvcomKit.NorShelf.tryGetArchive [static method]: string -> bool -> System.DateTime -> (string * Microsoft.Research.Science.Data.DataSet * int) option
Oceanbox.FvcomKit.ROMS inherit obj
Oceanbox.FvcomKit.ROMS+AdjoinedGrid inherit obj, implements Oceanbox.FvcomKit.ROMS+AdjoinedGrid System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.ROMS+AdjoinedGrid System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.ROMS+AdjoinedGrid..ctor [constructor]: (float [], float [] [], float [] [], float [] [], float [], float [], float [])
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.angle [property]: [read-only] float []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.Equals [method]: (Oceanbox.FvcomKit.ROMS+AdjoinedGrid, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.get_angle [method]: unit -> float []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.get_h [method]: unit -> float []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.get_u [method]: unit -> float []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.get_v [method]: unit -> float []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.get_zRho [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.get_zU [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.get_zV [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.h [property]: [read-only] float []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.u [property]: [read-only] float []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.v [property]: [read-only] float []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.zRho [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.zU [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedGrid.zV [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp inherit obj, implements Oceanbox.FvcomKit.ROMS+AdjoinedProp System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.ROMS+AdjoinedProp System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.ROMS+AdjoinedProp..ctor [constructor]: (float [] [], float [] [], float [], float [] [], float [] [])
Oceanbox.FvcomKit.ROMS+AdjoinedProp.Equals [method]: (Oceanbox.FvcomKit.ROMS+AdjoinedProp, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.ROMS+AdjoinedProp.get_salt [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.get_temp [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.get_u [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.get_v [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.get_zeta [method]: unit -> float []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.salt [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.temp [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.u [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.v [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+AdjoinedProp.zeta [property]: [read-only] float []
Oceanbox.FvcomKit.ROMS+GridData`1 inherit obj, implements 'a Oceanbox.FvcomKit.ROMS+GridData System.IEquatable, System.Collections.IStructuralEquatable, 'a Oceanbox.FvcomKit.ROMS+GridData System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.ROMS+GridData`1..ctor [constructor]: ('a, 'a, 'a)
Oceanbox.FvcomKit.ROMS+GridData`1.Equals [method]: ('a Oceanbox.FvcomKit.ROMS+GridData, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.ROMS+GridData`1.get_rho [method]: unit -> 'a
Oceanbox.FvcomKit.ROMS+GridData`1.get_u [method]: unit -> 'a
Oceanbox.FvcomKit.ROMS+GridData`1.get_v [method]: unit -> 'a
Oceanbox.FvcomKit.ROMS+GridData`1.rho [property]: [read-only] 'a
Oceanbox.FvcomKit.ROMS+GridData`1.u [property]: [read-only] 'a
Oceanbox.FvcomKit.ROMS+GridData`1.v [property]: [read-only] 'a
Oceanbox.FvcomKit.ROMS+IRomsToFvcom - interface with 11 member(s)
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.get_rhoAdjoint [method]: unit -> Oceanbox.FvcomKit.Adjoin+FvcomAdjoint
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.get_uAdjoint [method]: unit -> Oceanbox.FvcomKit.Adjoin+FvcomAdjoint
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.get_uv [method]: unit -> bool
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.get_vAdjoint [method]: unit -> Oceanbox.FvcomKit.Adjoin+FvcomAdjoint
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.rhoAdjoint [property]: [read-only] Oceanbox.FvcomKit.Adjoin+FvcomAdjoint
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.rhoToFvcom [method]: 'a [] -> 'a []
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.uAdjoint [property]: [read-only] Oceanbox.FvcomKit.Adjoin+FvcomAdjoint
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.uToFvcom [method]: 'a [] -> 'a []
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.uv [property]: [read-only] bool
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.vAdjoint [property]: [read-only] Oceanbox.FvcomKit.Adjoin+FvcomAdjoint
Oceanbox.FvcomKit.ROMS+IRomsToFvcom.vToFvcom [method]: 'a [] -> 'a []
Oceanbox.FvcomKit.ROMS+RomsGrid inherit obj, implements Oceanbox.FvcomKit.ROMS+RomsGrid System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.ROMS+RomsGrid System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.ROMS+RomsGrid..ctor [constructor]: (float [] Oceanbox.FvcomKit.ROMS+GridData, float [] Oceanbox.FvcomKit.ROMS+GridData [], (float [] * float []) Oceanbox.FvcomKit.ROMS+GridData, bool [] Oceanbox.FvcomKit.ROMS+GridData, float [])
Oceanbox.FvcomKit.ROMS+RomsGrid.angle [property]: [read-only] float []
Oceanbox.FvcomKit.ROMS+RomsGrid.Equals [method]: (Oceanbox.FvcomKit.ROMS+RomsGrid, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.ROMS+RomsGrid.get_angle [method]: unit -> float []
Oceanbox.FvcomKit.ROMS+RomsGrid.get_h [method]: unit -> float [] Oceanbox.FvcomKit.ROMS+GridData
Oceanbox.FvcomKit.ROMS+RomsGrid.get_pos [method]: unit -> (float [] * float []) Oceanbox.FvcomKit.ROMS+GridData
Oceanbox.FvcomKit.ROMS+RomsGrid.get_wetMask [method]: unit -> bool [] Oceanbox.FvcomKit.ROMS+GridData
Oceanbox.FvcomKit.ROMS+RomsGrid.get_z [method]: unit -> float [] Oceanbox.FvcomKit.ROMS+GridData []
Oceanbox.FvcomKit.ROMS+RomsGrid.h [property]: [read-only] float [] Oceanbox.FvcomKit.ROMS+GridData
Oceanbox.FvcomKit.ROMS+RomsGrid.pos [property]: [read-only] (float [] * float []) Oceanbox.FvcomKit.ROMS+GridData
Oceanbox.FvcomKit.ROMS+RomsGrid.wetMask [property]: [read-only] bool [] Oceanbox.FvcomKit.ROMS+GridData
Oceanbox.FvcomKit.ROMS+RomsGrid.z [property]: [read-only] float [] Oceanbox.FvcomKit.ROMS+GridData []
Oceanbox.FvcomKit.ROMS+RomsProps inherit obj, implements Oceanbox.FvcomKit.ROMS+RomsProps System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.ROMS+RomsProps System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.ROMS+RomsProps..ctor [constructor]: (float [] [], float [] [], float [], float [] [], float [] [])
Oceanbox.FvcomKit.ROMS+RomsProps.Equals [method]: (Oceanbox.FvcomKit.ROMS+RomsProps, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.ROMS+RomsProps.get_salt [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+RomsProps.get_temp [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+RomsProps.get_u [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+RomsProps.get_v [method]: unit -> float [] []
Oceanbox.FvcomKit.ROMS+RomsProps.get_zeta [method]: unit -> float []
Oceanbox.FvcomKit.ROMS+RomsProps.salt [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+RomsProps.temp [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+RomsProps.u [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+RomsProps.v [property]: [read-only] float [] []
Oceanbox.FvcomKit.ROMS+RomsProps.zeta [property]: [read-only] float []
Oceanbox.FvcomKit.ROMS.adjoinGirds [static method]: Oceanbox.FvcomKit.ROMS+IRomsToFvcom -> Oceanbox.FvcomKit.ROMS+RomsGrid -> Oceanbox.FvcomKit.ROMS+AdjoinedGrid
Oceanbox.FvcomKit.ROMS.adjoinProps [static method]: Oceanbox.FvcomKit.ROMS+IRomsToFvcom -> Oceanbox.FvcomKit.ROMS+RomsProps -> Oceanbox.FvcomKit.ROMS+AdjoinedProp
Oceanbox.FvcomKit.ROMS.adjoinRomsToFvcom [static method]: ProjNet.FSharp.Transform+IProj -> Oceanbox.FvcomKit.Grid+Grid -> Oceanbox.FvcomKit.ROMS+RomsGrid -> Oceanbox.FvcomKit.ROMS+RomsProps -> (Oceanbox.FvcomKit.ROMS+AdjoinedGrid * Oceanbox.FvcomKit.ROMS+AdjoinedProp)
Oceanbox.FvcomKit.ROMS.calcUVBar [static method]: Oceanbox.FvcomKit.Fvcom+FvcomGrid -> (float [] [], float [] []) -> (float MathNet.Numerics.LinearAlgebra.Vector * float MathNet.Numerics.LinearAlgebra.Vector)
Oceanbox.FvcomKit.ROMS.computeAngles [static method]: Oceanbox.FvcomKit.Fvcom+FvcomGrid -> Oceanbox.FvcomKit.ROMS+AdjoinedGrid -> float []
Oceanbox.FvcomKit.ROMS.genRomsToFvcomAdjoints [static method]: ProjNet.FSharp.Transform+IProj -> Oceanbox.FvcomKit.Grid+Grid -> Oceanbox.FvcomKit.ROMS+RomsGrid -> Oceanbox.FvcomKit.ROMS+IRomsToFvcom
Oceanbox.FvcomKit.ROMS.mkAllDepthInterpolCoefs [static method]: Oceanbox.FvcomKit.Fvcom+FvcomGrid -> Oceanbox.FvcomKit.ROMS+AdjoinedGrid -> Oceanbox.FvcomKit.Interpol+DepthInterpolCoefs
Oceanbox.FvcomKit.ROMS.readGrid [static method]: Microsoft.Research.Science.Data.DataSet -> Oceanbox.FvcomKit.ROMS+RomsGrid
Oceanbox.FvcomKit.ROMS.readProps [static method]: Microsoft.Research.Science.Data.DataSet -> int -> Oceanbox.FvcomKit.ROMS+RomsProps
Oceanbox.FvcomKit.ROMS.readVerticalGrid [static method]: string -> float []
Oceanbox.FvcomKit.ROMS.readWetMask [static method]: Microsoft.Research.Science.Data.DataSet -> bool [] Oceanbox.FvcomKit.ROMS+GridData
Oceanbox.FvcomKit.Smoothing inherit obj
Oceanbox.FvcomKit.Smoothing.rectifyOutOfBoundsElements [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+Grid -> int [] -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.rectifyOutOfBoundsElements2D [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+Grid -> int [] -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.rectifyOutOfBoundsElements3D [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+Grid -> int [] -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.rectifyOutOfBoundsNodes [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> int [] -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.rectifyOutOfBoundsNodes2D [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> int [] -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.rectifyOutOfBoundsNodes3D [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> int [] -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.smooth [static method]: single [] -> int [] -> single
Oceanbox.FvcomKit.Smoothing.smooth' [static method]: single [] -> int [] -> single
Oceanbox.FvcomKit.Smoothing.smoothElements [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+Grid -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.smoothElements2D [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+Grid -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.smoothElements3D [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> Oceanbox.FvcomKit.Grid+Grid -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.smoothNodes [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.smoothNodes2D [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> single [] -> single []
Oceanbox.FvcomKit.Smoothing.smoothNodes3D [static method]: Oceanbox.FvcomKit.Grid+NeighborIndex -> single [] -> single []
Oceanbox.FvcomKit.Thredds inherit obj
Oceanbox.FvcomKit.Thredds+Kind inherit obj, implements Oceanbox.FvcomKit.Thredds+Kind System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Thredds+Kind System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
Oceanbox.FvcomKit.Thredds+Kind+Tags inherit obj
Oceanbox.FvcomKit.Thredds+Kind+Tags.Avg [static field]: int = 0
Oceanbox.FvcomKit.Thredds+Kind+Tags.Qck [static field]: int = 1
Oceanbox.FvcomKit.Thredds+Kind.Avg [static property]: [read-only] Oceanbox.FvcomKit.Thredds+Kind
Oceanbox.FvcomKit.Thredds+Kind.Equals [method]: (Oceanbox.FvcomKit.Thredds+Kind, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Thredds+Kind.get_Avg [static method]: unit -> Oceanbox.FvcomKit.Thredds+Kind
Oceanbox.FvcomKit.Thredds+Kind.get_IsAvg [method]: unit -> bool
Oceanbox.FvcomKit.Thredds+Kind.get_IsQck [method]: unit -> bool
Oceanbox.FvcomKit.Thredds+Kind.get_Qck [static method]: unit -> Oceanbox.FvcomKit.Thredds+Kind
Oceanbox.FvcomKit.Thredds+Kind.get_Tag [method]: unit -> int
Oceanbox.FvcomKit.Thredds+Kind.IsAvg [property]: [read-only] bool
Oceanbox.FvcomKit.Thredds+Kind.IsQck [property]: [read-only] bool
Oceanbox.FvcomKit.Thredds+Kind.Qck [static property]: [read-only] Oceanbox.FvcomKit.Thredds+Kind
Oceanbox.FvcomKit.Thredds+Kind.Tag [property]: [read-only] int
Oceanbox.FvcomKit.Thredds+Mode inherit obj, implements Oceanbox.FvcomKit.Thredds+Mode System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Thredds+Mode System.IComparable, System.IComparable, System.Collections.IStructuralComparable - union type with 2 cases
Oceanbox.FvcomKit.Thredds+Mode+Tags inherit obj
Oceanbox.FvcomKit.Thredds+Mode+Tags.Analyzed [static field]: int = 0
Oceanbox.FvcomKit.Thredds+Mode+Tags.Forecast [static field]: int = 1
Oceanbox.FvcomKit.Thredds+Mode.Analyzed [static property]: [read-only] Oceanbox.FvcomKit.Thredds+Mode
Oceanbox.FvcomKit.Thredds+Mode.Equals [method]: (Oceanbox.FvcomKit.Thredds+Mode, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Thredds+Mode.Forecast [static property]: [read-only] Oceanbox.FvcomKit.Thredds+Mode
Oceanbox.FvcomKit.Thredds+Mode.get_Analyzed [static method]: unit -> Oceanbox.FvcomKit.Thredds+Mode
Oceanbox.FvcomKit.Thredds+Mode.get_Forecast [static method]: unit -> Oceanbox.FvcomKit.Thredds+Mode
Oceanbox.FvcomKit.Thredds+Mode.get_IsAnalyzed [method]: unit -> bool
Oceanbox.FvcomKit.Thredds+Mode.get_IsForecast [method]: unit -> bool
Oceanbox.FvcomKit.Thredds+Mode.get_Tag [method]: unit -> int
Oceanbox.FvcomKit.Thredds+Mode.IsAnalyzed [property]: [read-only] bool
Oceanbox.FvcomKit.Thredds+Mode.IsForecast [property]: [read-only] bool
Oceanbox.FvcomKit.Thredds+Mode.Tag [property]: [read-only] int
Oceanbox.FvcomKit.Thredds.dateRange [static method]: System.DateTime -> int -> System.DateTime list
Oceanbox.FvcomKit.Thredds.tryGetTimeIndex [static method]: Microsoft.Research.Science.Data.DataSet -> System.DateTime -> int option
Oceanbox.FvcomKit.Thredds.tryOpenArchive [static method]: string -> Microsoft.Research.Science.Data.DataSet option
Oceanbox.FvcomKit.Thredds.tryOpenThredds [static method]: string list -> (string * Microsoft.Research.Science.Data.DataSet) option
Oceanbox.FvcomKit.Types inherit obj
Oceanbox.FvcomKit.Types+BBox inherit System.ValueType, implements Oceanbox.FvcomKit.Types+BBox System.IEquatable, System.Collections.IStructuralEquatable, Oceanbox.FvcomKit.Types+BBox System.IComparable, System.IComparable, System.Collections.IStructuralComparable
Oceanbox.FvcomKit.Types+BBox..ctor [constructor]: (float, float, float, float, (float * float))
Oceanbox.FvcomKit.Types+BBox.center [property]: [read-only] (float * float)
Oceanbox.FvcomKit.Types+BBox.empty [static property]: [read-only] Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Types+BBox.Equals [method]: (Oceanbox.FvcomKit.Types+BBox, System.Collections.IEqualityComparer) -> bool
Oceanbox.FvcomKit.Types+BBox.get_center [method]: unit -> (float * float)
Oceanbox.FvcomKit.Types+BBox.get_empty [static method]: unit -> Oceanbox.FvcomKit.Types+BBox
Oceanbox.FvcomKit.Types+BBox.get_maxX [method]: unit -> float
Oceanbox.FvcomKit.Types+BBox.get_maxY [method]: unit -> float
Oceanbox.FvcomKit.Types+BBox.get_minX [method]: unit -> float
Oceanbox.FvcomKit.Types+BBox.get_minY [method]: unit -> float
Oceanbox.FvcomKit.Types+BBox.maxX [property]: [read-only] float
Oceanbox.FvcomKit.Types+BBox.maxY [property]: [read-only] float
Oceanbox.FvcomKit.Types+BBox.minX [property]: [read-only] float
Oceanbox.FvcomKit.Types+BBox.minY [property]: [read-only] float
Oceanbox.FvcomKit.Types.propTo2D [static method]: 'a [] -> single []
Oceanbox.FvcomKit.Types.propTo2D$W [static method]: ('a -> single, 'a []) -> single []
Oceanbox.FvcomKit.Types.propTo3D [static method]: 'a [] -> single []
Oceanbox.FvcomKit.Types.propTo3D$W [static method]: ('a -> single, 'a []) -> single []
Oceanbox.FvcomKit.Types.trace [static method]: Microsoft.FSharp.Core.PrintfFormat<unit, System.IO.TextWriter, unit, unit> -> 'a -> 'a
Oceanbox.FvcomKit.Types.unzip2D [static method]: ('a * 'b) [] -> ('a [] * 'b [])
Polygon inherit obj
Polygon.inpolygon [static method]: (float * float) [] -> (float, float) -> bool

View File

@@ -1,6 +1,7 @@
module Oceanbox.FvcomKit.Thredds
open System
open Microsoft.Research.Science.Data
open Microsoft.Research.Science.Data.NetCDF4
open Serilog
@@ -21,20 +22,20 @@ type Kind =
| Avg -> "avg"
| Qck -> "qck"
let dateRange (start: DateTime) days =
let dateRange (start: DateTime) days : DateTime list =
if days < 0 then
List.unfold (fun d -> if d < days then None else Some (start.AddDays d, d - 1)) 0
else
List.unfold (fun d -> if d > days then None else Some (start.AddDays d, d + 1)) 0
let tryOpenArchive url =
let tryOpenArchive url : DataSet option =
let uri = NetCDFUri ()
uri.Url <- url
do uri.Url <- url
try
let ds = NetCDFDataSet.Open uri
Some ds
with e ->
Log.Debug e.Message
do Log.Debug e.Message
None
let rec tryOpenThredds =
@@ -42,18 +43,22 @@ let rec tryOpenThredds =
| [] -> None
| x :: xs ->
match tryOpenArchive x with
| None ->
tryOpenThredds xs
| Some ds ->
Log.Debug $"thredds: {x}"
do Log.Debug $"thredds: {x}"
Some (x, ds)
| None -> tryOpenThredds xs
let tryGetTimeIndex (ds: DataSet) (t: DateTime) =
let ot = ds["ocean_time"].GetData () :?> double[]
let t0 = DateTimeOffset.FromUnixTimeSeconds (ot[0] |> int64)
let t1 = DateTimeOffset.FromUnixTimeSeconds (ot[^0] |> int64)
Log.Debug $"t={t} t0={t0} tn={t1}"
let first = Array.head ot
let last = Array.last ot
let t0 = DateTimeOffset.FromUnixTimeSeconds (first |> int64)
let t1 = DateTimeOffset.FromUnixTimeSeconds (last |> int64)
do Log.Debug $"t={t} t0={t0} tn={t1}"
if t < t0.DateTime || t > t1.DateTime then
Log.Error "time is out of bounds"
do Log.Error "time is out of bounds"
None
else
let dt = t - t0.DateTime

View File

@@ -4,6 +4,7 @@ open System
type Vertex = float * float
[<Struct>]
type BBox = {
minX: float
maxX: float

41
src/default.nix Normal file
View File

@@ -0,0 +1,41 @@
{
SDSLite,
projnet,
dotnet-sdk,
dotnet-runtime,
buildDotnetModule,
}:
let
name = "Oceanbox.Fvcomkit";
projectFile = ./Oceanbox.FvcomKit.fsproj;
versionMatch = builtins.match ".*<Version>([^<]+)</Version>.*" (
builtins.readFile projectFile
);
version = builtins.head versionMatch;
in
buildDotnetModule {
name = name;
pname = name;
version = version;
src = ./.;
buildInputs = [
projnet
SDSLite
];
projectFile = "Oceanbox.FvcomKit.fsproj";
inherit
dotnet-sdk
dotnet-runtime
;
nugetDeps = ./deps.json;
packNupkg = true;
# NOTE(mrtz): Can't package nuget without it
# [ref](https://github.com/dotnet/fsharp/issues/12320)
dotnetFlags = "--property:TargetsForTfmSpecificContentInPackage=";
}

272
src/deps.json Normal file
View File

@@ -0,0 +1,272 @@
[
{
"pname": "DynamicInterop",
"version": "0.9.1",
"hash": "sha256-IB76dA0+K/y/2s/qYL7AfVOF0+6W2hVIBgf9YdZ1oJY="
},
{
"pname": "FSharp.Core",
"version": "9.0.303",
"hash": "sha256-AxR6wqodeU23KOTgkUfIgbavgbcSuzD4UBP+tiFydgA="
},
{
"pname": "FSharp.Data",
"version": "6.3.0",
"hash": "sha256-zhVkSfqCljqr6UR0IUMOHUBlR61PvwYKq63PQ09yJPM="
},
{
"pname": "FSharp.Data",
"version": "6.4.1",
"hash": "sha256-+Z7zbD8cKmhHJWg7Z8XHJ8IeJXCWr/kgRl+VbbsMFw8="
},
{
"pname": "FSharp.Data.Csv.Core",
"version": "6.3.0",
"hash": "sha256-JdOr3NDmLPohkPpZaWjKqssw0+Wr1lVDtJwTNJ/JhcY="
},
{
"pname": "FSharp.Data.Csv.Core",
"version": "6.4.1",
"hash": "sha256-oz040beVF7WMONi3n0dPQlZD5deQWnClSXKRijgnw/k="
},
{
"pname": "FSharp.Data.Html.Core",
"version": "6.3.0",
"hash": "sha256-tSstVvAT9o+0Pr6cIReJOvh0kcthOWgt1CPzgIRoYRQ="
},
{
"pname": "FSharp.Data.Html.Core",
"version": "6.4.1",
"hash": "sha256-QBbvE8WXUVjS/0mW3aohZBuyfr3M7UGw7kt1oSrlq+s="
},
{
"pname": "FSharp.Data.Http",
"version": "6.3.0",
"hash": "sha256-/PzzLT0ev4miFswct+YscFDwoaq05BSJATM4fPvxk8o="
},
{
"pname": "FSharp.Data.Http",
"version": "6.4.1",
"hash": "sha256-0YD/jSCppE1siXrUcTx0OmVdgsjMk+gn0pHp+3GS3V4="
},
{
"pname": "FSharp.Data.Json.Core",
"version": "6.3.0",
"hash": "sha256-MFe88psxmHWGQYoG8NXi4z33TlWO+dMwOV4NViaUmTM="
},
{
"pname": "FSharp.Data.Json.Core",
"version": "6.4.1",
"hash": "sha256-0Fmo0f1jC3s+Dime8j2oqLnOK+elqo1xWmktpEYrZlk="
},
{
"pname": "FSharp.Data.Runtime.Utilities",
"version": "6.3.0",
"hash": "sha256-psc/tsHLYrorjeBBBLviwwA57XMFXUP2ywZqLMzfxac="
},
{
"pname": "FSharp.Data.Runtime.Utilities",
"version": "6.4.1",
"hash": "sha256-rNo2XQMME1zrPaIezD15P0RoTu8wyhtiJyB99Qp1hcE="
},
{
"pname": "FSharp.Data.WorldBank.Core",
"version": "6.3.0",
"hash": "sha256-QdL5ylUCvvrhvnnSPWj4MfN7B78hMbb5IRmozK7oJjM="
},
{
"pname": "FSharp.Data.WorldBank.Core",
"version": "6.4.1",
"hash": "sha256-nUyyziwpY58UnBNpqFoe/1bgDfQIq6gOqtQIwAo7x/c="
},
{
"pname": "FSharp.Data.Xml.Core",
"version": "6.3.0",
"hash": "sha256-67ftkfQJZ3iD62YKFh8Tu9Fuusb96KlKWxgykP1Wd9U="
},
{
"pname": "FSharp.Data.Xml.Core",
"version": "6.4.1",
"hash": "sha256-ZiD2aiD5yUZR4CDZl6mh4ji1G3xvm4Yd9Gya/e+D32w="
},
{
"pname": "FSharpPlus",
"version": "1.5.0",
"hash": "sha256-jQUlF3hsi3xpg+AdTnQw2L+lzbvTh5BIyLXCdVT6u6M="
},
{
"pname": "FSharpPlus",
"version": "1.7.0",
"hash": "sha256-6hDoDOnMFXQC5Hrk6Fhd+Wj+PbPFXzL9+xLIqgILJuY="
},
{
"pname": "FsPickler",
"version": "5.3.2",
"hash": "sha256-hjtm55aPJllzcVMPjFP4KYiEEBYtCcrUhbVOR+34agg="
},
{
"pname": "KdTree",
"version": "1.4.1",
"hash": "sha256-R4+L26pJoliLiwMuxmJDoa3Vf16gBq417fN+iNCy7Yc="
},
{
"pname": "MathNet.Numerics",
"version": "5.0.0",
"hash": "sha256-RHJCVM6OxquJF7n5Mbe/oNbucBbkge6ULcbAczOgmVo="
},
{
"pname": "MathNet.Numerics.FSharp",
"version": "5.0.0",
"hash": "sha256-pPbh8JdmMjBgEu84c/qV4YJ+LLr4+c31C6t++u29qBs="
},
{
"pname": "MessagePack",
"version": "3.1.3",
"hash": "sha256-OBn7iltr/rdE7ZKmv0MCUQSS+6OJKUYtlHdTbhEwzzE="
},
{
"pname": "MessagePack.Annotations",
"version": "3.1.3",
"hash": "sha256-o+T3u+xaHtW1c7AeWysCmIDUfN8lRhes2LoW5iQBafs="
},
{
"pname": "MessagePackAnalyzer",
"version": "3.1.3",
"hash": "sha256-5t4Av4CQ8HI7y9aAw+2qcOp+fsY0/3PdaFPJeCEAXQ0="
},
{
"pname": "Microsoft.NET.StringTools",
"version": "17.11.4",
"hash": "sha256-lWfzY35WQ+iKS9TpuztDTljgF9CIORhFhFEm0p1dVBE="
},
{
"pname": "Microsoft.NETCore.Platforms",
"version": "1.1.0",
"hash": "sha256-FeM40ktcObQJk4nMYShB61H/E8B7tIKfl9ObJ0IOcCM="
},
{
"pname": "Microsoft.NETCore.Targets",
"version": "1.1.0",
"hash": "sha256-0AqQ2gMS8iNlYkrD+BxtIg7cXMnr9xZHtKAuN4bjfaQ="
},
{
"pname": "ProjNET",
"version": "2.0.0",
"hash": "sha256-GjBnuGXmdFagIw9mX51Kpu/nn4gXta6a0cK/dxOWaZY="
},
{
"pname": "runtime.any.System.IO",
"version": "4.3.0",
"hash": "sha256-vej7ySRhyvM3pYh/ITMdC25ivSd0WLZAaIQbYj/6HVE="
},
{
"pname": "runtime.any.System.Reflection",
"version": "4.3.0",
"hash": "sha256-ns6f++lSA+bi1xXgmW1JkWFb2NaMD+w+YNTfMvyAiQk="
},
{
"pname": "runtime.any.System.Reflection.Primitives",
"version": "4.3.0",
"hash": "sha256-LkPXtiDQM3BcdYkAm5uSNOiz3uF4J45qpxn5aBiqNXQ="
},
{
"pname": "runtime.any.System.Runtime",
"version": "4.3.0",
"hash": "sha256-qwhNXBaJ1DtDkuRacgHwnZmOZ1u9q7N8j0cWOLYOELM="
},
{
"pname": "runtime.any.System.Text.Encoding",
"version": "4.3.0",
"hash": "sha256-Q18B9q26MkWZx68exUfQT30+0PGmpFlDgaF0TnaIGCs="
},
{
"pname": "runtime.any.System.Threading.Tasks",
"version": "4.3.0",
"hash": "sha256-agdOM0NXupfHbKAQzQT8XgbI9B8hVEh+a/2vqeHctg4="
},
{
"pname": "runtime.native.System",
"version": "4.3.0",
"hash": "sha256-ZBZaodnjvLXATWpXXakFgcy6P+gjhshFXmglrL5xD5Y="
},
{
"pname": "runtime.unix.System.Private.Uri",
"version": "4.3.0",
"hash": "sha256-c5tXWhE/fYbJVl9rXs0uHh3pTsg44YD1dJvyOA0WoMs="
},
{
"pname": "Serilog",
"version": "4.2.0",
"hash": "sha256-7f3EpCsEbDxXgsuhE430KVI14p7oDUuCtwRpOCqtnbs="
},
{
"pname": "Serilog.Sinks.Console",
"version": "6.0.0",
"hash": "sha256-QH8ykDkLssJ99Fgl+ZBFBr+RQRl0wRTkeccQuuGLyro="
},
{
"pname": "Serilog.Sinks.File",
"version": "6.0.0",
"hash": "sha256-KQmlUpG9ovRpNqKhKe6rz3XMLUjkBqjyQhEm2hV5Sow="
},
{
"pname": "Serilog.Sinks.Seq",
"version": "9.0.0",
"hash": "sha256-NnAkRbxwQGdNXz6DDONRxorNh1nqH2TfAQtokbq5qDw="
},
{
"pname": "System.IO",
"version": "4.3.0",
"hash": "sha256-ruynQHekFP5wPrDiVyhNiRIXeZ/I9NpjK5pU+HPDiRY="
},
{
"pname": "System.Memory",
"version": "4.5.3",
"hash": "sha256-Cvl7RbRbRu9qKzeRBWjavUkseT2jhZBUWV1SPipUWFk="
},
{
"pname": "System.Numerics.Vectors",
"version": "4.5.0",
"hash": "sha256-qdSTIFgf2htPS+YhLGjAGiLN8igCYJnCCo6r78+Q+c8="
},
{
"pname": "System.Private.Uri",
"version": "4.3.0",
"hash": "sha256-fVfgcoP4AVN1E5wHZbKBIOPYZ/xBeSIdsNF+bdukIRM="
},
{
"pname": "System.Reflection",
"version": "4.3.0",
"hash": "sha256-NQSZRpZLvtPWDlvmMIdGxcVuyUnw92ZURo0hXsEshXY="
},
{
"pname": "System.Reflection.Emit.ILGeneration",
"version": "4.3.0",
"hash": "sha256-mKRknEHNls4gkRwrEgi39B+vSaAz/Gt3IALtS98xNnA="
},
{
"pname": "System.Reflection.Emit.Lightweight",
"version": "4.3.0",
"hash": "sha256-rKx4a9yZKcajloSZHr4CKTVJ6Vjh95ni+zszPxWjh2I="
},
{
"pname": "System.Reflection.Primitives",
"version": "4.3.0",
"hash": "sha256-5ogwWB4vlQTl3jjk1xjniG2ozbFIjZTL9ug0usZQuBM="
},
{
"pname": "System.Runtime",
"version": "4.3.0",
"hash": "sha256-51813WXpBIsuA6fUtE5XaRQjcWdQ2/lmEokJt97u0Rg="
},
{
"pname": "System.Text.Encoding",
"version": "4.3.0",
"hash": "sha256-GctHVGLZAa/rqkBNhsBGnsiWdKyv6VDubYpGkuOkBLg="
},
{
"pname": "System.Threading.Tasks",
"version": "4.3.0",
"hash": "sha256-Z5rXfJ1EXp3G32IKZGiZ6koMjRu0n8C1NGrwpdIen4w="
}
]

12
src/version.json Normal file
View File

@@ -0,0 +1,12 @@
{
"version": "5.15",
"publicReleaseRefSpec": [
"^refs/heads/main$"
],
"pathFilters": [
":/Directory.Build.props",
":/README.md",
":/global.json",
":/src/"
]
}

View File

@@ -1,18 +0,0 @@
module Tests
open Expecto
let server =
testList
"Server"
[
testCase "Adding valid Todo"
<| fun _ ->
let expectedResult = Ok()
Expect.equal (Ok()) expectedResult "Result should be ok"
]
let all = testList "All" [ server ]
[<EntryPoint>]
let main _ = runTests defaultConfig all

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Tests.fs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\Oceanbox.FvcomKit.fsproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Expecto" Version="10.2.2" />
<PackageReference Update="FSharp.Core" Version="9.0.201" />
</ItemGroup>
</Project>

189
xtest/Arome.fs Normal file
View File

@@ -0,0 +1,189 @@
module Arome
open System
open Microsoft.Research.Science.Data
open Xunit
open FsUnit.Xunit
open FsUnit.CustomMatchers
open Serilog
open ProjNet.FSharp
open Oceanbox.FvcomKit
let logger =
LoggerConfiguration()
.MinimumLevel.Is(Events.LogEventLevel.Verbose)
.WriteTo.Console()
.CreateLogger()
do Log.Logger <- logger
[<Literal>]
let private path = "/data/archives/Arome/meps_det_sfc_20220102T00Z.nc"
let trans = makeTransform CoordSys.WGS84 (CoordSys.LCCMet ())
// Use Netcdf to open dataset
let private openDataset (path: string) : DataSet =
let sw = Diagnostics.Stopwatch.StartNew()
let uri = NetCDF4.NetCDFUri()
do uri.FileName <- path
do uri.OpenMode <- ResourceOpenMode.ReadOnly
do uri.Deflate <- NetCDF4.DeflateLevel.Off
let ds = NetCDF4.NetCDFDataSet.Open uri
do Log.Debug $"openDataSet: {path} completed in {sw.ElapsedMilliseconds}ms"
ds
let private aromeGrid = {
Arome.SquareGrid.empty with
dimensions = 949, 1069
BBox = {
minX = -18.12241427
maxX = 54.24126163
minY = 49.7653854
maxY = 75.22869642
center = 27.12063081, 37.61434821
}
squareSize = 2.444065489
}
[<Fact>]
let ``Create grid``() =
use ds = openDataset path
let res = Arome.getGrid ds
// "Should be able to create square grid from /data/archives/Arome/meps_det_sfc_20220102T00Z.nc"
res |> should be (ofCase <@ Result<Arome.SquareGrid, string>.Ok @>)
[<Fact>]
let ``test grid regularity``() =
let trans = makeTransform CoordSys.WGS84 (CoordSys.LCCMet ())
use ds = openDataset path
let dimensions = ds.Dimensions["x"].Length, ds.Dimensions["y"].Length
let longs : float array2d = ds["longitude"].GetData () :?> float[,]
let lats : float array2d = ds["latitude"].GetData () :?> float[,]
// NOTE: The netcdf file dimensions are defined as (y, x)
let width = Array2D.length2 longs
let height = Array2D.length1 lats
let points : Arome.Points array =
let result = Array.create (width * height) Arome.Points.Zero
for i in 0 .. height - 1 do
for j in 0 .. width - 1 do
let lat = lats[i, j]
let lon = longs[i, j]
let p = lon, lat
// NOTE(simkir): Convert to lambert and undo all I've done... :(
let x, y = trans.project p
result[i * width + j] <- Arome.Points.OfTuple (single x, single y)
result
let mutable acc = 0.0f
for i in 0 .. height - 1 do
for j in 0 .. width - 2 do
let p0 = points[i * width + j]
let p1 = points[i * width + j + 1]
let dx = if p0.x < p1.x then p1.x - p0.x else p0.x - p1.x
acc <- acc + dx
let count = width * height
let avgDiffX = acc / single count
Log.Debug("Avg. X distance: {Avg}m", avgDiffX)
acc <- 0.0f
for i in 0 .. height - 2 do
for j in 0 .. width - 1 do
let p0 = points[i * width + j]
let p1 = points[(i + 1) * width + j]
let dy = if p0.y < p1.y then p1.y - p0.y else p0.y - p1.y
acc <- acc + dy
let avgDiffY = acc / single count
Log.Debug("Avg. Y distance: {Avg}m", avgDiffY)
[<Fact>]
let ``point within first rect``() =
use ds = openDataset path
let res = Arome.getGrid ds
match res with
| Ok grid ->
let width, _height = grid.dimensions
let p0 = grid.points[0 * width + 0]
let p1 = grid.points[1 * width + 1]
let rect = Arome.Rect.OfPoints p0 p1
// { x = -1064984.25f y = -1353489.375f }, { x = -1062474.625f y = -1350985.875f }
let p2 = Arome.Points.OfTuple (-1063000.25f, -1353486.0f)
let within = Arome.Rect.pointWithin rect p2
within |> should equal true
| Error _ ->
failwith "Should create grid"
[<Fact>]
let ``Read uvs for index (1, 1)``() =
use ds = openDataset path
let res = Arome.getGrid ds
match res with
| Ok grid ->
let idx =
let lat = 50.35
let lon = 0.304
let p = trans.project((lon, lat))
Arome.tryFindIndex grid p
match idx with
| Some (i, j) ->
let u, v = Arome.readUV ds 0 i j
(u, v) |> should equal (8.530239f, 6.659096f) // "Find uv (8.530239, 6.659096) at index (1, 1)"
| None ->
failwith "Should find idx"
| Error _ ->
failwith "Should find grid"
[<Fact>]
let ``Try search index (1, 1069) based on map coords``() =
let lat = 72.800
let lon = -17.850
let p = trans.project((lon, lat))
let res =
use ds = openDataset path
Arome.getGrid ds
match res with
| Ok grid ->
let idx = Arome.tryFindIndex grid p
idx |> should equal (Some (4, 1067)) // "Should find idx (1, 1069)"
| Error _ ->
failwith "Should find grid"
[<Fact>]
let ``Read uvs for pos (60.3562, 5.2178)``() =
let lat = 60.3562
let lon = 5.2178
let p = trans.project((lon, lat))
use ds = openDataset path
let res = Arome.getGrid ds
match res with
| Ok grid ->
let idx = Arome.tryFindIndex grid p
match idx with
| Some (i, j) ->
let u, v = Arome.readUV ds 0 i j
// "Find uv (2.367153168, -0.3955917358) at pos (60.3562, 5.2178) almost in Bergen"
(u, v) |> should equal (-0.3750343323f, 7.744056702f)
| None ->
failwith "Should find idx"
| Error _ ->
failwith "Should find grid"
[<Fact>]
let ``Read uvs for t 23 x 43 y 144``() =
use ds = openDataset path
let u, v = Arome.readUV ds 23 43 144
// "Find uv (2.367153168, -0.3955917358) at pos (60.3562, 5.2178) almost in Bergen"
(u, v) |> should equal (11.77926254f, 5.764093399f)

24
xtest/TestSurface.fs Normal file
View File

@@ -0,0 +1,24 @@
module TestSurface
open ApiSurface
open Xunit
let assembly = typedefof<Oceanbox.FvcomKit.Arome.SquareGrid>.Assembly
let dir = "/home/mrtz/devel/Oceanbox.FvcomKit/src/"
[<Fact>]
let ``Ensure API surface has not been modified`` () = ApiSurface.assertIdentical assembly
[<Fact(Skip = "Explicit: Run only when you want to update the API baseline.")>]
let ``Update API surface`` () =
ApiSurface.writeAssemblyBaselineWithDirectory dir assembly
// TODO(mrtz): 352 undocumented functions :/
// [<Fact>]
// let ``Ensure public API is fully documented`` () =
// DocCoverage.assertFullyDocumented assembly
// TODO(mrtz): Enable once we use nerdbank versioning
// [<Fact>]
// let ``EnsureVersionIsMonotonic`` () =
// MonotonicVersion.validate assembly "Oceanbox.FvcomKit"

44
xtest/xtest.fsproj Normal file
View File

@@ -0,0 +1,44 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<IsPublishable>false</IsPublishable>
<IsTestProject>true</IsTestProject>
<RootNamespace>xtest</RootNamespace>
<TargetFramework>net9.0</TargetFramework>
<TestingPlatformDotnetTestSupport>true</TestingPlatformDotnetTestSupport>
<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>
<!--
This template uses native xUnit.net command line options when using 'dotnet run' and
VSTest by default when using 'dotnet test'. For more information on how to enable support
for Microsoft Testing Platform, please visit:
https://xunit.net/docs/getting-started/v3/microsoft-testing-platform
-->
</PropertyGroup>
<ItemGroup>
<Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<Compile Include="TestSurface.fs" />
<Compile Include="Arome.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ApiSurface" Version="5.0.3" />
<PackageReference Include="FsUnit" Version="7.1.1" />
<PackageReference Include="FsUnit.xUnit" Version="7.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="Oceanbox.SDSLite" Version="2.8.0" />
<PackageReference Include="xunit.v3" Version="3.2.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../src/Oceanbox.FvcomKit.fsproj" />
</ItemGroup>
</Project>

4
xtest/xunit.runner.json Normal file
View File

@@ -0,0 +1,4 @@
{
"$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
"shadowCopy": false
}