Index: /issm/trunk-jpl/src/m/contrib/netCDF/export_netCDF.py
===================================================================
--- /issm/trunk-jpl/src/m/contrib/netCDF/export_netCDF.py	(revision 18864)
+++ /issm/trunk-jpl/src/m/contrib/netCDF/export_netCDF.py	(revision 18864)
@@ -0,0 +1,194 @@
+from netCDF4 import Dataset
+import numpy
+import time
+import collections
+from mesh2d import *
+from mesh3dprisms import *
+from results import *
+from os import path, remove
+
+def netCDFExp(md,filename):
+
+	#defining some sub-functions
+	#retriev the dimension tuple from a dictionnary
+	def GetDim(var,shape,i,istime):
+		output=[]
+		for dim in range(0,i):
+			if type(shape[0])==int:
+				try:
+					output=output+[str(DimDict[shape[dim]])]
+				except KeyError:
+					if (shape[dim])>1:
+						NewDim=NCData.createDimension(str(field),(shape[dim]))
+						DimDict[len(NewDim)]=str(field)
+						output=output+[str(DimDict[shape[dim]])]
+						print 'Defining dimension ' +str(shape[dim]) +' for '+str(field)
+			elif type(shape[0])==str:#dealling with a dictionnary
+				try:
+					output=[str(DimDict[numpy.shape(shape)[0]])]+['DictDim']
+				except KeyError:
+					NewDim=NCData.createDimension(str(field),numpy.shape(shape)[0])
+					DimDict[len(NewDim)]=str(field)
+					output=[str(DimDict[numpy.shape(dict.keys(var))[0]])]+['DictDim']
+					print 'Defining dimension ' +str(numpy.shape(shape)[0]) +' for '+str(field)
+				break
+		if istime:
+			output=output+['Time']
+		return tuple(output)
+	#============================================================================
+
+  #Define the variables
+	def CreateVar(var,istime,*step_args):
+		#grab type
+		try:
+			val_type=str(var.dtype)
+		except AttributeError:
+			val_type=type(var)
+		#grab dimension
+		try:
+			val_shape=dict.keys(var)
+		except TypeError:
+			val_shape=numpy.shape(var)
+
+		val_dim=numpy.shape(val_shape)[0]
+		#Now define and fill up variable
+
+		#treating scalar string or bool as atribute
+		if val_type==str or val_type==bool:
+			NCgroup.__setattr__(str(field), str(var))
+
+		#treating list as string table
+		elif val_type==list:
+			ncvar = NCgroup.createVariable(str(field),str,GetDim(var,val_shape,val_dim,istime))
+			for elt in range(0,val_dim):
+				try:
+					ncvar[elt] = var[elt]
+				except IndexError:
+					ncvar[0]= " "
+		#treating bool tables as string tables
+		elif val_type=='bool':
+			ncvar = NCgroup.createVariable(str(field),str,GetDim(var,val_shape,val_dim,istime))
+			for elt in range(0,val_shape[0]):
+				ncvar[elt] = str(var[elt])
+		#treating dictionaries as string tables of dim 2
+		elif val_type==collections.OrderedDict:
+			ncvar = NCgroup.createVariable(str(field),str,GetDim(var,val_shape,val_dim,istime))
+			for elt in range(0,val_dim):
+				ncvar[elt,0]=dict.keys(var)[elt]
+				ncvar[elt,1]=str(dict.values(var)[elt]) #converting to str to avoid potential problems
+		#Now dealing with numeric variables
+		else:
+			ncvar = NCgroup.createVariable(str(field),TypeDict[val_type],GetDim(var,val_shape,val_dim,istime))
+			
+			if istime:
+				last=step_args[0]
+				freq=step_args[1]
+				vartab=var
+				for time in range(freq-1,last,freq):
+					timevar=md.results.__dict__[supfield].__getitem__(time).__dict__[field]
+					#print 'Treating '+str(group)+'.'+str(supfield)+'.'+str(field)+' for time '+str(time)
+					vartab=numpy.column_stack((vartab,timevar))
+				print numpy.shape(ncvar)
+				ncvar[:,:]=vartab
+			else:
+				try:
+					nan_val=numpy.isnan(var)
+					if nan_val.all():
+						ncvar [:] = 'NaN'
+					else:
+						ncvar[:] = var
+				except TypeError: #type does not accept nan, get vallue of the variable
+					ncvar[:] = var
+	#============================================================================
+	
+	#Now going on Real treatment
+	if path.exists(filename):
+		print ('File {} allready exist'.format(filename))
+		newname=raw_input('Give a new name or "delete" to replace: ')
+		if newname=='delete':
+			remove(filename)
+		else:
+			print ('New file name is {}'.format(newname))
+			filename=newname
+			
+	NCData=Dataset(filename, 'w', format='NETCDF4')
+	NCData.description = 'Results for run' + md.miscellaneous.name
+	NCData.history = 'Created ' + time.ctime(time.time())
+
+	#gather geometry and timestepping as dimensions
+	Duration=md.timestepping.final_time-md.timestepping.start_time
+	if Duration>0 and md.timestepping.time_step*md.settings.output_frequency>0:
+		StepNum=Duration/(md.timestepping.time_step*md.settings.output_frequency)
+	else:
+		StepNum=1
+		
+	EltNum=NCData.createDimension('EltNum',md.mesh.numberofelements)
+	VertNum=NCData.createDimension('VertNum',md.mesh.numberofvertices)
+	VertperElt=NCData.createDimension('VertperElt',numpy.shape(md.mesh.elements)[1])
+	if type(md.mesh) is mesh2d:
+		DimNum=NCData.createDimension('DimNum',2)
+	elif type(md.mesh) is mesh3dprisms:
+		DimNum=NCData.createDimension('DimNum',3)
+	else:
+		print 'I can not get the Dimension of the problem'
+	EdgeNum=NCData.createDimension('EdgeNum',md.mesh.numberofedges)
+	Time=NCData.createDimension('Time',StepNum)
+	SegNum=NCData.createDimension('SegNum',numpy.shape(md.mesh.segmentmarkers)[0])
+	InvSteps=NCData.createDimension('InvSteps',md.inversion.nsteps)
+	DictDim=NCData.createDimension('DictDim',2)
+
+	DimDict = {len(EltNum):'EltNum',
+						 len(VertNum):'VertNum',
+						 len(VertperElt):'VertperElt',
+						 len(DimNum):'DimNum',
+						 len(EdgeNum):'EdgeNum',
+						 len(Time):'Time',
+						 len(SegNum):'SegNum',
+						 len(InvSteps):'InvSteps'}
+
+	TypeDict = {float:'f8',
+							'float64':'f8',
+							int:'i8',
+							'int64':'i8'}
+	
+	#get all model classes and create respective groups
+	groups=dict.keys(md.__dict__)
+	for group in groups:
+		NCgroup=NCData.createGroup(str(group))
+		#In each group gather the fields of the class
+		fields=dict.keys(md.__dict__[group].__dict__)
+
+		#Special treatment for the results
+		if str(group)=='results':
+			for supfield in fields:#looping on the different solutions
+				if type(md.results.__dict__[supfield])==list:#the solution have several timestep
+					#get last timesteps and output frequency
+					last_step = numpy.size(md.results.__dict__[supfield])
+					step_freq = md.settings.output_frequency
+					#grab first time step
+					subfields=dict.keys(md.results.__dict__[supfield].__getitem__(0).__dict__)
+					for field in subfields:
+#						print 'Treating '+str(group)+'.'+str(supfield)+'.'+str(field)+' for time '+str(0)
+						if str(field)!='errlog' and str(field)!='outlog' and str(field)!='SolutionType':
+							Var=md.results.__dict__[supfield].__getitem__(0).__dict__[field]
+							CreateVar(Var,True,last_step,step_freq)
+#							print 'Treating '+str(group)+'.'+str(supfield)+'.'+str(field)+' for time '+str(0)
+					
+				elif type(md.results.__dict__[supfield])==results:#only one timestep
+					subfields=dict.keys(md.results.__dict__[supfield].__dict__)
+					for field in subfields:
+						if str(field)!='errlog' and str(field)!='outlog' and str(field)!='SolutionType':
+							Var=md.results.__dict__[supfield].__dict__[field]
+							CreateVar(Var,False)
+#							print 'Treating '+str(group)+'.'+str(supfield)+'.'+str(field)
+				else:
+					print 'Result format not suported'
+		else:
+			
+			for field in fields:
+#				print 'Treating ' +str(group)+'.'+str(field)
+				Var=md.__dict__[group].__dict__[field]
+				CreateVar(Var,False)
+	NCData.close()
+
+
