Index: /issm/trunk-jpl/src/c/classes/IoModel.cpp
===================================================================
--- /issm/trunk-jpl/src/c/classes/IoModel.cpp	(revision 20839)
+++ /issm/trunk-jpl/src/c/classes/IoModel.cpp	(revision 20840)
@@ -1142,48 +1142,221 @@
 }
 /*}}}*/
-void  IoModel::FetchData(Option** poption,int index){/*{{{*/
-
-	_error_("not implemented yet");
-
-	/*output: */
-	//int     code;
-	//char   *name        = NULL;
-
-	///*First get option name*/
-	//this->FetchData(&name,index);
-
-	///*Get option value*/
-	//fid=this->SetFilePointerToData(&code,NULL,index+1);
-	//switch(code){
-	//	case 3: {//IssmDouble
-	//				GenericOption<IssmDouble>* option;
-	//				IssmDouble value;
-	//				FetchData(&value,index+1);
-	//				option = new GenericOption<IssmDouble>();
-	//				option->value = value;
-	//				option->name  = name;
-	//				option->numel = 1;
-	//				option->ndims = 1;
-	//				option->size  = NULL;
-	//				/*Assign output pointers: */
-	//				*poption=option;
-	//				break;
-	//			}
-	//	case 4: {//char
-	//				GenericOption<char*>* option;
-	//				char* value = NULL;
-	//				FetchData(&value,index+1);
-	//				option = new GenericOption<char*>();
-	//				option->value = value;
-	//				option->name  = name;
-	//				option->numel = 1;
-	//				option->ndims = 1;
-	//				option->size  = NULL;
-	//				*poption=option;
-	//				break;
-	//			}
-	//	default:
-	//		  _error_("Option of format " << code << " not supported yet");
-	//}
+void  IoModel::FetchData(Options* options,const char* lastnonoption){/*{{{*/
+
+	/*record descriptions; */
+	const char* mddot = "md.";
+	char* record_name = NULL;
+	int   record_name_size;
+	int   record_length;
+	int   record_code; 
+
+	/*records: */
+	IssmDouble   scalar = 0;
+	char        *string = NULL;
+	int          string_size;
+
+	/*recover my_rank:*/
+	int my_rank=IssmComm::GetRank();
+
+	/*Go find in the binary file, the position of the data we want to fetch: */
+	if(my_rank==0){
+		fseek(fid,0,SEEK_SET);
+		for(;;){
+			/*Read size of first string name: */
+			if(fread(&record_name_size,sizeof(int),1,fid)==0) _error_("could not read record_name");
+			if(record_name_size<3 || record_name_size>80) _error_("error while looking in binary file. Found a string of size "<<record_name_size);
+
+			/*Allocate string of correct size: */
+			record_name=xNew<char>(record_name_size+1);
+			record_name[record_name_size]='\0';
+
+			/*Read record_name: */
+			if(fread(record_name,record_name_size*sizeof(char),1,fid)==0)_error_("Could not find field "<<lastnonoption);
+			if(strncmp(record_name,mddot,3)!=0) _error_("error while reading binary file: record does not start with \"md.\": "<<record_name);
+
+			/*Is this the record sought for? : */
+			if(strcmp(record_name,lastnonoption)==0){
+				if(fread(&record_length,sizeof(int),1,fid)!=1) _error_("Could not read record_length");
+				fseek(fid,record_length,SEEK_CUR);
+				xDelete<char>(record_name);
+				break;
+			}
+			else{
+				if(fread(&record_length,sizeof(int),1,fid)!=1) _error_("Could not read record_length");
+				fseek(fid,record_length,SEEK_CUR);
+				xDelete<char>(record_name);
+			}
+		}
+	}
+
+	/*Go find in the binary file, the position of the data we want to fetch: */
+	if(my_rank==0){ //cpu 0{{{
+
+		/*Now march through file looking for the correct data identifiers (bool,int,IssmDouble or string): */
+		for(;;){
+
+			/*Read size of first string name: */
+			if(fread(&record_name_size,sizeof(int),1,fid)==0){
+				/*we have reached the end of the file. break: */
+				record_code=0; //0 means bailout
+				ISSM_MPI_Bcast(&record_code,1,ISSM_MPI_INT,0,IssmComm::GetComm());  /*tell others cpus we are bailing: */
+				break;
+			}
+			if(record_name_size<3 || record_name_size>80){
+				_error_("error while looking in binary file. Found a string of size "<<record_name_size);
+			}
+
+			/*Allocate string of correct size: */
+			record_name=xNew<char>(record_name_size+1);
+			record_name[record_name_size]='\0';
+
+			/*Read record_name: */
+			if(fread(record_name,record_name_size*sizeof(char),1,fid)==0){
+				_error_("Could not read record name");
+			}
+			if(strncmp(record_name,mddot,3)!=0){
+				_error_("error while reading binary file: record does not start with \"md.\": "<<record_name);
+			}
+			if(strcmp(record_name,"md.EOF")==0){
+				xDelete<char>(record_name);
+				record_code=0; //0 means bailout
+				ISSM_MPI_Bcast(&record_code,1,ISSM_MPI_INT,0,IssmComm::GetComm());  /*tell others cpus we are bailing: */
+				break;
+			}
+
+			/* Read the record length and the data type code: */
+			if(fread(&record_length,sizeof(int),1,this->fid)!=1) _error_("Cound not read record_length");
+			if(fread(&record_code  ,sizeof(int),1,this->fid)!=1) _error_("Cound not read record_code");
+
+			/*Tell other cpus what we are doing: */
+			ISSM_MPI_Bcast(&record_code,1,ISSM_MPI_INT,0,IssmComm::GetComm());  /*tell other cpus what we are going to do: */
+
+			/*Tell other cpus the name of the data, then branch according to the data type: */
+			ISSM_MPI_Bcast(&record_name_size,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+			ISSM_MPI_Bcast(record_name,record_name_size,ISSM_MPI_CHAR,0,IssmComm::GetComm()); 
+			ISSM_MPI_Bcast(&record_length,1,ISSM_MPI_INT,0,IssmComm::GetComm());  
+
+			switch(record_code){
+				case 3:
+					  {
+						if(fread(&scalar,sizeof(IssmPDouble),1,this->fid)!=1) _error_("could not read scalar ");
+						ISSM_MPI_Bcast(&scalar,1,ISSM_MPI_PDOUBLE,0,IssmComm::GetComm()); 
+						GenericOption<IssmDouble>* option = new GenericOption<IssmDouble>();
+						char* optionname=xNew<char>(strlen(record_name)-3+1);
+						xMemCpy(optionname,&record_name[3],strlen(record_name)-3+1);
+						option->value = scalar;
+						option->name  = optionname;
+						option->numel = 1;
+						option->ndims = 1;
+						option->size  = NULL;
+						options->AddOption(option);
+					  }
+					break;
+				case 4: 
+					  {
+					/*We have to read a string from disk. First read the dimensions of the string, then the string: */
+					if(fread(&string_size,sizeof(int),1,this->fid)!=1) _error_("could not read length of string ");
+					ISSM_MPI_Bcast(&string_size,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+
+					if(string_size){
+						string=xNew<char>(string_size+1);
+						string[string_size]='\0';
+
+						/*Read string, then broadcast: */
+						if(fread(string,string_size*sizeof(char),1,this->fid)!=1)_error_(" could not read string ");
+						ISSM_MPI_Bcast(string,string_size,ISSM_MPI_CHAR,0,IssmComm::GetComm()); 
+					}
+					else{
+						string=xNew<char>(1);
+						string[0]='\0';
+					}
+
+					/*Add string to parameters: */
+					GenericOption<char*>* option = new GenericOption<char*>();
+					char* optionname=xNew<char>(strlen(record_name)-3+1);
+					xMemCpy(optionname,&record_name[3],strlen(record_name)-3+1);
+					option->value = string;
+					option->name  = optionname;
+					option->numel = 1;
+					option->ndims = 1;
+					option->size  = NULL;
+					options->AddOption(option);
+
+					  }
+					break;
+				default: 
+					_error_("record type not supported:" << record_code); 
+					break;
+			}
+			xDelete<char>(record_name);
+		}
+	} //}}}
+	else{ //cpu ~0 {{{
+		for(;;){ //wait on cpu 0
+			ISSM_MPI_Bcast(&record_code,1,ISSM_MPI_INT,0,IssmComm::GetComm());  /*get from cpu 0 what we are going to do: */
+			if(record_code==0){
+				break; //we are done, break from the loop
+			}
+			else{
+				ISSM_MPI_Bcast(&record_name_size,1,ISSM_MPI_INT,0,IssmComm::GetComm());
+				_assert_(record_name_size);
+				record_name=xNew<char>((record_name_size+1)); record_name[record_name_size]='\0';
+				ISSM_MPI_Bcast(record_name,record_name_size,ISSM_MPI_CHAR,0,IssmComm::GetComm()); 
+				ISSM_MPI_Bcast(&record_length,1,ISSM_MPI_INT,0,IssmComm::GetComm());  
+				switch(record_code){
+					case 3:
+						  {
+							if(fread(&scalar,sizeof(IssmPDouble),1,this->fid)!=1) _error_("could not read scalar ");
+							ISSM_MPI_Bcast(&scalar,1,ISSM_MPI_PDOUBLE,0,IssmComm::GetComm()); 
+							char* optionname=xNew<char>(strlen(record_name)-3+1);
+							xMemCpy(optionname,&record_name[3],strlen(record_name)-3+1);
+							GenericOption<IssmDouble>* option = new GenericOption<IssmDouble>();
+							option->value = scalar;
+							option->name  = optionname;
+							option->numel = 1;
+							option->ndims = 1;
+							option->size  = NULL;
+							options->AddOption(option);
+						  }
+						break;
+					case 4: 
+						  {
+						/*We have to read a string from disk. First read the dimensions of the string, then the string: */
+						if(fread(&string_size,sizeof(int),1,this->fid)!=1) _error_("could not read length of string ");
+						ISSM_MPI_Bcast(&string_size,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
+
+						if(string_size){
+							string=xNew<char>(string_size+1);
+							string[string_size]='\0';
+
+							/*Read string, then broadcast: */
+							if(fread(string,string_size*sizeof(char),1,this->fid)!=1)_error_(" could not read string ");
+							ISSM_MPI_Bcast(string,string_size,ISSM_MPI_CHAR,0,IssmComm::GetComm()); 
+						}
+						else{
+							string=xNew<char>(1);
+							string[0]='\0';
+						}
+
+						/*Add string to parameters: */
+						char* optionname=xNew<char>(strlen(record_name)-3+1);
+						xMemCpy(optionname,&record_name[3],strlen(record_name)-3+1);
+						GenericOption<char*>* option = new GenericOption<char*>();
+						option->value = string;
+						option->name  = optionname;
+						option->numel = 1;
+						option->ndims = 1;
+						option->size  = NULL;
+						options->AddOption(option);
+						  }
+						break;
+					default: 
+						_error_("record type not supported:" << record_code); 
+						break;
+				}
+
+			}
+		}
+	} //}}}
 
 }
@@ -1956,40 +2129,4 @@
 
 	_error_("Could not find constant \""<<constant_name <<"\"");
-}
-/*}}}*/
-void  IoModel::LastIndex(int *pindex){/*{{{*/
-
-	int my_rank;
-	int lastindex,index;
-	int record_length;
-
-	/*recover my_rank:*/
-	my_rank=IssmComm::GetRank();
-
-	/*Go find in the binary file, the position of the data we want to fetch: */
-	if(my_rank==0){
-
-		/*First set FILE* position to the beginning of the file: */
-		fseek(fid,0,SEEK_SET);
-
-		/*Now march through file looking for the correct data identifier: */
-		for(;;){
-			/*Read name for this size of first string name: */
-			if(fread(&index,sizeof(int),1,fid)==0){
-				/*Ok, we have reached the end of the file. break: */
-				break;
-			}
-
-			/*read the record length, and use it to skip this record: */
-			if(fread(&record_length,sizeof(int),1,fid)!=1) _error_("Could not read record_length");
-			fseek(fid,record_length,SEEK_CUR);
-			lastindex=index;
-		}
-	}
-	/*Broadcast code and vector type: */
-	ISSM_MPI_Bcast(&lastindex,1,ISSM_MPI_INT,0,IssmComm::GetComm()); 
-
-	/*Assign output pointers:*/
-	*pindex=lastindex;
 }
 /*}}}*/
Index: /issm/trunk-jpl/src/c/classes/IoModel.h
===================================================================
--- /issm/trunk-jpl/src/c/classes/IoModel.h	(revision 20839)
+++ /issm/trunk-jpl/src/c/classes/IoModel.h	(revision 20840)
@@ -124,5 +124,5 @@
 		void        FetchData(IssmDouble**  pscalarmatrix,int* pM,int* pN,const char* data_name);
 		void        FetchData(IssmDouble*** pmatrixarray,int** pmdims,int** pndims, int* pnumrecords,const char* data_name);
-		void        FetchData(Option **poption,int index);
+		void        FetchData(Options *options,const char* data_name);
 		void        FetchData(int num,...);
 		void        FetchDataToInput(Elements* elements,const char* vector_name,int input_enum);
@@ -134,5 +134,4 @@
 		void        FetchMultipleData(int** pvector, int* pnum_instances,const char* data_name);
 		void        FetchMultipleData(IssmDouble** pvector, int* pnum_instances,const char* data_name);
-		void        LastIndex(int *pindex);
 		fpos_t*     SetFilePointersToData(int** pcodes,int** pvector_types, int* pnum_instances, const char* data_name);
 		FILE*       SetFilePointerToData(int* pcode,int* pvector_type, const char* data_name);
Index: /issm/trunk-jpl/src/c/main/kriging.cpp
===================================================================
--- /issm/trunk-jpl/src/c/main/kriging.cpp	(revision 20839)
+++ /issm/trunk-jpl/src/c/main/kriging.cpp	(revision 20840)
@@ -132,12 +132,11 @@
 void ProcessInputfile(IssmDouble **px,IssmDouble **py,IssmDouble **pdata,int *pnobs,IssmDouble **px_interp,IssmDouble **py_interp,int *pninterp,Options **poptions,FILE* fid){
 
-	int      ninterp,nobs,numoptions;
-	IssmDouble  *x        = NULL;
-	IssmDouble  *y        = NULL;
-	IssmDouble  *data     = NULL;
-	IssmDouble  *x_interp = NULL;
-	IssmDouble  *y_interp = NULL;
-	Options *options  = NULL;
-	Option  *option   = NULL;
+	int         ninterp    ,nobs;
+	IssmDouble *x        = NULL;
+	IssmDouble *y        = NULL;
+	IssmDouble *data     = NULL;
+	IssmDouble *x_interp = NULL;
+	IssmDouble *y_interp = NULL;
+	Options    *options  = NULL;
 
 	int      M,N;
@@ -145,19 +144,13 @@
 	iomodel->fid=fid;
 	iomodel->CheckFile();
-	iomodel->FetchData(&x,&M,&N,"md.0");        nobs=M*N;
-	iomodel->FetchData(&y,&M,&N,"md.1");        _assert_(M*N==nobs);
-	iomodel->FetchData(&data,&M,&N,"md.2");     _assert_(M*N==nobs);
-	iomodel->FetchData(&x_interp,&M,&N,"md.3"); ninterp=M*N;
-	iomodel->FetchData(&y_interp,&M,&N,"md.4"); _assert_(M*N==ninterp);
+	iomodel->FetchData(&x,&M,&N,"md.x");        nobs=M*N;
+	iomodel->FetchData(&y,&M,&N,"md.y");        _assert_(M*N==nobs);
+	iomodel->FetchData(&data,&M,&N,"md.data");     _assert_(M*N==nobs);
+	iomodel->FetchData(&x_interp,&M,&N,"md.x_interp"); ninterp=M*N;
+	iomodel->FetchData(&y_interp,&M,&N,"md.y_interp"); _assert_(M*N==ninterp);
 
 	/*Read options*/
 	options = new Options();
-	iomodel->LastIndex(&N);
-	numoptions=(int)((N-4)/2);
-	for(int i=0;i<numoptions;i++){
-		iomodel->FetchData(&option,5+2*i);
-		options->AddOption(option);
-		option=NULL;
-	}
+	iomodel->FetchData(options,"md.y_interp");
 
 	/*Assign output pointer*/
Index: /issm/trunk-jpl/src/m/classes/pairoptions.m
===================================================================
--- /issm/trunk-jpl/src/m/classes/pairoptions.m	(revision 20839)
+++ /issm/trunk-jpl/src/m/classes/pairoptions.m	(revision 20840)
@@ -284,19 +284,15 @@
 			end
 		end % }}}
-		function marshall(self,fid,firstindex)% {{{
-
-			error('needs to be revised with new marhsall format...');
+		function marshall(self,fid)% {{{
+
 			for i=1:size(self.list,1),
 				name  = self.list{i,1};
 				value = self.list{i,2};
 
-				%Write option name
-				WriteData(fid,prefix,'enum',(firstindex-1)+2*i-1,'data',name,'format','String');
-
 				%Write option value
 				if (isnumeric(value) & numel(value)==1),
-					WriteData(fid,prefix,'enum',(firstindex-1)+2*i,'data',value,'format','Double');
+					WriteData(fid,'','name',['md.' name],'data',value,'format','Double');
 				elseif ischar(value),
-					WriteData(fid,prefix,'enum',(firstindex-1)+2*i,'data',value,'format','String');
+					WriteData(fid,'','name',['md.' name],'data',value,'format','String');
 				else
 					error(['Cannot marshall option ' name ': format not supported yet']);
Index: /issm/trunk-jpl/src/m/contrib/morlighem/gslib/pkriging.m
===================================================================
--- /issm/trunk-jpl/src/m/contrib/morlighem/gslib/pkriging.m	(revision 20839)
+++ /issm/trunk-jpl/src/m/contrib/morlighem/gslib/pkriging.m	(revision 20840)
@@ -18,24 +18,16 @@
 end
 
-%First, write MaximumNumberOfDefinitionsEnum to make sure that the Enums are synchronized
-WriteData(fid,'enum',MaximumNumberOfDefinitionsEnum(),'data',true,'format','Boolean');
-
 %Write all data
-WriteData(fid,'enum',0,'data',x,'format','DoubleMat');
-WriteData(fid,'enum',1,'data',y,'format','DoubleMat');
-WriteData(fid,'enum',2,'data',observations,'format','DoubleMat');
-WriteData(fid,'enum',3,'data',x_interp,'format','DoubleMat');
-WriteData(fid,'enum',4,'data',y_interp,'format','DoubleMat');
-
-%Last, write MaximumNumberOfEnum+1 to make sure that the binary file is not corrupt
-WriteData(fid,'enum',MaximumNumberOfDefinitionsEnum()+1,'data',true,'format','Boolean');
+WriteData(fid,'','name','md.x','data',x,'format','DoubleMat');
+WriteData(fid,'','name','md.y','data',y,'format','DoubleMat');
+WriteData(fid,'','name','md.data','data',observations,'format','DoubleMat');
+WriteData(fid,'','name','md.x_interp','data',x_interp,'format','DoubleMat');
+WriteData(fid,'','name','md.y_interp','data',y_interp,'format','DoubleMat');
 
 %Now, write number of options
-options.marshall(fid,5);
-st=fclose(fid);
-if st==-1,
-	error(['marshall error message: could not close file ' name '.bin']);
-end
-% =========================================   MARSHALL.m =================================================
+options.marshall(fid);
+
+%Last, write "md.EOF" to make sure that the binary file is not corrupt
+WriteData(fid,'','name','md.EOF','data',true,'format','Boolean');
 
 %Launch job on remote cluster
