diff --git a/HRR - Document Analysis/HRR - Document Analysis - Medical Information Extraction.step b/HRR - Document Analysis/HRR - Document Analysis - Medical Information Extraction.step new file mode 100644 index 00000000..a3443f02 --- /dev/null +++ b/HRR - Document Analysis/HRR - Document Analysis - Medical Information Extraction.step @@ -0,0 +1 @@ +{"description":"","displayName":"HRR - Document Analysis - Medical Information Extraction.step","eTag":"\"khlla9brm8\"","flowMetadata":{"inputPorts":[],"outputPorts":[]},"metadataVersion":1,"name":"HRR - Document Analysis - Medical Information Extraction.step","properties":{},"templates":{"SAS":"/***********************************************************************************************\n\n SCRIPT: HRR - Document Analysis - Execute Information Extraction.step\n\n PURPOSE:\n This script serves as a Custom Step driver for the Medical Record Review (MRR) pipeline.\n It assembles input and output paths based on user-supplied macro variables from the UI,\n dynamically constructs the MRR JSON user config, and invokes the `%mrr_information_extraction`\n macro for full end-to-end information extraction.\n\n KEY FEATURES:\n -------------\n - Validates and parses SAS server–based input and export directory selections\n - Dynamically builds the `userConfig` JSON string using macro variables from the UI\n - Normalizes and default-fills optional flags (e.g., bookmarking, date handling)\n - Assigns and loads macro catalog for MRR pipeline execution\n - Supports both SDA and SAS input data types\n - Executes `%mrr_information_extraction` with fully resolved `userConfig` file\n\n REQUIRED MACRO VARIABLES (UI-provided):\n ---------------------------------------\n - _mrr_input_source_type [SAS:SASDATASET or SDA:MAPPINGFILE]\n - _mrr_source_data_file [SAS server file reference]\n - _mrr_output_export_directory [SAS server export directory]\n - _mrr_output_export_file_type [csv, json, xls, xlsx, sas7bdat, sashdat]\n - _mrr_macro_catalog_dirpath [SAS macro catalog directory]\n - _mrr_astore_dirpath [SAS astore models directory]\n\n OPTIONAL FLAGS & FORMATTERS:\n ----------------------------\n - _mrrStandardizedCasing [YES | NO]\n - _mrrEnableBookmarking [YES | NO]\n - _mrrFlagInvalidDates [YES | NO]\n - _mrrMinValidDate [ISO8601 date, defaults to 1930-01-01]\n - _mrrMaxValidDate [ISO8601 date, defaults to current date]\n - _mrrDateFormat [SAS date format, e.g., DATE9.]\n - _mrrDebugLevel [DEBUG | INFO | WARN | ERROR]\n\n DERIVED MACRO VARIABLES (auto-generated by this script):\n --------------------------------------------------------\n - _mrr_user_config_json [Full JSON config string]\n - _mrr_usercfg_fpath [Resolved filepath of temp user config file]\n - _mrr_src_filepath [Source file (SASDATASET or MAPPINGFILE)]\n - _mrr_export_dirpath [Export directory path]\n - _mrr_sda_fpath / _mrr_sas_fpath [Resolved file based on input source mode]\n\n\n OUTPUTS:\n --------\n - A temporary file containing the user config JSON, written to `filename usercfg`\n - Execution of `%mrr_information_extraction` using the provided `astoreDirpath`\n - Exported files written to `_mrr_export_dirpath` in the selected format\n\n DEPENDENCIES:\n -------------\n - `%mrr_information_extraction` must be available in the macro catalog\n - `%mrr_assign_sasmacro_catalog` utility macro included inline\n - Assumes all required macro variables are supplied at runtime via Custom Step UI\n\n HISTORY:\n --------\n - 2025-10-01 | mupago | | Initial creation\n - 2025-11-25 | winado | AAIMDEV-5070 | Added logic to gracefully assign SAS macro catalog\n - 2025-11-25 | winado | AAIMDEV-5069 | Refactored to use astoreDirpath instead of rootDirpath\n - 2025-12-03 | mupago | AAIMDEV-5070 | Updated parameters for astore dirpath and macro catalog \n***********************************************************************************************/\n\n/* cas;\ncas casauto;\ncaslib _all_ assign;\noptions casdatalimit=8G; */\n/* options mprint mprintnest mlogic symbolgen mautosource mlogicnest; */\n\n%put \"_mrr_input_source_type selected is:\" &_mrr_input_source_type;\n%put \"_mrrColumnNamesSASOnly_r1_c1 selected is:\" &_mrrColumnNamesSASOnly_r1_c1;\n%put \"_mrrColumnNamesSASOnly_r1_c2 selected is:\" &_mrrColumnNamesSASOnly_r1_c2;\n%put \"_mrrColumnNamesSASOnly_r1_c3 selected is:\" &_mrrColumnNamesSASOnly_r1_c3;\n%put \"_mrr_source_data_file selected is:\" &_mrr_source_data_file;\n%put \"_mrr_output_export_directory selected is:\" &_mrr_output_export_directory;\n%put \"_mrr_output_export_file_type selected is:\" &_mrr_output_export_file_type;\n%put \"_mrr_astore_directory selected is:\" &_mrr_astore_directory;\n%put \"_mrr_macro_catalog_directory selected is:\" &_mrr_macro_catalog_directory;\n\n%put \"_mrrStandardizedCasing selected is:\" &_mrrStandardizedCasing;\n%put \"_mrrFlagInvalidDates selected is:\" &_mrrFlagInvalidDates;\n%put \"_mrrEnableBookmarking selected is:\" &_mrrEnableBookmarking;\n%put \"_mrrMinValidDate selected is:\" &_mrrMinValidDate;\n%put \"_mrrMaxValidDate selected is:\" &_mrrMaxValidDate;\n%put \"_mrrDateFormat selected is:\" &_mrrDateFormat;\n%put \"_mrrDebugLevel selected is:\" &_mrrDebugLevel;\n\n/* Root Directory Location for the SAS macro directory structure within which all sas macro programs can be found */\n/* %let _mrr_root_dirpath = /aaim_shared_data/SDV/code/runuser; */\n/* %let _mrr_astore_dirpath = /aaim_shared_data/SDV/code/runuser/data/models/vta/astores; */\n\n/* Directory location where the SAS macro catalog is found */\n/* %let _mrr_macro_catalog_dirpath = /aaim_shared_data/SDV/code/runuser/src/catalog; */\n\n/* %let _mrr_worklib_dirpath_ = %sysfunc(pathname(work)); */\n\n/* Destination filepath where the userconfig json file will be written out */\n/* %let _mrr_user_cfg_file = &_mrr_worklib_dirpath_./userconfig_content.json; */\n\n/* Assign and load compiled macro catalog */\n/* libname _MRRCAT_ clear;\nlibname _MRRCAT_ \"&_mrr_macro_catalog_dirpath\";\noptions mstored sasmstore=\"_MRRCAT_\"; */\n\ndata _null_;\n\n * Check that the user provided Astore file directory is on the SAS server and not in SAS Content;\n mode_1 = kscan(\"&_mrr_astore_directory.\", 1, ':');\n\n if mode_1 EQ 'sasserver' then do;\n call symputx('_mrr_astore_dirpath', kscan(\"&_mrr_astore_directory.\", 2, ':'));\n end;\n else do;\n putLog 'ERROR: Please ensure that the selected source directory is on the SAS server.';\n abort 40;\n end;\n\n * Check that the user provided macro catalog directory is on the SAS server and not in SAS Content;\n mode_2 = kscan(\"&_mrr_macro_catalog_directory.\", 1, ':');\n \n if mode_2 EQ 'sasserver' then do;\n call symputx('_mrr_macro_catalog_dirpath', kscan(\"&_mrr_macro_catalog_directory.\", 2, ':'));\n end;\n else do;\n putLog 'ERROR: Please ensure that the selected export directory is on the SAS server.';\n abort 41;\n end;\n\nrun;\n\n/* Logic to gracefully establish SAS macro catalog accessibility */\n%macro mrr_assign_sasmacro_catalog(libref=_MRRCAT_, dirpath=);\n\n %put \"dirpath passed into macro catalog assignment module is: \" &dirpath.;\n %put \"libref passed into macro catalog assingment module is:\" &libref.; \n\n /* Ensure libref meets length requirement */\n %if %klength(&libref.) > 8 %then %do;\n %put ERROR: SAS macro catalog libref <&libref> supplied to mrr_assign_sasmacro_catalog must be <= 8 characters long!;\n %return;\n %end;\n\n /* Determine if SAS macro catalog already exists from prior execution */\n proc sql noprint; \n select count(distinct libname) \n into: mrr_sasmacro_catalog_exists \n from dictionary.libnames \n where kupcase(kstrip(libname)) = kupcase(kstrip(\"&libref\"));\n quit;\n\n /* If it exists then clear it to avoid error */\n %if &mrr_sasmacro_catalog_exists. = 1 %then %do;\n %sysmstoreclear;\n %end;\n\n /* Now assign and load compiled macro catalog */\n libname &libref. &dirpath.;\n options mstored sasmstore=\"&libref\";\n\n /* Check if it exists now after assignment */\n\n %put \"Checking if macro catalog now exists and is accessible or not\";\n\n proc sql; \n select count(distinct libname) \n into: mrr_sasmacro_catalog_exists \n from dictionary.libnames \n where kupcase(kstrip(libname)) = kupcase(kstrip(\"&libref\"));\n quit;\n\n %put \"mrr_sasmacro_catalog_exists macro variable is now set to: \" &mrr_sasmacro_catalog_exists. \" after the library invocation step\";\n\n%mend mrr_assign_sasmacro_catalog;\n\n/* Assign and load compiled macro catalog */\n%mrr_assign_sasmacro_catalog(libref=_MRRCAT_, dirpath=\"&_mrr_macro_catalog_dirpath.\");\n\n* _mrr_ is short for Execute MRR Batch, where MRR stands for SAS Medical Record Review;\ndata _null_;\n\n * Extract the first argument from the Input Source Type parameter to be passed on to the json config file;\n call symputx('_mrr_input_source', kscan(\"&_mrr_input_source_type.\", 1, ':'));\n\n * Check that the user provided a source (input) directory on the SAS server and not in SAS Content;\n mode_1 = kscan(\"&_mrr_source_data_file.\", 1, ':');\n if mode_1 EQ 'sasserver' then do;\n call symputx('_mrr_src_filepath', kscan(\"&_mrr_source_data_file.\", 2, ':'));\n end;\n else do;\n putLog 'ERROR: Please ensure that the selected source directory is on the SAS server.';\n abort 42;\n end;\n\n * Check that the user provided a export (output) directory on the SAS server and not in SAS Content;\n mode_2 = kscan(\"&_mrr_output_export_directory.\", 1, ':');\n\n if mode_2 EQ 'sasserver' then do;\n call symputx('_mrr_export_dirpath', kscan(\"&_mrr_output_export_directory.\", 2, ':'));\n end;\n else do;\n putLog 'ERROR: Please ensure that the selected export directory is on the SAS server.';\n abort 43;\n end;\n\nrun;\n\n%put \"source file path assigned value is:\" &_mrr_src_filepath;\n%put \"export directory path assigned value is:\" &_mrr_export_dirpath;\n\n/* Conditionally populate the filepath for either the SAS or SDA specific input data mode */\n\n%if %kupcase(&_mrr_input_source) = SDA %then %do;\n %let _mrr_sda_fpath = &_mrr_src_filepath;\n %let _mrr_sas_fpath =;\n%end;\n\n%if %kupcase(&_mrr_input_source) = SAS %then %do;\n %let _mrr_sas_fpath = &_mrr_src_filepath;\n %let _mrr_sda_fpath=;\n%end;\n\n%if %kupcase(_mrrFlagInvalidDates) = YES %then %do;\n %let _mrrFlagInvalidDates = true;\n%end;\n\n%else %do;\n %let _mrrFlagInvalidDates = false;\n%end;\n\n%if %kupcase(_mrrEnableBookmarking) = YES %then %do;\n %let _mrrEnableBookmarking = true;\n%end;\n%else %do;\n %let _mrrEnableBookmarking = false;\n%end;\n\n%if &_mrrMinValidDate = %then %do; \n %let _mrrMinValidDate = 1930-01-01; \n%end;\n\n%if &_mrrMaxValidDate = %then %do; \n %let _mrrMaxValidDate = CURRENTDATE;\n%end;\n\ndata _null_;\n /* Convert character ISO date to SAS date and reformat */\n minValidDate_num = input(\"&_mrrMinValidDate\", yymmdd10.);\n formatted_MinValidDate = put(minValidDate_num, date9.);\n call symputx('_mrrMinValidDate', formatted_MinValidDate);\nrun;\n\n%if &_mrrMaxValidDate ne CURRENTDATE %then %do;\n\n data _null_;\n /* Convert character ISO date to SAS date and reformat */\n maxValidDate_num = input(\"&_mrrMaxValidDate\", yymmdd10.);\n formatted_MaxValidDate = put(maxValidDate_num, date9.);\n call symputx('_mrrMaxValidDate', formatted_MaxValidDate);\n run;\n\n%end;\n\n%put \"_mrr_sda_fpath populated as:\" &_mrr_sda_fpath;\n%put \"_mrr_sas_fpath populated as:\" &_mrr_sas_fpath;\n%put \"_mrrFlagInvalidDates populated as:\" &_mrrFlagInvalidDates;\n%put \"_mrrEnableBookmarking populated as:\" &_mrrEnableBookmarking;\n%put \"_mrrMinValidDate populated as:\" &_mrrMinValidDate;\n%put \"_mrrMaxValidDate populated as:\" &_mrrMaxValidDate;\n\n/* Dynamically create the user config json string in a sas macro using the parameters passed on from the Custom Step */\n\n%let _mrr_user_config_json=\n{\n \"global\": [\n {\n \"main\": [\n {\n \"id\": \"1000\",\n\t \"datamode\": \"ECE\",\n \"persist_scoring_data\": \"true\"\n }\n ],\n \"parms\": [\n {\n \"sub\": [\n {\n \"id\": \"1001\",\n \"name\": \"output_flat_files\",\n \"type\": \"flag\",\n \"value\": \"true\"\n },\n {\n \"id\": \"1002\",\n \"name\": \"flat_file_dirpath\",\n \"type\": \"directory_path\",\n \"value\": \"%superq(_mrr_export_dirpath)\"\n },\n {\n \"id\": \"1003\",\n \"name\": \"flat_file_format\",\n \"type\": \"file_format\",\n \"value\": \"%superq(_mrr_output_export_file_type)\"\n }\n ]\n }\n ]\n }\n ],\n \"import\": [\n {\n \"main\": [\n {\n \"id\": \"2000\",\n \"import_source\": \"%superq(_mrr_input_source)\"\n }\n ],\n \"parms\": [\n {\n \"id\": \"2010\",\n \"source\": \"SDA\",\n \"datatype\": \"OCRFILE\",\n \"method\": \"MAPPINGFILE\",\n \"description\": \"Loads OCR output produced by the SAS Document Analysis (SDA) process\",\n \"sda_filepath\": \"%superq(_mrr_sda_fpath)\"\n },\n {\n \"id\": \"2020\",\n \"source\": \"SAS\",\n \"datatype\": \"DATASET\",\n \"method\": \"DATAFILE\",\n \"description\": \"Loads input dataset from a SAS datafile\",\n \"sas_filepath\": \"%superq(_mrr_sas_fpath)\",\n \"sub\": [\n {\n \"id\": \"2021\",\n \"name\": \"document_id\",\n \"type\": \"column_name\",\n \"value\": \"%superq(_mrrColumnNamesSASOnly_r1_c1)\"\n },\n {\n \"id\": \"2022\",\n \"name\": \"document_text\",\n \"type\": \"column_name\",\n \"value\": \"%superq(_mrrColumnNamesSASOnly_r1_c2)\"\n },\n {\n \"id\": \"2023\",\n \"name\": \"document_page_number\",\n \"type\": \"column_name\",\n \"value\": \"%superq(_mrrColumnNamesSASOnly_r1_c3)\"\n }\n ]\n }\n ]\n }\n ],\n \"std\": [\n {\n \"main\": [\n {\n \"id\": \"3000\",\n \"standardized_casing\": \"%superq(_mrrStandardizedCasing)\",\n \"enable_bookmarking\": \"%superq(_mrrEnableBookmarking)\"\n }\n ],\n \"parms\": [\n {\n \"sub\": [\n {\n \"id\": \"3001\",\n \"name\": \"date_format\",\n \"type\": \"sas_format\",\n \"value\": \"%superq(_mrrDateFormat)\"\n },\n {\n \"id\": \"3002\",\n \"name\": \"flag_invalid_dates\",\n \"type\": \"flag\",\n \"value\": \"%superq(_mrrFlagInvalidDates)\"\n },\n {\n \"id\": \"3003\",\n \"name\": \"min_valid_date\",\n \"type\": \"string\",\n \"value\": \"%superq(_mrrMinValidDate)\"\n },\n {\n \"id\": \"3004\",\n \"name\": \"max_valid_date\",\n \"type\": \"string\",\n \"value\": \"%superq(_mrrMaxValidDate)\"\n }\n ]\n }\n ]\n }\n ]\n}\n;\n\n/* Assign a temporary fileref named 'usercfg' */\nfilename usercfg temp;\n\n/* Write json content to the target directory location */ \ndata _null_ ;\n file usercfg ;\n length jsonstring $32767 ;\n jsonstring = symget('_mrr_user_config_json') ;\n jsonlen = klength(ktrim(kleft(jsonstring))) ;\n put jsonstring $varying. jsonlen ;\nrun ;\n\n/* Write out the temp file to the log just to verify the contents */\ndata _null_;\n infile usercfg;\n\tinput ;\n put \"Start of the user config file in the log\";\n\tput _infile_;\n put \"End of the user config file in the log\";\nrun;\n\n/* Extract the fullpath of the temp file to a macro variable to pass as a parameter to the macro function */\n%let _mrr_usercfg_fpath = %sysfunc(pathname(usercfg));\n\n%put \"The _mrr_usercfg_fpath macro value assigned as:\" &_mrr_usercfg_fpath;\n\n/* Execute MRR end-to-end information extraction */\n%mrr_information_extraction(userConfig=&_mrr_usercfg_fpath, astoreDirpath=&_mrr_astore_dirpath., loglevel=&_mrrDebugLevel.); \n\nlibname _MRROUT_ clear;\nlibname _MRROUT_ \"&_mrr_export_dirpath.\";\n\n/* Clear the temporary fileref - usercfg */\nfilename usercfg clear;"},"type":"code","ui":"{\n\t\"showPageContentOnly\": true,\n\t\"pages\": [\n\t\t{\n\t\t\t\"id\": \"_mrrOptionsPage\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"Options\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"_mrr_options_page_text\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"SAS Studio Custom Step for executing the SAS Document Analysis Health Record Review information extraction process. \\n\\nAt a minimum, user must specify a folder containing either the SAS or SDA file to be processed, the output directory to export results, and the desired file type format for the exported results.\\n\\nThe source directory should be located on the server file system (not in SAS Content). \\n\\nIf using SAS as the input source, the following file extensions are supported: [sas7bdat, sashdat]. If using the mapping output from the upstream SDA OCR process, the following file types are supported: [csv, xlsx].\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"_mrr_Main_Inputs\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Main Inputs (Required)\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrr_input_source_type\",\n\t\t\t\t\t\t\t\"type\": \"radiogroup\",\n\t\t\t\t\t\t\t\"label\": \"Input Source Type:\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"SDA : SAS Document Analysis OCR Output File (csv, xls, xlsx)\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"SAS : SAS Dataset File (sas7bdat or sashdat)\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrrColumnNamesSASOnly\",\n\t\t\t\t\t\t\t\"type\": \"optiontable\",\n\t\t\t\t\t\t\t\"label\": \"Column Names (Only required if input source is SAS)\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"tabletype\": \"authorboth\",\n\t\t\t\t\t\t\t\"initialrowcount\": 1,\n\t\t\t\t\t\t\t\"min\": null,\n\t\t\t\t\t\t\t\"max\": null,\n\t\t\t\t\t\t\t\"showcolumnlabels\": true,\n\t\t\t\t\t\t\t\"columns\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"_mrr_document_id\",\n\t\t\t\t\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\t\t\t\t\"label\": \" Document ID Field\",\n\t\t\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\t\t\"value\": \"docid\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"_mrr_document_text\",\n\t\t\t\t\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Document Text Field\",\n\t\t\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\t\t\"value\": \"doctext\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"id\": \"_mrr_document_page_number\",\n\t\t\t\t\t\t\t\t\t\"type\": \"textfield\",\n\t\t\t\t\t\t\t\t\t\"label\": \"Document Page Number\",\n\t\t\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\t\t\"value\": null\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"visible\": [\n\t\t\t\t\t\t\t\t\"$_mrr_input_source_type\",\n\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\"SAS : SAS Dataset File (sas7bdat or sashdat)\"\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"repeatref\": null,\n\t\t\t\t\t\t\t\"enabled\": [\n\t\t\t\t\t\t\t\t\"$_mrr_input_source_type\",\n\t\t\t\t\t\t\t\t\"=\",\n\t\t\t\t\t\t\t\t\"SAS : SAS Dataset File (sas7bdat or sashdat)\"\n\t\t\t\t\t\t\t]\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrr_source_data_file\",\n\t\t\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\t\t\"label\": \"Input Source File:\",\n\t\t\t\t\t\t\t\"pathtype\": \"file\",\n\t\t\t\t\t\t\t\"placeholder\": \"Select the input file from directory path\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrr_output_export_directory\",\n\t\t\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\t\t\"label\": \"Export Directory Path:\",\n\t\t\t\t\t\t\t\"pathtype\": \"folder\",\n\t\t\t\t\t\t\t\"placeholder\": \"Select the export directory path to write output file\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrr_output_export_file_type\",\n\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\"label\": \"Export File Type:\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"csv\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"xlsx\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"xls\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"sas7bdat\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"sashdat\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"json\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"placeholder\": \"Select the output file type\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrr_astore_directory\",\n\t\t\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\t\t\"label\": \"Astore File(s) Directory Path: \",\n\t\t\t\t\t\t\t\"pathtype\": \"folder\",\n\t\t\t\t\t\t\t\"placeholder\": \"Select the model astore file(s) directory path\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrr_macro_catalog_directory\",\n\t\t\t\t\t\t\t\"type\": \"path\",\n\t\t\t\t\t\t\t\"label\": \"SAS Macro Catalog Directory Path:\",\n\t\t\t\t\t\t\t\"pathtype\": \"folder\",\n\t\t\t\t\t\t\t\"placeholder\": \"Select the macro catalog directory path\",\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"_mrr_additional_options\",\n\t\t\t\t\t\"type\": \"section\",\n\t\t\t\t\t\"label\": \"Additional Inputs (Optional)\",\n\t\t\t\t\t\"open\": true,\n\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\"children\": [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrrStandardizedCasing\",\n\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\"label\": \"Standardized Key-Value Casing\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"lowcase\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"upcase\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"propcase\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"required\": true,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrrFlagInvalidDates\",\n\t\t\t\t\t\t\t\"type\": \"radiogroup\",\n\t\t\t\t\t\t\t\"label\": \"Flag Invalid Dates?\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"Yes\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"No\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrrEnableBookmarking\",\n\t\t\t\t\t\t\t\"type\": \"radiogroup\",\n\t\t\t\t\t\t\t\"label\": \"Enable Bookmarking? (Only supported when using SDA as input source)\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"Yes\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"No\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrrMinValidDate\",\n\t\t\t\t\t\t\t\"type\": \"datetime\",\n\t\t\t\t\t\t\t\"label\": \"Minimum Valid Date (Default: Jan 1, 1930)\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\t\t\"min\": \"1930-01-01\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrrMaxValidDate\",\n\t\t\t\t\t\t\t\"type\": \"datetime\",\n\t\t\t\t\t\t\t\"label\": \"Maximum Valid Date (Default: CURRENTDATE)\",\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"visible\": \"\",\n\t\t\t\t\t\t\t\"min\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrrDateFormat\",\n\t\t\t\t\t\t\t\"type\": \"dropdown\",\n\t\t\t\t\t\t\t\"label\": \"Desired Date Format (Default: MMDDYY10.)\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DATE9.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DDMMYY.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DDMMYY10.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DDMMYYD.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DDMMYYD10.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DDMMYYN8.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DDNNTTP10.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DDMMYYS10.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"MMDDYY.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"MMDDYY10.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"MMDDYYD.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"MMDDYYD10.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"MMDDYYP.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"MMDDYYP10.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"MMDDYYS.\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"MMDDYYS10.\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"required\": false,\n\t\t\t\t\t\t\t\"placeholder\": \"\",\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"id\": \"_mrrDebugLevel\",\n\t\t\t\t\t\t\t\"type\": \"radiogroup\",\n\t\t\t\t\t\t\t\"label\": \"Desired Log Level:\",\n\t\t\t\t\t\t\t\"items\": [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"INFO\"\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\"value\": \"DEBUG\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"id\": \"_mrrAboutPage\",\n\t\t\t\"type\": \"page\",\n\t\t\t\"label\": \"About\",\n\t\t\t\"children\": [\n\t\t\t\t{\n\t\t\t\t\t\"id\": \"_mrr_about_page_text\",\n\t\t\t\t\t\"type\": \"text\",\n\t\t\t\t\t\"text\": \"SAS Document Analysis - Execute Batch MRR Process step\\n==========\\n\\nThe \\\"SAS Document Analysis - Execute Batch MRR Process\\\" custom step enables to run a full batch job, without the need to write any code. It can also be run inside a flow with the \\\"OCR - Document Analysis - Execute Batch OCR Process\\\" custom step to seamlessly integrate the OCR and MRR processes to run in sequence.\\n\\nThe location of the generated output will be displayed for after running this step.\\n\",\n\t\t\t\t\t\"visible\": \"\"\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t],\n\t\"syntaxversion\": \"1.3.0\",\n\t\"values\": {\n\t\t\"_mrr_input_source_type\": {\n\t\t\t\"value\": \"SDA : SAS Document Analysis OCR Output File (csv, xls, xlsx)\"\n\t\t},\n\t\t\"_mrrColumnNamesSASOnly\": null,\n\t\t\"_mrr_source_data_file\": \"\",\n\t\t\"_mrr_output_export_directory\": \"\",\n\t\t\"_mrr_output_export_file_type\": null,\n\t\t\"_mrr_astore_directory\": \"\",\n\t\t\"_mrr_macro_catalog_directory\": \"\",\n\t\t\"_mrrStandardizedCasing\": {\n\t\t\t\"value\": \"lowcase\"\n\t\t},\n\t\t\"_mrrFlagInvalidDates\": {\n\t\t\t\"value\": \"Yes\"\n\t\t},\n\t\t\"_mrrEnableBookmarking\": {\n\t\t\t\"value\": \"No\"\n\t\t},\n\t\t\"_mrrMinValidDate\": \"\",\n\t\t\"_mrrMaxValidDate\": null,\n\t\t\"_mrrDateFormat\": {\n\t\t\t\"value\": \"MMDDYY10.\"\n\t\t},\n\t\t\"_mrrDebugLevel\": {\n\t\t\t\"value\": \"INFO\"\n\t\t}\n\t},\n\t\"promptHierarchies\": []\n}"} \ No newline at end of file diff --git a/HRR - Document Analysis/README.md b/HRR - Document Analysis/README.md new file mode 100644 index 00000000..b4b14864 --- /dev/null +++ b/HRR - Document Analysis/README.md @@ -0,0 +1,49 @@ +# HRR - Document Analysis + +## Description + +SAS Studio Custom Step for executing the SAS Document Analysis Health Record information extraction process. This custom step is provided to enable point-and-click usage of the functionality available as part of the [Health Record Review](https://www.sas.com/en_us/solutions/ai/models.html) offering from within the SAS Studio interface. + +## Required Inputs + +At a minimum, user must specify the following to execute this custom step: + + - a folder / directory containing either the SAS or SDA file to be processed, + - an output folder / directory to export results, + - a desired file type format for the exported results, + - a folder / directory containing model astore files and + - a folder / directory containing SAS macro catalog + +The source directory should be located on the server file system (not in SAS Content). + +If using SAS as the input source, the following file extensions are supported: [sas7bdat, sashdat]. If using the mapping output from the upstream SDA OCR process, the following file types are supported: [csv, xlsx]. + +## User Interface + +* ### HRR - Document Analysis - Medical Information - Options Page - Main Inputs ### + + ![](img/hrr_document_analysis_medical_information_extraction_options_1.png) + +* ### HRR - Document Analysis - Medical Information - Options Page - Additional Inputs (Optional) ### + + ![](img/hrr_document_analysis_medical_information_extraction_options_2.png) + +## Requirements + +- SAS Viya 2025.12 or later +- A license for SAS Document Analysis is required + +## Settings + +For more information about the different settings please refer to the SAS documentation linked below. + +## Documentation +- [SAS Document Analysis documentation](https://go.documentation.sas.com/doc/en/aaimdacdc/default/aaimdawlcm/home.htm) +- [Custom step documentation](https://github.com/sassoftware/sas-studio-custom-steps/tree/main/HRR%20-%20Document%20Analysis) + +## Change Log + +### HRR - Document Analysis - Medical Information Extraction + +* Version 1.0 (08DEC2025) + * Initial version \ No newline at end of file diff --git a/HRR - Document Analysis/img/hrr_document_analysis_medical_information_extraction_options_1.png b/HRR - Document Analysis/img/hrr_document_analysis_medical_information_extraction_options_1.png new file mode 100644 index 00000000..1eaa8cb8 Binary files /dev/null and b/HRR - Document Analysis/img/hrr_document_analysis_medical_information_extraction_options_1.png differ diff --git a/HRR - Document Analysis/img/hrr_document_analysis_medical_information_extraction_options_2.png b/HRR - Document Analysis/img/hrr_document_analysis_medical_information_extraction_options_2.png new file mode 100644 index 00000000..311c230d Binary files /dev/null and b/HRR - Document Analysis/img/hrr_document_analysis_medical_information_extraction_options_2.png differ