SAS Documentation
SASĀ® Solution for Stress Testing
Reference manual - version 08.2021
Loading...
Searching...
No Matches
irmc_script_data_adjustment.sas
1/* ********************************************* */
2/* Data Adjustment Script: Input Parameters */
3/* ********************************************* */
4
5/* TGT Authentication Ticket */
6%let rgf_tgt_ticket = ${globals.ticket};
7
8/* Get the root location of the SAS Risk Workgroup Application */
9%let sas_risk_workgroup_dir = ${globals.sas_risk_workgroup_dir};
10
11/* Cycle Id */
12%let cycle_id = ${context.cycle.key};
13
14/* Run Id */
15%let run_id = ${context.runId};
16
17/* Run Type */
18%let run_type = ${context.runType};
19
20/* Analysis Data key, name, and description */
21%let analysis_data_key = ${params.ANALYSISDATA.key};
22%let analysis_data_name = ${params.ANALYSISDATA.name};
23%let analysis_data_desc = ${params.ANALYSISDATA.description};
24
25/* Output Analysis Data Name and Description */
26%let out_analysis_data_name = ${params.OUTANALYSISDATANAME};
27%let out_analysis_data_desc = ${params.OUTANALYSISDATADESC};
28
29/* Schema Name and Version of the Data Definition object associated with this Analysis Data object */
30%let schema_name = ${params.ANALYSISDATA.nav("analysisData_dataDefinition|RMC")[0].schemaName};
31%let schema_version = ${params.ANALYSISDATA.nav("analysisData_dataDefinition|RMC")[0].schemaVersion};
32%let business_category = ${params.ANALYSISDATA.nav("analysisData_dataDefinition|RMC")[0].businessCategoryCd};
33%let analysisData_libref = ${params.ANALYSISDATA.nav("analysisData_dataDefinition|RMC")[0].libref};
34
35/* RuleSet Key and type */
36%let ruleSet_key = ${params.RULESET.key};
37%let ruleSet_type = ${params.RULESET.ruleSetType};
38
39/* Log Level: 1-4 */
40%let log_level = ${params.LOGLEVEL};
41
42/* Create rules audit table (only applicable for Classification Rule Set) - this can be replaced with a model parameter in the future */
43%let create_rules_audit = No;
44
45/* Reset syscc macro variable */
46%let syscc = 0;
47
48/* ********************************************* */
49
50/* Initialize the environment */
51%include "&sas_risk_workgroup_dir./groups/Public/SASRiskManagementCore/cycles/&cycle_id./init.sas" / lrecl = 32000 source2;
52
53/* Set logging options (based on the value of LOG_LEVEL macro variable) */
54%irm_set_logging_options();
55
56%macro extract_lookup_analysis_info(lookupRulesData);
57 data _null_;
58 set &lookupRulesData.;
59 if (upcase(analysisData) eq "PLACEHOLDER") then do;
60 call symput('lookup_analysis_json', '');
61 end;
62 else if not missing(analysisData) then do;
63 call symput('lookup_analysis_json', analysisData);
64 end;
65 else do;
66 call symput('lookup_analysis_json', '');
67 end;
68 run;
69
70 /* Only proceed if there are rules with cross tables */
71 %if &lookup_analysis_json. ne %then %do;
72
73 /* Determine number of rules with cross tables */
74 data _null_;
75 call symput('lookupRulesData_obs', nobs);
76 stop;
77 set &lookupRulesData. nobs=nobs;
78 run;
79
80 /* For each cros table entry, need to fetch the analysis data */
81 %do j = 1 %to &lookupRulesData_obs.;
82
83 /* Extract the analysis data key for this cross table */
84 data _null_;
85 set &lookupRulesData.(obs=&j. firstobs=&j.);
86 if (upcase(analysisData) eq "PLACEHOLDER") then do;
87 call symput('lookup_analysis_json', '');
88 end;
89 else if not missing(analysisData) then do;
90 call symput('lookup_analysis_json', analysisData);
91 end;
92 else do;
93 call symput('lookup_analysis_json', '');
94 end;
95 run;
96
97 filename dqrsjson temp;
98 data _null_;
99 file dqrsjson;
100 length JSON $1000;
101 JSON = %unquote(%str(%'&lookup_analysis_json%'));
102 put JSON;
103 run;
104
105 libname jsonlibn JSON fileref=dqrsjson;
106 proc transpose data=jsonlibn.alldata(drop=p v) out=lookup_keys;
107 id p1;
108 var value;
109 run;
110
111 /* Now that key for analysis data key is available, assign to macro variable for use in irm_rgf_retrieve_analysis_data */
112 data _null_;
113 set lookup_keys;
114 if not missing(key) then call symput('lookup_analysis_key', key);
115 else call symput('lookup_analysis_key','');
116 run;
117
118 /* Retrieve Lookup Table AnalysisData details */
119 %let httpSuccess = 0;
120 %let responseStatus =;
121 %irm_rgf_retrieve_analysis_data(key = &lookup_analysis_key.
122 , libref = &dr_libref.
123 , outds = %str(&)schema_name.
124 , outds_partition_list = partition_list
125 , out_type = view
126 , outds_dataInfo = analysis_data
127 , outds_dataDef = data_definition
128 , host = &rgf_protocol.://&rgf_host.
129 , server = &rgf_service.
130 , solution = &rgf_solution.
131 , port = &rgf_port.
132 , tgt_ticket = &rgf_tgt_ticket.
133 , outVarTicket = ticket
134 , outSuccess = httpSuccess
135 , outResponseStatus = responseStatus
136 , restartLUA = Y
137 , clearCache = Y
138 );
139
140 %if(not &httpSuccess. or not %rsk_dsexist(analysis_data)) %then
141 %return;
142
143 /* Get the schema name, ie the name of the local copy of the analysis data */
144 data _null_;
145 set data_definition;
146 call symputx("schema_name", schemaName, "L");
147 run;
148
149 data &lookupRulesData.;
150 length schema_name $32.;
151 set &lookupRulesData.;
152 if (_N_ eq &j. ) then schema_name = "&schema_name.";
153 run;
154 %end;
155 %end;
156 %else %do;
157 data &lookupRulesData.;
158 length schema_name $32.;
159 ruleset_row_key = '';
160 schema_name = '';
161 run;
162 %end;
163%mend;
164
165/* Get Detail Data */
166%irm_get_details(libref = &analysisData_libref.
167 , table_name = &schema_name.
168 , table_id = &analysis_data_key.
169 , schema_version = &schema_version.
170 , out_ds = &schema_name.
171 , out_ds_meta = out_ds_meta
172 , out_partition_list = partition_list
173 , out_type = view
174 );
175
176/* Get Rules Set table */
177%irm_rest_get_rgf_rule_set(host = &rgf_protocol.://&rgf_host.
178 , server = &rgf_service.
179 , solution = &rgf_solution.
180 , port = &rgf_port.
181 , tgt_ticket = &rgf_tgt_ticket.
182 , key = &ruleSet_key.
183 , outds = rules_info
184 , outVarTicket = ticket
185 , outSuccess = httpSuccess
186 , outResponseStatus = responseStatus
187 );
188
189
190/* Apply Rules */
191%if(&ruleSet_type. eq AllocationRuleSet or &ruleSet_type. eq QFactorRuleSet or &ruleSet_type. eq MgtActionRuleSet) %then %do;
192
193 /* Workaround for the SQLContraintTransformer which requires a RGF hotfix */
194 data rules_info;
195 set rules_info;
196 filter_exp = prxchange('s/LOWER\‍(\s*(\w+)\s*\‍) like LOWER\‍(\s*"%([^%]+)%"\s*\‍)/prxmatch("\/\Q$2\E\/i", $1)/i', -1, filter_exp);
197 /* Convert != to ne */
198 filter_exp = prxchange("s/(!=)/ne/i", -1, filter_exp);
199 /* If rule set type is Management Action, update the filter expression and drop record_id */
200 if ruleSetType = "MgtActionRuleSet" then do;
201 filter_exp = catt(filter_exp, " and (FORECAST_TIME ne 0)");
202 drop record_id;
203 end;
204 run;
205
206 /* Run Allocation Rules */
207 %irm_apply_allocation_rules(ds_in = &schema_name.
208 , rule_def_ds = rules_info
209 , exclude_filter_vars = ruleSetKey
210 , custom_filter_var = filter_exp
211 , ds_out = modified_details
212 , ds_out_rule_summary = rule_summary
213 );
214
215 /* Finalize Summary table */
216 data &solutionId._alloc_rule_summary / view = &solutionId._alloc_rule_summary;
217 attrib
218 ruleSetKey length = 8. label = "Ruleset Key"
219 rule_condition length = $10000. label = "Rule Condition"
220 adjustment_value length = $150. label = "Adjustment Value"
221 measure_var_nm length = $150. label = "Measure Variable Name"
222 adjustment_type length = $150. label = "Adjustment Type"
223 allocation_method length = $150. label = "Allocation Method"
224 aggregation_method length = $32. label = "Aggregation Method"
225 weight_var_nm length = $150. label = "Weight Variable Name"
226 weighted_aggregation_flg length = $3. label = "Weighted Aggregation Flag"
227 affected_row_cnt length = 8. label = "Affected Row Count"
228 total_row_cnt length = 8. label = "Total Row Count"
229 ;
230 set rule_summary;
231 keep
232 ruleSetKey
233 rule_condition
234 adjustment_value
235 measure_var_nm
236 adjustment_type
237 allocation_method
238 aggregation_method
239 weight_var_nm
240 weighted_aggregation_flg
241 affected_row_cnt
242 total_row_cnt
243 ;
244 run;
245
246 %let rule_summary_schema_name = %lowcase(&solutionId._alloc_rule_summary);
247 %let filterable_vars = measure_var_nm adjustment_type allocation_method aggregation_method weight_var_nm weighted_aggregation_flg;
248 %let dataDefinition_name = Allocation Rules Summary Schema;
249 %let dataDefinition_desc = Allocation Rules Summary schema definition;
250%end;
251
252%if(&ruleSet_type. eq BusinessRuleSet) %then %do;
253
254 ${function:ProcessSpreadsheetParameter(params.RULESETANALYSISLOOKUPDATAMAPPING,"lookupRulesData")}
255
256 /* For any rules with cross tables, look up each mapped data analysis and stop named of local data set in SCHEMA_NAME */
257 %extract_lookup_analysis_info(lookupRulesData);
258
259 /* Merge the data set with the with the SCHEMA_NAME with rules_info */
260 proc sql noprint;
261 create table rules_info_aug as
262 select a.*, b.schema_name from
263 rules_info a left join lookupRulesData b
264 on (a.key eq b.ruleset_row_key) or b.ruleset_row_key eq ''
265 ;
266 quit;
267
268 /* Set the name of the source and target table, any lookup info, fix up the syntax of the lookup_key and lookup_data */
269 data rules_info;
270 set rules_info_aug;
271 source_table = "&schema_name.";
272 source_table_desc = "&analysis_data_name. (&analysis_data_key.)";
273 target_table = "modified_details";
274
275 /* Set name of local work analysis data set in LOOKUP_TABLE, as required by irm_run_rules */
276 if not missing(schema_name) then lookup_table = schema_name;
277
278 /* Variables in key and data from rule are in the form '["v1", "v2"]', we need to change to 'v1 v2' for irm_run_rules */
279 lookup_key = compress(lookup_key, '"[]');
280 lookup_key = tranwrd(lookup_key, ',', '');
281 lookup_data = compress(lookup_data, '"[]');
282 lookup_data = tranwrd(lookup_data, ',', '');
283 run;
284
285 /* Run Business Rules */
286 %irm_run_rules(ds_rule_def = rules_info
287 , ds_out_summary = rule_summary
288 );
289
290 /* Finalize Summary table */
291 data &solutionId._business_rule_summary / view = &solutionId._business_rule_summary;
292 attrib
293 ruleSetKey length = 8. label = "Ruleset Key"
294 ;
295 set rule_summary;
296 ruleSetKey = &ruleSet_key.;
297 run;
298
299 %let rule_summary_schema_name = %lowcase(&solutionId._business_rule_summary);
300 %let filterable_vars = source_table rule_id rule_name rule_reporting_lev1 rule_reporting_lev2 rule_reporting_lev3 rule_message_txt source_table rule_id;
301 %let dataDefinition_name = Business Rules Summary Schema;
302 %let dataDefinition_desc = Business Rules Summary schema definition;
303%end;
304
305%if(&ruleSet_type. eq ClassificationRuleSet) %then %do;
306
307 /* Workaround for the SQLContraintTransformer which requires a RGF hotfix */
308 data rules_info;
309 set rules_info (rename = (classification_value = adjustment_value
310 classification_field = measure_var_nm));
311 filter_exp = prxchange('s/LOWER\‍(\s*(\w+)\s*\‍) like LOWER\‍(\s*"%([^%]+)%"\s*\‍)/prxmatch("\/\Q$2\E\/i", $1)/i', -1, filter_exp);
312 /* Convert != to ne */
313 filter_exp = prxchange("s/(!=)/ne/i", -1, filter_exp);
314 /* If rule set type is Management Action, update the filter expression and drop record_id */
315 if ruleSetType = "ClassificationRuleSet" then do;
316 allocation_method = "INDIVIDUAL";
317 adjustment_type = "ABSOLUTE";
318 end;
319 run;
320
321 /* Run Allocation Rules */
322 %irm_apply_allocation_rules(ds_in = &schema_name.
323 , rule_def_ds = rules_info
324 , exclude_filter_vars = ruleSetKey
325 , custom_filter_var = filter_exp
326 , ds_out = modified_details
327 , ds_out_audit = rule_details
328 , ds_out_rule_summary = rule_summary
329 );
330
331 /* Finalize Summary table */
332 data &solutionId._alloc_rule_summary / view = &solutionId._alloc_rule_summary;
333 attrib
334 ruleSetKey length = 8. label = "Ruleset Key"
335 rule_condition length = $10000. label = "Rule Condition"
336 adjustment_value length = $150. label = "Adjustment Value"
337 measure_var_nm length = $150. label = "Measure Variable Name"
338 adjustment_type length = $150. label = "Adjustment Type"
339 allocation_method length = $150. label = "Allocation Method"
340 aggregation_method length = $32. label = "Aggregation Method"
341 weight_var_nm length = $150. label = "Weight Variable Name"
342 weighted_aggregation_flg length = $3. label = "Weighted Aggregation Flag"
343 affected_row_cnt length = 8. label = "Affected Row Count"
344 total_row_cnt length = 8. label = "Total Row Count"
345 ;
346 set rule_summary;
347 keep
348 ruleSetKey
349 rule_condition
350 adjustment_value
351 measure_var_nm
352 adjustment_type
353 allocation_method
354 aggregation_method
355 weight_var_nm
356 weighted_aggregation_flg
357 affected_row_cnt
358 total_row_cnt
359 ;
360 run;
361
362 %let rule_summary_schema_name = %lowcase(&solutionId._alloc_rule_summary);
363 %let filterable_vars = measure_var_nm adjustment_type allocation_method aggregation_method weight_var_nm weighted_aggregation_flg;
364 %let dataDefinition_name = Allocation Rules Summary Schema;
365 %let dataDefinition_desc = Allocation Rules Summary schema definition;
366
367%end;
368
369%if(&ruleSet_type. eq ClassificationRuleSet and &create_rules_audit eq Yes) %then %do;
370 /* Retrieve the primary key */
371 data _null_;
372 set out_ds_meta;
373 call symputx("primary_key", primary_key, "L");
374 run;
375 /* Classification audit table */
376 data &solutionId._alloc_rule_detail;
377 attrib
378 table_id length = 8. label = "Table Id"
379 project_id length = 8 label = "Analysis Cycle Id"
380 load_id length = $32. label = "Load Id"
381 entity_id length = $32. label = "Entity Id"
382 workgroup length = $32. label = "Risk Workgroup"
383 reporting_dt length = 8. label = "Base Date" format = yymmddd10.
384 ;
385 set &schema_name. (keep = &primary_key.);
386 attrib
387 measure_name length = $32. label = "Classification Field"
388 current_txt_value length = $150. label = "Current Value"
389 previous_txt_value length = $150. label = "Previous Value"
390 processed_dttm length = 8. label = "Processed Datetime" format = datetime21.
391 ;
392 stop;
393 run;
394 /* Append modified_delta to the output details table */
395 proc append base = &solutionId._alloc_rule_detail
396 data = rule_details force;
397 run;
398 /* Set the parameters needed to store the analysis data */
399 %let rule_audit_dtl_schema_name = %lowcase(&solutionId._alloc_rule_audit);
400 %let filterable_vars_dtl = classification_field;
401 %let dataDef_name_audit_dtl = Rules Audit Definition;
402 %let dataDef_desc_audit_dtl = Rules Audit schema definition;
403%end;
404
405/* Register results only if there are no errors */
406%if &syscc. <= 4 %then %do;
407 /* Store the modified table to the Data Repository and register it in RGF */
408 %irm_rgf_store_analysis_data(ds_in = modified_details
409 /* Analysis Data Parameters */
410 , analysis_data_name = &out_analysis_data_name.
411 , analysis_data_desc = &out_analysis_data_desc.
412 , base_date = &base_dt.
413 , cycle_id = &cycle_id.
414 , entity_id = &entity_id.
415 , status_cd = Preliminary
416 , %sysfunc(ifc(&run_type = Analysis Run, analysis_run_id = &run_id., model_run_id = &run_id.))
417
418 /* Data Definition Parameters */
419 , libref = &analysisData_libref.
420 , schema_name = &schema_name.
421 , schema_version = &schema_version.
422
423 /* Output tables */
424 , out_exceptions = data_exceptions
425 , out_analysis_data = new_analysys_data
426 , out_partition_list = new_partitions
427 , out_data_definition = data_definition
428 , out_link_instance = link_instance
429
430 /* Connection Parameters */
431 , host = &rgf_protocol.://&rgf_host.
432 , server = &rgf_service.
433 , solution = &rgf_solution.
434 , port = &rgf_port.
435 , tgt_ticket = &rgf_tgt_ticket.
436 , outVarTicket = ticket
437 , outSuccess = httpSuccess
438 , outResponseStatus = responseStatus
439 );
440
441
442 /* Store the audit summary table to the Data Repository and register it in RGF */
443 %irm_rgf_store_analysis_data(ds_in = &rule_summary_schema_name.
444 /* Analysis Data Parameters */
445 , analysis_data_name = Adjustments Summary (&analysis_data_name.) - %sysfunc(date(), yymmdd10.) %sysfunc(time(), tod8.)
446 , analysis_data_desc = Summary information about the adjustments that were applied on Analysis Data object &analysis_data_name. (Object Id: &analysis_data_key.).
447 , base_date = &base_dt.
448 , cycle_id = &cycle_id.
449 , entity_id = &entity_id.
450 , status_cd = Preliminary
451 , %sysfunc(ifc(&run_type = Analysis Run, analysis_run_id = &run_id., model_run_id = &run_id.))
452
453 /* Data Definition Parameters */
454 , data_definition_name = &dataDefinition_name.
455 , data_definition_desc = &dataDefinition_desc.
456 , libref = &analysisData_libref.
457 , engine = META
458 , meta_library_name = &dr_library_name.
459 , schema_name = &rule_summary_schema_name.
460 , schema_version = &content_version.
461 , schema_type = FLAT
462 , business_category = &business_category.
463 , data_category = AUDIT_SUMMARY
464 , risk_type = OTHER
465 , data_type = &ruleSet_type.
466 , partition_vars =
467 , filterable_vars = &filterable_vars.
468 , classification_vars =
469 , attributable_vars =
470 , mandatory_segmentation_vars =
471 , projection_vars =
472 , custom_code =
473 , constraint_enabled_flg = N
474
475 /* Output tables */
476 , out_exceptions = audit_data_exceptions
477 , out_analysis_data = audit_analysys_data
478 , out_partition_list = audit_partitions
479 , out_data_definition = audit_data_definition
480 , out_link_instance = audit_link_instance
481
482 /* Connection Parameters */
483 , host = &rgf_protocol.://&rgf_host.
484 , server = &rgf_service.
485 , solution = &rgf_solution.
486 , port = &rgf_port.
487 , tgt_ticket = &rgf_tgt_ticket.
488 , outVarTicket = ticket
489 , outSuccess = httpSuccess
490 , outResponseStatus = responseStatus
491 );
492%end;
493
494/* Register classification rules audit table if necessary and if there were no errors */
495%if (&syscc. <= 4 and (&ruleSet_type. eq ClassificationRuleSet and &create_rules_audit eq Yes) )%then %do;
496 /* Store the audit details table to the Data Repository and register it in RGF */
497 %irm_rgf_store_analysis_data(ds_in = &solutionId._alloc_rule_detail
498 /* Analysis Data Parameters */
499 , analysis_data_name = Classification Audit (&analysis_data_name.) - %sysfunc(date(), yymmdd10.) %sysfunc(time(), tod8.)
500 , analysis_data_desc = Audit information about the classifications that were applied on Analysis Data object &analysis_data_name. (Object Id: &analysis_data_key.).
501 , base_date = &base_dt.
502 , cycle_id = &cycle_id.
503 , entity_id = &entity_id.
504 , status_cd = Preliminary
505 , %sysfunc(ifc(&run_type = Analysis Run, analysis_run_id = &run_id., model_run_id = &run_id.))
506
507 /* Data Definition Parameters */
508 , data_definition_name = &dataDef_name_audit_dtl.
509 , data_definition_desc = &dataDef_desc_audit_dtl.
510 , libref = &analysisData_libref.
511 , engine = META
512 , meta_library_name = &dr_library_name.
513 , schema_name = &rule_audit_dtl_schema_name.
514 , schema_version = &content_version.
515 , schema_type = FLAT
516 , business_category = &business_category.
517 , data_category = AUDIT_SUMMARY
518 , risk_type = OTHER
519 , data_type = &ruleSet_type.
520 , partition_vars =
521 , filterable_vars = &filterable_vars.
522 , classification_vars =
523 , attributable_vars =
524 , mandatory_segmentation_vars =
525 , projection_vars =
526 , custom_code =
527 , constraint_enabled_flg = N
528
529 /* Output tables */
530 , out_exceptions = audit_dtl_data_exceptions
531 , out_analysis_data = audit_dtl_analysys_data
532 , out_partition_list = audit_dtl_partitions
533 , out_data_definition = audit_dtl_data_definition
534 , out_link_instance = audit_dtl_link_instance
535
536 /* Connection Parameters */
537 , host = &rgf_protocol.://&rgf_host.
538 , server = &rgf_service.
539 , solution = &rgf_solution.
540 , port = &rgf_port.
541 , tgt_ticket = &rgf_tgt_ticket.
542 , outVarTicket = ticket
543 , outSuccess = httpSuccess
544 , outResponseStatus = responseStatus
545 );
546%end;