Avoid impossible allocations.

Avoid impossible allocations.

Stata gives *syntax error* on J(0,1,.) and other constructions
with invalid matrix dimensions. This is *not* a syntax error,
it's a value error, but all the user gets is that cryptic message.

program _svm, plugin /*load the C extension if not already loaded*/

* subroutine to convert the global struct svm_model that lives in the DLL to a mixture of e() entries, variables, and matrices
* this needs to be its own subroutine because, due to limitations in the Stata C API,th
* it does an awkward dance where _svm.plugin writes to the (global!) scalar dict and then this code copies those entries to r()
* as with svm_load, the extension function is called multiple times with sub-sub-commands, because it doesn't have permission to perform all the operations needed
program define _svm_model2stata, eclass
  version 13

  * as with loading, this has to call in and out of the plugin because chicken/egg:
  *   the plugin doesn't have permission to allocate Stata memory (in this case matrices),
  *   but we don't know how much to allocate before interrogating the svm_model

  local have_sv_indices = 0
  local have_rho = 0
  local have_probA = 0 /*an undefined macro will inconsistently cause an eval error because `have_rho'==1 will eval to ==1 will eval to "unknown variable"*/
  local have_probB = 0 /*so just define them ahead of time to be safe*/

  * Phase 1
  plugin call _svm, "_model2stata" 1

  * the total number of (detected?) classes
  ereturn scalar nr_class = _model2stata_nr_class
  scalar drop _model2stata_nr_class

  * the number of support vectors
  ereturn scalar l = _model2stata_l
  scalar drop _model2stata_l

  * Phase 2
  * Allocate Stata matrices and copy the libsvm matrices and vectors

  *TODO: SV and sv_indices are probably best translated jointly by adding an indicator variable column to the original dataset telling if that observation was chosen as a support vector (of course, this will mean we need to further clamp the upper limit)

  if(`have_sv_indices'==1 & `e(l)'>0) {
    matrix SVs = J(e(l),1,.) /*but for now we can just copy out sv_indices*/
    matrix colnames SVs = "SVs"
  }

  * nSV tells how many support vectors went into each class
  * The sum of the entries in nSV should be l
  matrix nSV = J(e(nr_class),1,.)
  matrix colnames nSV = "nSV"
  /*matrix rownames nSV = . . */

  if(`e(nr_class)'>0) {
    matrix labels = J(e(nr_class),1,.)
    matrix colnames labels = "labels"
  }

  if(`e(nr_class)'>1 & `e(l)'>0) {
    matrix sv_coef = J(e(nr_class)-1,e(l),.)
  }

  if(`have_rho'==1 & `e(nr_class)'>0) {
    matrix rho = J(e(nr_class),e(nr_class),.)
  }
  if(`have_probA'==1 & `e(nr_class)'>0) {
    matrix probA = J(e(nr_class),e(nr_class),.)
  }
  if(`have_probB'==1 & `e(nr_class)'>0) {
    matrix probB = J(e(nr_class),e(nr_class),.)
  }

  * TODO: also label the rows according to model->label (libsvm's "labels" are just more integers, but it helps to be consistent anyway);
  *  I can easily extract ->label with the same code, but attaching it to the rownames of the other is tricky
  plugin call _svm, "_model2stata" 2

  * Phase 3
  * Export the rest of the values to e()
  * We *cannot* export matrices to e() from the C interface, hence we have to do this very explicit thing
  * NOTE: 'ereturn matrix' erases the old name (unless you specify ,copy), which is why we don't have to explicitly drop things
  *       'ereturn scalar' doesn't do this, because Stata loves being consistent. Just go read the docs for 'syntax' and see how easy it is.
  * All of these are silenced because various things might kill any of them, and we want failures to be independent of each other

  quietly capture ereturn matrix SVs = SVs

  quietly capture ereturn matrix nSV = nSV
  quietly capture ereturn matrix labels = labels

  quietly capture ereturn matrix sv_coef = sv_coef
  quietly capture ereturn matrix rho = rho
  quietly capture ereturn matrix probA = probA
  quietly capture ereturn matrix probB = probB

end

program _svm, plugin /*load the C extension if not already loaded*/

* subroutine to convert the global struct svm_model that lives in the DLL to a mixture of e() entries, variables, and matrices
* this needs to be its own subroutine because, due to limitations in the Stata C API,th
* it does an awkward dance where _svm.plugin writes to the (global!) scalar dict and then this code copies those entries to r()
* as with svm_load, the extension function is called multiple times with sub-sub-commands, because it doesn't have permission to perform all the operations needed
program define _svm_model2stata, eclass
  version 13

  * as with loading, this has to call in and out of the plugin because chicken/egg:
  *   the plugin doesn't have permission to allocate Stata memory (in this case matrices),
  *   but we don't know how much to allocate before interrogating the svm_model

  local have_sv_indices = 0
  local have_rho = 0
  local have_probA = 0 /*an undefined macro will inconsistently cause an eval error because `have_rho'==1 will eval to ==1 will eval to "unknown variable"*/
  local have_probB = 0 /*so just define them ahead of time to be safe*/

  * Phase 1
  plugin call _svm, "_model2stata" 1

  * the total number of (detected?) classes
  ereturn scalar nr_class = _model2stata_nr_class
  scalar drop _model2stata_nr_class

  * the number of support vectors
  ereturn scalar l = _model2stata_l
  scalar drop _model2stata_l

  * Phase 2
  * Allocate Stata matrices and copy the libsvm matrices and vectors

  *TODO: SV and sv_indices are probably best translated jointly by adding an indicator variable column to the original dataset telling if that observation was chosen as a support vector (of course, this will mean we need to further clamp the upper limit)

  if(`have_sv_indices'==1) {
    matrix SVs = J(e(l),1,.) /*but for now we can just copy out sv_indices*/
    matrix colnames SVs = "SVs"
  }

  * nSV tells how many support vectors went into each class
  * The sum of the entries in nSV should be l
  matrix nSV = J(e(nr_class),1,.)
  matrix colnames nSV = "nSV"
  /*matrix rownames nSV = . . */

  matrix labels = J(e(nr_class),1,.)
  matrix colnames labels = "labels"

  matrix sv_coef = J(e(nr_class)-1,e(l),.)

  if(`have_rho'==1) {
    matrix rho = J(e(nr_class),e(nr_class),.)
  }
  if(`have_probA'==1) {
    matrix probA = J(e(nr_class),e(nr_class),.)
  }
  if(`have_probB'==1) {
    matrix probB = J(e(nr_class),e(nr_class),.)
  }

  * TODO: also label the rows according to model->label (libsvm's "labels" are just more integers, but it helps to be consistent anyway);
  *  I can easily extract ->label with the same code, but attaching it to the rownames of the other is tricky
  plugin call _svm, "_model2stata" 2

  * Phase 3
  * Export the rest of the values to e()
  * We *cannot* export matrices to e() from the C interface, hence we have to do this very explicit thing
  * NOTE: 'ereturn matrix' erases the old name (unless you specify ,copy), which is why we don't have to explicitly drop things
  *       'ereturn scalar' doesn't do this, because Stata loves being consistent. Just go read the docs for 'syntax' and see how easy it is.

  if(`have_sv_indices'==1) {
    ereturn matrix SVs = SVs
  }

  ereturn matrix nSV = nSV
  ereturn matrix labels = labels

  ereturn matrix sv_coef = sv_coef
  if(`have_rho'==1) {
    ereturn matrix rho = rho
  }
  if(`have_probA'==1) {
    ereturn matrix probA = probA
  }
  if(`have_probB'==1) {
    ereturn matrix probB = probB
  }

end


redo: fix broken 'set -e' functionality in redo

#!/bin/bash
# automaton
# (c) 2013 Justin Gottula
# The source code of this project is distributed under the terms of the
# simplified BSD license. See the LICENSE file for details.

exec >&2

# redo appears to be broken
set -e

TARGET=$1
TARGET_BASE=$2
OUTPUT=$3

CC="avr-gcc"
AS="avr-as"
LD="avr-ld"
NM="avr-nm"
OBJCOPY="avr-objcopy"
OBJDUMP="avr-objdump"

PROJ_NAME="automaton"

MCU="atmega324a"
CPU_KHZ="20000"

DEFINES=("F_CPU=${CPU_KHZ}000UL")
INC_DIRS=(src)
LIB_DIRS=()
LIBS=()

CFLAGS_CPU=("-mmcu=$MCU" -fpack-struct -ffreestanding)
CFLAGS_DEBUG=(-ggdb)
CFLAGS_OPT=(-Os -flto -fuse-linker-plugin -fwhole-program -mcall-prologues \
	-mrelax -mstrict-X -fmerge-all-constants -ffast-math)
CFLAGS_WARN=(-Wall -Wextra -Waddr-space-convert -Wno-unused-function)
CFLAGS_ETC=(-fno-diagnostics-show-caret -pipe)

CFLAGS="-std=gnu11 ${CFLAGS_CPU[@]} ${CFLAGS_DEBUG[@]} ${CFLAGS_OPT[@]} \
${CFLAGS_WARN[@]} ${CFLAGS_ETC[@]}"
CFLAGS_COMPILE="$CFLAGS ${DEFINES[@]/#/-D} ${INC_DIRS[@]/#/-I}"
CFLAGS_LINK="$CFLAGS ${LIB_DIRS[@]/#/-L} ${LIBS[@]/#/-l}"

SOURCES=$(find src -type f -iname "*.c")
OBJECTS=${SOURCES//.c/.o}

OUT_ELF="out/$PROJ_NAME.elf"
OUT_BIN="out/$PROJ_NAME.bin"
OUT_HEX="out/$PROJ_NAME.hex"
OUT_MAP="out/$PROJ_NAME.map"
OUT_DUMP="out/$PROJ_NAME.dump"
OUT_LST="out/$PROJ_NAME.lst"

case "$TARGET" in
all)
	redo-ifchange $OUT_ELF $OUT_BIN $OUT_HEX $OUT_MAP $OUT_DUMP $OUT_LST
	;;
$OUT_ELF)
	redo-ifchange $OBJECTS
	$CC $CFLAGS_LINK -o $OUTPUT $OBJECTS
	;;
$OUT_BIN)
	redo-ifchange $OUT_ELF
	$OBJCOPY -O binary $OUT_ELF $OUTPUT
	stat --printf='%n: %s bytes\n' $OUTPUT
	;;
$OUT_HEX)
	redo-ifchange $OUT_ELF
	$OBJCOPY -O ihex $OUT_ELF $OUTPUT
	;;
$OUT_MAP)
	redo-ifchange $OUT_ELF
	$NM -Cn $OUT_ELF >$OUTPUT
	;;
$OUT_DUMP)
	redo-ifchange $OUT_ELF
	$OBJDUMP -aCdfhp $OUT_ELF >$OUTPUT
	;;
$OUT_LST)
	redo-ifchange $OUT_ELF
	$OBJDUMP -CdS -j '.text' $OUT_ELF >$OUTPUT
	;;
*.o)
	$CC $CFLAGS_COMPILE -o${TARGET//.o/.dep} -MM -MG ${TARGET//.o/.c}

	read DEPS <${TARGET//.o/.dep}
	redo-ifchange ${DEPS#*:}

	$CC $CFLAGS_COMPILE -o$OUTPUT -c ${TARGET//.o/.c}
	;;
clean)
	rm -rf $(find out -type f)
	rm -rf $(find src -type f -iname "*.o")
	rm -rf $(find src -type f -iname "*.dep")
	;;
load)
	redo-ifchange $OUT_HEX

	AVRDUDE_CMD="sudo avrdude -u -p ${MCU/atmega/m} -c usbasp -B 460800 \
	-U flash:w:$OUT_HEX"

	# retry once upon failure
	$($AVRDUDE_CMD)
	if [[ "$?" != "0" ]]; then
		$($AVRDUDE_CMD)
	fi
	;;
*)
	echo "unknown target '$TARGET'"
	exit 1
	;;
esac

#!/bin/bash
# automaton
# (c) 2013 Justin Gottula
# The source code of this project is distributed under the terms of the
# simplified BSD license. See the LICENSE file for details.

exec >&2

TARGET=$1
TARGET_BASE=$2
OUTPUT=$3

CC="avr-gcc"
AS="avr-as"
LD="avr-ld"
NM="avr-nm"
OBJCOPY="avr-objcopy"
OBJDUMP="avr-objdump"

PROJ_NAME="automaton"

MCU="atmega324a"
CPU_KHZ="20000"

DEFINES=("F_CPU=${CPU_KHZ}000UL")
INC_DIRS=(src)
LIB_DIRS=()
LIBS=()

CFLAGS_CPU=("-mmcu=$MCU" -fpack-struct -ffreestanding)
CFLAGS_DEBUG=(-ggdb)
CFLAGS_OPT=(-Os -flto -fuse-linker-plugin -fwhole-program -mcall-prologues \
	-mrelax -mstrict-X -fmerge-all-constants -ffast-math)
CFLAGS_WARN=(-Wall -Wextra -Waddr-space-convert -Wno-unused-function)
CFLAGS_ETC=(-fno-diagnostics-show-caret -pipe)

CFLAGS="-std=gnu11 ${CFLAGS_CPU[@]} ${CFLAGS_DEBUG[@]} ${CFLAGS_OPT[@]} \
${CFLAGS_WARN[@]} ${CFLAGS_ETC[@]}"
CFLAGS_COMPILE="$CFLAGS ${DEFINES[@]/#/-D} ${INC_DIRS[@]/#/-I}"
CFLAGS_LINK="$CFLAGS ${LIB_DIRS[@]/#/-L} ${LIBS[@]/#/-l}"

SOURCES=$(find src -type f -iname "*.c")
OBJECTS=${SOURCES//.c/.o}

OUT_ELF="out/$PROJ_NAME.elf"
OUT_BIN="out/$PROJ_NAME.bin"
OUT_HEX="out/$PROJ_NAME.hex"
OUT_MAP="out/$PROJ_NAME.map"
OUT_DUMP="out/$PROJ_NAME.dump"
OUT_LST="out/$PROJ_NAME.lst"

case "$TARGET" in
all)
	redo-ifchange $OUT_ELF $OUT_BIN $OUT_HEX $OUT_MAP $OUT_DUMP $OUT_LST
	;;
$OUT_ELF)
	redo-ifchange $OBJECTS
	$CC $CFLAGS_LINK -o $OUTPUT $OBJECTS
	;;
$OUT_BIN)
	redo-ifchange $OUT_ELF
	$OBJCOPY -O binary $OUT_ELF $OUTPUT
	stat --printf='%n: %s bytes\n' $OUTPUT
	;;
$OUT_HEX)
	redo-ifchange $OUT_ELF
	$OBJCOPY -O ihex $OUT_ELF $OUTPUT
	;;
$OUT_MAP)
	redo-ifchange $OUT_ELF
	$NM -Cn $OUT_ELF >$OUTPUT
	;;
$OUT_DUMP)
	redo-ifchange $OUT_ELF
	$OBJDUMP -aCdfhp $OUT_ELF >$OUTPUT
	;;
$OUT_LST)
	redo-ifchange $OUT_ELF
	$OBJDUMP -CdS -j '.text' $OUT_ELF >$OUTPUT
	;;
*.o)
	$CC $CFLAGS_COMPILE -o${TARGET//.o/.dep} -MM -MG ${TARGET//.o/.c}

	read DEPS <${TARGET//.o/.dep}
	redo-ifchange ${DEPS#*:}

	$CC $CFLAGS_COMPILE -o$OUTPUT -c ${TARGET//.o/.c}
	;;
clean)
	rm -rf $(find out -type f)
	rm -rf $(find src -type f -iname "*.o")
	rm -rf $(find src -type f -iname "*.dep")
	;;
load)
	redo-ifchange $OUT_HEX

	AVRDUDE_CMD="sudo avrdude -u -p ${MCU/atmega/m} -c usbasp -B 460800 \
	-U flash:w:$OUT_HEX"

	# retry once upon failure
	$($AVRDUDE_CMD)
	if [[ "$?" != "0" ]]; then
		$($AVRDUDE_CMD)
	fi
	;;
*)
	echo "unknown target '$TARGET'"
	exit 1
	;;
esac


redo: redo all in load

redo: redo all in load

#!/bin/bash
# automaton
# (c) 2013 Justin Gottula
# The source code of this project is distributed under the terms of the
# simplified BSD license. See the LICENSE file for details.

exec >&2

# redo appears to be broken
set -e

TARGET=$1
TARGET_BASE=$2
OUTPUT=$3

CC="avr-gcc"
AS="avr-as"
LD="avr-ld"
NM="avr-nm"
OBJCOPY="avr-objcopy"
OBJDUMP="avr-objdump"

PROJ_NAME="automaton"

MCU="atmega324a"
CPU_KHZ="20000"

DEFINES=("F_CPU=${CPU_KHZ}000UL")
INC_DIRS=(src)
LIB_DIRS=()
LIBS=()

CFLAGS_CPU=("-mmcu=$MCU" -fpack-struct -ffreestanding)
CFLAGS_DEBUG=(-ggdb)
CFLAGS_OPT=(-Os -flto -fuse-linker-plugin -fwhole-program -mcall-prologues \
	-mrelax -mstrict-X -fmerge-all-constants -ffast-math)
CFLAGS_WARN=(-Wall -Wextra -Waddr-space-convert -Wno-unused-function)
CFLAGS_ETC=(-fno-diagnostics-show-caret -pipe)

CFLAGS="-std=gnu11 ${CFLAGS_CPU[@]} ${CFLAGS_DEBUG[@]} ${CFLAGS_OPT[@]} \
${CFLAGS_WARN[@]} ${CFLAGS_ETC[@]}"
CFLAGS_COMPILE="$CFLAGS ${DEFINES[@]/#/-D} ${INC_DIRS[@]/#/-I}"
CFLAGS_LINK="$CFLAGS ${LIB_DIRS[@]/#/-L} ${LIBS[@]/#/-l}"

SOURCES=$(find src -type f -iname "*.c")
OBJECTS=${SOURCES//.c/.o}

OUT_ELF="out/$PROJ_NAME.elf"
OUT_BIN="out/$PROJ_NAME.bin"
OUT_HEX="out/$PROJ_NAME.hex"
OUT_MAP="out/$PROJ_NAME.map"
OUT_DUMP="out/$PROJ_NAME.dump"
OUT_LST="out/$PROJ_NAME.lst"

case "$TARGET" in
all)
	redo-ifchange $OUT_ELF $OUT_BIN $OUT_HEX $OUT_MAP $OUT_DUMP $OUT_LST
	;;
$OUT_ELF)
	redo-ifchange $OBJECTS
	$CC $CFLAGS_LINK -o $OUTPUT $OBJECTS
	;;
$OUT_BIN)
	redo-ifchange $OUT_ELF
	$OBJCOPY -O binary $OUT_ELF $OUTPUT
	stat --printf='%n: %s bytes\n' $OUTPUT
	;;
$OUT_HEX)
	redo-ifchange $OUT_ELF
	$OBJCOPY -O ihex $OUT_ELF $OUTPUT
	;;
$OUT_MAP)
	redo-ifchange $OUT_ELF
	$NM -Cn $OUT_ELF >$OUTPUT
	;;
$OUT_DUMP)
	redo-ifchange $OUT_ELF
	$OBJDUMP -aCdfhp $OUT_ELF >$OUTPUT
	;;
$OUT_LST)
	redo-ifchange $OUT_ELF
	$OBJDUMP -CdS -j '.text' $OUT_ELF >$OUTPUT
	;;
*.o)
	$CC $CFLAGS_COMPILE -o${TARGET//.o/.dep} -MM -MG ${TARGET//.o/.c}

	read DEPS <${TARGET//.o/.dep}
	redo-ifchange ${DEPS#*:}

	$CC $CFLAGS_COMPILE -o$OUTPUT -c ${TARGET//.o/.c}
	;;
clean)
	rm -rf $(find out -type f)
	rm -rf $(find src -type f -iname "*.o")
	rm -rf $(find src -type f -iname "*.dep")
	;;
load)
	redo all

	AVRDUDE_CMD="sudo avrdude -u -p ${MCU/atmega/m} -c usbasp -B 460800 \
	-U flash:w:$OUT_HEX"

	# retry once upon failure
	$($AVRDUDE_CMD)
	if [[ "$?" != "0" ]]; then
		$($AVRDUDE_CMD)
	fi
	;;
*)
	echo "unknown target '$TARGET'"
	exit 1
	;;
esac

#!/bin/bash
# automaton
# (c) 2013 Justin Gottula
# The source code of this project is distributed under the terms of the
# simplified BSD license. See the LICENSE file for details.

exec >&2

# redo appears to be broken
set -e

TARGET=$1
TARGET_BASE=$2
OUTPUT=$3

CC="avr-gcc"
AS="avr-as"
LD="avr-ld"
NM="avr-nm"
OBJCOPY="avr-objcopy"
OBJDUMP="avr-objdump"

PROJ_NAME="automaton"

MCU="atmega324a"
CPU_KHZ="20000"

DEFINES=("F_CPU=${CPU_KHZ}000UL")
INC_DIRS=(src)
LIB_DIRS=()
LIBS=()

CFLAGS_CPU=("-mmcu=$MCU" -fpack-struct -ffreestanding)
CFLAGS_DEBUG=(-ggdb)
CFLAGS_OPT=(-Os -flto -fuse-linker-plugin -fwhole-program -mcall-prologues \
	-mrelax -mstrict-X -fmerge-all-constants -ffast-math)
CFLAGS_WARN=(-Wall -Wextra -Waddr-space-convert -Wno-unused-function)
CFLAGS_ETC=(-fno-diagnostics-show-caret -pipe)

CFLAGS="-std=gnu11 ${CFLAGS_CPU[@]} ${CFLAGS_DEBUG[@]} ${CFLAGS_OPT[@]} \
${CFLAGS_WARN[@]} ${CFLAGS_ETC[@]}"
CFLAGS_COMPILE="$CFLAGS ${DEFINES[@]/#/-D} ${INC_DIRS[@]/#/-I}"
CFLAGS_LINK="$CFLAGS ${LIB_DIRS[@]/#/-L} ${LIBS[@]/#/-l}"

SOURCES=$(find src -type f -iname "*.c")
OBJECTS=${SOURCES//.c/.o}

OUT_ELF="out/$PROJ_NAME.elf"
OUT_BIN="out/$PROJ_NAME.bin"
OUT_HEX="out/$PROJ_NAME.hex"
OUT_MAP="out/$PROJ_NAME.map"
OUT_DUMP="out/$PROJ_NAME.dump"
OUT_LST="out/$PROJ_NAME.lst"

case "$TARGET" in
all)
	redo-ifchange $OUT_ELF $OUT_BIN $OUT_HEX $OUT_MAP $OUT_DUMP $OUT_LST
	;;
$OUT_ELF)
	redo-ifchange $OBJECTS
	$CC $CFLAGS_LINK -o $OUTPUT $OBJECTS
	;;
$OUT_BIN)
	redo-ifchange $OUT_ELF
	$OBJCOPY -O binary $OUT_ELF $OUTPUT
	stat --printf='%n: %s bytes\n' $OUTPUT
	;;
$OUT_HEX)
	redo-ifchange $OUT_ELF
	$OBJCOPY -O ihex $OUT_ELF $OUTPUT
	;;
$OUT_MAP)
	redo-ifchange $OUT_ELF
	$NM -Cn $OUT_ELF >$OUTPUT
	;;
$OUT_DUMP)
	redo-ifchange $OUT_ELF
	$OBJDUMP -aCdfhp $OUT_ELF >$OUTPUT
	;;
$OUT_LST)
	redo-ifchange $OUT_ELF
	$OBJDUMP -CdS -j '.text' $OUT_ELF >$OUTPUT
	;;
*.o)
	$CC $CFLAGS_COMPILE -o${TARGET//.o/.dep} -MM -MG ${TARGET//.o/.c}

	read DEPS <${TARGET//.o/.dep}
	redo-ifchange ${DEPS#*:}

	$CC $CFLAGS_COMPILE -o$OUTPUT -c ${TARGET//.o/.c}
	;;
clean)
	rm -rf $(find out -type f)
	rm -rf $(find src -type f -iname "*.o")
	rm -rf $(find src -type f -iname "*.dep")
	;;
load)
	redo-ifchange $OUT_HEX

	AVRDUDE_CMD="sudo avrdude -u -p ${MCU/atmega/m} -c usbasp -B 460800 \
	-U flash:w:$OUT_HEX"

	# retry once upon failure
	$($AVRDUDE_CMD)
	if [[ "$?" != "0" ]]; then
		$($AVRDUDE_CMD)
	fi
	;;
*)
	echo "unknown target '$TARGET'"
	exit 1
	;;
esac


iematch : implement many to one

iematch : implement many to one

implement many to one algorithm. add _matchCount to output vars. fix bug
with new varname input check.

	clear all

	*command starts here

	cap program drop 	iematch
	    program define	iematch

		syntax  [if] [in]  , ///
			GRPdummy(varname) 		///
			MATCHvar(varname) 		///
			[						///
			idvar(varname)			///
			m1						///
			matchidname(string)		///
			matchdiffname(string)	///
			matchnoname(string)		///
			matchcount(string)		///
			maxdiff(numlist max = 1 min = 1) ///
			]

		*****
		*1 format errors as smcl
		*2 option to disable countdown
		*3 test not matchcount without m1
		*4 test that tmt are not more than ctrl if one to one

		noi di "Syntax OK!"

		pause on

		qui {

		********************************
		*
		*	Gen temp sort and merge var
		*
		********************************

		tempvar originalSort

		gen `originalSort' = _n

		preserve

*Testing input
if 1 {

			if "`if'`in'" != "" keep `if'`in'

			********************************
			*
			*	Checking group dummy
			*
			********************************

			*Test that the group dummy is 1, 0 or missing
			cap assert inlist(`grpdummy', 1, 0, .) | `grpdummy' > .
			if _rc != 0 {

				di as error "The variable in grpdummy(`grpdummy') is not a dummy variable. The variable is only allowed to have the values 1, 0 or missing. Observations with missing varaibles in the grpdummy are ignored by this command."
				error _rc
			}

			**Exclude obs with missing value in groupdummy

			*Count number of obs to be dropped and and output that number if more than zero
			count if missing(`grpdummy')
			if `r(N)' > 0 {
				*This is not an error just outputting the number
				noi di "{pstd}`r(N)' observation(s) were excluded due to missing value in group dummy{p_end}"
			}
			*Drop obs with missing
			drop if missing(`grpdummy')

			********************************
			*
			*	Checking match continous var
			*
			********************************

			*Test that the continous is numeric
			cap confirm numeric variable `matchvar'
			if _rc != 0 {

				di as error "The variable to match on specified in matchvar(`matchvar') is not a numeric variable."
				error 109

			}

			**Exclude obs with missing value in groupdummy

			*Count number of obs to be dropped and and output that number if more than zero
			count if missing(`matchvar')
			if `r(N)' > 0 {
				*This is not an error just outputting the number
				noi di "{pstd}`r(N)' observation(s) were excluded due to missing value in match varaible{p_end}"
			}
			*Drop obs with missing
			drop if missing(`matchvar')

			********************************
			*
			*	Checking duplicates in varaible names in options
			*
			********************************

			*Create a local of all varnames used in any option
			local allnewvars `idvar' `matchidname' `matchdiffname' `matchnoname'

			*Check if there are any duplicates in the local of all varnames in options
			local dupnewvars : list dups allnewvars

			*Throw error if there were any duplicates
			if "`dupnewvars'" != "" {

				di as error "The same variable name was used twice or more in the options. Go back and check syntax"
				error 198

			}

			********************************
			*
			*	Checking ID var
			*
			********************************

			*Checking set-up for the ID var used for _matchID
			if "`idvar'" == "" {

				*Copy this name
				local idvar _ID

				*Make sure that the default name _ID is not already used
				cap confirm variable `idvar'
				if _rc == 0 {

					di as error "A variable with name `idvar' is already defined. Either drop this variable or specify a variable using idvar() that fully and uniquely identifies the data set."
					error 110

				}

				*Generate the ID var from row number
				gen `idvar' = _n

			}
			else {

				*Make sure that user specified ID is uniquely and fully identifying the observations
				cap isid `idvar'
				if _rc != 0 {

					di as error "Variable `idvar' specified in idvar() does not fully and uniquely identify the observations in the data set. Meaning that `idvar' is not allowed to have any duplicates or missing values. Make `idvar' uniquly and fully idnetifying or exclude the varaibleas using if or in."
					error 450

				}
			}

			********************************
			*
			*	Checking and generating the MatchID and the MatchDiff var
			*
			********************************

			*Test input from user or test if deafault value is valiable
			iematchMatchVarCheck _matchID `matchidname'
			local matchIDname "`r(validVarName)'"
			gen  `matchIDname' = .

			if "`m1'" != "" {

				iematchMatchVarCheck _matchCount `matchcount'
				local matchCountName "`r(validVarName)'"
				gen `matchCountName' = .

			}

			iematchMatchVarCheck _matchDiff `matchdiffname'
			local matchDiffName "`r(validVarName)'"
			gen `matchDiffName' = .

			iematchMatchVarCheck _matchOrReason `matchnoname'
			local matchReasonName "`r(validVarName)'"
			gen `matchReasonName' = .

			*Create a label for missing values that explains no match
			label define matchLabel 0 "Not Matched" 1 "Matched" .n "Obs not included in match" .m "No match within maxdiff"

			*Apply the label
			label value `matchReasonName' matchLabel

}

			********************************
			*
			*	Creating tempvar used
			*
			********************************

			*Initiate the temporary variables used by this command
			tempvar prefID prefDiff matched

			gen `prefID' 		= .
			gen `prefDiff' 		= .
			gen byte `matched' 	= 0

			** Generate the inverse of the matchvar to sort descending (gsort is too slow),
			*  a random var to seperate two values with the same match var, and the inverse
			*  of the random var for when sorting descending.
			tempvar rand invsort invrand

			sort `matchvar'
			gen  `invsort' = -1 * `matchvar'

			gen    `rand' = uniform()
			gen `invrand' = -1 * `rand'

			tempvar					 diffup   diffdo   valUp_0   valDo_0   valUp_1   valDo_1   IDup   IDdo   IDup_0   IDdo_0   IDup_1   IDdo_1
			local 	 updownTempVars `diffup' `diffdo' `valUp_0' `valDo_0' `valUp_1' `valDo_1' `IDup' `IDdo' `IDup_0' `IDdo_0' `IDup_1' `IDdo_1'

			foreach tempVar of local updownTempVars {

				gen `tempVar' = .

			}

		********************************
		*	Start matching
		********************************

			***************************
			*
			*	One to one match
			*
			***************************

			if "`m1'" == "" {

				noi di ""
				noi di "{pstd}Observations left to match: {p_end}"
				count if `grpdummy' == 1 & `matched' == 0
				local left2Match = `r(N)'
				noi di "{pstd}`left2Match' " _c

				while (`left2Match' > 0) {

					**For all observations still to be matched, assign the preferred
					* match among the other unmatched observations
					qui updatePrefDiffPreffID `prefID' `prefDiff' `matchvar' `invsort' `idvar' `grpdummy' `matched' `rand' `invrand' `updownTempVars'

					if "`maxdiff'" != "" {

						replace `matched' 			= 1		if `prefDiff' > `maxdiff' & `grpdummy' == 1
						replace `prefID'			= .		if `prefDiff' > `maxdiff'
						replace `matchReasonName' 	= .m 	if `prefDiff' > `maxdiff' & `grpdummy' == 1
					}

					replace `matched' = 1 if `matched' == 0 & `prefID' == `idvar'[_n-1] & `prefID'[_n-1] == `idvar'
					replace `matched' = 1 if `matched' == 0 & `prefID' == `idvar'[_n+1] & `prefID'[_n+1] == `idvar'

					count if `grpdummy' == 1 & `matched' == 0
					local left2Match = `r(N)'
					noi di "`left2Match' " _c

				}
				noi di "{p_end}" _c

			}

			***************************
			*
			*	Many to one match
			*
			***************************
			else {

				updatePrefDiffPreffID `prefID' `prefDiff' `matchvar' `invsort' `idvar' `grpdummy' `matched' `rand' `invrand' `updownTempVars'

				if "`maxdiff'" != "" {

					replace `matched' 			= 1		if `prefDiff' > `maxdiff' & `grpdummy' == 1
					replace `prefID'			= .		if `prefDiff' > `maxdiff'
					replace `matchReasonName' 	= .m 	if `prefDiff' > `maxdiff' & `grpdummy' == 1
				}

				replace `prefID'			=  `idvar' if `grpdummy' == 0
				bys 	`prefID' 			:   replace `matchCountName' = _N
				replace `prefID' 			= . if  	`matchCountName' == 1
				replace  `matchCountName'	= . if  	`matchCountName' == 1

				replace `matched' = 1 if !missing(`prefID')
			}

			*Return vars
			replace `matchDiffName' 	= `prefDiff'	if `matched' == 1
			replace `matchIDname' 		= `idvar' 		if `matched' == 1 & `grpdummy' == 0
			replace `matchIDname' 		= `prefID' 		if `matched' == 1 & `grpdummy' == 1

			*Target obs not used
			replace `matchReasonName' = 0 if `matched' == 0 & `grpdummy' == 0

			*only keep output vars
			keep `matchIDname' `matchDiffName' `idvar' `originalSort' `matchReasonName' `matchCountName'

			tempfile mergefile

			save `mergefile'

		restore

		tempvar mergevar

		merge 1:1  `originalSort' using `mergefile', gen(`mergevar')

		replace `matchReasonName' = .n if `mergevar' == 1

		replace `matchReasonName' = 1 if `matchReasonName' == .

		noi tab `matchReasonName' `grpdummy', m

		sort `originalSort'

	}

	end

*Testing input (functions)
 if 1 {
	*Cheack matchVar input
	cap program drop 	iematchMatchVarCheck
		program define 	iematchMatchVarCheck  , rclass

		args defaultName userName

		if "`defaultName'" == "_matchID" 		local optionName matchidname
		if "`defaultName'" == "_matchDiff" 		local optionName matchdiffname
		if "`defaultName'" == "_matchOrReason" 	local optionName matchnoname
		if "`defaultName'" == "_matchCount" 	local optionName matchcount

		*All the default names
		local dfltNms _noMatchReason _matchDiff _matchOrReason _matchCount

		*The other two default names
		local othDfltNms : list dfltNms - defaultName

		*Creating two locals with the deafult name in each local
		local Oth1 : word 1 of `othDfltNms'
		local Oth2 : word 2 of `othDfltNms'
		local Oth3 : word 3 of `othDfltNms'

		*Testing that the option name is not the same as the other variable's default name.
		if ("`userName'" == "`Oth1'" | "`userName'" == "`Oth2'" | "`userName'" == "`Oth3'" | "`userName'" == "_ID")  {

			noi di as error "{phang}The new name specified in `optionName'(`userName') is not allowed to be _ID, `Oth1', `Oth2', or `Oth3'{p_end}"
			error 198
		}

		*Checking set-up for the ID var used for _matchID
		if "`userName'" == "" {

			*CSet the default name
			local validMatchVarname `defaultName'

			*Make sure that the default name _ID is not already used
			cap confirm variable `validMatchVarname'
			if _rc == 0 {

				noi di as error "A variable with name `validMatchVarname' is already defined. Either drop this variable or specify a new variable name using `optionName'()."
				error 110

			}

		}

		else {

			*CSet the default name
			local validMatchVarname `userName'

			*Make sure that the default name _ID is not already used
			cap confirm variable `validMatchVarname'
			if _rc == 0 {

				noi di as error "The variable name specified in `optionName'(`userName') is already defined in the data set. Either drop this variable or specify a another variable name using `optionName'()."
				error 110

			}

		}

		*Testing that the new name is valid by creating a variable that is dropped immedeatly afterwards
		cap gen `validMatchVarname' = .

		if _rc != 0 {

			noi di as error "The variable name specified in `optionName'(`userName') is not a valid variable name."
			error _rc

		}
		drop `validMatchVarname'

		return local validVarName 	"`validMatchVarname'"

	end
}

*Matching functions
if 1 {

	** This function is called to assign the preferred match for all unmatched
	*  observations to any other unmatched observation. Returns a variable pref that is the
	cap program drop 	updatePrefDiffPreffID
		program define 	updatePrefDiffPreffID

		args prefID prefDiff matchvar invsort idvar grpvar matched rand invrand diffup diffdo valUp_0 valDo_0 valUp_1 valDo_1 IDup IDdo IDup_0 IDdo_0 IDup_1 IDdo_1

		*****************
		*Update possible matches with higher rank value
		sort `matched' `matchvar' `rand'

		updateBestValID 0 `matchvar' `idvar' `grpvar' `matched' `valUp_0' `IDup_0'
		updateBestValID 1 `matchvar' `idvar' `grpvar' `matched' `valUp_1' `IDup_1'

		*****************
		*Update possible matches with lower rank value
		sort `matched' `invsort' `invrand'

		updateBestValID 0 `matchvar' `idvar' `grpvar' `matched' `valDo_0' `IDdo_0'
		updateBestValID 1 `matchvar' `idvar' `grpvar' `matched' `valDo_1' `IDdo_1'

		*****************
		*Create one varaible common for both groups with diff upwards
		replace `diffup' 	= abs(`matchvar' - `valUp_1') if `grpvar' == 1
		replace `diffup' 	= abs(`matchvar' - `valUp_0') if `grpvar' == 0

		*Create one varaible common for both groups with diff downwards
		replace `diffdo' 	= abs(`matchvar' - `valDo_1') if `grpvar' == 1
		replace `diffdo' 	= abs(`matchvar' - `valDo_0') if `grpvar' == 0

		*Create one varaible common for both groups with ID upwards
		replace `IDup' 		= `IDup_1' 	if `grpvar' == 1
		replace `IDup' 		= `IDup_0' 	if `grpvar' == 0

		*Create one varaible common for both groups with ID downwards
		replace `IDdo' 		= `IDdo_1' 	if `grpvar' == 1
		replace `IDdo' 		= `IDdo_0' 	if `grpvar' == 0

		replace `prefID' 	= `IDdo' 	if `matched' == 0 & `diffdo' <= `diffup'
		replace `prefID' 	= `IDup' 	if `matched' == 0 & `diffdo' >  `diffup'

		replace `prefDiff' 	= `diffdo' 	if `matched' == 0 & `diffdo' <= `diffup'
		replace `prefDiff' 	= `diffup' 	if `matched' == 0 & `diffdo' >  `diffup'

	end

	** This function goes through the observatioins from top to down and copying
	*  the match value of the closest observation of the other group above to
	*  (bestVal) and the ccoprresponding ID to (bestID) for obe group at the time.
	*  To go from bottuom to top sort with invsort and apply this command.
	cap program drop 	updateBestValID
		program define 	updateBestValID

		args grpvl matchval idvar grpvar matched bestVal bestID

		*Reset all values
		replace `bestVal' 	= .
		replace `bestID' 	= .

		*Set the match value and ID of observations that are in the other group
		replace `bestVal'   = `matchval' 		if `grpvar' != `grpvl' & `matched' == 0
		replace `bestID'  	= `idvar' 			if `grpvar' != `grpvl' & `matched' == 0

		*Fill in that value from the observation in the other group until getting to another observation of the other group
		replace `bestVal'   = `bestVal'[_n-1]	if `bestVal' == . & `matched' == 0
		replace `bestID'  	= `bestID'[_n-1] 	if `bestID'	 == . & `matched' == 0

	end

}

	clear

	set seed 125345324

	set obs 30000

	gen id = _n

	gen rand1 = uniform()

	gen tmt = (rand1 < .40)

	*replace tmt = . if (rand1 < .45)

	drop rand1
	tab tmt

	gen p_hat = uniform()

	*replace p_hat = p_hat + .03 if tmt == 1

	*replace p_hat = . if p_hat < .2

	iematch  , grp(tmt) match(p_hat) idvar(id)   maxdiff(.01)  //matchidname(Kallefille)

	clear all

	*command starts here

	cap program drop 	iematch
	    program define	iematch

		syntax  [if] [in]  , ///
			GRPdummy(varname) 		///
			MATCHvar(varname) 		///
			[						///
			idvar(varname)			///
			matchidname(string)		///
			matchdiffname(string)	///
			matchnoname(string)		///
			maxdiff(numlist max = 1 min = 1) ///
			]

		*****
		*1 format errors as smcl
		*2 make match only on obs with value in group dummy
		*3 m:1 match
		*4 option to disable countdown

		noi di "Syntax OK!"

		pause on

		qui {

		********************************
		*
		*	Gen temp sort and merge var
		*
		********************************

		tempvar originalSort

		gen `originalSort' = _n

		preserve

*Testing input
if 1 {

			if "`if'`in'" != "" keep `if'`in'

			********************************
			*
			*	Checking group dummy
			*
			********************************

			*Test that the group dummy is 1, 0 or missing
			cap assert inlist(`grpdummy', 1, 0, .) | `grpdummy' > .
			if _rc != 0 {

				di as error "The variable in grpdummy(`grpdummy') is not a dummy variable. The variable is only allowed to have the values 1, 0 or missing. Observations with missing varaibles in the grpdummy are ignored by this command."
				error _rc
			}

			**Exclude obs with missing value in groupdummy

			*Count number of obs to be dropped and and output that number if more than zero
			count if missing(`grpdummy')
			if `r(N)' > 0 {
				*This is not an error just outputting the number
				noi di "{pstd}`r(N)' observation(s) were excluded due to missing value in group dummy{p_end}"
			}
			*Drop obs with missing
			drop if missing(`grpdummy')

			********************************
			*
			*	Checking match continous var
			*
			********************************

			*Test that the continous is numeric
			cap confirm numeric variable `matchvar'
			if _rc != 0 {

				di as error "The variable to match on specified in matchvar(`matchvar') is not a numeric variable."
				error 109

			}

			**Exclude obs with missing value in groupdummy

			*Count number of obs to be dropped and and output that number if more than zero
			count if missing(`matchvar')
			if `r(N)' > 0 {
				*This is not an error just outputting the number
				noi di "{pstd}`r(N)' observation(s) were excluded due to missing value in match varaible{p_end}"
			}
			*Drop obs with missing
			drop if missing(`matchvar')

			********************************
			*
			*	Checking duplicates in varaible names in options
			*
			********************************

			*Create a local of all varnames used in any option
			local allnewvars `idvar' `matchidname' `matchdiffname' `matchnoname'

			*Check if there are any duplicates in the local of all varnames in options
			local dupnewvars : list dups allnewvars

			*Throw error if there were any duplicates
			if "`dupnewvars'" != "" {

				di as error "The same variable name was used twice or more in the options. Go back and check syntax"
				error 198

			}

			********************************
			*
			*	Checking ID var
			*
			********************************

			*Checking set-up for the ID var used for _matchID
			if "`idvar'" == "" {

				*Copy this name
				local idvar _ID

				*Make sure that the default name _ID is not already used
				cap confirm variable `idvar'
				if _rc == 0 {

					di as error "A variable with name `idvar' is already defined. Either drop this variable or specify a variable using idvar() that fully and uniquely identifies the data set."
					error 110

				}

				*Generate the ID var from row number
				gen `idvar' = _n

			}
			else {

				*Make sure that user specified ID is uniquely and fully identifying the observations
				cap isid `idvar'
				if _rc != 0 {

					di as error "Variable `idvar' specified in idvar() does not fully and uniquely identify the observations in the data set. Meaning that `idvar' is not allowed to have any duplicates or missing values. Make `idvar' uniquly and fully idnetifying or exclude the varaibleas using if or in."
					error 450

				}
			}

			********************************
			*
			*	Checking and generating the MatchID and the MatchDiff var
			*
			********************************

			*Test input from user or test if deafault value is valiable
			iematchMatchVarCheck _matchID `matchidname'
			local matchIDname "`r(validVarName)'"
			gen  `matchIDname' = .

			iematchMatchVarCheck _matchDiff `matchdiffname'
			local matchDiffName "`r(validVarName)'"
			gen `matchDiffName' = .

			iematchMatchVarCheck _matchOrReason `matchnoname'
			local noMatchReasonName "`r(validVarName)'"
			gen `noMatchReasonName' = .

			*Create a label for missing values that explains no match
			label define matchLabel 0 "Not Matched" 1 "Matched" .n "Obs not included in match" .m "No match within maxdiff"

			*Apply the label
			label value `noMatchReasonName' matchLabel

}

			********************************
			*
			*	Creating tempvar used
			*
			********************************

			*Initiate the temporary variables used by this command
			tempvar prefID prefDiff matched

			gen `prefID' 		= .
			gen `prefDiff' 		= .
			gen byte `matched' 	= 0

			** Generate the inverse of the matchvar to sort descending (gsort is too slow),
			*  a random var to seperate two values with the same match var, and the inverse
			*  of the random var for when sorting descending.
			tempvar rand invsort invrand

			sort `matchvar'
			gen  `invsort' = -1 * `matchvar'

			gen    `rand' = uniform()
			gen `invrand' = -1 * `rand'

			tempvar					diffup diffdo valUp_0 valDo_0 valUp_1 valDo_1 IDup IDdo IDup_0 IDdo_0 IDup_1 IDdo_1
			local 	 updownTempVars `diffup' `diffdo' `valUp_0' `valDo_0' `valUp_1' `valDo_1' `IDup' `IDdo' `IDup_0' `IDdo_0' `IDup_1' `IDdo_1'

			foreach tempVar of local updownTempVars {

				gen `tempVar' = .

			}

			********************************
			*
			*	Start matching
			*
			********************************
			noi di ""
			noi di "{pstd}Observations left to match: {p_end}"
			count if `grpdummy' == 1 & `matched' == 0
			local left2Match = `r(N)'
			noi di "{pstd}`left2Match' " _c

			while (`left2Match' > 0) {

				**For all observations still to be matched, assign the preferred
				* match among the other unmatched observations
				qui updatePrefDiffPreffID `prefID' `prefDiff' `matchvar' `invsort' `idvar' `grpdummy' `matched' `rand' `invrand' `updownTempVars'

				if "`maxdiff'" != "" {

					replace `matched' 			= 1		if `prefDiff' > `maxdiff' & `grpdummy' == 1
					replace `prefID'			= .		if `prefDiff' > `maxdiff'
					replace `noMatchReasonName' = .m 	if `prefDiff' > `maxdiff' & `grpdummy' == 1
				}

				replace `matched' = 1 if `matched' == 0 & `prefID' == `idvar'[_n-1] & `prefID'[_n-1] == `idvar'
				replace `matched' = 1 if `matched' == 0 & `prefID' == `idvar'[_n+1] & `prefID'[_n+1] == `idvar'

				count if `grpdummy' == 1 & `matched' == 0
				local left2Match = `r(N)'
				noi di "`left2Match' " _c

			}
			noi di "{p_end}" _c

			*Return vars
			replace `matchDiffName' 	= `prefDiff'	if `matched' == 1
			replace `matchIDname' 		= `idvar' 		if `matched' == 1 & `grpdummy' == 0
			replace `matchIDname' 		= `prefID' 		if `matched' == 1 & `grpdummy' == 1

			*Target obs not used
			replace `noMatchReasonName' = 0 if `matched' == 0 & `grpdummy' == 0

			*only keep output vars
			keep `matchIDname' `matchDiffName' `idvar' `originalSort' `noMatchReasonName'

			tempfile mergefile

			save `mergefile'

		restore

		tempvar mergevar

		merge 1:1  `originalSort' using `mergefile', gen(`mergevar')

		replace `noMatchReasonName' = .n if `mergevar' == 1

		replace `noMatchReasonName' = 1 if `noMatchReasonName' == .

		noi tab `noMatchReasonName' `grpdummy', m

		sort `originalSort'

	}

	end

*Testing input (functions)
 if 1 {
	*Cheack matchVar input
	cap program drop 	iematchMatchVarCheck
		program define 	iematchMatchVarCheck  , rclass

		args defaultName userName

		if "`defaultName'" == "_matchID" 		local optionName matchidname
		if "`defaultName'" == "_matchDiff" 		local optionName matchdiffname
		if "`defaultName'" == "_matchOrReason" 	local optionName matchnoname

		*All the default names
		local dfltNms _noMatchReason _matchDiff _matchOrReason

		*The other two default names
		local othDfltNms : list dfltNms - defaultName

		*Creating two locals with the deafult name in each local
		local Oth1 : word 1 of `othDfltNms'
		local Oth2 : word 2 of `othDfltNms'

		*Testing that the option name is not the same as the other variable's default name.
		if ("`defaultName'" == "_matchID" & ("`userName'" == "`Oth1'" | "`userName'" == "`Oth2'" | "`userName'" == "_ID"))  {

			noi di as error `" ("`defaultName'" == "_matchID" & ("`userName'" == "`Oth1'" | "`userName'" == "`Oth2'" | "`userName'" == "_ID")) "'

			noi di as error "The new name specified in `optionName'() is not allowed to be _ID, `Oth1', nor `Oth2'"
			error 198
		}

		*Checking set-up for the ID var used for _matchID
		if "`userName'" == "" {

			*CSet the default name
			local validMatchVarname `defaultName'

			*Make sure that the default name _ID is not already used
			cap confirm variable `validMatchVarname'
			if _rc == 0 {

				noi di as error "A variable with name `validMatchVarname' is already defined. Either drop this variable or specify a new variable name using `optionName'()."
				error 110

			}

		}

		else {

			*CSet the default name
			local validMatchVarname `userName'

			*Make sure that the default name _ID is not already used
			cap confirm variable `validMatchVarname'
			if _rc == 0 {

				noi di as error "The variable name specified in `optionName'(`userName') is already defined in the data set. Either drop this variable or specify a another variable name using `optionName'()."
				error 110

			}

		}

		*Testing that the new name is valid by creating a variable that is dropped immedeatly afterwards
		cap gen `validMatchVarname' = .

		if _rc != 0 {

			noi di as error "The variable name specified in `optionName'(`userName') is not a valid variable name."
			error _rc

		}
		drop `validMatchVarname'

		return local validVarName 	"`validMatchVarname'"

	end
}

*Matching functions
if 1 {

	** This function is called to assign the preferred match for all unmatched
	*  observations to any other unmatched observation. Returns a variable pref that is the
	cap program drop 	updatePrefDiffPreffID
		program define 	updatePrefDiffPreffID

		args prefID prefDiff matchvar invsort idvar grpvar matched rand invrand diffup diffdo valUp_0 valDo_0 valUp_1 valDo_1 IDup IDdo IDup_0 IDdo_0 IDup_1 IDdo_1

		*****************
		*Update possible matches with higher rank value
		sort `matched' `matchvar' `rand'

		updateBestValID 0 `matchvar' `idvar' `grpvar' `matched' `valUp_0' `IDup_0'
		updateBestValID 1 `matchvar' `idvar' `grpvar' `matched' `valUp_1' `IDup_1'

		*****************
		*Update possible matches with lower rank value
		sort `matched' `invsort' `invrand'

		updateBestValID 0 `matchvar' `idvar' `grpvar' `matched' `valDo_0' `IDdo_0'
		updateBestValID 1 `matchvar' `idvar' `grpvar' `matched' `valDo_1' `IDdo_1'

		*****************
		*Create one varaible common for both groups with diff upwards
		replace `diffup' 	= abs(`matchvar' - `valUp_1') if `grpvar' == 1
		replace `diffup' 	= abs(`matchvar' - `valUp_0') if `grpvar' == 0

		*Create one varaible common for both groups with diff downwards
		replace `diffdo' 	= abs(`matchvar' - `valDo_1') if `grpvar' == 1
		replace `diffdo' 	= abs(`matchvar' - `valDo_0') if `grpvar' == 0

		*Create one varaible common for both groups with ID upwards
		replace `IDup' 		= `IDup_1' 	if `grpvar' == 1
		replace `IDup' 		= `IDup_0' 	if `grpvar' == 0

		*Create one varaible common for both groups with ID downwards
		replace `IDdo' 		= `IDdo_1' 	if `grpvar' == 1
		replace `IDdo' 		= `IDdo_0' 	if `grpvar' == 0

		replace `prefID' 	= `IDdo' 	if `matched' == 0 & `diffdo' <= `diffup'
		replace `prefID' 	= `IDup' 	if `matched' == 0 & `diffdo' >  `diffup'

		replace `prefDiff' 	= `diffdo' 	if `matched' == 0 & `diffdo' <= `diffup'
		replace `prefDiff' 	= `diffup' 	if `matched' == 0 & `diffdo' >  `diffup'

	end

	** This function goes through the observatioins from top to down and copying
	*  the match value of the closest observation of the other group above to
	*  (bestVal) and the ccoprresponding ID to (bestID) for obe group at the time.
	*  To go from bottuom to top sort with invsort and apply this command.
	cap program drop 	updateBestValID
		program define 	updateBestValID

		args grpvl matchval idvar grpvar matched bestVal bestID

		*Reset all values
		replace `bestVal' 	= .
		replace `bestID' 	= .

		*Set the match value and ID of observations that are in the other group
		replace `bestVal'   = `matchval' 		if `grpvar' != `grpvl' & `matched' == 0
		replace `bestID'  	= `idvar' 			if `grpvar' != `grpvl' & `matched' == 0

		*Fill in that value from the observation in the other group until getting to another observation of the other group
		replace `bestVal'   = `bestVal'[_n-1]	if `bestVal' == . & `matched' == 0
		replace `bestID'  	= `bestID'[_n-1] 	if `bestID'	 == . & `matched' == 0

	end

}

	clear

	set seed 125345324

	set obs 300000

	gen id = _n

	gen rand1 = uniform()

	gen tmt = (rand1 < .40)

	*replace tmt = . if (rand1 < .45)

	drop rand1
	tab tmt

	gen p_hat = uniform()

	*replace p_hat = p_hat + .03 if tmt == 1

	*replace p_hat = . if p_hat < .2

	iematch  , grp(tmt) match(p_hat) idvar(id)  maxdiff(.01) //matchidname(Kallefille)


[INFRA] - Updated wave.do file with new signals

onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -expand -group {clock and reset} -radix hexadecimal /top_tb/T1/clk
add wave -noupdate -expand -group {clock and reset} -radix hexadecimal /top_tb/T1/reset
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/curr_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_seq_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_jmp_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_beq_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_brn_eq_pc_top
add wave -noupdate -expand -group instr -radix hexadecimal /top_tb/T1/instr_top
add wave -noupdate -expand -group instr -radix hexadecimal /top_tb/T1/funct_top
add wave -noupdate -expand -group instr -radix hexadecimal /top_tb/T1/op_top
add wave -noupdate -expand -group instr /top_tb/T1/sign_ext_top
add wave -noupdate -expand -group instr /top_tb/T1/is_r_type_top
add wave -noupdate -expand -group instr /top_tb/T1/is_i_type_top
add wave -noupdate -expand -group instr /top_tb/T1/is_j_type_top
add wave -noupdate -expand -group control /top_tb/T1/reg_src_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/reg_dst_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/jump_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/branch_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/mem_read_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/mem_to_reg_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/alu_op_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/mem_wr_top
add wave -noupdate -expand -group control /top_tb/T1/alu_src_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/reg_wr_top
add wave -noupdate -expand -group control /top_tb/T1/sign_ext_top
add wave -noupdate -expand -group control /top_tb/T1/use_link_reg_top
add wave -noupdate -expand -group alu -radix hexadecimal /top_tb/T1/r_data_p1_top
add wave -noupdate -expand -group alu -radix hexadecimal /top_tb/T1/r_data_p2_top
add wave -noupdate -expand -group alu /top_tb/T1/n_top
add wave -noupdate -expand -group alu -radix hexadecimal /top_tb/T1/res_alu_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/rd_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/rs_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/rt_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/r_data_p1_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/r_data_p2_rf_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/wr_data_rf_top
add wave -noupdate -expand -group rf /top_tb/T1/rs_dec_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/rd_dec_top
add wave -noupdate -radix hexadecimal /top_tb/T1/sign_imm_top
add wave -noupdate -radix hexadecimal /top_tb/T1/target_top
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/opr_a_alu_i
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/opr_b_alu_i
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/op_alu_i
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/cin_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/opr_b_negated_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/adder_out_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/carry_out_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/shifter_out_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/logical_out_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/res_alu_o
add wave -noupdate -group {alu block} /top_tb/T1/A1/n_alu_o
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/z_alu_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/alu_op_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/alu_src_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/branch_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/controls
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/instr_funct_ctl_i
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/instr_op_ctl_i
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/jump_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/mem_read_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/mem_to_reg_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/mem_wr_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/reg_dst_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/reg_wr_ctl_o
add wave -noupdate -group {control block} /top_tb/T1/C1/sign_ext_ctl_o
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/clk
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/reset
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_reg_p1_rf_i
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_data_p1
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_data_p1_rf_o
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_reg_p2_rf_i
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_data_p2
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_data_p2_rf_o
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/w_reg_rf_i
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/w_en_rf_i
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/w_data_rf_i
add wave -noupdate -expand -group {rf block} -radix hexadecimal /top_tb/T1/R1/reg_file
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/funct_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/instr_dec_i
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/is_i_type_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/is_j_type_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/is_r_type_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/op_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/rd_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/rs_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/rt_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/shamt_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/sign_imm_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/target_dec_o
add wave -noupdate -expand -group {decode block} -radix hexadecimal /top_tb/T1/D1/use_link_reg_dec_o
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {53 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 282
configure wave -valuecolwidth 187
configure wave -justifyvalue left
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {0 ps} {110 ps}

onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -expand -group {clock and reset} -radix hexadecimal /top_tb/T1/clk
add wave -noupdate -expand -group {clock and reset} -radix hexadecimal /top_tb/T1/reset
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/curr_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_seq_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_jmp_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_beq_pc_top
add wave -noupdate -expand -group pc -radix hexadecimal /top_tb/T1/next_brn_eq_pc_top
add wave -noupdate -expand -group instr -radix hexadecimal /top_tb/T1/instr_top
add wave -noupdate -expand -group instr -radix hexadecimal /top_tb/T1/funct_top
add wave -noupdate -expand -group instr -radix hexadecimal /top_tb/T1/op_top
add wave -noupdate -expand -group instr /top_tb/T1/sign_ext_top
add wave -noupdate -expand -group instr /top_tb/T1/is_r_type_top
add wave -noupdate -expand -group instr /top_tb/T1/is_i_type_top
add wave -noupdate -expand -group instr /top_tb/T1/is_j_type_top
add wave -noupdate -expand -group control /top_tb/T1/reg_src_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/reg_dst_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/jump_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/branch_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/mem_read_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/mem_to_reg_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/alu_op_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/mem_wr_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/reg_wr_top
add wave -noupdate -expand -group control -radix hexadecimal /top_tb/T1/alu_src_top
add wave -noupdate -expand -group alu -radix hexadecimal /top_tb/T1/r_data_p1_top
add wave -noupdate -expand -group alu -radix hexadecimal /top_tb/T1/r_data_p2_top
add wave -noupdate -expand -group alu /top_tb/T1/n_top
add wave -noupdate -expand -group alu -radix hexadecimal /top_tb/T1/res_alu_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/rd_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/rs_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/rt_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/r_data_p1_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/r_data_p2_rf_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/wr_data_rf_top
add wave -noupdate -expand -group rf /top_tb/T1/rs_dec_top
add wave -noupdate -expand -group rf -radix hexadecimal /top_tb/T1/rd_dec_top
add wave -noupdate -radix hexadecimal /top_tb/T1/sign_imm_top
add wave -noupdate -radix hexadecimal /top_tb/T1/target_top
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/opr_a_alu_i
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/opr_b_alu_i
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/op_alu_i
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/cin_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/opr_b_negated_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/adder_out_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/carry_out_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/shifter_out_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/logical_out_alu
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/res_alu_o
add wave -noupdate -group {alu block} /top_tb/T1/A1/n_alu_o
add wave -noupdate -group {alu block} -radix hexadecimal /top_tb/T1/A1/z_alu_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/alu_op_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/alu_src_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/branch_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/controls
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/instr_funct_ctl_i
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/instr_op_ctl_i
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/jump_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/mem_read_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/mem_to_reg_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/mem_wr_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/reg_dst_ctl_o
add wave -noupdate -group {control block} -radix hexadecimal /top_tb/T1/C1/reg_wr_ctl_o
add wave -noupdate -group {control block} /top_tb/T1/C1/sign_ext_ctl_o
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/clk
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_data_p1
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_data_p1_rf_o
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_data_p2
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_data_p2_rf_o
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_reg_p1_rf_i
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/r_reg_p2_rf_i
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/reg_file
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/reset
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/w_data_rf_i
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/w_en_rf_i
add wave -noupdate -group {rf block} -radix hexadecimal /top_tb/T1/R1/w_reg_rf_i
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {50 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 282
configure wave -valuecolwidth 187
configure wave -justifyvalue left
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {96 ps} {206 ps}


iegraph : help fiel adding ahmad

iegraph : help fiel adding ahmad

{smcl}
{* 26 Dec 2016}{...}
{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}
, [{cmd:noconfbars} {cmdab:ti:tle(}{it:string}{cmd:)}
{cmdab:save(}{it:string}{cmd:)} {cmdab:confbarsnone(}{it:varlist}{cmd:)}
{it:any towway graph options}
]

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt :{cmd:noconfbars}} Removes the confidence interval bars from graphs for all treatments.{p_end}
{synopt :{cmdab:ti:tle(}{it:string}{cmd:)}} Manually sets the title of the graph.{p_end}
{synopt :{cmdab:save(}{it:string}{cmd:)}} Sets the filename and the directory to which the graph will be set.{p_end}
{synopt :{cmdab:confbarsnone(}{it:varlist}{cmd:)}} Removes confidence interval bars from only the {it:varlist} listed.{p_end}
{synopt :{cmdab:yzero}} Forces y-axis on the graph to start at 0.{p_end}
{synopt :{cmdab: Graph Options}} Options that can be used with normal graph commands can also be used. See example 2 for details.{p_end}
{synoptline}

{marker desc}
{title:Description}

{pstd}{cmdab:iegraph} This command creates bar graphs on the based on the coefficients
	of treatment dummies in regression results. This command is developed for reading
	stored results of 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 immedeatly after running the regression or as long as teh 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 varaible and one dummy for each
	treatment arm where control is the omitted category. This regressions can also include
	covariates, fixed effects etc., but as long as the treatment status is defined by
	mutually exclusive dummy variables. See especially example 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-Differneces}{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 varaibles, 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}{cmd:noconfbars} Removes the confidence interval bars from graphs for all
	treatments. The default value for the confidence interval bars ar 95%. {p_end}

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

{phang}{cmdab:save(}{it:string}{cmd:)} Sets the filename and the directory to which
	the graph will be set.{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 is 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 reserached. 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 is not included
		in {cmd:iegraph}. {inp:noconfbars} omitts the confidence intervall 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:"$Output/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 presidence 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}Ahmad Zia Wahdat{break}

{title:Author}

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

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietools 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}
{* 26 Dec 2016}{...}
{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}
, [{cmd:noconfbars} {cmdab:ti:tle(}{it:string}{cmd:)}
{cmdab:save(}{it:string}{cmd:)} {cmdab:confbarsnone(}{it:varlist}{cmd:)}
{it:any towway graph options}
]

{marker opts}{...}
{synoptset 22}{...}
{synopthdr:options}
{synoptline}
{synopt :{cmd:noconfbars}} Removes the confidence interval bars from graphs for all treatments.{p_end}
{synopt :{cmdab:ti:tle(}{it:string}{cmd:)}} Manually sets the title of the graph.{p_end}
{synopt :{cmdab:save(}{it:string}{cmd:)}} Sets the filename and the directory to which the graph will be set.{p_end}
{synopt :{cmdab:confbarsnone(}{it:varlist}{cmd:)}} Removes confidence interval bars from only the {it:varlist} listed.{p_end}
{synopt :{cmdab:yzero}} Forces y-axis on the graph to start at 0.{p_end}
{synopt :{cmdab: Graph Options}} Options that can be used with normal graph commands can also be used. See example 2 for details.{p_end}
{synoptline}

{marker desc}
{title:Description}

{pstd}{cmdab:iegraph} This command creates bar graphs on the based on the coefficients
	of treatment dummies in regression results. This command is developed for reading
	stored results of 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 immedeatly after running the regression or as long as teh 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 varaible and one dummy for each
	treatment arm where control is the omitted category. This regressions can also include
	covariates, fixed effects etc., but as long as the treatment status is defined by
	mutually exclusive dummy variables. See especially example 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-Differneces}{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 varaibles, 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}{cmd:noconfbars} Removes the confidence interval bars from graphs for all
	treatments. The default value for the confidence interval bars ar 95%. {p_end}

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

{phang}{cmdab:save(}{it:string}{cmd:)} Sets the filename and the directory to which
	the graph will be set.{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 is 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 reserached. 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 is not included
		in {cmd:iegraph}. {inp:noconfbars} omitts the confidence intervall 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:"$Output/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 presidence 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}{break}

{title:Author}

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

{phang}Please send bug-reports, suggestions and requests for clarifications
		 writing "ietools 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"}


ieimpgraph : fix typo

ieimpgraph : fix typo

cap	program drop	ieimpgraph
	program define 	ieimpgraph

	syntax anything

	mat list e(b)

	foreach var of local varlist {

		local beta = _b[`var']

		di "`beta'"

	}

end

cap	program drop	tobeused
	program define 	tobeused

	capture file close `textfile'_`date'
	file open  `textfile'_`date' using `textfile'_`date'.txt, text write replace
	file write `textfile'_`date' ///
		"Variable" 	_tab "Tmt-Status"	_tab "mean" _tab "coeff" _tab "conf_int_min" _tab "conf_int_max" _tab "obs" _tab "star" _n
	file close `textfile'_`date'

	local REG_RESULTS ""
	foreach depvar of local depvars {

		rename lag2_`depvar' lagvar

		local regname `depvar'
			eststo `regname' : areg `depvar' tmt_reg tmt_sdp tmt_inc lagvar NoCropBoroBL NoCropBL incorrect_no_bl NoPlotDataBL NoHarvValueDataBL if t == 2, a(d_code) cl(v_code)
		local  REG_RESULTS "`REG_RESULTS' `regname'"

		foreach tmt_arm in reg sdp inc {
			scalar coeff_`tmt_arm' 		= _b[tmt_`tmt_arm']
			scalar coeff_se_`tmt_arm' 	= _se[tmt_`tmt_arm']

			sum `depvar' if e(sample) & tmt_`tmt_arm' == 1
			scalar obs_`tmt_arm'	= r(N)
		}

		sum `depvar' if e(sample) & tmt_reg == 0 & tmt_sdp == 0 & tmt_inc == 0
		scalar ctl_N		= r(N)
		scalar ctl_mean	  	= r(mean)
		scalar ctl_mean_sd 	= r(sd)

		estadd scalar ctl_mean_table	=r(mean)
		estadd scalar ctl_N_table		=r(N)
		estadd scalar ctl_mean_sd_table	=r(sd)

		sum lagvar if e(sample) & !(NoCropBoroBL == 1 | NoCropBL == 1 | incorrect_no_bl == 1 | NoPlotDataBL == 1 | NoHarvValueDataBL == 1)
		scalar BL_mean 		= r(mean)
		scalar BL_N 	= r(N)

		estadd scalar BL_mean_table	=r(mean)
		estadd scalar BL_N_table	=r(N)

		rename lagvar lag2_`depvar'

		foreach tmt_arm in reg sdp inc {
			scalar  conf_int_min_`tmt_arm'   =coeff_`tmt_arm'-(1.96*coeff_se_`tmt_arm') + ctl_mean
			scalar  conf_int_max_`tmt_arm'   =coeff_`tmt_arm'+(1.96*coeff_se_`tmt_arm') + ctl_mean

			test    tmt_`tmt_arm'

			scalar  pvalue =r(p)
			local star_`tmt_arm'
			if pvalue < 0.10 {
				local star_`tmt_arm' "*"
			}
			if pvalue < 0.05 {
				local star_`tmt_arm' "**"
			}
			if pvalue < 0.01 {
				local star_`tmt_arm' "***"
			}

			scalar tmt_mean_`tmt_arm' = ctl_mean + coeff_`tmt_arm'
		}

		file open  `textfile'_`date' using `textfile'_`date'.txt, text write append
		file write `textfile'_`date' ///
			"`regname'" _tab "Control"  _tab %9.3f (ctl_mean)      _tab  		 			_tab 		 			  	  _tab 			 				_tab %9.3f (ctl_N) 	   _tab			  	  _n ///
			"`regname'" _tab "reg"		_tab %9.3f (tmt_mean_reg)  _tab  %9.3f (coeff_reg)  _tab %9.3f (conf_int_min_reg) _tab %9.3f (conf_int_max_reg) _tab %9.3f (obs_reg)   _tab "`star_reg'"  _n ///
			"`regname'" _tab "sdp"		_tab %9.3f (tmt_mean_sdp)  _tab  %9.3f (coeff_sdp)  _tab %9.3f (conf_int_min_sdp) _tab %9.3f (conf_int_max_sdp) _tab %9.3f (obs_sdp)   _tab "`star_sdp'"  _n ///
			"`regname'" _tab "inc"		_tab %9.3f (tmt_mean_inc)  _tab  %9.3f (coeff_inc)  _tab %9.3f (conf_int_min_inc) _tab %9.3f (conf_int_max_inc) _tab %9.3f (obs_inc)   _tab "`star_inc'"  _n
		file close `textfile'_`date'

	}
	esttab `REG_RESULTS' using "$csv/outcomeVar_AllTreat_`date'.csv",      ///
		title(`tabeleFileName') stats(BL_mean_table BL_N_table ctl_mean_table ctl_N_table ctl_mean_sd_table N) mtitles nonumbers plain br  star(* 0.10 ** 0.05 *** 0.01) ///
		b(a3)  se(%9.2f) alignment(l) replace

	/***************************************

		Produce the graphs

	***************************************/

	insheet using `textfile'_`date'.txt, clear tab

	pause on

	cd "$graphs/gRaw"

	gen tmt = .
	replace tmt = 1 if tmtstatus == "Control"
	replace tmt = 2 if tmtstatus == "reg"
	replace tmt = 3 if tmtstatus == "sdp"
	replace tmt = 4 if tmtstatus == "inc"

	gen placement = tmt

	*gen 	placement = tmt if demo_code == 1
	*replace placement = tmt + 5 if demo_code == 2

	foreach percentVar in mean coeff conf_int_min conf_int_max {

		replace `percentVar' =  `percentVar' * 100 if variable == "c1_commerce"
	}

	gen 	labelString 		= ""
	gen 	labelCategory		= .
	local 	continVars_Large  	c1_harv_value c1_net_yield c1_gross_yield c1_total_earnings c2_inp_total_spending c1_IAAP_harv_value c1_net_yield_nonLabor c1_net_yield_allLabor
	local 	continVars_Small  	c1_total_plotsize
	local 	percentage_Vars   	c1_commerce

	foreach L_var of local continVars_Large {

		replace labelCategory = 1 if variable == "`L_var'"
	}
	foreach S_var of local continVars_Small {

		replace labelCategory = 2 if variable == "`S_var'"
	}
	foreach P_var of local percentage_Vars {

		replace labelCategory = 3 if variable == "`P_var'"
	}

	tempvar labelString_temp decimal_postion

	tostring mean,	gen(`labelString_temp') force
	gen 	`decimal_postion' = strpos(`labelString_temp',".")

	*For continious values without decimal point (means include all in practice)
	replace `decimal_postion' = 10 if  `decimal_postion' == 0

	replace labelString = substr(`labelString_temp',1,(`decimal_postion'-1)) 		if labelCategory == 1
	replace labelString = substr(`labelString_temp',1,4) 							if labelCategory == 2
	replace labelString = substr(`labelString_temp',1,`decimal_postion'+1) + "%"	if labelCategory == 3

	tempfile restart_loop
	save 	`restart_loop', replace

	levelsof variable
	foreach level in `r(levels)' {
		use `restart_loop', clear
		di "`level'"
		keep if variable == "`level'"

		foreach tmt in reg sdp inc {
			preserve
				keep if tmtstatus == "`tmt'"
				local obs_`tmt'  = obs[1]
				local star_`tmt' = star[1]
			restore
		}

		preserve
			keep if tmtstatus == "Control"
			local obs_ctrl  = obs[1]
		restore

		local title "ERROR"

		if "`level'" == "c1_IAAP_harv_value"	local title "Harvest value IAPP crops, Taka"
		if "`level'" == "c1_commerce"			local title "Commercialization, earnings/production %"
		if "`level'" == "c1_gross_yield"		local title "Gross yield, Taka/Ha"
		if "`level'" == "c1_gross_yield_comp"	local title "Gross yield, plots with completed harvest, Taka/Ha"
		if "`level'" == "c1_gross_yield_harv" 	local title "Gross yield, actaully harvested all plots, Taka/Ha"
		if "`level'" == "c1_harv_value"			local title "Total value all harvest, Taka"
		if "`level'" == "c1_harv_value_int"		local title "Total value harvest intercropped, Taka"
		if "`level'" == "c1_harv_value_mono" 	local title "Total value harvest monocropped, Taka"
		if "`level'" == "c1_net_yield"			local title "Net yield, Taka/Ha"
		if "`level'" == "c1_total_earnings"		local title "Total earnings all crop sales, Taka"
		if "`level'" == "c1_total_plotsize"		local title "Total plotsize, Ha"
		if "`level'" == "c2_inp_total_spending"	local title "Total input spending, Taka"

		local noyscale ylabel(#3) ytitle("")
		*if "`title'" != "Boro" & "`title'" != "Lentil" & "`title'" != "Mustard" local noyscale ysc(off)

		if "`level'" == "c2_inp_total_spending"	local noyscale ylabel(#2) ytitle("")
		if "`level'" == "c1_gross_yield"		local noyscale ylabel(#2) ytitle("")

		local graphname	gph_`textfile'_`level'
		sort placement
		graph twoway (bar mean placement if tmt == 1, color("17 33 44")	 ) ///
			(bar mean placement if tmt == 2 , color("228 202 194") 		) ///
			(bar mean placement if tmt == 3 , color("215 107 96" ) 		 ) ///
			(bar mean placement if tmt == 4 , color("156 36  24" ) 		) ///
			(rcap conf_int_max conf_int_min placement, lc(gs) 						) ///
			(scatter  mean placement, msym(none) mlab(labelString) mlabs(medium) mlabpos(10) mlabcolor(black))	, ///
			legend(order(1 2 3 4) lab(1 "Control") lab(2 "Regular Treatment") lab(3 "Shared Demo Treatment") lab(4 "Incentives Treatment")) ///
			 plotregion(margin(b+3 t+3)) ///
			xlabel(	1 `" (N = `obs_ctrl') "' ///
					2 `" "(N = `obs_reg')" " `star_reg' " "' ///
					3 `" "(N = `obs_sdp')" " `star_sdp' " "' ///
					4 `" "(N = `obs_inc')" " `star_inc' " "', noticks labsize(medsmall)) ///
			graphregion( lcolor("182 222 255") fcolor("182 222 255")) ///
			plotregion(fcolor("247 247 247") ) ///
		   	xtitle("") ``level'_lab' `noyscale'  ///
			title("`title'") saving(`graphname'.gph, replace)
			graph export `graphname'.png, replace
		*pause
	}

	*Main outcomes
	cd "$graphs/gRaw"
	grc1leg gph_ag_outcome_log_c1_harv_value.gph 	///
			gph_ag_outcome_log_c1_net_yield.gph 	///
			gph_ag_outcome_log_c1_gross_yield.gph 	///
			gph_ag_outcome_log_c1_total_earnings.gph 	///
		,saving(gph_ag_outcome_log_MAIN.png, replace) /*ycom*/ ///
		cols(2) imargin(small) graphregion( lcolor("182 222 255") fcolor("182 222 255"))
	graph use gph_ag_outcome_log_MAIN.png
	graph display, xsize(8.5)

	cd "$graphs/"
	graph export gph_ag_outcome_log_MAIN.eps, preview(on) replace

	pause

	*Other ag outcomes
	cd "$graphs/gRaw"
	grc1leg gph_ag_outcome_log_c2_inp_total_spending.gph 	///
			gph_ag_outcome_log_c1_total_plotsize.gph 	///
			gph_ag_outcome_log_c1_IAAP_harv_value.gph 	///
			gph_ag_outcome_log_c1_commerce.gph 	///
		,saving(gph_ag_outcome_log_other.png, replace) /*ycom*/ ///
		cols(2) imargin(small) graphregion( lcolor("182 222 255") fcolor("182 222 255"))
	graph use gph_ag_outcome_log_other.png
	graph display, xsize(8.5)

		cd "$graphs/"
	graph export gph_ag_outcome_log_other.eps, preview(on) replace

	cap log close `logname'
end

cap	program drop	ieimpgraph
	program define 	ieimpgraph

	syntax ganything

	mat list e(b)

	foreach var of local varlist {

		local beta = _b[`var']

		di "`beta'"

	}

end

cap	program drop	tobeused
	program define 	tobeused

	capture file close `textfile'_`date'
	file open  `textfile'_`date' using `textfile'_`date'.txt, text write replace
	file write `textfile'_`date' ///
		"Variable" 	_tab "Tmt-Status"	_tab "mean" _tab "coeff" _tab "conf_int_min" _tab "conf_int_max" _tab "obs" _tab "star" _n
	file close `textfile'_`date'

	local REG_RESULTS ""
	foreach depvar of local depvars {

		rename lag2_`depvar' lagvar

		local regname `depvar'
			eststo `regname' : areg `depvar' tmt_reg tmt_sdp tmt_inc lagvar NoCropBoroBL NoCropBL incorrect_no_bl NoPlotDataBL NoHarvValueDataBL if t == 2, a(d_code) cl(v_code)
		local  REG_RESULTS "`REG_RESULTS' `regname'"

		foreach tmt_arm in reg sdp inc {
			scalar coeff_`tmt_arm' 		= _b[tmt_`tmt_arm']
			scalar coeff_se_`tmt_arm' 	= _se[tmt_`tmt_arm']

			sum `depvar' if e(sample) & tmt_`tmt_arm' == 1
			scalar obs_`tmt_arm'	= r(N)
		}

		sum `depvar' if e(sample) & tmt_reg == 0 & tmt_sdp == 0 & tmt_inc == 0
		scalar ctl_N		= r(N)
		scalar ctl_mean	  	= r(mean)
		scalar ctl_mean_sd 	= r(sd)

		estadd scalar ctl_mean_table	=r(mean)
		estadd scalar ctl_N_table		=r(N)
		estadd scalar ctl_mean_sd_table	=r(sd)

		sum lagvar if e(sample) & !(NoCropBoroBL == 1 | NoCropBL == 1 | incorrect_no_bl == 1 | NoPlotDataBL == 1 | NoHarvValueDataBL == 1)
		scalar BL_mean 		= r(mean)
		scalar BL_N 	= r(N)

		estadd scalar BL_mean_table	=r(mean)
		estadd scalar BL_N_table	=r(N)

		rename lagvar lag2_`depvar'

		foreach tmt_arm in reg sdp inc {
			scalar  conf_int_min_`tmt_arm'   =coeff_`tmt_arm'-(1.96*coeff_se_`tmt_arm') + ctl_mean
			scalar  conf_int_max_`tmt_arm'   =coeff_`tmt_arm'+(1.96*coeff_se_`tmt_arm') + ctl_mean

			test    tmt_`tmt_arm'

			scalar  pvalue =r(p)
			local star_`tmt_arm'
			if pvalue < 0.10 {
				local star_`tmt_arm' "*"
			}
			if pvalue < 0.05 {
				local star_`tmt_arm' "**"
			}
			if pvalue < 0.01 {
				local star_`tmt_arm' "***"
			}

			scalar tmt_mean_`tmt_arm' = ctl_mean + coeff_`tmt_arm'
		}

		file open  `textfile'_`date' using `textfile'_`date'.txt, text write append
		file write `textfile'_`date' ///
			"`regname'" _tab "Control"  _tab %9.3f (ctl_mean)      _tab  		 			_tab 		 			  	  _tab 			 				_tab %9.3f (ctl_N) 	   _tab			  	  _n ///
			"`regname'" _tab "reg"		_tab %9.3f (tmt_mean_reg)  _tab  %9.3f (coeff_reg)  _tab %9.3f (conf_int_min_reg) _tab %9.3f (conf_int_max_reg) _tab %9.3f (obs_reg)   _tab "`star_reg'"  _n ///
			"`regname'" _tab "sdp"		_tab %9.3f (tmt_mean_sdp)  _tab  %9.3f (coeff_sdp)  _tab %9.3f (conf_int_min_sdp) _tab %9.3f (conf_int_max_sdp) _tab %9.3f (obs_sdp)   _tab "`star_sdp'"  _n ///
			"`regname'" _tab "inc"		_tab %9.3f (tmt_mean_inc)  _tab  %9.3f (coeff_inc)  _tab %9.3f (conf_int_min_inc) _tab %9.3f (conf_int_max_inc) _tab %9.3f (obs_inc)   _tab "`star_inc'"  _n
		file close `textfile'_`date'

	}
	esttab `REG_RESULTS' using "$csv/outcomeVar_AllTreat_`date'.csv",      ///
		title(`tabeleFileName') stats(BL_mean_table BL_N_table ctl_mean_table ctl_N_table ctl_mean_sd_table N) mtitles nonumbers plain br  star(* 0.10 ** 0.05 *** 0.01) ///
		b(a3)  se(%9.2f) alignment(l) replace

	/***************************************

		Produce the graphs

	***************************************/

	insheet using `textfile'_`date'.txt, clear tab

	pause on

	cd "$graphs/gRaw"

	gen tmt = .
	replace tmt = 1 if tmtstatus == "Control"
	replace tmt = 2 if tmtstatus == "reg"
	replace tmt = 3 if tmtstatus == "sdp"
	replace tmt = 4 if tmtstatus == "inc"

	gen placement = tmt

	*gen 	placement = tmt if demo_code == 1
	*replace placement = tmt + 5 if demo_code == 2

	foreach percentVar in mean coeff conf_int_min conf_int_max {

		replace `percentVar' =  `percentVar' * 100 if variable == "c1_commerce"
	}

	gen 	labelString 		= ""
	gen 	labelCategory		= .
	local 	continVars_Large  	c1_harv_value c1_net_yield c1_gross_yield c1_total_earnings c2_inp_total_spending c1_IAAP_harv_value c1_net_yield_nonLabor c1_net_yield_allLabor
	local 	continVars_Small  	c1_total_plotsize
	local 	percentage_Vars   	c1_commerce

	foreach L_var of local continVars_Large {

		replace labelCategory = 1 if variable == "`L_var'"
	}
	foreach S_var of local continVars_Small {

		replace labelCategory = 2 if variable == "`S_var'"
	}
	foreach P_var of local percentage_Vars {

		replace labelCategory = 3 if variable == "`P_var'"
	}

	tempvar labelString_temp decimal_postion

	tostring mean,	gen(`labelString_temp') force
	gen 	`decimal_postion' = strpos(`labelString_temp',".")

	*For continious values without decimal point (means include all in practice)
	replace `decimal_postion' = 10 if  `decimal_postion' == 0

	replace labelString = substr(`labelString_temp',1,(`decimal_postion'-1)) 		if labelCategory == 1
	replace labelString = substr(`labelString_temp',1,4) 							if labelCategory == 2
	replace labelString = substr(`labelString_temp',1,`decimal_postion'+1) + "%"	if labelCategory == 3

	tempfile restart_loop
	save 	`restart_loop', replace

	levelsof variable
	foreach level in `r(levels)' {
		use `restart_loop', clear
		di "`level'"
		keep if variable == "`level'"

		foreach tmt in reg sdp inc {
			preserve
				keep if tmtstatus == "`tmt'"
				local obs_`tmt'  = obs[1]
				local star_`tmt' = star[1]
			restore
		}

		preserve
			keep if tmtstatus == "Control"
			local obs_ctrl  = obs[1]
		restore

		local title "ERROR"

		if "`level'" == "c1_IAAP_harv_value"	local title "Harvest value IAPP crops, Taka"
		if "`level'" == "c1_commerce"			local title "Commercialization, earnings/production %"
		if "`level'" == "c1_gross_yield"		local title "Gross yield, Taka/Ha"
		if "`level'" == "c1_gross_yield_comp"	local title "Gross yield, plots with completed harvest, Taka/Ha"
		if "`level'" == "c1_gross_yield_harv" 	local title "Gross yield, actaully harvested all plots, Taka/Ha"
		if "`level'" == "c1_harv_value"			local title "Total value all harvest, Taka"
		if "`level'" == "c1_harv_value_int"		local title "Total value harvest intercropped, Taka"
		if "`level'" == "c1_harv_value_mono" 	local title "Total value harvest monocropped, Taka"
		if "`level'" == "c1_net_yield"			local title "Net yield, Taka/Ha"
		if "`level'" == "c1_total_earnings"		local title "Total earnings all crop sales, Taka"
		if "`level'" == "c1_total_plotsize"		local title "Total plotsize, Ha"
		if "`level'" == "c2_inp_total_spending"	local title "Total input spending, Taka"

		local noyscale ylabel(#3) ytitle("")
		*if "`title'" != "Boro" & "`title'" != "Lentil" & "`title'" != "Mustard" local noyscale ysc(off)

		if "`level'" == "c2_inp_total_spending"	local noyscale ylabel(#2) ytitle("")
		if "`level'" == "c1_gross_yield"		local noyscale ylabel(#2) ytitle("")

		local graphname	gph_`textfile'_`level'
		sort placement
		graph twoway (bar mean placement if tmt == 1, color("17 33 44")	 ) ///
			(bar mean placement if tmt == 2 , color("228 202 194") 		) ///
			(bar mean placement if tmt == 3 , color("215 107 96" ) 		 ) ///
			(bar mean placement if tmt == 4 , color("156 36  24" ) 		) ///
			(rcap conf_int_max conf_int_min placement, lc(gs) 						) ///
			(scatter  mean placement, msym(none) mlab(labelString) mlabs(medium) mlabpos(10) mlabcolor(black))	, ///
			legend(order(1 2 3 4) lab(1 "Control") lab(2 "Regular Treatment") lab(3 "Shared Demo Treatment") lab(4 "Incentives Treatment")) ///
			 plotregion(margin(b+3 t+3)) ///
			xlabel(	1 `" (N = `obs_ctrl') "' ///
					2 `" "(N = `obs_reg')" " `star_reg' " "' ///
					3 `" "(N = `obs_sdp')" " `star_sdp' " "' ///
					4 `" "(N = `obs_inc')" " `star_inc' " "', noticks labsize(medsmall)) ///
			graphregion( lcolor("182 222 255") fcolor("182 222 255")) ///
			plotregion(fcolor("247 247 247") ) ///
		   	xtitle("") ``level'_lab' `noyscale'  ///
			title("`title'") saving(`graphname'.gph, replace)
			graph export `graphname'.png, replace
		*pause
	}

	*Main outcomes
	cd "$graphs/gRaw"
	grc1leg gph_ag_outcome_log_c1_harv_value.gph 	///
			gph_ag_outcome_log_c1_net_yield.gph 	///
			gph_ag_outcome_log_c1_gross_yield.gph 	///
			gph_ag_outcome_log_c1_total_earnings.gph 	///
		,saving(gph_ag_outcome_log_MAIN.png, replace) /*ycom*/ ///
		cols(2) imargin(small) graphregion( lcolor("182 222 255") fcolor("182 222 255"))
	graph use gph_ag_outcome_log_MAIN.png
	graph display, xsize(8.5)

	cd "$graphs/"
	graph export gph_ag_outcome_log_MAIN.eps, preview(on) replace

	pause

	*Other ag outcomes
	cd "$graphs/gRaw"
	grc1leg gph_ag_outcome_log_c2_inp_total_spending.gph 	///
			gph_ag_outcome_log_c1_total_plotsize.gph 	///
			gph_ag_outcome_log_c1_IAAP_harv_value.gph 	///
			gph_ag_outcome_log_c1_commerce.gph 	///
		,saving(gph_ag_outcome_log_other.png, replace) /*ycom*/ ///
		cols(2) imargin(small) graphregion( lcolor("182 222 255") fcolor("182 222 255"))
	graph use gph_ag_outcome_log_other.png
	graph display, xsize(8.5)

		cd "$graphs/"
	graph export gph_ag_outcome_log_other.eps, preview(on) replace

	cap log close `logname'
end


sh.do: explicitly check /bin/sh instead of sh.

Because our experiment involves creating a file called redo/sh, and the
redo directory (or some other version of redo's dirctory) might be on
the path, just testing 'sh' is actually wrong: we might end up with
some earlier version of redo-sh.

Instead, specifically for sh, always demand that we test /bin/sh.

exec >&2
redo-ifchange t/shelltest.od

rm -rf $1.new $1/sh
mkdir $1.new

GOOD=
WARN=

# Note: list low-functionality, maximally POSIX-like shells before more
# powerful ones.  We want weaker shells to take precedence, as long as they
# pass the tests, because weaker shells are more likely to point out when you
# use some non-portable feature.
for sh in dash /usr/xpg4/bin/sh ash posh mksh ksh ksh88 ksh93 pdksh \
		zsh bash busybox /bin/sh; do
	printf "%-30s" "Testing $sh..."
	FOUND=`which $sh 2>/dev/null` || { echo "missing"; continue; }

	# It's important for the file to actually be named 'sh'.  Some
	# shells (like bash and zsh) only go into POSIX-compatible mode if
	# they have that name.  If they're not in POSIX-compatible mode,
	# they'll fail the test.
	rm -f $1.new/sh
	ln -s $FOUND $1.new/sh

	set +e
	( cd t && ../$1.new/sh shelltest.od >shelltest.tmp 2>&1 )
	RV=$?
	set -e

	msgs=
	crash=
	while read line; do
		#echo "line: '$line'" >&2
		stripw=${line#warning: }
		stripf=${line#failed: }
		crash=$line
		[ "$line" = "$stripw" ] || msgs="$msgs W$stripw"
		[ "$line" = "$stripf" ] || msgs="$msgs F$stripf"
	done <t/shelltest.tmp
	rm -f t/shelltest.tmp
	msgs=${msgs# }
	crash=${crash##*:}
	crash=${crash# }

	case $RV in
		40) echo "ok $msgs"; [ -n "$GOOD" ] || GOOD=$FOUND ;;
		41) echo "failed    $msgs" ;;
		42) echo "warnings  $msgs"; [ -n "$WARN" ] || WARN=$FOUND ;;
		*)  echo "crash     $crash" ;;
	esac
done

rm -rf $1 $1.new $3

if [ -n "$GOOD" ]; then
	echo "Selected perfect shell: $GOOD"
	mkdir $3
	ln -s $GOOD $3/sh
elif [ -n "$WARN" ]; then
	echo "Selected mostly good shell: $WARN"
	mkdir $3
	ln -s $WARN $3/sh
else
	echo "No good shells found!  Maybe install dash, bash, or zsh."
	exit 13
fi

exec >&2
redo-ifchange t/shelltest.od

rm -rf $1.new $1/sh
mkdir $1.new

GOOD=
WARN=

# Note: list low-functionality, maximally POSIX-like shells before more
# powerful ones.  We want weaker shells to take precedence, as long as they
# pass the tests, because weaker shells are more likely to point out when you
# use some non-portable feature.
for sh in dash /usr/xpg4/bin/sh ash posh mksh ksh ksh88 ksh93 pdksh \
		zsh bash busybox sh; do
	printf "%-30s" "Testing $sh..."
	FOUND=`which $sh 2>/dev/null` || { echo "missing"; continue; }

	# It's important for the file to actually be named 'sh'.  Some
	# shells (like bash and zsh) only go into POSIX-compatible mode if
	# they have that name.  If they're not in POSIX-compatible mode,
	# they'll fail the test.
	rm -f $1.new/sh
	ln -s $FOUND $1.new/sh

	set +e
	( cd t && ../$1.new/sh shelltest.od >shelltest.tmp 2>&1 )
	RV=$?
	set -e

	msgs=
	crash=
	while read line; do
		#echo "line: '$line'" >&2
		stripw=${line#warning: }
		stripf=${line#failed: }
		crash=$line
		[ "$line" = "$stripw" ] || msgs="$msgs W$stripw"
		[ "$line" = "$stripf" ] || msgs="$msgs F$stripf"
	done <t/shelltest.tmp
	rm -f t/shelltest.tmp
	msgs=${msgs# }
	crash=${crash##*:}
	crash=${crash# }

	case $RV in
		40) echo "ok $msgs"; [ -n "$GOOD" ] || GOOD=$FOUND ;;
		41) echo "failed    $msgs" ;;
		42) echo "warnings  $msgs"; [ -n "$WARN" ] || WARN=$FOUND ;;
		*)  echo "crash     $crash" ;;
	esac
done

rm -rf $1 $1.new $3

if [ -n "$GOOD" ]; then
	echo "Selected perfect shell: $GOOD"
	mkdir $3
	ln -s $GOOD $3/sh
elif [ -n "$WARN" ]; then
	echo "Selected mostly good shell: $WARN"
	mkdir $3
	ln -s $WARN $3/sh
else
	echo "No good shells found!  Maybe install dash, bash, or zsh."
	exit 13
fi


* upload html only when sound files are already there

for f in `ls -1 *.input.* | sed 's/\(.*\)\.input.*/\1/'`; do
    echo $f.oga.upload
    echo $f.mp3.upload
    echo $f.html.upload
done | xargs redo-ifchange

redo-ifchange index.html.upload feed.atom.upload

for f in `ls -1 *.input.* | sed 's/\(.*\)\.input.*/\1/'`; do
    echo $f.html.upload
    echo $f.oga.upload
    echo $f.mp3.upload
done | xargs redo-ifchange

#redo-ifchange index.html.upload