Can anyone perhaps suggest the easiest way of translating the C code into Python, bearing in mind that I'm rather a beginner?
Thanks Hanlie 2011/3/1, Hanlie Pretorius <hanlie.pretor...@gmail.com>: > 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