I see that I have misread the manual and that I need to reproduce the code in the C example in python. The SWMM DLL doesn't contain ready-made functions to open files etc.
Apologies for posting before I was completely sure of the problem. Hanlie 2011/3/1, Hanlie Pretorius <hanlie.pretor...@gmail.com>: > Hi Python Tutors, > > I'm using a storm water modelling program, EPA SWMM, to model the > hydrology and hydraulics of a study area. > > SWMM reports its results in a binary (.out) file that contains the > results for each element in the model at each time step in the model > run. According to the SWMM interface manual > (http://www.epa.gov/ednnrmrl/models/swmm/swmm5_iface.zip), one can use > a DLL file to read the .out file. I want to do this so that I can read > the state of a river at a specific time and plot its water level in a > GIS. > > After some searching on the Internet, I came across ctypes, which I > have tried. According to the SWMM manual: > > [manual] > Opening the Output File > ---------------------------------- > A function named OpenSwmmOutFile(outFile) that performs these tasks is > contained in the example code files that accompany this guide. The > argument to the function is the name of the binary output file. The > return value from the function is an integer code with the following > meanings: > 0 - the run was successful > 1 - the run was terminated with an error > 2 - the output file could not be opened. > [/manual] > > So, I tried the following python code: > [code] > In [14]: swmmdll = > cdll.LoadLibrary("C:\\Hanlie\\model\\SWMM\\swmm5_0_018.dll") > > In [15]: results_file="C:\\Hanlie\\model\\SWMM\\c83a_v0\\c83a_v0.3.out" > > In [16]: open_file=swmmdll.OpenSwmmOutFile(results_file) > ------------------------------------------------------------ > Traceback (most recent call last): > File "<ipython console>", line 1, in <module> > File "C:\Python26\lib\ctypes\__init__.py", line 366, in __getattr__ > func = self.__getitem__(name) > File "C:\Python26\lib\ctypes\__init__.py", line 371, in __getitem__ > func = self._FuncPtr((name_or_ordinal, self)) > AttributeError: function 'OpenSwmmOutFile' not found > [/code] > > Can anyone perhaps help me to access the functions in this DLL? > > The manual also states: > [manual] > The following files are needed for applications that call functions > from the swmm5.dll library: > · swmm5.h for C/C++ applications > · swmm5.bas for Visual Basic applications > · swmm5.pas for Delphi applications. > [/manual] > > And they give an example in C, Basic and Pascal to use the interface. > I have appended the C example to this message. > > Thanks > Hanlie > > [code] > // swmm5_iface.c > // > // Example code for interfacing SWMM 5 with C/C++ programs. > // > // Remember to #include the file swmm5_iface.h in the calling program. > > #include <stdio.h> > #include <windows.h> > #include "swmm5.h" > > int SWMM_Nperiods; // number of reporting periods > int SWMM_FlowUnits; // flow units code > int SWMM_Nsubcatch; // number of subcatchments > int SWMM_Nnodes; // number of drainage system nodes > int SWMM_Nlinks; // number of drainage system links > int SWMM_Npolluts; // number of pollutants tracked > double SWMM_StartDate; // start date of simulation > int SWMM_ReportStep; // reporting time step (seconds) > > int RunSwmmExe(char* cmdLine); > int RunSwmmDll(char* inpFile, char* rptFile, char* outFile); > int OpenSwmmOutFile(char* outFile); > int GetSwmmResult(int iType, int iIndex, int vIndex, int period, > float* value); > void CloseSwmmOutFile(void); > > static const int SUBCATCH = 0; > static const int NODE = 1; > static const int LINK = 2; > static const int SYS = 3; > static const int RECORDSIZE = 4; // number of bytes per file record > > static int SubcatchVars; // number of subcatch reporting > variables > static int NodeVars; // number of node reporting > variables > static int LinkVars; // number of link reporting > variables > static int SysVars; // number of system reporting > variables > > static FILE* Fout; // file handle > static int StartPos; // file position where results start > static int BytesPerPeriod; // bytes used for results in each > period > static void ProcessMessages(void); > > //----------------------------------------------------------------------------- > int RunSwmmExe(char* cmdLine) > //----------------------------------------------------------------------------- > { > int exitCode; > STARTUPINFO si; > PROCESS_INFORMATION pi; > > // --- initialize data structures > memset(&si, 0, sizeof(si)); > memset(&pi, 0, sizeof(pi)); > si.cb = sizeof(si); > si.wShowWindow = SW_SHOWNORMAL; > > // --- launch swmm5.exe > exitCode = CreateProcess(NULL, cmdLine, NULL, NULL, 0, > 0, NULL, NULL, &si, &pi); > > // --- wait for program to end > exitCode = WaitForSingleObject(pi.hProcess, INFINITE); > > // --- retrieve the error code produced by the program > GetExitCodeProcess(pi.hProcess, &exitCode); > > // --- release handles > CloseHandle(pi.hProcess); > CloseHandle(pi.hThread); > return exitCode; > } > > > //----------------------------------------------------------------------------- > int RunSwmmDll(char* inpFile, char* rptFile, char* outFile) > //----------------------------------------------------------------------------- > { > int err; > double elapsedTime; > > // --- open a SWMM project > err = swmm_open(inpFile, rptFile, outFile); > if (!err) > { > // --- initialize all processing systems > err = swmm_start(1); > if (err == 0) > { > // --- step through the simulation > do > { > // --- allow Windows to process any pending events > ProcessMessages(); > > // --- extend the simulation by one routing time step > err = swmm_step(&elapsedTime); > > ///////////////////////////////////////////// > // --- call progress reporting function here, > // using elapsedTime as an argument > ///////////////////////////////////////////// > > } while (elapsedTime > 0.0 && err == 0); > > // --- close all processing systems > swmm_end(); > } > } > > // --- close the project > swmm_close(); > return err; > } > > > //----------------------------------------------------------------------------- > void ProcessMessages(void) > //----------------------------------------------------------------------------- > { > > /**** Only use this function with a Win32 application ***** > MSG msg; > while (TRUE) > { > if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) > { > if (msg.message == WM_QUIT) break; > else > { > TranslateMessage(&msg); > DispatchMessage(&msg); > } > } > else break; > } > ***********************************************************/ > > } > > > //----------------------------------------------------------------------------- > int OpenSwmmOutFile(char* outFile) > //----------------------------------------------------------------------------- > { > int magic1, magic2, errCode, offset, offset0, version; > int err; > > // --- open the output file > Fout = fopen(outFile, "rb"); > if (Fout == NULL) return 2; > > // --- check that file contains at least 14 records > fseek(Fout, 0L, SEEK_END); > if (ftell(Fout) < 14*RECORDSIZE) > { > fclose(Fout); > return 1; > } > > // --- read parameters from end of file > fseek(Fout, -5*RECORDSIZE, SEEK_END); > fread(&offset0, RECORDSIZE, 1, Fout); > fread(&StartPos, RECORDSIZE, 1, Fout); > fread(&SWMM_Nperiods, RECORDSIZE, 1, Fout); > fread(&errCode, RECORDSIZE, 1, Fout); > fread(&magic2, RECORDSIZE, 1, Fout); > > // --- read magic number from beginning of file > fseek(Fout, 0L, SEEK_SET); > fread(&magic1, RECORDSIZE, 1, Fout); > > // --- perform error checks > if (magic1 != magic2) err = 1; > else if (errCode != 0) err = 1; > else if (SWMM_Nperiods == 0) err = 1; > else err = 0; > > // --- quit if errors found > if (err > 0 ) > { > fclose(Fout); > Fout = NULL; > return err; > } > > // --- otherwise read additional parameters from start of file > fread(&version, RECORDSIZE, 1, Fout); > fread(&SWMM_FlowUnits, RECORDSIZE, 1, Fout); > fread(&SWMM_Nsubcatch, RECORDSIZE, 1, Fout); > fread(&SWMM_Nnodes, RECORDSIZE, 1, Fout); > fread(&SWMM_Nlinks, RECORDSIZE, 1, Fout); > fread(&SWMM_Npolluts, RECORDSIZE, 1, Fout); > > // Skip over saved subcatch/node/link input values > offset = (SWMM_Nsubcatch+2) * RECORDSIZE // Subcatchment area > + (3*SWMM_Nnodes+4) * RECORDSIZE // Node type, invert & max > depth > + (5*SWMM_Nlinks+6) * RECORDSIZE; // Link type, z1, z2, > max depth & length > offset = offset0 + offset; > fseek(Fout, offset, SEEK_SET); > > // Read number & codes of computed variables > fread(&SubcatchVars, RECORDSIZE, 1, Fout); // # Subcatch variables > fseek(Fout, SubcatchVars*RECORDSIZE, SEEK_CUR); > fread(&NodeVars, RECORDSIZE, 1, Fout); // # Node variables > fseek(Fout, NodeVars*RECORDSIZE, SEEK_CUR); > fread(&LinkVars, RECORDSIZE, 1, Fout); // # Link variables > fseek(Fout, LinkVars*RECORDSIZE, SEEK_CUR); > fread(&SysVars, RECORDSIZE, 1, Fout); // # System variables > > // --- read data just before start of output results > offset = StartPos - 3*RECORDSIZE; > fseek(Fout, offset, SEEK_SET); > fread(&SWMM_StartDate, sizeof(double), 1, Fout); > fread(&SWMM_ReportStep, RECORDSIZE, 1, Fout); > > // --- compute number of bytes of results values used per time period > BytesPerPeriod = 2*RECORDSIZE + // date value (a double) > (SWMM_Nsubcatch*SubcatchVars + > SWMM_Nnodes*NodeVars+ > SWMM_Nlinks*LinkVars + > SysVars)*RECORDSIZE; > > // --- return with file left open > return err; > } > > > //----------------------------------------------------------------------------- > int GetSwmmResult(int iType, int iIndex, int vIndex, int period, float* > value) > //----------------------------------------------------------------------------- > { > int offset; > > // --- compute offset into output file > *value = 0.0; > offset = StartPos + (period-1)*BytesPerPeriod + 2*RECORDSIZE; > if ( iType == SUBCATCH ) > { > offset += RECORDSIZE*(iIndex*SubcatchVars + vIndex); > } > else if (iType == NODE) > { > offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars + > iIndex*NodeVars + vIndex); > } > else if (iType == LINK) > { > offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars + > SWMM_Nnodes*NodeVars + > iIndex*LinkVars + vIndex); > } > else if (iType == SYS) > { > offset += RECORDSIZE*(SWMM_Nsubcatch*SubcatchVars + > SWMM_Nnodes*NodeVars + > SWMM_Nlinks*LinkVars + vIndex); > } > else return 0; > > // --- re-position the file and read the result > fseek(Fout, offset, SEEK_SET); > fread(value, RECORDSIZE, 1, Fout); > return 1; > } > > > //----------------------------------------------------------------------------- > void CloseSwmmOutFile(void) > //----------------------------------------------------------------------------- > { > if (Fout != NULL) > { > fclose(Fout); > Fout = NULL; > } > } > [/code] > _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor