#pragma rtGlobals=1
#pragma version = 1.0
#pragma IgorVersion = 6.12
//=======================================================
// NetDCF file Maker
// makes a GUI for making NetDCF files from IGOR data
// also scales data using scale factor and offset if input
// this does NOT convert compressed data into integer format etc
// You need to have the ncgen.exe files installed
//=======================================================
//=======================================================
// Copyright (C) 2015
// Jonathan Crosier (SEAES, University of Manchester, UK)
// j.crosier@manchester.ac.uk
//=======================================================
//=======================================================
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//=======================================================
//=======================================================
static strconstant KS_NCGEN_GLB_TITLES="Conventions;Title;Institution;Source;History;References;Comment;"
//=======================================================
// Add commnad to panel Menu
menu "NCGEN"
//puts the panels on the IGOR menus
"NCGEN build", /Q, buildMakeNCGENGUI()
"NCGEN panel", /Q, MakeNCGEN_win(4)
"NCGEN Global Vars", /Q, MakeNCGEN_win(2)
"NCGEN Data Table", /Q, MakeNCGEN_win(1)
end
//=======================================================
// this calls the functions which make the panel and globals
function buildMakeNCGENGUI()
DFRef StartDir=GetDataFolderDFR()
newdatafolder/o/s root:ncgen
MakeNCGEN_run()
MakeNCGEN_win(7)
Setdatafolder StartDir
end
//=======================================================
// makes the globals for the panels
Function MakeNCGEN_run()
string/g NCGEN_input=""
string/g NCGEN_output=""
string/g NCGEN_file=""
variable/G NCGEN_okay=0
make /o/n=0/t NCGEN_data,NCGEN_dim1,NCGEN_dim2,NCGEN_dim3,NCGEN_dim4,NCGEN_sName,NCGEN_Lname
make /o/n=0/t NCGEN_format,NCGEN_fillVal,NCGEN_units,NCGEN_scaling,NCGEN_offset
make /o/n=(itemsinlist(KS_NCGEN_GLB_TITLES))/t NCGEN_Gname=stringfromlist(p,KS_NCGEN_GLB_TITLES),NCGEN_Gdata
end
//=======================================================
// makes/recalls the various windows
Function MakeNCGEN_win(WinID)
variable WinID
if(WinID&1)
if (!wintype("NCGEN_Dtable"))
execute("NCGEN_Dtable()")
else
dowindow /f NCGEN_Dtable
endif
endif
if(WinID&2)
if (!wintype("NCGEN_Gtable"))
execute("NCGEN_Gtable()")
else
dowindow /f NCGEN_Gtable
endif
endif
if(WinID&4)
if (!wintype("NCGEN_panel"))
execute("NCGEN_panel()")
else
dowindow /f NCGEN_panel
endif
endif
end
//=======================================================
// makes the main panel
Window NCGEN_panel() : Panel
PauseUpdate; Silent 1
// ceate a panel
NewPanel/k=1 /W=(80,70,420,190) as "CDL and netCDF file creater"
ModifyPanel fixedsize=1,noedit=1
// file IO
SetVariable NCGEN_input,pos={10,10},size={280,16},title="ncgen folder",value= root:ncgen:NCGEN_input,noedit=1
SetVariable NCGEN_output,pos={10,35},size={280,16},title="output folder",value= root:ncgen:NCGEN_output,noedit=1
Button NCGEN_input_button, pos={300,8}, size={20,20},title="\W649",proc=NCGEN_setinput
Button NCGEN_output_button, pos={300,33}, size={20,20},title="\W649",proc=NCGEN_setoutput
SetVariable NCGEN_file,pos={10,60},size={200,16},title="Filename",value= root:ncgen:NCGEN_file
// status lights
TitleBox NCGEN_exe, pos={30,85}, size={20,20},title="ncgen",labelBack=(50000,50000,50000)
TitleBox NCGEN_access, pos={90,85}, size={20,20},title="access",labelBack=(50000,50000,50000)
// the main button to start making the netCDF
Button NCGEN_make,pos={150,85},size={80,20},proc=NCGEN_maker,title="Do it!"
EndMacro
//=======================================================
// makes the table for data types
window NCGEN_Dtable() : Table
pauseupdate; silent 1
if(datafolderexists("root:ncgen"))
String StartDir=GetDataFolder(1)
setdatafolder root:ncgen
Edit/k=1/W=(6,62,885.75,243.5) NCGEN_data,NCGEN_dim1,NCGEN_dim2,NCGEN_dim3,NCGEN_dim4,NCGEN_sName,NCGEN_Lname
AppendToTable NCGEN_fillVal,NCGEN_units,NCGEN_scaling,NCGEN_offset
ModifyTable title(NCGEN_data)="Data Waves",title(NCGEN_dim1)="Dimension1",title(NCGEN_dim2)="Dimension2",title(NCGEN_dim3)="Dimension3"
ModifyTable title(NCGEN_dim4)="Dimension4",title(NCGEN_sName)="Short Name",title(NCGEN_Lname)="Long Name"
ModifyTable title(NCGEN_fillVal)="Fill Value",title(NCGEN_units)="Data units",title(NCGEN_scaling)="Scale Factor",title(NCGEN_offset)="Offset"
Setdatafolder StartDir
endif
end
//=======================================================
// makes the table for the global attributes
window NCGEN_Gtable() : Table
pauseupdate; silent 1
if(datafolderexists("root:ncgen"))
String StartDir=GetDataFolder(1)
setdatafolder root:ncgen
Edit/k=1/W=(6,62,885.75,243.5) NCGEN_Gname,NCGEN_Gdata
ModifyTable title(NCGEN_Gname)="Global Attribute Name",title(NCGEN_Gdata)="Global Attribute Data"
ModifyTable autosize(NCGEN_Gname)={0,0,-1,0,0},width(NCGEN_Gdata)=350
Setdatafolder StartDir
endif
end
//=======================================================
// this function checks that ncgen.exe is found, and that it is in a read/write location
Function NCGEN_check_install()
SVAR NCGEN_input=root:ncgen:NCGEN_input
NVAR NCGEN_okay=root:ncgen:NCGEN_okay
// check the path contains ncgen
variable ncgen_result = 0
Newpath/O/Q/Z ncgenPath, NCGEN_input
if(V_flag==0)
String FileList = IndexedFile(ncgenPath, -1, ".exe")
variable i,j=itemsinlist(FileList)
for(i=0;i0)
Open/P=ncgenPath/Z fileID as "ncgen.tmp"
if(V_flag==0)
Close fileID
DeleteFile/P=ncgenPath "ncgen.tmp"
readwrite_result = 1
endif
endif
// set a status light
if(readwrite_result)
TitleBox NCGEN_access,labelBack=(30000,65000,30000)
else
TitleBox NCGEN_access,labelBack=(65000,30000,30000)
endif
NCGEN_okay=(readwrite_result&ncgen_result)? 1 : 0
End
//=======================================================
// sets the path to ncgen
Function NCGEN_setinput(ControlName) : ButtonControl
String ControlName
// get the path
svar NCGEN_input=root:ncgen:NCGEN_input
NCGEN_input=""
Newpath/O/Q/Z/M="Browse to the folder containing ncgen" ncgenPath
if(V_Flag==0)
Pathinfo ncgenPath
variable len = strlen(s_path)
NCGEN_input = S_path[0,len-2]
endif
NCGEN_check_install()
End
//=======================================================
// set the output path for the netCDF files
Function NCGEN_setoutput(ControlName) : ButtonControl
String ControlName
// get the path
svar NCGEN_output=root:ncgen:NCGEN_output
NCGEN_output=""
Newpath/O/Q/Z/M="Browse to the folder for the output netCDF file" ncgenPath
if(V_Flag==0)
Pathinfo ncgenPath
variable len = strlen(s_path)
NCGEN_output = S_path[0,len-2]
endif
End
//=======================================================
// makes the CDL file, makes teh batch file and calls the batch file
function NCGEN_maker(controlName) : ButtonControl
string controlName
// check the folder containing globals exists
if(!datafolderexists("root:ncgen"))
Doalert 0, "Igor NCGEN data folder not found. Please rebuild!"
return 0
endif
// check ncgen is present
NCGEN_check_install()
NVAR NCGEN_okay=root:ncgen:NCGEN_okay
if(NCGEN_okay==0)
Doalert 0, "ncgen not found, or not in write access folder. Aborting!"
return 0
endif
String StartDir=GetDataFolder(1)
setdatafolder root:ncgen
// reference globals
svar NCGEN_input
svar NCGEN_output
svar NCGEN_file
// check output paths and names have been specified
if(strlen(NCGEN_output)==0)
Doalert 0, "No output path set. Aborting!"
return 0
endif
if(strlen(NCGEN_file)==0)
Doalert 0, "No output file name set. Aborting!"
return 0
endif
// convert MAC path to wondows paths for batch file operations
String ncgenPath = ParseFilePath(5, NCGEN_input, "\\", 0, 0)
String outputPath = ParseFilePath(5, NCGEN_output, "\\", 0, 0)
// create the ascii CDL file
variable error = CDL_build(NCGEN_file,outputPath)
if(error)
Doalert 0, "Error encountered during cdl build. See history area for details."
else
// execute the batch file which calls ncgen
NCGEN_batch(NCGEN_file,outputPath,ncgenPath)
ExecuteScriptText /Z outputPath+"\\"+NCGEN_file+".bat"
Deletefile/Z outputPath+"\\"+NCGEN_file+".bat"
// show the output fole in explorer?
Doalert 1, "Finished!\rView the file in windows explorer?"
if(V_flag==1)
Newpath/O/Q/Z ncgenPath, NCGEN_output
pathinfo/show ncgenPath
endif
endif
Setdatafolder StartDir
end
//=======================================================
// makes the batch file with the ncgen.exe call
function NCGEN_batch(filename,folder,input)
string filename,folder,input
variable ref
newpath /O /Q /Z batPath,folder
Open /P=batPath /Z ref as filename+".bat"
fprintf ref, "xcopy /y \"%s\" \"%s\"\r\n",folder+"\\"+filename+".cdl",input
fprintf ref, "cd/D \"%s\"\r\n",input
fprintf ref, "ncgen -b -o \"%s\" \"%s\"\r\n",filename+".nc",filename+".cdl"
fprintf ref, "xcopy /y \"%s\" \"%s\"\r\n",filename+".nc",folder
fprintf ref, "del %s\r\n",filename+".nc"
fprintf ref, "del %s\r\n",filename+".cdl"
fprintf ref, "@pause"
close ref
end
//=======================================================
// makes the CDL formatted file
function CDL_build(filename,folder)
string filename,folder
variable i,j,ii,jj,iii,jjj,iiii,jjjj,iiiii,jjjjj,ref,pos1,pos2,off,scale,len
string dataStr1,dataStr2,outStr,info
variable error = 1
// references the data
wave/z/t NCGEN_data,NCGEN_dim1,NCGEN_dim2,NCGEN_dim3,NCGEN_dim4,NCGEN_sName,NCGEN_Lname
wave/z/t NCGEN_format,NCGEN_fillVal,NCGEN_units,NCGEN_scaling,NCGEN_offset
wave/z/t NCGEN_Gname,NCGEN_Gdata
if(!waveexists(NCGEN_data))
print "NCGEN info waves not found. Rebuild ncgen in Igor."
return error
endif
// strip out blanks for data and dimension names as these can be blank
NCGEN_data=replacestring(" ",NCGEN_data[p],"")
NCGEN_dim1=replacestring(" ",NCGEN_dim1[p],"")
NCGEN_dim2=replacestring(" ",NCGEN_dim2[p],"")
NCGEN_dim3=replacestring(" ",NCGEN_dim3[p],"")
NCGEN_dim4=replacestring(" ",NCGEN_dim4[p],"")
// check for bad wave references and presence of all implied dimensions in the data list
dataStr1 = "NCGEN_data;NCGEN_dim1;NCGEN_dim2;NCGEN_dim3;NCGEN_dim4;"
dataStr2 = "data;dim1;dim2;dim3;dim4;"
jj=itemsinlist(dataStr1)
for(ii=0;ii0)
if(!waveexists($(SourceRef[i])))
print "Bad wave reference in input table for "+stringfromlist(ii,dataStr2)+" in row "+num2str(i)+"."
return error
elseif(StringMatch(stringfromlist(ii,dataStr2), "dim*" )==1)
if(NCGEN_TextWave_search(NCGEN_data, SourceRef[i]) == 0)
Print "Dimensional data for "+stringfromlist(ii,dataStr2)+" for row "+num2str(i)+" not in data list of input table."
return error
endif
endif
endif
endfor
endfor
// opens the file
newpath /O /Q /Z ncgenPath,folder
Open /P=ncgenPath /Z ref as filename+".cdl"
fprintf ref, "netcdf %s { \r\n",filename
fprintf ref, "\r\n"
// outputs dimension information
fprintf ref, "dimensions:\r\n\r\n"
j=dimsize(NCGEN_data,0)
for(i=0;i0)
fprintf ref,",%s",NCGEN_sName[CDLfindstr(NCGEN_data,NCGEN_dim2[i])]
endif
if(strlen(NCGEN_dim3[i])>0)
fprintf ref,",%s",NCGEN_sName[CDLfindstr(NCGEN_data,NCGEN_dim3[i])]
endif
if(strlen(NCGEN_dim4[i])>0)
fprintf ref,",%s",NCGEN_sName[CDLfindstr(NCGEN_data,NCGEN_dim4[i])]
endif
fprintf ref,");\r\n"
// outputs the attributes
fprintf ref,"\t\t%s:%s = \"%s\";\r\n",NCGEN_sName[i],"long_name",NCGEN_Lname[i]
fprintf ref,"\t\t%s:%s = \"%s\";\r\n",NCGEN_sName[i],"units",NCGEN_units[i]
fprintf ref,"\t\t%s:%s = %s;\r\n",NCGEN_sName[i],"_FillValue",NCGEN_fillVal[i]
fprintf ref,"\t\t%s:%s = %s;\r\n",NCGEN_sName[i],"scale_factor",NCGEN_scaling[i]
fprintf ref,"\t\t%s:%s = %s;\r\n",NCGEN_sName[i],"add_offset",NCGEN_offset[i]
else
Close ref
Print "Data not found. Check wave reference for "+NCGEN_data[i]+" in netcdf input table."
return error
endif
fprintf ref, "\r\n"
endfor
// output global attributes
fprintf ref, "//global attributes\r\n"
for(i=0;i