****************************************************************************************************
*                                           PROGRAM OVERVIEW
****************************************************************************************************
*
* PROGRAM: ms_cidacov.sas  
*
* Created (mm/dd/yyyy): 12/19/2014
* Last modified: 03/27/2017
* Version: 2.9
*
*--------------------------------------------------------------------------------------------------
* PURPOSE:
*   This macro will manage covariates.                                        
*   
*  Program inputs:  
*	-DPLocal.&RUNID._&data.
*	-infolder.&COHORTFILE. 
*	-infolder.&UTILFILE.
*	-infolder.Comorbcodes
*	-infolder.&Covariatecodes.
*	-infolder.&DRUGCLASSFILE.
*	-infolder.&MONITORINGFILE.
*                                     
*  Program outputs: 
*	-DPLocal.&RUNID._ads_&data.
*	-DPLocal.&RUNID._Claims_icddx09
*	-DPLocal.&RUNID._Claims_icddx10
*	-DPLocal.&RUNID._Claims_icddxOT
*	-DPLocal.&RUNID._Claims_icdpx09
*	-DPLocal.&RUNID._Claims_icdpx10
*	-DPLocal.&RUNID._Claims_icdpxOT
*	-DPLocal.&RUNID._Claims_cpt
*	-DPLocal.&RUNID._Claims_hcpcs
*	-DPLocal.&RUNID._Claims_drugclass 
*	-DPLocal.&RUNID._Claims_rx
*	-DPLocal.&RUNID._Claims_lab   
*	-MSOC.&RUNID._baseline&outcohort._&i.;
*	-MSOC.&RUNID._profile._&i.;
*	-MSOC.&RUNID._baseline_&mfu._&i.;

*  PARAMETERS:       
*	-data: indicates input the patient-level dataset  
*	-outcohort: indicates the suffix for output baseline table if additional cohorts are created
*            
*  Programming Notes:                                                                                
*	-This macro includes the optional execution of ms_util and ms_cci_elix macros                                                                           
*
*
*--------------------------------------------------------------------------------------------------
* CONTACT INFO: 
*  Mini-Sentinel Coordinating Center
*  info@mini-sentinel.org
*
*--------------------------------------------------------------------------------------------------
*  CHANGE LOG: 
*
*   Version   Date       Initials      Comment (reference external documentation when available)
*   -------   --------   --------   ---------------------------------------------------------------
*     1.3    03/31/2015    AC       Made changes to programming notes in header section.
*
*     1.4    03/31/2015    EM       Adapt code to Surveilance mode.
*
*     1.5    06/30/2015    EM       Removed Surveillance Analysis related code
*
*     1.6    06/30/2015    EM       Calculation of a baseline table (similar to table 1) for TYPE1 and TYPE2 requests.  
*
*     1.7    12/23/2015    EM       Changed age group names to be consitent with table 1.  
*
*     1.8    01/15/2016    VC       Allow for greater flexibility specifying the covariate assessment window.  
*									Create combined covariate variables.
*
*	  1.9    04/21/2016	   DM  		Added a w.a.r.n.i.n.g. when no baseline table is produced because no 
*									users were identified in the request
*
*	  1.10   08/10/2016	  AP(SOC)	Added 2 new HDPS dimension files (DX10 and PX10) for ICD10 (QCI-186)
*
*	  1.11   08/15/2016    DM       Added Surveillance Analysis related code removed in 1.5
*
*	  1.12   10/17/2016    DM       Fixed a couple of issues regarding Surveillance Analysis
*
*	  1.13   11/30/2016	  AP		Removed infolder libname from Monitoring File sort to accomodate 
*									truncation by DPMax Date	
*
*	  1.14   12/09/2016	  AP		Remove KeepAllDum as a parameter in the ComorbFile
*
*	  1.15   12/12/2016	  AP		Removed code that de-duped RX codes across covariates (QRP-289)
*
*	  2.0    03/27/2017	  DM		Removed covariates extraction from CDM. Now done earlier in ms_cidanum 
*
*	  2.1    05/05/2017	  AP		Added race, hispanic, and year to baseline table
*
*	  2.2	 07/10/2017	  AP		1. Added baseline table for Types 3-5
*									2. Added covariate profile table
*									3. Added MFU analysis
*
*	  2.3	 09/14/2017	  AP		Bug fix (QRP-429)
*
*	  2.4	 09/27/2017	  AP		Changed Type 3 dataset names, MFU lab extraction (QRP-432, QRP-433)
*
*	  2.5	 11/15/2017	  AP		Added shaving of covariates (QRP-419)
*
*	  2.6	 12/07/2017	  AP		1. Fixed PX table name in CCI macro call (QRP-469)
*									2. Sorting T4 control group by delnum (QRP-471)
*
*	  2.7	 12/21/2017	  AP		1. Modified comorbidity score window parameters (QRP-435)
*									2. Added CODEDAYS to covariate selection (QRP-455)
*
*	  2.8    02/27/2018	  RR		1. Ability to add never exposed group if requested (QRP-495)
*
*	  2.9    03/27/2018	  AP		Removed group variable from ms_util hash table (QRP-534)
*
***************************************************************************************************;

%macro ms_cidacov(data=, outcohort=);

%put =====> MACRO CALLED: ms_cidacov v2.9;

%ms_starttimer(START=CIDACOV);
    
	%put Macro will further read raw data using the prefix Libname: &DataLib.;

/******************/
/* Pre-Processing */
/******************/
*List of patients from CIDANum;

    proc sort nodupkey data=DPLocal.&RUNID._&data. out=PtsList(keep=Patid);
    by Patid;
    run;

    proc sort nodupkey data=DPLocal.&RUNID._&data. out=&RUNID._&data.;
    by Group Patid IndexDt;
    run;

*must have at least one patient;
%isdata(dataset=&RUNID._&data.);
%if %eval(&NOBS. > 0) %then %do;

%ISDATA(dataset=infolder.&COVARIATECODES.);	    
%IF %EVAL(&NOBS.>0) %THEN %DO;					
	proc sql noprint;	
	    select count (distinct CovarNum) 
	    into :NumCovars
	    from infolder.&COVARIATECODES.
		where codecat not in ("CC");
	quit;
	proc sql noprint;	
	    select count (distinct CovarNum) 
	    into :NumComb
	    from infolder.&COVARIATECODES.
		where codecat in ("CC");
	quit;
	%put Number of covars: &NumCovars;
	%put Number of covarComb: &NumComb;
%END;

*Assign pointer to prior DPLocal when running surveillance mode;
%global DPLOCALPOINTER;
%let DPLOCALPOINTER=DPLocal;
%if "&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p" %then %let DPLocalPointer=DPLPrior;
%put NOTE: DPLOCAL for prior run is set to &DPLocalPointer.;	

*Creating the number of groups to create cohorts;
 %isdata(dataset=COHORTFILE);    
    data _null_;
    call symputx("Numgroup","&nobs.");
    run;
*creating agegroupsort to add to master patient file;
	%macro addagegroupsort;
   		%do group = 1 %to &Numgroup.;
			data _age&group.;
		 		set cohortfile;
			 	if _n_ = &group.;
				if missing(agestrat) then agestrat = "00-01 02-04 05-09 10-14 15-18 19-21 22-44 45-64 65-74 75+";

			   	numgrp = countw(AGESTRAT," ") ;
				do i=1 to numgrp;
		  	    	AgeGroup=scan(AGESTRAT,i, " ");
		  		 	AgeGroupSort=i;
		  		 	output;
		 		end;
		 		keep group AgeGroup AgeGroupSort;
			run;
	%end;
	data _age;
		set  %do group = 1 %to &Numgroup.;
			 _age&group.
			 %end;;
	run;
		proc sql noprint undo_policy=none;
		create table dplocal.&runid._&data. as 
		select mstr.*,
		       age.AgeGroupSort
		from  DPLocal.&RUNID._&data. as mstr left join
		      _age as age
		      on age.AgeGroup=mstr.AgeGroup
			  and upcase(age.group) = upcase(mstr.group)
			  order by Group, PatID, IndexDt;
	quit;
 %mend addagegroupsort;
 %addagegroupsort;
*Initialize the number of groups;
%let Ngrp = 1;
/*********************************/
/* Compute Utilization Variables */
/*********************************/
 
    %macro RunUtil;

    %ISDATA(dataset=UTILFILE);	
    %IF %EVAL(&NOBS.>0) %THEN %DO;

        *Extracting Encounter Data;
        data _BaseEnc(keep=PatId ADate EncType);
        if 0 then set PtsList;
        declare hash ht (hashexp:16, dataset:"PtsList");
        ht.definekey('PatId');
        ht.definedone();

        do until(eof1);
          set &datalib.&encTable. end=eof1;
          if ht.find()=0 then output;
        end;
        stop;
        run;

        %do Group=1 %to &Numgroup.;

            *Processing Util parameters;
            Data _ITUtil;
            set UTILFILE;
            if _n_ = &Group.;
            call symputx('ITGROUP',strip(Group));

            if INCLINDEX=. then INCLINDEX=0; *defensive coding -  must be populated; 

            *always looking backwards (<0);
            call symputx("MEDUTILFROM",-1*MEDUTILFROM);
            *always looking forward (>=0);
        	if MEDUTILTO >=0 then call symputx("MEDUTILTO",MEDUTILTO+1); /*+1 because in ms_util, &medutilto = 0 excludes index*/
            else call symputx("MEDUTILTO",0);

        	call symputx("CARESETTINGS",compress(CARESETTINGS,"',"));  *defensive coding; 
            if "&Analysis."="ps" or "&Analysis."="ads" or "&Analysis."="ms" then do;
                call symputx("CARESETTINGS","'AV' 'OA' 'IP' 'IS' 'ED'");  *defensive coding; 
                call symputx("BYENC","Y");
            end;
            else call symputx("BYENC","N");
        	call symputx("CSSTRAT",CSSTRAT);
            run;

            %put &CARESETTINGS.;

            data _null_;
            set COHORTFILE;
            if Group = "&ITGROUP." then do;
                call symputx('ITGROUP',strip(Group));
            end;
            run;
            %put &group. &ITGROUP.;

            *Creating index reference file;
			proc sort data=&RUNID._&data. out= _indexfile(keep=patid indexdt) %if %eval(&type.=5) %then %do; nodupkey %end; ;
				by patid group indexdt;
				where group = "&ITGROUP.";
			run;

            *Calculate Utilization;
            %MS_UTIL(ENCOUNTERFILE=_BaseEnc,		
              	     INDEXFILE=_IndexFile,
            	     INDEXDT=IndexDt, 
            	     PRIORDAYS=&MEDUTILFROM.,
            	     INCLINDEX=&MEDUTILTO.,
            	     CARESETTINGS=&CARESETTINGS., 
            	     BYENC=&BYENC.,
            	     CSSTRAT=&CSSTRAT.,
            	     OUTFILE=_ITUtil 
                 );  

            *Post Process;
            data _ITUtil;
            set _ITUtil;
            format group $40.;
            Group="&ITGROUP."; 
            length NumVisits $10.;
            format NumVisits $10.;
            NumVisits=NumVisit;
            drop NumVisit;
            run;

            *Combine Util for multiple groups;
            %IF %EVAL(&group.=1) %THEN %DO;
                data _AllUtil;
                set _ITUtil;
                run;
            %END;
            %ELSE %DO;
                proc append base=_AllUtil
                            data=_ITUtil force;
                run;
            %END;

            *Clean-up;
            proc datasets library=work nolist nowarn;
            delete _ITUtil _IndexFile;
            quit;

	        proc sort data=_AllUtil;
	        by Group PatId IndexDt;
	        run;
     	%END; *do loop;

		%if "&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p" %then %do;
		    data _NewPatients;
		    set DPLocal.&RUNID._&data.;
		    where &PERIODIDSTART. <= IndexLook  <= &PERIODIDEND.;
		    keep Group PatId IndexDt;
		    run;

		    proc sort nodupkey;
		    by Group PatId IndexDt;
		    run;

		    data _AllUtil;
		    merge _AllUtil(in=a)
		          _NewPatients(in=b);
		    by Group PatId IndexDt;
		    if a and b;
		    run;
		%end;

        data DPLocal.&RUNID._&data.;
        merge DPLocal.&RUNID._&data.
              _AllUtil;
        by Group PatId IndexDt;
        run;

        %ISDATA(dataset=infolder.&DRUGCLASSFILE.);	
        %IF %EVAL(&NOBS.>0) %THEN %DO;

			proc sort data=&RUNID._&data. out= _BaseTmp(keep=group patid indexdt) %if %eval(&type.=5) %then %do; nodupkey %end; ;
				by group patid indexdt;
			run;
			
    	    *Adding DRUGUTIL window to base file;
    	    data _BaseTmp;
    	    if 0 then set UTILFILE(Keep=Group DrugUtilFrom DrugUtilTo);
    	    declare hash ht (hashexp:16, dataset:"UTILFILE");
    	    ht.definekey('Group');
    	    ht.definedata('DrugUtilFrom','DrugUtilTo'); 

    	    ht.definedone();

    	    do until(eof1);
    	    set _BaseTmp end=eof1;
        	    if ht.find()=0 then do;
                if .<DrugUtilFrom < 0 then DrugUtilFrom=-1*DrugUtilFrom;                
                output;
                end;
    	    end;
    	    stop;
    	    run;

            *calculate NumGeneric-NumClass;
            *extract Rx data in covariatewindow before IndexDt;
            proc sql noprint;
            create table _UtilRx as
            select Pts.Group, 
                   Pts.PatId,
                   Pts.IndexDt,
                   disp.NDC
            from _BaseTmp as pts,
                 &DataLib.&DisTable. as disp
            where pts.PatId = disp.Patid and 
                  %MS_PeriodsOverlap(period1=pts.IndexDt-COALESCE(pts.DrugUtilFrom,99999) COALESCE(pts.indexdt+DrugUtilTo/*-1*/,99999),                             
                                     period2=disp.RxDate);
            quit;

            *get Generic ClassName;
            proc sql noprint;
            create table _UtilRxClassGen as
            select Pts.Group, 
                   Pts.PatId,
                   Pts.IndexDt,
                   RxCl.Generic,
                   RxCl.ClassName,
                   1 as one
            from _UtilRx as pts,
                 infolder.&DRUGCLASSFILE. as RxCl
            where pts.NDC = RxCl.ndc;
            quit;

            *Count number of rows in dispensing table with NDC in drugclass file ;
            proc sql noprint;
            create table _NumRx as
            select Pts.Group, 
                   Pts.PatId,
                   Pts.IndexDt,
                   1 as one
            from _UtilRx as pts,
                 (select distinct ndc from infolder.&DRUGCLASSFILE.) as RxCl
            where pts.NDC = RxCl.ndc;
            quit;
            
            proc means data=_NumRx noprint nway;
            var one;
            class Group PatId IndexDt;
            output out=_NumRx(drop=_:) sum=NumRx;
            run;

            *Count number of disctinct Generic;
            proc sort nodupkey data=_UtilRxClassGen out=_Generic;
            by Group PatId IndexDt Generic;
            run;
            proc means data=_Generic noprint;
            var one;
            by Group PatId IndexDt;
            output out=_Generic(drop=_:) sum=NumGeneric;
            run;

            *Count number of disctinct ClassName;
            proc sort nodupkey data=_UtilRxClassGen out=_ClassName;
            by Group PatId IndexDt ClassName;
            run;
            proc means data=_ClassName noprint;
            var one;
            by Group PatId IndexDt;
            output out=_ClassName(drop=_:) sum=NumClass;
            run;

            *combine all three metrics;
            data _combine;
            merge _Generic
                  _ClassName
                  _NumRx;
            by Group PatId IndexDt;
            run;

			%if "&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p" %then %do;
			    data _combine;
			    merge _combine(in=a)
			          _NewPatients(in=b);
			    by Group PatId IndexDt;
			    if a and b;
			    run;

			    %if %eval(&PERIODIDSTART.>1) %then %do;			      	  

			      %macro PriorPeriods;
			        *complete covariates with pre-indexdt values from prior periods;
			        data _PriorPeriods;
			        set &DPLOCALPOINTER..&RUNID._ads_&data._%eval(&PERIODIDSTART.-1);
			        by Group PatId IndexDt;
			        keep Group PatId IndexDt NumGeneric NumClass NumRx;
			        run;
			      %mend;
			      %PriorPeriods;

			      data _baseTmp;
			      merge _baseTmp
			            _PriorPeriods;
			      by Group PatId IndexDt;
			      run;

			      proc datasets library=work nolist nowarn;
			      delete _PriorPeriods;
			      run;
			    %end;

			%end;

            *put Back in _Base;        
            data _baseTmp;
            merge _baseTmp(in=a)
                  _combine(keep=Group PatId IndexDt NumRx NumGeneric NumClass); *combine only contains new patients - other vars already updated;
            by Group PatId IndexDt;
            if a;  
            run;

            *Update Master file with utilization data;
            data DPLocal.&RUNID._&data.;
            merge DPLocal.&RUNID._&data.
                  _basetmp;
            by Group PatId IndexDt;
			if missing(NumRx) then NumRx=0;
			if missing(NumGeneric) then NumGeneric=0;
			if missing(NumClass) then NumClass=0;
            run;

            proc datasets library=work nolist nowarn;
            delete _BaseEnc IndexFile _:;
            quit;
        %END;
        %ISDATA(dataset=infolder.&DRUGCLASSFILE.);	
        %IF %EVAL(&NOBS.=0) %THEN %DO;
    		data DPLocal.&RUNID._&data.;
    		set DPLocal.&RUNID._&data.;
    		NumRx=.;
    		NumGeneric=.;
    		NumClass=.;
    		run;
        %END;
    %END;  
	%ELSE %DO;		
		data DPLocal.&RUNID._&data.;
		set DPLocal.&RUNID._&data.;
		ExactNumVisit=.;
		NumVisits_AV=.;
		NumVisits_IP=.;
		NumVisits_ED=.;
		NumVisits_OA=.;
		NumVisits_IS=.;
		NumVisits="";
		NumRx=.;
		NumGeneric=.;
		NumClass=.;
		run;
	%END;	*util calcs;
    %mend;

    %RunUtil;

/*********************************************/
/* and pre-extract the data for ADS          */ 
/* and Charlson Comorbidity/Elixhauser Index */
/*********************************************/

    %macro RunCovExtraction;

    *Test whether extraction is necessary;
    %IF %LENGTH(&CovarCodes.) | %LENGTH(&Comorbfile.) %THEN %DO;
        * Extraction needed: Create extraction lookup files;    
        data _CovRx
             CovMeds;
        set &ComborbsCodes.
            &CovarCodes.;       
        if CodeCat="RX" then output _CovRx; 
		&CovarCodes2.;
        run;

	%MS_ProcessWildcards(InFile=CovMeds, 
                         CodeVar=code, 
                         OutFile=CovMeds);

    *Break out CaresettingPrincipal into Caresetting and Principal;
    %ms_caresettingprincipal(InFile=CovMeds, 
                             Var=CareSettingPrincipal, 
                             OutFile=CovMeds);

	*Extracting meds using EncType and PDX to meds;
    %ms_loopmeds(datafile=Meds,
                 lookfile=CovMeds, 
                 outfile=_temp_PreMeds);

	*restricting to pts in cidanum;
 	data _temp_PreMeds1(rename=DummyDate=ADate);
        if 0 then set PtsList;
        declare hash pt (hashexp:16, dataset:"PtsList");
        pt.definekey('PatId');
        pt.definedone();

        do until(eof1);
          set _temp_PreMeds end=eof1;
          if pt.find()=0 then do;
			format DummyDate mmddyy10.;
			length DummyDate 4.;
			DummyDate=ADate;
			RxSup=1;
			RxAmt=1;
			drop ADate;
			output;
		end;
        end;
        stop;
	run;

    %ms_extractdrugs(datafile=Drugs,
                     datavar=NDC ,
                     lookfile=_CovRx(drop=codecat CodeType), 
                     lookvar=code, 
                     outfile=_temp_PreDrugs);     


	*restricting to pts in cidanum;
 	data _temp_PreDrugs1;
        if 0 then set PtsList;
        declare hash pt1 (hashexp:16, dataset:"PtsList");
        pt1.definekey('PatId');
        pt1.definedone();

        do until(eof1);
          set _temp_PreDrugs end=eof1;
          if pt1.find()=0 then do;
			RxSupEndDt=Rxdate+RxSup-1; 	
			output;
		end;
        end;
        stop;
	run;

	proc sort nodupkey data=_temp_PreDrugs(keep=StudyName StockGroup NDC Comorbcode CovarNum CovFrom CovTo CARESETTINGPRINCIPAL codedays) out=PreDrugParams;
		by StudyName StockGroup;
	run;

	*separate out covariates;
	data ElixMeds (drop=covfrom covto)
		 _temp_PreMeds2;
		set _temp_PreMeds1;
			
		if Comorbcode eq 1 then output ElixMeds;
		else output _temp_PreMeds2;
	run;

	proc datasets nowarn noprint lib=work; delete _temp_PreMeds1 _temp_PreMeds _temp_PreDrugs; quit;

	*Loop through groups to shave claims, stockpile, then re-shave;
	%do Group=1 %to &Ngroup.;

		data _null_;
			set infolder.&COHORTFILE.;
			if _n_ = &Group. then do;
				call symputx('ITGROUP',strip(Group));     
			end;
		run;
		
		%IF %eval(&type.) = 2 %THEN %DO;
		*Creating index reference file;
		proc sort data=&RUNID._&data. out= _ptsgroup(keep=patid group) nodupkey;
				by patid group;
				where group in ("&ITGROUP.", "&ITGROUP._nvrexp");  
			run;

		proc sql noprint;
			select count(distinct group) as group into: Ngrp
			from _ptsgroup;
		quit;
		%END;

	    %ms_shaveoutside(reffile=ENR_&GROUP.,
                     refstart=Enr_Start,
                     refend=Enr_End,
                     KeepPartBf=N,
                     ToShaveFile=_temp_PreMeds2,
                     ToShaveStart=ADate,
                     ToShaveEnd=ADate,
                     outfile=PreMeds_&group.);

		%ms_shaveoutside(reffile=ENR_&GROUP.,
                   refstart=Enr_Start,
                   refend=Enr_End,
                   KeepPartBf=N,
                   ToShaveFile=_temp_PreDrugs1,
                   ToShaveStart=RxDate,
                   ToShaveEnd=RxSupEndDt,
                   outfile=_temp_PreDrugs2);


		*Apply stockpiling;
		%MS_STOCKPILING(INFILE=_temp_PreDrugs2,	  		
	                    CLMDATE=RxDate,                            		
	                    CLMSUP=RxSup,                              		
	                    CLMAMT=RxAmt,	                           		
	        		    PROCFLAG=,                                 		
	        		    PERCENTDAYS=&PERCENTDAYS.,                         		
	        		    GROUPING=StudyName StockGroup,                   		
	        		    SAMEDAY=&SAMEDAY.,                                 	
	        			SUPRANGE=&SUPRANGE.,									
	        			AMTRANGE=&AMTRANGE.,
	        		    ID=,                                       		
	        		    OUTFILE=_temp_PreDrugs3,  		
	        			OUTFILEEXCL=PreDrugCovar&group.
	                    );

		proc datasets lib=work noprint nowarn; delete _temp_PreDrugs2; quit;

		*Reshave;
		%ms_shaveoutside(reffile=ENR_&GROUP.,
                   refstart=Enr_Start,
                   refend=Enr_End,
                   KeepPartBf=N,
                   ToShaveFile=_temp_PreDrugs3,
                   ToShaveStart=RxDate,
                   ToShaveEnd=ExpireDt,
                   outfile=_temp_PreDrugs3);

		proc sort data=_temp_PreDrugs3;
			by StudyName StockGroup;
		run;

		%IF %eval(&type.) = 2 & &Ngrp. = 2 %THEN %DO;
			data PreDrugs_&group.;
			 merge _temp_PreDrugs3
				  PreDrugParams;
			 by StudyName StockGroup;
			 drop NumDispensing ExpireDt;
			run;

			proc sql noprint undo_policy=none;
				 create table PreDrugs_&group. as
				 select a.*, b.group
				 from PreDrugs_&group. a inner join _ptsgroup b
				 on a.patid = b.patid;
			quit;

			proc sql noprint undo_policy=none;
				 create table PreMeds_&group. as
				 select a.*, b.group
				 from PreMeds_&group. a inner join _ptsgroup b
				 on a.patid = b.patid;
			quit;
		%END;
		%ELSE %DO;
			data PreDrugs_&group.;
			 merge _temp_PreDrugs3
				  PreDrugParams;
			 by StudyName StockGroup;   
			 format group $40.;
			 group = "&ITGROUP.";   
			 drop NumDispensing ExpireDt;
			run;

			data PreMeds_&group.;
			set PreMeds_&group.;
					format group $40.;
					group = "&ITGROUP.";
			run;
		%END;

		%if %eval(&group.) =1 %then %do;
			data PreDrugs; 
				set PreDrugs_&group.;
			run;
			data PreMeds; 
				set PreMeds_&group.;
			run;
		%end;
		%else %do;
			data PreDrugs; 
				set PreDrugs PreDrugs_&group.;
			run;
			data PreMeds; 
				set PreMeds PreMeds_&group.;
			run;
		%end;

	    proc datasets library=work nolist nowarn;
	    	delete predrugs_: premeds_: ElixMeds_:;
	    quit;  
	%end;
	proc datasets library=work nolist nowarn;
		delete _: PreDrugParams;
	quit;  
	%END;
    %mend;
    %RunCovExtraction;


/******************************************/
/* Charlson Comorbidity/Elixhauser Index) */
/******************************************/

    %macro RunCciElix;

    %ISDATA(dataset=Comorbfile);	
    %IF %EVAL(&NOBS.>0) %THEN %DO;

        %do Group=1 %to &Numgroup.;

		  *Process input file;
            data _null_;
               set Comorbfile;
               if _n_ = &Group. then do;
                    call symputx('ITGROUP',Group);
                    call symputx('comorbfrom',coalesce(comorbfrom,-999999)); 
                    call symputx('comorbto',coalesce(comorbto,999999));
                    call symputx('ccigroup',ccigroup);
                end;
            run;

       		*Break down Meds in procs and diags;
            data _cci_elix_dx
                 _cci_elix_px;
            set ElixMeds;
            *where Comorbcode eq 1;
            if Codecat="DX" then output _cci_elix_dx;
            if Codecat="PX" then output _cci_elix_px;
            run;

            %put &ITGROUP. &comorbfrom. &comorbto. &ccigroup.;

            *The Charlson/Elixhauser combined comorbidity score will be calculated;
            data _IndexFile;
            set &RUNID._&data.;
            where Group="&ITGROUP.";
            Keep Patid indexdt;
            run;

            %ms_cci_elix(COMORBFROM=&comorbfrom.,
                         COMORBTO=&comorbto.,
                         INFILE=_IndexFile, 
                         PATID=PatId,
                         INDEXDT=IndexDt, 
                         PREOUTFILE=_PreOutFile,
                         DIAGFILE=_cci_elix_dx,
                         DX_DT_VAR=Adate,
                         DX_CODETYP=Codetype,
                         DX_CODE=Code,
                         PROCFILE=_cci_elix_px, 
                         PX_DT_VAR=Adate,
                         PX_CODETYP=Codetype,
                         PX_CODE=Code,
                         CCI_LOOKUP=infolder.Comorbcodes, 
                         OUTFILE=_ITcci_elix,
                         CCIGROUP=&ccigroup.,
                         KEEPALLDUM=0);   /*&keepalldum.*/

        	*Post Process;
            data _ITcci_elix;
            set _ITcci_elix;
            format group $40.;
            Group="&ITGROUP."; 
            length ccielixgrp $10.;
            format ccielixgrp $10.;
            ccielixgrp=COMBINED_SCORE;
            run;

            *Combine Util for multiple groups;
            %IF %EVAL(&group.=1) %THEN %DO;
                data _ALLcci_elix;
                set _ITcci_elix;
                run;
            %END;
            %ELSE %DO;
                proc append base=_ALLcci_elix
                            data=_ITcci_elix force;
                run;
            %END;

            *Clean-up;
            proc datasets library=work nolist nowarn;
            delete _ITcci_elix _IndexFile _PreOutFile;
            quit;

        %END; *group loop;

        proc sort data=_ALLcci_elix;
        by Group PatId IndexDt;
        run;

		%if "&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p" %then %do;

		    data _NewPatients;
		    set DPLocal.&RUNID._&data.;
		    where &PERIODIDSTART. <= IndexLook  <= &PERIODIDEND.;
		    keep Group PatId IndexDt;
		    run;

		    proc sort nodupkey;
		    by Group PatId IndexDt;
		    run;

		    data _ALLcci_elix;
		    merge _ALLcci_elix(in=a)
		          _NewPatients(in=b);
		    by Group PatId IndexDt;
		    if a and b;
		    run;
		%end;

        *Update Master file with utilization data;
        data DPLocal.&RUNID._&data.;
        merge DPLocal.&RUNID._&data.
              _ALLcci_elix;
        by Group PatId IndexDt;
        run;

        proc datasets library=work nolist nowarn;
        delete _BaseEnc IndexFile _: 
               Elix_infile_sort Dsout Cci_diag_temp Cci_diag_lookup;
        quit;

    %end;
	%else %do;		
		data DPLocal.&RUNID._&data.;
		set DPLocal.&RUNID._&data.;
		COMBINED_SCORE="";
		COMBINED_SCORE_NUM=.;
		ccielixgrp="";
		run;
	%end;
    %mend;

    %RunCciElix;

/****************/
/* Prepare ADS	*/
/****************/

    %macro ADS;
    %put &analysis.;
    %if %str(%UPCASE("&ANALYSIS."))=%str("PS") or %str(%UPCASE("&ANALYSIS."))=%str("ADS") or %str(%UPCASE("&ANALYSIS."))=%str("MS") %then %do;

		%let t1_table1vars = ;
		%let t2_table1vars = ;
		%let t3_table1vars = ;
		%let t4_table1vars = ;
		%let t5_table1vars = ;
		%let analysiscohort = ;

		%if %eval(&type.=2) %then %do;
			%let t2_table1vars =NumEvents tte blackoutper EpisodeType LastLookFollowed: EpisodeEndDt;
		%end;
		%if %eval(&type.=3) %then %do;
			%let t3_table1vars = DAYS_FROM: analysiscohort censor:;
			%let analysiscohort = analysiscohort censor:;
		%end;
		%if %eval(&type.=4) %then %do;
			%let t4_table1vars = delnum EpisodeEndDt;
		%end;
		%if %eval(&type.=5) %then %do;
			%let t5_table1vars = episodenum;
		%end;
	
        *Creating the base file to extract data 
         and then divide into different PeriodId;
        data _Base;
        set DPLocal.&RUNID._&data.;

        rename AgeGroup=Age_Cat
               FEventDt=EventDt
               NumVisits_IP=NumIP
               NumVisits_ED=NumED
               NumVisits_AV=NumAV
               NumVisits_OA=NumOA
               NumVisits_IS=NumIS
               COMBINED_SCORE_NUM=COMORBIDSCORE;

        keep  PatID IndexDt Year Group Age AgeGroup AgeGroupSort Sex Race hispanic FEventDt
              COMBINED_SCORE_NUM NumVisits_IP NumVisits_ED NumVisits_AV NumVisits_OA NumVisits_IS
              NumGeneric NumClass NumRx &t2_table1vars. &t3_table1vars. &t4_table1vars. &t5_table1vars.;
        run;

		proc datasets lib=work nolist;
       		modify _Base;
	        attrib _all_ label=''; *Remove labels;
       quit;

        proc sort data=_base;
        	by Group Patid IndexDt %if %eval(&type.=5) %then %do; episodenum %end;;
        run;

		%if %eval(&type.=5) %then %do;
		data _base;
			set _base;
			by group patid indexdt episodenum;
			if first.patid;
		run;
		%end;

        /**************************/
        /* Creating Covar1-CovarN */
        /**************************/

        *Combine records;
        Data _CombineRecords;
        length Adate ExpireDt 4.;  * to avoid w a r n i n g s;
        set PreDrugs(rename=RxDate=ADate)
            PreMeds;
        format Adate ExpireDt date9.;
        ExpireDt=Adate+max(1,RxSup)-1;
        where studyname ne '';
        Keep Group PatId Adate ExpireDt studyname CovarNum covfrom covto codedays;
        run; 

        proc datasets library=work nowarn nolist;
        delete _Drugs CovMeds PreMeds;
        quit;

	    /*Finding those claims in covariatewindow*/
        proc sql noprint;
        create table _Covar as
        select distinct pts.Patid,
                        pts.Group,
                        pts.IndexDt,
                        Rec.studyname,
						Rec.Adate,
						Rec.covfrom,
						Rec.covto,
                        Rec.CovarNum,
						Rec.codedays
        from _base as pts, 
             _CombineRecords as Rec
        where pts.Patid = rec.Patid and pts.group = rec.group and
             %MS_PeriodsOverlap(period1=coalesce(pts.IndexDt+covFrom,-99999) COALESCE(pts.indexdt+CovTo/*-1*/,99999),                                             
                                period2=Rec.ADate Rec.ExpireDt)
        order by pts.Group,
                 pts.Patid,
                 pts.IndexDt;
        quit;

		/*Count number of ADate per covariate and only keep covariate when freq >=codedays*/
		proc means data=_Covar noprint nway missing;
			class group patid indexdt studyname covfrom covto covarnum codedays / missing;
			output out=_Covar(drop=_: where=(freq>=codedays)) n=freq;
		run;

        *Squaring;
        data _Covar;
        set  studynames
             _Covar(drop=freq codedays);
        Rec=1;
        run;

        *One record per Patid Group IndexDt;
        proc transpose data=_Covar out=_Covar(drop=_NAME_) prefix=COVAR;
        var Rec;
        by Group Patid IndexDt;
        id Covarnum;
        idlabel studyname;
        run;

		/******************************/
		/*Verify if any combcovariates*/
		/******************************/		
	    %ISDATA(dataset=infolder.&COVARIATECODES.);	
		%IF %EVAL(&NOBS.>0) %THEN %DO;
			data _COMBO;
			set infolder.&COVARIATECODES.;
			where codecat in ("CC");
			run;

			%if "&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p" %then %do;
			    data _NewPatients;
			    set DPLocal.&RUNID._&data.;
			    where &PERIODIDSTART. <= IndexLook  <= &PERIODIDEND.;
			    keep Group PatId IndexDt;
			    run;

			    proc sort nodupkey;
			    by Group PatId IndexDt;
			    run;
			%end;

			%ISDATA(dataset=_COMBO);
			%IF %EVAL(&NOBS.>=1) %THEN %DO;				
				data _COMBO;
				set _COMBO;
				format RuleLong $1000.;
				RuleLong=code;
				%do j=1 %to &numcovars.;
					RuleLong=left(TRANWRD(cat(' ',rulelong,' '),(" &j. ")," COVAR&j. "));
					RuleLong=left(TRANWRD(cat(' ',rulelong,' '),("(&j. "),"(COVAR&j. "));
					RuleLong=left(TRANWRD(cat(' ',rulelong,' '),(" &j.)")," COVAR&j.)"));
				%end;
				run;

				*Create CombCovar variables;
				%do i=(&numcovars.+1) %to (&numcovars.+&numcomb.);
					data _null_;
					set _COMBO (where=(Covarnum=&i.));
					call symput ('Rule',RuleLong);
					call symput ('Label',Studyname);
					run;
					%put &Rule.;

					data _covar;
					set _covar;
					COVAR&i.=0;
					if &rule. then do;
					COVAR&i.=1;
					end;
					label COVAR&i.="&Label.";
					run;

				%end;*do loop numcomb;

				%if "&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p" %then %do;
				    
					proc sort data=_Covar;
				    by Group PatId IndexDt;
				    run;

				    data _Covar;
				    merge _Covar(in=a)
				          _NewPatients(in=b);
				    by Group PatId IndexDt;
				    if a and b;
				    run;

				%end;

		        *Add dummies to master file (and will also order the vars by covarN);
		        %macro PutBack;
		        data _base;
		        merge _base(in=a)
		              _Covar(keep=Group PatId IndexDt  %do j=1 %to &numcovars.;%str(covar&j. )%end;
													   %do k=(&numcovars.+1) %to (&numcovars.+&numcomb.);%str(covar&k. )%end;);
		        by Group PatId IndexDt;
		        if a;  
		        run;
		        %mend;
		        %PutBack;
			%END;
			%ELSE %DO;
				%if "&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p" %then %do;				    

				    data _Covar;
				    merge _Covar(in=a)
				          _NewPatients(in=b);
				    by Group PatId IndexDt;
				    if a and b;
				    run;

				%end;

		        *Add dummies to master file (and will also order the vars by covarN);
		        %macro PutBack;
		        data _base;
		        merge _base(in=a)
		              _Covar(keep=Group PatId IndexDt  %do j=1 %to &numcovars.;%str(covar&j. )%end;);
		        by Group PatId IndexDt;
		        if a;  
		        run;
		        %mend;
		        %PutBack;
			%END;
		%END;

        *Creating individual PeriodId files;
		%isdata(dataset=&Monitoringfile.); 
		%if %eval(&nobs.>0) %then %do;
	        proc sort data=&Monitoringfile. out=_Looks;
	        by PeriodId;
	        run;

	        data _Looks;
	        set _looks end=eof;
	        lastEndDt=lag(enddate);
	        format incrstartfollowup date9.;
	        incrstartfollowup=startfollowup;
	        if _N_>1 then incrstartfollowup=lastEndDt+1;        
	        drop lastEndDt;
	        run;

			proc sql noprint undo_policy=none;;
	        create table _base as
	        select distinct base.*,
	                        look.PERIODID as time
	        from _Base as base, 
	             _Looks as look
	        where incrstartfollowup <= IndexDt <= enddate;
	        quit;
		%end;

		%if %eval(&type.=3) %then %do;
			data _looks;
				set msoc.&runid._Metadata_for_time_period_&PERIODIDSTART.;
	  			 incrstartfollowup=ExpPeriodStartDt;
				 enddate = ExpPeriodEndDt;
				 periodid = TimePeriod;
			run;

			proc sql noprint undo_policy=none;;
		        create table _base as
		        select distinct base.*,
		                        look.PERIODID as time
		        from _Base as base, 
		             _Looks as look
		        where incrstartfollowup <= IndexDt <= enddate and base.group=look.group;
	        quit;
		%end;

		%let delnum = ;
		/*Need to include DelNum for Type 4 control grp because ctrl group may not be unique on group/patid/indexdt*/
		%if "&data" = "ctrl" %then %do; 
			%let delnum = delnum; 
		%end;


        %macro forAdsloop;
        %do i=&PERIODIDSTART. %to &PERIODIDEND.;
         
			proc sort data =_base;
				by Group PatId IndexDt &delnum.;
			run;

            data DPLocal.&RUNID._ads_&data._&i.;
            set _Base;
      		if _N_=1 then set _Looks(keep=PERIODID enddate where=(PERIODID=&i.));

            if missing(NumGeneric) then NumGeneric=0;
            if missing(NumClass) then NumClass=0;
            if missing(NumRx) then NumRx=0;

			*if Type = 2 then: 
				1. Adjust tte for episodes going beyond the PERIODID
				2. Add followuptime_ and event_ vars ;

			%if %eval(&type.=2) %then %do;
	            if IndexDt <= enddate and EpisodeEndDt > min(LastLookFollowedDt,enddate) then do;
	               if EventDt > min(LastLookFollowedDt,enddate) then EventDt = .; 
	               *tte = min(tte,enddate - IndexDt +1 -  BlackOutPer);
	               tte = min(LastLookFollowedDt,EventDt,enddate) - IndexDt +1 -  BlackOutPer;
	            end;

				*Variables needded for the ADS;
	            Followuptime_ITT=.;
	            Event_ITT=0;
	            if EpisodeType="ITT" then do;
	                Followuptime_ITT=tte;
	                Event_ITT=EventDt>0;
	            end;

	            Followuptime_astreated=.;
	            Event_astreated=0;

	            if EpisodeType="EPI" then do;
	                Followuptime_astreated=tte;
	                Event_astreated=EventDt>0;				
	            end;

				drop BlackOutPer EpisodeEndDt;
			%end;

            *fill covars with 0s;
            %do j=1 %to &numcovars.;%str(covar&j.=covar&j.>0;)%end;
			%do k=(&numcovars.+1) %to (&numcovars.+&numcomb.);%str(covar&k.=covar&k.>0; )%end;

            *Output incremental datasets;
            if IndexDt <= enddate then output DPLocal.&RUNID._ads_&data._&i.;

            *Cleanup to keep only required in specs;
            drop enddate PERIODID;
            run;

			*Carry forward information from previous look in ads_mstr;
			%IF %EVAL(&i.>1) & %eval(&type.=2) %THEN %DO;
				%let previous = %eval(&i-1); 
				data DPLocal.&RUNID._ads_&data._&i.;
				merge DPLocal.&RUNID._ads_&data._&i.
              	  	  &DPLOCALPOINTER..&RUNID._ads_&data._&previous. (where=(Time < &PERIODIDSTART. and LastLookFollowed > 0)
															  keep=Time LastLookFollowed Group PatId IndexDt Followuptime_: Event_:
															  %do j=1 %to &numcovars.;%str(covar&j. )%end;
															  %do k=(&numcovars.+1) %to (&numcovars.+&numcomb.);%str(covar&k. )%end;);
	        	by Group PatId IndexDt;
	        	run;
			%END;

		%end;
		%mend forAdsloop;
        %forAdsloop;

		%macro baselineloop(where=, t3out=);
        %do i=&PERIODIDSTART. %to &PERIODIDEND.;

			proc sql noprint;
				select count(*) into: nusers
				from DPLocal.&RUNID._ads_&data._&i.
				where &where.;
			quit;
			%if %eval(&nusers.>0) %then %do;

				*************************
				*Create baseline profile*
				*************************;

				%if "&profile." = "y" %then %do;
					data _tempcovar;
						set DPLocal.&RUNID._ads_&data._&i.;
						patient = 1;
						where &where.;
					run;
					proc means data=_tempcovar noprint nway;
						var patient;
						class group patid covar1-covar%eval(&numcovars.+&numcomb.);
						id patient;
						output out=_covarprofile(drop=_:) max(patient) = npts
														sum(patient) = n_episodes;
					run;
						
					proc means data=_covarprofile nway noprint missing;
						var Npts n_episodes;
					    class group covar1-covar%eval(&numcovars.+&numcomb.);
					    output out=msoc.&runid._profile&outcohort.&t3out._&i.(drop=_:) sum=;                                  
					run;
				%end;

				***********************
				*Create Baseline table*
				***********************;

				*Strip age_cat of special characters;
				  data _RawData;
				  set  DPLocal.&RUNID._ads_&data._&i. (drop = agegroupsort); 
				  by group patid indexdt &delnum.;
				  Age_cat=TRANSLATE(Age_cat,"_","-"); 
				  Age_cat=upcase(compress(Age_cat,' <>+-'));
				  patient=1;
				  where &where.;
				  run;

				*Create age group dummies - can be multiple index per patient;
				  proc transpose data=_RawData out=_AgeGroups(keep=group patid indexdt Age: &delnum.)  prefix=AGE;
				  var patient;
				  by group patid indexdt &delnum.;
				  id Age_cat;
				  run;

				*Create sex dummies - can be multiple index per patient;
				  proc transpose data=_RawData out=_Genders(keep=group patid indexdt Sex_: &delnum.)  prefix=Sex_;
				  var patient;
				  by group patid indexdt &delnum.;
				  id Sex;
				  run;

				*Create race dummies - can be multiple index per patient;
				  proc transpose data=_RawData out=_races(keep=group patid indexdt Race_: &delnum.)  prefix=Race_;
				  var patient;
				  by group patid indexdt &delnum.;
				  id race;
				  run;


				*Create hispanic dummies - can be multiple index per patient;
				  proc transpose data=_RawData out=_hispanic(keep=group patid indexdt Hispanic_: &delnum.)  prefix=Hispanic_;
				  var patient;
				  by group patid indexdt &delnum.;
				  id hispanic;
				  run;

				*Create year dummies - can be multiple index per patient;
				  proc transpose data=_RawData out=_years(keep=group patid indexdt year_: &delnum.)  prefix=Year_;
				  var patient;
				  by group patid indexdt &delnum.;
				  id year;
				  run;

				*Merge back agegroup and sex dummies;
				  data _RawData;
				  merge _RawData(drop=patient)
				        _AgeGroups
						_Genders
						_years
						_races
						_hispanic;
					  by group patid indexdt &delnum.;

					  patient=0;
					  *create a new patient indicator to count distinct patients;
					  if first.patid then patient=1;

					  if not first.patid then do;
						array Sexes Sex_:;
						do over Sexes;
						  Sexes=.;
						end;

						array races race_:;
						do over races;
						  races=.;
						end;

						array hispanics hispanic_:;
						do over hispanics;
						  hispanics=.;
						end;
					  end;
				  run;

				*Process discrete vars;
				  proc means data=_RawData(drop=age age_cat) nway noprint;
				  var patient Age: Sex_: year_: race_: hispanic_:
						%if %eval(&numcovars. ge 1) %then %do; covar: %end;
						%if %eval(&numcomb. ge 1) %then %do; covar: %end;;
				  class group;
				  output out=_Discrete(drop=_:) sum=;
				  run;

				*Process continuous vars;
				  proc means data=_RawData nway noprint;
				  var /*Followuptime_ITT Followuptime_astreated */
				      Age COMORBIDSCORE 
				      NumAV NumOA NumIP NumIS NumED 
				      NumGeneric NumClass NumRx;
				  class group;
				  output out=_Continuous(rename=_freq_=N_episodes drop=_type_)
				        mean= mean_Age mean_COMORBIDSCORE 
				             mean_NumAV mean_NumOA mean_NumIP mean_NumIS mean_NumED 
				             mean_NumGeneric mean_NumClass mean_NumRx
				         std= std_Age std_COMORBIDSCORE 
				             std_NumAV std_NumOA std_NumIP std_NumIS std_NumED 
				             std_NumGeneric std_NumClass std_NumRx;
				  run;

				*merge the two;
				  data msoc.&RUNID._baseline&outcohort.&t3out._&i.;
				  merge _discrete
				        _continuous;
				  by group;

				  /*Set to missing if &race_out =N/&hispanic_ou=N for each group*/
				  if upcase(group) not in (&race_groups2.) then do;
					array races race_:;
						do over races;
						  races=.;
						end;
				  end;

				  if upcase(group) not in (&hispanic_groups2.) then do;
					array hispanic hispanic_:;
						do over hispanic;
						  hispanic=.;
						end;
				  end;

				  run;

				*add missing groups if any; 
				proc sql noprint;
					create table _MissingGroups as
					select distinct (Group), 0 as patient, 0 as N_Episodes  
					from COHORTFILE
					where group not in
					  (select distinct (Group) 
					   from msoc.&RUNID._baseline&outcohort.&t3out._&i.
					  )
					;
				quit;
					 
				data msoc.&RUNID._baseline&outcohort.&t3out._&i.;
				set msoc.&RUNID._baseline&outcohort.&t3out._&i.
					_MissingGroups;
				run;
			%end;
			%else %do;
				%put WARNING: No users. Baseline table &RUNID._baseline&outcohort.&t3out._&i. will not be produced.;
			%end;
        %end;
        %mend baselineloop;
        %baselineloop(where=1, t3out=);

		%if %eval(&type.=3) %then %do;
      		%baselineloop(where=analysiscohort=1 and censorenrol=0 and censordeath=0, t3out=_an);
      		%baselineloop(where=AnalysisCohort=1, t3out=_an_censor);
		%end;

        /*****************************/
        /* Claims_icddx09.sas7bdat   */
        /* Claims_icddx10.sas7bdat   */
		/* Claims_dxOT.sas7bdat		 */
        /* Claims_icdpx09.sas7bdat   */
		/* Claims_icdpx10.sas7bdat   */
		/* Claims_pxOT.sas7bdat		 */
        /* Claims_cpt.sas7bdat       */
        /* Claims_hcpcs.sas7bdat     */
        /* Claims_drugclass.sas7bdat */
		/* Claims_rx.sas7bdat		 */
		/* Claims_lab.sas7bdat		 */
        /*****************************/
        %macro ClaimsFiles;
            %let HDPS=N;
			%let MFU=N;

            %ISDATA(dataset=HDPSSettings);
			*Note: HDPS settings contains groups where HDPS=Y;	
            %IF %EVAL(&NOBS.>0) %THEN %DO;
              data _ToSelect;
              set HDPSSettings;
              where upcase(HDPS)="Y";
              if upcase(HDPS)="Y" then call symputx("HDPS",upcase(HDPS));
              keep Group;
              run;
              %put &HDPS.;
            %END;

			*Note: MFU is performed on all groups, so _ToSelect contains all groups, 
				even if HDPS is not performed on all groups;
			%isdata(dataset=infolder.&mfufile.);
			%if %eval(&nobs.>0) %then %do;
				data _ToSelect;
					set cohortfile;
					keep group;
				run;
				%let MFU=Y;
				%put &MFU;
			%end;

            %if %str(&HDPS.)=%str(Y) | %str(&MFU.)=%str(Y) %then %do; 
            
               *keep only patients in groups where HDPS is required (All groups for MFU);
                data _lookup(keep=Patid Group Indexdt &analysiscohort.);
                if 0 then set _ToSelect(Keep=Group);
                declare hash ht (hashexp:16, dataset:"_ToSelect");
                ht.definekey('Group');
                ht.definedone();

                do until(eof1);
                  set &RUNID._&data. end=eof1;
                  if ht.find()=0 then output;
                end;
                stop;
                run;

				*keep only new patients;
				%if "&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p" %then %do;

				    proc sort nodupkey data=_NewPatients(keep=Group PatId);
				    by Group PatId;
				    run;

				    data _lookup;
				    merge _lookup(in=a)
				          _NewPatients(in=b);
				    by Group PatId;
				    if a and b;
				    run;
				%end;

				/*Determine Min and Max Windows. Cannot use coalesce() because HDPS or MFU may use entire history 
				  whereas the other is a defined window */
				%let HDPS_MFU_FROM=.;
				%let HDPS_MFU_TO=.;

				/*Enrollment considered absolute value of window, need to obtain true max window*/
				%if %str(&MFU.)=%str(Y) %then %do;
					proc means data=infolder.&mfufile. nway noprint;
				    var MFUFROM MFUTO;
				    output out=MFU_WIN min(MFUFROM)= 
				                        max(MFUTO)=;
				    run;
				    
				    data _NULL_;
				    set MFU_WIN;
				    call symputx("MinMFUWinFrom",put(MFUFROM,best.));
				    call symputx("MaxMFUWinTo",put(MFUTO,best.));
				    run;

					%put &MinMFUWinFrom. &MaxMFUWinTo.;
				%end;
   
			    %put &MinHDPSWinfrom. &MaxHDPSWinTo.;

				%if %str(&HDPS.)=%str(Y) & %str(&MFU.)=%str(N) %then %do; 
					%let HDPS_MFU_FROM=&MinHDPSWinfrom.;
					%let HDPS_MFU_TO=&MaxHDPSWinTo.;
				%end;
				%else %if %str(&HDPS.)=%str(N) & %str(&MFU.)=%str(Y) %then %do; 
					%let HDPS_MFU_FROM=&MinMFUWinFrom.;
					%let HDPS_MFU_TO=&MaxMFUWinTo.;
				%end;
				%else %do; /*both HDPS and MFU*/
					%if &MinHDPSWinfrom. ne . & &MinMFUWinFrom. ne . %then %let HDPS_MFU_FROM = %sysfunc(min(&MinHDPSWinfrom.,&MinMFUWinFrom.));
					%else %let HDPS_MFU_FROM = .;

					%if &MaxHDPSWinTo. ne . & &MaxMFUWinTo. ne . %then %let HDPS_MFU_TO = %sysfunc(max(&MaxHDPSWinTo.,&MaxMFUWinTo.));
					%else %let HDPS_MFU_TO = .;
				%end;

				%let t3vars = ;
				%if %eval(&type.=3) %then %do;
				%let t3vars = , pts.analysiscohort, pts.censordeath, pts.censorenrol;
				%end;


                *Claims_icddx;
                proc sql noprint;
                create table &RUNID._Claims_icddx as
                select /*distinct*/ claims.Patid,
                                compress(claims.DX) as Code,
								claims.DX_Codetype,
                                claims.Adate,
								claims.enctype,
								claims.pdx,
                                pts.group,
								pts.indexdt
								&t3vars.
                from _lookup as pts, 
                     &DataLib.&Diatable. as claims
                where pts.Patid = claims.Patid and
                      %MS_PeriodsOverlap(period1=pts.IndexDt+coalesce(&HDPS_MFU_FROM.,-99999) pts.IndexDt+coalesce(&HDPS_MFU_TO.,99999),                                             
                                         period2=claims.ADate)
                order by claims.Patid, 
                         pts.group;
                quit;

  				data DPLocal.&RUNID._Claims_icddx09
                     DPLocal.&RUNID._Claims_icddx10
					 DPLocal.&RUNID._Claims_dxOT;
                set &RUNID._Claims_icddx; 

                if DX_Codetype in("09") then output DPLocal.&RUNID._Claims_icddx09;
				if DX_Codetype in("10","11") then output DPLocal.&RUNID._Claims_icddx10;
				if DX_Codetype in("OT") then output DPLocal.&RUNID._Claims_dxOT; /*For MFU*/
                run;

                *Claims_icdpx;
                proc sql noprint;
                create table &RUNID._Claims_icdpx as
                select /*distinct*/ claims.Patid,
                                compress(claims.PX) as Code,
                                pts.group,
                                claims.PX_Codetype,
                                claims.Adate,
								claims.Enctype,
								pts.indexdt
								&t3vars.
                from _lookup as pts, 
                     &DataLib.&Proctable. as claims
                where pts.Patid = claims.Patid and
                      %MS_PeriodsOverlap(period1=pts.IndexDt+coalesce(&HDPS_MFU_FROM.,-99999) pts.IndexDt+coalesce(&HDPS_MFU_TO.,99999),                                             
                                         period2=claims.ADate)
                order by claims.Patid, 
                         pts.group;
                quit;

                data DPLocal.&RUNID._Claims_icdpx09
					 DPLocal.&RUNID._Claims_icdpx10
                     DPLocal.&RUNID._Claims_cpt
                     DPLocal.&RUNID._Claims_hcpcs
					 DPLocal.&RUNID._Claims_pxOT;
                set &RUNID._Claims_icdpx; 

                if PX_Codetype in("09") then output DPLocal.&RUNID._Claims_icdpx09;
                if PX_Codetype in("10","11") then output DPLocal.&RUNID._Claims_icdpx10;
                if PX_Codetype in("C2","C3","C4") then output DPLocal.&RUNID._Claims_cpt;
                if PX_Codetype in("HC","H3")      then output DPLocal.&RUNID._Claims_hcpcs;
				if PX_Codetype in("RE","ND","LO","OT") then output DPLocal.&RUNID._Claims_pxOT; /*For MFU*/
                run;

                *Claims_drugclass;
                proc sql noprint;
                create table _Claims_drugclass as
                select /*distinct*/ claims.Patid,
                                claims.NDC as Code,
                                claims.Rxdate as Adate,
                                pts.group,
								pts.indexdt,
								claims.rxsup,
								claims.rxamt
								&t3vars.
                from _lookup as pts, 
                     &DataLib.&distable. as claims
                where pts.Patid = claims.Patid and
                      %MS_PeriodsOverlap(period1=pts.IndexDt+coalesce(&HDPS_MFU_FROM.,-99999) pts.IndexDt+coalesce(&HDPS_MFU_TO.,99999),                                             
                                         period2=claims.RxDate) /*claims.ADate+RxSup-1*/;
                quit;

				/*For MFU*/
				data DPLocal.&RUNID._Claims_rx;
					set _Claims_drugclass;
					where rxsup >0 and rxamt > 0;
				run;

                *add Drugclass information for HDPS;
                proc sql noprint;
                create table DPLocal.&RUNID._Claims_drugclass as
                select /*distinct*/ claims.Patid,
									claims.indexdt,
                                claims.group,
                                claims.adate,
                                ndc.classname as Code
                from infolder.&DRUGCLASSFILE. as ndc
                     inner join 
                     _Claims_drugclass as claims
                on ndc.ndc = claims.Code
                order by claims.Patid, 
                         claims.group;
                quit;

				/*Lab table - for MFU only*/
				%ISDATA(dataset=indata.&labtable.);	
   				%IF %EVAL(&NOBS.>0) %THEN %DO;
		   			proc sql noprint;
		        		create table DPLocal.&RUNID._Claims_lab as
		        		select claims.patid,
							   pts.group,
							   pts.indexdt,
							   coalesce(claims.lab_dt,claims.result_dt,claims.order_dt,0) as adate, 
		        		       upcase(claims.result_type) as result_type, 
		                       claims.loinc,
		        		       claims.px, 
		                       claims.px_codetype,
							   claims.ms_test_name,
							   claims.specimen_source,
							   claims.ms_test_sub_category,
							   claims.ms_result_unit,
							   claims.fast_ind,
							   claims.pt_loc
							   &t3vars.
		        		from _lookup as pts, 
						     &DataLib.&labtable. as claims
						where pts.Patid = claims.Patid and %MS_PeriodsOverlap(period1=pts.IndexDt+coalesce(&HDPS_MFU_FROM.,-99999) pts.IndexDt+coalesce(&HDPS_MFU_TO.,99999),                                             
						                                      period2=coalesce(claims.lab_dt,claims.result_dt,claims.order_dt,0))
						order by claims.Patid, pts.group;
					quit;
				%end; *Lab MFU codes;
				
				%if ("&SURVEILLANCEMODE."="f" or "&SURVEILLANCEMODE."="p") & %eval(&PERIODIDSTART.>=2)  %then %do;

				  data DPLocal.&RUNID._Claims_icdpx09;
				  set  DPLocal.&RUNID._Claims_icdpx09
				      &DPLOCALPOINTER..&RUNID._Claims_icdpx09;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_icdpx10;
				  set  DPLocal.&RUNID._Claims_icdpx10
				      &DPLOCALPOINTER..&RUNID._Claims_icdpx10;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_cpt;
				  set  DPLocal.&RUNID._Claims_cpt
				      &DPLOCALPOINTER..&RUNID._Claims_cpt;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_hcpcs;
				  set  DPLocal.&RUNID._Claims_hcpcs
				      &DPLOCALPOINTER..&RUNID._Claims_hcpcs;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_pxOT;
				  	set DPLocal.&RUNID._Claims_pxOT
				       &DPLOCALPOINTER..&RUNID._Claims_pxOT;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_icddx09;
				  set  DPLocal.&RUNID._Claims_icddx09
				      &DPLOCALPOINTER..&RUNID._Claims_icddx09;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_icddx10;
				  set  DPLocal.&RUNID._Claims_icddx10
				      &DPLOCALPOINTER..&RUNID._Claims_icddx10;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_dxOT;
				  set DPLocal.&RUNID._Claims_dxOT
				     &DPLOCALPOINTER..&RUNID._Claims_dxOT;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_drugclass;
				  set  DPLocal.&RUNID._Claims_drugclass
				      &DPLOCALPOINTER..&RUNID._Claims_drugclass;
				  by Patid group;
				  run;

				  data DPLocal.&RUNID._Claims_rx;
				  set  DPLocal.&RUNID._Claims_rx
				      &DPLOCALPOINTER..&RUNID._Claims_rx;
				  by Patid group;
				  run;

				 %ISDATA(dataset=indata.&labtable.);	
   				  %IF %EVAL(&NOBS.>0) %THEN %DO;
				  data DPLocal.&RUNID._Claims_lab;
				  set  DPLocal.&RUNID._Claims_lab
				      &DPLOCALPOINTER..&RUNID._Claims_lab;
				  by Patid group;
				  run;
				  %end;

				%end;
            %END;  *HDPS/MFU extraction;
        %mend;
		%if "&data." = "mstr" %then %do;
        %ClaimsFiles;
		%end;

		/**Conduct MFU analysis*/
		%macro MFU(where=, t3out=);
		
		/*Determine number of analyses*/
		proc sql noprint;
			select max(ANALYSISNUM) into: mfucnt
			from infolder.&mfufile;
		quit;

		/*loop through analyses*/
		%do a = 1 %to &mfucnt.;

			/*number of CodeCat/CodeType within analysis*/
			data _currentMFU;
				set infolder.&mfufile.(where=(ANALYSISNUM=&a.));
				if _n_ = 1 then do;
						/*These parameters are set for the analysis and not unique to CODECAT/CODETYPE*/
						call symputx('TOPXX',TOPXX);
						call symputx('MFUFROM',MFUFROM);
						call symputx('MFUTO',MFUTO);
						call symputx('COUNTMETHOD',upcase(COUNTMETHOD));
				end;
			run;
			%put &TOPXX. &MFUFROM. &MFUTO.;

			/*CODECAT list*/
			proc sql noprint;
				select distinct codecat into: codecatlist separated by ' '
				from _currentMFU;
			quit;
			%put &codecatlist.;

			*DX/PX codes;
			%if %index(&codecatlist., DX)>0 | %index(&codecatlist., PX)>0 %then %do;
				data _mfudxpx;
					set _currentMFU;
					where codecat in('DX', 'PX');
				run;
			
 				*Break out CaresettingPrincipal into Caresetting and Principal;
    				%ms_caresettingprincipal(InFile=_mfudxpx, 
                             Var=CareSettingPrincipal, 
                             OutFile=_mfudxpx);

				*Select all codetypes;
				%let dx_codetypelist = 'XX'; /*Dummy code*/
				%let px_codetypelist = 'XX';
					proc sql noprint;
						select distinct "'"||(compress(codetype))||"'" into: dx_codetypelist separated by "," 
						from _mfudxpx
						where codecat = 'DX';
						select distinct "'"||(compress(codetype))||"'" into: px_codetypelist separated by "," 
						from _mfudxpx
						where codecat = 'PX';
					quit;
					%put &dx_codetypelist &px_codetypelist.;

				*Stack Claims datasets;
				data claims_dxpx(where=(&where.));
					set DPLocal.&RUNID._Claims_icddx09(rename=dx_codetype = codetype where=(codetype in (&dx_codetypelist.)) in=a)
						DPLocal.&RUNID._Claims_icddx10(rename=dx_codetype = codetype where=(codetype in (&dx_codetypelist.)) in=b)
						DPLocal.&RUNID._Claims_dxOT(rename=dx_codetype = codetype where=(codetype in (&dx_codetypelist.)) in=c)
						DPLocal.&RUNID._Claims_icdpx09(rename=px_codetype = codetype where=(codetype in (&px_codetypelist.)) in=d)
						DPLocal.&RUNID._Claims_icdpx10(rename=px_codetype = codetype where=(codetype in (&px_codetypelist.)) in=e)
						DPLocal.&RUNID._Claims_pxOT(rename=px_codetype = codetype where=(codetype in (&px_codetypelist.)) in=f)
						DPLocal.&RUNID._Claims_cpt(rename=px_codetype = codetype where=(codetype in (&px_codetypelist.)) in=g)
						DPLocal.&RUNID._Claims_hcpcs(rename=px_codetype = codetype where=(codetype in (&px_codetypelist.)) in=h);

						if a or b or c then codecat = 'DX';
						if c or d or e or f or g or h then codecat = 'PX';	
				run;

				*Envelope will not be run for MFU analysis;

				*Extract records;
				proc sql noprint;
					create table _dxpxcodes as
					select claim.patid,
						   compress(claim.code,' .') as code format=$18. length=18,
						   claim.codetype format=$3. length=3,
						   claim.codecat,
						   claim.group
					from claims_dxpx as claim, _mfudxpx as mfu
					where claim.codetype = mfu.codetype and   
						((mfu.EncType = claim.EncType and mfu.Pdx = claim.Pdx) or  /*No Wilcards*/
		               	(mfu.EncType = "**"          and mfu.Pdx = claim.Pdx) or  /*Any EncType*/
		               	(mfu.EncType = claim.EncType and mfu.Pdx = "*") or        /*Any Pdx*/
		               	(mfu.EncType = "**"          and mfu.Pdx = "*"))
						and %MS_PeriodsOverlap(period1=IndexDt+coalesce(&MFUFROM.,-99999) IndexDt+coalesce(&MFUTO.,99999),                                             
                                            period2=ADate);
        		quit;

				proc append data=_dxpxcodes base=_allmfucodes force; run;
			%end; *DX/PX codes;

			*RX codes;
			%if %index(&codecatlist., RX)>0 %then %do;
				data _mfurx;
					set _currentMFU(where=(codecat='RX'));
				run;

				*Determine whether to extract 09, 11, or both;
				proc sql noprint;
					select distinct codetype into: rx_codetypelist separated by ' ' 
					from _mfurx;
				quit;
				%put &rx_codetypelist.;

				*Extract 9-digit NDC codes;
				%if %index(&rx_codetypelist, 09) > 0 %then %do;
				proc sql noprint;
					create table _rxcodes09 as
					select claim.patid,
						   compress(substr(claim.code, 1,9)) as code format=$18. length=18,
						   '09' as codetype format=$3. length=3,
						   'RX' as codecat,
						   claim.group
					from DPLocal.&RUNID._Claims_rx(where=(&where.)) as claim,
						 _mfurx as mfu
					where %MS_PeriodsOverlap(period1=IndexDt+coalesce(&MFUFROM.,-99999) IndexDt+coalesce(&MFUTO.,99999),                                             
                                            period2=ADate);
        		quit;
				proc append data=_rxcodes09 base=_allmfucodes force; run;
				%end;

				*Extract 11-digit NDC codes;
				%if %index(&rx_codetypelist, 11) > 0 %then %do;
				proc sql noprint;
					create table _rxcodes11 as
					select claim.patid,
						   compress(claim.code) as code format=$18. length=18,
						   '11' as codetype format=$3. length=3,
						   'RX' as codecat,
						   claim.group
					from DPLocal.&RUNID._Claims_rx(where=(&where.)) as claim,
						 _mfurx as mfu
					where %MS_PeriodsOverlap(period1=IndexDt+coalesce(&MFUFROM.,-99999) IndexDt+coalesce(&MFUTO.,99999),                                             
                                            period2=ADate);
        		quit;
				proc append data=_rxcodes11 base=_allmfucodes force; run;
				%end; 
			%end; *RX codes;
			  		
			*Lab codes;
			%if %index(&codecatlist., LB)>0 %then %do;
				data _mfulb_01_02
					 _mfulb;
					set _currentMFU(where=(codecat='LB'));

					if substr(codetype,1,2) in ('01','02') then output _mfulb_01_02;
						else output _mfulb; 
				run;

				%isdata(dataset=_mfulb_01_02);
				%if %eval(&nobs.>0) %then %do;

					/*Select codetypes*/
					proc sql noprint;
						select distinct "'"||(compress(codetype))||"'" into: lb_codetypelist separated by ' ' 
						from _mfulb_01_02;
					quit;
					%put &lb_codetypelist;

					%let result_type_n = 'XXX';
					%let result_type_c = 'XXX';

					%macro assign_lab_resulttype(cat=);
						*Determine whether to restrict to N, C, or both;
						%if %index(&lb_codetypelist., &cat.N) > 0 %then %do;
							%let result_type_n = 'N';
						%end;
						%if %index(&lb_codetypelist., &cat.C) > 0 %then %do;
							%let result_type_c = 'C';
						%end;
					%mend;

					/*Count SOC-defined lab codes (codetype = 01N, 01C)*/
					%if %index(&lb_codetypelist., 01) > 0 %then %do;

						%assign_lab_resulttype(cat=01);

						*Code in infolder.&LABSCODEMAP. should be unique;
	        			proc sort nodupkey data=infolder.&LABSCODEMAP. out=_Map;
	        			by Code;
	        			run;

	        			*Extract Lab Records;
	        		    proc sql noprint;
	        			create table _mfulab01 as
	        			select claim.patid,
							   claim.group,
	        			       compress(_map.Code,' .') as code format=$18. length=18,
	                           cat('01',claim.result_type) as codetype format=$3. length=3,
							   'LB' as codecat
	        			from _Map as look,
	        			     DPLocal.&RUNID._Claims_lab(where=(&where.)) as claim
	        			where upcase(strip(look.ms_test_name))  		= upcase(strip(claim.ms_test_name)) and 
	                          upcase(strip(look.ms_test_sub_category)) 	= upcase(strip(claim.ms_test_sub_category)) and 
	                          upcase(strip(look.specimen_source))      	= upcase(strip(claim.specimen_source)) and 
	        			      upcase(strip(look.ms_result_unit))      	= upcase(strip(claim.ms_result_unit)) and
							  upcase(strip(look.result_type))			= upcase(strip(claim.result_type)) and
		    				  upcase(strip(look.fast_ind))				= upcase(strip(claim.fast_ind))and
	        			      upcase(strip(look.pt_loc))				= upcase(strip(claim.pt_loc)) and
							  upcase(strip(claim.result_type))			in (&result_type_n, &result_type_c) and 
							  %MS_PeriodsOverlap(period1=claim.IndexDt+coalesce(&MFUFROM.,-99999) claim.IndexDt+coalesce(&MFUTO.,99999),                                             
	                                            period2=claim.ADate);
	        			quit;

						proc append data=_mfulab01 base=_allmfucodes force; run;
					%end;

					/*Count LOINC lab codes (codetype = 02N, 02 C)*/
					%if %index(&lb_codetypelist., 02) > 0 %then %do;

						%assign_lab_resulttype(cat=02);

	        			*Extract Lab Records;
	        		    proc sql noprint;
	        			create table _mfulab02 as
	        			select claim.patid,
							   claim.group,
	        			       compress(LOINC) as code format=$18. length=18,
	                           cat('02',claim.result_type) as codetype format=$3. length=3,
							   'LB' as codecat
	        			from  DPLocal.&RUNID._Claims_lab(where=(&where.)) as claim
	        			where upcase(strip(claim.result_type)) in (&result_type_n, &result_type_c) and 
							  LOINC is not missing and 
							  %MS_PeriodsOverlap(period1=claim.IndexDt+coalesce(&MFUFROM.,-99999) claim.IndexDt+coalesce(&MFUTO.,99999),                                             
	                                            period2=claim.ADate);
	        			quit;

						proc append data=_mfulab02 base=_allmfucodes force; run;
					%end;
				%end;

				%isdata(dataset=_mfulb);
				%if %eval(&nobs.>0) %then %do;
					/*Count PX lab codes)*/
						data _lkup03;
							set _mfulb(rename=codetype=codetype1);
								codetype = substr(codetype1,1,2);
								result_nc = substr(codetype1,3,1);
						run;

	        			*Extract Lab Records;
	        		    proc sql noprint;
	        			create table _mfulab03 as
	        			select claim.patid,
							   claim.group,
	        			       compress(px) as code format=$18. length=18,
	                           lkup.codetype format=$3. length=3,
							   'LB' as codecat
	        			from  DPLocal.&RUNID._Claims_lab(where=(&where.)) as claim,
							  _lkup03 as lkup
	        			where upcase(strip(lkup.codetype)) = upcase(strip(claim.px_codetype)) and
							  PX is not missing and 
							  upcase(strip(lkup.result_nc)) = upcase(strip(claim.result_type)) and 
							  %MS_PeriodsOverlap(period1=claim.IndexDt+coalesce(&MFUFROM.,-99999) claim.IndexDt+coalesce(&MFUTO.,99999),                                             
	                                            period2=claim.ADate);
	        			quit;

						proc append data=_mfulab03 base=_allmfucodes force; run;
				%end;
			%end;

			*Calculate Top XX and output aggregate dataset;
			%let countmethodvar = codecount;
			%if "&countmethod" = "P" %then %do;
				%let countmethodvar = patcount;
			%end;

			proc sql noprint;
				create table _aggregate_counts as
				select group,
					   code,
					   codecat, 
					   codetype, 
					   count(*) as codecount,
					   count(distinct patid) as patcount
				from _allmfucodes
				group by group, code, codecat, codetype
				order by group, &countmethodvar. desc;
			quit;

			data _codecounts;
				set _aggregate_counts;
				by group descending &countmethodvar.;

				analysisnum =&a.;

				if first.group then rank = 0;
				rank = rank +1;
				retain rank;

				if rank <= &topxx. then output;
			run;

			%if %eval(&a.=1) %then %do;
				data msoc.&runid._mfu&t3out.;
					set _codecounts;
				run;
			%end;
			%else %do;
				proc append data=_codecounts base=msoc.&runid._mfu&t3out. force; run;
			%end;

			proc datasets lib=work nowarn noprint;
				delete _aggregate_counts _codecounts _allmfucodes _rxxcodes11 _rxxcodes09 _dxpxcodes _mfudxpx _mfurx _mfulab _currentMFU;
			quit;
		%end; *Analysisnum loop;

		%mend;
		%isdata(dataset=infolder.&mfufile.);
		%if %eval(&nobs.>0) %then %do;
		%if "&data." = "mstr" %then %do;
			%MFU(where=1, t3out=)
			%if %eval(&type.=3) %then %do;
     		%MFU(where=analysiscohort=1 and censorenrol=0 and censordeath=0, t3out=_an);
        	%MFU(where=analysiscohort=1, t3out=_an_censor);
			%end;
		%end;
		%end;
    %END;
    %mend;
    %ADS;
%end;
%else %do;
%put WARNING: No users were identified in this request. If a baseline table was specified it will not be produced.;
%end;

%ms_stoptimer(START=&CIDACOV.);

%put NOTE: ******** END OF MACRO: ms_cidacov v2.9 ********;

%mend ms_cidacov;