# Convert the main image 
		for y in range(nYTiles):
			for x in range(nXTiles):
				writer.setResolution(0);
				# The x and y coordinates for the current tile
				tileX = x * tileSizeX;
				tileY = y * tileSizeY;
				effTileSizeX = tileSizeX
				if (tileX + tileSizeX) >= width:
					effTileSizeX = width - tileX
				effTileSizeY = tileSizeY
				if (tileY + tileSizeY) >= height:
					effTileSizeY = height - tileY
				# Read tiles from the input file and write them to the output OME-Tiff
				buf = reader.openBytes(image, tileX, tileY, effTileSizeX, effTileSizeY)
				writer.saveBytes(image, buf, tileX, tileY, effTileSizeX, effTileSizeY)

		# Create the downsampled resolutions and write to output
		for i in range(resolutions):
			currentScale = int(Math.pow(scale, i + 1))
			writer.setResolution(i + 1)
			resolutionWidth = width / currentScale
			resolutionHeight = height / currentScale
			nXTiles = int(math.floor(resolutionWidth / tileSizeX))
			nYTiles = int(math.floor(resolutionHeight / tileSizeY))
			if nXTiles * tileSizeX != resolutionWidth:
				nXTiles = nXTiles + 1
			if nYTiles * tileSizeY != resolutionHeight:
				nYTiles = nYTiles + 1
			for y in range(nYTiles):
	## Outputs each stitched z plane as a separate file
	iReader = ImageReader()
	iReader.setId(parentLSMFilePath)
	for z in range(max_coords[2]+basic_info[4]):
	## for z in range(50,51):
		IJ.showStatus("z: "+str(z+1)+" of "+str(max_coords[2]+basic_info[4]))
		chIps = []
		resImages = []
		for ch in range(basic_info[0]):
			chIps.append(ByteProcessor(max_coords[0]+scale_info[2],max_coords[1]+scale_info[2]))
		for ch in range(basic_info[0]):
			resImages.append(ImagePlus("ch"+str(ch+1),chIps[ch]))
		for se in range(basic_info[1]):
			IJ.showProgress(se,basic_info[1])
			if z >= coords_upscaled[se][2] and z <= coords_upscaled[se][2]+basic_info[4]-1:
				iReader.setSeries(se)
				for ch in range(basic_info[0]):
					byteArray = iReader.openBytes((z-coords_upscaled[se][2])*basic_info[0]+ch)
					testIp = ByteProcessor(scale_info[2],scale_info[2],byteArray)
					testImage = ImagePlus("tester",testIp)
					Image_stamper.stampStack(testImage,resImages[ch],coords_upscaled[se][0],coords_upscaled[se][1],0)			
					activeIp = chIps[ch]
					testImage.close()
					
					
		for ch in range(len(resImages)):
			IJ.saveAsTiff(resImages[ch],parentLSMFilePath+"_tiles/v_img/img_z_"+str(z+1)+"_c_"+str(ch+1)+".tif")
		#outPlaneImage = RGBStackMerge.mergeChannels(resImages,False)
		#IJ.saveAsTiff(outPlaneImage,parentLSMFilePath+"_tiles/v_img/img_z_"+str(z+1)+".tif")
		#outPlaneImage.close()
reader.setId(file)

# setup resolutions
for i in range(resolutions):
    divScale = Math.pow(scale, i + 1)
    omeMeta.setResolutionSizeX(PositiveInteger(int(reader.getSizeX() / divScale)), 0, i + 1)
    omeMeta.setResolutionSizeY(PositiveInteger(int(reader.getSizeY() / divScale)), 0, i + 1)

# setup writer
writer = OMETiffWriter()
writer.setMetadataRetrieve(omeMeta)
writer.setId(outFile)
type = reader.getPixelType()

# read and write main image
img = reader.openBytes(0)
writer.saveBytes(0, img)

# create ImageScaler for downsampling
scaler = SimpleImageScaler()

# generate downsampled resolutions and write to output
for i in range(resolutions):
    writer.setResolution(i + 1)
    x = omeMeta.getResolutionSizeX(0, i + 1).getValue()
    y = omeMeta.getResolutionSizeY(0, i + 1).getValue()
    downsample = scaler.downsample(img, reader.getSizeX(), reader.getSizeY(), Math.pow(scale, i + 1),
         FormatTools.getBytesPerPixel(type), reader.isLittleEndian(),
         FormatTools.isFloatingPoint(type), reader.getRGBChannelCount(),
         reader.isInterleaved())
    writer.saveBytes(0, downsample)
for series in range(reader.getSeriesCount()):
    reader.setSeries(series)
    writer.setSeries(series)

    # convert each image in the current series
    for image in range(reader.getImageCount()):
        width = reader.getSizeX()
        height = reader.getSizeY()

        # Determined the number of tiles to read and write
        nXTiles = int(math.floor(width / tileSizeX))
        nYTiles = int(math.floor(height / tileSizeY))
        if nXTiles * tileSizeX != width:
            nXTiles = nXTiles + 1
        if nYTiles * tileSizeY != height:
            nYTiles = nYTiles + 1
        for y in range(nYTiles):
            for x in range(nXTiles):
                # The x and y coordinates for the current tile
                tileX = x * tileSizeX
                tileY = y * tileSizeY
                # Read tiles from the input file and write them to the output OME-Tiff
                buf = reader.openBytes(image, tileX, tileY, tileSizeX,
                                       tileSizeY)
                writer.saveBytes(image, buf, tileX, tileY, tileSizeX,
                                 tileSizeY)

# close reader and writer
writer.close()
reader.close()
IJ.log("Done")