Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read/write nested data as flattened parameter name to and from toml file #48

Merged
merged 13 commits into from
Mar 22, 2022
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,15 @@ The catalog is a YAML formatted file which tells the app what nodes are availabl
1. global: Description of global parameters
* schema: What parameters are valid. Formatted as JSON schema draft 7.
* uiSchema: How the form for filling the parameters should be rendered.
* tomlSchema: How toml keys are mapped to in-memory representation.
2. nodes: Description of available nodes.
* id: Identifier of node, for computers
* label: Label of node, for humans
* category: Category to which node belongs
* description: Text describing what node needs, does and produces.
* schema: What parameters are valid. Formatted as JSON schema draft 7.
* uiSchema: How the form for filling the parameters should be rendered.
* tomlSchema: How toml keys are mapped to in-memory representation.
3. catagories: Descriptions of node categories
* name: Name of category
* description: Description of category
Expand All @@ -128,6 +130,10 @@ Besides the built-in react-json-schema-form uiSchema fields the workflow builder

Any property with a group uiSchema field will be grouped together with other properties with the same group in the form. The generated toml file will have the props ungrouped.

### tomlSchema

See [docs/tomlSchema.md](docs/tomlSchema.md).

### Catalog index

In the worklfow builder you can pick a catalog from a list. This list gets downloaded from [public/catalog/index.json](public/catalog/index.json) and is formatted like
Expand Down
347 changes: 347 additions & 0 deletions docs/tomlSchema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,347 @@
# tomlSchema

Any array or object value can be written in different ways to a toml file.
Use the toml schema in the catalog to overwrite the default behaviour.

The default behavior is to write the value as a nested structure like

In memory have parameter object like

```js
{
key1: [ 1, 2 ], // Array of scalar
key2: [ "a", "b" ], // Array of scalar
key3: { a: 1, b: 2}, // Object
key4: { a: [ 1, 2 ]}, // Object with array of scalar
key5: [ { a: 1 }, { a: 2 }], // Array with objects
key6: [ { a: [ 1, 2 ]} ], // Array with oboject with array of scalar
key7: [ [ 1, 2], [ 3 ,4 ] ], // Array of array of scalar
key8: [ [ { a: 1 }, { a: 2 }], [ { a: 3 } ,{ a: 4 } ] ], // Array of array of object
}
```

The parameter object JSON shema is defined in the catalog.

The resulting toml would look like

```toml
key1 = [ 1, 2 ]
key2 = [ "a", "b" ]
key3.a = 1
key3.b = 2
key4.a = [ 1, 2 ]
key5 = [ { a = 1 }, { a = 2 }]
key6 = [ { a = [ 1, 2 ]} ]
key7 = [ [ 1, 2], [ 3 ,4 ] ]
key8 = [ [ { a = 1 }, { a = 2 }], [ { a = 3 } ,{ a = 4 } ] ]
```

The tomlSchema object follows the tree structure of the schema hierarchy.

Special keywords in tomlSchema:

1. **indexed**, when true will have array index appended to key
2. **flatten**, when true will have object property names appended to key
3. **sectioned**, when true will write children inside own table (for example `[<module>.<key>]`)
4. **items**, to nest a toml schema for an array item
5. **properties**, to nest a toml schema for an object property

Below are examples of supported toml schema snippets.

## Array of scalars

In toml

```toml
param_1 = 11
param_2 = 22
param_3 = 33
Comment on lines +56 to +58
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

11, 22, and 33 are just example numbers, but due to their structure and correspondence to the params, it took me some time to realize they might as well be random other numbers. Perhaps we could consider making them a bit more arbitrary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I chose those number to easily map the indices to the values. Using arbitrary numbers would make it harder to investigate any errors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this is the documentation, not testing code or so

```

In catalog

```yaml
schema:
type: object
properties:
param:
type: array
items:
type: number
tomlSchema:
param:
indexed: true
```

In memory

```json
{
"param": [11, 22, 33]
}
```

## Array of objects flattened

In toml

```toml
name_something_1 = 11
name_else_1 = 22
name_something_2 = 33
name_else_2 = 44
```

In catalog

```yaml
schema:
type: object
properties:
name:
type: array
items:
type: object
properties:
something:
type: number
else:
type: number
tomlSchema:
name:
indexed: true
items:
flatten: true
```

In memory

```json
{
"name": [{
"something": 11,
"else": 22,
}, {
"something": 33,
"else": 44,
}]
}
```

## Array of objects sectioned

In toml

```toml
[[name]]
something = 11
else = 22

[[name]]
something = 33
else = 44
Peter9192 marked this conversation as resolved.
Show resolved Hide resolved
```

In catalog

```yaml
schema:
type: object
properties:
name:
type: array
items:
type: object
properties:
something:
type: number
else:
type: number
tomlSchema:
name:
items:
sectioned: true
```

In memory

```json
{
"name": [{
"something": 11,
"else": 22,
}, {
"something": 33,
"else": 44,
}]
}
```

## Array of array of objects

In toml

```toml
fle_sta_1_1 = 11
fle_end_1_1 = 22
fle_sta_1_2 = 33
fle_end_1_2 = 44
fle_sta_2_1 = 55
fle_end_2_1 = 66
```

In catalog

```yaml
schema:
type: object
additionalProperties: false
properties:
fle:
type: array
description: Outer array is molecule index
items:
type: array
description: Inner array is segment index
items:
type: object
properties:
sta:
title: Starting residue number
type: number
end:
title: End residue number
type: number
additionalProperties: false
tomlSchema:
fle:
indexed: true
items:
indexed: true
items:
flatten: true
```

In memory

```json
{
"fle": [
[
{
"sta": 11,
"end": 22
},
{
"sta": 33,
"end": 44
}
],
[
{
"sta": 55,
"end": 66
}
]
]
}
```

## Array of objects with object as toml table and scalar as array prop

In toml

```toml
[topoaa.mol_1]
cyclicpept = false
hisd_1 = 13
hisd_2 = 42

[topoaa.mol_2]
cyclicpept = true
hisd_1 = 314
hisd_2 = 512
```

In catalog

```yaml
schema:
type: object
properties:
mol:
type: array
items:
type: object
properties:
cyclicpept:
type: boolean
hisd:
type: array
items:
type: number
tomlSchema:
mol:
indexed: true
items:
sectioned: true
properties:
hisd:
indexed: true
```

In memory

```json
{
"mol": [{
"cyclicpept": false,
"hisd": [13, 42]
}, {
"cyclicpept": true,
"hisd": [314, 512]
}]
}
```

## Node parameter where value is an object as section

In toml

```toml
[somenode]

[somenode.foo]
bar.bla = 'hi'
```

In catalog

```yaml
schema:
type: object
properties:
foo:
type: object
properties:
bar:
type: object
properties:
bla:
type: string
tomlSchema:
foo:
sectioned: true
```

In memory parameters for node called `somenode`.

```json
{
"foo": {
"bar": {
"bla": "hi"
}
}
}
```
Loading