#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