****************************************************************************************************
*                                           PROGRAM OVERVIEW
****************************************************************************************************
*
* PROGRAM: ms_createpov56.sas  
*
* Created (mm/dd/yyyy): 02/02/2017
* Last modified: 11/20/2017
* Version: 1.3
*
*--------------------------------------------------------------------------------------------------
* PURPOSE:
*	This program will identify events of interest:
*	-During an episode for TYPE2 analysis
* 	-In Risk or Ctrl window for TYPE3 analysis
*
*  Program inputs:                                                                                   
*	-Dataset with valid episodes (_PtsMasterList)  
*   -Dataset with claims defined as being potential events
*   -Dataset with incidence claims that should be outside the washout period
* 
*  Program outputs:                                                                                                                                       
* 	-Dataset with valid events
* 
* PARAMETERS:
*  	-CohortId = Identifier for the cohort being processed (primary, secondary)
*
*  Programming Notes:                                                                                
*                                                                           
*
*
*--------------------------------------------------------------------------------------------------
* CONTACT INFO: 
*  Mini-Sentinel Coordinating Center
*  info@mini-sentinel.org
*
*--------------------------------------------------------------------------------------------------
*  CHANGE LOG: 
*
*   Version   Date       Initials	   Comment (reference external documentation when available)
*   -------   --------   --------   ---------------------------------------------------------------
*   1.1       07/07/17		AP		Modified to separate out events in FUP washout vs blackout period
*
*	1.2		  10/03/17		AP		Modified to consider episodes that have events during blackout period (QRP-319)
*
*	1.3		  11/20/17		AP		Removed parameter to consider episodes that have events during blackout period (QRP-466)
*
***************************************************************************************************;

%macro ms_createpov56();

%put =====> MACRO CALLED: ms_createpov56 v1.3;

	****************************************;
	* Type 2 cohort definition		 		;
	****************************************;
	%if %eval(&type=2) %then %do;

        *Find episodes with Events in T2FupWashPer;
        *If T2FupWashPer=. then patients need to never have had an Event (hence 99999); 
        proc sql noprint;
        create table _EventsInFupWash(where=(InGap=1)) as
        select distinct Epi.PatId,
                        Epi.IndexDt,
                        %MS_PeriodsOverlap(period1=Epi.IndexDt-min(Epi.T2FupWashPer,99999) Epi.IndexDt-1,                                             
                                           period2=pov5.ADate pov5.ExpireDt) as InGap
        from _PtsMasterList as Epi, 
             _FUPEvent(keep=PatId Adate Expiredt) as pov5
        where Epi.Patid = pov5.Patid
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

		*Identify episodes with Events in Blackoutwindow;
		proc sql noprint;
        create table _EventsInBlackout(where=(InGap=1)) as
        select distinct Epi.PatId,
                        Epi.IndexDt,
                        %MS_PeriodsOverlap(period1=Epi.IndexDt Epi.IndexDt+Epi.blackoutper-1,                                             
                                           period2=pov5.ADate pov5.ExpireDt) as InGap
        from _PtsMasterList as Epi, 
             _FUPEvent(keep=PatId Adate Expiredt) as pov5
        where Epi.Patid = pov5.Patid
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

        *Identify episodes with IOC in T2FupWashPer at IndexDt;
        proc sql noprint;
        create table _WashEventsInFupWash(where=(InGap=1)) as
        select distinct Epi.PatId,
                        Epi.IndexDt,
                        %MS_PeriodsOverlap(period1=Epi.IndexDt-min(Epi.T2FupWashPer,99999) Epi.IndexDt-1/*+Epi.blackoutper*/,
                                           period2=pov6.ADate pov6.ExpireDt) as InGap
        from _PtsMasterList as Epi, 
             _FUPWash(keep=PatId Adate Expiredt) as pov6
        where Epi.Patid = pov6.Patid
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

        *Keep only valid Episodes, i.e. those without events or IOC in T2FupWashPer;
        data _PtsMasterList;
        merge _PtsMasterList(in=a)
              _EventsInFupWash(in=b keep=PatId IndexDt)
              _WashEventsInFupWash(in=c keep=PatId IndexDt)
			  _EventsInBlackout(in=d keep=patid indexdt);
        by PatId IndexDt;
        if a and not b and not c and not d ;
        run;

		*Apply the EventCount parameter condition;
        %IF %EVAL(&eventcount.=1) %THEN %DO;
            proc sort nodupkey data=_FUPEvent;
            by PatId Adate codecat codetype code;
            run;
        %END;
        %IF %EVAL(&eventcount.=2) %THEN %DO;
            proc sort nodupkey data=_FUPEvent;
            by PatId Adate;
            run;
 		%END;

		*Keep only overlapping events;
      	%ms_shaveoutside(reffile=_PtsMasterList,
                         refstart=indexdt,     /*Not possible to have event in blackoutper*/
                         refend=EpisodeEndDt,
                         KeepPartBf=Y,
                         ToShaveFile=_FUPEvent,
                         ToShaveStart=Adate,
                         ToShaveEnd=ExpireDt,
                         outfile=_FUPEventShaved);

        *Identify episodes with events;
        proc sql noprint;
        create table _EPisodesWithEvents(where=(InGap=1)) as
        select distinct index.Patid,
                        index.IndexDt,
                        inc.Adate as EventDt,
						inc.Code,
                        %MS_PeriodsOverlap(period1=index.indexdt index.EpisodeEndDt,                                             
                                           period2=Inc.ADate Inc.ExpireDt) as InGap
        from _PtsMasterList as index, 
             _FUPEventShaved as Inc
        where index.Patid = Inc.Patid;
        quit;

        *Summarize Events;
        proc means data=_EPisodesWithEvents nway noprint;
        var InGap EventDt;
        class Patid IndexDt;
        output out=_EPisodesWithEvents(drop=_:) sum(InGap)=NumEvents min(EventDt)=FEventDt/KEEPLEN;
        run;

        *Get first event in any episode (for T2CohortDef ='03');
        proc means data=_EPisodesWithEvents nway noprint;
        var FEventDt;
        class PatId;
        output out=_FirstEventDtInEpisode(drop=_:) min(FEventDt)=FEventDt_Any/KEEPLEN;
        run;        

    %end;  

	****************************************;
	* Type 3 cohort definition 				;
	****************************************;
    %if %eval(&type=3) %then %do; 

        *Find all events in CTRL window;
        proc sql noprint;
        create table _CtrlEventsInWin as
        select distinct Epi.PatId,
               Epi.IndexDt,
               Epi.LookBackLength,
               1 as CtrlEventInWin,
               min(max(T3CtrlFromDt,Ctrl.ADate)) as CtrlEventDt  format=date9. /*Adate is either before or in the interval*/
        from _PtsMasterList as Epi, 
             _FUPEvent(keep=PatId Adate Expiredt) as Ctrl
        where Epi.Patid = Ctrl.Patid and 
              %MS_PeriodsOverlap(period1=Epi.T3CtrlFromDt Epi.T3CtrlToDt,                                             
                                           period2=Ctrl.ADate Ctrl.ExpireDt)
        group by Epi.PatId,
                 Epi.IndexDt
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

        *Find all CTRL window events with prior events in LookBackLengthWin;
        proc sql noprint;
        create table _CtrlEventsInLookBackWin as
        select distinct Epi.PatId,
                        Epi.IndexDt,
                        1 as CtrlEventInLookBackWin
        from _CtrlEventsInWin as Epi, 
             _FUPEvent(keep=PatId Adate Expiredt) as Ctrl
        where Epi.Patid = Ctrl.Patid and 
              %MS_PeriodsOverlap(period1=Epi.CtrlEventDt-LookBackLength Epi.CtrlEventDt-1,                                             
                                 period2=Ctrl.ADate Ctrl.ExpireDt)
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

        *Find all CTRL window events with prior WASH events in LookBackLengthWin;
        proc sql noprint;
        create table _CtrlWashEventsInLBWin as
        select distinct Epi.PatId,
                        Epi.IndexDt,
                        1 as CtrlWashEventInLookBackWin
        from _CtrlEventsInWin as Epi, 
             _FUPWash(keep=PatId Adate Expiredt) as Ctrl
        where Epi.Patid = Ctrl.Patid and
              %MS_PeriodsOverlap(period1=Epi.CtrlEventDt-LookBackLength Epi.CtrlEventDt-1,                                     
                                 period2=Ctrl.ADate Ctrl.ExpireDt)
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

        *Find all events in RISK window;
        proc sql noprint;
        create table _RiskEventsInWin as
        select distinct Epi.PatId,
               Epi.IndexDt,
               Epi.LookBackLength,
               1 as RiskEventInWin,
               min(max(T3RiskFromDt,Risk.ADate)) as RiskEventDt  format=date9. /*Adate is either before or in the interval*/
        from _PtsMasterList as Epi, 
             _FUPEvent(keep=PatId Adate Expiredt) as Risk
        where Epi.Patid = Risk.Patid and 
              %MS_PeriodsOverlap(period1=Epi.T3RiskFromDt Epi.T3RiskToDt,                                             
                                           period2=Risk.ADate Risk.ExpireDt)
        group by Epi.PatId,
                 Epi.IndexDt
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

        *Find all RISK window events with prior events in LookBackLengthWin;
        proc sql noprint;
        create table _RiskEventsInLookBackWin as
        select distinct Epi.PatId,
                        Epi.IndexDt,
                        1 as RiskEventInLookBackWin
        from _RiskEventsInWin as Epi, 
             _FUPEvent(keep=PatId Adate Expiredt) as Risk
        where Epi.Patid = Risk.Patid and 
              %MS_PeriodsOverlap(period1=Epi.RiskEventDt-LookBackLength Epi.RiskEventDt-1,                                             
                                 period2=Risk.ADate Risk.ExpireDt)
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

        *Find all RISK window events with prior WASH events in LookBackLengthWin;
        proc sql noprint;
        create table _RiskWashEventsInLBWin as
        select distinct Epi.PatId,
                        Epi.IndexDt,
                        1 as RiskWashEventInLookBackWin
        from _RiskEventsInWin as Epi, 
             _FUPWash(keep=PatId Adate Expiredt) as Risk
        where Epi.Patid = Risk.Patid and
              %MS_PeriodsOverlap(period1=Epi.RiskEventDt-LookBackLength Epi.RiskEventDt-1,                                     
                                 period2=Risk.ADate Risk.ExpireDt)
        order by Epi.Patid,
                 Epi.indexDt;
        quit;

        *Keep only valid events (event in only one window);
        data _Events;
        merge _CtrlEventsInWin
              _CtrlEventsInLookBackWin
              _CtrlWashEventsInLBWin
              _RiskEventsInWin
              _RiskEventsInLookBackWin
              _RiskWashEventsInLBWin;
        by PatId IndexDt;

        *Patients need to have at least one event in one of the windows;		                
        format FEventDt date9.;
        FEventDt=min(RiskEventDt,CtrlEventDt);

        if (CtrlEventInWin and not CtrlEventInLookBackWin and not CtrlWashEventInLookBackWin) then do;
            WinOfEvent="CTRL";
            output;
        end;
        else if (RiskEventInWin and not RiskEventInLookBackWin and not RiskWashEventInLookBackWin) then do;
            WinOfEvent="RISK";
            output;
        end;        

        keep PatId IndexDt FEventDt WinOfEvent;
        run;

        *Remove true duplicates;
        proc sort nodupkey data=_Events;
        by PatId IndexDt FEventDt WinOfEvent;
        run;        	
	
    %end;

%put NOTE: ********END OF MACRO: ms_createpov56 v1.3********;

%mend ms_createpov56;