/* History:
   2025-11-21 Load module checkFile from v143_modules in log_u_storage.
*/

**Creates logger dataset to save notes, warnings, and errors;
%macro create_logger();

	data _log_record;
		length section $128.;
		length message $32767.;
		
		error_code = .;
		section = "";
		message = "";
	run;
%mend create_logger;

**Adds notes, warnings, and errors to the logger dataset and writes them to the log;
%macro update_logger(error_code=0,
										 section=,
										 message=);
										 
	%local error_class;
										 
	**Update logger dataset;
	data _new_record;
	
		length section $128.;
		length message $32767.;
		
		error_code = &error_code.;
		section = "&section.";
		message = "&message.";
	run;
	
	data _log_record;
		set _log_record
				_new_record;
	run;
	
	**Write to log;
	%if &error_code. = 1 %then %do;
	
		%let error_class = NOTE;
	%end;
	%else %if &error_code. = 2 %then %do;
	
		%let error_class = WARNING;
	%end;
	%else %do;
	
		%let error_class = ERROR;
	%end;
	
	%let message = &error_class.: &message.;
	
	%put &message.;								 
%mend update_logger;

**Checks variables for valid matches in a dataset;
%macro check_variables_match(section=,
														 variables=,
														 variable_text=,
														 dataset=,
														 column=,
														 dataset_text=);
															
	%local i variable var_exists;
	
	%if &column. = %str() %then %do;
	
		**If no column is specified, extract dataset names;
		proc contents data=&dataset. out=_contents noprint; run;
		
		%let dataset = _contents;
		%let column = NAME;
	%end;
															
	%do i = 1 %to %sysfunc(countw(&variables., %str( )));
	
		%let variable = %sysfunc(scan(&variables., &i., %str( )));
		
		%let var_exists = 0;
		data _NULL_;
			set &dataset. end=_last;
			
			if compare("&variable.", &column., "i") = 0 then call symputx("var_exists", 1);
		run;
		
		%if &var_exists. = 0 %then %do;
		
			%update_logger(error_code=3, section=&section., message=&variable_text. &variable. was not found in &dataset_text.);
		%end;
	%end;
%mend check_variables_match;

**Checks indicators and amounts for corresponding variables in backtransformation;
%macro check_backtran_match(section=,
														variables=,
														backtran=);
											
	%local i variable var_exists;

	%do i = 1 %to %sysfunc(countw(&variables., %str( )));
	
		%let variable = %sysfunc(scan(&variables., &i., %str( )));
		
		%let var_exists = 0;
		data _NULL_;
			set &backtran.;
			
			if find("&variable.", variable, "i") ^= 0 then call symputx("var_exists", 1);
		run;
		
		%if &var_exists. = 0 %then %do;
		
			%update_logger(error_code=3, section=&section., message=&variable. was not found in backtransformation variables);
		%end;
	%end;
%mend check_backtran_match;

**Checks number of MCMC iterations, burn-in, and thinning;
%macro check_iterations(num_mcmc_iterations=,
												num_burn=,
												num_thin=,
												num_post=);
					
	**Number of MCMC iterations;							
	%if &num_mcmc_iterations. = %str() %then %do;
	
		%update_logger(error_code=3, section=Iterations, message=Number of MCMC iterations not specified);
	%end;
	
	%if &num_mcmc_iterations. ^= %str() %then %do;
	
		%if &num_mcmc_iterations. < 1 %then %do;
		
			%update_logger(error_code=3, section=Iterations, message=Number of MCMC iterations is less than one);
		%end;
	%end;
	
	**Number of burn-in iterations;
	%if &num_burn. = %str() %then %do;
	
		%update_logger(error_code=3, section=Iterations, message=Number of burn-in iterations not specified);
	%end;
	
	%if &num_burn. ^= %str() %then %do;
	
		%if &num_burn. < 0 %then %do;
		
			%update_logger(error_code=3, section=Iterations, message=Number of burn-in iterations is negative);
		%end;
	%end;
	
	**Compare total iterations and burn-in;
	%if &num_mcmc_iterations. ^= %str() and &num_burn. ^= %str() %then %do;
	
		%if &num_mcmc_iterations. <= &num_burn. %then %do;
		
			%update_logger(error_code=3, section=Iterations, message=Number of burn-in iterations is not less than total number of MCMC iterations);
		%end;
	%end;
	%else %do;
	
		%update_logger(error_code=1, section=Iterations, message=Number of MCMC iterations not compared to number of burn-in iterations because one or both were not specified);
	%end;
	
	**Thinning number;
	%if &num_thin. = %str() %then %do;
	
		%update_logger(error_code=3, section=Iterations, message=Thinning number not specified);
	%end;
	
	%if &num_thin. ^= %str() %then %do;
	
		%if &num_thin. < 1 %then %do;
		
			%update_logger(error_code=3, section=Iterations, message=Thinning number is less than one);
		%end;
	%end;
	
	**Post-MCMC iterations;
	%if &num_post. = %str() %then %do;
	
		%update_logger(error_code=3, section=Iterations, message=Number of post-MCMC iterations not specified);
	%end;
	
	%if &num_post. ^= %str() %then %do;
	
		%if &num_post. < 0 %then %do;
		
			%update_logger(error_code=3, section=Iterations, message=Number of post-MCMC iterations is negative);
		%end;
	%end;
	
	**Check for any errors;
	%let passed_iterations = 1;
	data _NULL_;
		set _log_record;
		if section = "Iterations";
		
		if error_code = 3 then call symputx("passed_iterations", 0);
	run;
%mend check_iterations;

**Check MCMC input library;
%macro check_data(pre_mcmc_data=,
									id=,
									repeat_obs=,
									weight=);

	**Input dataset;
	%if %sysfunc(exist(&pre_mcmc_data._mcmc_in)) = 0 %then %do;
	
		%update_logger(error_code=3, section=Data, message=&pre_mcmc_data._mcmc_in not found.);
	%end;
	
	%if &id. = %str() %then %do;
	
		%update_logger(error_code=3, section=Data, message=Subject ID variable not specified);
	%end;
	
	%if %sysfunc(exist(&pre_mcmc_data._mcmc_in)) = 1 and &id. ^= %str() %then %do;
	
		%check_variables_match(section=Data,
													 variables=&id.,
													 variable_text=Subject identifier,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input_data);
	%end;
	%else %do;
	
		%update_logger(error_code=1, section=Data, message=ID variable could not be checked for existence in input data due to errors in variable or data);
	%end;
	
	%if &repeat_obs. = %str() %then %do;
	
		%update_logger(error_code=3, section=Data, message=Repeat observation variable not specified);
	%end;
	
	%if %sysfunc(exist(&pre_mcmc_data._mcmc_in)) = 1 and &repeat_obs. ^= %str() %then %do;
	
		%check_variables_match(section=Data,
												   variables=&repeat_obs.,
													 variable_text=Repeat observation variable,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input_data);
	%end;
	%else %do;
	
		%update_logger(error_code=1, section=Data, message=Repeat observation variable could not be checked for existence in input data due to errors in variable or data);
	%end;
	
	%if &weight. ^= %str() %then %do;
	
		%if %sysfunc(exist(&pre_mcmc_data._mcmc_in)) = 1 %then %do;
		
			%check_variables_match(section=Data,
														 variables=&weight.,
														 variable_text=Weight variable,
														 dataset=&pre_mcmc_data._mcmc_in,
														 dataset_text=input_data);
		%end;
		%else %do;
		
			%update_logger(error_code=1, section=Data, message=Weight variable could not be checked for existence in input data due to errors in input data);
		%end;
	%end;
	
	**Backtransformation;
	%if %sysfunc(exist(&pre_mcmc_data._backtran)) = 0 %then %do;
	
		%update_logger(error_code=3, section=Data, message=&pre_mcmc_data..backtransformation not found);
	%end;
	
	%if %sysfunc(exist(&pre_mcmc_data._backtran)) = 1 %then %do;
	
		%check_variables_match(section=Data,
													 variables=variable tran_lambda minamount tran_center tran_scale biomarker,
													 variable_text=Variable,
													 dataset=&pre_mcmc_data._backtran,
													 dataset_text=backtran);
	%end;
	%else %do;
	
		%update_logger(error_code=1, section=Backtran, message=Variables could not be checked for existence in backtransformation data due to errors in backtransformation data);
	%end;
	
	**Check for any errors;
	%let passed_data = 1;
	data _NULL_;
		set _log_record;
		if section = "Data";
		
		if error_code = 3 then call symputx("passed_data", 0);
	run;
%mend check_data;

**Checks variable list parameters;
%macro check_variables(episodic_variables=,
											 episodic_indicators=,
											 episodic_amounts=,
											 daily_variables=,
											 daily_amounts=,
											 never_consumer_variable=,
											 never_consumer_indicator=,
											 never_consumer_amount=,
											 pre_mcmc_data=);
														
	%local is_nci_multivar;
	
	data _NULL_;
		_dsid = open("&pre_mcmc_data._mcmc_in");
		_check = (varnum(_dsid, "_nci_multivar") ^= 0);
			
		call symputx("is_nci_multivar", _check);
	run;
	
	**Episodic variables;
	%if &episodic_variables. ^= %str() %then %do;
		
		%check_variables_match(section=Variables,
													 variables=&episodic_variables.,
													 variable_text=Episodic variable,
													 dataset=&pre_mcmc_data._backtran,
													 column=variable,
													 dataset_text=backtransformation variables);
	%end;
	
	%if &episodic_variables. ^= %str() and &episodic_indicators. = %str() %then %do;
	
		%if &is_nci_multivar. = 0 %then %do;
		
			%update_logger(error_code=3, section=Variables, message=Episodic indicators not specified with episodic variables when nci_multivar_preprocessor was not used);
		%end;
	%end;
	
	%if &episodic_variables. ^= %str() and &episodic_amounts. = %str() %then %do;
	
		%if &is_nci_multivar. = 0 %then %do;
		
			%update_logger(error_code=3, section=Variables, message=Episodic amounts not specified with episodic variables when nci_multivar_preprocessor was not used);
		%end;
	%end;
	
	%if &episodic_variables. = %str() and &episodic_indicators. ^= %str() %then %do;
		
		%check_backtran_match(section=Variables,
													variables=&episodic_indicators.,
													backtran=&pre_mcmc_data._backtran);
	%end;
	
	%if &episodic_variables. = %str() and &episodic_amounts. ^= %str() %then %do;
		
		%check_backtran_match(section=Variables,
													variables=&episodic_amounts.,
													backtran=&pre_mcmc_data._backtran);
	%end;
	
	%if &episodic_indicators. ^= %str() %then %do;
		
		%check_variables_match(section=Variables,
													 variables=&episodic_indicators.,
													 variable_text=Episodic indicator,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
	%end;
	
	%if &episodic_amounts. ^= %str() %then %do;
	
		%check_variables_match(section=Variables,
													 variables=&episodic_amounts.,
													 variable_text=Episodic amount,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
	%end;
	
	**Daily variables;
	%if &daily_variables. ^= %str() %then %do;
		
		%check_variables_match(section=Variables,
													 variables=&daily_variables.,
													 variable_text=Daily variable,
													 dataset=&pre_mcmc_data._backtran,
													 column=variable,
													 dataset_text=backtransformation variables);
	%end;
	
	%if &daily_variables. ^= %str() and &daily_amounts. = %str() %then %do;
	
		%if &is_nci_multivar. = 0 %then %do;
		
			%update_logger(error_code=3, section=Variables, message=Daily amounts not specified with daily variables when nci_multivar_preprocessor was not used);
		%end;
	%end;
	
	%if &daily_variables. = %str() and &daily_amounts. ^= %str() %then %do;
		
		%check_backtran_match(section=Variables,
													variables=&daily_amounts.,
													backtran=&pre_mcmc_data._backtran);
	%end;
	
	%if &daily_amounts. ^= %str() %then %do;
		
		%check_variables_match(section=Variables,
													 variables=&daily_amounts.,
													 variable_text=Daily amount,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
	%end;
	
	**Never-consumer variable;
	%if &never_consumer_variable. ^= %str() %then %do;
		
		%check_variables_match(section=Variables,
													 variables=&never_consumer_variable.,
													 variable_text=Never-consumer variable,
													 dataset=&pre_mcmc_data._backtran,
													 column=variable,
													 dataset_text=backtransformation variables);
	%end;
	
	%if %sysfunc(countw(&never_consumer_variable., %str( ))) > 1 %then %do;
	
		%update_logger(error_code=3, section=Variables, message=More than one never-consumer variable specified);
	%end;
	
	%if &never_consumer_variable. ^= %str() and &never_consumer_indicator. = %str() %then %do;
	
		%if &is_nci_multivar. = 0 %then %do;
		
			%update_logger(error_code=3, section=Variables, message=Never-consumer indicator not specified with never-consumer variable when nci_multivar_preprocessor was not used);
		%end;
	%end;
	
	%if &never_consumer_variable. ^= %str() and &never_consumer_amount. = %str() %then %do;
	
		%if &is_nci_multivar. = 0 %then %do;
		
			%update_logger(error_code=3, section=Variables, message=Never-consumer amount not specified with never-consumer variable when nci_multivar_preprocessor was not used);
		%end;
	%end;
	
	%if &never_consumer_variable. = %str() and &never_consumer_indicator. ^= %str() %then %do;
		
		%check_backtran_match(section=Variables,
													variables=&never_consumer_indicator.,
													backtran=&pre_mcmc_data._backtran);
	%end;
	
	%if &never_consumer_variable. = %str() and &never_consumer_amount. ^= %str() %then %do;
		
		%check_backtran_match(section=Variables,
													variables=&never_consumer_amount.,
													backtran=&pre_mcmc_data._backtran);
	%end;
	
	%if &never_consumer_indicator. ^= %str() %then %do;
		
		%check_variables_match(section=Variables,
													 variables=&never_consumer_indicator.,
													 variable_text=Never-consumer indicator,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
	%end;
	
	%if %sysfunc(countw(&never_consumer_indicator., %str( ))) > 1 %then %do;
	
		%update_logger(error_code=3, section=Variables, message=More than one never-consumer indicator specified);
	%end;
	
	%if &never_consumer_amount. ^= %str() %then %do;
		
		%check_variables_match(section=Variables,
													 variables=&never_consumer_amount.,
													 variable_text=Never-consumer amount,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
	%end;
	
	%if %sysfunc(countw(&never_consumer_amount., %str( ))) > 1 %then %do;
	
		%update_logger(error_code=3, section=Variables, message=More than one never-consumer amount specified);
	%end;
	
	**Check for any errors;
	%let passed_variables = 1;
	data _NULL_;
		set _log_record;
		if section = "Variables";
		
		if error_code = 3 then call symputx("passed_variables", 0);
	run;
%mend check_variables;

**Checks covariate list parameters;
%macro check_covariates(default_covariates=,
												episodic_indicator_covariates=,
												episodic_amount_covariates=,
												daily_amount_covariates=,
												individual_covariates=,
												never_consumer_covariates=,
												pre_mcmc_data=,
												variable_data=);
												
	%local num_episodic num_daily
				 has_never_consumers;
	
	data _NULL_;
		set &variable_data.;
		
		call symputx("num_episodic", num_episodic);
		call symputx("num_daily", num_daily);
		
		call symputx("has_never_consumers", has_never_consumers);
	run;
	
	%if &default_covariates. ^= %str() %then %do;
		
		%check_variables_match(section=Covariates,
													 variables=&default_covariates.,
													 variable_text=Default covariate,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
	%end;
	
	%if &episodic_indicator_covariates. ^= %str() %then %do;
		
		%check_variables_match(section=Covariates,
													 variables=&episodic_indicator_covariates.,
													 variable_text=Episodic indicator covariate,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
													 
		%if &num_episodic. = 0 %then %do;
		
			%update_logger(error_code=2, section=Covariates, message=Episodic indicator covariates specified without episodic variables);
		%end;
	%end;
	
	%if &episodic_amount_covariates. ^= %str() %then %do;
		
		%check_variables_match(section=Covariates,
													 variables=&episodic_amount_covariates.,
													 variable_text=Episodic amount covariate,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
													 
		%if &num_episodic. = 0 %then %do;
		
			%update_logger(error_code=2, section=Covariates, message=Episodic amount covariates specified without episodic variables);
		%end;
	%end;
	
	%if &daily_amount_covariates. ^= %str() %then %do;
		
		%check_variables_match(section=Covariates,
													 variables=&daily_amount_covariates.,
													 variable_text=Daily amount covariate,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
													 
		%if &num_daily. = 0 %then %do;
		
			%update_logger(error_code=2, section=Covariates, message=Daily amount covariates specified without daily variables);
		%end;
	%end;
	
	%if &individual_covariates. ^= %str() %then %do;
	
		%if %sysfunc(exist(&individual_covariates.)) %then %do;
		
			%local has_correct_columns;
		
			%check_variables_match(variables=variable covariates,
														 variable_text=Column,
														 dataset=&individual_covariates.,
														 dataset_text=individual covariate data,
														 section=Individual Covariates);
			
			%let has_correct_columns = 1;											 
			data _NULL_;
				set _log_record;
				if section = "Individual Covariates";
				
				if error_code = 3 then call symputx("has_correct_columns", 0);
			run;
			
			%if &has_correct_columns. = 1 %then %do;
			
				%local list_names num_lists i;
				
				**Dataset of model variables;
				data _model_variables (keep = variable);
					set &variable_data.;
					
					%do i = 1 %to &num_episodic.;
					
						variable = episodic_ind&i.;
						output;
						
						variable = episodic_amt&i.;
						output;
					%end;
					
					%do i = 1 %to &num_daily.;
					
						variable = daily_amt&i.;
						output;
					%end;
				run;
				
				**List of variables with individual covariates;
				data _NULL_;
					set &individual_covariates. end=last;
				
					length list_names $32767.;
				
					retain list_names;
				
					individual_names = catx(" ", list_names, variable);
				
					if last = 1 then do;
					
						call symputx("list_names", list_names);
						call symputx("num_lists", _N_);
					end;
				run;
				
				%check_variables_match(section=Covariates,
															 variables=&list_names.,
															 variable_text=Individual covariate list name,
															 dataset=_model_variables,
															 column=variable,
															 dataset_text=model variables);
															 
				%do i = 1 %to &num_lists.;
				
					data _NULL_;
						set &individual_covariates.;
						if _N_ = &i.;
					
						call symputx("covariates", covariates);
						call symputx("variable", variable);
					run;
				
					%check_variables_match(section=Covariates,
																 variables=&covariates.,
																 variable_text=&variable. covariate,
																 dataset=&pre_mcmc_data._mcmc_in,
																 dataset_text=input data);
				%end;
			%end;
		%end;
		%else %do;
		
			%update_logger(error_code=3, section=Covariates, message=Individual covariate dataset does not exist);
		%end;
	%end;
	
	%if &never_consumer_covariates. ^= %str() %then %do;
		
		%check_variables_match(section=Covariates,
													 variables=&never_consumer_covariates.,
													 variable_text=Never-consumer covariate,
													 dataset=&pre_mcmc_data._mcmc_in,
													 dataset_text=input data);
													 
		%if &has_never_consumers. = 0 %then %do;
		
			%update_logger(error_code=2, section=Covariates, message=Never-consumer covariates specified without a never-consumer variable);
		%end;
	%end;
	
	**Check for any errors;
	%let passed_covariates = 1;
	data _NULL_;
		set _log_record;
		if section in ("Covariates" "Individual Covariates");
		
		if error_code = 3 then call symputx("passed_covariates", 0);
	run;
%mend check_covariates;

%macro check_sigma_u(sigma_u_prior=,
										 variable_data=);
													 
	%if &sigma_u_prior. ^= %str() %then %do;
		
		proc iml;
		
			reset storage=WORK.mcmc_modules;
			
			load module=(update_logger check_sigma_u);
			
			run check_sigma_u("&sigma_u_prior.",
												"&variable_data.");
		quit;
	%end;
	
	**Check for any errors;
	%let passed_sigma_u = 1;
	data _NULL_;
		set _log_record;
		if section = "Sigma-U";
		
		if error_code = 3 then call symputx("passed_sigma_u", 0);
	run;
%mend check_sigma_u;

%macro check_design(covariate_data=,
										variable_data=,
										pre_mcmc_data=,
										id=);
										
	proc iml;
	
		/* Load v143 modules */
		reset storage=WORK.v143_modules;
		load module=_all_;
	
		reset storage=WORK.mcmc_modules;
		load module=(check_design);
	
		run check_design("&covariate_data.",
										 "&variable_data.",
										 "&pre_mcmc_data.",
										 "&id.");
	quit;
	
	**Check for any errors;
	%let passed_design = 1;
	data _NULL_;
		set _log_record;
		if section = "Design";
		
		if error_code = 3 then call symputx("passed_design", 0);
	run;
%mend check_design;

%macro log_u_storage(save_mcmc_u=,
										 save_all_u=,
										 num_mcmc_iterations=,
										 num_burn=,
										 num_thin=,
										 num_post=,
										 pre_mcmc_data=,
										 id=,
										 variable_data=);
										 
	proc iml;
	
		reset storage=WORK.v143_modules;
		load module=(update_logger checkFile);
	
		reset storage=WORK.mcmc_modules;
		load module=(format_memsize log_u_storage);
		
		run log_u_storage("&save_mcmc_u.",
											"&save_all_u.",
											&num_mcmc_iterations.,
											&num_burn.,
											&num_thin.,
											&num_post.,
											"&pre_mcmc_data.",
											"&id.",
											"&variable_data.");
	quit;
%mend log_u_storage;

**Checks MCMC macro inputs and processes variable and covariate lists;
%macro check_and_process_input(pre_mcmc_data=,
															 id=,
															 weight=,
															 repeat_obs=,
															 episodic_variables=,
															 episodic_indicators=,
															 episodic_amounts=,
															 daily_variables=,
															 daily_amounts=,
															 never_consumer_variable=,
															 never_consumer_indicator=,
															 never_consumer_amount=,
															 default_covariates=,
															 default_intercept=,
															 episodic_indicator_covariates=,
															 episodic_indicator_intercept=,
															 episodic_amount_covariates=,
															 episodic_amount_intercept=,
															 daily_amount_covariates=,
															 daily_amount_intercept=,
															 individual_covariates=,
															 individual_intercept=,
															 never_consumer_covariates=,
															 never_consumer_intercept=,
															 sigma_u_prior=,
															 num_mcmc_iterations=,
															 num_burn=,
															 num_thin=,
															 num_post=,
															 save_mcmc_u=,
															 save_all_u=,
															 outname=);
	
	%local passed_iterations passed_data passed_variables passed_covariates passed_design passed_sigma_u;
															 
	**Define check variables (these get set inside the check macros);
	%let passed_iterations = 0;
	%let passed_data = 0;
	%let passed_variables = 0;
	%let passed_covariates = 0;
	%let passed_sigma_u = 0;
	%let passed_design = 0;
	
	**create error logger;
	%create_logger();
	
	**check MCMC iterations;
	%check_iterations(num_mcmc_iterations=&num_mcmc_iterations.,
										num_burn=&num_burn.,
										num_thin=&num_thin.,
										num_post=&num_post.);
										
	**check input dataset;
	%check_data(pre_mcmc_data=&pre_mcmc_data.,
							id=&id.,
							weight=&weight.,
							repeat_obs=&repeat_obs.);
							
	**checks requiring valid dataset;
	%if &passed_data. = 1 %then %do;
	
		**check model variables;
		%check_variables(episodic_variables=&episodic_variables.,
										 episodic_indicators=&episodic_indicators.,
										 episodic_amounts=&episodic_amounts.,
										 daily_variables=&daily_variables.,
										 daily_amounts=&daily_amounts.,
										 never_consumer_variable=&never_consumer_variable.,
										 never_consumer_indicator=&never_consumer_indicator.,
										 never_consumer_amount=&never_consumer_amount.,
										 pre_mcmc_data=&pre_mcmc_data.);
	%end;
	
	**process variables;
	%if &passed_variables. = 1 %then %do;
	
		%process_variables(pre_mcmc_data=&pre_mcmc_data.,
											 episodic_variables=&episodic_variables.,
											 episodic_indicators=&episodic_indicators.,
											 episodic_amounts=&episodic_amounts.,
										 	 daily_variables=&daily_variables.,
										 	 daily_amounts=&daily_amounts.,
										 	 never_consumer_variable=&never_consumer_variable.,
										 	 never_consumer_indicator=&never_consumer_indicator.,
										 	 never_consumer_amount=&never_consumer_amount.,
										 	 outname=&outname.);
	%end;
	
	**checks requiring valid model variables;
	%if &passed_variables. = 1 %then %do;
								 	 
		**check covariates;
		%check_covariates(default_covariates=&default_covariates.,
											episodic_indicator_covariates=&episodic_indicator_covariates.,
											episodic_amount_covariates=&episodic_amount_covariates.,
											daily_amount_covariates=&daily_amount_covariates.,
											individual_covariates=&individual_covariates.,
											never_consumer_covariates=&never_consumer_covariates.,
											pre_mcmc_data=&pre_mcmc_data.,
											variable_data=&outname._vars);
											
		**check Sigma-u prior;
		%check_sigma_u(sigma_u_prior=&sigma_u_prior.,
									 variable_data=&outname._vars);
	%end;
	
	**process covariates;
	%if &passed_covariates. = 1 %then %do;
	
		%process_covariates(variable_data=&outname._vars,
												default_covariates=&default_covariates.,
												default_intercept=&default_intercept.,
												episodic_indicator_covariates=&episodic_indicator_covariates.,
												episodic_indicator_intercept=&episodic_indicator_intercept.,
												episodic_amount_covariates=&episodic_amount_covariates.,
												episodic_amount_intercept=&episodic_amount_intercept.,
												daily_amount_covariates=&daily_amount_covariates.,
												daily_amount_intercept=&daily_amount_intercept.,
												individual_covariates=&individual_covariates.,
												individual_intercept=&individual_intercept.,
												never_consumer_covariates=&never_consumer_covariates.,
												never_consumer_intercept=&never_consumer_intercept.,
												outname=&outname.);	
	%end;
	
	**checks requiring valid covariates;
	%if &passed_covariates. = 1 %then %do;
									
		**check design matrices for each variable;
		%check_design(covariate_data=&outname._covars,
									variable_data=&outname._vars,
									pre_mcmc_data=&pre_mcmc_data.,
									id=&id.);
	%end;
	
	**exit if any errors are found;
	%if &passed_iterations. = 0 or
			&passed_data.				= 0 or
			&passed_variables.  = 0 or
			&passed_covariates. = 0 or
			&passed_sigma_u.		= 0 or
			&passed_design.			= 0 %then %do;
			
		data _NULL_;
			
			put "ERROR: Error(s) found in MCMC macro input";
			abort abend 2;
		run;
	%end;
	
	**log U matrix storage;
	%log_u_storage(save_mcmc_u=&save_mcmc_u.,
								 save_all_u=&save_all_u.,
								 num_mcmc_iterations=&num_mcmc_iterations.,
								 num_burn=&num_burn.,
								 num_thin=&num_thin.,
								 num_post=&num_post.,
								 pre_mcmc_data=&pre_mcmc_data.,
								 id=&id.,
								 variable_data=&outname._vars);
%mend check_and_process_input;