diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a1ef9e3..90142ba 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,6 +20,13 @@ repos: - id: mixed-line-ending - id: trailing-whitespace + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 0.28.3 + hooks: + - id: check-jsonschema + args: ["--schemafile", "schema.json"] + files: ^models/.*\.(json|yaml|yml)$ + - repo: https://github.com/pre-commit/mirrors-prettier rev: v4.0.0-alpha.8 hooks: diff --git a/.vscode/settings.json b/.vscode/settings.json index 5bb57cf..fbe3486 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,6 +12,12 @@ "editor.defaultFormatter": "esbenp.prettier-vscode" }, "editor.formatOnSave": true, + "json.schemas": [ + { + "fileMatch": ["models/*.json"], + "url": "./schema.json" + } + ], "julia.executablePath": "${workspaceFolder}/.pixi/envs/default/bin/julia", "livePreview.defaultPreviewPath": "docs/_build/html", "python.defaultInterpreterPath": ".pixi/envs/default/bin/python", @@ -21,5 +27,8 @@ "**/bower_components": true, "**/node_modules": true, "**/pixi.lock": true + }, + "yaml.schemas": { + "./schema.json": ["models/*.yaml", "models/*.yml"] } } diff --git a/schema.json b/schema.json new file mode 100644 index 0000000..ab44eb9 --- /dev/null +++ b/schema.json @@ -0,0 +1,443 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Amplitude Model Serialization Format", + "description": "This schema describes the serialization format of an amplitude model for hadron physics.", + "additionalProperties": false, + "definitions": { + "AngularMomentum": { + "anyOf": [ + { "type": "integer", "minimum": 0 }, + { + "type": "string", + "pattern": "^(0|[1-9][0-9]*)$" + } + ] + }, + "ComplexNumber": { + "anyOf": [ + { "type": "number" }, + { + "type": "string", + "pattern": "^-?\\d+(\\.\\d+)?(e[-+]?\\d+)? *[+-] *\\d+(\\.\\d+)?(e[-+]?\\d+)?i$" + } + ], + "examples": ["1", "1.0", "1.0 + 2.0i", "1.0-2.0i"] + }, + "DecayChain": { + "type": "object", + "properties": { + "name": { + "description": "A label for the decay chain, used for clarity and not as a standardized identifier.", + "type": "string" + }, + "propagators": { + "description": "List of the lineshape descriptors.", + "type": "array", + "items": { + "type": "object", + "properties": { + "spin": { + "$ref": "#/definitions/Spin" + }, + "node": { + "description": "Defines a node in the topology graph by specifying the particles involved in the interaction.", + "$ref": "#/definitions/Topology" + }, + "parametrization": { + "type": "string", + "description": "Lineshape parametrization. Should match the \"name\" of one of the function definitions under the \"functions\" section." + } + }, + "required": ["spin", "node", "parametrization"], + "additionalProperties": false + }, + "uniqueItems": true + }, + "topology": { + "description": "Structure of this decay chain represented as nasted particle grouping into intermediate subsystems.", + "$ref": "#/definitions/Topology" + }, + "vertices": { + "description": "Vertices define the nodes in the decay graphs denoted by groupping of particle indices.", + "type": "array", + "items": { "$ref": "#/definitions/Vertex" }, + "uniqueItems": true + }, + "weight": { + "description": "The weight in each chain gives the complex coefficient that multiplies the decay matrix element of the chain’s specific sequence of interactions and propagations. It influences the probability of the chain’s occurrence and interference with other decay chains. The weight is a complex number.", + "$ref": "#/definitions/ComplexNumber" + } + }, + "required": ["name", "propagators", "topology", "vertices", "weight"], + "additionalProperties": false + }, + "Function": { + "type": "object", + "properties": { + "name": { + "description": "Identifier that can be used elsewhere to reference this function.", + "type": "string" + }, + "type": { + "description": "Common type defines mathematical expression of the object.", + "type": "string" + }, + "channels": { + "type": "array", + "items": { + "type": "object", + "properties": { + "gsq": { "type": "number" }, + "ma": { "type": "number" }, + "mb": { "type": "number" }, + "l": { + "description": "Orbital angular momentum between particles in the decay.", + "$ref": "#/definitions/AngularMomentum" + }, + "d": { + "description": "Size of the potential well for Blatt-Weisskopf factor.", + "type": "number" + } + }, + "required": ["gsq", "ma", "mb", "l", "d"], + "additionalProperties": false + }, + "uniqueItems": true + }, + "expression": { + "description": "Expression for the function. Use this for custom functions.", + "type": "string" + }, + "l": { + "description": "Orbital angular momentum of the decay.", + "$ref": "#/definitions/AngularMomentum" + }, + "mass": { + "description": "Nominal mass of the resonance in GeV.", + "type": "number", + "minimum": 0 + }, + "width": { + "description": "Nominal width of the resonance in GeV.", + "type": "number", + "minimum": 0 + }, + "ma": { "type": "number", "minimum": 0 }, + "mb": { "type": "number", "minimum": 0 } + }, + "required": ["name", "type"], + "allOf": [ + { + "if": { "properties": { "type": { "const": "custom" } } }, + "then": { "required": ["expression"] } + }, + { + "if": { "properties": { "type": { "const": "BlattWeisskopf" } } }, + "then": { "required": ["radius", "l"] } + }, + { + "if": { "properties": { "type": { "const": "MomentumPower" } } }, + "then": { "required": ["l"] } + }, + { + "if": { "properties": { "type": { "const": "BreitWigner" } } }, + "then": { "required": ["mass", "width", "ma", "mb", "l", "d"] } + }, + { + "if": { + "properties": { "type": { "const": "MultichannelBreitWigner" } } + }, + "then": { "required": ["channels", "mass"] } + } + ] + }, + "Parameter": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "value": { "type": "number" } + }, + "additionalProperties": false + }, + "Spin": { + "description": "The spin of the particle, described as a fraction in string format. If the particle is a fermion, the spin is an integer or half-integer. If the particle is a boson, the spin is an integer.", + "examples": ["0", "1/2", "1", "-3/2"], + "pattern": "^(?![-+]0)[-+]?\\d+(/2)?$", + "type": "string" + }, + "State": { + "type": "object", + "properties": { + "index": { + "type": "integer", + "description": "A unique identifier for each particle, with 0 reserved for the initial state particle.", + "minimum": 0 + }, + "mass": { + "anyOf": [{ "type": "number" }, { "type": "string" }], + "description": "Mass of the particle in GeV. Can be a constant value or a parametrization described under \"functions\" section." + }, + "name": { + "type": "string", + "description": "A label for each particle, used for clarity and not as a standardized identifier." + }, + "spin": { + "description": "The spin quantum number of the particle, represented in string format", + "$ref": "#/definitions/Spin" + } + }, + "required": ["index", "name", "spin", "mass"] + }, + "Topology": { + "type": "array", + "items": { + "anyOf": [ + { "type": "integer", "minimum": 1 }, + { "$ref": "#/definitions/Topology" } + ] + }, + "uniqueItems": true + }, + "Vertex": { + "type": "object", + "required": ["type", "node"], + "properties": { + "type": { + "description": "Specifies how the helicity recoupling factor H_{lam1,lam2} is computed. Each option reflects different ways of relating combinations of the helicity indices to a real-valued factor, the recoupling coefficient.", + "enum": ["helicity", "ls", "parity"], + "enumDescriptions": [ + "Recoupling with LS computes the value of the recoupling functions using Clebsch-Gordan coefficients.", + "Parity` recoupling is controlled by the parity factor and gives a non-zero value for two combination of the helicity pair, the selected one and the opposite.", + "No recoupling. The factor is 1 for a pair of selected helicities and zero for other combinations." + ] + }, + "helicities": { + "type": "array", + "description": "Spin projections of the two decay products in the vertex.", + "items": { "$ref": "#/definitions/Spin" }, + "minItems": 2, + "maxItems": 2 + }, + "node": { + "$ref": "#/definitions/Topology", + "description": "Description of the position of the vertex within the decay topology." + }, + "parity_factor": { + "description": "Factor that is is required for parity couplings and LS couplings. Gives a non-zero value for two combination of the helicity pair, the selected one and the opposite.", + "enum": ["-", "+"] + }, + "l": { + "description": "Orbital angular momentum of particles in the decay the vertex.", + "$ref": "#/definitions/AngularMomentum" + }, + "s": { + "description": "Coupled spin of the vertex.", + "$ref": "#/definitions/Spin" + }, + "formfactor": { + "description": "Optional form-factor for the vertex. The form-factor is a function of three arguments, (mX^2, mA^2, mB^2) for X->[A,B] vertex, that is defined under \"functions\" section.", + "default": "", + "type": "string" + } + }, + "additionalProperties": false, + "allOf": [ + { + "if": { "properties": { "type": { "const": "helicity" } } }, + "then": { "required": ["helicities"] } + }, + { + "if": { "properties": { "type": { "const": "ls" } } }, + "then": { "required": ["l", "s"] } + }, + { + "if": { "properties": { "type": { "const": "parity" } } }, + "then": { "required": ["helicities", "parity_factor"] } + } + ] + } + }, + "properties": { + "distributions": { + "type": "array", + "description": "List of amplitude model PDF descriptions.", + "items": { + "properties": { + "decay_description": { + "type": "object", + "description": "Description of the decay that underlies the PDF.", + "properties": { + "chains": { + "type": "array", + "description": "List with definitions of the decay chains and their corresponding amplitudes that contribute to the PDF.", + "items": { "$ref": "#/definitions/DecayChain" }, + "minItems": 1 + }, + "kinematics": { + "type": "object", + "description": "Definition of the initial and final state of the decay.", + "properties": { + "initial_state": { + "description": "Initial state of the decay.", + "$ref": "#/definitions/State" + }, + "final_state": { + "type": "array", + "description": "List of states that form the final state.", + "items": { "$ref": "#/definitions/State" }, + "minItems": 1, + "uniqueItems": true + } + }, + "additionalProperties": false + }, + "reference_topology": { + "$ref": "#/definitions/Topology", + "description": "Definition of the basic decay structure (topology) of the model, which is used to define 1) parametrization of the decay kinematics, and 2) reference quantization axes. It outlines the decay chain for which the amplitude is written without a need for the alignment rotations. All other chains that have different decay topology must be aligned to this reference topology." + }, + "appendix": { "type": "object" } + }, + "additionalProperties": false + }, + "name": { "type": "string" }, + "parameters": { + "type": "array", + "items": { "$ref": "#/definitions/Parameter" }, + "uniqueItems": true + }, + "type": { + "description": "The type of the distribution. See https://rub-ep1.github.io/amplitude-serialization/description.html#amplitude-model-and-observables", + "markdownDescription": "The type of the distribution. For more info, see [here](https://rub-ep1.github.io/amplitude-serialization/description.html#amplitude-model-and-observables).", + "enum": [ + "HadronicUnpolarizedIntensity", + "HadronicPolarizedIntensity" + ], + "enumDescriptions": [ + "Amplitude model distribution that sums over the polarization of the initial state.", + "Amplitude model distribution that takes the polarization of the initial state into account." + ] + } + }, + "type": "object" + }, + "minItems": 1, + "uniqueItems": true + }, + "domains": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "description": "Identifier for the distribution. Can be referred to from elsewhere in the model description.", + "type": "string" + }, + "type": { + "enum": ["product_domain"], + "enumDescriptions": [ + "Box-shaped domain defined by min-max values over each variable." + ] + }, + "parameters": { + "type": "array", + "description": "List of parameters and their values that together describe a domain in phase space.", + "items": { "$ref": "#/definitions/Parameter" }, + "uniqueItems": true + }, + "axes": { + "type": "array", + "description": "List of variables and their ranges.", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "Name of the variable." + }, + "min": { "type": "number" }, + "max": { "type": "number" } + }, + "required": ["name"] + }, + "uniqueItems": true + } + }, + "required": ["name", "type"], + "allOf": [ + { + "if": { "properties": { "type": { "const": "product_domain" } } }, + "then": { "required": ["axes"] } + } + ], + "additionalProperties": false + }, + "uniqueItems": true + }, + "functions": { + "type": "array", + "description": "Definitions of functions that are used in the model.", + "items": { "$ref": "#/definitions/Function" }, + "uniqueItems": true + }, + "misc": { + "type": "object", + "description": "Any additional information about the model.", + "properties": { + "amplitude_model_checksums": { + "type": "array", + "description": "A list of checksums that can be used to validate whether the computational implementation of the serialized amplitude model is correct.", + "items": { + "properties": { + "point": { + "description": "Parameter point over which to evaluate the distribution.", + "type": "string", + "pattern": "^validation_point[0-9]*$" + }, + "distribution": { + "type": "string", + "description": "The name of the distribution for which the checksum is calculated." + }, + "value": { + "description": "The resulting checksum value ('non-normalized intensity').", + "minimum": 0, + "type": "number" + } + }, + "uniqueItems": true + } + } + } + }, + "parameter_points": { + "type": "array", + "description": "Definition of points in parameter space over which the model can be evaluated.", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "Identifier for the parameter point. Can be referred to from elsewhere in the model description." + }, + "parameters": { + "type": "array", + "description": "List of parameters and their values that together describe a point in phase space.", + "items": { "$ref": "#/definitions/Parameter" }, + "uniqueItems": true + } + }, + "required": ["name"], + "additionalProperties": false + }, + "uniqueItems": true + } + }, + "required": [ + "distributions", + "domains", + "functions", + "misc", + "parameter_points" + ], + "type": "object" +}