cap program drop synth_est
version 14
program define synth_est
	syntax [anything] , runs(integer) database(string) dir_sim(string) dir_dataout(string) [neg_w rpath(string)]

	quietly{

	loc nw = 0
	loc nwname = ""
	loc upperw = 6
	loc lowerw = 0
	loc type NotRecycling

	if "`neg_w'" =="neg_w"{
		loc nw = 1
		loc nwname = "_negW"
		loc lambda "0.001"
		local input1  temp/input1_`database'`nwname'.dta
		local output1 temp/output1_`database'`nwname'.dta
	}

	import delimited "`dir_sim'/`database'.csv" , clear

	destring eventtime , replace force
	gen z = (eventtime >= 0)
	replace z = 0 if eventtime == .

	save "temp/`database'`nwname'.dta", replace

	forvalues k = 1/`runs'{

		tempvar treated_periods donor mean
		loc run = `k'

		use "temp/`database'`nwname'.dta" if run == `run', clear
		sum time
		loc tmax = r(max)
		egen `treated_periods' = total(z) , by(index)
		replace z = 0 if `treated_periods' == `tmax'
		replace `treated_periods' = 0 if `treated_periods' == `tmax'

		noi di "Run: " `run'
		levelsof `treated_periods' if `treated_periods' != 0 , loc(tr)
		noi di "Running Synthetic Control Estimations..."
		glo treated ""
		foreach p in `tr' {
			levelsof index if `treated_periods' == `p' , loc(u)
			foreach i in `u'{
				preserve
					gen `donor' = 0
					replace `donor' = 1 if `treated_periods' == 0
					if `upperw' != 0{
						replace `donor' = 1 if `treated_periods' <= `p'- `upperw'
					}
					if `lowerw' != 0{
						replace `donor' = 1 if `treated_periods' >= `p'+ `lowerw'
					}
					keep if `donor' == 1 | index == `i'
					count if `donor' == 1
					loc t = `tmax'-`p'
					loc t2 = `tmax'-`p'+1
					if `t' > 1{
						keep if time <= `t'+6
						glo trend = ""
						forvalues k = 1(1)`t'{
							glo trend = "$trend y(`k')"
						}
						tsset index time
						tempfile sr`i'
						if `nw'==1{
							sum `treated_periods' if index == `i'
							loc trp = r(max)
							if `trp' < `tmax'-2 {
								glo treated "$treated `i'"
								save `input1' , replace
								rscript using "source/lib/R/sc/negativeWeightsSC.R" ///
									, ///
									rpath("`rpath'") ///
									args("`input1'" "`output1'" "`lambda'") ///
									force
								use "`output1'" , clear
								rename time _time
								rename estimate _Y_synthetic
								foreach var in _Co_Number _W_Weight _Y_treated{
								 gen `var' = .
								}
								save `sr`i'' , replace
								erase `output1'
								use `input1' , clear
							}
						}
						else {
							glo treated "$treated `i'"
							synth y $trend , trunit(`i') trperiod(`t2') keep(`sr`i'') replace
						}
						keep index time eventtime
						keep if index == `i'
						drop if time == .
						drop if eventtime == .
						tempfile t_`i'
						save `t_`i'' , replace
					}
				restore
			}
		}
		noi di "Synthetic Control Estimations Complete."
		noi di "Calculating mean effect..."
		loc cont = 0
		if `upperw' == 0{
			loc upperw2 = 6
		}
		else{
			loc upperw2 = `upperw'
		}
		foreach i in $treated {
			use `sr`i'' , clear
			rename _time time
			drop if time == .
			merge 1:1 time using `t_`i''
			drop _merge
			keep if inrange(eventtime,-6,`upperw2')
			if `nw' == 0{
				gen estimated_effect_`i' = _Y_treated - _Y_synthetic
			}
			else{
				gen estimated_effect_`i' =  _Y_synthetic
			}

			keep eventtime estimated_effect_`i'
			if `cont' == 0 {
				count
				if r(N) < 6+`upperw2'{
					loc f = 6+`upperw2'-r(N)
					loc N = _N+`f'
					set obs `N'
					sum eventtime
					loc min = r(min)
					loc max = r(max)
					if `min' > -6{
						loc lim = abs(-6)-abs(`min')
						forvalues k = 1/`lim'{
							loc pos = _N-`k'+1
							replace eventtime = -6+(`k'-1) in `pos'
						}
						sort eventtime
					}
					if `max' < `upperw2'-1{
						loc lim = `upperw2'-1-`max'
						forvalues k = 1/`lim'{
								loc pos = _N-`k'+1
								replace eventtime = `max'+`k' in `pos'
						}
						sort eventtime
					}
				}
				sort eventtime
				tempfile results_run`run'_uw`upperw'_lw`lowerw'
				save `results_run`run'_uw`upperw'_lw`lowerw'' , replace
				loc ++cont
			}
			else{
				merge 1:1 eventtime using `results_run`run'_uw`upperw'_lw`lowerw''
				drop _merge
				save `results_run`run'_uw`upperw'_lw`lowerw'' , replace
			}
		}
		egen mean_effect_`run' = rowmean(estimated_effect_*)
		save `results_run`run'_uw`upperw'_lw`lowerw'' , replace
		noi di "Mean effect complete."

	}

	loc cont = 0

	forvalues k = 1/`runs'{
		loc run = `k'
		if `cont' == 0{
			use `results_run`run'_uw`upperw'_lw`lowerw'' , clear
			keep eventtime mean_effect*
			loc ++cont
		}
		else{
			merge 1:1 eventtime using `results_run`run'_uw`upperw'_lw`lowerw'', keepusing(mean_effect_`run')
			keep if _merge == 3
			drop _merge
		}
	}
	egen median=rowmedian(mean_effect_*)
	egen top2_5=rowpctile(mean_effect_*) , p(97.5)
	egen bottom2_5=rowpctile(mean_effect_*) , p(2.5)

	if `nw' == 1{
		save "`dir_dataout'/`database'_`type'`nwname'" , replace
		export delimited "`dir_dataout'/`database'_`type'`nwname'.csv", replace
	}
	else{
		save "`dir_dataout'/`database'_`type'" , replace
		export delimited "`dir_dataout'/`database'_`type'.csv", replace
	}

	noi di "End of command."
	}
end
