/*
 *
 * A neuroConstruct helper file of some simple utilities for checking the
 * morphologies of cells loaded into NEURON
 *
 * Some of these functions provide GENESIS like output, for comparing models in each simulator
 * Some functions need a little more tweaking
 *
 */

objectvar nil


/*
 * Provides information on the morphology of the current accessed section
 */
proc morph() {

    totalarea = 0
    print "Currently addressed section: ", secname()
    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
    print "+    Number of 3D info points: ", n3d()

    for i=0,n3d()-1{

		delx = x3d(i)-lastx
		dely = y3d(i)-lasty
		delz = z3d(i)-lastz
		len = sqrt((delx*delx)+(dely*dely)+(delz*delz))

		if (i==0){
			delx = dely = delz = len = 0
		}

		 print "+ ", secname(), " ", i, ": (", x3d(i), ", ", y3d(i), ", ", z3d(i),") diam: ", diam3d(i), "  del: (", delx,", ", dely,", ", delz,")  len: ", len
		
		lastx = x3d(i)
		lasty = y3d(i)
		lastz = z3d(i)

	}

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    print "+    Number of segments (nseg): ", nseg

    for i=0,nseg+1{
        print "+ ", secname(), " ", i/(nseg+1), " diam: ", diam((i/(nseg+1))), " area: ", area((i/(nseg+1))), " um^2"
        totalarea = totalarea + area((i/(nseg+1)))
    }
    print "+    Total area: ", totalarea

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
    print ""
}



/*
 * Provides information on the total area, etc.
 * Useful as a simple test for comparing cells
 */
proc areainfo(){

    totalnum = 0
    totalarea = 0

    forall totalnum = totalnum +1

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    print "+"
    forall {

        totalsecarea = 0

        for i=0,n3d()-1 print "+ ", secname(), " ", i, ": (", x3d(i), ", ", y3d(i), ", ", z3d(i), ") diam: ", diam3d(i)

        for i=0,nseg+1{
            //print "+ ", secname(), " ", i/(nseg+1), " diam: ", diam((i/(nseg+1))), " area: ", area((i/(nseg+1))), " um^2"
            totalsecarea = totalsecarea + area((i/(nseg+1)))
        }
        print "+    Total section area in ",secname(), ": ", totalsecarea

        totalarea = totalarea + totalsecarea
    }

    print "+"
    print "+    Number of sections: ", totalnum
    print "+    Total all sections: ", totalarea, " um^2"
    print "+    Total all sections: ", totalarea/(1000000*1000000), " m^2"
    print "+    Total all sections: ", totalarea/(10000*10000), " cm^2"

    print "+"

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
}


/*
 * Prints voltage of all of the created compartments
 */
proc allv(){

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    forall {
        if (nseg ==1) {
            print secname(), ": ", v
        } else {
            print secname(), " (nseg = ",nseg,"): "
            for i=0,nseg+1{
                strdef ind
                sprint(ind, "    %f: ", (i/(nseg+1)))

                print ind, "\t\t ", v((i/(nseg+1)))
            }
    
        }
    }

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

}

/*
 * Prints ca conc of all of the created compartments
 */
proc allca(){

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    forall {
        if (ismembrane("ca_ion")) {
            if (nseg ==1) {
                print secname(), ": ", cai
            } else {
                print secname(), " (nseg = ",nseg,"): "
                for i=0,nseg+1{
                    strdef ind
                    sprint(ind, "    %f: ", (i/(nseg+1)))
                    print ind, "\t\t ", cai((i/(nseg+1)))
                }
        
            }
        }
    }

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

}

/*
 * Prints info on network connections
 */
proc allsyns() {
    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    for i=0,allCells.count()-1 {

        allCells.o[i].netInfo()

    }

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

}



/*
 * Prints info on all cells
 */
proc allcells() {
    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    for i=0,allCells.count()-1 {
        allCells.o[i].toString()
    }

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

}

/*
 * Provides information on the current section similar to that produced
 * with "showfield *" in GENESIS
 */
proc gen() {

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    totalarea = 0
    totalRa = 0


    print ""
    print secname()
    print ""
    print "Voltage        = ", v

    for i=0,nseg+1{

        thisPoint = i/(nseg+1)
        nextPoint = (i+1)/(nseg+1)
        halfWay = thisPoint


        areaHere = area(halfWay)

        RaHere = ri(halfWay)

        print "  - Section from ", thisPoint, " to ", nextPoint, ", area: ", areaHere

        print "    Ra to end of this length = ", RaHere*1000, " ohm"


        totalarea = totalarea + areaHere
        if (i>0){
            totalRa = totalRa + RaHere
        }
    }

    print "Total area     = ", totalarea
    print "Total Ra     = ", totalRa*1000 , " ohm"


    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

}




/*
 * Provides information on the current section, like an expanded psection()
 */
proc secinfo() {

    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

    totalarea = 0
    totalRa = 0


    print ""
    print secname()
    print ""
    print "Voltage        = ", v
    print "nseg = ", nseg


    for i=1,nseg+1{

        thisPoint = i/(nseg+1)
        nextPoint = (i+1)/(nseg+1)
        halfWay = thisPoint


        areaHere = area(halfWay)

        RaHere = ri(halfWay)

        print "  - Section from ", thisPoint, ", to ", nextPoint, ", area: ", areaHere

        print "    Ra             = ", RaHere*1000, " ohm"


        totalarea = totalarea + areaHere
        totalRa = totalRa + RaHere
    }

    print "Total area     = ", totalarea
    print "Total Ra     = ", totalRa*1000 , " ohm (Note that this doesn't have any physical meaning)"


    print "++++++++++++++++++++++++++++++++++++++++++++++++++++++++"

}


objectvar listNcSyn
objectvar listNcPre


proc netConnInfo() {
    netConInfo()
}

/*
 * Helper functions for getting more info on NetConn objects
 */
proc netConInfo() {

    
    print "-- ",hostid,"---------------------------------------------------------"
    print "-- ",hostid,"-- NetConn: ", $o1
    if ($o1!=nil) {
        print "-- ",hostid,"-- Pre: ",$o1.precell(),", Syn: ",$o1.syn,"(",$o1.postcell, ")", ", Active: ",$o1.active(),", Valid: ",$o1.valid()
        /*
        // Doesn't seem to work with section in template... 
        if ($o1.precell()!=nil) { 
            print "-- ",hostid,"-- From: ", $o1.precell().toString()
            loc = $o1.preloc()
            print "-- ",hostid,"-- Section: ", secname(), " - ", loc
            pop_section()

        }*/
        if ($o1.postcell()!=nil) { print "-- ",hostid,"-- To: ", $o1.postcell().toString() }
        print "-- ",hostid,"-- Weight: ",$o1.weight, ", Delay: ",$o1.delay, ", Thresh: ",$o1.threshold

        listNcSyn = $o1.synlist()

        for i=0,listNcSyn.count()-1 {
            print "-- ",hostid,"-- NetConns sharing syn: ", listNcSyn.o(i)
        }      
  
        listNcPre = $o1.precelllist()

        for i=0,listNcPre.count()-1 {
            print "-- ",hostid,"-- NetConns sharing pre cell: ", listNcPre.o(i)
        }
    }

    print "-- ",hostid,"---------------------------------------------------------"
}

proc netConInfoParallel() {
    netConInfo($o1)
    if ($o1!=nil) {
        print "-- ",hostid,"----------------------- Src gid: ", $o1.srcgid
    }
    print " "
}


// Some utilities for automating testing of generated NEURON

numTestsPassed = 0
numTestsFailed = 0


proc testEquals() {

	if ($1 != $2) { 
		print "Test failed: ", $1, "  != ", $2
		numTestsFailed = numTestsFailed + 1
	} else {
		numTestsPassed = numTestsPassed + 1
	}

}


objref testResultFile

proc createTestReport() {

    print "------------------------------------------------------------------------------"

    print "    Finished tests. Number of passed tests: ", numTestsPassed, ", number of failed tests: ", numTestsFailed

    {testResultFile = new File()}

    if(numTestsFailed == 0) {
        testResultFile.wopen("passed")
    } else {
        testResultFile.wopen("failed")
    }

    {testResultFile.printf("numPassed=%g\n", numTestsPassed)}
    {testResultFile.printf("numFailed=%g\n", numTestsFailed)}

    {testResultFile.close()}


    print "------------------------------------------------------------------------------"

}