diff --git a/apl_build.js b/apl_build.js new file mode 100644 index 0000000..08bd60a --- /dev/null +++ b/apl_build.js @@ -0,0 +1,19 @@ +Handlebars.registerHelper('replaceAll', function (string, search, replacement) { + return (string !== undefined && string !== null) ? string.replaceAll(search, replacement) : ''; +}); + +Handlebars.registerHelper('pad', function (num, size) { + return String(num).padStart(size, '0'); +}); + +Handlebars.registerHelper('joinarray', function (a, sep, prefix=false) { + if (!a || !Array.isArray(a) || a.length === 0) { + // Handle empty or undefined array + return ''; + } + const result = a.join(sep); + if (result !== '' && prefix) { + return `${sep}${result}`; + } + return result; +}); diff --git a/apl_build.json b/apl_build.json new file mode 100644 index 0000000..a6e1cc1 --- /dev/null +++ b/apl_build.json @@ -0,0 +1,594 @@ +{ + "title": "JHU/APL Builds", + "description": "Metadata for a single, NASA STRI build using a metals additive manufacturing printer", + "type": "object", + "definitions": { + "igsnMetadata": { + "id": "igsnMetadata", + "type": "object", + "format": "grid-strict", + "title": "Sample IGSN Creation", + "options": { + "grid_columns": 12, + "titleHidden": true + }, + "properties": { + "_text1": { + "format": "hidden", + "type": "string", + "title": "IGSN metadata", + "description": "

This section gathers necessary information to create an IGSNs for each sample created during the build

", + "propertyOrder": 0, + "options": { + "grid_columns": 12, + "grid_break": true + } + }, + "institution": { + "type": "string", + "description": "Originating Institution", + "enum": [ + "AP" + ], + "default": "AP", + "propertyOrder": 1, + "options": { + "titleHidden": true, + "grid_columns": 3, + "enum_titles": [ + "Johns Hopkins University Applied Physics Laboratory (APL)" + ] + } + }, + "groupJH": { + "type": "string", + "description": "Group within the institution", + "enum": [ + "L" + ], + "default": "C", + "propertyOrder": 2, + "options": { + "titleHidden": true, + "grid_columns": 3, + "enum_titles": [ + "Applied Physics Laboratory" + ] + } + }, + "material": { + "type": "string", + "description": "Material Type", + "enum": [ + "MA" + ], + "default": "MA", + "propertyOrder": 3, + "options": { + "titleHidden": true, + "grid_columns": 3, + "enum_titles": [ + "metals and alloys" + ] + } + }, + "submaterialMA": { + "type": "string", + "description": "Material Subtype", + "enum": [ + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L" + ], + "propertyOrder": 4, + "default": "L", + "options": { + "titleHidden": true, + "dependencies": { + "material": "MA" + }, + "enum_titles": [ + "Al-containing", + "commercially puremetals", + "Cu-containing", + "Fe-containing", + "intermetallics", + "Mg-containing", + "Ni-containing", + "rare earth", + "refactories", + "steels", + "superalloys", + "Ti-containing" + ], + "grid_columns": 3, + "grid_break": true + } + }, + "title": { + "type": "string", + "title": "Sample Name", + "template": "{{replaceAll params.runDate '-' ''}}_{{params.location}}_{{material}}_QC{{pad buildNumber 2}}{{joinarray extraInfo '_' true}}", + "watch": { + "params": "root.userParameters", + "material": "root.buildPlate.material", + "buildNumber": "root.buildNumber", + "extraInfo": "root.extraInfo" + }, + "readOnly": true, + "propertyOrder": 5, + "options": { + "grid_columns": 12, + "titleHidden": true, + "hidden": true + } + }, + "attributes": { + "type": "object", + "propertyOrder": 6, + "properties": { + "alternateIdentifiers": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "properties": { + "alternateIdentifier": { + "type": "string", + "propertyOrder": 1, + "watch": { + "sampleId": "root.printerBuildID" + }, + "template": "{{sampleId}}" + }, + "alternateIdentifierType": { + "type": "string", + "propertyOrder": 2, + "default": "local" + } + } + } + } + }, + "options": { + "grid_columns": 12, + "grid_break": true, + "hidden": true + } + } + } + }, + "igsn": { + "id": "igsn", + "type": "object", + "format": "grid-strict", + "title": "Sample IGSN Creation", + "options": { + "grid_columns": 12, + "titleHidden": true + }, + "properties": { + "suffix": { + "type": "string", + "propertyOrder": 1, + "options": { + "hidden": true, + "grid_columns": 12 + }, + "default": "" + }, + "prefix": { + "type": "string", + "propertyOrder": 2, + "description": "The unique identifier for the build.", + "hidden": true, + "template": "{{org}}{{gJH}}{{material}}{{sMA}}", + "watch": { + "org": "root.igsnMeta.institution", + "gJH": "root.igsnMeta.groupJH", + "material": "root.igsnMeta.material", + "sMA": "root.igsnMeta.submaterialMA" + }, + "options": { + "grid_columns": 12, + "hidden": true + } + }, + "request": { + "type": "boolean", + "propertyOrder": 3, + "title": "Request IGSN", + "description": "Whether to request an IGSN.", + "default": true, + "options": { + "hidden": true, + "grid_columns": 12 + } + }, + "track": { + "type": "boolean", + "propertyOrder": 4, + "title": "Track IGSN", + "description": "Whether to create Sample tracking.", + "default": true, + "options": { + "hidden": true, + "grid_columns": 12 + } + }, + "field": { + "type": "string", + "propertyOrder": 5, + "title": "Field with IGSN prefix", + "const": "assignedIGSN", + "default": "assignedIGSN", + "options": { + "hidden": true, + "grid_columns": 12 + } + }, + "batch": { + "type": "object", + "propertyOrder": 6, + "properties": { + "method": { + "type": "string", + "propertyOrder": 1, + "title": "Batching Method", + "default": "croom", + "options": { + "hidden": true + } + } + } + } + } + }, + "geometry": { + "type": "object", + "format": "grid-strict", + "properties": { + "geometryType": { + "title": "Geometry Type", + "type": "string", + "enum": [ + "AXF", + "RBF", + "MIC", + "TEN", + "4PB", + "COM", + "POW" + ], + "options": { + "grid_columns": 6, + "enum_titles": [ + "Axial Fatigue (AXF)", + "Rotating Beam Fatigue (RBF)", + "Microstructure (MIC)", + "Axial Tension (TEN)", + "Four point bend (4PB)", + "Composition (COM)", + "Powder (POW)" + ] + }, + "propertyOrder": 0, + "description": "The geometry type available for the build" + }, + "count": { + "title": "Count", + "type": "number", + "minimum": 1, + "maximum": 1000, + "propertyOrder": 1, + "options": { + "grid_columns": 6 + }, + "description": "The number of parts that can be built with this geometry type" + } + }, + "description": "Geometry type for the build" + }, + "fileUpload": { + "title": "File", + "type": "object", + "format": "grid", + "properties": { + "file": { + "title": "Upload file", + "type": "string", + "propertyOrder": 1 + }, + "button": { + "title": "Browse", + "format": "button", + "options": { + "button": { + "action": "button1CB", + "uploadFor": "file" + } + }, + "propertyOrder": 2 + }, + "targetPath": { + "type": "string", + "title": "Target Path", + "watch": { + "path": "root.printerBuildID" + }, + "template": "{{path}}", + "options": { + "hidden": true + }, + "propertyOrder": 3 + } + } + }, + "keyValue": { + "title": "Misc. metadata", + "type": "object", + "format": "grid", + "properties": { + "key": { + "title": "Key", + "type": "string", + "propertyOrder": 0 + }, + "value": { + "title": "Value", + "type": "string", + "propertyOrder": 1 + } + }, + "required": [ + "key", + "value" + ] + } + }, + "properties": { + "assignedIGSN": { + "type": "string", + "propertyOrder": 0, + "template": "{{prefix}}{{suffix}}", + "watch": { + "prefix": "igsn.prefix", + "suffix": "igsn.suffix" + }, + "options": { + "hidden": true, + "grid_columns": 12 + } + }, + "igsnMeta": { + "$ref": "#/definitions/igsnMetadata", + "propertyOrder": 0, + "options": { + "hidden": false + } + }, + "igsn": { + "$ref": "#/definitions/igsn", + "propertyOrder": 0, + "options": { + "hidden": true + } + }, + "printerBuildID": { + "title": "Printer Build ID", + "description": "Automatically generated identifier for the printer build", + "type": "string", + "template": "{{replaceAll params.runDate '-' ''}}_{{params.location}}_{{material}}_QC{{pad buildNumber 2}}{{joinarray extraInfo '_' true}}", + "watch": { + "params": "root.userParameters", + "material": "root.buildPlate.material", + "buildNumber": "root.buildNumber", + "extraInfo": "root.extraInfo" + }, + "readOnly": true, + "propertyOrder": 1 + }, + "buildPlate": { + "title": "Build Plate", + "type": "object", + "format": "grid", + "properties": { + "material": { + "title": "Material", + "type": "string", + "enum": [ + "Ti-6Al-4V" + ], + "default": "Ti-6Al-4V", + "propertyOrder": 0 + }, + "temperature": { + "title": "Temperature (C)", + "type": "number", + "minimum": 0, + "maximum": 450, + "propertyOrder": 1 + } + }, + "required": [ + "material", + "temperature" + ], + "propertyOrder": 2 + }, + "buildNumber": { + "title": "Build Number", + "description": "Sequential build number for the given day and location (e.g. 1 for first build of the day)", + "type": "number", + "minimum": 1, + "maximum": 100, + "default": 1, + "propertyOrder": 3 + }, + "buildMachine": { + "title": "Build Machine", + "description": "Machine used for the build", + "type": "string", + "enum": [ + "Renishaw AM500Q at APL", + "EOS M290 at CMU" + ], + "propertyOrder": 4 + }, + "rawPowderID": { + "title": "Raw Powder", + "description": "Reference to a 'Raw Powder Details' entry", + "type": "array", + "items": { + "type": "string", + "enumSource": "girder.formId:663e6d21b18fa1c426e939ab" + }, + "propertyOrder": 5 + }, + "buildGeometries": { + "title": "Build Geometries", + "description": "Available build geometries for the printer", + "type": "array", + "uniqueItems": true, + "minItems": 1, + "items": { + "headerTemplate": "Geometry {{i1}}", + "$ref": "#/definitions/geometry" + }, + "propertyOrder": 5, + "options": { + "grid_columns": 12 + }, + "format": "grid" + }, + "extraInfo": { + "title": "Extraneous Information", + "description": "Optional identifiers for split/batch numbers, etc.", + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "propertyOrder": 6 + }, + "userParameters": { + "title": "User Parameters", + "type": "object", + "format": "grid", + "properties": { + "runDate": { + "title": "Run Date", + "type": "string", + "format": "date", + "description": "Date in YYYY-MM-DD format", + "default": "2025-01-01", + "propertyOrder": 0 + }, + "runTime": { + "title": "Run Time", + "type": "string", + "format": "time", + "default": "00:00:00", + "propertyOrder": 1 + }, + "location": { + "title": "Location", + "description": "Location where the build occurred", + "type": "string", + "options": { + "enum_titles": [ + "Applied Physics Laboratory", + "Carnegie Mellon University", + "Northwestern University" + ] + }, + "default": "APL", + "enum": [ + "APL", + "CMU", + "NU" + ], + "propertyOrder": 2 + }, + "teamMembers": { + "title": "Team Members", + "type": "array", + "items": { + "type": "string", + "enum": [ + "Evan Adcock", + "Nick Lamprinakos", + "Katie O'Donnell" + ] + }, + "propertyOrder": 3 + } + }, + "required": [ + "runDate", + "runTime", + "location", + "teamMembers" + ], + "propertyOrder": 7 + }, + "buildFile": { + "title": "Build File", + "description": "Upload the build file (e.g. *.openjz)", + "$ref": "#/definitions/fileUpload", + "propertyOrder": 8 + }, + "reportFile": { + "title": "Build Report File", + "description": "Upload e.g. the EOS job quality report (PDF)", + "$ref": "#/definitions/fileUpload", + "propertyOrder": 9 + } + }, + "required": [ + "printerBuildID", + "buildMachine", + "buildNumber", + "rawPowderID", + "buildGeometries", + "userParameters", + "buildFile", + "reportFile" + ], + "if": { + "properties": { + "igsn": { + "properties": { + "request": { + "const": false + } + } + } + } + }, + "then": { + "properties": { + "igsnMeta": { + "options": { + "hidden": true + }, + "readonly": true + }, + "assignedIGSN": { + "options": { + "hidden": false + }, + "readonly": true + } + } + } +}