*! Version 5.4 28July2023
*! Jean-Benoit Hardouin, Myriam Blanchin
************************************************************************************************************
* Stata program : pcm
* Estimate the parameters of the Partial Credit Model
* Version 1 : December 17, 2007 [Jean-Benoit Hardouin]
* Version 2 : July 15, 2011 [Jean-Benoit Hardouin]
* Version 2.1 : October 18th, 2011 [Jean-Benoit Hardouin] : -fixedvar- option, new presentation
* Version 2.2 : October 23rd, 2013 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 2.3 : April 10th, 2014 [Jean-Benoit Hardouin] : correction of -fixedvar- option
* Version 3 : July 6th, 2019 [Jean-Benoit Hardouin] : New version using gsem
* Version 3.1 : July 9th, 2019 [Jean-Benoit Hardouin] : Small corrections
* Version 3.2 : July 17th, 2019 [Jean-Benoit Hardouin] : Small corrections
* Version 3.3 : July 25th, 2019 [Jean-Benoit Hardouin] : -pce- option
* Version 3.4 : August 23th, 2019 [Jean-Benoit Hardouin] : Correction of a bug
* Version 3.5 : August 29th, 2019 [Jean-Benoit Hardouin] : Correction of a bug with modamax``i''
* Version 4: September 13th, 2019 [Myriam Blanchin]: addition of longitudinal pcm
* Version 4.1: September 15th, 2019 [Jean-Benoit Hardouin]: correction of a small bug in the outputs
* Version 4.2: September 27th, 2019 [Jean-Benoit Hardouin] : EQUATING
* Version 4.3: November 8th, 2019 [Jean-Benoit Hardouin] : add a constant when difficulty parameters are fixed
* Version 5: August 2nd, 2022 [Jean-Benoit Hardouin] : New MAP graph, corrected estimation of the latent trait
* Version 5.1: July 8th, 2023 [Jean-Benoit Hardouin] : Correction of the MAP graph (histogram) and residuals graphs
* Version 5.2: July 16th, 2023 [Jean-Benoit Hardouin] : Add of new graphs for Equating
* Version 5.3: July 21th, 2023 [Jean-Benoit Hardouin] : Improvements for the docx option
* Version 5.4: July 28th, 2023 [Jean-Benoit Hardouin] : Improvements for graphs et corrections of bugs
*
*
* Jean-benoit Hardouin, Myriam Blanchin - University of Nantes - France
* INSERM UMR 1246-SPHERE "Methods in Patient Centered Outcomes and Health Research", Nantes University, University of Tours
* jean-benoit.hardouin@univ-nantes.fr, myriam.blanchin@univ-nantes.fr
*
* News about this program : http://www.anaqol.org
*
* Copyright 2007, 2011, 2013, 2014, 2019, 2022, 2023 Jean-Benoit Hardouin, Myriam Blanchin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
************************************************************************************************************/


program define pcm, rclass
syntax varlist(min=2 numeric) [iweight] [if] [in] [, CONTinuous(varlist) CATegorical(varlist) ITerate(int 100) TOLerance(real 0.01) model DIFFiculties(name) VARiance(real -1) rsm Graphs noGRAPHItems noCORRected filesave dirsave(string) docx(string) extension(string) alpha(real 0.01)  PCE WMLiterate(int 1) GENLT(string) GENINF(string) REPlace postpce visit(varname) id(varname) eqset1(varlist) eqset2(varlist) eqset1name(string) eqset2name(string) EQGraph eqaddset1(real 0) eqaddset2(real 0) eqmultset1(real 1) eqmultset2(real 1) eqwithci eqgenscore(string)  DIMname(string) minsize(int 30) vardif(varname) itemsdif(varlist) noRESiduals]

version 14
preserve
tokenize `varlist'
local nbitems : word count `varlist'
marksample touse ,novarlist
*preserve

/*************************************************************************************************************
QUELQUES TESTS
*************************************************************************************************************/

if `variance'!=-1&`variance'<=0 {
	di in red "The -variance- option cannot be negative"
	exit 198
}
if `variance'!=-1&"`visit'"!="" {
	di in red "The -variance- and -visit- options cannot be used simultaneously."*
	exit 198
}
if "`genlt'"!=""|"`geninf'"!="" {
    capture confirm new variable `genlt' `genlt'_se `geninf' `genlt'_corr `genlt'_opt `genlt'_opt_se
	if _rc!=0&"`replace'"=="" {
	    di in red "The variables `genlt', `genlt'_se, `genlt'_corr, `genlt'_opt, `genlt'_opt_se and/or `geninf' alreday exist. Please modify the -genlt- and/or -geninf- option"
		exit 198
	}
	if _rc!=0&"`replace'"!="" {
	    qui capture drop `genlt'
		qui capture drop `genlt'_se
		qui capture drop `geninf'
		qui capture drop `genlt'_corr
		qui capture drop `genlt'_opt
		qui capture drop `genlt'_opt_se
	}
}
if ("`eqset1'"!=""&"`eqset2'"=="")|("`eqset1'"==""&"`eqset2'"!="") {
    di in red "The two options -eqset1- and -eqset2- must be used simultaneously"
	exit 198
}
if ("`eqset1'"!=""&"`graphs'"!="") {
    di in red "The two options -eqset1- and -graph- cannot be used simultaneously"
	exit 198
}
if "`corrected'"!="" {
	local xtitle "Latent trait"
}
else {
	local xtitle "Corrected latent trait"
}



/*************************************************************************************************************
GESTION DES VARIABLES CONTINUES ET CATEGORIELLES
*************************************************************************************************************/
if "`visit'"!=""{
	if "`id'"==""{
		di in red "Option -visit- must be combined with option -id-. Please fill in the -id- option"
		exit 198
	}
	qui levelsof `visit'
	local levelsofv `r(levels)'
	local nbvisits=r(r)
	local timemin: word 1 of `levelsofv'
	local timemax: word `nbvisits' of `levelsofv'
	if `timemax'>5{
		di as error "You must use a discrete time variable (-visit- option) with less than 5 measurement occasions"
		error 198
	}
	if `timemin'!=1{
		di as error "You must use a -visit- variable coded at 1 for the first visit"
		error 198
	}
	qui reshape wide `varlist', i(`id') j(`visit')
	local multivisit=1
}
else {
	local timemax=1
	foreach i in `varlist' {
	   *rename `i' `i'1
	}
	local multivisit
}
qui count if `touse'
local nbobs=r(N)

local timelist
forvalues t=1/`timemax'{
	local timelist `timelist' T`t'
}

local modcont
local premodcont
local nbpar=0
local nbcont=0
local nbcat=0
if "`continuous'"!="" {
	tokenize `continuous'
	local nbcont : word count `continuous'
	local continuous
	forvalues i=1/`nbcont' {
		local cont`i' ``i''
		local continuous `continuous' ``i''
		local modcont `modcont' ``i''
	    local ++nbpar
	}
	local premodcont (`modcont'->T1)
	local modcont (`modcont'->`timelist')
}

local modcat
local premodcat
if "`categorical'"!="" {
	tokenize `categorical'
	local nbcat : word count `categorical'
	local categorical
	forvalues i=1/`nbcat' {
		local cat`i' ``i''
		local categorical `categorical' ``i''
		local modcat `modcat' i.``i''
		qui levelsof ``i''
		local levelsof``i'' `r(levels)'
		local nbpar=`nbpar'+`r(r)'-1
	    *di "categorical : ``i'' levels : `levelsof``i'''"
	}
	local premodcat (`modcat'->T1)
	local modcat (`modcat'->`timelist')
}


if "`dirsave'"=="" {
   local dirsave `c(pwd)'
}

/*************************************************************************************************************
GESTION DES ITEMS ET TESTS
*************************************************************************************************************/

tokenize `varlist'
local modamax=1
local modamin=0
local pbmin
local nbdiff=0
local scoremax=0
forvalues i=1/`nbitems' {
    local name``i'': variable label ``i''
	if "`name``i'''"=="" {
		local name``i'' ``i''
	}
	local modamax`i'=1
	local modamax``i''=1
	if `timemax'>1 {
		forvalues t=1/`timemax'{
			 *qui replace ``i'`t''=``i'`t''-`min'
			 qui su ``i''`t' if `touse'
			 if `r(min)'!=`modamin' {
				 local modamin=r(min)
				 local pbmin `pbmin' ``i'`t''
			 }
			 if `r(max)'>`modamax' {
				 local modamax=r(max)
			 }
			 if `r(max)'>`modamax`i'' {
				local modamax`i'=r(max)
			}
		}
	}
	else {
		*di "i: `i' ``i''"
		qui su ``i'' if `touse'
		if `r(min)'!=`modamin' {
		    local modamin=r(min)
			local pbmin `pbmin' ``i''
		}
		if `r(max)'>`modamax' {
			local modamax=r(max)
		}
		if `r(max)'>`modamax`i'' {
			local modamax`i'=r(max)
			local modamax``i''=r(max)
		}
	}
	*di "local scoremax=`scoremax'+`modamax`i''"
	local scoremax=`scoremax'+`modamax`i''
	if "`rsm'"=="" {
		local nbdiff=`nbdiff'+`modamax`i''
	}
}
if "`rsm'"!="" {
   local nbdiff=`nbitems'+`modamax'-1
}
if `modamin'!=0 {
   di as error "The minimal answer category of each item must be coded by 0. This is not the case for the following items: `pbmin' (`modamin') "
   error 198
}
qui count if `touse'
local nbind=r(N)
*set trace on
local code
local precode
if `timemax'>1 {
	forvalues k=1/`modamax' {
	   forvalues t=1/`timemax'{
			local code`k'
		   forvalues i=1/`nbitems' {
			   if `k'<=`modamax`i'' {
				  local code`k' `code`k'' `k'.``i''`t'
			   }
		   }
		   local code`k' (`code`k''<-T`t'@`k')
		   if `t'==1{
				local precode `precode' `code`k''
		   }
		   local code `code' `code`k''
		}
	}
}
else {
	forvalues k=1/`modamax' {
		local code`k'
		forvalues i=1/`nbitems' {
			if `k'<=`modamax`i'' {
				local code`k' `code`k'' `k'.``i''
			}
		}
		local code`k' (`code`k''<-T1@`k')
		local precode `precode' `code`k''
		local code `code' `code`k''
	}
}

/*************************************************************************************************************
OPTION PCE
*************************************************************************************************************/

if "`pce'"!=""&"`difficulties'"==""&"`visit'"=="" {
    tempname sedelta b
	qui raschpce `varlist' if `touse'
	local ll=r(ll)
	matrix `sedelta'=r(sedelta)
	matrix `sedelta'=`sedelta''
	matrix `b'=r(b)
	*matrix `b'=`b''
	local difficulties `b'
	*matrix list `b'
	matrix loulou=`b'
	return matrix diff_parm=`b'
	`qui' pcm `varlist' if `touse', diff(loulou)  geninf(TInf_0) genlt(lt_0) /*postpce*/
	*exit
}


/*************************************************************************************************************
RECUPERATION DES PARAMETRES DE DIFFICULTES ET DEFINITION DES CONTRAINTES
*************************************************************************************************************/
if "`difficulties'"!=""&"`rsm'"!="" {
   di as error "You can not defined in the same time the difficulties and the rsm options"
   error 198
}
local t=1
local constraints
local codemean
local codevar
local codecov
forvalues j=2/`timemax'{
	forvalues i=1/`nbitems' {
		forvalues k=1/`modamax`i'' {
			qui constraint `t' [`k'.``i''`j']_cons=[`k'.``i''`multivisit']_cons
			local constraints `constraints' `t'
			local ++t

		}
	}
	if "`continuous'"=="" &  "`categorical'"==""{
		local codemean `codemean' T`j'@m`j'
		local codevar `codevar' T`j'@v`j'
		forvalues l=1/`=`j'-1'{
			local codecov `codecov' T`l'*T`j'@cov`l'`j'
		}
	}
	else{
		local codevar `codevar' e.T`j'@v`j'
		forvalues l=1/`=`j'-1'{
			local codecov `codecov' e.T`l'*e.T`j'@cov`l'`j'
		}
	}
}
if `timemax'>1{
	if "`continuous'"=="" &  "`categorical'"==""{
		local codelg means(T1@0 `codemean') var(T1@v1 `codevar') cov(`codecov')
	}
	else{
		local codelg var(e.T1@v1 `codevar') cov(`codecov')
	}
}
else {
    local constrvar
    if `variance'>0 {
		if "`continuous'"=="" &  "`categorical'"==""{
			local constrvar var(T1@`variance')
		}
		else{
			*local constrvar var(e.T1@`variance')
		}
	}
}

local fixedmean
if "`difficulties'"!="" {
    tempname beta
	matrix `beta'=J(`nbitems',`modamax',.)
	matrix list `difficulties'
	forvalues i=1/`nbitems' {
		forvalues k=1/`modamax`i'' {
			if `difficulties'[`i',`k']==. {
				 di as error "The kth difficulty parameter of the item ``i'' is not correctly defined in the difficulties matrix"
				 error 198
			}
			else {
				if `k'==1 {
					matrix `beta'[`i',1]=-`difficulties'[`i',1]
  			    }
				else {
				    matrix `beta'[`i',`k']=`beta'[`i',`=`k'-1']-`difficulties'[`i',`k']
				}
				qui constraint `t' [`k'.``i''`multivisit']_cons=`beta'[`i',`k']
				local constraints `constraints' `t'
				local ++t
			}
		}
	}
	if "`continuous'"=="" &  "`categorical'"=="" {
		local fixedmean mean(T1)
	}
	else{
		local fixedmean
	}
}



/*************************************************************************************************************
DEFINITION DES CONTRAINTES POUR UN RSM
*************************************************************************************************************/
if "`rsm'"!="" {
   local constraints
   forvalues k=2/`modamax' {
       forvalues i=2/`nbitems' {
	       qui constraint `t'   [`=`k'-1'.``i''`multivisit']_cons-[`k'.``i''`multivisit']_cons+[1.``i''`multivisit']_cons=[`=`k'-1'.`1'1]_cons-[`k'.`1'1]_cons+[1.`1'1]_cons
		   local constraints `constraints' `t'
		   local ++t
	   }
   }
}

/*************************************************************************************************************
MODELE
*************************************************************************************************************/


discard
*di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' "
if "`model'"!="" {
    local qui
}
else {
	local qui qui
}
if `timemax'==1{
   *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'"
   `qui' gsem `code' `modcont' `modcat' if `touse' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
   *qui gen un=1
   *`qui' gsem `code' (i.group un->T) ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `constrvar' `fixedmean'
}
else{
    *di "`qui' gsem `precode' `premodcont' `premodcat',iterate(`iterate') tol(`tolerance') "
    `qui' gsem `precode' `premodcont' `premodcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints')
     matrix esti_B = e(b)
    *di "`qui' gsem `code' `modcont' `modcat' ,iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)"
    `qui' gsem `code' `modcont' `modcat' if `touse',iterate(`iterate') tol(`tolerance') constraint(`constraints') latent(`timelist') `codelg' from(esti_B,skip)
}
local ll=e(ll)

*set trace on
tempvar latent score group selatent latent2 miss
tempname groups
*capture qui predict mu, mu
*su mu
qui predict `latent'* if `touse',latent se(`selatent'*)
*di "latent=`latent' "
*su
*set trace on

if "`genlt'"!="" {
	if `timemax'==1 {
		qui gen `genlt'=`latent'1 if `touse'
		qui gen `genlt'_se=`selatent'1 if `touse'
	}
	forvalues t=2/`timemax' {
		qui gen `genlt'`t'=`latent'`t' if `touse'
		qui gen `genlt'`t'_se=`selatent'`t' if `touse'
	}
}

set seed 123456
if `timemax'>1 {
	forvalues t=1/`timemax'{
		qui gen `latent2'`t'=`latent'`t'+invnorm(uniform())*`selatent'`t' if `touse'
		local listit
		forvalues i=1/`nbitems' {
			local listit `listit' ``i''`t'
		}
		qui genscore `listit' if `touse',score(`score'`t')
		qui gengroup `latent'`t' if `touse',newvariable(`group'`t') continuous minsize(`minsize')
	}
}
else {
	qui gen `latent2'=`latent'1+invnorm(uniform())*`selatent'1 if `touse'
	local listit
	forvalues i=1/`nbitems' {
		local listit `listit' ``i''
	}
	qui genscore `listit' if `touse',score(`score')
	qui gengroup `latent'1 if `touse',newvariable(`group') continuous minsize(`minsize')
}
forvalues s=0/`scoremax' {
    qui count if `score'==`s'&`touse'
	local effscore`s'=r(N)
}


/*time 1 only*/
qui levelsof `group'`multivisit' if `touse'
local nbgroups=r(r)
matrix `groups'=J(`nbgroups',`=`nbitems'+10',.)
forvalues g=1/`nbgroups' {
	matrix `groups'[`g',`=`nbitems'+3']=0
	qui count if `group'`multivisit'==`g'&`touse'
	local effgroup`g'=r(N)
	forvalues i=1/`nbitems' {
			qui count if ``i''`multivisit'!=.&`group'`multivisit'==`g'&`touse'
			local n=r(N)
			if `n'>0 {
				qui su ``i''`multivisit' if `group'`multivisit'==`g'&`touse'
				matrix `groups'[`g',`i']=r(mean)
				matrix `groups'[`g',`=`nbitems'+3']=`groups'[`g',`=`nbitems'+3']+`r(mean)'
			}
			else {
				matrix `groups'[`g',`i']=.
				matrix `groups'[`g',`=`nbitems'+3']=.
			}
	}
	qui su `latent'1 if `group'`multivisit'==`g'&`touse'
	matrix `groups'[`g',`=`nbitems'+1']=r(mean)
	matrix `groups'[`g',`=`nbitems'+7']=r(min)
	matrix `groups'[`g',`=`nbitems'+8']=r(max)
	qui count if `group'`multivisit'==`g'&`touse'
	matrix `groups'[`g',`=`nbitems'+2']=r(N)
	qui su `score' if `group'`multivisit'==`g'&`score'!=.&`touse'
	matrix `groups'[`g',`=`nbitems'+4']=r(min)
	matrix `groups'[`g',`=`nbitems'+5']=r(max)
}

/*number of non-missing on all time points*/
egen `miss'=rowmiss(`score'*) if `touse'
qui count if `miss'==0&`touse'
local nbobsssmd=r(N)
drop `miss'

di
di as text "Number of individuals:" %6.0f as result `nbobs'
di as text "Number of individuals with a complete answer pattern:" %6.0f as result `nbobsssmd'
di as text "Number of items:" %6.0f as result `nbitems'

di as text "Marginal log-likelihood:" %12.4f as result `ll'
di
return scalar ll=`ll'



*set trace on
/*************************************************************************************************************
RECUPERATION DES ESTIMATIONS DES PARAMETRES DE DIFFICULTE
*************************************************************************************************************/

tempname diff diffmat vardiff diffmat2
*set trace on
qui matrix `diffmat'=J(`nbitems',`modamax',.)
qui matrix `diffmat2'=J(`nbitems',`modamax',.)
qui matrix `diff'=J(`nbdiff',6,.)
local rn
*qui matrix `vardiff'=J(`nbdiff',`nbdiff',.)
*matrix list `diff'
*set trace on
local t=1
forvalues i=1/`nbitems' {
    qui matrix `diffmat'[`i',1]=-_b[1.``i''`multivisit':_cons]
    qui matrix `diffmat2'[`i',1]=-_b[1.``i''`multivisit':_cons]
	qui lincom -_b[1.``i''`multivisit':_cons]
    qui matrix `diff'[`t',1]=`r(estimate)'
    qui matrix `diff'[`t',2]=`r(se)'
    qui matrix `diff'[`t',3]=`r(z)'
    qui matrix `diff'[`t',4]=`r(p)'
    qui matrix `diff'[`t',5]=`r(lb)'
    qui matrix `diff'[`t',6]=`r(ub)'
	local rn `rn' 1.``i''`multivisit'
	local ++t
	local sum _b[1.``i''`multivisit':_cons]
	if "`rsm'"=="" {
	    forvalues k=2/`modamax`i'' {
			local sum "_b[`k'.``i''`multivisit':_cons]-(`sum')"
			*di "``i''`multivisit' `k' `sum'"
			local sum2 "_b[`=`k'-1'.``i''`multivisit':_cons]-_b[`k'.``i''`multivisit':_cons]"
			qui lincom (`sum2')
			*set trace on
			qui matrix `diffmat'[`i',`k']=`r(estimate)'
			qui matrix `diffmat2'[`i',`k']=`diffmat2'[`i',`=`k'-1']+`diffmat'[`i',`k']
			qui matrix `diff'[`t',1]=`r(estimate)'
			qui matrix `diff'[`t',2]=`r(se)'
			qui matrix `diff'[`t',3]=`r(z)'
			qui matrix `diff'[`t',4]=`r(p)'
			qui matrix `diff'[`t',5]=`r(lb)'
			qui matrix `diff'[`t',6]=`r(ub)'
			*qui matrix `vardiff'[`t',`t']=`r(se)'^2
			*set trace off
			local rn `rn' `k'.``i''`multivisit'
			local ++t
		}
    }
}
if "`rsm'"!="" {
    forvalues k=2/`modamax' {
		qui lincom _b[`=`k'-1'.`1'`multivisit':_cons]-_b[`k'.`1'`multivisit':_cons]+_b[1.`1'`multivisit':_cons] /*``i'' instead of `i'?*/
		qui matrix `diff'[`t',1]=`r(estimate)'
		qui matrix `diff'[`t',2]=`r(se)'
		qui matrix `diff'[`t',3]=`r(z)'
		qui matrix `diff'[`t',4]=`r(p)'
		qui matrix `diff'[`t',5]=`r(lb)'
		qui matrix `diff'[`t',6]=`r(ub)'
		forvalues i=1/`nbitems' {
		    qui matrix `diffmat'[`i',`k']=`diff'[`t',1]+`diffmat'[`i',1]
		    qui matrix `diffmat2'[`i',`k']=`diffmat'[`i',`k']+`diffmat2'[`i',`=`k'-1']
		}
		local rn `rn' tau`k'
		local ++t
	}
}
local cn Estimate S.e. z p "Lower bound" "Upper Bound"
matrix colnames `diff'=`cn'
*di "matrix rownames `diff'=`rn'"
matrix rownames `diff'=`rn'
*matrix list `diff'
*matrix list `diffmat'
*matrix list `diffmat2'
*matrix list `vardiff'

/*************************************************************************************************************
RECUPERATION DES ESTIMATIONS DES PARAMETRES POUR LES COVARIABLES, MOYENNES ET VARIANCES
*************************************************************************************************************/
tempname covariates
local nbcov=0
forvalues j=2/`timemax'{
	local nbcov=`nbcov'+`j'-1
}
qui matrix `covariates'=J(`=`nbpar'+`timemax'+2*`nbcov'',6,.)

*set trace on
local t=1


forvalues j=1/`=`timemax'-1'{
	forvalues k=`=`j'+1'/`timemax'{
		if "`categorical'"=="" & "`continuous'"=="" {
			if `j'==1{
				qui lincom [/]mean(T`k')
			}
			else{
				qui lincom [/]mean(T`k')-[/]mean(T`j')
			}
			qui matrix `covariates'[`t',1]=`r(estimate)'
			qui matrix `covariates'[`t',2]=`r(se)'
			qui matrix `covariates'[`t',3]=`r(z)'
			qui matrix `covariates'[`t',4]=`r(p)'
			qui matrix `covariates'[`t',5]=`r(lb)'
			qui matrix `covariates'[`t',6]=`r(ub)'
			local ++t
		}
		else{
			if "`categorical'"!=""{
				local first=0
				foreach l in `levelsof`cat1'' {
					if `first'==0 {
						local ++first
					}
					else{
						if `first'==1 {
							qui lincom [T`k']`l'.`cat1'-[T`j']`l'.`cat1'
							qui matrix `covariates'[`t',1]=`r(estimate)'
							qui matrix `covariates'[`t',2]=`r(se)'
							qui matrix `covariates'[`t',3]=`r(z)'
							qui matrix `covariates'[`t',4]=`r(p)'
							qui matrix `covariates'[`t',5]=`r(lb)'
							qui matrix `covariates'[`t',6]=`r(ub)'
							local ++t
							local ++first
						}
					}
				}
			}
			else{
				qui lincom [T`k']`cont1'-[T`j']`cont1'
				qui matrix `covariates'[`t',1]=`r(estimate)'
				qui matrix `covariates'[`t',2]=`r(se)'
				qui matrix `covariates'[`t',3]=`r(z)'
				qui matrix `covariates'[`t',4]=`r(p)'
				qui matrix `covariates'[`t',5]=`r(lb)'
				qui matrix `covariates'[`t',6]=`r(ub)'
				local ++t
			}
		}
	}
}

forvalues j=1/`timemax'{
	if "`continuous'"!=""|"`categorical'"!="" {
		qui lincom _b[/var(e.T`j')]
	}
	else {
		qui lincom _b[/var(T`j')]
	}
	qui matrix `covariates'[`t',1]=`r(estimate)'
	qui matrix `covariates'[`t',2]=`r(se)'
	qui matrix `covariates'[`t',3]=`r(z)'
	qui matrix `covariates'[`t',4]=`r(p)'
	qui matrix `covariates'[`t',5]=`r(lb)'
	qui matrix `covariates'[`t',6]=`r(ub)'
	local ++t
}
forvalues j=1/`=`timemax'-1'{
	if "`continuous'"!=""|"`categorical'"!="" {
		forvalues k=`=`j'+1'/`timemax'{
			qui lincom _b[/cov(e.T`j',e.T`k')]
			qui matrix `covariates'[`t',1]=`r(estimate)'
			qui matrix `covariates'[`t',2]=`r(se)'
			qui matrix `covariates'[`t',3]=`r(z)'
			qui matrix `covariates'[`t',4]=`r(p)'
			qui matrix `covariates'[`t',5]=`r(lb)'
			qui matrix `covariates'[`t',6]=`r(ub)'
			local ++t
		}
	}
	else{
		forvalues k=`=`j'+1'/`timemax'{
			qui lincom _b[/cov(T`j',T`k')]
			qui matrix `covariates'[`t',1]=`r(estimate)'
			qui matrix `covariates'[`t',2]=`r(se)'
			qui matrix `covariates'[`t',3]=`r(z)'
			qui matrix `covariates'[`t',4]=`r(p)'
			qui matrix `covariates'[`t',5]=`r(lb)'
			qui matrix `covariates'[`t',6]=`r(ub)'
			local ++t
		}
	}
}
forvalues i=1/ `nbcont' {
   qui lincom `cont`i''
   qui matrix `covariates'[`t',1]=`r(estimate)'
   qui matrix `covariates'[`t',2]=`r(se)'
   qui matrix `covariates'[`t',3]=`r(z)'
   qui matrix `covariates'[`t',4]=`r(p)'
   qui matrix `covariates'[`t',5]=`r(lb)'
   qui matrix `covariates'[`t',6]=`r(ub)'
   local ++t
}
forvalues i=1/ `nbcat' {
   local first=0
   foreach j in `levelsof`cat`i''' {
	   if `first'==0 {
	      local ++first
	   }
	   else {
		   qui	lincom `j'.`cat`i''
		   qui matrix `covariates'[`t',1]=`r(estimate)'
		   qui matrix `covariates'[`t',2]=`r(se)'
		   qui matrix `covariates'[`t',3]=`r(z)'
		   qui matrix `covariates'[`t',4]=`r(p)'
		   qui matrix `covariates'[`t',5]=`r(lb)'
		   qui matrix `covariates'[`t',6]=`r(ub)'
		   local ++t
	   }
   }
}
*matrix list `covariates'


/*************************************************************************************************************
OUTPUTS
*************************************************************************************************************/

if "`postpce'"=="" {
	local t=1
	local diffname
	*set trace on
	di "{hline 83}"
	di  as text _col(70) "<--95% IC -->"
	di   _col(70) "Lower" _col(78) "Upper"
	di "Items" _col(22) "Threshold" _col(35) "Estimate" _col(47) "s.e." _col(59) "z" _col(66) "p" _col(69) " Bound" _col(78) "Bound"
	di "{hline 83}"
	*set trace on
	forvalues i=1/`nbitems' {
	   *local l=1
	   forvalues j=1/`modamax`i'' {
		  if "`rsm'"==""|`j'==1 {
			  if `j'==1 {
				 di as text abbrev("`name``i'''",20) _c
			  }
			  di as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %6.2f `diff'[`t',3] _col(62) %5.3f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6]
			  local ++t
			  *local ++l
			  local diffname `diffname' `j'.``i''
		  }
	   }
	}
	if "`rsm'"!="" {
		forvalues k=2/`modamax' {
			di as text "tau`k'"  as result _col(38) %5.2f `diff'[`t',1]  _col(46) %5.2f `diff'[`t',2] _col(54) %6.2f `diff'[`t',3] _col(62) %5.3f `diff'[`t',4] _col(70) %5.2f `diff'[`t',5] _col(78) %5.2f `diff'[`t',6]
			local diffname `diffname' tau`k'
			local ++t
		}
	}
	di as text "{hline 83}"
	local t=1
	local listmoy
	local listvar
	local listcov
	forvalues j=1/`timemax'{
		local listvar `listvar' Variance_T`j'
		forvalues k=`=`j'+1'/`timemax'{
			local listcov `listcov' Cov_T`j'_T`k'
		}
		forvalues k=`=`j'+1'/`timemax'{
			local listmoy `listmoy' Mean_diff_T`j'_T`k'
		}
	}
	local n: word count `listmoy' `listvar' `listcov'
	forvalues i=1/`n' {
		local v: word `i' of `listmoy' `listvar' `listcov'
		di as text _col(1) %5.2f "`v'"  as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6]
		local ++t
	}
	local n: word count `continuous'
	forvalues i=1/`n' {
		local v: word `i' of  `continuous'
		local v2 :  variable label `v'
		if "`v2'"=="" {
		   local v2 `v'
		}
		di as text _col(1) %5.2f  abbrev("`v2'",20)  as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6]
		local ++t
	}

	local rn Variance `continuous'

	local n: word count  `categorical'
	*di "local n: word count of  `categorical' "
	*di "n=`n'"
	local catname
	forvalues i=1/`n' {
		local v: word `i' of `categorical'
		local v2 : variable label `v'
		if "`v2'"=="" {
		   local v2 `v'
		}
		local first=1
		local saute=1
		foreach j in `levelsof`cat`i''' {
			if `saute'==0 {
				if `first'==1 {
					di as text _col(1) abbrev("`v2'",20) _c
				}
				di  as text _col(30) %5.2f "`j'" as result _col(38) %5.2f `covariates'[`t',1]  _col(46) %5.2f `covariates'[`t',2] _col(54) %6.2f `covariates'[`t',3] _col(62) %5.3f `covariates'[`t',4] _col(70) %5.2f `covariates'[`t',5] _col(78) %5.2f `covariates'[`t',6]
				local ++first
				local rn `rn' `j'.`n'
				local ++t
				local catname `catname' `j'.`v'
			}
			else {
			   local saute=0
			}
		}
		*local ++t
	}
	di as text "{hline 83}"
	if "`visit'"==""{
		di
		qui su `latent'1 if `touse'
		*qui local PSI=1-(`r(sd)')^2/((`covariates'[1,1])+(`r(sd)')^2)
		*di as text "Variance of the estimated latent variable: " as result %4.2f `=(`r(sd)')^2'
        tempvar se2latent
		qui gen `se2latent'=(`selatent'1)^2 if `touse'
		qui su `se2latent' if `touse'
		local resvar=r(mean)
		di as text "Mean squared std error of the latent variable: " as result %4.2f `resvar'
		di as text "Global variance of the latent variable: " as result %4.2f `=((`covariates'[1,1])+(`resvar'))'
		local PSI=(`covariates'[1,1])/((`covariates'[1,1])+(`resvar'))
		di as text "PSI: " as result %4.2f `PSI' _c
		if "`continuous'"!=""|"`categorical'"!="" {
		    di as text " (without adjustment on covariates)"
	    }
		else {
		    di
		}
		di
		return scalar PSI=`PSI'

	}



	matrix colnames `covariates'=`cn'
	matrix rownames `covariates'=`rn'
}


/*************************************************************************************************************
ESTIMATION OF THE CORRECTED VALUES OF THE LT ESTIMATORS (values of lt that explained the best the score)
**************************************************************************************************************/
*set trace on
tempfile savefile
qui save `savefile'

qui drop _all

qui set obs 2000
qui gen u=(_n-1000)/200*`=2*sqrt(`covariates'[1,1])'
qui gen Tcum=0
qui gen TInf=0
forvalues i=1/`nbitems' {
		local d=1
		qui gen cum``i''=0
		if "`rsm'"=="" {
			local mm=`modamax`i''
		}
		else {
			local mm `modamax'
		}
		forvalues k=1/`mm' {
			local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
		}
		qui gen c0_``i''=1/(`d')
		forvalues k=1/`mm' {
			qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
			qui replace cum``i''=cum``i''+c`k'_``i''*`k'
		}
		qui gen Inf``i''=0
		forvalues k=1/`mm' {
			qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
		}
		*set trace on
		qui replace Tcum=Tcum+cum``i''
		qui replace TInf=TInf+Inf``i''
	    local scoremax=0
		forvalues l=1/`nbitems' {
		      local scoremax=`scoremax'+`modamax`l''
	    }
		qui gen ecart=.
		local listlt
		forvalues l=0/`scoremax' {
		    if `l'==0 {
			   local j=0.25
			}
			else if `l'==`scoremax' {
			   local j=`scoremax'-0.25
			}
			else {
			   local j=`l'
			}
		    qui replace ecart=abs(Tcum-`j')
		    qui su ecart
			local tmp=r(min)
			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
			local estlt`l'=`r(mean)'
			local listlt `listlt' `estlt`l''
			*qui su TInf if round(ecart, 0.01)==round(`tmp',0.01)
			*local setlt`l'=sqrt(1/`r(mean)')
		}
		qui drop ecart
}
qui use `savefile', clear


*set trace on
/*************************************************************************************************************
FIT TESTS
*************************************************************************************************************/

/*Quelques explications
latent : estimation EAP du trait latent
latent2 : estimation Plausible Value à partir de l'estimation EAP
corrlatent : estimation corrigée cherchant la meilleur valeur du trait latent qui explique le score, interpolation à partir de l'EAP pour les individus avec des données manquantes
*/


if "`visit'"==""{
	tempvar corrlatent corrlatenttmp
	qui gen `corrlatenttmp'=.
	forvalues s=0/`scoremax' {
	    qui replace `corrlatenttmp'=`estlt`s'' if `score'==`s'
	}
	qui ipolate `corrlatenttmp' `latent'1 , generate(`corrlatent') epolate
	*list `corrlatenttmp' `latent2' `corrlatent'
	qui replace `corrlatent'=`corrlatenttmp' if `corrlatenttmp'!=.
	qui replace `corrlatent'=`latent' if `corrlatenttmp'==.
	*su  `corrlatenttmp' `latent2' `corrlatent'
    *twoway (scatter `corrlatent' `score') (scatter `latent2' `score')
	forvalues g=1/`nbgroups' {
			*di "group=`g'"
			qui su `corrlatent' if `group'==`g'&`touse'
			*di "qui matrix `groups'[`g',`=`nbitems'+9']=`r(min)'"
			*di "qui matrix `groups'[`g',`=`nbitems'+10']=`r(max)'"
			if r(N)!=0 {
				qui matrix `groups'[`g',`=`nbitems'+9']=`r(min)'
				qui matrix `groups'[`g',`=`nbitems'+10']=`r(max)'
			}
	}
	tempname fit
	qui matrix `fit'=J(`nbitems',6,.)
	matrix colnames `fit'=OUTFIT INFIT "Standardized OUTFIT" "Standardized INFIT" "corrOUTFIT" "corrINFIT"
	matrix rownames `fit'=`varlist'
	*matrix list `fit'

	tempvar Tcum TInf cum
	qui gen `Tcum'=0 if `touse'
	qui gen `TInf'=0 if `touse'
	if "`postpce'"=="" {
		di as text "{hline 90}"
		di as text _col(60) "<---  Standardized   --->"
		di as text "Items" _col(34) "OUTFIT" _col(50) "INFIT" _col(64) "OUTFIT" _col(80) "INFIT"
		di as text "{hline 90}"
		di as text "Referenced values*" _col(29) "[" %4.2f `=1-6/sqrt(`nbobs')' ";" %4.2f `=1+6/sqrt(`nbobs')' "]" _col(44) "[" %4.2f `=1-2/sqrt(`nbobs')' ";" %4.2f `=1+2/sqrt(`nbobs')' "]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
		di as text "Referenced values**" _col(29) "[0.75;1.30]" _col(44) "[0.75;1.30]" _col(60) "[-2.6;2.6]" _col(75) "[-2.6;2.6]"
		di as text "{hline 90}"
	}
	*set trace on
	local chi2=0
	local chi2_old=0
	forvalues g=1/`nbgroups' {
	   local chi2_g`g'=0
	   local chi2_old_g`g'=0
	}
	forvalues i=1/`nbitems' {
		if "`rsm'"=="" {
			local mm=`modamax`i''
		}
		else {
			local mm `modamax'
		}
		tempvar cum_old``i'' c_old0_``i'' Inf_old``i'' y_old``i'' y2_old``i''
		tempvar cum``i'' c0_``i'' Inf``i'' C``i'' C2``i'' C3``i'' y``i'' y2``i'' z``i'' z2``i'' i``i''
		tempvar corrcum``i'' corrc0_``i'' corrInf``i'' corry``i'' corrz``i'' corrz2``i'' corri``i''

		local d=1
		local corrd=1
		local d_old=1
		qui gen `corrcum``i'''=0 if `touse'
		qui gen `cum``i'''=0 if `touse'
		qui gen `cum_old``i'''=0 if `touse'
		forvalues k=1/`mm' {
			local corrd `corrd'+exp(`k'*`corrlatent'-`diffmat2'[`i',`k'])
			local d `d'+exp(`k'*`latent2'-`diffmat2'[`i',`k'])
			local d_old `d_old'+exp(`k'*`latent'1-`diffmat2'[`i',`k'])
		}
		qui gen `corrc0_``i'''=1/(`corrd') if `touse'
		qui gen `c0_``i'''=1/(`d') if `touse'
		qui gen `c_old0_``i'''=1/(`d_old') if `touse'
		forvalues k=1/`mm' {
			tempvar corrc`k'_``i'' c`k'_``i'' c_old`k'_``i''
			qui gen `corrc`k'_``i'''=exp(`k'*`corrlatent'-`diffmat2'[`i',`k'])/(`corrd') if `touse'
			qui gen `c`k'_``i'''=exp(`k'*`latent2'-`diffmat2'[`i',`k'])/(`d') if `touse'
			qui gen `c_old`k'_``i'''=exp(`k'*`latent'1-`diffmat2'[`i',`k'])/(`d') if `touse'
			qui replace `corrcum``i'''=`corrcum``i'''+`corrc`k'_``i'''*`k' if `touse'
			qui replace `cum``i'''=`cum``i'''+`c`k'_``i'''*`k' if `touse'
			qui replace `cum_old``i'''=`cum_old``i'''+`c_old`k'_``i'''*`k' if `touse'
		}
		qui gen `corrInf``i'''=0 if `touse'
		qui gen `Inf``i'''=0 if `touse'
		qui gen `Inf_old``i'''=0 if `touse'
		qui gen `C``i'''=0 if `touse'
		forvalues k=0/`mm' {
			qui replace `corrInf``i'''=`corrInf``i'''+(`k'-`corrcum``i''')^2*`corrc`k'_``i''' if `touse'
			qui replace `Inf``i'''=`Inf``i'''+(`k'-`cum``i''')^2*`c`k'_``i''' if `touse'
			qui replace `Inf_old``i'''=`Inf_old``i'''+(`k'-`cum_old``i''')^2*`c_old`k'_``i''' if `touse'
			qui replace `C``i'''=`C``i'''+(`k'-`cum``i''')^4*`c`k'_``i''' if `touse'
		}
		qui count if ``i''!=.&`touse'
		local n``i''=r(N)

		qui gen `C2``i'''=`C``i'''/((`Inf``i''')^2) if `touse'
		qui su `C2``i''' if `touse'
		local q2o``i''=(`r(mean)'-1)/((`n``i'''))

		qui gen `C3``i'''=`C``i'''-(`Inf``i''')^2 if `touse'
		qui su `C3``i'''
		local n=r(sum)
		qui su `Inf``i''' if `touse'
		local d=r(sum)
		local q2i``i''=`n'/((`d')^2)

		//di "``i'' qo = `=sqrt(`q2o``i''')' qi = `=sqrt(`q2i``i''')'"

		qui replace `Tcum'=`Tcum'+`cum``i''' if `touse'
		qui replace `TInf'=`TInf'+`Inf``i''' if `touse'
		qui gen `corry``i'''=``i''-`corrcum``i''' if `touse'
		qui gen `y``i'''=``i''-`cum``i''' if `touse'
		qui gen `y_old``i'''=``i''-`cum_old``i''' if `touse'
		qui gen `y2``i'''=(`y``i''')^2 if `touse'
		qui gen `y2_old``i'''=(`y_old``i''')^2 if `touse'
		qui gen `corrz``i'''=(`corry``i'''/sqrt(`corrInf``i''')) if `touse'
		qui gen `z``i'''=(`y``i'''/sqrt(`Inf``i''')) if `touse'
		local chi2_``i''=0
		local chi2_old_``i''=0
		forvalues g=1/`nbgroups' {

			qui su `y2``i''' if `group'==`g'&`touse'
			local n=r(sum)
			qui su ``i'' if `group'==`g'&`touse'
			local n1=r(sum)
			qui su `cum``i''' if `group'==`g'&`touse'
			local n2=r(sum)
			qui su `Inf``i''' if `group'==`g'&`touse'
			local d=r(sum)
			*qui count if `group'==`g'
			*local eff=r(N)
			*di "chi2_`g'_``i''=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')"
			local chi2=`chi2'+/*`eff'**/(`n1'-`n2')^2/(`d')
			local chi2_``i''=`chi2_``i'''+/*`eff'**/(`n1'-`n2')^2/(`d')
			local chi2_g`g'=`chi2_g`g''+/*`eff'**/(`n1'-`n2')^2/(`d')
			qui su `y2_old``i''' if `group'==`g'&`touse'
			local n_old=r(sum)
			qui su ``i'' if `group'==`g'&`touse'
			local n1_old=r(sum)
			qui su `cum_old``i''' if `group'==`g'&`touse'
			local n2_old=r(sum)
			qui su `Inf_old``i''' if `group'==`g'&`touse'
			local d_old=r(sum)
			local chi2_old=`chi2_old'+(`n1_old'-`n2_old')^2/(`d_old')
			local chi2_old_``i''=`chi2_old_``i'''+(`n_old')/(`d_old')
			local chi2_old_g`g'=`chi2_old_g`g''+(`n_old')/(`d_old')
		}
		*di "Item ``i'' Chi2``i''=`chi2_``i''' et chi2=`chi2'  Chi2_old=`chi2_old_``i''' et chi2_old=`chi2_old' "
		*su `z``i'''
		label variable `corrz``i''' "Corrected standardized residuals associated to ``i''"
		label variable `z``i''' "Standardized residuals associated to ``i''"
		label variable `latent'1 "Latent trait"
		label variable `corrlatent' "Corrected latent trait"
		*set trace on
		if  "`graphs'"!=""&"`graphitems'"=="" {
			*set trace on
			*set tracedepth 1
			if "`filesave'"!="" {
				local fs saving("`dirsave'//residuals_``i''",replace)
			}
			local thr=abs(invnorm(`alpha'/2))
			tempvar id``i''
			local hline
			forvalues l=1/`modamax`i'' {
				local hline `hline' `=`diffmat'[`i',`l']'
			}
			if "`residuals'"=="" {
				if "`corrected'"!="" {
					qui gen `id``i'''=_n if abs(`z``i''')>`thr'*sqrt(`covariates'[1,1])&`touse'
					qui tostring `id``i''',replace
					qui replace `id``i'''="" if `id``i'''=="."&`touse'
					qui su `z``i''' if `touse'
					local min=r(min)
					local max=r(max)
					local min=floor(min(`min',`=-`thr'*sqrt(`covariates'[1,1])'))
					local max=ceil(max(`max',`=`thr'*sqrt(`covariates'[1,1])'))

					qui graph twoway scatter `z``i''' `latent' if `touse', xline(`hline',lwidth(vthin) lcolor(gray)) colordiscrete colorvar(``i'') colorlist(blue green orange purple gray red cyan ) ylabel(`min'(1)`max') yline(`=-`thr'*sqrt(`covariates'[1,1])' `=`thr'*sqrt(`covariates'[1,1])',  lcolor(black)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals") subtitle(`name``i''') `fs'
				}
				else {
				*set trace on
					qui gen `id``i'''=_n if abs(`corrz``i''')>`thr'*sqrt(`covariates'[1,1])&`touse'
					qui tostring `id``i''',replace
					qui replace `id``i'''="" if `id``i'''=="."&`touse'
					qui su `corrz``i''' if `touse'
					local min=r(min)
					local max=r(max)
					local min=floor(min(`min',`=-`thr'*sqrt(`covariates'[1,1])'))
					local max=ceil(max(`max',`=`thr'*sqrt(`covariates'[1,1])'))
					qui graph twoway scatter `corrz``i''' `corrlatent' if `touse',xline(`hline',lwidth(vthin)  lcolor(gray))  colordiscrete colorvar(``i'') colorlist(blue green orange purple gray red cyan ) ylabel(`min'(1)`max') yline(`=-`thr'*sqrt(`covariates'[1,1])' `=`thr'*sqrt(`covariates'[1,1])', lcolor(black)) mlabel(`id``i''') name(residuals``i'',replace) title("Standardized residuals") subtitle(`name``i''') `fs'
				}
			}
			*set trace off
		}
		*set trace off
		qui gen `z2``i'''=(`z``i''')^2 if `touse'
		qui su `z2``i''' if `touse'
		local OUTFIT``i''=`r(mean)'
		qui matrix `fit'[`i',1]=`OUTFIT``i'''
		local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
		qui matrix `fit'[`i',3]=`OUTFITs``i'''
		qui su `Inf``i''' if ``i''!=.&`touse'
		local sumw``i''=r(sum)
		qui gen `i``i'''=`Inf``i'''*`z2``i''' if `touse'
		qui su `i``i''' if ``i''!=.&`touse'
		local INFIT``i'' = `=`r(sum)'/`sumw``i''''
		qui matrix `fit'[`i',2]=`INFIT``i'''
		local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
		qui matrix `fit'[`i',4]=`INFITs``i'''

		/*corrected*/
		qui gen `corrz2``i'''=(`corrz``i''')^2 if `touse'
		qui su `corrz2``i''' if `touse'
		local corrOUTFIT``i''=`r(mean)'
		qui matrix `fit'[`i',5]=`corrOUTFIT``i'''
		*local OUTFITs``i''=((`r(mean)')^(1/3)-1)*(3/sqrt(`q2o``i'''))+sqrt(`q2o``i''')/3
		*qui matrix `fit'[`i',3]=`OUTFITs``i'''
		qui su `corrInf``i''' if ``i''!=.&`touse'
		local corrsumw``i''=r(sum)
		qui gen `corri``i'''=`corrInf``i'''*`corrz2``i''' if `touse'
		qui su `corri``i''' if ``i''!=.&`touse'
		local corrINFIT``i'' = `=`r(sum)'/`corrsumw``i''''
		qui matrix `fit'[`i',6]=`corrINFIT``i'''
		*local INFITs``i''=(`=`r(sum)'/`sumw``i''''^(1/3)-1)*(3/sqrt(`q2i``i'''))+sqrt(`q2i``i''')/3
		*qui matrix `fit'[`i',4]=`INFITs``i'''


		if "`postpce'"=="" {
			di abbrev("`name``i'''",20) _col(35) %5.3f `OUTFIT``i''' _col(50) %5.3f `INFIT``i''' _col(64) %6.3f `OUTFITs``i''' _col(79) %6.3f `INFITs``i''' /*_col(94) %5.3f `corrOUTFIT``i''' _col(109) %5.3f `corrINFIT``i'''*/
		}
	}
	if "`postpce'"=="" {
		di as text "{hline 90}"
		di as text "*: As suggested by Bond and Fox (2007)"
		di as text "**: As suggested by Wright (Smith, 1998)"
	}
	if "`geninf'"!="" {
	    gen `geninf'=`TInf' if `touse'
	}
}
*set trace off
/*************************************************************************************************************
ESTIMATION OF THE WEIGHTED ML ESTIMATORS
**************************************************************************************************************/
*set trace on
*di "estimation `wmliterate'"
if "`postpce'"!="" {
    local conv=10
	local it=`wmliterate'
	di "Iteration : `it'"
	while(`conv'>=1) {
		di "Iteration `it' : conv=`conv'"
		tempvar   sinf
		qui gen `sinf'=sqrt(TInf_`=`it'-1') if `touse'
		`qui' pcm `varlist' [iweight=`sinf'] if `touse',diff(loulou) wmliterate(`it') geninf(TInf_`it') genlt(lt_`it')
		tempvar  ecart_`it'
		qui gen `ecart_`it''=abs(lt_`it'-lt_`=`it'-1') if `touse'
		qui su `ecart_`it'' if `touse'
		local conv =r(mean)
		local ++it
	}
    exit
}

/*ANCIENNE PLACE DES CORRECTED VALUES*/





/*************************************************************************************************************
RESULTS BY GROUP
*************************************************************************************************************/
if "`visit'"==""{
*set trace on
    tempname matscorelt matgroupscorelt
	*di "qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)"
	qui matrix `matscorelt'=J(`=`nbitems'*`modamax'+1',3,.)
	qui matrix `matgroupscorelt'=J(`=(`nbitems'*`modamax'+1+2*`nbgroups')*4',7,.)
	qui matrix colnames `matgroupscorelt'="Group" "Score" "Frequency" "Estimation of latent trait" "s.e. of latent trait" "Expected score" "Corrected latent trait"

	local row=1
	di
	di as text "{hline 71}"
	di _col(32) "Latent Trait" _col(50) "Expected" _col(63) "Corrected"
	di "Group" _col(10) "Score" _col(20) "Freq" _col(32) "Mean" _col(42) "s.e." _col(53) "Score" _col(60) "latent trait"
	di as text "{hline 71}"
	forvalues g=1/`nbgroups' {
		local sumuc=0
		local sumc=0
		qui count if `group'`multivisit'==`g'&`touse'
		local eff`g'=r(N)
		qui count if `group'`multivisit'==`g'&`score'`multivisit'!=.&`touse'
		local effcompleted`g'=r(N)
		qui count if `score'`multivisit'!=.&`group'`multivisit'==`g'&`touse'
		local n=r(N)
		di as text "`g' (n=" as result `eff`g'' as text ")" _c
		if `n'>0 {
			qui su `score'`multivisit' if `group'`multivisit'==`g'&`touse'
			local scoremin`g'=`r(min)'
			local scoremax`g'=`r(max)'
			forvalues s=`scoremin`g''/`scoremax`g'' {
				qui count if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
				local eff=r(N)
				local effscore`s'=r(N)
				if `eff'!=0 {
					qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
					local mean=r(mean)
					*di "local ltscore`s'=`=ceil(`r(mean)'*100)/100'"
					local ltscore`s'=`=ceil(`r(mean)'*100)/100'
					*di "local sumc=`sumc'+(`eff')*(`estlt`s'')"
					*di "local sumuc=`sumuc'+(`eff')*(`mean')"
				    local sumuc=(`sumuc'+((`eff')*(`mean')))
				    local sumc=(`sumc'+((`eff')*(`estlt`s'')))
				}
				qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
				local se=r(mean)
				qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==`s'&`touse'
				local exp=r(mean)
				if `eff'>0 {
				   di as text _col(10) %5.0f `s' as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) %5.2f `exp' _col(66) %6.3f `estlt`s''  `setlt`s''
				}
				*set trace on
				*matrix list `matscorelt'
				qui matrix `matscorelt'[`=`s'+1',1]=`eff'
				qui matrix `matscorelt'[`=`s'+1',2]=`mean'
				qui matrix `matscorelt'[`=`s'+1',3]=`se'
				qui matrix `matgroupscorelt'[`row',1]=`g'
				qui matrix `matgroupscorelt'[`row',2]=`s'
				qui matrix `matgroupscorelt'[`row',3]=`eff'
				qui matrix `matgroupscorelt'[`row',4]=`mean'
				qui matrix `matgroupscorelt'[`row',5]=`se'
				qui matrix `matgroupscorelt'[`row',6]=`exp'
				qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
				local ++row
				*set trace off
			}

		}
		*set trace on
		qui count if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
		local eff=r(N)
		local eff_md_`g'=r(N)
		if `eff'!=0 {
			qui su `latent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
			local mean=r(mean)
			local lt_md_`g'=r(mean)
			local sumuc=(`sumuc'+((`eff')*(`mean')))
			qui su `selatent'1 if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
			local se=r(mean)
			qui su `Tcum' if `group'`multivisit'==`g'&`score'`multivisit'==.&`touse'
			local exp=r(mean)
			di  as text _col(10) "    ." as result _col(20) %4.0f `eff' _col(30) %6.3f `mean' _col(40) %6.3f `se' _col(53) /*%5.2f `exp'*/
			qui matrix `matgroupscorelt'[`row',1]=`g'
			*qui matrix `matgroupscorelt'[`row',2]=`s'
			qui matrix `matgroupscorelt'[`row',3]=`eff'
			qui matrix `matgroupscorelt'[`row',4]=`mean'
			qui matrix `matgroupscorelt'[`row',5]=`se'
			qui matrix `matgroupscorelt'[`row',6]=`exp'
			*qui matrix `matgroupscorelt'[`row',7]=`estlt`s''
			local ++row
		}
		*set trace off
		*di "local lt`g'=`sumuc'/`eff`g''"
		*di "local clt`g'=`sumc'/`effcompleted`g''"
		local lt`g'=(`sumuc')/(`eff`g'')
		local clt`g'=(`sumc')/(`effcompleted`g'')
		matrix `groups'[`g',`=`nbitems'+6']=`clt`g''
		*di "group `g' est=`lt`g'' corrected est=`clt`g''"
		di as text "         " "{dup 62:-}"
		if "`scoremin`g''"=="" {
			local scoremin`g' "."
		}
		if "`scoremax`g''"=="" {
			local scoremax`g' "."
		}
		di  as text _col(10) "`scoremin`g''/`scoremax`g''" as result _col(20) %4.0f `eff`g'' _col(30) %6.3f `lt`g''  _col(66) %6.3f `clt`g''
		di as text "{hline 71}"
		qui matrix `matgroupscorelt'[`row',1]=`g'
		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
		qui matrix `matgroupscorelt'[`row',5]=`se'
		*qui matrix `matgroupscorelt'[`row',6]=`exp'
		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
		local ++row
	}
	local nbrowmat=`row'-1
	qui matrix `matgroupscorelt'=`matgroupscorelt'[1..`nbrowmat',1..7]
	*matrix list `matscorelt'
}

*set trace on

/*************************************************************************************************************
Categories/Items/Test Characteristics Curves and Information graphs
*************************************************************************************************************/
*set trace on
if "`visit'"==""{
	if "`graphs'"!=""|"`graphs'"=="" {

		tempfile savefile
		qui save `savefile'

		*qui clear
		qui drop _all
		local pas=1000*round(`=sqrt(`covariates'[1,1])',0.001)
		local pas=round(`pas')
		qui set obs `pas'
		qui gen u=round((_n-`pas'/2)/(`pas'/10)*`=sqrt(`covariates'[1,1])',0.01)
		*list u
		qui gen Tcum=0
		qui gen TInf=0
		qui gen ecartcum=.
		forvalues i=1/`nbitems' {
		   local scatteri`i'
		   local scatteric`i'
		   forvalues g=1/`nbgroups' {
			  local x=`groups'[`g',`=`nbitems'+1']
			  local xc=`groups'[`g',`=`nbitems'+6']
			  local xmin=`groups'[`g',`=`nbitems'+7']
			  local xmax=`groups'[`g',`=`nbitems'+8']
			  local xcmin=`groups'[`g',`=`nbitems'+9']
			  local xcmax=`groups'[`g',`=`nbitems'+10']
			  local y=`groups'[`g',`i']
			  local s1=`groups'[`g',`=`nbitems'+2']
			  local seuil=20
			  local s vtiny
			  *set trace on
			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
				  if `s1'>`seuil' {
					 local s `lab'
				  }
				  local seuil=`seuil'+10
			  }
			  local scatteri`i' `scatteri`i'' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off) || pci `y' `xmin'  `y' `xmax' ,lcolor(black)
			  local scatteric`i' `scatteric`i'' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off) || pci `y' `xcmin'  `y' `xcmax' ,lcolor(black)
			*set trace off
			}
			local d=1
			qui gen cum``i''=0
			*set trace on
			if "`rsm'"=="" {
				local mm=`modamax`i''
			}
			else {
				local mm `modamax'
			}
			forvalues k=1/`mm' {
				local d `d'+exp(`k'*u-`diffmat2'[`i',`k'])
			}
			qui gen c0_``i''=1/(`d')
			label variable c0_``i'' "Pr(X=0)"
			local xline
			local yline
			forvalues k=1/`mm' {
				qui gen c`k'_``i''=exp(`k'*u-`diffmat2'[`i',`k'])/(`d')
				qui replace cum``i''=cum``i''+c`k'_``i''*`k'
				label variable c`k'_``i'' "Pr(X=`k')"
				local xline `xline' `=`diffmat'[`i',`k']'
				local yline `yline' `=`k'-0.5'

			}
			forvalues k=0/`mm' {
			    if `k'==0 {
				   local l=0.25
				}
				else if `k'==`mm' {
				   local l=`k'-0.25
				}
				else {
				   local l=`k'
				}
				qui replace ecartcum=abs(cum``i''-`l')
				qui su ecartcum
				qui su u if round(ecartcum,0.01)==round(`r(min)',0.01)
				local bestest``i''_`k'=r(mean)
				*di "item ``i'' cat `k' : est=`bestest``i''_`k''"
			}
			qui gen Inf``i''=0
			label variable Inf``i'' "`name``i'''"
			forvalues k=0/`mm' {
				qui replace Inf``i''=Inf``i''+(`k'-cum``i'')^2*c`k'_``i''
			}
			if "`graphitems'"=="" {
				if "`filesave'"!="" {
					local fsc saving("`dirsave'//CCC_``i''",replace)
					local fsi saving("`dirsave'//ICC_``i''",replace)
				}
				if "`graphs'"!="" {
					qui graph twoway line c*_``i'' u , name(CCC``i'', replace) title(Categories Characteristic Curve (CCC)) subtitle(`name``i''') ytitle("Probability") xtitle("`xtitle'") `fsc' xline(`xline',lwidth(vthin) lcolor(gray))
					if "`corrected'"!="" {
						qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC)") subtitle(`name``i''') ytitle("Score to the item") xtitle("Latent trait") `scatteri`i'' `fsi' xline(`xline',lwidth(vthin) lcolor(gray)) ylabel(0(.5)`modamax`i'')
					}
					else {
						qui graph twoway line cum``i'' u, name(ICC``i'',replace) title("Item Characteristic Curve (ICC)") subtitle(`name``i''') ytitle("Score to the item") xtitle("Corrected latent trait") `scatteric`i'' `fsi' xline(`xline',lwidth(vthin) lcolor(gray)) ylabel(0(.5)`modamax`i'')
					}
				}
			}
			qui replace Tcum=Tcum+cum``i''
			qui replace TInf=TInf+Inf``i''
		}
	    local scoremax=0
		forvalues i=1/`nbitems' {
		      local scoremax=`scoremax'+`modamax`i''
	    }
		qui gen ecart=.
		forvalues i=0/`scoremax' {
		    if `i'==0 {
			   local j=0.25
			}
			else if `i'==`scoremax' {
			   local j=`scoremax'-0.25
			}
			else {
			   local j=`i'
			}
		    qui replace ecart=abs(Tcum-`j')
		    qui su ecart
			local tmp=r(min)
			qui su u if round(ecart, 0.01)==round(`tmp',0.01)
			local estlt`i'=`r(mean)'
			*di "score `i' : `r(mean)'"
		}
		if "`filesave'"!="" {
			local fst saving("`dirsave'//TCC",replace)
			local fsteo saving("`dirsave'//TCCeo",replace)
			local fsi saving("`dirsave'//ICC",replace)
			local fsti saving("`dirsave'//TIC",replace)
			local fstii saving("`dirsave'//TICi",replace)
			local fsm saving("`dirsave'//map",replace)
		}
		if "`graphs'"!="" {
*qui save "C:\temp\info\info",replace
			label variable TInf "Information curve"

			qui graph twoway line Tcum u, name(TCC,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("`xtitle'") `fst' subtitle(`dimname') ylabel(0(1)`scoremax') xline(`listlt',lwidth(vthin) lcolor(gray))
			qui graph twoway line Inf* u, name(IIC,replace) title("Item Information Curves") ytitle("Information") xtitle("`xtitle'")  `fsi' subtitle(`dimname')
			qui graph twoway line TInf u, name(TIC,replace) title("Test Information Curve") ytitle("Information") xtitle("`xtitle'")  `fsti' subtitle(`dimname')
			qui graph twoway (line Inf*  u, lwidth(thin)) (line TInf u, lwidth(thick)), name(TIC,replace) title("Test/Item Information Curve") ytitle("Information") xtitle("`xtitle'")  `fstii' subtitle(`dimname')
		}
		local scatteri
		local scatteric
		forvalues g=1/`nbgroups' {
		*matrix list `groups'
			local x=`groups'[`g',`=`nbitems'+1']
			local xc=`groups'[`g',`=`nbitems'+6']
			local xmin=`groups'[`g',`=`nbitems'+7']
			local xmax=`groups'[`g',`=`nbitems'+8']
			local xcmin=`groups'[`g',`=`nbitems'+9']
			local xcmax=`groups'[`g',`=`nbitems'+10']
			local y=`groups'[`g',`=`nbitems'+3']
			  local s1=`groups'[`g',`=`nbitems'+2']
			  local seuil=20
			  local s tiny
			  *set trace on
			  foreach lab in  /*tiny*/ vsmall small medsmall medium medlarge  large   vlarge  huge vhuge /*ehuge*/ {
				  if `s1'>`seuil' {
					 local s `lab'
				  }
				  local seuil=`seuil'+10
			  }
			local scatteri `scatteri' || scatteri `y' `x' , mcolor(black) msize(`s') legend(off)|| pci `y' `xmin'  `y' `xmax' ,lcolor(black)
			local scatteric `scatteric' || scatteri `y' `xc' , mcolor(black) msize(`s') legend(off) || pci `y' `xcmin'  `y' `xcmax' ,lcolor(black)
		}
		*set trace on
		if "`graphs'"!="" {
			if "`corrected'"!="" {
				qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Latent trait") `scatteri' `fsteo' subtitle(`dimname') xline(`listlt',lwidth(vthin) lcolor(gray))
			}
			else {
				qui graph twoway line Tcum u , name(TCCeo,replace) title("Test Characteristic Curve (TCC)") ytitle("Score to the test") xtitle("Corrrected latent trait") `scatteric' `fsteo' subtitle(`dimname') xline(`listlt',lwidth(vthin) lcolor(gray))
			}
		}
		*set trace off
	}


/*************************************************************************************************************
MAP
*************************************************************************************************************/
	*set trace on
	if "`graphs'"!=""|"eqset1"!="" {
		gen eff=0
		gen eff_md=0
		local effmax=0
			*gen uround=round(u,0.01)
			*list uround
		/*le bloc suivant était pour avoir des batons par groupe*/
		/*forvalues g=1/`nbgroups' {
			local eff=`groups'[`g',`=`nbitems'+2']
			if `groups'[`g',`=`nbitems'+2']>`effmax' {
			   local effmax=`groups'[`g',`=`nbitems'+2']
			}
			local lat=round(`groups'[`g',`=`nbitems'+1'],0.01)
			*di "replace eff=`eff' if round(u,0.01)==`lat'"
			qui replace eff=`eff' if round(u,0.01)==`lat'
		}*/
		/*le bloc suivant est pour avoir des batons par score*/
		qui gen uceil=ceil(u*100)/100
		forvalues s=0/`scoremax' {
			if `effscore`s''>`effmax' {
			   local effmax=`effscore`s''
			}
			*di "`s' qui replace eff=`effscore`s'' if ceil(u*100)/100==`=round(`ltscore`s'',0.01)'"
			qui replace eff=`effscore`s'' if round(u,0.01)==round(`ltscore`s'',0.01)
		}
		forvalues g=1/`nbgroups' {
			*di "if `eff_md_`g''>`effmax' { (`lt_md_`g'')"
			if `eff_md_`g''>`effmax' {
			   local effmax=`eff_md_`g''
			}
			qui replace eff_md=`eff_md_`g'' if round(u,0.01)==round(`lt_md_`g'',0.01)
		}

		gen density=normalden(u)*sqrt(`covariates'[1,1])
		label variable eff "Complete"
		label variable eff_md "Incomplete"
		label variable u "Latent trait"
		label variable TInf "Information curve"
		label variable density "Density function of the latent trait"
		local scatteri
		local scatterj
		local color
		qui su u if eff!=0|eff_md!=0
		*set trace on
		*set tracedepth 1
		*if eff!=0|eff_md!=0 {
			local floor=floor(`r(min)')
			local ceil=ceil(`r(max)')
		*}
		*else  {
		*	local floor=-10
		*	local ceil=10
		*}
		local sep
		local ylbl
		forvalues i=1/`nbitems' {
		   local color`i':word `i' of `color'
		   local unit=round(`effmax'/`nbitems',1)
		   local y=-`i'*`unit'
		   loca staritem
		   *local legend `"1 2 `=(`modamax'+1)*`nbitems'+1' `=(`modamax'+1)*`nbitems'+2' 3 "1" "'
		   local legend `"5 "1" "'
		   forvalues l=1/`modamax' {
			   if `l'>=2 {
			      local legend `" `legend' `=2*`l'+3' "`l'" "'
			   }
			   local x=`diffmat'[`i',`l']
			   local scatteri `scatteri' || scatteri `y' `x' "`l'" ,mcolor(black) mlabcolor(black)
			   if `l'==1 {
			      local xant=`x'
			   }
			   else {
			      local xant=`diffmat'[`i',`=`l'-1']
			   }
			   if `xant'>`x' {
				  local star *
				  local staritem *
			   }
			   else {
			      local star
			   }
			   local scatterj `" `scatterj' `sep' scatteri `y' `x'   , pstyle(p`l') || pci `y' `xant' `y' `x', pstyle(p1) color(black)"'
			   local sep ||
			   if `x'<`floor' {
				  local floor=floor(`x')
			   }
			   if `x'>`ceil'&`x'!=. {
				  local ceil=ceil(`x')
			   }
		   }
		   local nomcourt``i''=abbrev("`name``i'''",20)
   		   local ylbl `ylbl' `=-`i'*`unit'' "`nomcourt``i'''`staritem'"
		   local scatteri `scatteri' || scatteri `y' `=`floor'-2' "``i''",mcolor(black) mlabcolor(black) msize(vtiny)
		}
		qui su eff
		local maxe=ceil(`=(floor(`r(max)'/10)+1)*10')
		qui su eff_md
		local maxe_md=ceil(`=(floor(`r(max)'/10)+1)*10')
		local maxe=max(`maxe',`maxe_md')
		qui su TInf
		local maxi=1.2*ceil(`r(max)')
		qui su density
		local maxd=round(`r(max)', 0.01)+0.01
		qui drop if u<`floor'|u>`ceil'
		*di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) legend(off) xlabel(0(1)`ceil')) (line TInf u,yaxis(2)) (line density u,yaxis(3)) `scatterj'   , name(map,replace) ytitle(Frequencies)  ylabel(0(`=`maxi'/5')`maxi' ,axis(2)) ylabel(0(`=`maxd'/5')`maxd' ,axis(3)) ylabel(-`maxe'(`=`maxe'/5')`maxe' ,axis(1)) title(Individuals/items representations (Map)) xsize(12) ysize(9) note(Red line: Information curve - Green line : Density of the latent trait) xtitle(Latent trait) `fsm'"
		*graph combine TIC IIC,  col(1)
		*graph save "map" "map.gph", replace
		*discard
		*qui graph twoway line TInf u , name(map,replace)
		*qui graph twoway `scatterj'  , name(map2,replace) ytitle("")   ylabel(`ylbl', grid angle(0))  legend(off) xsize(12) ysize(9)
		*su
*list eff u if eff!=0
*browse
		if "`eqset1'"==""&"`graphs'"!="" {
		    *list eff u uceil if eff!=0&eff!=.
			*save tmp, replace
			*di "`legend'"
			*di "holes(3/`nbcolslegende' `=`nbcolslegende'+3'/`=`nbcolslegende'*2')"
			local nbcolslegende=max(2,`modamax')
			if `modamax'==1 {
			   local holes "holes(2)"
			}
			tempvar line1 line2
			qui gen `line1'=.
			qui gen `line2'=.
			label variable `line2' "Density"
			label variable `line1' "Information"
			qui graph twoway (line `line1' u ,lwidth(medthick) lcolo(red)) (line `line2' u ,lwidth(medthick) lcolo(green)) (line density u,yaxis(3) lwidth(medthick) lcolo(green) ) (bar eff u,  barwidth(.1) yaxis(1) xlabel(`floor'(1)`ceil') color(erose) )  (bar eff_md u,  barwidth(.05) yaxis(1) xlabel(`floor'(1)`ceil') color(stred) )  (line TInf u,yaxis(2) lwidth(medthick) lcolo(red) ) `scatterj'   , xline(0, lcolor(black)) legend(on position(3)     /*symysize(*.6) symxsize(*.6) textwidth(*.6)*/ /*cols(`nbcolslegende')*/ cols(1)  `holes' order(`"- "Functions" 2 1 - "" - "Patterns" 3 4 - "" - "Thresholds" `legend'  "') /*subtitle(Threshold parameters,size(*.7)) */size(small)) name(map,replace) ytitle("                           Frequencies")  ylabel(0(`=`maxi'/5')`maxi' `maxi'(`maxi')`=`maxi'*2' ,axis(2)) yscale(axis(2) off) yscale(axis(3) off)  ylabel(-`maxd'(`=`maxd'/5')`maxd' ,axis(3)) yline(0,lwidth(medium) lpattern(solid) lcolor(black))  ylabel(`ylbl',/*noticks*/ grid angle(0) axis(1)) ylabel(`ylbl' 0(`=`maxe'/5')`maxe', grid angle(0) axis(1)) title("Individuals/items representations (Map)") xsize(12) ysize(9) note("* : dysfunctioning items") xtitle("`xtitle'") `fsm' subtitle(`dimname')
		}
		else if "`eqset1'"!="" {
			qui su eff
	        local ceil=ceil(ceil(`r(max)'/10)*10)

            qui tempfile equating
			qui save `equating', replace
		}
	}
	qui use `savefile', clear
}



/*************************************************************************************************************
Best estimates by category
*************************************************************************************************************/

tempname bestest
matrix `bestest'=J(`nbitems',`=`modamax'+1',.)
di
local long=`modamax'*8+33
di
di "Best estimates by answer category"
di "{hline `long'}"
di "Item" _col(29) "Cat 0"  _c
forvalues j=1/`modamax' {
     local col=29+`j'*8
	 di _col(`col') "Cat `j'"     _c
}
di
di "{hline `long'}"
forvalues i=1/`nbitems' {
    di abbrev("`name``i'''",20) _c
	forvalues j=0/`modamax`i'' {
	    di _col(`=28+`j'*8') %6.3f round(`bestest``i''_`j'', 0.001) _c
		matrix `bestest'[`i',`=`j'+1']=`bestest``i''_`j''
	}
	di
}
di "{hline `long'}"



/*************************************************************************************************************
EQUATING
*************************************************************************************************************/
if "`eqset1'"!="" {
    if "`eqgenscore'"!="" {
	   local tmp1 `=ustrlen("`eqgenscore'`eqset1name'")'
	   local tmp2 `=ustrlen("`eqgenscore'`eqset2name'")'
	   local mlength=max(`tmp1',`tmp2')
	   if `mlength'>27 {
			di as error "The number of characters containing in the strings eqgenscore+eqset1name or eqgenscore+eqset2name must be lesser than 27"
			di as error "eqgenscore+eqset1name : `tmp1' characters"
			di as error "eqgenscore+eqset2name : `tmp2' characters"
			error 130
			*exit
		}
	}
	if "`eqset1name'"=="" {
	   local eqset1name="Set_1"
	}
	else if `c(version)'>17 {
		local eqset1name `=regexreplaceall("`eqset1name'"," ","_",.)'
	}
	if "`eqset2name'"=="" {
	   local eqset2name="Set_2"
	}
	else if `c(version)'>17 {
		local eqset2name `=regexreplaceall("`eqset2name'"," ","_",.)'
	}
	*di "set1:`eqset1name' set2:`eqset2name'"

    tokenize `eqset1'
	local nbset1: word count `eqset1'
	forvalues i=1/`nbset1' {
	   local eq1_`i':word `i' of `eqset1'
	}
    tokenize `eqset2'
	local nbset2: word count  `eqset2'
	forvalues i=1/`nbset2' {
	   local eq2_`i':word `i' of `eqset2'
	}



	tempfile fileeq
	qui save `fileeq',replace
	forvalues t=1/2{
		local scoremaxset`t'=0
		forvalues i=1/`nbset`t'' {
			local scoremaxset`t'=`scoremaxset`t''+`modamax`eq`t'_`i'''
		}
	}
	drop _all
	qui set obs `=(`scoremaxset1'+`scoremaxset2'+2)*3'
	forvalues t=1/2 {
		qui gen scoreset`t'=.
		qui gen scoreset`t'm=.
		qui gen scoreset`t'p=.
	}
	forvalues i=0/`scoremaxset1' {
	    qui replace scoreset1=`i' in `=`i'+1'
	    qui replace scoreset1m=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)'
	    qui replace scoreset1p=`i' in `=`i'+1+(`scoremaxset1'+`scoremaxset2'+2)*2'
	}
	forvalues i=`=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2' {
	    qui replace scoreset2=`i'-`scoremaxset1'-2 in `i'
	    qui replace scoreset2m=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)'
	    qui replace scoreset2p=`i'-`scoremaxset1'-2 in `=`i'+(`scoremaxset1'+`scoremaxset2'+2)*2'
	}
	local s=0
	local eqset1b
	foreach i in `eqset1' {
		qui gen s1_`i'=0
		forvalues m=1/`modamax`i'' {
		   qui gen s1_`i'_`m'=0 in 1/`=`scoremaxset1'+1'
		   qui replace s1_`i'_`m'=1 if scoreset1>`s' in 1/`=`scoremaxset1'+1'
		   qui replace s1_`i'=s1_`i'+s1_`i'_`m'
		   local ++s
		}
	    local eqset1b `eqset1b' s1_`i'
	}
	local s=0
	local eqset2b
	foreach i in `eqset2' {
		qui gen s2_`i'=0
		forvalues m=1/`modamax`i'' {
		   qui gen s2_`i'_`m'=0 in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
		   qui replace s2_`i'_`m'=1 if scoreset2>`s' in `=`scoremaxset1'+2'/`=`scoremaxset1'+`scoremaxset2'+2'
		   qui replace s2_`i'=s2_`i'+s2_`i'_`m'
		   local ++s
		}
		local eqset2b `eqset2b' s2_`i'
	}
	tokenize `varlist'
	tempname diffset1 diffset2
	forvalues t=1/2 {
		qui matrix `diffset`t''=J(`nbset`t'',`modamax',.)
		local n=1
		local listset`t'
		foreach j in `eqset`t'' {
			forvalues i=1/`nbitems' {
				if "`j'"=="``i''" {
					local listset`t' `listset`t'' `i'
					forvalues m=1/`modamax' {
						qui matrix `diffset`t''[`n',`m']=`diffmat'[`i',`m']
					}
					local ++n
				}
			}
		}
	}
	local var=`covariates'[1,1]
	qui gen lt=.
	forvalues t=1/2 {
		tempname matscorelt`t'
		qui pcm `eqset`t'b', diff(`diffset`t'') var(`var') minsize(1)
		qui matrix `matscorelt`t''=r(matscorelt)
		forvalues i=0/`scoremaxset`t'' {
			qui replace lt=`matscorelt`t''[`=`i'+1',2] if scoreset`t'==`i'
			qui replace lt=`matscorelt`t''[`=`i'+1',2]+1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'p==`i'
			qui replace lt=`matscorelt`t''[`=`i'+1',2]-1.96*`matscorelt`t''[`=`i'+1',3] if scoreset`t'm==`i'
		}
		qui ipolate scoreset`t' lt, gen(score`t') epolate
	}
	qui ipolate scoreset1 lt, gen(score1bis) epolate


	forvalues t=1/2 {
		qui replace score`t'=scoreset`t'm if scoreset`t'm!=.
		qui replace score`t'=scoreset`t'p if scoreset`t'p!=.
		qui replace score1=score1bis if score1==.
		qui replace score`t'=0 if score`t'<0
		qui replace score`t'=`scoremaxset`t'' if score`t'>`scoremaxset`t''
	}
	local pciset1
	local pciset2
	*set trace on
	local minimini=0
	local maximaxi=0
	forvalues t=1/2 {
        qui gen adjscore`t'=(score`t'+`eqaddset`t'')*`eqmultset`t''
	    qui gen adjscore`=3-`t''=(score`=3-`t''+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''
		tempname matscore`t'
		qui matrix `matscore`t''=J(`=`scoremaxset`t''+1',7,.)
		*set trace on
		forvalues s=0/`scoremaxset`t'' {
		    qui matrix `matscore`t''[`=`s'+1',1]=`s'
			qui su lt if scoreset`t'==`s'
		    qui matrix `matscore`t''[`=`s'+1',2]=r(mean)
			if `ceil'==0 {
				local ceil=1
			}
			if "`eqwithci'"=="" {
				local pciset`t'  `pciset`t'' scatteri `=-`ceil'/5*`t'' `r(mean)' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)||
			}
			local mean=r(mean)
			qui su lt if scoreset`t'm==`s'
		    qui matrix `matscore`t''[`=`s'+1',3]=r(mean)
			local moins=r(mean)
			if `moins'<`minimini' {
				*di "local minimini=floor(`moins')"
				local minimini=floor(`moins')
			}
			qui su lt if scoreset`t'p==`s'
		    qui matrix `matscore`t''[`=`s'+1',4]=r(mean)
			local plus=r(mean)
			if `plus'>`maximaxi' {
				*di "local maximaxi=ceil(`plus')"
				local maximaxi=ceil(`plus')
			}

			if "`eqwithci'"!="" {
				local y=-`ceil'/5*((2.5*`t'-2)+2*(`s'/`scoremaxset`t''))
				*local pciset`t'  `pciset`t'' scatteri `y' `mean' (12) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
				local pciset`t'  `pciset`t'' scatteri `y' `mean'  , mlabsize(tiny) mcolor(black) mlabcolor(black)|| scatteri `y' `moins' (9) "`=round((`s'+`eqaddset`t'')*`eqmultset`t'',1)'"  , msize(0) mlabsize(tiny) mcolor(black) mlabcolor(black)|| pci `y' `moins' `y' `plus',pstyle(p1) color(black)||
			}
			qui su score`=3-`t'' if scoreset`t'==`s'
		    qui matrix `matscore`t''[`=`s'+1',5]=r(mean)
			qui su score`=3-`t'' if scoreset`t'm==`s'
		    qui matrix `matscore`t''[`=`s'+1',6]=r(mean)
			qui su score`=3-`t'' if scoreset`t'p==`s'
		    qui matrix `matscore`t''[`=`s'+1',7]=r(mean)
		}
		matrix colnames `matscore`t'' =score`t' lt lt- lt+ score`=3-`t'' score`=3-`t''- score`=3-`t''+
		di as text
		di as text "{hline 78}"
		di as text "EQUATING `eqset`t'name' TO `eqset`=3-`t''name'"
		di as text "{hline 78}"
		di "`eqset`t'name' : `eqset`t''"
		di "`eqset`=3-`t''name' : `eqset`=3-`t'''"
		local eqset`t'namea=abbrev("`eqset`t'name'",18)
		local eqset`=3-`t''namea=abbrev("`eqset`=3-`t''name'",12)
		di "{hline 78}"
		di "Score"           _col(20) "<----- Latent trait ----->" _col(52) "<- Score `eqset`=3-`t''namea'" _col(77) "->"
		di "`eqset`t'namea'" _col(20) "Estimated" _col(39) "[95%IC]" _col(52) "Estimated" _col(72) "[95%IC]"
		di "{hline 78}"
		forvalues s=0/`scoremaxset`t'' {
		    local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
		    local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')

			di %4.0f `=(`matscore`t''[`=`s'+1',1]+`eqaddset`t'')*`eqmultset`t''' _col(24) %5.2f `matscore`t''[`=`s'+1',2] _col(33) "[" %5.2f `matscore`t''[`=`s'+1',3] ";" %5.2f `matscore`t''[`=`s'+1',4] "]" _col(56) %5.2f `=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' _col(66) "[" %5.2f `min' ";" %5.2f `max' "]"
		}
		di "{hline 78}"
		if "`eqgraph'"!="" {
		    *set trace on
			if `eqmultset`=3-`t'''>0 {
				local xlabel 	"`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''(`=ceil((`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''"
			}
			else {
				local xlabel 	"`=(`scoremaxset`=3-`t'''+`eqaddset`=3-`t''')*`eqmultset`=3-`t''''(`=ceil((-`scoremaxset`=3-`t'''*`eqmultset`=3-`t''')/20)')`=`eqaddset`=3-`t'''*`eqmultset`=3-`t''''"
			}
			if `eqmultset`t''>0 {
				local ylabel 	"`=`eqaddset`t''*`eqmultset`t'''(`=ceil((`scoremaxset`t''*`eqmultset`t'')/20)')`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''"
			}
			else {
				local ylabel 	"`=(`scoremaxset`t''+`eqaddset`t'')*`eqmultset`t'''(`=ceil((-`scoremaxset`t''*`eqmultset`t'')/20)')`=`eqaddset`t''*`eqmultset`t'''"
			}
			*set trace off
			*di "xlabel : `xlabel'"
			*di "subtitle=`subtitle'"
			twoway (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''!=.,lcolor(black) lpattern(solid) lwidth(thick)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''m!=.,lcolor(black) lpattern(dash) lwidth(thin)) (line adjscore`t' adjscore`=3-`t'' if scoreset`=3-`t''p!=.,lcolor(black) lpattern(dash) lwidth(thin)), title("Equating score of `eqset`=3-`t''name' to `eqset`t'name' ") ytitle("Score `eqset`t'name'") xtitle("Score `eqset`=3-`t''name'") ylabel(`ylabel') xlabel(`xlabel') name(eq`t'to`=3-`t'') legend(order(1 2) label(1 "Estimated") label(2 "95%IC") position(6)) subtitle("`dimname'")
		}
		qui drop adjscore`t' adjscore`=3-`t''
	}

	if "`eqgraph'"!="" {
		qui use "`equating'",clear
	    qui su u
	    local flooru=floor(`r(min)')
	    local ceilu=ceil(`r(max)')
		qui su eff
	    local ceil=ceil(ceil(`r(max)'/10)*10)
		if `ceil'==0 {
		   local ceil=1
		}

		local title "Equating"
		if "`eqset1name'"!=""&"`eqset2name'"!=""{
		   local title "Equating between `eqset1name' and `eqset2name'"
		}
		if "`eqwithci'"=="" {
		   local ylabel1=-`ceil'/5
		   local ylabel2=-2*`ceil'/5
		   local gapu=ceil((`ceilu'-`flooru')/15)
		}
		else {
		    local ylabel1=-0.5*`ceil'/5
		    local ylabel2=-3*`ceil'/5
		   	local flooru=min(`flooru',`minimini')
			local ceilu=max(`ceilu',`maximaxi')
			local gapu=ceil((`ceilu'-`flooru')/15)
		}
	    *di "qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(1)`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle(                           Frequencies)    ylabel(`=-`ceil'/5*2' `eqset1name' `=-`ceil'/5' `eqset2name' 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title(Equating) xsize(12) ysize(9)  xtitle(Latent trait) "
	    qui graph twoway (bar eff u, barwidth(.2) yaxis(1) xlabel(`flooru'(`gapu')`ceilu') color(erose)) || `pciset1' `pciset2'  , yline(0, lcolor(black)) legend(off) name(equating,replace) ytitle("                           Frequencies")    /*ylabel(`ylbl', grid angle(0) axis(1))*/ ylabel(`ylabel1' "`eqset1name'" `ylabel2' "`eqset2name'" 0(`=`ceil'/5')`ceil', grid angle(0) axis(1)) title("`title'") subtitle("`dimname'") xsize(12) ysize(9)  xtitle("Latent trait")
	}
	qui use `fileeq',clear
	*set trace on
	tempname scoreset1 scoreset2
	forvalues t=1/2 {
		qui genscore `eqset`t'' if `touse',score(`scoreset`t'')
	 	qui su `scoreset`t'' if `touse'
		local maxscoreset=r(max)
		*qui matrix list `matscore`t''
		if "`eqgenscore'"!="" {
			local eqgenscore `=regexreplaceall("`eqgenscore'"," ","_")'
			*di "eqgenscore : `eqgenscore'"
			foreach k in mean min max random {
				capture confirm  variable `eqgenscore'_`k'_`eqset`=3-`t''name'
				if _rc==0&"`replace'"!="" {
					qui replace `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
				}
				else if _rc==0&"`replace'"!="" {
					di as error "The variable `eqgenscore'_`k'_`eqset`=3-`t''name' already exists"
					error 198
				}
				else {
					qui gen `eqgenscore'_`k'_`eqset`=3-`t''name'=. if `touse'
				}
			}
			*tab `scoreset`t''
			forvalues s=0/`maxscoreset' {
				*di "qui replace `eqgenscore'_`eqset`=3-`t''name'=`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''' if `scoreset`t''==`s'"
				local min=min(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
				local max=max(`=(`matscore`t''[`=`s'+1',6]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',`=(`matscore`t''[`=`s'+1',7]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''')
				qui replace `eqgenscore'_mean_`eqset`=3-`t''name'=round(`=(`matscore`t''[`=`s'+1',5]+`eqaddset`=3-`t''')*`eqmultset`=3-`t'''',1) if round(`scoreset`t'',1)==`s'&`touse'
				qui replace `eqgenscore'_min_`eqset`=3-`t''name'=round(`min',1) if round(`scoreset`t'',1)==`s'&`touse'
				qui replace `eqgenscore'_max_`eqset`=3-`t''name'=round(`max',1) if round(`scoreset`t'',1)==`s'&`touse'
				qui replace `eqgenscore'_random_`eqset`=3-`t''name'=round(uniform()*(`max'-`min')+`min',1) if round(`scoreset`t'',1)==`s'&`touse'
			}
		}
		return matrix score`t'_to_`=3-`t''=`matscore`t''
	}

}


/*************************************************************************************************************
RETOUR AU FICHIER INITIAL ET SAUVEGARDE DES NOUVELLES VARIABLES
*************************************************************************************************************/
*set trace on
if "`visit'"!="" {
	tempfile sauv
	*set trace on
	*tempname corrlatent corrbilatent
	qui keep `latent'* `selatent'* `id' `visit'
    qui reshape wide , i(`id') j(`visit')
	qui sort `id'
	qui save `sauv', replace
	restore,preserve
	if "`replace'"!=""&("`genlt'"!=""|"`geninf'"!="") {
    	capture drop `genlt'
    	capture drop `genlt'_se
    	capture drop `geninf'
    	capture drop `genlt'_corr
    	capture drop `genlt'_best
    	*capture drop `genlt'_opt_se
    }
	*su
	tempname idorder
	qui gen `idorder'=_n
	qui sort `id'
	qui merge 1:1 `id' using `sauv'

	qui sort `idorder'
    qui drop `idorder'
}
else {
*set trace on
*set tracedepth 1
    if "`genlt'"!="" {
		qui gen `genlt'_corr=`corrlatent' if `touse'
/*		qui gen `genlt'_corr2=. if `touse'
		forvalues s=0/`scoremax' {
			qui replace `genlt'_corr2=`estlt`s'' if `score'==`s'&`touse'
		}
		forvalues g=1/`nbgroups' {
			qui replace `genlt'_corr2=`clt`g'' if `group'==`g'&`genlt'_corr==.&`touse'
		}
*/
		tempvar tmpitem mean nbnonmiss
		forvalues i=1/`nbitems' {
			qui gen `tmpitem'_`i'=. if `touse'
			forvalues k=0/`modamax' {
				qui replace `tmpitem'_`i'=`bestest'[`i',`=`k'+1'] if ``i''==`k'&`touse'
			}
		}
		*su
		qui egen `genlt'_best=rowmean(`tmpitem'_*) if `touse'
		*qui egen `genlt'_opt_se=rowsd(`tmpitem'_*) if `touse'
		qui egen `nbnonmiss'=rownonmiss(`tmpitem'_*) if `touse'
		*qui replace `genlt'_opt_se=sqrt((`genlt'_opt_se^2+`resvar')/`nbnonmiss') if `touse'
 	}
	restore,not
}

/*************************************************************************************************************
CREATION DU DOCX
*************************************************************************************************************/

if "`docx'"!="" {
    putdocx clear
    putdocx begin, footer(fall_report)
	putdocx table hdr = (1, 3), border(all, nil) tofooter(fall_report)
	if "`rsm'"=="" {
		putdocx table hdr(1, 1) = ("Partial Credit Model")
	}
	else {
		putdocx table hdr(1, 1) = ("Rating Scale Model")
	}
	putdocx table hdr(1, 2) = ("`dimname'"), halign(center)
	putdocx table hdr(1, 3) = ("Page "), pagenumber
	putdocx table hdr(1, 3) = ("/"), totalpages append
	putdocx table hdr(1, 3), halign(right)
	putdocx paragraph ,style(Title)
	if "`dimname'" =="" {
	    local dimname2 "Rasch analysis"
	}
	else {
	    local dimname2 "Rasch analysis of the `dimname' dimension"
	}
	putdocx text ("`dimname2'") ,
	putdocx paragraph ,style(Subtitle)
	putdocx text ("General informations") ,
	putdocx paragraph
	putdocx text ("Number of individuals: `nbobs'")
	putdocx paragraph
	putdocx text ("Number of complete individuals: `nbobsssmd'")
	putdocx paragraph
    putdocx text ("Number of items: `nbitems'")
	putdocx paragraph
    putdocx text ("Names of the dimension: `dimname'")
	putdocx paragraph
    putdocx text ("List of items: `varlist'")
	putdocx paragraph
    putdocx text ("Date: $S_DATE, $S_TIME")
	putdocx paragraph
	local model Partial Credit Model (PCM)
	if "`rsm'"!="" {
	   local model Rating Scale Model (RSM)
	}
	putdocx text ("Model: `model'")
	putdocx paragraph
	putdocx text ("Marginal log-likelihood: `ll'")

	putdocx paragraph, style(Subtitle)
	putdocx text ("Estimation of the parameters") ,
	local paramname
	forvalues j=1/`nbitems' {
		forvalues k=1/`modamax' {
		     if `k'<=`modamax`j'' {
			     local paramname `paramname' "``j''_`k'"
			 }
	    }
	}
	*di "matrix colnames `diff'=`paramname'"
	matrix rownames `diff'=`paramname'
    putdocx table table1 = matrix(`diff') , nformat(%9.3f) rownames colnames  border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil) headerrow(1)  halign(center)
    putdocx table table1(.,1), halign(left)
    putdocx table table1(.,2/7), halign(right)
    putdocx table table1(1,.), halign(right) border(top) border(bottom)


	qui putdocx table table2 = matrix(`covariates') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)  headerrow(1)
    putdocx table table2(.,1), halign(left)
    putdocx table table2(.,2/7), halign(right)
    putdocx table table2(1,.), halign(right) border(top) border(bottom)




	putdocx paragraph,style(Subtitle)
	putdocx text ("Fit indexes for items") , /*bold underline font(,14) smallcaps*/
	qui putdocx table table3 = matrix(`fit') , nformat(%9.3f) rownames colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)    headerrow(1)
    putdocx table table3(.,1), halign(left)
    putdocx table table3(.,2/5), halign(right)
    putdocx table table3(1,.), halign(right) border(top) border(bottom)



	putdocx paragraph, style(Subtitle)
	putdocx text ("Estimation per group/score")
	*putdocx text ("Estimation per group/score") , bold underline font(,14) smallcaps
	*set trace on
	putdocx table tbl = (`=`nbrowmat'+1',7), border(all,nil) width(7) halign(center) note(EAP: Expected A Posteriori ; BE: Best Estimates) headerrow(1)
    putdocx table tbl(1,.), halign(right) border(top) border(bottom)
	putdocx table tbl(1,1) = ("Group"), halign(right)
	putdocx table tbl(1,2) = ("score"), halign(right)
	putdocx table tbl(1,3) = ("Frequency"), halign(right)
	putdocx table tbl(1,4) = ("EAP Mean"), halign(right)
	putdocx table tbl(1,5) = ("EAP s.e."), halign(right)
	putdocx table tbl(1,6) = ("Exp score"), halign(right)
	putdocx table tbl(1,7) = ("BE Mean"), halign(right)
	local fin=1
	forvalues row=1/`nbrowmat' {
	    local row2=`row'+1
		local g: di %9.0f `matgroupscorelt'[`row',1]
		local gh=`matgroupscorelt'[`row',1]
		if `fin'==1 {
			putdocx table tbl(`row2',1) = ("`g'"), halign(right)
		}
		if `matgroupscorelt'[`row',2]!=.|`matgroupscorelt'[`row',7]==. {
		    local s: di %9.0f `matgroupscorelt'[`row',2]
			local fin=0
		}
		else {
			local s "`scoremin`gh''/`scoremax`gh''"
			local fin=1
			*local fin "border(top) border(bottom)"
			*di "c'est la fin"
			putdocx table tbl(`row2',.),  border(bottom) border(top, dashed)
			putdocx table tbl(`row2',1), border(top, nil)
		}
		local eff: di %9.0f `matgroupscorelt'[`row',3]
		local lt: di %9.3f `matgroupscorelt'[`row',4]
		local se: di %9.3f `matgroupscorelt'[`row',5]
		local exp: di %9.2f `matgroupscorelt'[`row',6]
		local clt: di %9.3f `matgroupscorelt'[`row',7]
		*putdocx table tbl(`row',.), addrows(7)
		putdocx table tbl(`row2',2) = ("`s'"), halign(right)
		putdocx table tbl(`row2',3) = ("`eff'"), halign(right)
		putdocx table tbl(`row2',4) = ("`lt'"), halign(right)
		putdocx table tbl(`row2',5) = ("`se'"), halign(right)
		putdocx table tbl(`row2',6) = ("`exp'"), halign(right)
		putdocx table tbl(`row2',7) = ("`clt'"), halign(right)

	}

/*
		qui matrix `matgroupscorelt'[`row',1]=`g'
		*qui matrix `matgroupscorelt'[`row',2]="`scoremin`g''/`scoremax`g''"
		qui matrix `matgroupscorelt'[`row',3]=`eff`g''
		qui matrix `matgroupscorelt'[`row',4]=`lt`g''
		qui matrix `matgroupscorelt'[`row',5]=`se'
		*qui matrix `matgroupscorelt'[`row',6]=`exp'
		qui matrix `matgroupscorelt'[`row',7]=`clt`g''
		local ++row
	}
	local nbrowmat=`row'-1


local row 1
local vari 1
foreach x in gear_ratio turn foreign _cons {
putdocx table tbl5(`row',.), addrows(2)
local b: display %9.3f rtable[`vari',1]
local se: display %9.3f rtable[`vari',2]
local ++vari
local ++row
putdocx table tbl5(`row',1) = ("`x'"), halign(right)
putdocx table tbl5(`row',2) = ("`b'"), halign(right)
local ++row
local se = strtrim("`se'")
putdocx table tbl5(`row',2) = ("(`se')"), halign(right)
}*/

	*qui putdocx table tablename = matrix(`matgroupscorelt') , nformat(%9.3f) /*rownames*/ colnames border(start, nil) border(insideH, nil) border(insideV, nil) border(end, nil)
	local extension png
}

/*************************************************************************************************************
SAUVEGARDE DES GRAPHIQUES
*************************************************************************************************************/
*set trace on
if "`filesave'"!="" {
    if "`graphs'"!="" {
		if "`docx'"!="" {
		    putdocx pagebreak
				putdocx paragraph, style(Subtitle)
				putdocx text ("General Graphs")
		}
		foreach i in TCC TCCeo TIC IIC map {
			if "`extension'"!="" {
			    qui graph export "`dirsave'//`i'.`extension'", replace name(`i')
            }
			*graph display `i'
			*qui graph save "`dirsave'//`i'", replace
			if "`docx'"!="" {
			    putdocx paragraph
			    putdocx image "`dirsave'//`i'.png", height(10cm)
			}
		}
	    *discard
		if "`graphitems'"=="" {
			putdocx paragraph, style(Subtitle)
			putdocx text ("Graphs per item")
			forvalues i=1/`nbitems' {
				if "`docx'"!="" {
					putdocx paragraph, style(Heading1)
				    putdocx text ("Graphs for ``i''")
				}
				foreach j in CCC ICC residuals {
					*graph display `j'``i''
					*qui graph save "`dirsave'//`j'_``i''", replace

	 			    if "`extension'"!="" {
					    qui graph export "`dirsave'//`j'_``i''.`extension'", replace name(`j'``i'')
					}
					if "`docx'"!="" {
						putdocx paragraph
						putdocx image "`dirsave'//`j'_``i''.png" , height(10cm)
					}
				}
			}
		}
	}
}
if "`docx'"!="" {
    putdocx save "`dirsave'//`docx'.docx", replace
}


/*************************************************************************************************************
RETURNS
*************************************************************************************************************/

*set trace on

matrix colnames `diff'="Estimate" "Std err" "z" "p" "lb" "ul"
matrix colnames `covariates'=Estimate s.e. z p lb ul
matrix rownames `diff'=`diffname'
*matrix list `diff'
matrix rownames `covariates'=Variance `continuous' `catname'
return matrix difficulties=`diff'
return matrix covariates=`covariates'
return matrix matscorelt=`matscorelt'
return matrix matgroupscorelt=`matgroupscorelt'
return matrix bestest=`bestest'
capture restore, not
end