/* Parses a cell specification file implemented as a hoc template.
   It is assumed that dendritic sections are named "dend[n]".  If the global
   flag_spines is set to 1, then any explicit spines (whose names match the
   pattern "spine[n]") are counted on each section, and then used to adjust the
   section's length and diameter according to the normalization procedure
   discussed in Guy Major's PhD thesis.
     Regardless of the setting of flag_spines, all explicit spines are then
   deleted, and tree properties set according to the passive properties
   defined at the top of this file.

   Arguments:
     $1: the index of the cell to read.
 */

/* Passive properties.  These are mapped to NEURON's definitions of the
   same properties below.  */
/*  The values we used in the study */
//CM=0.89 // average of Hanbing's WTD1 result.
RM=1/G_PAS
RA=100	// used by default for Wolf, Evans MSN studies

/* Traub values 
 * CM = 0.9
 * RM = 50000
 * RA = 250
 */

//G_PAS=1/RM


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

	find_totLen_byDist()

	DEPRECATED.  Use find_totLen() below instead.

	May 2012, cmw

	Does NOT calculate the total length accurately.  It misses half a section 
	length, equal to L/(2*nseg).  The find_totLen() function below calculates it 
	properly.  This code is kept here as legacy.

************************************************************************************/
func find_totLen_byDist() {  local p_prLen, p_totLen, m_prLen, m_totLen, prxCut, lastX

    prxCut = $1

    printf("\tProximal < %g um\n",prxCut)
    soma { distance() }

    p_prLen = 0
    p_totLen = 0
    m_prLen = 0
    m_totLen = 0

//printf("PROXIMAL\n")
    forsec proximal {
        p_totLen += L
	if( distance(1) < prxCut ) {
	    p_prLen += L
	    //printf("%s: **** 0 (%g) - 1 (%g):  prL %g\n",secname(),distance(0),distance(1),p_prLen)
        }
	if( distance(0) < prxCut  && distance(1) > prxCut ) {
            lastX = 0
            for(x) {
	        if( distance(x) < prxCut ) lastX = x
            }
            p_prLen += distance(lastX)-distance(0)
	    //printf("%s: ---- 0 (%g) - %g (%g) - 1 (%g):  prL %g\n",secname(),distance(0),lastX,distance(lastX),distance(1),p_prLen)
        }
        
    }

//printf("MIDDEND\n")
    forsec middend {
        m_totLen += L
	if( distance(1) < prxCut ) {
	    m_prLen += L
	    //printf("%s: **** 0 (%g) - 1 (%g):  prL %g\n",secname(),distance(0),distance(1),m_prLen)
        }
	if( distance(0) < prxCut  && distance(1) > prxCut ) {
            lastX = 0
            for(x) {
	        if( distance(x) < prxCut ) lastX = x
            }
            m_prLen += distance(lastX)-distance(0)
	    printf("%s: ---- 0 (%g) - lastX = %g (%g) - 1 (%g):  prL %g\n",secname(),distance(0),lastX,distance(lastX),distance(1),m_prLen)
        }
        
    }

    printf("Soma\t%g\n",soma.L)
    printf("Proximal\n\tprox\t%g\n\tdist\t%g\n\ttotl\t%g\n",p_prLen,p_totLen-p_prLen,p_totLen)
    printf("Middend\n\tprox\t%g\n\tdist\t%g\n\ttotl\t%g\n",m_prLen,m_totLen-m_prLen,m_totLen)

    return p_prLen + m_prLen + soma.L
}




func find_totLen() {  local prLen, totLen, prxCut, lastX, dstChg, LChg, prDistLen

    prxCut = $1

    //printf("\tProximal < %g um\n",prxCut)
    soma { distance() }

    prLen = 0
    totLen = 0


    forsec "soma" { 
	for(x) {
	    if( x==0 || x == 1 ) continue
	    Lcnt += L / nseg

	}
    }
    prLen = Lcnt
    totLen = Lcnt

    forsec dendritic {
	lastX = 0
	LChg = 0
	for(x) {
	    if( x==0 || x==1 ) continue
	    totLen += L / nseg
	    if( distance(x) > prxCut ) { 
	        continue 
	    }
	    //lastX = x
	    LChg += (L / nseg)
    	}
	prLen += LChg

        /****
	if( distance(0) < prxCut  && distance(1) > prxCut ) {
 	    dstChg = distance(lastX)-distance(0)
	    printf("%s: [L %g / nseg %d = %g; half = %g] ---- 0 (%g) - last X = %g (%g) - 1 (%g):  dstL %g\tLChg %g\tDIFF %g\n",secname(),L,nseg, L/nseg,L/(2*nseg),distance(0),lastX,distance(lastX),distance(1),dstChg,LChg,dstChg-LChg)
	}
	****/
    }


    printf("Total length, including soma (computed with L/nseg):\n\tprox\t%g\ndist\t%g\ntotal\t%g\n",prLen,totLen-prLen,totLen)

    return prLen
}




func find_totProxLen() {  local prLen, totLen, prxCut, lastX, dstChg, LChg, prDistLen

    prxCut = $1

    soma { distance() }

    prLen = 0
    totLen = 0

    forsec "soma" { 
	for(x) {
	    if( x==0 || x == 1 ) continue
	    Lcnt += L / nseg

	}
    }
    prLen = Lcnt
    totLen = Lcnt

    forsec proximal {
	lastX = 0
	LChg = 0
	for(x) {
	    if( x==0 || x==1 ) continue
	    totLen += L / nseg
	    if( distance(x) > prxCut ) { 
	        continue 
	    }
	    //lastX = x
	    LChg += (L / nseg)
    	}
	prLen += LChg

    }


    printf("Total proximal length, including soma (computed with L/nseg):\n\tprox\t%g\ndist\t%g\ntotal\t%g\n",prLen,totLen-prLen,totLen)

    return prLen
}


func find_totMiddLen() {  local prLen, totLen, prxCut, lastX, dstChg, LChg, prDistLen

    prxCut = $1

    soma { distance() }

    prLen = 0
    totLen = 0

    forsec "soma" { 
	for(x) {
	    if( x==0 || x == 1 ) continue
	    Lcnt += L / nseg

	}
    }
    prLen = Lcnt
    totLen = Lcnt

    forsec middend {
	lastX = 0
	LChg = 0
	for(x) {
	    if( x==0 || x==1 ) continue
	    totLen += L / nseg
	    if( distance(x) > prxCut ) { 
	        continue 
	    }
	    //lastX = x
	    LChg += (L / nseg)
    	}
	prLen += LChg

    }


    printf("Total middend length, including soma (computed with L/nseg):\n\tprox\t%g\ndist\t%g\ntotal\t%g\n",prLen,totLen-prLen,totLen)

    return prLen
}