/**
	\file POP_READ_WRITE.c
	\author ken.johnson@asu.edu

	Read and write a file for the data challenge.

	This provides a simple example to implement in your code. It assumes that
	all of the files are in the current working directory. You must have
	the zip files, POP_BHAR_09AUG06.zip and POP_materials.zip unzipped in your
	current working directory for this code to execute.

	compiled using
		gcc POP_READ_WRITE.c -o POP_READ_WRITE

	can be executed by
		./POP_READ_WRITE
**/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

#define get3(__foo,_dim,_i,_j,_k)   	((__foo)[_i+_dim[0]*(_j+_dim[1]*(_k))])
#define get4(__foo,_dim,_i,_j,_k,_l)	((__foo)[_i+_dim[0]*(_j+_dim[1]*(_k+_dim[2]*(_l)))])
#define get5(__foo,_dim,_i,_j,_k,_l,_m)	((__foo)[_i+_dim[0]*(_j+_dim[1]*(_k+_dim[2]*(_l+_m*_dim[3])))])
/**
	\author ken.johnson@asu.edu

	Reads the data for the challenge
**/
float *reader (char *filename, unsigned long num_elements)	{
	FILE *file;
	float *data = NULL;
	unsigned long check;
	unsigned long fileLength;

	// allocate memory for the data
	data = (float *) malloc (num_elements * sizeof(float));
	assert (data != NULL);

	// open the file
	file = fopen (filename, "rb");
	assert (file != NULL);

	// check that the file size matches how much we want to read
	fseek (file, 0, SEEK_END);
	fileLength = ftell (file);
	assert( fileLength == num_elements * sizeof(float));
	fseek (file, 0, SEEK_SET);

	// read the data
	check = fread(data, sizeof(float), num_elements, file);
	assert (check == num_elements);

	return data;
}
/**
	\author ken.johnson@asu.edu

	Writes the data for the challenge
**/
void writer (char *filename, float *data, unsigned long num_elements)	{
	FILE *file;
	unsigned long check;

	// open the file
	file = fopen (filename, "wb");
	assert (file != NULL);

	// write the data
	check = fwrite(data, sizeof(float), num_elements, file);
	assert (check == num_elements);
}

int main ()	{
	int dim[4] = {2, 2000, 4000, 8}; // data dimension sizes
	int codim[3] = {3, 2000, 4000}; // coordinate dimension sizes
	int b1dim[5] = {2, 80, 80, 55, 8}; // b1map dimension sizes
	unsigned long size;
	float *data = NULL;
	float *coords = NULL;
	float *b1map = NULL;
	int i;

	size = dim[0] * dim[1] * dim[2] * dim[3];
	data = reader ("POP_BHAR_09AUG06.dat", size);

	size = codim[0] * codim[1] * codim[2];
	coords = reader ("POP_BHAR_09AUG06.crd", size);

	size = b1dim[0] * b1dim[1] * b1dim[2] * b1dim[3] * b1dim[4];
	b1map = reader ("POP_B1MAP80x80x55x8.dat", size);

	// print out sample of the coil sensitivity
	// (real part of the center line of the fourth coil)
	for (i=0; i<b1dim[1]; i++)	{
		printf("%f\n", get5(b1map, b1dim, 0, i, 40, 28, 3));
	}

	// write the coil sensitivity back out
	//size = b1dim[0] * b1dim[1] * b1dim[2] * b1dim[3] * b1dim[4];
	//writer ("b1copy.dat", b1map, size);

	// deallocate the arrays
	free (data);
	data = NULL;
	free (coords);
	coords = NULL;
	free (b1map);
	b1map = NULL;

	return 0;
}
