Spelling correction

Spelling correction

Corrected spelling from untiofobs to unitof obs

{smcl}
{* 15 Dec 2017}{...}
{hline}
help for {hi:iefolder}
{hline}

{title:Title}

{phang2}{cmdab:iefolder} {hline 2} sets up project folders and master do-files according to World Bank DIME's standards.{p_end}

{phang2}For a more descriptive discussion on the intended usage and work flow of this
command please see the {browse "https://dimewiki.worldbank.org/wiki/Iefolder":DIME Wiki}.

{title:Syntax}

{pstd} {ul:When initially setting up the {hi:DataWork} folder in a new project:}{p_end}

{phang2}{cmd:iefolder} new project, {cmdab:proj:ectfolder(}{it:directory}{cmd:)} {p_end}

{pstd} {ul:When adding folders to and already existing {hi:DataWork} folder:}{p_end}

{phang2}{cmd:iefolder} new {it:itemtype} {it:itemname} , {cmdab:proj:ectfolder(}{it:directory}{cmd:)}
	[{cmdab:abb:reviation(}{it:string}{cmd:)} {cmdab:sub:folder(}{it:folder}{cmd:)}] {p_end}

{pmore}where {it:itemtype} is either {it:round}, {it:unitofobs} or {it:subfolder}. See
	details on {it:itemtype} and {it:itemname} below.{p_end}

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt : {cmdab:proj:ectfolder(}{it:dir}{cmd:)}}The location of
	the project folder where the {hi:DataWork} folder should be
	created (new projects), or where it is located (new rounds, unitofobs and subfolders).{p_end}
{synopt : {cmdab:abb:reviation(}{it:string}{cmd:)}}Optional abbreviation
	of round name to be used to make globals shorter. Can only be used
	when {it:itemtype} is round.{p_end}
{synopt : {cmdab:sub:folder(}{it:folder}{cmd:)}}Creates the round folders inside
	a subfolder to DataWork. Only works with new rounds and only after the subfolder
	has been created with {it:iefolder new subfolder}.{p_end}
{synoptline}

{marker desc}{title:Description}

{pstd}{cmdab:iefolder} automates the process of setting up the folders and master do-files
	where all the data work will take place in a project folder. The folder structure set
	up by {cmdab:iefolder} follows {browse "https://dimewiki.worldbank.org/wiki/DataWork_Folder":DIME's best practices}.

{pstd}In addition to setting up the {hi:DataWork} folder and its folder structure, the
	command creates master do-files linking to all main folders in the folder structure. These
	master do-files are updated whenever more rounds, units of observations, and
	subfolders are added to the project folder using this command.

{pstd}{ul:{hi:itemtypes}}{break} This command can create either a new DataWork folder or add folders to an
	existing DataWork folder. The existing DataWork folder must have been created
	with {cmd:iefolder} for the additions to work. A new DataWork folder is created using specifying {ul:project}. There are three types of folders that can be added to an existing folder by specifying {ul:round}, {ul:unitofobs} or {ul:subfolder}. See
	next paragraphs for descriptions.

{pstd}{ul:{it:project}} sets up a new DataWork folder and its initial folder structure. You must always do this before you can do anything else. It also sets up the main master do-file for this DataWork folder. {cmd:iefolder} is implemented so that you can keep working for years with your project in between adding folders. The command reads and preserves changes made manually to the DataWork folder and master do-file before adding more folders using {cmd:iefolder}.

{pstd}{ul:{it:round}} folders are folders specific to a data collection round, for example, {it:Baseline}, {it:Endline},
	{it:Follow Up} etc. (See {it:subfolder} below if your project is more complex than that.) When adding a new round, a round folder are added to the DataWork
	and inside it the round folder structure described {browse "https://dimewiki.worldbank.org/wiki/DataWork_Survey_Round":here}. {cmd:iefolder} also
	creates a master do-file specific for this round with globals referencing the main folders
	in the folder structure specific to this round. Folders are created in two places, both in the DataWork folder, and in the Encrypted folder.

{pstd}{ul:{it:unitofobs}} folders are folders specific to a unit of observation,
	for example the master data set folder. Read more about master data sets and the folder structure
	this commands sets up for you at {browse "https://dimewiki.worldbank.org/wiki/Master_Data_Set":here}. A
	master data folder for each new unit of observation is created in two places. Both in
	the MasterData folder in the DataWork folder, and in the Encrypted folder.

{pstd}{ul:{it:subfolder}} can be used to organize folders with a lot of data collections. For examples, instead of having only one baseline data collection, a project might have a student, a teacher, and a school data collections all in baseline. With {it:subfolder} you can, using this example, create a folder called Baseline in the DataWork folder, and when creating the rounds for student, teacher and school, you can create those round inside the Baseline folder using the option {cmd:subfolder(}{it:Baseline}{cmd:)}. When creating a subfolder, only a single folder is created in the DataWork folder and it is empty. The main master do-file is however updated with a global to this folder.

{marker optslong}{title:Options}

{phang}{cmdab:proj:ectfolder(}{it:dir}{cmd:)} should point to the same folder regardless
	of which {it:itemtype} is created. If {it:new project} is specified, the file path should
	point to where DataWork should be created, and if {it:new round} or {it:new project} is
	specified, it should point to where DataWork was already created. See how the file path is
	the same both time when {cmd:iefolder} is called twice in Example 1 below.

{phang}{cmdab:abb:reviation(}{it:string}{cmd:)} can be used to shorten the globals created
	in the master do-files that point to the sub-folders to {it:round} folders. For example,
	if you create a new {it:round} called Baseline, as in Example 1, then a global to the
	DataSet folder called Baseline_dt will be created in the master do-file. If the
	abbreviation option would have been used, like in Example 2, then the global would
	have been called BL_dt.

{phang}{cmdab:sub:folder(}{it:folder}{cmd:)} creates a round folder inside the folder specified in this option. This option can only be used when creating a new round. The folder specified must have been created using {cmd:iefolder}. See example 3.

{title:Examples}

{pstd}{hi:Example 1.}

{pmore}{inp:global projectFolder "C:\Users\Documents\DropBox\ProjectABC"}

{pmore}{inp:iefolder new project , projectfolder("$projectFolder")}{break}
{inp:iefolder new round baseline , projectfolder("$projectFolder")}

{pstd}In the example above, in the line the first time {cmd:iefolder} is used, a folder
	called {hi:DataWork} is created at the location of {it:"C:\Users\Documents\DropBox\ProjectABC"}.
	In the line where {cmd:iefolder} used a second time, a folder for the baseline round
	is created inside the {hi:DataWork} folder. Note that the folder provided
	in {inp:projectfolder()} is the same both times.

{pstd}Both the {hi:DataWork} folder and the {hi:baseline} folder created have sub-folders
	and master do-files creating globals pointing to these.

{pstd}{hi:Example 2.}

{pmore}{inp:global projectFolder "C:\Users\Documents\DropBox\ProjectABC"}

{pmore}{inp:iefolder new project , projectfolder("$projectFolder")}{break}
{inp:iefolder new round baseline , projectfolder("$projectFolder") abbreviation("BL")}

{pstd}The example above creates the same folder structure as in Example 1, but
	in the globals in the master do-files the abbreviation BL is used instead of
	baseline. But the folders created on disk will still be called baseline.

{pstd} {hi:Example 3.}

{pstd}This example shows how to use subfolders.

{pmore}{inp:global projectFolder "C:\Users\Documents\DropBox\ProjectABC"}

{pmore}{inp:iefolder new project , projectfolder("$projectFolder")}

{pmore}{inp:iefolder new subfolder baseline , projectfolder("$projectFolder")}{break}
{inp:iefolder new round studentBL , projectfolder("$projectFolder") subfolder("baseline")}{break}
{inp:iefolder new round teacherBL , projectfolder("$projectFolder") subfolder("baseline")}

{pstd}The code above creates a new {hi:DataWork} folder inside the folder ProjectABC. Then {hi:subfolder} is used to create a folder called baseline. Then the two baseline rounds, student and teacher, are created inside the folder baseline.

{pstd}The code below shows how the endline folder can be created in the same folder. Note that the rounds need to have unique names even across subfolders, and that is why the student and teacher round have the suffix EL.

{pmore}{inp:global projectFolder "C:\Users\Documents\DropBox\ProjectABC"}

{pmore}{inp:iefolder new subfolder endline , projectfolder("$projectFolder")}{break}
{inp:iefolder new round studentEL , projectfolder("$projectFolder") subfolder("endline")}{break}
{inp:iefolder new round teacherEL , projectfolder("$projectFolder") subfolder("endline")}

{pstd} {hi:Example 4.}

{pstd}The example below is meant to describe an intended workflow for a full
	life cycle of an impact evaluation. First we need to set up the {hi:DataWork} folder.
	We do that using {it:{cmd:iefolder} new project}. Like this:

{pmore}{inp:iefolder new project , projectfolder("C:\DropBox\ProjectABC")}

{pstd}Our first data collection will be a baseline where the unit of observation
	is households. We therefore need to set up folders for the unit of observation
	"households". In the encrypted master folder for "housholds" you can create your
	list over households and you have a subfolder called {it:Sampling} where you
	can keep do files and data with identifying infomration. We create all of that by
	using {it:{cmd:iefolder} new untiofobs household}.	Like this:

{pmore}{inp:iefolder new untiofobs household , projectfolder("C:\DropBox\ProjectABC") abbreviation("BL")}

{pstd}When we are ready to start preparing for the baseline we want to create the
	baseline folder. We do that using {it:{cmd:iefolder} new round baseline}. Like this:

{pmore}{inp:iefolder new round baseline , projectfolder("C:\DropBox\ProjectABC") abbreviation("BL")}

{pstd}At this point we can collect the baseline data, save the data in the folders
	we created and write the report. Then long stretches of time might pass before
	we need to use the command.

{pstd}Let's say that when we plan for midline we also want
	to collect data about the villages that the households we interview in baseline
	live in. Then we need to create a new master folder for the unit of observation
	villages. We do that using {it:{cmd:iefolder} new untiofobs village}. Like this:

{pmore}{inp:iefolder new untiofobs village , projectfolder("C:\DropBox\ProjectABC")}

{pstd}Then we need to create the rounds used for the midline round for both
	households and for villages. Since this is separate data collection (although
	they might happen at the same time). We create those folders like this:

{pmore}{inp:iefolder new round midline {space 6}, projectfolder("C:\DropBox\ProjectABC") abbreviation("ML")}{break}
{inp:iefolder new round midlineVillage, projectfolder("C:\DropBox\ProjectABC") abbreviation("MLvill")}

{pstd}Finally, in the last round of data collection, we are only collecting data
	on households again. Since we are not collecting data on any new unit
	of observation, we do not need to create any new master folder.

{pmore}{inp:iefolder new round endline , projectfolder("C:\DropBox\ProjectABC") abbreviation("EL")}

{title:Acknowledgements}

{phang}I would like to acknowledge the help in testing and proofreading I received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Guadalupe Bedoya{break}Laura Costica{break}Luiza Cardoso De Andrade{break}Mrijan Rimal{break}Sakina Shibuya{break}Seungmin Lee

{title:Author}

{phang}Kristoffer Bjarkefur, The World Bank, DECIE

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit iefolder" in the subject line to:{break}
		 kbjarkefur@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through
		 the github repository of ietoolkit:{break}
		 {browse "https://github.com/worldbank/ietoolkit"}

{smcl}
{* 15 Dec 2017}{...}
{hline}
help for {hi:iefolder}
{hline}

{title:Title}

{phang2}{cmdab:iefolder} {hline 2} sets up project folders and master do-files according to World Bank DIME's standards.{p_end}

{phang2}For a more descriptive discussion on the intended usage and work flow of this
command please see the {browse "https://dimewiki.worldbank.org/wiki/Iefolder":DIME Wiki}.

{title:Syntax}

{pstd} {ul:When initially setting up the {hi:DataWork} folder in a new project:}{p_end}

{phang2}{cmd:iefolder} new project, {cmdab:proj:ectfolder(}{it:directory}{cmd:)} {p_end}

{pstd} {ul:When adding folders to and already existing {hi:DataWork} folder:}{p_end}

{phang2}{cmd:iefolder} new {it:itemtype} {it:itemname} , {cmdab:proj:ectfolder(}{it:directory}{cmd:)}
	[{cmdab:abb:reviation(}{it:string}{cmd:)} {cmdab:sub:folder(}{it:folder}{cmd:)}] {p_end}

{pmore}where {it:itemtype} is either {it:round}, {it:unitofobs} or {it:subfolder}. See
	details on {it:itemtype} and {it:itemname} below.{p_end}

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt : {cmdab:proj:ectfolder(}{it:dir}{cmd:)}}The location of
	the project folder where the {hi:DataWork} folder should be
	created (new projects), or where it is located (new rounds, unitofobs and subfolders).{p_end}
{synopt : {cmdab:abb:reviation(}{it:string}{cmd:)}}Optional abbreviation
	of round name to be used to make globals shorter. Can only be used
	when {it:itemtype} is round.{p_end}
{synopt : {cmdab:sub:folder(}{it:folder}{cmd:)}}Creates the round folders inside
	a subfolder to DataWork. Only works with new rounds and only after the subfolder
	has been created with {it:iefolder new subfolder}.{p_end}
{synoptline}

{marker desc}{title:Description}

{pstd}{cmdab:iefolder} automates the process of setting up the folders and master do-files
	where all the data work will take place in a project folder. The folder structure set
	up by {cmdab:iefolder} follows {browse "https://dimewiki.worldbank.org/wiki/DataWork_Folder":DIME's best practices}.

{pstd}In addition to setting up the {hi:DataWork} folder and its folder structure, the
	command creates master do-files linking to all main folders in the folder structure. These
	master do-files are updated whenever more rounds, units of observations, and
	subfolders are added to the project folder using this command.

{pstd}{ul:{hi:itemtypes}}{break} This command can create either a new DataWork folder or add folders to an
	existing DataWork folder. The existing DataWork folder must have been created
	with {cmd:iefolder} for the additions to work. A new DataWork folder is created using specifying {ul:project}. There are three types of folders that can be added to an existing folder by specifying {ul:round}, {ul:untiofobs} or {ul:subfolder}. See
	next paragraphs for descriptions.

{pstd}{ul:{it:project}} sets up a new DataWork folder and its initial folder structure. You must always do this before you can do anything else. It also sets up the main master do-file for this DataWork folder. {cmd:iefolder} is implemented so that you can keep working for years with your project in between adding folders. The command reads and preserves changes made manually to the DataWork folder and master do-file before adding more folders using {cmd:iefolder}.

{pstd}{ul:{it:round}} folders are folders specific to a data collection round, for example, {it:Baseline}, {it:Endline},
	{it:Follow Up} etc. (See {it:subfolder} below if your project is more complex than that.) When adding a new round, a round folder are added to the DataWork
	and inside it the round folder structure described {browse "https://dimewiki.worldbank.org/wiki/DataWork_Survey_Round":here}. {cmd:iefolder} also
	creates a master do-file specific for this round with globals referencing the main folders
	in the folder structure specific to this round. Folders are created in two places, both in the DataWork folder, and in the Encrypted folder.

{pstd}{ul:{it:unitofobs}} folders are folders specific to a unit of observation,
	for example the master data set folder. Read more about master data sets and the folder structure
	this commands sets up for you at {browse "https://dimewiki.worldbank.org/wiki/Master_Data_Set":here}. A
	master data folder for each new unit of observation is created in two places. Both in
	the MasterData folder in the DataWork folder, and in the Encrypted folder.

{pstd}{ul:{it:subfolder}} can be used to organize folders with a lot of data collections. For examples, instead of having only one baseline data collection, a project might have a student, a teacher, and a school data collections all in baseline. With {it:subfolder} you can, using this example, create a folder called Baseline in the DataWork folder, and when creating the rounds for student, teacher and school, you can create those round inside the Baseline folder using the option {cmd:subfolder(}{it:Baseline}{cmd:)}. When creating a subfolder, only a single folder is created in the DataWork folder and it is empty. The main master do-file is however updated with a global to this folder.

{marker optslong}{title:Options}

{phang}{cmdab:proj:ectfolder(}{it:dir}{cmd:)} should point to the same folder regardless
	of which {it:itemtype} is created. If {it:new project} is specified, the file path should
	point to where DataWork should be created, and if {it:new round} or {it:new project} is
	specified, it should point to where DataWork was already created. See how the file path is
	the same both time when {cmd:iefolder} is called twice in Example 1 below.

{phang}{cmdab:abb:reviation(}{it:string}{cmd:)} can be used to shorten the globals created
	in the master do-files that point to the sub-folders to {it:round} folders. For example,
	if you create a new {it:round} called Baseline, as in Example 1, then a global to the
	DataSet folder called Baseline_dt will be created in the master do-file. If the
	abbreviation option would have been used, like in Example 2, then the global would
	have been called BL_dt.

{phang}{cmdab:sub:folder(}{it:folder}{cmd:)} creates a round folder inside the folder specified in this option. This option can only be used when creating a new round. The folder specified must have been created using {cmd:iefolder}. See example 3.

{title:Examples}

{pstd}{hi:Example 1.}

{pmore}{inp:global projectFolder "C:\Users\Documents\DropBox\ProjectABC"}

{pmore}{inp:iefolder new project , projectfolder("$projectFolder")}{break}
{inp:iefolder new round baseline , projectfolder("$projectFolder")}

{pstd}In the example above, in the line the first time {cmd:iefolder} is used, a folder
	called {hi:DataWork} is created at the location of {it:"C:\Users\Documents\DropBox\ProjectABC"}.
	In the line where {cmd:iefolder} used a second time, a folder for the baseline round
	is created inside the {hi:DataWork} folder. Note that the folder provided
	in {inp:projectfolder()} is the same both times.

{pstd}Both the {hi:DataWork} folder and the {hi:baseline} folder created have sub-folders
	and master do-files creating globals pointing to these.

{pstd}{hi:Example 2.}

{pmore}{inp:global projectFolder "C:\Users\Documents\DropBox\ProjectABC"}

{pmore}{inp:iefolder new project , projectfolder("$projectFolder")}{break}
{inp:iefolder new round baseline , projectfolder("$projectFolder") abbreviation("BL")}

{pstd}The example above creates the same folder structure as in Example 1, but
	in the globals in the master do-files the abbreviation BL is used instead of
	baseline. But the folders created on disk will still be called baseline.

{pstd} {hi:Example 3.}

{pstd}This example shows how to use subfolders.

{pmore}{inp:global projectFolder "C:\Users\Documents\DropBox\ProjectABC"}

{pmore}{inp:iefolder new project , projectfolder("$projectFolder")}

{pmore}{inp:iefolder new subfolder baseline , projectfolder("$projectFolder")}{break}
{inp:iefolder new round studentBL , projectfolder("$projectFolder") subfolder("baseline")}{break}
{inp:iefolder new round teacherBL , projectfolder("$projectFolder") subfolder("baseline")}

{pstd}The code above creates a new {hi:DataWork} folder inside the folder ProjectABC. Then {hi:subfolder} is used to create a folder called baseline. Then the two baseline rounds, student and teacher, are created inside the folder baseline.

{pstd}The code below shows how the endline folder can be created in the same folder. Note that the rounds need to have unique names even across subfolders, and that is why the student and teacher round have the suffix EL.

{pmore}{inp:global projectFolder "C:\Users\Documents\DropBox\ProjectABC"}

{pmore}{inp:iefolder new subfolder endline , projectfolder("$projectFolder")}{break}
{inp:iefolder new round studentEL , projectfolder("$projectFolder") subfolder("endline")}{break}
{inp:iefolder new round teacherEL , projectfolder("$projectFolder") subfolder("endline")}

{pstd} {hi:Example 4.}

{pstd}The example below is meant to describe an intended workflow for a full
	life cycle of an impact evaluation. First we need to set up the {hi:DataWork} folder.
	We do that using {it:{cmd:iefolder} new project}. Like this:

{pmore}{inp:iefolder new project , projectfolder("C:\DropBox\ProjectABC")}

{pstd}Our first data collection will be a baseline where the unit of observation
	is households. We therefore need to set up folders for the unit of observation
	"households". In the encrypted master folder for "housholds" you can create your
	list over households and you have a subfolder called {it:Sampling} where you
	can keep do files and data with identifying infomration. We create all of that by
	using {it:{cmd:iefolder} new untiofobs household}.	Like this:

{pmore}{inp:iefolder new untiofobs household , projectfolder("C:\DropBox\ProjectABC") abbreviation("BL")}

{pstd}When we are ready to start preparing for the baseline we want to create the
	baseline folder. We do that using {it:{cmd:iefolder} new round baseline}. Like this:

{pmore}{inp:iefolder new round baseline , projectfolder("C:\DropBox\ProjectABC") abbreviation("BL")}

{pstd}At this point we can collect the baseline data, save the data in the folders
	we created and write the report. Then long stretches of time might pass before
	we need to use the command.

{pstd}Let's say that when we plan for midline we also want
	to collect data about the villages that the households we interview in baseline
	live in. Then we need to create a new master folder for the unit of observation
	villages. We do that using {it:{cmd:iefolder} new untiofobs village}. Like this:

{pmore}{inp:iefolder new untiofobs village , projectfolder("C:\DropBox\ProjectABC")}

{pstd}Then we need to create the rounds used for the midline round for both
	households and for villages. Since this is separate data collection (although
	they might happen at the same time). We create those folders like this:

{pmore}{inp:iefolder new round midline {space 6}, projectfolder("C:\DropBox\ProjectABC") abbreviation("ML")}{break}
{inp:iefolder new round midlineVillage, projectfolder("C:\DropBox\ProjectABC") abbreviation("MLvill")}

{pstd}Finally, in the last round of data collection, we are only collecting data
	on households again. Since we are not collecting data on any new unit
	of observation, we do not need to create any new master folder.

{pmore}{inp:iefolder new round endline , projectfolder("C:\DropBox\ProjectABC") abbreviation("EL")}

{title:Acknowledgements}

{phang}I would like to acknowledge the help in testing and proofreading I received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Guadalupe Bedoya{break}Laura Costica{break}Luiza Cardoso De Andrade{break}Mrijan Rimal{break}Sakina Shibuya{break}Seungmin Lee

{title:Author}

{phang}Kristoffer Bjarkefur, The World Bank, DECIE

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit iefolder" in the subject line to:{break}
		 kbjarkefur@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through
		 the github repository of ietoolkit:{break}
		 {browse "https://github.com/worldbank/ietoolkit"}


Preserve UCINumeric

Preserve UCINumeric

drop if year == .
notes drop _dta

rename UCINumeric country
gen UCINumeric = country
label variable country "Country"
label variable year "Year"
order country year UCI*
sort country year

compress
save "$FILENAME", replace

drop if year == .
notes drop _dta

rename UCINumeric country
label variable country "Country"
label variable year "Year"
order country year UCI*
sort country year

compress
save "$FILENAME", replace


cookbook/container: skip on missing cpio and missing kvm kernel image.

exec >&2   # any output we produce is a log message
no_simple=
no_debian=
no_runlocal=
no_runkvm=
no_docker=

if ! ./need.sh ldd; then
	echo "skipping simple image."
	no_simple=1
fi
if ! ./need.sh debootstrap eatmydata; then
	echo "skipping debian image."
	no_debian=1
fi
if ! ./need.sh cpio; then
	echo "skipping tarball generation."
	no_image=1
fi
if ! ./need.sh fakeroot fakechroot ||
   ! ./try_fakeroot.sh "x" true 2>/dev/null; then
	echo "skipping chroot test."
	no_runlocal=1
	echo "skipping debian image."
	no_debian=1
fi
if ! ./need.sh unshare ||
   ! unshare -r true 2>/dev/null; then
	echo " -- 'unshare -r' command doesn't work."
	echo "skipping chroot test."
	no_runlocal=1
fi
if ! ./need.sh busybox kvm cpio; then
	echo "skipping kvm test."
	no_runkvm=1
fi
kernel="/boot/vmlinuz-$(uname -r)"
if ! [ -e "$kernel" ]; then
	echo " -- missing kernel: $kernel"
	echo "skipping kvm test."
	no_runkvm=1
fi
if ! ./need.sh docker cpio ||
   ! docker images >/dev/null; then
	echo "skipping docker test."
	no_docker=1
fi
if [ -n "$NO_SLOW_TESTS" ]; then
	echo " -- NO_SLOW_TESTS is set."
	echo "skipping debian image."
	no_debian=1
fi

add() { targets="$targets $*"; }

[ -z "$no_simple$no_image" ] && add simple.image.gz
[ -z "$no_simple$no_runlocal" ] && add libs.runlocal
[ -z "$no_simple$no_runkvm" ] && add libs.runkvm
[ -z "$no_simple$no_docker" ] && add simple.rundocker

[ -z "$no_debian$no_image" ] && add debian.image
[ -z "$no_debian$no_runlocal" ] && add debian.runlocal
[ -z "$no_debian$no_runkvm" ] && add debian.runkvm
[ -z "$no_debian$no_docker" ] && add debian.rundocker

redo-ifchange $targets

check() {
	label=$1
	shift
	printf "checking %-18s %-35s " "$label:" "$*" >&2
	if test "$@"; then
		printf "ok\n" >&2
	else
		printf "failed\n" >&2
	fi
}

hellocheck() {
	check "$1" "$(cat "$1")" = "Hello, world!"
}

debcheck() {
	check "$1" "$(cat "$1")" -ge "70"
	check "$1" "$(cat "$1")" -le "100"
}

if [ -z "$no_simple" ]; then
	[ -n "$no_runlocal" ] || hellocheck libs.runlocal
	[ -n "$no_runkvm" ] || hellocheck libs.runkvm
	[ -n "$no_docker" ] || hellocheck simple.rundocker
fi

if [ -z "$no_debian" ]; then
	[ -n "$no_runlocal" ] || debcheck debian.runlocal
	[ -n "$no_runkvm" ] || debcheck debian.runkvm
	[ -n "$no_docker" ] || debcheck debian.rundocker
fi

exec >&2   # any output we produce is a log message
no_simple=
no_debian=
no_runlocal=
no_runkvm=
no_docker=

if ! ./need.sh ldd; then
	echo "skipping simple image."
	no_simple=1
fi
if ! ./need.sh debootstrap eatmydata; then
	echo "skipping debian image."
	no_debian=1
fi
if ! ./need.sh fakeroot fakechroot ||
   ! ./try_fakeroot.sh "x" true 2>/dev/null; then
	echo "skipping chroot test."
	no_runlocal=1
	echo "skipping debian image."
	no_debian=1
fi
if ! ./need.sh unshare ||
   ! unshare -r true 2>/dev/null; then
	echo " -- 'unshare -r' command doesn't work."
	echo "skipping chroot test."
	no_runlocal=1
fi
if ! ./need.sh busybox kvm; then
	echo "skipping kvm test."
	no_runkvm=1
fi
if ! ./need.sh docker ||
   ! docker images >/dev/null; then
	echo "skipping docker test."
	no_docker=1
fi
if [ -n "$NO_SLOW_TESTS" ]; then
	echo " -- NO_SLOW_TESTS is set."
	echo "skipping debian image."
	no_debian=1
fi

add() { targets="$targets $*"; }

[ -z "$no_simple" ] && add simple.image.gz
[ -z "$no_simple$no_runlocal" ] && add libs.runlocal
[ -z "$no_simple$no_runkvm" ] && add libs.runkvm
[ -z "$no_simple$no_docker" ] && add simple.rundocker

[ -z "$no_debian" ] && add debian.image
[ -z "$no_debian$no_runlocal" ] && add debian.runlocal
[ -z "$no_debian$no_runkvm" ] && add debian.runkvm
[ -z "$no_debian$no_docker" ] && add debian.rundocker

redo-ifchange $targets

check() {
	label=$1
	shift
	printf "checking %-18s %-35s " "$label:" "$*" >&2
	if test "$@"; then
		printf "ok\n" >&2
	else
		printf "failed\n" >&2
	fi
}

hellocheck() {
	check "$1" "$(cat "$1")" = "Hello, world!"
}

debcheck() {
	check "$1" "$(cat "$1")" -ge "70"
	check "$1" "$(cat "$1")" -le "100"
}

if [ -z "$no_simple" ]; then
	[ -n "$no_runlocal" ] || hellocheck libs.runlocal
	[ -n "$no_runkvm" ] || hellocheck libs.runkvm
	[ -n "$no_docker" ] || hellocheck simple.rundocker
fi

if [ -z "$no_debian" ]; then
	[ -n "$no_runlocal" ] || debcheck debian.runlocal
	[ -n "$no_runkvm" ] || debcheck debian.runkvm
	[ -n "$no_docker" ] || debcheck debian.rundocker
fi


Fix typo

Fix typo

#!/usr/bin/env python3
from collections import defaultdict, OrderedDict
from pathlib import Path
import json, yaml
import redo
from data import Databases, Evaluations, Mappings, Dnf, ErrorAnalysis, ErrorAnalyses
from utils import get_logger
import comap
from comap import cui_names, translation_read_2to3

logger = get_logger(__name__)

def create_error_analyses(events, databases, mappings, dnfs,
                          evaluations,
                          residuals_info):
    error_analyses_fn = defaultdict(dict)
    error_analyses_fp = defaultdict(dict)
    for event in events:
        mapping = mappings.get(event)
        for database in databases.databases():
            evaluation = evaluations[event][database]
            if evaluation:
                error_analysis_fn = create_error_analysis_fn(event,
                                                             database,
                                                             databases,
                                                             dnfs[event],
                                                             evaluation,
                                                             mapping.exclusion_codes(database),
                                                             residuals_info[database][event],
                                                             mapping)
                error_analysis_fp = create_error_analysis_fp(event,
                                                             database,
                                                             databases,
                                                             dnfs[event],
                                                             evaluation,
                                                             mapping)
            else:
                error_analysis_fn, error_analysis_fp = None, None
            error_analyses_fn[database][event] = error_analysis_fn
            error_analyses_fp[database][event] = error_analysis_fp
    return ErrorAnalyses(error_analyses_fn, error_analyses_fp)

def create_error_analysis_fp(event, database, databases, dnf, evaluation, mapping):
    coding_system = databases.coding_system(database)
    tp, fp, fn = evaluation.tp, evaluation.fp, evaluation.fn
    dnf_codes = dnf.codes(coding_system)

    def categorize(code):
        if code in dnf_codes:
            return 'in-dnf'
        else:
            return 'other-fp'

    code_categories, unassigned = dict(), set()
    for code in fp:
        category = categorize(code)
        if category:
            code_categories[code] = category
        else:
            unassigned.add(code)
    if unassigned:
        logger.warn("Unassigned codes for %s: %s", coding_system, ', '.join(unassigned))
    return ErrorAnalysis(code_categories, unassigned)

def database_specific(code, database, databases, dnf, mapping):
    """Checks if all cosynonyms of `code` are false positive for the
    mapping.
    """
    voc = databases.coding_system(database)
    return all(
        not (generated & reference)
        # All CUI sets that have `code`
        for cuis in dnf.cui_sets() if code in dnf.get(cuis).get(voc, set())
        # All *other* databases
        for database1 in databases.databases() if database1 != database
        for generated in [dnf.get(cuis).get(databases.coding_system(database1), set())]
        for reference in [mapping.codes(database1) or set()]
    )

def get_relateds(cuis, databases):
    # {cui: {rel: [sourceConcept]}}
    relateds0 = comap.get_client().related(cuis, ['RN', 'CHD', 'RB', 'PAR'], databases.coding_systems())
    # {cui: {cui}}
    return {
        cui: {sourceConcept['cui'] for sourceConcept in sourceConcepts}
        for cui in relateds0
        for sourceConcepts in relateds0[cui].values()
    }

def get_cuis(codes, coding_system, dnf):
    return {cui
            for cuis, for_cuis in dnf.disjunction().items()
            if codes & for_cuis.get(coding_system, set())
            for cui in cuis}

def create_error_analysis_fn(event, database, databases, dnf, evaluation,
                             exclusion_codes, residuals_info, mapping):
    coding_system = databases.coding_system(database)
    fn = evaluation.fn
    known_fn = comap.get_client().known_codes(fn, coding_system)
    fn_cuis = get_cuis(fn, coding_system, dnf)
    dnf_codes = dnf.codes(coding_system)
    relateds = get_relateds(fn_cuis, databases)

    def categorize_fn(code):
        # if code in residuals_info:
        #     return residuals_info[code]['category']
        if code not in dnf_codes:
            return 'not-in-dnf'
        if code not in known_fn:
            return 'not-in-umls'
        if not any(relateds.get(cui) for cui in dnf.cuis(code, coding_system)):
            return 'isolated'
        if any(evaluation.cuis & relateds.get(cui, set()) for cui in fn_cuis):
            return 'next-expansion'
        if exclusion_codes and code in exclusion_codes:
            return 'exclusion'
        if database_specific(code, database, databases, dnf, mapping):
            return 'database-specific'
        return None

    code_categories, unassigned = dict(), set()
    for code in fn:
        category = categorize_fn(code)
        if category:
            code_categories[code] = category
        else:
            unassigned.add(code)

    if unassigned:
        logger.warn("Unassigned codes for %s: %s", coding_system, ", ".join(unassigned))
        if coding_system == 'RCD2':
            t = translation_read_2to3(unassigned)
        names = cui_names(fn_cuis)
        def for_code(code):
            cuis = dnf.cuis(code, coding_system)
            res = OrderedDict([
                ('cuis', {
                    cui: OrderedDict([
                        ('name', names.get(cui, '?')),
                        ('relateds', ' '.join(relateds.get(cui, []))),
                    ])
                    for cui in cuis
                }),
            ])
            if coding_system == 'RCD2':
                res['RCD'] = list(t[code])
            return res
        unassigned = {
            code: for_code(code)
            for code in unassigned
        }

    return ErrorAnalysis(code_categories, unassigned)

if redo.running():
    project = redo.snippets[0]
    variation_id = '.'.join(redo.snippets[1:])
    project_path = Path('projects') / project

    with redo.ifchange(project_path / 'config.yaml') as f:
        config = yaml.load(f)
        databases = Databases.of_config(config)
        events = config['events']

    with redo.ifchange('{}.mappings.json'.format(project)) as f:
        mappings = Mappings.of_data(json.load(f))

    with redo.ifchange(project_path / 'residuals-info.yaml') as f:
        data = yaml.load(f)
        residuals_info = {
            database: {
                event: dict(data.get(database, {}).get(event, {}))
                for event in events
            }
            for database in databases.databases()
        }

    with redo.ifchange({
            event: '{}.{}.dnf.json'.format(project, event)
            for event in events
    }) as files:
        dnfs = {
            event: Dnf.of_data(json.load(files[event]))
            for event in events
        }

    with redo.ifchange('{}.evaluations.json'.format(project)) as f:
        evaluations = Evaluations.of_data(json.load(f))\
            .for_variation(variation_id, events, databases.databases())

    error_analyses = create_error_analyses(events, databases,
                                           mappings, dnfs,
                                           evaluations,
                                           residuals_info)

    with redo.output() as f:
        yaml.dump(error_analyses.to_data(), f, default_flow_style=False)

#!/usr/bin/env python3
from collections import defaultdict, OrderedDict
from pathlib import Path
import json, yaml
import redo
from data import Databases, Evaluations, Mappings, Dnf, ErrorAnalysis, ErrorAnalyses
from utils import get_logger
import comap
from comap import cui_names, translation_read_2to3

logger = get_logger(__name__)

def create_error_analyses(events, databases, mappings, dnfs,
                          evaluations,
                          residuals_info):
    error_analyses_fn = defaultdict(dict)
    error_analyses_fp = defaultdict(dict)
    for event in events:
        mapping = mappings.get(event)
        for database in databases.databases():
            evaluation = evaluations[event][database]
            if evaluation:
                error_analysis_fn = create_error_analysis_fn(event,
                                                             database,
                                                             databases,
                                                             dnfs[event],
                                                             evaluation,
                                                             mapping.exclusion_codes(database),
                                                             residuals_info[database][event],
                                                             mapping)
                error_analysis_fp = create_error_analysis_fp(event,
                                                             database,
                                                             databases,
                                                             dnfs[event],
                                                             evaluation,
                                                             mapping)
            else:
                error_analysis_fn, error_analysis_fp = None, None
            error_analyses_fn[database][event] = error_analysis_fn
            error_analyses_fp[database][event] = error_analysis_fp
    return ErrorAnalyses(error_analyses_fn, error_analyses_fp)

def create_error_analysis_fp(event, database, databases, dnf, evaluation, mapping):
    coding_system = databases.coding_system(database)
    tp, fp, fn = evaluation.tp, evaluation.fp, evaluation.fn
    dnf_codes = dnf.codes(coding_system)

    def categorize(code):
        if code in dnf_codes:
            return 'in-dnf'
        else:
            return 'other-fp'

    code_categories, unassigned = dict(), set()
    for code in fp:
        category = categorize(code)
        if category:
            code_categories[code] = category
        else:
            unassigned.add(code)
    if unassigned:
        logger.warn("Unassigned codes for %s: %s", coding_system, ', '.join(unassigned))
    return ErrorAnalysis(code_categories, unassigned)

def database_specific(code, database, databases, dnf, mapping):
    """Checks if all cosynonyms of `code` are false positive for the
    mapping.
    """
    voc = databases.coding_system(database)
    return all(
        not (generated & reference)
        # All CUI sets that have `code`
        for cuis in dnf.cui_sets() if code in dnf.get(cuis).get(voc, set())
        # All *other* databases
        for database1 in databases.databases() if database1 != database
        for generated in [dnf.get(cuis).get(databases.coding_system(database1), set())]
        for reference in [mapping.codes(database1) or set()]
    )

def get_relateds(cuis, databases):
    # {cui: {rel: [sourceConcept]}}
    relateds0 = comap.get_client().related(cuis, ['RN', 'CHD', 'RB', 'PAR'], databases.coding_systems())
    # {cui: {cui}}
    return {
        cui: {sourceConcept['cui'] for sourceConcept in sourceConcepts}
        for cui in relateds0
        for sourceConcepts in relateds0[cui].values()
    }

def get_cuis(codes, coding_system, dnf):
    return {cui
            for cuis, for_cuis in dnf.disjunction().items()
            if codes & for_cuis.get(coding_system, set())
            for cui in cuis}

def create_error_analysis_fn(event, database, databases, dnf, evaluation,
                             exclusion_codes, residuals_info, mapping):
    coding_system = databases.coding_system(database)
    fn = evaluation.fn
    known_fn = comap.get_client().known_codes(fn, coding_system)
    fn_cuis = get_cuis(fn, coding_system, dnf)
    dnf_codes = dnf.codes(coding_system)
    relateds = get_relateds(fn_cuis, databases)

    def categorize_fn(code):
        # if code in residuals_info:
        #     return residuals_info[code]['category']
        if code not in dnf_codes:
            return 'not-in-dnf'
        if code not in known_fn:
            return 'not-in-umls'
        if not any(relateds.get(cui) for cui in dnf.cuis(code, coding_system)):
            return 'isolated'
        if any(evaluation.cuis & relateds.get(cui, set()) for cui in fn_cuis):
            return 'next-expansion'
        if exclusion_codes and code in exclusion_codes:
            return 'exclusion'
        if database_specific(code, database, databases, dnf, mapping):
            return 'database-specific'
        return None

    code_categories, unassigned = dict(), set()
    for code in fn:
        category = categorize_fn(code)
        if category:
            code_categories[code] = category
        else:
            unassigned.add(code)

    if unassigned:
        logger.warn("Unasssigned codes for %s: %s", coding_system, ", ".join(unasssigned))
        if coding_system == 'RCD2':
            t = translation_read_2to3(unassigned)
        names = cui_names(fn_cuis)
        def for_code(code):
            cuis = dnf.cuis(code, coding_system)
            res = OrderedDict([
                ('cuis', {
                    cui: OrderedDict([
                        ('name', names.get(cui, '?')),
                        ('relateds', ' '.join(relateds.get(cui, []))),
                    ])
                    for cui in cuis
                }),
            ])
            if coding_system == 'RCD2':
                res['RCD'] = list(t[code])
            return res
        unassigned = {
            code: for_code(code)
            for code in unassigned
        }

    return ErrorAnalysis(code_categories, unassigned)

if redo.running():
    project = redo.snippets[0]
    variation_id = '.'.join(redo.snippets[1:])
    project_path = Path('projects') / project

    with redo.ifchange(project_path / 'config.yaml') as f:
        config = yaml.load(f)
        databases = Databases.of_config(config)
        events = config['events']

    with redo.ifchange('{}.mappings.json'.format(project)) as f:
        mappings = Mappings.of_data(json.load(f))

    with redo.ifchange(project_path / 'residuals-info.yaml') as f:
        data = yaml.load(f)
        residuals_info = {
            database: {
                event: dict(data.get(database, {}).get(event, {}))
                for event in events
            }
            for database in databases.databases()
        }

    with redo.ifchange({
            event: '{}.{}.dnf.json'.format(project, event)
            for event in events
    }) as files:
        dnfs = {
            event: Dnf.of_data(json.load(files[event]))
            for event in events
        }

    with redo.ifchange('{}.evaluations.json'.format(project)) as f:
        evaluations = Evaluations.of_data(json.load(f))\
            .for_variation(variation_id, events, databases.databases())

    error_analyses = create_error_analyses(events, databases,
                                           mappings, dnfs,
                                           evaluations,
                                           residuals_info)

    with redo.output() as f:
        yaml.dump(error_analyses.to_data(), f, default_flow_style=False)


Updated with IEgraph title help

Updated with IEgraph title help

{smcl}
{* 31 May 2017}{...}
{hline}
help for {hi:iegraph}
{hline}

{title:Title}

{phang2}{cmdab:iegraph} {hline 2} Generates graphs based on regressions with treatment dummies common in impact evaluations.

{title:Syntax}

{phang2}
{cmdab:iegraph} {varlist}
, [ {cmdab:basicti:tle(}{it:string}{cmd:)} {cmdab:varl:abels}
{cmdab:save(}{it:string}{cmd:)} {cmdab:grey:scale} {cmdab:yzero}
{cmd:noconfbars} {cmdab:confbarsnone(}{it:varlist}{cmd:)}
{it:any twoway graph options}
]

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt :{cmdab:basicti:tle(}{it:string}{cmd:)}} Manually sets the title of the graph.{p_end}
{synopt :{cmdab:varl:abels}} Uses variable labels for legends instead of variable names.{p_end}
{synopt :{cmdab:save(}{it:string}{cmd:)}} Sets the filename and the directory to which the graph will be set/exported.{p_end}
{synopt :{cmdab:grey:scale}} Uses greyscales for the bars instead of colors.{p_end}
{synopt :{cmdab:yzero}} Forces y-axis on the graph to start at 0.{p_end}
{synopt :{cmd:noconfbars}} Removes the confidence interval bars from graphs for all treatments.{p_end}
{synopt :{cmdab:confbarsnone(}{it:varlist}{cmd:)}} Removes confidence interval bars from only the {it:varlist} listed.{p_end}
{synoptline}

{pstd}Any twoway graph options that can be used with normal twoway graph commands can
	also be used. If any of these commands conflict with any of the built in options,
	then the user specified settings have precedence. See example 2 for details.{p_end}

{marker desc}
{title:Description}

{pstd}{cmdab:iegraph} This command creates bar graphs on the basis of the coefficients
	of treatment dummies in regression results. This command is developed for reading
	stored results from two types of impact evaluation regression models, but there
	are countless of other examples where the command also can be used. {cmd:iegraph} must
	be used immediately after running the regression or as long as the regression result is
	still stored in or restored to Stata's {help ereturn} results.

{pstd}{bf:Model 1: OLS with Treatment Dummies}{break}The most typical impact evaluation regression is
	to have the outcome variable as the dependent variable and one dummy for each
	treatment arm where control is the omitted category. These regressions can also include
	covariates, fixed effects etc., but as long as the treatment status is defined by
	mutually exclusive dummy variables. See especially examples 1 and 2 below. This command
	works with any number of treatment arms but works best from two arms (treatment
	and control) to five treatment arms (4 different treatments and control). More
	arms than that may result in a still correct but perhaps cluttered graph.

{pstd}{bf:Model 2: Difference-in-Differences}{break}Another typical regression model in impact
	evaluations are difference-in-difference (Diff-in-Diff) models with two treatment arms (treatment
	and control) and two time periods. If the Diff-in-Diff regression is specified as having the
	outcome variable as the dependent variable and three dummy variables (time, treatment
	and timeXtreatment) as the independent variables, then this command will produce a nice
	graph. Controls, treatment effects etc. may be added to the regression model. See especially example 3.

{pstd}{bf:Graph Output}{break}The graph generated by this command is created using the following values. The
	control bar is the mean of the outcome variable for the control group. It is not
	the constant from the regression as those are not identical if, for example, fixed effects
	and covariates were used. For each treatment group the bar is the sum of the value
	of the control bar and the beta coefficient in the regression of the corresponding
	treatment dummy. The confidence intervals are calculated from the variance in the
	beta coefficients in the regression.{p_end}

{pstd}The graph also includes the N for each treatment arm in the regression and uses
	that value as labels on the x-axis. Stars are added to this value if the corresponding
	coefficient is statistically different from zero in the regression{p_end}

{marker optslong}
{title:Options}

{phang}{cmdab:basicti:tle(}{it:string}{cmd:)} Manually sets the title of the graph. This
	can be overwritten using twoway's title feature for more options like title size, position
	, etc.{p_end}

{phang}{cmdab:varl:abels} Sets the legends to the variable labels for the
	variables instead of the variable names.{p_end}

{phang}{cmdab:save(}{it:string}{cmd:)} Sets the filename and the directory to which
	the graph will be set. If the filename ends with no extension or '.gph', it will be
	saved in the graph format. Extensions(png,pdf,tif,wmf,emf,ps,and eps) will be exported.
	Wmf and Emf are only available for the Windows version of Stata. Png and Tif for all
	versions of Stata except Console.{p_end}

{phang}{cmdab:grey:scale} Uses greyscales for the bars instead of colors. The color
	of the control bar will be black and the treatment bar will run in equal shade
	differences from light grey to dark grey.{p_end}

{phang}{cmd:noconfbars} Removes the confidence interval bars from graphs for all
	treatments. The default value for the confidence interval bars is 95%. {p_end}

{phang}{cmdab:confbarsnone(}{it:varlist}{cmd:)} Removes confidence interval bars
	from only the {it:varlist} listed. The remaining variables in the graphs which
	have not been specified in {cmdab:confbarsnone} will still have the confidence
	interval bars. {p_end}

{phang}{cmdab:yzero} Manually sets the y-axis of the graph to start at zero
	instead of the Stata default.{p_end}

{marker optslong}
{title:Examples}

{pstd} {hi:Example 1.}

{pmore} {inp:regress} {it:outcomevar treatment_dummy}{break}
		{inp:iegraph} {it:treatment_dummy} , {inp:basictitle({it:"Treatment Effect on Outcome"})}

{pmore}In the example above, there are only two treatment arms (treatment and
		control). {it:treatment_dummy} has a 1 for all treatment observations and
		a 0 for all control observations. The graph will have one bar for control and
		it shows the mean for {it:outcomevar} for all observations in control. The
		second bar in the graph will be the sum of that mean and the coefficient
		for {it:treatment_dummy} in the regression. The graph will also have the
		title: Treatment Effect on Outcome.

{pstd} {hi:Example 2.}

{pmore} {inp:regress} {it:income tmt_1 tmt_2 age education}{inp:, cluster(}{it:district}{inp:)}{break}
		{inp:iegraph} {it:tmt_1 tmt_2}{inp:, noconfbars yzero basictitle({it:"Treatment effect on income"}) }

{pmore}In the example above, the treatment effect on income in researched. There
		are three treatment arms; control, treatment 1 ({it:tmt_1}) and treatment
		2 ({it:tmt_2}). It is important that no observation has the value 1 in
		both {it:tmt_1} and {it:tmt_2} (i.e. no observation is in more than one
		treatment) and some observations must have the value 0 in both {it:tmt_1}
		and {it:tmt_2} (i.e. control observations). The variables {it:age} and
		{it:education} are covariates (control variables) and are not included
		in {cmd:iegraph}. {inp:noconfbars} omits the confidence interval bars
		, and {inp:yzero} sets the y-axis to start at 0.

{pstd} {hi:Example 3.}

{pmore} {inp:regress} {it:chld_wght time treat timeXtreat}{break}
		{inp:iegraph} {it:time treat timeXtreat} {inp:, basictitle({it:"Treatment effect on Child Weight (Diff-in-Diff)"})}

{pmore}In the example above, the data set is a panel data set with two time
		periods and the regression estimates the treatment effect on child weight
		using a Difference-in-Differences model.
		The dummy variable {it:time} indicates if it is time period 0 or 1.
		The dummy variable {it:treat} indicates if the observation is treatment
		or control. {it:timeXtreat} is the interaction term of {it:time}
		and {it:treat}. This the standard way to set up a Difference-in-Differences
		regression model.

{pstd} {hi:Example 4.}

{pmore} {inp:regress} {it:harvest T1 T2 T3 } {break}
		{inp:iegraph} {it:T1 T2 T3} {inp:, basictitle({it:"Treatment effect on harvest"})
		xlabel(,angle(45)) yzero ylabel(minmax) save({it:"Graph1.gph"})}

{pmore}The example above shows how to save a graph to disk. It also shows that
	most two-way graph options can be used. In this example the {cmd:iegraph}
	option {cdm:yzero} conflicts with the two-way option {cmd:ylabel(minmax)}.
	In such a case the user specified option takes precedence over {cmd:iegraph}
	options like {cdm:yzero}.

{title:Acknowledgements}

{phang}We would like to acknowledge the help in testing and proofreading we received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Luiza Cardoso De Andrade{break}Michael Orevba{break}Ahmad Zia Wahdat{break}

{title:Authors}

{phang}Kristoffer Bjarkefur & Mrijan Rimal, The World Bank, DECIE

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit iegraph" in the subject line to:{break}
		 kbjarkefur@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through
		 the github repository of ietoolkit:{break}
		 {browse "https://github.com/worldbank/ietoolkit"}

{smcl}
{* 31 May 2017}{...}
{hline}
help for {hi:iegraph}
{hline}

{title:Title}

{phang2}{cmdab:iegraph} {hline 2} Generates graphs based on regressions with treatment dummies common in impact evaluations.

{title:Syntax}

{phang2}
{cmdab:iegraph} {varlist}
, [ {cmdab:ti:tle(}{it:string}{cmd:)} {cmdab:varl:abels}
{cmdab:save(}{it:string}{cmd:)} {cmdab:grey:scale} {cmdab:yzero}
{cmd:noconfbars} {cmdab:confbarsnone(}{it:varlist}{cmd:)}
{it:any twoway graph options}
]

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt :{cmdab:ti:tle(}{it:string}{cmd:)}} Manually sets the title of the graph.{p_end}
{synopt :{cmdab:varl:abels}} Uses variable labels for legends instead of variable names.{p_end}
{synopt :{cmdab:save(}{it:string}{cmd:)}} Sets the filename and the directory to which the graph will be set/exported.{p_end}
{synopt :{cmdab:grey:scale}} Uses greyscales for the bars instead of colors.{p_end}
{synopt :{cmdab:yzero}} Forces y-axis on the graph to start at 0.{p_end}
{synopt :{cmd:noconfbars}} Removes the confidence interval bars from graphs for all treatments.{p_end}
{synopt :{cmdab:confbarsnone(}{it:varlist}{cmd:)}} Removes confidence interval bars from only the {it:varlist} listed.{p_end}
{synoptline}

{pstd}Any twoway graph options that can be used with normal twoway graph commands can
	also be used. If any of these commands conflict with any of the built in options,
	then the user specified settings have precedence. See example 2 for details.{p_end}

{marker desc}
{title:Description}

{pstd}{cmdab:iegraph} This command creates bar graphs on the basis of the coefficients
	of treatment dummies in regression results. This command is developed for reading
	stored results from two types of impact evaluation regression models, but there
	are countless of other examples where the command also can be used. {cmd:iegraph} must
	be used immediately after running the regression or as long as the regression result is
	still stored in or restored to Stata's {help ereturn} results.

{pstd}{bf:Model 1: OLS with Treatment Dummies}{break}The most typical impact evaluation regression is
	to have the outcome variable as the dependent variable and one dummy for each
	treatment arm where control is the omitted category. These regressions can also include
	covariates, fixed effects etc., but as long as the treatment status is defined by
	mutually exclusive dummy variables. See especially examples 1 and 2 below. This command
	works with any number of treatment arms but works best from two arms (treatment
	and control) to five treatment arms (4 different treatments and control). More
	arms than that may result in a still correct but perhaps cluttered graph.

{pstd}{bf:Model 2: Difference-in-Differences}{break}Another typical regression model in impact
	evaluations are difference-in-difference (Diff-in-Diff) models with two treatment arms (treatment
	and control) and two time periods. If the Diff-in-Diff regression is specified as having the
	outcome variable as the dependent variable and three dummy variables (time, treatment
	and timeXtreatment) as the independent variables, then this command will produce a nice
	graph. Controls, treatment effects etc. may be added to the regression model. See especially example 3.

{pstd}{bf:Graph Output}{break}The graph generated by this command is created using the following values. The
	control bar is the mean of the outcome variable for the control group. It is not
	the constant from the regression as those are not identical if, for example, fixed effects
	and covariates were used. For each treatment group the bar is the sum of the value
	of the control bar and the beta coefficient in the regression of the corresponding
	treatment dummy. The confidence intervals are calculated from the variance in the
	beta coefficients in the regression.{p_end}

{pstd}The graph also includes the N for each treatment arm in the regression and uses
	that value as labels on the x-axis. Stars are added to this value if the corresponding
	coefficient is statistically different from zero in the regression{p_end}

{marker optslong}
{title:Options}

{phang}{cmdab:ti:tle(}{it:string}{cmd:)} Manually sets the title of the graph.{p_end}

{phang}{cmdab:varl:abels} Sets the legends to the variable labels for the
	variables instead of the variable names.{p_end}

{phang}{cmdab:save(}{it:string}{cmd:)} Sets the filename and the directory to which
	the graph will be set. If the filename ends with no extension or '.gph', it will be
	saved in the graph format. Extensions(png,pdf,tif,wmf,emf,ps,and eps) will be exported.
	Wmf and Emf are only available for the Windows version of Stata. Png and Tif for all
	versions of Stata except Console.{p_end}

{phang}{cmdab:grey:scale} Uses greyscales for the bars instead of colors. The color
	of the control bar will be black and the treatment bar will run in equal shade
	differences from light grey to dark grey.{p_end}

{phang}{cmd:noconfbars} Removes the confidence interval bars from graphs for all
	treatments. The default value for the confidence interval bars is 95%. {p_end}

{phang}{cmdab:confbarsnone(}{it:varlist}{cmd:)} Removes confidence interval bars
	from only the {it:varlist} listed. The remaining variables in the graphs which
	have not been specified in {cmdab:confbarsnone} will still have the confidence
	interval bars. {p_end}

{phang}{cmdab:yzero} Manually sets the y-axis of the graph to start at zero
	instead of the Stata default.{p_end}

{marker optslong}
{title:Examples}

{pstd} {hi:Example 1.}

{pmore} {inp:regress} {it:outcomevar treatment_dummy}{break}
		{inp:iegraph} {it:treatment_dummy} , {inp:title({it:"Treatment Effect on Outcome"})}

{pmore}In the example above, there are only two treatment arms (treatment and
		control). {it:treatment_dummy} has a 1 for all treatment observations and
		a 0 for all control observations. The graph will have one bar for control and
		it shows the mean for {it:outcomevar} for all observations in control. The
		second bar in the graph will be the sum of that mean and the coefficient
		for {it:treatment_dummy} in the regression. The graph will also have the
		title: Treatment Effect on Outcome.

{pstd} {hi:Example 2.}

{pmore} {inp:regress} {it:income tmt_1 tmt_2 age education}{inp:, cluster(}{it:district}{inp:)}{break}
		{inp:iegraph} {it:tmt_1 tmt_2}{inp:, noconfbars yzero title({it:"Treatment effect on income"}) }

{pmore}In the example above, the treatment effect on income in researched. There
		are three treatment arms; control, treatment 1 ({it:tmt_1}) and treatment
		2 ({it:tmt_2}). It is important that no observation has the value 1 in
		both {it:tmt_1} and {it:tmt_2} (i.e. no observation is in more than one
		treatment) and some observations must have the value 0 in both {it:tmt_1}
		and {it:tmt_2} (i.e. control observations). The variables {it:age} and
		{it:education} are covariates (control variables) and are not included
		in {cmd:iegraph}. {inp:noconfbars} omits the confidence interval bars
		, and {inp:yzero} sets the y-axis to start at 0.

{pstd} {hi:Example 3.}

{pmore} {inp:regress} {it:chld_wght time treat timeXtreat}{break}
		{inp:iegraph} {it:time treat timeXtreat} {inp:, title({it:"Treatment effect on Child Weight (Diff-in-Diff)"})}

{pmore}In the example above, the data set is a panel data set with two time
		periods and the regression estimates the treatment effect on child weight
		using a Difference-in-Differences model.
		The dummy variable {it:time} indicates if it is time period 0 or 1.
		The dummy variable {it:treat} indicates if the observation is treatment
		or control. {it:timeXtreat} is the interaction term of {it:time}
		and {it:treat}. This the standard way to set up a Difference-in-Differences
		regression model.

{pstd} {hi:Example 4.}

{pmore} {inp:regress} {it:harvest T1 T2 T3 } {break}
		{inp:iegraph} {it:T1 T2 T3} {inp:, title({it:"Treatment effect on harvest"})
		xlabel(,angle(45)) yzero ylabel(minmax) save({it:"Graph1.gph"})}

{pmore}The example above shows how to save a graph to disk. It also shows that
	most two-way graph options can be used. In this example the {cmd:iegraph}
	option {cdm:yzero} conflicts with the two-way option {cmd:ylabel(minmax)}.
	In such a case the user specified option takes precedence over {cmd:iegraph}
	options like {cdm:yzero}.

{title:Acknowledgements}

{phang}We would like to acknowledge the help in testing and proofreading we received in relation to this command and help file from (in alphabetic order):{p_end}
{pmore}Luiza Cardoso De Andrade{break}Michael Orevba{break}Ahmad Zia Wahdat{break}

{title:Authors}

{phang}Kristoffer Bjarkefur & Mrijan Rimal, The World Bank, DECIE

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietoolkit iegraph" in the subject line to:{break}
		 kbjarkefur@worldbank.org

{phang}You can also see the code, make comments to the code, see the version
		 history of the code, and submit additions or edits to the code through
		 the github repository of ietoolkit:{break}
		 {browse "https://github.com/worldbank/ietoolkit"}