
#include <stdio.h>
#include <direct.h>

/* This is Russ Bowers' program for batch conversion of Bruker 1r binary format data files into ascii text, dfp input, or Igor Pro files. */
/* This program converts from little endian to big endian format after reading the binary 1r file. */
/* Ability to decimate the spectrum is provided e.g. go from 16k to 1k  */
/* The program reads the procs and acqus files to obtain the spectral width, number of points, and temperature */
/* bruk2igor should be executed in the same folder as the list.txt file (without any command line argument) */
/* or alternatively, folder containing the "list.txt" can be specified as a command line argument to bruk2igor */
/* Use the command unix find . -name "1r" > list.txt  to create the list of files */
/* You can edit this file to delete filenames of spectra you do not wish to convert */


int main( int argc, char *argv[] )
{

FILE *fptr,*fout,*list;

int data[64000];
int i,j,k,l,pos,n,li,test,outform,interval,n_out;
char filename[128][256],outpath[256],outname[256],expname[256],expname_temp[256],series[256],procs_path[256],expdir[256],listname[256],acqs_path[256],filenum[256];
float sw,freq,dfreq,te,dt;
int npts;

if (argc==2) {
	sscanf(argv[1],"%s",expdir);
	strcpy(listname,expdir);
	strcat(listname,"/list.txt");
} else strcpy(listname,"list.txt");

list=fopen(listname,"r");
if (!list) {
	printf("no list.txt file found\n");
	exit(0);
}

li=0;
do {
	test=fscanf(list,"%s",filename[li++]);
} while (test==1);
li--;
fclose(list);



printf("program found %d 1r files listed in list.txt\n",li);
if (li==0) exit(0);

printf("\nenter output format [0=.txt, 1=.dfp, 2=.itx (igor)] > ");
scanf("%d",&outform);

/* make the output directory */

	i=0;
	do { 
		outpath[i]=filename[0][i];
		expname_temp[i]=filename[0][i]; }
	while (filename[0][i++]!='/');
	
	expname_temp[i-1]='\0';
	if (strlen(expname_temp)>4) { 
		for (l=0;l<5;l++) expname[l]=expname_temp[l];
		expname[5]='\0';
	} else strcpy(expname,expname_temp);

	outpath[i++]='\0';

	strcat(outpath,"fds");
	mkdir(outpath);

for (j=0;j<li;j++) {  /* LOOP OVER FILES */
	pos=strlen(filename[j]);
	strcpy(procs_path,"\0");
	strcpy(acqs_path,"\0");
	for (i=0;i<pos-2;i++) procs_path[i]=filename[j][i];
	procs_path[i]='\0';
	strncpy(acqs_path,procs_path,strlen(procs_path)-8);
	acqs_path[strlen(procs_path)-8]='\0';

	strcat(procs_path,"procs");
	strcat(acqs_path,"acqus");

	i=0; l=0;

	while (filename[0][i++]!='/');
//	strcpy(series,"/");
	strcpy(series,expname);
	strcat(series,"_");
	k=strlen(series);
	while (filename[j][i]!='/') {
		series[k++]=filename[j][i];
		filenum[l++]=filename[j][i];
		i++;
	}
	series[k]='\0';
	filenum[l]='\0';

	if (strncmp(filenum,"999",3)==0) {
		printf("warning: encountered 999 file in list.\n");
	}

	get_info(procs_path,&sw,&npts);
	get_TE(acqs_path,&te);

	if (j==0) {

		printf("enter point interval [1=every point] >");
		scanf("%d",&interval);
		n_out=npts/interval;
	}

	printf(" sw=%10.3e npts=%d TE=%f",sw,npts,te);

	if (npts>1) {
		freq=-sw/2.0;
		dfreq=sw/(npts-1);

//		dt=round_dt(sw);  /* convert dwell time to microseconds */
		dt=1.e6/sw;

		fptr=fopen(filename[j],"rb");

		if (!fptr) {
			printf("spectrum file %s not found\n",filename[j]);
			exit(0);
		}

		n=fread(&data[0],sizeof(int),npts,fptr);
		printf(" -> %d points read\n",n);
		fclose(fptr);


		
		if (outform==0) {
			strcpy(outname,outpath);
			strcat(outname,"/");
			strcat(outname,series);
			strcat(outname,".txt");
			fout=fopen(outname,"w");
			freq=-sw/2.0;
			for (i=0;i<npts;i+=interval) {
				fprintf(fout,"%f %d\n",freq,INT_little_endian_TO_big_endian(data[i]));
				freq+=interval*dfreq;
			}
			fclose(fout);
		} else if (outform==1) {
			strcpy(outname,outpath);
			strcat(outname,"/");
			strcat(outname,series);
			strcat(outname,".dfp");
			fout=fopen(outname,"w");
			fprintf(fout,"%d\n%-10.4f\n%s\n",n_out,dt,series);
			for (i=0;i<npts;i+=interval) fprintf(fout,"%d\n",INT_little_endian_TO_big_endian(data[i]));
			fclose(fout);
		} else if (outform==2) {
			if (j==0) {
				strcpy(outname,outpath);
				strcat(outname,"/");
				strcat(outname,expname);
				strcat(outname,".itx");
				fout=fopen(outname,"w");

				fprintf(fout,"IGOR\n");
				fprintf(fout,"WAVES/S/O f_%s\nBEGIN\n",expname);
				freq=-sw/2.0;
				for (i=0;i<npts;i+=interval) { fprintf(fout,"%10.2f\n",freq); freq+=interval*dfreq; }
				fprintf(fout,"END\n");
				fprintf(fout,"X SetScale x 0,0, \"Hz\", f_%s\; SetScale d 0,0, \"Hz\", f_%s\n",expname,expname);
			} else fout=fopen(outname,"a");

			fprintf(fout,"WAVES/I/O %s\nBEGIN\n",series);
			for (i=0;i<npts;i+=interval) fprintf(fout,"%d\n",INT_little_endian_TO_big_endian(data[i]));
			fprintf(fout,"END\n");
			fprintf(fout,"X SetScale x 0,0, \"a.u.\", %s\; SetScale d 0,0, \"a.u.\", %s\n",series,series);
			if (j==0) fprintf(fout,"X Display %s vs f_%s\; DoWindow/C TempGraph\n",series,expname);
			else fprintf(fout,"X AppendToGraph/C=(%5d,%5d,%5d) %s vs f_%s\n",2*rand(),2*rand(),2*rand(),series,expname);
			if (j==li-1) {
				fprintf(fout,"X ModifyGraph width=1024,height=432\n");
				fprintf(fout,"X Legend/C/N=text0/F=0/S=3/A=RT/X=0/Y=0\n");
			}
			fclose(fout);
		}

	} else printf(" -> no data written\n");
}
}


get_TE(path,te)
char *path;
float *te;
{
FILE *acqptr;
char str[256],str2[256],c;
int i,quit;

acqptr=fopen(path,"r");
if (!acqptr) {
	printf("acqus file not found\n");
	exit(0);
}

quit=0;
while ((fgets(str,80,acqptr)!=NULL)&&(quit==0)) {
  if (strncmp(str,"##$TE",5)==0) sscanf(str,"%s %f",str2,te);
  if (strncmp("##END=",str,6)==0) quit=1;
}

fclose(acqptr);

}


get_info(path,sw,npts)
char *path;
float *sw;
int *npts;
{
FILE *procptr;
char str[256],str2[256],c;
int i,quit;

procptr=fopen(path,"r");
if (!procptr) {
	printf("procs file not found\n");
	exit(0);
}

quit=0;
while ((fgets(str,80,procptr)!=NULL)&&(quit==0)) {
  if (strncmp(str,"##$FTSIZE",9)==0) sscanf(str,"%s %d",str2,npts);
  if (strncmp(str,"##$SW_p",7)==0) sscanf(str,"%s %f",str2,sw);
  if (strncmp("##END=",str,6)==0) quit=1;
}

fclose(procptr);

}

int INT_little_endian_TO_big_endian(int i)
{
    return((i&0xff)<<24)+((i&0xff00)<<8)+((i&0xff0000)>>8)+((i>>24)&0xff);
}
