proc spikeout() {local i, rank  localobj f				// Write out a spike raster (cell, spike time)
	pc.barrier()									// Wait for all ranks to get to this point
	sprint(cmd,"./results/%s/spikeraster.dat", RunName)
	f = new File(cmd)
	if (pc.id == 0) { 								// Write header to file 1 time only
		f.wopen()
		f.close()
	}
	
	for rank = 0, pc.nhost-1 {				// For each processor, allow processor to append to file the spike times of its cells
		if (rank == pc.id) {				// Ensure that each processor runs once
			f.aopen() 						// Open for appending to file
			for i=0, pnm.idvec.size-1 {
				f.printf("%.3f %d\n", pnm.spikevec.x[i], pnm.idvec.x[i])	// Print the spike time and spiking cell gid
			}
			f.close()
		}
		pc.barrier()
	}
}

proc spikeoutfast() {local i  localobj f				// Write out a spike raster quickly in parallel (cell, spike time)
	sprint(cmd,"./results/%s/spikeraster_%g.dat", RunName, pc.id)
	f = new File(cmd)
	f.wopen()
	for i=0, pnm.idvec.size-1 {
		f.printf("%.3f %d\n", pnm.spikevec.x[i], pnm.idvec.x[i])	// Print the spike time and spiking cell gid
	}
	f.close()

	
	g=1
	if (CatFlag==1) {
		pc.barrier()
		while (pc.nhost>g) {
			g=g*2
			if ((pc.id/g - int(pc.id/g))==0.5) {
				sprint(dircmd,"cat ./results/%s/spikeraster_%g.dat >> ./results/%s/spikeraster_%g.dat", RunName, pc.id, RunName, int(pc.id-g/2))
				{system(dircmd, direx)}			
				sprint(dircmd,"rm ./results/%s/spikeraster_%g.dat", RunName, pc.id)
				{system(dircmd, direx)}			
			}
			pc.barrier()
		}
	}
	pc.barrier()
	if (pc.id==0) {
		if (CatFlag==1) {		
			sprint(dircmd,"cat ./results/%s/spikeraster_0.dat >> ./results/%s/spikeraster.dat", RunName, RunName)
			{system(dircmd, direx)}		
			sprint(dircmd,"rm ./results/%s/spikeraster_%g.dat", RunName, pc.id)
			{system(dircmd, direx)}	
		}	
	}
}

proc sumnumout() {local alltime, allct, allspk localobj f
	allct = pc.allreduce(nclist.count,1)
	allspk = pc.allreduce(pnm.idvec.size,1)
	comptime = pc.step_time
	avgcomp = pc.allreduce(comptime, 1)/pc.nhost
	maxcomp = pc.allreduce(comptime, 2)
	loadbal=1
	exchtime=0
	if (maxcomp>0) {
		loadbal=avgcomp/maxcomp
		exchtime= $1 - maxcomp
	}

	if (pc.id == 0) { 								// Write header to file 1 time only
		alltime = startsw() - loadstart
		sprint(cmd,"./results/%s/sumnumout.txt", RunName)
		f = new File(cmd)
		f.wopen()
		f.printf("NumCells = %g;\nNumSpikes = %g;\nNumConnections = %g;\nRunTime = %g;\nNumCellTypes = %g;\nLoadBalResult = %g;\nExchangeResult = %g;\n", ncell, allspk, allct, alltime, numCellTypes, loadbal, exchtime)	// Print the spike time and spiking cell gid
		f.close()
	}
}

proc timeout() {local i, rank, gid, srcid localobj tgt, f, cell// Write out runtimes for each processor
	pc.barrier()					// Wait for all ranks to get to this point
	sprint(cmd,"./results/%s/runtimes.dat", RunName)
	f = new File(cmd)
	if (pc.id == 0) { 				// Write header to file 1 time only
		f.wopen()
		f.printf("host\tset up\tcreated cells\tconnected cells\tran simulation\t\n")
		f.close()
	}
	
	for rank = 0, pc.nhost-1 {				// For each processor, allow processor to append its runtimes to file
		if (rank == pc.id) {				// Ensure that each processor runs once
			f.aopen() 						// Open for appending to file
			f.printf("%g\t%g\t%g\t%g\t%g\n", pc.id, loadtime, createtime, connecttime, runtime)
			f.close()
		}
		pc.barrier()
	}
}

proc highIndexout() {local i, ij, gid localobj cell
	pc.barrier()					// Wait for all ranks to get to this point
	sprint(cmd,"./results/%s/MaxHighIndex.txt", RunName)
	f = new File(cmd)
	
	perRankmax=0
	for j = 0, numCellTypes-1 {
		if (cellType[j].LastHighIndex>perRankmax) {
			perRankmax=cellType[j].LastHighIndex
		}
	}
	maxconn = pc.allreduce(perRankmax, 2)
	
	perRankmax=0
	for pcitr(&i, &ij, &gid, 0, ncell) {	
		if (pc.gid_exists(gid)) {
			cell = pc.gid2cell(gid)
			if (ransynlist.object(cell.randi).seq()>perRankmax) {
				perRankmax=ransynlist.object(cell.randi).seq()
			}	
		}
	}
	maxsyn = pc.allreduce(perRankmax, 2)
	
	perRankmax=0
	for pcitr(&i, &ij, &gid, 0, ncell) {	
		if (pc.gid_exists(gid)) {
			cell = pc.gid2cell(gid)
			if (ransynlist.object(cell.randi).seq()>perRankmax) {
				perRankmax=ranstimlist.object(cell.randi).seq()
			}	
		}
	}
	maxstim = pc.allreduce(perRankmax, 2)
	
	if (pc.id == 0) { 				// Write header to file 1 time only
		f.wopen()
		f.printf("connection_highIndex=%f;\nsynapse_highIndex=%f;\nstimulation_highIndex=%f;\n",maxconn,maxsyn,maxstim)
		f.close()
	}
}



objref spkhist, f4
strdef cmd
proc setupSpikeHistogram() {
	spkhist = new Vector(pc.nhost)
	if (pc.id==0) {
		pc.max_histogram(spkhist)
	}
}

proc printSpikeHistogram() {
	sprint(cmd,"./results/%s/spkhist.dat", RunName)
	f4 = new File(cmd)
	f4.wopen()

			// Open for appending to file
	for i=0, pc.nhost-1 {
		f4.printf("%d\t%d\n", i, spkhist.x[i])	// Print the spike time and spiking cell gid
	}
	f4.close()
}