modules/post/reporter_automotive_assessment.mjs

// module: TRUE
import { ProtocolAssessment, DoOccupantAssessmentOccupantData, DoAssessmentOptions } from "automotive_assessments.mjs";
import { WorkflowOccupant } from "../shared/workflow_occupant.mjs";

// T/HIS script to run REPORTER version of automotive assessments workflow

/* TODO TODO TODO
 *
 * Questions for Chris:
 *
 * 1.   Why do we need all the if statements with upper_rib_irtracc_length etc?
 *      Could they be included in the WorkflowOccupant constructor? In fact,
 *      why don't they belong to the Chest or Abdomen OccupantBodyParts?
 * 2.   How do we get the Workflow class to behave when T/HIS launched from
 *      REPORTER? At the moment, it doesn't seem to check for the workflow
 *      stuff at all. I have commented it out and replaced it with hardwired
 *      JSON parsing below, for now.
 * 3.   How do you think we should trigger image generation?
 *
 */

/**
 * Carries out an assessment on the body parts specified by the
 * REPORTER template, according to the specified regulation and
 * occupant, plotting the results in T/HIS and capturing images
 * that can be loaded by the REPORTER template.
 * @param {string} f_json_name JSON filename containing user data
 * @param {string} output_dir REPORTER output directory for images etc.
 */
export function reporter_occupant_assessment(f_json_name, output_dir) {
    do_reporter_occupant_assessment(f_json_name, output_dir);
}

function do_reporter_occupant_assessment(f_json_name, output_dir) {
    /* Parse the REPORTER jobs JSON file */
    let f_job_name = `${output_dir}/report_contents.json`;
    let f_job = new File(f_job_name, File.READ);
    let job_str = "";
    let line;
    while ((line = f_job.ReadLongLine()) != undefined) {
        job_str = job_str + line;
    }
    f_job.Close();
    let jobs = JSON.parse(job_str).jobs;

    let results = [];

    /* For each REPORTER job, we need to do an occupant assessment for each
     * occupant variant i.e. to run through the process of plotting graphs for
     * e.g. Driver only, or a comparison of Driver and Passenger
     */
    for (let job of jobs) {
        for (let occ_var of job.occupant_variants) {
            let reporter_occupants_data = [];
            let num_selected_models = 1;

            for (let i = 0; i < num_selected_models; i++) {
                //let user_data_debug = Workflow.ModelUserDataFromIndex(i);
                //let model_iasdd_debug = Workflow.ModelIdFromIndex(i);
                //let unit_system_debug = Workflow.ModelUnitSystemFromIndex(i);

                /* Workflow class doesn't work for REPORTER yet so hard-wire JSON.parse for now */
                let f_json = new File(f_json_name, File.READ);
                let json_str = "";
                let line;
                while ((line = f_json.ReadLongLine()) != undefined) {
                    json_str = json_str + line;
                }
                f_json.Close();
                /* TODO currently hard-wiring parse of first workflow we find */
                let workflow = JSON.parse(json_str).workflows[0];
                let user_data = workflow.data;
                /* TODO currently hard-wiring single model M1 */
                let model_id = 1;
                let unit_system = null;
                switch (workflow.model_unit_system) {
                    case "U1":
                        unit_system = Workflow.UNIT_SYSTEM_U1;
                        break;
                    case "U2":
                        unit_system = Workflow.UNIT_SYSTEM_U2;
                        break;
                    case "U3":
                        unit_system = Workflow.UNIT_SYSTEM_U3;
                        break;
                    case "U4":
                        unit_system = Workflow.UNIT_SYSTEM_U4;
                        break;
                    case "U5":
                        unit_system = Workflow.UNIT_SYSTEM_U5;
                        break;
                    case "U6":
                        unit_system = Workflow.UNIT_SYSTEM_U6;
                        break;
                }

                /* Add user occupant data to the list if it matches the occupant variant requested in the reporter job */
                for (let o of user_data.occupants) {
                    let user_occ = WorkflowOccupant.CreateFromUserData(o);
                    for (let job_occ of occ_var.occupants) {
                        if (job_occ.position == user_occ.position && job_occ.front_rear == user_occ.front_rear) {
                            reporter_occupants_data.push(
                                new DoOccupantAssessmentOccupantData(user_occ, model_id, unit_system)
                            );
                        }
                    }
                }
            }

            if (reporter_occupants_data.length == 0) {
                ErrorMessage("No occupants selected");
                return;
            }

            let reporter_assessment_types = occ_var.assessment_types;
            if (reporter_assessment_types.length == 0) {
                ErrorMessage("No assessment types selected");
                return;
            }

            /* Create a protocol instance with the required datums */

            let protocol = ProtocolAssessment.CreateDefaultProtocol(job.regulation, job.crash_test, job.version);

            /* Options to pass to DoOccupantAssessment */

            let first_graph_id = 1;
            let first_page_id = 1;
            let blank_all = true;
            let remove_existing_graphs = true;

            let options = new DoAssessmentOptions(
                DoAssessmentOptions.GRAPH_LAYOUT_REPORTER,
                first_graph_id,
                first_page_id,
                blank_all,
                remove_existing_graphs,
                output_dir
            );

            /* Do the assessment */

            let job_occ_var_results = protocol.DoOccupantAssessment(
                reporter_occupants_data,
                reporter_assessment_types,
                options
            );

            /* Add results for this occupant variant to the overall list of results */
            for (let prop in job_occ_var_results.output) {
                results[prop] = job_occ_var_results.output[prop];
            }
        }
    }

    /* Send the results to REPORTER */

    let f_res_name = `${output_dir}/automotive_assessment_results.csv`;
    let f_res = new File(f_res_name, File.WRITE);
    for (let prop in results) {
        f_res.Writeln(
            `${prop.replace(/\s/g, "_")},${results[prop]},Result from Automotive Assessments Workflow,General`
        );
    }
    f_res.Close();
}