diff --git a/schemas/beam.schema.json b/schemas/beam.schema.json new file mode 100644 index 0000000..5dc0180 --- /dev/null +++ b/schemas/beam.schema.json @@ -0,0 +1,104 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/beam", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Gaussian beam", + "description": "Gaussian beam characterization at the launch point.", + "type": "object", + "properties": { + "cocos": {"$ref": "cocos"}, + "power": { + "description": "Beam power at launch. Units [MW]", + "type": "number", + "minimum": 0 + }, + "freq": { + "description": "Wave frequency. Units [GHz]", + "type": "number", + "exclusiveMinimum": 0 + }, + "polarization": { + "description": "Beam polarization.\\nIt can be one of the plasma modes, or an arbitrary polarization,\\ncharacterized via the polarization ellipse parameters, that in general\\nwill couple to both OM and XM", + "type": "object", + "properties": { + "mode": { + "description": "The propagation mode the beam couples to. One of:\\n - `OM`: Ordinary mode\\n - `XM`: eXtraordinary mode\n - `ANY`: arbitrary polarization", + "enum": ["OM", "XM", "ANY"] + }, + "ellipse": {"$ref": "#/$defs/polEllipse"} + } + }, + "pos": { + "description": "Point where the beam is defined", + "$ref": "coordscyl" + }, + "dir": { + "description": "Beam direction at launch", + "type": "object", + "properties": { + "cocos": {"$ref": "cocos"}, + "alpha": { + "description": "Poloidal angle. alpha = atan2(-k_z, -k_R), with k the unit wavevector at launch. Units [deg]", + "type": "number" + }, + "beta": { + "description": "Toroidal angle. beta = asin(k_phi), with k the unit wavevector at launch. Units [deg]", + "type": "number" + } + } + }, + "shape": { + "description": "Beam shape at launch", + "type": "object", + "properties": { + "amplitude": { + "description": "Amplitude ellipse (E-field amplitude 1/e-fold on-axis value)", + "type": "object", + "properties": { + "w": { + "description": "Semi-axes of the ellipse. Units [m]", + "type": "array", + "items": {"type": "number", "exclusiveMinimum": 0}, + "minItems": 2, + "maxItems": 2 + }, + "phi": {"$ref": "#/$defs/rotAngle"} + } + }, + "phase": { + "description": "Phase ellipse (wavefront curvature)", + "type": "object", + "properties": { + "invR": { + "description": "Principal curvatures of the phase front. Units [m^-1]", + "type": "array", + "items": {"type": "number"}, + "minItems": 2, + "maxItems": 2 + }, + "phi": {"$ref": "#/$defs/rotAngle"} + } + } + } + } + }, + "$defs": { + "polEllipse": { + "description": "Angles defining an elliptical polarization", + "type": "object", + "properties": { + "psi": { + "description": "Polarization ellipse orientation.\\nThe angle is measured counter-clockwise angle from x' to the polarization\\nellipse major axis in a local right-handed Cartesian frame (x',y',z')\\nwith z' parallel to the beam axis direction k, and x' in the horizontal\\nplane of the global frame (i.e., x'.z=0). Units [deg]", + "type": "number" + }, + "chi": { + "description": "Polarization ellipticity.\\n|tan(chi)| = b/a ≤ 1 is the ratio of the polarization ellipse semi-axes\\nsign(chi) = +1 for a right-handed wave (i.e., electric field rotating\\nfrom x' to y' at fixed z') and -1 for a left-handed wave. Units [deg]", + "type": "number" + } + } + }, + "rotAngle": { + "description": "Ellipse orientation. The angle is measured counter-clockwise from x' to\\nthe first principal direction, in a local right-handed Cartesian frame\\n(x',y',z') with z' parallel to the beam axis direction k, and x' in the\\nhorizontal plane of the global frame (i.e., x'.z=0). Units [deg]", + "type": "number" + } + } +} diff --git a/schemas/cocos.schema.json b/schemas/cocos.schema.json new file mode 100644 index 0000000..39e2a41 --- /dev/null +++ b/schemas/cocos.schema.json @@ -0,0 +1,10 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/cocos", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "COCOS Tokamak COordinate COnventions code", + "type": "integer", + "oneOf": [ + {"minimum": 1, "maximum": 8}, + {"minimum": 11, "maximum": 18} + ] +} diff --git a/schemas/coordscart.schema.json b/schemas/coordscart.schema.json new file mode 100644 index 0000000..4a300e7 --- /dev/null +++ b/schemas/coordscart.schema.json @@ -0,0 +1,20 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/coordscart", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Cartesian coordinates in right-handed reference (x, y, z)", + "type": "object", + "properties": { + "x": { + "description": "x coordinate. Units [m]", + "type": "number" + }, + "y": { + "description": "y coordinate. Units [m]", + "type": "number" + }, + "z": { + "description": "z coordinate. Units [m]", + "type": "number" + } + } +} diff --git a/schemas/coordscyl.schema.json b/schemas/coordscyl.schema.json new file mode 100644 index 0000000..80ea637 --- /dev/null +++ b/schemas/coordscyl.schema.json @@ -0,0 +1,23 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/coordscyl", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Coordinates in a cylindrical reference (R, phi, z)", + "type": "object", + "properties": { + "cocos": {"$ref": "cocos"}, + "r": { + "description": "Major radius. Units [m]", + "type": "number", + "minimum": 0 + }, + "phi": { + "description": "Toroidal angle. Units [deg]", + "type": "number", + "default": 0 + }, + "z": { + "description": "Vertical coordinate. Units [m]", + "type": "number" + } + } +} diff --git a/schemas/coreprof.schema.json b/schemas/coreprof.schema.json new file mode 100644 index 0000000..6a47885 --- /dev/null +++ b/schemas/coreprof.schema.json @@ -0,0 +1,28 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/coreprof", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Tabulated core plasma profiles", + "type": "object", + "properties": { + "psiNorm": { + "description": "Normalized poloidal magnetic flux. 0 = magnetic axis, 1 = boundary. Units [-]", + "$ref": "grid1d", + "minimum": 0 + }, + "ne": { + "description": "Electron density. Units [10^19 m^-3]", + "$ref": "number1d", + "minimum": 0 + }, + "te": { + "description": "Electron temperature. Units [keV]", + "$ref": "number1d", + "minimum": 0 + }, + "zEff": { + "description": "Effective ion charge. Units [-]", + "$ref": "number1d", + "minimum": 0 + } + } +} diff --git a/schemas/equilibrium.schema.json b/schemas/equilibrium.schema.json new file mode 100644 index 0000000..8318ce7 --- /dev/null +++ b/schemas/equilibrium.schema.json @@ -0,0 +1,65 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/equilibrium", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Numerical magnetic equilibrium", + "type": "object", + "properties": { + "cocos": {"$ref": "cocos"}, + "psiNorm1d": { + "description": "Normalized poloidal magnetic flux on the grid of the 1D profiles. 0 = magnetic axis, 1 = boundary. Units [-]", + "$ref": "grid1d", + "minimum": 0 + }, + "fPol": { + "description": "Poloidal current function f(psi) = B_phi * R. Units [T.m]", + "$ref": "number1d" + }, + "q": { + "description": "Safety factor. Units [-]", + "$ref": "number1d" + }, + "rGrid": { + "description": "Major radius on the rows of the rectangular grid of the poloidal flux 2D map. Units [m]", + "$ref": "grid1d" + }, + "zGrid": { + "description": "Vertical coordinate on the columns of the rectangular grid of the poloidal flux 2D map. Units [m]", + "$ref": "grid1d" + }, + "psi2d": { + "description": "Poloidal magnetic flux on a rectangular (R,z) grid in row-major order:\\n`psi2d`[i][:] is a slice at z = `zGrid`[i];\\n`psi2d`[:][j] is a slice at R = `rGrid`[j].\\nUnits [Wb] or [Wb/rad], depending on COCOS.", + "$ref": "number2d" + }, + "psiAx": { + "description": "Poloidal flux at the magnetic axis. Units [Wb] or [Wb/rad] depending on COCOS.", + "type": "number" + }, + "psiBnd": { + "description": "Poloidal flux at the boundary. Units [Wb] or [Wb/rad] depending on COCOS.", + "type": "number" + }, + "rAx": { + "description": "Magnetic axis major radius. Units [m]", + "type": "number", + "exclusiveMinimum": 0 + }, + "zAx": { + "description": "Magnetic axis vertical coordinate. Units [m]", + "type": "number" + }, + "boundary": { + "description": "Plasma boundary contour in the Rz-plane", + "$ref": "rzpolygon" + }, + "currPhi": { + "description": "Toroidal plasma current enclosed by the boundary. Units [A].", + "type": "number" + }, + "bVac0": { + "description": "Vacuum magnetic field at the reference major radius R = `r0`. Units [T]", + "type": "number"}, + "r0": { + "description": "Reference major radius for the vacuum magnetic field `bVac0`. Units [m]", + "type": "number"} + } +} diff --git a/schemas/grid1d.json b/schemas/grid1d.json new file mode 100644 index 0000000..6a99494 --- /dev/null +++ b/schemas/grid1d.json @@ -0,0 +1,8 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/grid1d", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "1D array of unique numbers", + "type": "array", + "items": {"type": "number"}, + "uniqueItems": true +} diff --git a/schemas/io.schema.json b/schemas/io.schema.json new file mode 100644 index 0000000..15b1cca --- /dev/null +++ b/schemas/io.schema.json @@ -0,0 +1,24 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/io", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "GRAY Input/Output data", + "type": "object", + "properties": { + "inputs": { + "type": "object", + "properties": { + "equil" : {"$ref" : "equilibrium"}, + "coreProf" : {"$ref" : "coreprof"}, + "beam" : {"$ref" : "beam"}, + "wall" : {"$ref" : "wall"} + } + }, + "params" : {"$ref": "params"}, + "outputs" : { + "type" : "object", + "properties" : { + "hcdProf": {"constant": null} + } + } + } +} \ No newline at end of file diff --git a/schemas/number1d.schema.json b/schemas/number1d.schema.json new file mode 100644 index 0000000..4a6c649 --- /dev/null +++ b/schemas/number1d.schema.json @@ -0,0 +1,7 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/number1d", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "1D array of numbers", + "type": "array", + "items": {"type": "number"} +} diff --git a/schemas/number2d.schema.json b/schemas/number2d.schema.json new file mode 100644 index 0000000..5f74be2 --- /dev/null +++ b/schemas/number2d.schema.json @@ -0,0 +1,7 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/number2d", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "2D array of numbers", + "type": "array", + "items": {"$ref": "number1d"} +} diff --git a/schemas/params.schema.json b/schemas/params.schema.json new file mode 100644 index 0000000..7a60bc9 --- /dev/null +++ b/schemas/params.schema.json @@ -0,0 +1,266 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/params", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Code parameters", + "type" : "object", + "properties": { + "raytracing": { + "description": "Raytracing parameters", + "type": "object", + "properties": { + "nRayRad": { + "description": "Number of rays in the radial direction", + "type": "integer", + "minimum": 1, + "default": 1 + }, + "nRayAng": { + "description": "Number of rays in the angular direction", + "type": "integer", + "minimum": 1, + "default": 1 + }, + "rwMax": { + "description": "Normalized beam truncation radius.\\nThe last shell of rays is set at a distance r = `rwmax`⋅w from\\nthe magnetic axis, where w is the 1/e amplitude beam radius.", + "type": "number", + "exclusiveMinimum": 0, + "default": 1.0 + }, + "asBeam": { + "description": "`false` for raytracing (Geometrical Optics approximation), `true` for beamtracing (Complex GO)", + "type": "boolean", + "default": false + }, + "dStep": { + "description": "Step length for the numerical integration of the ray trajectories. Units [cm]", + "type": "number", + "exclusiveMinimum": 0 + }, + "nStep": { + "description": "Maximum number of integration steps", + "type": "integer", + "minimum": 0, + "default": 12000 + }, + "stepVar": { + "description": "Choice of the integration variable. One of:\\n - `ARCLEN`: arc length (s)\\n - `TIME`: time (actually c⋅t)\\n - `PHASE`: phase (actually the real part of the eikonal S_r=k₀⋅φ)", + "enum": ["ARCLEN", "TIME", "PHASE"], + "default": "TIME" + }, + "nPass": { + "description": "Maximum number of crossing (in, out) of the plasma.\\nWhen positive, reflections occur on the plasma limiter provided as input\\n(e.g., via the G-EQDSK file);\\nwhen negative on a simple cylindrical limiter is set at R = `rwall`", + "type": "integer", + "default": 1 + } + } + }, + "ecrh_cd": { + "description": "ECRH and current drive parameters", + "type":"object", + "properties": { + "absModel": { + "description": "Choice of the power absorption model. One of:\\n - `OFF`: no absorption\\n - `WEAK`: weakly relativistic\\n - `FULL`: fully relativistic\\n - `FULL_ALT`: fully relativistic (slower variant)\\nNote: `iwarm` /= `OFF` is required for current drive.", + "enum": ["OFF", "WEAK", "FULL", "FULL_ALT"], + "default": "FULL" + }, + "nLarm": { + "description": "Order of the electron Larmor radius expansion used for the warm dielectric tensor", + "type": "integer", + "minimum": 0, + "default": 5 + }, + "nIterMax": { + "description": "Max number of iterations for the solution of the warm dispersion relation.\\nNote: if negative the result of the first iteration will be used in case\\nthe result doesn't converge within |imx| iterations.", + "type": "integer", + "default": -20 + }, + "cdModel": { + "description": "Current drive model. One of:\\n - `OFF`: no current drive\\n - `COHEN`: Cohen model\\n - `NO_TRAP`: no trapping\\n - `NEOCLASS`: Neoclassical with momentum conservation", + "enum": ["OFF", "COHEN", "NO_TRAP", "NEOCLASS"], + "default": "NEOCLASS" + } + } + }, + "input": { + "description": "Input data pre-processing", + "type": "object", + "properties": { + "searchXPoint": { + "description": "Search X point for psi re-normalization.\\nOne of:\\n - `NO`: do not search\\n - `TOP`: upper X-point\\n - `BOTTOM`: lower X-point\\n - `BOTH`: search both, normalize to the innermost.", + "enum": ["NO", "TOP", "BOTTOM", "BOTH"], + "default": "NO" + }, + "smoothPsi": { + "description": "Tension of the 2D spline for the normalised poloidal flux ψ_n(R,z).\\n0 gives an interpolating spline.", + "type": "number", + "minimum": 0, + "default": 0.005 + }, + "smoothFpol": { + "description": "Tension of the 1D spline for the poloidal current function F(ψ)=R⋅B_T.\\n0 gives an interpolating spline.", + "type": "number", + "minimum": 0, + "default": 0.01 + }, + "smoothDens": { + "description": "Tension of the 1D spline for the electron density function n_e(ψ).\\n0 gives an interpolating spline.", + "type": "number", + "minimum": 0, + "default": 0.1 + }, + "signB": { + "description": "Force the sign of the toroidal field. One of:\\n - `+1`: counter-clockwise (viewed from above)\\n - `-1`: clockwise\\n - `0`: do not force, interpret sign according to input COCOS", + "enum": [-1, 0, 1], + "default": 0 + }, + "signI": { + "description": "Force the sign of the toroidal plasma current. One of:\\n - `+1`: counter-clockwise (viewed from above)\\n - `-1`: clockwise\\n - `0`: do not force, interpret sign according to input COCOS", + "enum": [-1, 0, 1], + "default": 0 + }, + "factB": { + "description": "Rescaling factor for the magnetic field, applied after sign forcing with `signB`.", + "type": "number", + "default": 1 + }, + "factTemp": { + "description": "Rescaling factor for the electron temperature profile.\\nThe combined effect with `factB` depends on the `scalType` parameter.\\n", + "type": "number", + "default": 1 + }, + "factDens": { + "description": "Rescaling factor for the electron density profile.\\nThe combined effect with `factB` depends on the `scalType` parameter.\\n", + "type": "number", + "default": 1 + }, + "scalType": { + "description": "Model for temperature and density rescaling with the magnetic field. One of:\\n - `OFF`: don't rescale with B\\n - `COLLISION`: preserve effective collisionality nustar:\\n n_e -> n_e⋅`factDens`⋅`factB`^(4/3)\\n T_e -> T_e⋅`factTemp`⋅`factB`^(2/3)\\n - `GREENWALD`, preserve Greenwald fraction n_e/n_GW:\\n n_e -> n_e⋅`factDens`⋅`factB`\\n T_e -> T_e⋅`factTemp`⋅`factB`", + "enum": ["OFF", "COLLISION", "GREENWALD"], + "default": "OFF" + } + } + }, + "output": { + "description": "Output data parameters", + "type": "object", + "properties": { + "rhoVar": { + "description": "Main radial coordinate to build uniform grid for ECRH&CD profiles. One of:\\n - `RHO_TOR`: ρ_t = √Φ_n (where Φ_n is the normalised toroidal flux)\\n - `RHO_POL`: ρ_p = √ψ_n (where ψ_n is the normalised poloidal flux)", + "enum": ["RHO_TOR", "RHO_POL"], + "default": "RHO_POL" + }, + "nRho": { + "description": "Number of points in the radial grid", + "type": "integer", + "minimum": 2, + "default": 501 + }, + "iStepProj": { + "description": "Step subsampling factor for the beam cross section (units 8, 12)", + "type": "integer", + "default": 5 + }, + "iStepTraj": { + "description": "Step subsampling factor for the outer rays data (unit 33)", + "type": "integer", + "default": 5 + } + } + }, + "beam": { + "description": "Beam launch parameters setup from configuration file", + "type": "object", + "properties": { + "filename": { + "description": "Filepath (relative to the parameters file) for the beam properties description, possibly in a system with one or more degrees of freedom", + "type": "string" + }, + "nSteerAxes": { + "description": "Number of degrees of freedom in the system described by the configuration file", + "type": "integer", + "minimum": 0, + "maximum": 2 + }, + "steering": { + "description": "Steering values used to select the beam parameters from the configuration file. The number of required values is set with the `nSteerAxis` parameter. Units [a.u.]", + "$ref": "number1d" + }, + "index": { + "description": "Position index of the selected beam in the configuration file, 1-based.", + "type": "integer", + "minimum": 1, + "default": 1 + }, + "power": {"$ref": "beam#/power"}, + "polarization": {"$ref": "beam#/polarization"} + } + }, + "equilibrium": { + "description": "Magnetic field configuration read from external file", + "type": "object", + "properties": { + "filename": { + "description": "Filepath (relative to the parameters file) of the equilibrium data", + "type": "string" + }, + "equilType": { + "description": "Type of magnetic equilibrium description. One of:\\n - `VACUUM`: vacuum (no plasma)\\n - `ANALYTICAL`: analytical model\\n - `EQDSK_FULL`: G-EQDSK format - data valid on the whole domain\\n - `EQDSK_PARTIAL`: G-EQDSK format - data valid only inside the LCFS", + "enum": ["VACUUM", "ANALYTICAL", "EQDSK_FULL", "EQDSK_PARTIAL"], + "default": "EQDSK_FULL" + }, + "cocos": { + "description": "COCOS index of the equilibrium data (G-EQDSK only)", + "$ref" : "cocos", + "default": 3 + }, + "hasPsiNorm": { + "description": "Whether the 2D poloidal flux is normalised (G-EQDSK only)", + "type": "boolean", + "default": false + }, + "hasDesc": { + "description": "Whether the header starts with a description/identification string (G-EQDSK only)", + "type": "boolean", + "default": true + }, + "hasFreeFormat": { + "description": "Whether the records have variable length (G-EQDSK only)\\nNote: some non-compliant programs output numbers formatted with variable\\nlength instead of using the single (5e16.9) specifier.", + "type": "boolean", + "default": false + } + } + }, + "profiles": { + "description": "(input) plasma profiles parameters", + "type": "object", + "properties": { + "filename": { + "description": "Filepath (relative to the parameters file) of the plasma profiles data", + "type": "string" + }, + "profType": { + "description": "Type of plasma profiles description. One of:\\n - `ANALYTIC`: analytical model\\n - `NUMERIC: tabulated data", + "enum": ["ANALYTIC", "NUMERIC"], + "default": "NUMERIC" + }, + "rhoDef": { + "description": "Plasma profiles radial coordinate in input file\\n(`profType`==`NUMERIC` only). One of:\\n - `RHO_TOR`: ρ_t = √Φ_n (where Φ_n is the normalised toroidal flux)\\n - `RHO_POL`: ρ_p = √ψ_n (where ψ_n is the normalised poloidal flux)\\n - `PSI_N`: normalised poloidal flux ψ_n", + "enum": ["RHO_TOR", "RHO_POL", "PSI_N"], + "default": "PSI_N" + } + } + }, + "misc": { + "description": "Other parameters", + "type": "object", + "properties": { + "rWall": { + "description": "Radius of the inner wall. Used to build a simple cylindrical limiter for\\nreflections (only when `nPass`<0), and to discard invalid solutions\\n(at R < `rWall`) when reconstructing the flux surfaces contours. Units [m]", + "type": "number", + "minimum": 0, + "default": 0 + } + } + } + } +} \ No newline at end of file diff --git a/schemas/rzpolygon.schema.json b/schemas/rzpolygon.schema.json new file mode 100644 index 0000000..201cb59 --- /dev/null +++ b/schemas/rzpolygon.schema.json @@ -0,0 +1,19 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/rzpolygon", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "Polygon in the poloidal Rz-plane", + "type": "object", + "properties": { + "r": { + "description": "Radial coordinate. Units [m]", + "allOf": [ + {"$ref": "number1d"}, + {"items": {"minimum": 0}} + ] + }, + "z": { + "description": "Vertical coordinate. Units [m]", + "$ref": "number1d" + } + } +} diff --git a/schemas/validate.py b/schemas/validate.py new file mode 100644 index 0000000..694f5f2 --- /dev/null +++ b/schemas/validate.py @@ -0,0 +1,53 @@ +import argparse +import json +import jsonschema +import jsonschema.protocols +import jsonschema.validators +from jsonschema import Draft202012Validator +from jsonschema.exceptions import SchemaError, ValidationError +from referencing import Registry, Resource +from referencing.jsonschema import DRAFT202012 + +parser = argparse.ArgumentParser( + description="Validate a JSON document against a JSON schema" +) +parser.add_argument("file", type=str, help="the JSON file to validate") +parser.add_argument("-s", "--schema", required=True, + help="file containing the schema definition." + ) +parser.add_argument("-r", "--resource", action="append", default=[], + help="additional schemas to be added to the registry " + + "for reference resolution. Multiple schema files can " + + "be added by specifying the option multiple times.") + +if __name__ == "__main__": + args = parser.parse_args() + # Load the schema and any additional resources and add them to the registry for reference resolution + # The schema is last in the list: it will remain stored in schema_dict at the end of the for loop + registry = Registry() + for schema_file in (*args.resource, args.schema): + with open(file=schema_file, mode="r") as f: + schema = json.load(f) + resource = Resource.from_contents( + contents=schema, + default_specification=DRAFT202012 + ) + registry = resource @ registry + # Load the JSON document to validate + with open(file=args.file, mode="r") as f: + document = json.load(f) + # Set the validator with the desired schema and check the schema itself before validating the document + validator = jsonschema.validators.validator_for(schema)(schema, registry=registry) + try: + validator.check_schema(schema) + except SchemaError as e: + print("Schema check failed.") + print(f"{e.message}") + exit(1) + try: + validator.validate(document) + print("Valid!") + except ValidationError as e: + print("Validation failed.") + print(f"{e.message}") + exit(1) diff --git a/schemas/wall.schema.json b/schemas/wall.schema.json new file mode 100644 index 0000000..5af27e0 --- /dev/null +++ b/schemas/wall.schema.json @@ -0,0 +1,12 @@ +{ + "$id": "https://www.istp-cnr.it/gray/schemas/wall", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "title": "First wall description", + "type": "object", + "properties": { + "contour2d": { + "description": "Axisymmetric approximation. The polygon is assumed closed even if the first and the last point do not match.", + "$ref": "rzpolygon" + } + } +}