├── .Rbuildignore ├── .gitattributes ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.txt ├── DESCRIPTION ├── LICENSE ├── NAMESPACE ├── NEWS ├── R ├── Net1-data.r ├── Net1rpt-data.r ├── epanet.inp-s3.r ├── epanet.rpt-s3.r ├── epanetReader.r ├── epanetmsx.rpt-s3.r ├── expandedLinkTable-s3.r ├── inpFuncs.r ├── msxFuncs.r ├── plotSparklineTable.r ├── rptFuncs.r ├── sparkline-s3.r ├── sparklineTable-s3.r ├── text_file_reader.r └── write.inp.r ├── README.md ├── data ├── Net1.rdata └── Net1rpt.rdata ├── img ├── Net1cl.png ├── Net1inp.png └── Net1rpt.png ├── inst ├── CITATION └── extdata │ ├── Net1.inp │ ├── Net1.rpt │ └── example.rpt ├── man ├── Net1.Rd ├── Net1rpt.Rd ├── binBreaker.Rd ├── epanetDefaultOptions.Rd ├── epanetReader.Rd ├── expandedLinkTable.Rd ├── is.epanet.inp.Rd ├── is.epanet.rpt.Rd ├── is.epanetmsx.rpt.Rd ├── is.expandedLinkTable.Rd ├── is.sparkline.Rd ├── is.sparklineTable.Rd ├── plot.epanet.inp.Rd ├── plot.epanet.rpt.Rd ├── plot.epanetmsx.rpt.Rd ├── plot.expandedLinkTable.Rd ├── plot.sparkline.Rd ├── plot.sparklineTable.Rd ├── plotElementsLegend.Rd ├── plotInpLinks.Rd ├── plotInpNodes.Rd ├── plotSparklineTable.Rd ├── print.summary.epanet.rpt.Rd ├── print.summary.epanetmsx.rpt.Rd ├── read.inp.Rd ├── read.msxrpt.Rd ├── read.rpt.Rd ├── read_lines_wrapper.Rd ├── sparkline.Rd ├── sparklineTable.Rd ├── summary.epanet.inp.Rd ├── summary.epanet.rpt.Rd ├── summary.epanetmsx.rpt.Rd └── write.inp.Rd └── tests ├── testthat.r └── testthat ├── 5deg.msxrpt ├── Net1-gui.inp ├── Net1-gui.rpt ├── Net1-noLinks-noNodes.rpt ├── Net1-noLinks.rpt ├── Net1-noNodes.rpt ├── Net1-noResult.rpt ├── Net1-pagebrks.rpt ├── Net1.inp ├── Net1.rpt ├── Net2-gui.rpt ├── Net2.inp ├── Net2.rpt ├── Net3-gui.rpt ├── Net3-nodes.rpt ├── Net3.inp ├── Net3.rpt ├── Net4.inp ├── README.rmd ├── empty.inp ├── example-noLinks.rpt ├── example-noNodes.rpt ├── example-noTitle.rpt ├── example.rpt ├── for-various-tests.inp ├── icdm13.inp ├── inp-pipe-table-some-statuses-empty.txt ├── oneprv.inp ├── oneprv.rpt ├── test_epanet.inp-s3.r ├── test_epanet.rpt-s3.r ├── test_epanetmsx.rpt-s3.r ├── test_expandedLinkTable-s3.r ├── test_inpFuncs.r ├── test_msxFuncs.r ├── test_plotSparklineTable.r ├── test_rptFuncs.r ├── test_sparkline-s3.r ├── test_sparklineTable-s3.r ├── test_text_file_reader.r ├── test_write-pkg-data.r ├── test_write.inp.r ├── writeNet1.inp ├── writeNet2.inp ├── writeNet3.inp └── writeOneprv.inp /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^\.travis\.yml$ 2 | ^\.gitignore$ 3 | ^img$ 4 | ^CONTRIBUTING.txt$ 5 | ^epanetReader.Rcheck$ 6 | ^epanetReader_*.tar.gz$ 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear on external disk 35 | .Spotlight-V100 36 | .Trashes 37 | 38 | # Directories potentially created on remote AFP share 39 | .AppleDB 40 | .AppleDesktop 41 | Network Trash Folder 42 | Temporary Items 43 | .apdisk 44 | 45 | # vim files 46 | *~ 47 | *swp 48 | *.prefs 49 | .project 50 | 51 | # stuff generated by rmarkdown 52 | README_files 53 | js 54 | css 55 | images 56 | index.html 57 | README.html 58 | 59 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: R 2 | cache: packages 3 | 4 | r_packages: 5 | - covr 6 | 7 | after_success: 8 | - Rscript -e 'library(covr); codecov()' 9 | -------------------------------------------------------------------------------- /CONTRIBUTING.txt: -------------------------------------------------------------------------------- 1 | Contributions are welcome! 2 | 3 | The developer sign-off should include the reference to the DCO (example below): 4 | DCO 1.1 Signed-off-by: Random J Developer 5 | 6 | 7 | Developer's Certificate of Origin 1.1 8 | 9 | By making a contribution to this project, I certify that: 10 | 11 | (a) The contribution was created in whole or in part by me and I 12 | have the right to submit it under the open source license 13 | indicated in the file; or 14 | 15 | (b) The contribution is based upon previous work that, to the best 16 | of my knowledge, is covered under an appropriate open source 17 | license and I have the right under that license to submit that 18 | work with modifications, whether created in whole or in part 19 | by me, under the same open source license (unless I am 20 | permitted to submit under a different license), as indicated 21 | in the file; or 22 | 23 | (c) The contribution was provided directly to me by some other 24 | person who certified (a), (b) or (c) and I have not modified 25 | it. 26 | 27 | (d) I understand and agree that this project and the contribution 28 | are public and that a record of the contribution (including all 29 | personal information I submit with it, including my sign-off) is 30 | maintained indefinitely and may be redistributed consistent with 31 | this project or the open source license(s) involved. 32 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: epanetReader 2 | Type: Package 3 | Title: Read Epanet Files into R 4 | Version: 0.8.0 5 | Date: 2018-09-12 6 | Author: Bradley J. Eck 7 | Maintainer: Bradley Eck 8 | Depends: 9 | R (>= 3.0.0), 10 | graphics, 11 | utils 12 | Suggests: 13 | testthat, 14 | epanet2toolkit, 15 | data.table (>= 1.11.2) 16 | Description: Reads water network simulation data in 'Epanet' text-based 17 | '.inp' and '.rpt' formats into R. Also reads results from 'Epanet-msx'. 18 | Provides basic summary information and plots. The README file has a 19 | quick introduction. See 20 | for more information on the Epanet software for modeling 21 | hydraulic and water quality behavior of water piping systems. 22 | License: MIT + file LICENSE 23 | URL: https://github.com/bradleyjeck/epanetReader 24 | LazyData: true 25 | RoxygenNote: 6.0.1 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2018 2 | COPYRIGHT HOLDER: IBM Corp. 3 | 4 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method(plot,epanet.inp) 4 | S3method(plot,epanet.rpt) 5 | S3method(plot,epanetmsx.rpt) 6 | S3method(plot,expandedLinkTable) 7 | S3method(plot,sparkline) 8 | S3method(plot,sparklineTable) 9 | S3method(print,summary.epanet.rpt) 10 | S3method(print,summary.epanetmsx.rpt) 11 | S3method(summary,epanet.inp) 12 | S3method(summary,epanet.rpt) 13 | S3method(summary,epanetmsx.rpt) 14 | export(epanetDefaultOptions) 15 | export(expandedLinkTable) 16 | export(is.epanet.inp) 17 | export(is.epanet.rpt) 18 | export(is.epanetmsx.rpt) 19 | export(is.expandedLinkTable) 20 | export(is.sparkline) 21 | export(is.sparklineTable) 22 | export(plotElementsLegend) 23 | export(plotInpLinks) 24 | export(plotInpNodes) 25 | export(plotSparklineTable) 26 | export(read.inp) 27 | export(read.msxrpt) 28 | export(read.rpt) 29 | export(read_lines_wrapper) 30 | export(sparkline) 31 | export(sparklineTable) 32 | export(write.inp) 33 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | epanetReader version 0.7.0 (released May 2018) 2 | ============================================= 3 | Changes: 4 | * added support for reading energy usage table from rpt files 5 | * switched from Kmisc::readlines to data.table::fread for faster reading of files 6 | due to absence of Kmisc on CRAN 7 | 8 | 9 | epanetReader version 0.6.2 (released Jan 2018) 10 | ============================================= 11 | Changes: 12 | * added is.XXX functions to check class of S3 objects 13 | * update built-in datasets with latest package output and check this with examples 14 | * handle inp file with an empty options section 15 | 16 | 17 | epanetReader version 0.4.0 (released Aug 2016) 18 | ============================================== 19 | Changes: 20 | * Use readlines from package Kmisc, if available, to speed up reading of large files 21 | 22 | * Added write.inp() function for writing inp files from an R object 23 | 24 | * Allow page breaks in rpt files to support reading rpt files 25 | created by Epanet's Windows GUI 26 | 27 | * Added citation information for recently published papers 28 | 29 | * Added support for reading sections of inp files that were not supported yet 30 | 31 | * Handled % sign in rpt file node result header for water trace analysis 32 | 33 | 34 | epanetReader version 0.3.1 (released Feb 2016) 35 | ============================================== 36 | 37 | Changes: 38 | * Added read.msxrpt() function to read results of multi-species 39 | water quality simulations made with EPANET-MSX 40 | 41 | * Added plotSparklineTable() function to generate tables 42 | of sparklines for exploratory analysis 43 | 44 | * Added data objects Net1 and Net1rpt in rdata format so 45 | some examples run without having to parse the text files. 46 | 47 | * Changed treatment of some columns of sections of .inp files from 48 | character to factor to improve summaries (e.g. Pipe Status, Valve Type) 49 | 50 | * Added support to read Status and Demands sections of .inp files 51 | 52 | * Plotting changes for simulation results: fixed bug for plotting with valves, 53 | changed aspect ratio to 1 for maps 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /R/Net1-data.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | #' Epanet's Net1 Example 10 | #' 11 | #' A dataset created by reading the Net1.inp file 12 | #' distributed with Epanet using this package's 13 | #' read.inp() function. 14 | #' 15 | #' @name Net1 16 | #' @docType data 17 | #' 18 | #' @usage Net1 19 | #' 20 | #' @format An object of class \code{epanet.inp} created by \link{read.inp}. 21 | #' @source http://www.epa.gov/sites/production/files/2014-06/en2setup_0.exe 22 | #' @examples 23 | #' #confirm built-in dataset matches output of read.inp 24 | #' inp <- file.path( find.package("epanetReader"), "extdata","Net1.inp") 25 | #' n1 <- suppressWarnings( read.inp(inp) ) 26 | #' ok <- isTRUE( all.equal(Net1, n1)) 27 | #' if( ok==FALSE) stop("built-in Net1 doesn't match read.inp") 28 | NULL 29 | -------------------------------------------------------------------------------- /R/Net1rpt-data.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015, 2018 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | #' Epanet's Net1 Example 10 | #' 11 | #' A dataset created by reading the Net1.rpt file 12 | #' distributed with Epanet using this package's 13 | #' read.rpt() function. 14 | #' 15 | #' @name Net1rpt 16 | #' @docType data 17 | #' @usage Net1rpt 18 | #' @format An object of class \code{epanet.rpt} created by \link{read.rpt}. 19 | #' @examples 20 | #' #confirm built-in dataset matches output of read.rpt 21 | #' rpt <- file.path( find.package("epanetReader"), "extdata","Net1.rpt") 22 | #' n1r <- read.rpt(rpt) 23 | #' ok <- isTRUE( all.equal(Net1rpt, n1r)) 24 | #' if( ok==FALSE) stop("built-in Net1rpt doesn't match read.rpt") 25 | NULL 26 | -------------------------------------------------------------------------------- /R/epanetReader.r: -------------------------------------------------------------------------------- 1 | #************************************* 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************* 8 | 9 | #' Read text files from Epanet into R 10 | #' 11 | #' \pkg{epanetReader} is a package for reading water network information 12 | #' and simulation results in Epanet's .inp 13 | #' and .rpt files into R. See functions \link{read.inp}, 14 | #' \link{read.rpt}, and \link{read.msxrpt} for some examples. 15 | #' 16 | #' @docType package 17 | #' @name epanetReader 18 | #' @author Bradley J. Eck 19 | 20 | NULL 21 | -------------------------------------------------------------------------------- /R/epanetmsx.rpt-s3.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | #' Read msx results 10 | #' 11 | #' reads an Epanet-msx .rpt file into R 12 | #' 13 | #' @aliases epanetmsx.rpt 14 | #' @export 15 | #' @param file the name of the file to read 16 | #' @return Returns an epanetmsx.rpt S3 object . 17 | #' 18 | #' \item{nodeResults}{data.frame} 19 | #' \item{linkResults}{data.frame} 20 | #' @details Specify the needed outputs from an Epanet-msx simulation in the 21 | #' [REPORT] section of the .msx file to create reports for reading with 22 | #' with this function. 23 | #' 24 | #' The function returns an S3 object (list) with a data.frame for node results and 25 | #' data.frame for link results. These data.frames contain results from all 26 | #' the time periods to facilitate time series plots. 27 | #' 28 | #' @references Shang, F., Uber, J.G., Rossman, L.A. (2011) 29 | #' EPANET Multi-species Extension User's Manual. 30 | #' US Environmental Protection Agency, Cincinnati. 31 | #' @examples 32 | #' # path to example file included with this package 33 | #' msr <- file.path( find.package("epanetReader"), "extdata","example.rpt") 34 | #' 35 | #' #read the results into R 36 | #' x <- read.msxrpt(msr) 37 | #' names(x) 38 | #' summary(x) 39 | #' plot(x) 40 | read.msxrpt <-function( file ){ 41 | 42 | mro <- epanetmsx.rpt(file) 43 | return( mro) 44 | 45 | } 46 | 47 | 48 | epanetmsx.rpt <- function( file ) { 49 | # this based heavily on the epanet.rpt function 50 | 51 | # read all the lines in the file 52 | allLines <- read_lines_wrapper(file) 53 | #checkRptFile( allLines ) 54 | 55 | title <- getTitle( allLines) 56 | 57 | lengthOfAllLines <- length( allLines) 58 | 59 | resLines <- grep("<<<.+>>>", allLines) 60 | numTables <- length(resLines) 61 | 62 | # empty lists of results 63 | nodeResList <- list() 64 | linkResList <- list() 65 | 66 | # initialize indices for these lists 67 | ni <- 0 # node index 68 | li <- 0 # link index 69 | 70 | # go through the tables 71 | for( i in 1:numTables ){ 72 | # get the section 73 | sectRange <- .getSectionRange( i, resLines, lengthOfAllLines) 74 | sect <- allLines[ sectRange$start : sectRange$end ] 75 | 76 | # create a data frame from this section 77 | df <- msxSection2df( sect ) 78 | 79 | # decide if it's for link or node results 80 | isNODE <- grepl( "Node", sect[1] ) 81 | isLINK <- grepl( "Link", sect[1] ) 82 | 83 | #add data to approriate list of data frames 84 | if( isNODE ){ 85 | # increment node indexer 86 | ni <- ni + 1 87 | nodeResList[[ ni ]] <- df 88 | } 89 | 90 | if( isLINK ){ 91 | # increment indexer 92 | li <- li + 1 93 | linkResList[[ li ]] <- df 94 | } 95 | } 96 | 97 | # combine all these results together 98 | nodeResDF <- do.call("rbind", nodeResList ) 99 | linkResDF <- do.call("rbind", linkResList ) 100 | 101 | # and make a list of the to return 102 | allResults <- list( Title = title, 103 | nodeResults = nodeResDF, 104 | linkResults = linkResDF ) 105 | 106 | class(allResults) <- "epanetmsx.rpt" 107 | 108 | return( allResults ) 109 | } 110 | 111 | 112 | #' Summary of Epanet-msx Simulation Results 113 | #' 114 | #' Provides a basic summary of simulation results 115 | #' 116 | #' @export 117 | #' @param object of epanetmsx.rpt class 118 | #' @param ... further arguments passed to summary() 119 | summary.epanetmsx.rpt <- function( object, ...){ 120 | 121 | # time info (you have results from tmin to tmax at an interval of delta_t) 122 | 123 | 124 | 125 | ################ 126 | # node results 127 | ################ 128 | 129 | # unique node IDs 130 | uni <- unique(object$nodeResults$ID) 131 | if( length(uni) > 0 ){ 132 | # node result names 133 | nrn <- names(object$nodeResults) 134 | 135 | # node result summary over species 136 | jmax <- length(nrn) - 1 137 | # species results 138 | nsr <- object$nodeResults[,3:jmax] 139 | # species names 140 | nds <- names(nsr) 141 | nrs <- summary(nsr ) 142 | 143 | # time info for nodes 144 | nodeTimeRangeSecs <- range(object$nodeResults$timeInSeconds) 145 | nodeDeltaT <- mean(diff( object$nodeResults$timeInSeconds) ) 146 | 147 | } else { 148 | # no node results 149 | nodeTimeRangeSecs <- NULL 150 | nodeDeltaT <- NULL 151 | nrs <- NULL 152 | nds <- NULL 153 | 154 | } 155 | 156 | ############### 157 | # link results 158 | ############### 159 | 160 | uli <- unique(object$linkResults$ID) 161 | if( length(uli) > 0 ){ 162 | lrn <- names(object$linkResults) 163 | jmax <- length(lrn) - 1 164 | lsr <- object$linkResults[,3:jmax] 165 | lks <- names(lsr) 166 | lrs <- summary(lsr ) 167 | linkTimeRangeSecs <- range(object$linkResults$timeInSeconds) 168 | linkDeltaT <- mean(diff( object$linkResults$timeInSeconds) ) 169 | } else { 170 | # no links 171 | linkTimeRangeSecs <- NULL 172 | linkDeltaT <- NULL 173 | lrs <- NULL 174 | lks <- NULL 175 | } 176 | 177 | 178 | # collect into an object 179 | msxrptSmry <- list( Title = object$Title, 180 | #nodes 181 | numNodes = length( uni ), 182 | uniqueNodeIDs = uni, 183 | nodeSpecies = nds, 184 | nodeTimeRangeInSeconds = nodeTimeRangeSecs, 185 | nodeTimestep = nodeDeltaT, 186 | nodeResSmry = nrs, 187 | #links 188 | numLinks = length( uli ), 189 | uniqueLinkIDs = uli, 190 | linkSpecies = lks, 191 | linkTimeRangeInSeconds = linkTimeRangeSecs, 192 | linkTimestep = linkDeltaT, 193 | linkResSmry = lrs ) 194 | 195 | class(msxrptSmry) <- "summary.epanetmsx.rpt" 196 | 197 | return( msxrptSmry) 198 | 199 | } 200 | 201 | 202 | 203 | #' Print msx rpt summary 204 | #' 205 | #' The function prints a summary of multi-species simulation results 206 | #' contained in the report file 207 | #' 208 | #' @export 209 | #' @param x a summary.epanetmsx.rpt object 210 | #' @param ... further arguments passed to print 211 | print.summary.epanetmsx.rpt <- function(x,...){ 212 | 213 | cat( x$Title) 214 | cat("\n") 215 | 216 | # node results 217 | cat(" node results\n") 218 | print( x$nodeResSmry) 219 | 220 | # link results 221 | cat(" Link results\n") 222 | print( x$linkResSmry) 223 | 224 | } 225 | 226 | 227 | 228 | #' Plot method for epanetmsx.rpt 229 | #' 230 | #' Plots a sparkline table of Epanet-msx results 231 | #' 232 | #' @export 233 | #' @param x epanetmsx.rpt object 234 | #' @param elementType character indicating whether results for "nodes" or links" should be plotted 235 | #' @param ... further arguments passed to plotSparklineTable 236 | #' @seealso plotSparklineTable 237 | plot.epanetmsx.rpt <- function(x, elementType = 'Nodes',...){ 238 | 239 | # argument checking 240 | if( length(elementType) > 1 ) stop("elementType must have length 1") 241 | 242 | sx <- summary(x) 243 | 244 | if( grepl("nodes", elementType, ignore.case = TRUE ) ){ 245 | 246 | xl <- c( utils::head(x$nodeResults$Time, 1), 247 | utils::tail(x$nodeResults$Time, 1) ) 248 | 249 | plotSparklineTable( x$nodeResults, row.var = 'ID', col.vars = sx$nodeSpecies, 250 | xvar = 'timeInSeconds', 251 | xrange.labels = xl , ... ) 252 | 253 | 254 | } else if( grepl("links", elementType, ignore.case = TRUE) ){ 255 | xl <- c( utils::head(x$linkResults$Time, 1), 256 | utils::tail(x$linkResults$Time, 1) ) 257 | 258 | plotSparklineTable( x$linkResults, row.var = 'ID', col.vars = sx$linkSpeices, 259 | xvar = 'timeInSeconds', 260 | xrange.labels = xl, ... ) 261 | 262 | } else { 263 | 264 | stop("illegal value of argument 'elementType' ") 265 | 266 | } 267 | } 268 | 269 | 270 | 271 | 272 | #' Check if an object has class 'epanetmsx.rpt' 273 | #' 274 | #' @param x an R object 275 | #' @export 276 | is.epanetmsx.rpt <- function(x){ 277 | inherits(x,"epanetmsx.rpt") 278 | 279 | } 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | -------------------------------------------------------------------------------- /R/expandedLinkTable-s3.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | # File: expandedLinkTable-s3.r 10 | # 11 | # Purpose: define an s3 class for a link table 12 | # with coordinates added 13 | 14 | 15 | #' Expanded Link Table 16 | #' 17 | #' Create an expandedLinkTable object by adding node coordinates to a 18 | #' data frame of pipes, pumps, or valves. 19 | #' 20 | #' @export 21 | #' @param Links data frame of Pipes, Pumps or Valves of from epanet.inp 22 | #' @param Coordinates table of epanet.inp 23 | #' @return an expandedLinkTable object 24 | #' @examples 25 | #' x <- expandedLinkTable(Net1$Pipes, Net1$Coordinates) 26 | #' print(x) 27 | #' plot(x) 28 | expandedLinkTable <- function( Links, Coordinates ){ 29 | 30 | # handle a missing table 31 | if( is.null(Links) ) { 32 | return(NA) 33 | #ept <- NA 34 | } else { 35 | ept <- merge( x = Links, by.x = "Node1", all.x = TRUE, sort = FALSE, 36 | y = Coordinates, by.y = "Node" ) 37 | #rename 38 | names(ept)[ grep("X.coord", names(ept)) ] <- "x1" 39 | names(ept)[ grep("Y.coord", names(ept)) ] <- "y1" 40 | 41 | #Node2 coords 42 | ept <- merge( x = ept, by.x = "Node2", all.x = TRUE, sort = FALSE, 43 | y = Coordinates, by.y = "Node" ) 44 | #rename 45 | names(ept)[ grep("X.coord", names(ept)) ] <- "x2" 46 | names(ept)[ grep("Y.coord", names(ept)) ] <- "y2" 47 | 48 | # midpoints for labeling 49 | ept$midx <- (ept$x1 + ept$x2) / 2 50 | ept$midy <- (ept$y1 + ept$y2) / 2 51 | 52 | # put the columns into order 53 | ept <- ept[ ,c( names(Links), 'x1', 'y1', 'x2', 'y2', 'midx', 'midy') ] 54 | 55 | } 56 | 57 | class(ept) <- c("expandedLinkTable", "data.frame") 58 | 59 | return(ept) 60 | } 61 | 62 | #' plot an expanded link table 63 | #' 64 | #' @export 65 | #' @param x object of type expandedLinkTable 66 | #' @param add logical indicating whether to add to the currently active plot. 67 | #' add=FALSE creates a new plot. 68 | #' @param label logical indicating if the links should be labeled at the mid points 69 | #' @param linewidths passed to lwd argument in segments() 70 | #' @param color passed to col argument in segments() 71 | #' @param ... further arguments passed to segments() 72 | #' @details 73 | #' An implementation of the generic plot function for 74 | #' expandedLinkTable objects. Links are drawn using segments(). 75 | #' Useful for building up network plots. 76 | plot.expandedLinkTable <- function(x, add=FALSE, label=FALSE, linewidths = 3, color = 'black', ...){ 77 | 78 | if( add == FALSE ){ 79 | # generate a blank plot first 80 | graphics::plot( range( c(x$x1, x$x2) ), 81 | range( c(x$y1, x$y2) ), 82 | type = 'n', 83 | xlab = "", xaxt = 'n', 84 | ylab = "", yaxt = 'n' 85 | ) 86 | 87 | } 88 | 89 | # just put the segments out there 90 | graphics::segments( x0 = x$x1, y0 = x$y1, 91 | x1 = x$x2, y1 = x$y2, 92 | lwd = linewidths, col = color, ... ) 93 | 94 | 95 | if( label == TRUE ){ 96 | graphics::text( x$midx, x$midy, x$ID) 97 | } 98 | } 99 | 100 | #' Check if an object has class 'expandedLinkTable' 101 | #' 102 | #' @param x an R object 103 | #' @export 104 | is.expandedLinkTable <- function( x ){ 105 | inherits( x, "expandedLinkTable") 106 | } 107 | -------------------------------------------------------------------------------- /R/msxFuncs.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | 10 | 11 | msxSection2df <- function( sect ){ 12 | # make a section into it's own data frame 13 | 14 | imax <- length(sect) 15 | 16 | # Take column headings from labels. 17 | headerRow1 <- unlist(strsplit( gsub("^\\s+", "", sect[3] ), "\\s+")) 18 | columnNames <- headerRow1 19 | 20 | 21 | # set colClasses, everything is numeric execpt fist 22 | # and last column 23 | lcn <- length( columnNames) 24 | cc <- rep("numeric", lcn ) 25 | cc[1] <- "character" # for ID column 26 | 27 | 28 | # make the section a data frame 29 | df <- utils::read.table( text = sect[6:imax], 30 | col.names=columnNames, 31 | colClasses = cc, 32 | strip.white = TRUE, fill = TRUE, header = FALSE ) 33 | 34 | # put an id column 35 | df$ID <- getID(sect[1]) 36 | 37 | # move it to the first col 38 | df <- df[ , c('ID', columnNames)] 39 | 40 | # convert that stamp into sections 41 | time_secs <- sapply(df$Time, .timeStampToSeconds ) 42 | 43 | df$timeInSeconds <- time_secs 44 | 45 | # Make a new column "ID" rather than 46 | # "Node" or "Link" to be consistent with inp objects 47 | 48 | 49 | 50 | return( df ) 51 | } 52 | 53 | # get the element ID from the 54 | # marker <<< Node/Link ID >>> 55 | # that starts the msx results tables 56 | getID <-function( marker ){ 57 | 58 | # gradually take out the unwanted parts 59 | m1 <- gsub("<<<", "", marker) 60 | m2 <- gsub(">>>", "", m1 ) 61 | m3 <- gsub("Node", "", m2 ) 62 | m4 <- gsub("Link", "", m3 ) 63 | ID <- gsub("\\s", "", m4) 64 | 65 | return(ID) 66 | } 67 | 68 | getTitle <-function( allLines ) { 69 | 70 | # it's between ******** and <<<< 71 | 72 | stars <- grep("\\*{3,}", allLines) 73 | i <- max(stars) + 2 74 | title <- allLines[i] 75 | 76 | hasTitle <- grepl("[A-Za-z]", title) 77 | if( hasTitle == FALSE){ 78 | title <- NULL 79 | } 80 | return(title) 81 | 82 | } 83 | -------------------------------------------------------------------------------- /R/plotSparklineTable.r: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # (c) Copyright IBM Corp. 2015 3 | # 4 | # Author: Bradley J. Eck 5 | ############################################################################### 6 | 7 | 8 | #' Plot Sparkline Table 9 | #' 10 | #' Generate a table of sparkline plots 11 | #' 12 | #' @export 13 | #' @param df data.frame of values to plot. 14 | #' @param row.var variable for rows of the table 15 | #' @param col.vars variables for columns of the table 16 | #' @param xvar optional name of variable for horizontal axis of sparkline plots 17 | #' @param xrange.labels optional vector of length 2 with labels for the first 18 | #' and last quantities plotted on x-axis, often a date and/or time 19 | #' 20 | #' @details Generates a table of 'sparkline' plots of data in df. rows the table correspond to 21 | #' different values of row.var. The table's first column gives the value of row.var. The 22 | #' remaining columns contain sparkline plots for the values of col.vars. When xvar is not 23 | #' provided values are plotted against their index in the extracted vector. The starting 24 | #' and ending values are labeled. 25 | #' Uses layout() function to arrange plots. 26 | #' 27 | #' @seealso 28 | #' yaletoolkit and sparkTable packages 29 | #' @references 30 | #' E. Tufte, Beautiful Evidence, Graphics Press, 2006. 31 | #' 32 | #' @examples 33 | #' plotSparklineTable( Orange, row.var = 'Tree', col.vars = c('age','circumference')) 34 | #' plotSparklineTable( Loblolly, row.var = 'Seed', col.vars = 'height') 35 | #' ## specify the x variable if you have it, especially if it differs 36 | #' plotSparklineTable(Theoph, row.var = 'Subject', col.vars = 'conc') 37 | #' ## a warning is normally issued with the ranges of xvar differ 38 | #' suppressWarnings( plotSparklineTable(Theoph, row.var = 'Subject', col.vars = 'conc', xvar = 'Time')) 39 | plotSparklineTable <- function( df, row.var, col.vars, xvar = NULL, xrange.labels = NULL ){ 40 | 41 | #this is now a wrapper function 42 | slt <- sparklineTable( df, row.var, col.vars, xvar, xrange.labels) 43 | graphics::plot(slt) 44 | 45 | } 46 | 47 | 48 | -------------------------------------------------------------------------------- /R/rptFuncs.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | # File: rptFuncs.r 10 | # 11 | # By: bradley.eck@ie.ibm.com 12 | # 13 | # Purpose: functions to read an rpt file 14 | 15 | .getSectionRange <- function( j, resLines, lengthOfAllLines ) { 16 | # get the section of the rpt file that corresponds 17 | # to the j-th entry in resLines 18 | 19 | startLine <- resLines[j] 20 | 21 | numTables <- length( resLines ) 22 | 23 | if( j < numTables ){ 24 | endLine <- resLines[j+1] - 1 25 | } else { 26 | endLine <- lengthOfAllLines - 1 27 | } 28 | 29 | rl <- list( start = startLine, end = endLine ) 30 | return( rl ) 31 | } 32 | 33 | .getTimeStamp <- function( tsLine){ 34 | 35 | tokens <- unlist( strsplit(tsLine, "\\s") ) 36 | 37 | # stamp in token after "at" 38 | stamp <- tokens[ grep( "at", tokens) + 1 ] 39 | 40 | if( length(stamp) == 0 ){ 41 | # use a time of zero if none is supplied 42 | stamp <- "0:00:00" 43 | } 44 | return( stamp ) 45 | 46 | } 47 | 48 | .timeStampToSeconds <- function( stamp ){ 49 | 50 | tokens <- unlist(strsplit(stamp,":")) 51 | 52 | if( length(tokens) < 2 ){ 53 | stop(paste("don't have interpretation for stamp", stamp )) 54 | } 55 | if( length(tokens) > 3 ){ 56 | stop(paste("don't have interpretation for stamp", stamp )) 57 | } 58 | 59 | 60 | hours <- tokens[1] 61 | minutes <- tokens[2] 62 | 63 | m <- as.integer(minutes) 64 | if( m > 59){ 65 | stop(paste0("invalid minutes in ", stamp)) 66 | } 67 | 68 | 69 | totalSeconds <- as.integer(hours) * 3600 + 70 | m * 60 71 | 72 | if( length( tokens) == 3 ){ 73 | 74 | seconds <- tokens[3] 75 | s <- as.integer(seconds) 76 | if( s > 59){ 77 | stop(paste0("invalid seconds in ", stamp)) 78 | } 79 | 80 | totalSeconds <- totalSeconds + as.integer(seconds) 81 | } 82 | 83 | return( as.integer(totalSeconds) ) 84 | } 85 | 86 | .section2df <- function( sect ){ 87 | # make a section into it's own data frame 88 | 89 | imax <- length(sect) 90 | 91 | # Take column headings from labels. Sometimes first column is labeled 92 | # in two rows, sometimes in 1. See tests. 93 | headerRow1 <- unlist(strsplit( gsub("^\\s+", "", sect[3] ), "\\s+")) 94 | headerRow2 <- unlist(strsplit( gsub("^\\s+", "", sect[4] ), "\\s+")) 95 | # When the water quality is a trace the header row includes a percent symbol 96 | # in this case modify headerRow1 one so that the last entry is Pct_from_ 97 | gpl <- grepl("\\%", headerRow1) 98 | if( max(gpl) > 0 ){ 99 | gp <- grep("\\%", headerRow1) 100 | cn <- paste("Pct", headerRow1[gp +1], utils::tail(headerRow2,1), sep = "_") 101 | headerRow1 <- c( headerRow1[1:(gp-1)], cn) 102 | } 103 | 104 | ## figure out the column names 105 | hr1_link <- grepl("link", headerRow1[1], ignore.case=TRUE) 106 | hr1_node <- grepl("node", headerRow1[1], ignore.case=TRUE) 107 | 108 | if( hr1_link | hr1_node){ 109 | columnNames <- c(headerRow1, "note") 110 | } else { 111 | # node or link is not in first col of first row 112 | columnNames <- c("ID", headerRow1, "note") 113 | } 114 | 115 | # name the first column "ID" rather than 116 | # "Node" or "Link" to be consistent with inp objects 117 | columnNames[1] <- "ID" 118 | 119 | # a quirk of the gui rpt file 120 | columnNames <- gsub( "VelocityUnit", "Velocity", columnNames) 121 | 122 | # set colClasses, everything is numeric execpt 123 | # columns: ID, Status, and note 124 | lcn <- length( columnNames) 125 | cc <- rep("numeric", lcn ) 126 | cc[1] <- "character" # for ID column 127 | cc[lcn] <- "character" # for note column 128 | #status column 129 | cc[grep("Status", columnNames)] <- "factor" 130 | 131 | 132 | # make the section a data frame 133 | df <- utils::read.table( text = sect[6:imax], 134 | col.names=columnNames, 135 | colClasses = cc, 136 | strip.white = TRUE, fill = TRUE, header = FALSE ) 137 | 138 | # now add the time info to the table 139 | stamp <- .getTimeStamp( sect[1] ) 140 | 141 | # convert that stamp into sections 142 | time_secs <- .timeStampToSeconds(stamp) 143 | 144 | df$Timestamp <- stamp 145 | df$timeInSeconds <- time_secs 146 | 147 | return( df ) 148 | } 149 | 150 | #' Bin Breaker 151 | #' 152 | #' Generate break points for use with cut() 153 | #' and range labels based on sample max and min 154 | #' 155 | #' @param x vector to find cuts for 156 | #' @param nbin number of bins 157 | #' @return list with elements Breaks and Labels 158 | #' @details 159 | #' Helpful in making labels use the acutal max and min rather than 160 | #' the +/- 1% cut() uses by default. 161 | binBreaker <- function( x, nbin){ 162 | 163 | xmax <- max(x, na.rm = TRUE ) 164 | xmin <- min(x, na.rm = TRUE ) 165 | 166 | # use cut() to find break points for the specified number of bins 167 | labs <- levels( cut( x, breaks = nbin )) 168 | # from help(cut) example on getting break points 169 | brks <- cbind(lower = as.numeric( sub("\\((.+),.*", "\\1", labs) ), 170 | upper = as.numeric( sub("[^,]*,([^]]*)\\]", "\\1", labs) )) 171 | 172 | # get the breaks to use with cut() 173 | brkpts4cut <- c( brks[1,1], brks[,2]) 174 | 175 | # force a zero in the legend values 176 | labs4legend <- levels( cut( x, breaks = c( xmin, brks[1:(nbin-1),2], xmax) )) 177 | 178 | #combine results into list and return 179 | return( list( Breaks = brkpts4cut, Labels = labs4legend)) 180 | 181 | } 182 | 183 | 184 | 185 | checkRptFile <- function( allLines ){ 186 | # check rpt file format 187 | 188 | 189 | # look for node results and link results 190 | hasNodeResults <- as.logical( max( grepl("Node Results", allLines))) 191 | hasLinkResults <- as.logical( max( grepl("Link Results", allLines))) 192 | hasEnergyResults <- as.logical( max( grepl("Energy Usage", allLines))) 193 | 194 | if( hasNodeResults == FALSE ){ 195 | 196 | msg <- paste(" Node results not found in .rpt file. \n", 197 | "Add the line 'Nodes All' to the [REPORT] section of the .inp file.") 198 | warning(msg) 199 | } 200 | 201 | if( hasLinkResults == FALSE ){ 202 | 203 | msg <- paste(" Link results not found in .rpt file. \n", 204 | "Add the line 'Links All' to the [REPORT] section of the .inp file.") 205 | warning(msg) 206 | } 207 | 208 | 209 | 210 | 211 | if( ( hasNodeResults == FALSE )& 212 | ( hasLinkResults == FALSE )& 213 | ( hasEnergyResults==FALSE ) ){ 214 | 215 | # no results to read, give error 216 | stop("No results to read") 217 | 218 | } 219 | 220 | } 221 | 222 | cleanRptLines <- function( allLines ){ 223 | 224 | # lines with page break 225 | pb_lines <- grepl("\f", allLines) 226 | myLines <- allLines[ !pb_lines ] 227 | 228 | # delete lines starting with __Page_# 229 | pg_lines <- grepl("^ Page ", myLines) 230 | myLines <- myLines[ !pg_lines ] 231 | 232 | # delete lines containing "(continued)" along with 233 | continues_header <- rep(FALSE, length(myLines)) 234 | continues_lines <- grep("(continued)", myLines) 235 | continues_header_lines <- unlist( lapply(continues_lines, seq, by=1, length.out=5)) 236 | continues_header[ continues_header_lines] <- TRUE 237 | 238 | cleanLines <- myLines[ !continues_header ] 239 | 240 | return( cleanLines) 241 | 242 | } 243 | 244 | getEnergyUsage <- function( cleanLines ){ 245 | 246 | tag <- grep("Energy Usage", cleanLines) 247 | 248 | result <- NULL 249 | 250 | if( length(tag) > 1 ){ 251 | warning("The string 'Energy Usage' appeared more than once in the rpt file so the energy usage table was not read") 252 | 253 | } else if ( length(tag) == 1 ){ 254 | # Energy Usage table exists 255 | begin <- tag + 5 256 | bars <- grep("-----",cleanLines) 257 | end <- bars[ which( bars > begin)[1] ] - 1 258 | 259 | # get the correct names for the cols 260 | varnames <- c("Pump","usageFactor","avgEfficiency", "kWh_per_m3","avg_kW","peak_kW","dailyCost") 261 | if( grepl("Mgal",cleanLines[ tag+3])){ 262 | varnames[4] <- "kWh_per_Mgal" 263 | } 264 | 265 | # build a data frame of energy usage 266 | egyusg <- utils::read.table( text = cleanLines[begin:end], 267 | stringsAsFactors = FALSE, 268 | col.names = varnames) 269 | result <- egyusg 270 | 271 | } 272 | 273 | return( result) 274 | 275 | } 276 | -------------------------------------------------------------------------------- /R/sparkline-s3.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | #' Sparkline 10 | #' 11 | #' Create sparkline object by extracting from a data frame 12 | #' 13 | #' @export 14 | #' @param df data.frame from which data for the sparkline is extracted 15 | #' @param id.var variable in df with IDs 16 | #' @param ID value in id.var on which to extract 17 | #' @param yvar name of variable for the y values in the sparkline 18 | #' @param xvar optional name of variable for horizontal axis of sparkline plots 19 | #' @details 20 | #' Creates an object with info for a single sparkline by extracting 21 | #' from a data.frame. The function works on data.frames with one column of ID variables 22 | #' and possibly several columns of other variables. The main use is 23 | #' as a helper function for building up a \link{sparklineTable}. 24 | #' 25 | #' @examples 26 | #' ## look at the names in the built-in data set Theoph 27 | #' names(Theoph) 28 | #' ## make sparkline object for the concentration over time in subject 2 29 | #' sl <- sparkline(df= Theoph, id.var = 'Subject', ID = 2, yvar='conc', xvar = 'Time') 30 | #' plot(sl) 31 | sparkline <- function( df, id.var, ID, yvar, xvar){ 32 | 33 | D <- df[ which( df[ , id.var] == ID ) , c( xvar, yvar ) ] 34 | D <- as.matrix(D) 35 | # if D has only one column we assume it's already in the right order 36 | # and add a vector of indices to plot against 37 | # if D has two columns we sort it into xvar order 38 | 39 | Dncol <- dim(D)[2] 40 | Dnrow <- dim(D)[1] 41 | 42 | colvarname <- paste(ID, yvar) 43 | 44 | if( Dncol == 1 ){ 45 | 46 | D <- cbind( 1:Dnrow, D) 47 | 48 | colnames(D) <- c("index", colvarname) 49 | 50 | } else if( Dncol == 2) { 51 | 52 | xord <- order( D[ , 1]) 53 | D <- D[xord, ] 54 | 55 | colnames(D) <- c(xvar, colvarname) 56 | 57 | } else { 58 | stop("D should only have two cols, something is wrong") 59 | } 60 | 61 | class(D) <- 'sparkline' 62 | 63 | return(D) 64 | 65 | } 66 | 67 | #' Plot a sparkline 68 | #' 69 | #' @export 70 | #' @param x sparkline object 71 | #' @param ... further arguments passed to plot.default 72 | #' @details 73 | #' Implementation of the generic plot function for a single sparkline object. 74 | #' The primarily used to build up plots of a sparklineTable 75 | #' @seealso sparkline 76 | plot.sparkline <- function( x, ... ){ 77 | 78 | dimxy <- dim(x) 79 | N <- dimxy[1] 80 | # argument checking 81 | if( dimxy[2] != 2 ) stop(" input x must have two columns") 82 | 83 | # give a 10% buffer in the vertical 84 | yr <- range(x[,2]) 85 | ybuff <- ( yr[2] - yr[1] ) * 0.10 86 | ylimits <- c( yr[1] - ybuff, yr[2] + ybuff ) 87 | 88 | # give a 1% buffer in the horizontal 89 | xr <- range(x[,1]) 90 | xbuff <- (xr[2] - xr[1]) * 0.01 91 | xlimits <- c(xr[1] - xbuff, xr[2] + xbuff ) 92 | 93 | graphics::plot.default(x, type = 'l', col = 'gray', 94 | xaxt='n', yaxt='n', xlab = '', ylab = '', 95 | ylim = ylimits, xlim = xlimits, 96 | frame.plot = FALSE, ... ) 97 | graphics::points( x[1,1], x[1,2], pch = 16, cex = .9 ) 98 | graphics::points( x[N,1], x[N,2], pch = 16, cex = .9 ) 99 | } 100 | 101 | 102 | #' Check if an object has class 'sparkline' 103 | #' 104 | #' @param x an R object 105 | #' @export 106 | is.sparkline <- function(x){ 107 | inherits(x,"sparkline") 108 | } 109 | -------------------------------------------------------------------------------- /R/sparklineTable-s3.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | # constructor for s3 class 10 | #' Sparkline Table 11 | #' 12 | #' Create S3 object of data for table of sparklines 13 | #' 14 | #' @export 15 | #' @param df data.frame of values to plot. 16 | #' @param row.var variable for rows of the table 17 | #' @param col.vars variables for columns of the table 18 | #' @param xvar optional name of variable for horizontal axis of sparkline plots 19 | #' @param xrange.labels optional vector of length 2 with labels for the first 20 | #' and last quantities plotted on x-axis, often a date and/or time 21 | #' @seealso plotSparklineTable 22 | #' 23 | sparklineTable <- function( df, row.var, col.vars, xvar = NULL, xrange.labels = NULL ){ 24 | 25 | #argument checking 26 | if( is.data.frame(df) == FALSE) stop("df must be a data.frame") 27 | if( length( row.var) != 1 ) stop("row.var must have length 1") 28 | if( (row.var %in% names(df)) == FALSE ) stop(paste("row.var", row.var, "is not a column in data.frame df")) 29 | if( min( col.vars %in% names(df)) < 1 ) stop(paste("at least one value in col.vars is not a column in data.frame df")) 30 | if( is.null(xvar) == FALSE ){ 31 | if( (xvar %in% names(df)) == FALSE ) { 32 | stop(paste("xvar", xvar, "is not a column in data.frame df")) 33 | } 34 | } 35 | # x range label 36 | xrl <- c("","") 37 | if( is.null(xrange.labels) == FALSE ){ 38 | if( length(xrange.labels) != 2 ) stop("xrange.labels must have length 2") 39 | xrl <- as.character(xrange.labels) 40 | } 41 | 42 | 43 | urv <- unique( df[ , row.var]) 44 | Nrv <- length(urv ) 45 | Ncv <- length(col.vars) 46 | M <- getLayoutMatrix( num.row.var = Nrv, 47 | num.col.vars = Ncv ) 48 | # number of sparklines 49 | Nsl <- Nrv * Ncv 50 | 51 | # need to create data structure for 52 | # sparkline table 53 | 54 | ################### 55 | # Constructor 56 | ################### 57 | 58 | # list of sparkline matrices 59 | sll <- list() 60 | 61 | k = 1 62 | # Loop over the rows 63 | for( i in 1:Nrv){ 64 | # Loop thru the params 65 | for(j in 1:Ncv){ 66 | # first param, start value 67 | xy <- sparkline( df, row.var, urv[i], col.vars[j], xvar) 68 | 69 | sll[[k]] <- xy 70 | k <- k + 1 71 | } 72 | } 73 | 74 | # check the data 75 | sparklineDataCheck( sll ) 76 | 77 | # make the table header 78 | H <- row.var 79 | for( j in 1:Ncv){ 80 | 81 | H <- c(H, xrl[1]) 82 | H <- c(H, col.vars[j]) 83 | H <- c(H, xrl[2]) 84 | 85 | #plotWord( xrl[1], font=2) 86 | #plotWord( col.vars[j], font = 2 , cex = 1) 87 | #plotWord( xrl[2], font=2) 88 | } 89 | 90 | # build up the object to return 91 | slt <- list( sparklines = sll, 92 | layoutMatrix = M, 93 | tableHeader = H, 94 | rowLabels = urv) 95 | 96 | class( slt ) <- 'sparklineTable' 97 | 98 | return( slt) 99 | } 100 | 101 | #' Plot Sparkline Table 102 | #' 103 | #' @export 104 | #' @param x object of class sparklineTable 105 | #' @param ... further arguments passed to par 106 | plot.sparklineTable <- function( x,... ){ 107 | 108 | ######################### 109 | # Plotting 110 | ######################### 111 | # create the plot grid 112 | oldpar <- graphics::par(no.readonly = TRUE) # keep up w the old params 113 | graphics::par( mar = c(0,0,0,0), oma = rep(1,4),...) 114 | graphics::layout( mat = x$layoutMatrix, respect = FALSE ) 115 | 116 | lapply( x$tableHeader, plotWord, font = 2) 117 | 118 | 119 | # Loop over the rows 120 | Nrv <- length( x$rowLabels) 121 | Ncv <- length(x$sparklines) / Nrv 122 | k = 1 123 | for( i in 1:Nrv){ 124 | 125 | plotWord( x$rowLabels[i]) 126 | 127 | # Loop thru the params 128 | for(j in 1:Ncv){ 129 | # first param, start value 130 | xy <- x$sparklines[[k]] 131 | N <- dim(xy)[1] 132 | plotWord( xy[1,2] ) 133 | graphics::plot( xy ) 134 | plotWord( xy[N,2] ) 135 | k = k + 1 136 | } 137 | } 138 | 139 | # go back to the old params 140 | graphics::par(oldpar) 141 | 142 | } 143 | 144 | 145 | 146 | sparklineDataCheck <- function( slt ){ 147 | # check data for which sparklines will be plotted to make 148 | # sure visualization will be faithful 149 | 150 | # (1) Do all sparklines have the same range of xvar ? 151 | kmax <- length( slt ) 152 | 153 | # calc the x range for each sparkline 154 | xrange <- list() 155 | for( k in 1:kmax){ 156 | xrange[[k]] <- range( slt[[k]][,1] ) 157 | } 158 | 159 | # see if they are all the same 160 | sameXrange <- ( length( unique(xrange)) == 1 ) 161 | 162 | if( sameXrange == FALSE ){ 163 | warning( "Sparklines have different ranges of X") 164 | } 165 | } 166 | 167 | getLayoutMatrix <- function( num.row.var, num.col.vars ){ 168 | 169 | 170 | # determine the matrix size for the layout 171 | nr <- 1 + num.row.var 172 | nc <- 1 + 3 * num.col.vars 173 | 174 | # col labels spread over three 175 | #header <- c(1, unlist( lapply ( 2:(num.col.vars+1), FUN = rep, times = 3 ) ) ) # param name takes up 3 columns 176 | #ki2j1 <- tail( header, 1 ) + 1 177 | #vals <- c(header, seq( from = ki2j1, by = 1, length.out = (nr-1) * nc ) ) 178 | 179 | vals <- 1 : (nr * nc) 180 | 181 | M <- matrix( data =vals, nrow = nr, ncol = nc, byrow = TRUE) 182 | 183 | return( M ) 184 | } 185 | 186 | plotWord <- function(w, ...){ 187 | 188 | if( is.numeric(w) ) { 189 | 190 | w <- format( w, digits = 3) 191 | } 192 | 193 | graphics::plot(c(0,1),c(0,1), type = 'n', 194 | xaxt='n', yaxt='n', xlab = '', ylab = '', 195 | frame.plot = FALSE ) 196 | graphics::text( .5, .5, w, ...) 197 | 198 | } 199 | 200 | #' Check if an object has class 'sparklineTable' 201 | #' 202 | #' @param x an R object 203 | #' @export 204 | is.sparklineTable <- function(x){ 205 | inherits(x,"sparklineTable") 206 | } 207 | -------------------------------------------------------------------------------- /R/text_file_reader.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2016 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | #' Read lines wrapper 9 | #' 10 | #' Wrapper function for different implementations of 11 | #' readlines functions 12 | #' 13 | #' @export 14 | #' @param file the name of the file to read 15 | #' @return character vector where each entry corresponds to 16 | #' a line in the file. 17 | #' @details 18 | #' calls Kmisc::readlines if available and base::readLines otherwise 19 | read_lines_wrapper <- function( file ){ 20 | 21 | sz <- base::file.info(file)$size 22 | size_MB <- sz / 1e6 23 | 24 | if( requireNamespace("data.table", quietly = TRUE)){ 25 | 26 | allLines <- data.table::fread(file, sep=NULL,colClasses = "character", strip.white=F, 27 | header=F,fill=T,data.table=F)[,1] 28 | 29 | 30 | } else { 31 | 32 | if( size_MB > 100){ 33 | warning("Consider installing package data.table to speed up file reading") 34 | } 35 | 36 | allLines <- readLines(file) 37 | 38 | } 39 | 40 | return (allLines) 41 | } 42 | -------------------------------------------------------------------------------- /R/write.inp.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2016 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | 10 | #' Write .inp file 11 | #' 12 | #' Write an epanet.inp object to a file 13 | #' 14 | #' @export 15 | #' @param x epanet.inp object to write 16 | #' @param file the name of the file where object is written 17 | #' @details 18 | #' Writes an epanet.inp object to a file suitable for simulation 19 | #' with EPANET. 20 | #' @return nothing 21 | #' @examples 22 | #' write.inp(Net1, "Net1-fromR.inp") 23 | #' n1 <- read.inp("Net1-fromR.inp") 24 | #' all.equal(Net1, n1) 25 | #' 26 | 27 | write.inp <- function(x, file){ 28 | 29 | cx <- class(x) 30 | if( cx != "epanet.inp" ) stop("x is not of class epanet.inp") 31 | 32 | file.create(file) 33 | 34 | nx = names(x) 35 | N <- length(x) 36 | for( i in 1:N){ 37 | section_name = toupper(nx[i]) 38 | tag <- paste0("[", section_name, "]") 39 | write( tag, file, append = TRUE) 40 | writeData( x[[i]], file, tag ) 41 | write("", file = file, append =TRUE) 42 | 43 | } 44 | write("[END]", file =file, append =TRUE) 45 | } 46 | 47 | writeData <- function(y, file, tag){ 48 | 49 | cy <- class(y) 50 | 51 | if( cy == 'character' ){ 52 | # write each entry as a line 53 | write(y, file, append = TRUE, ncolumns = 1 ) 54 | } else if( cy == 'data.frame'){ 55 | utils::write.table(y, file, append = TRUE, na = "", 56 | quote = F, col.names=F, row.names = F, sep = "\t") 57 | } else if( tag == "[OPTIONS]") { 58 | ny <- names(y) 59 | nyf <- gsub("_", " ", ny) 60 | s <- paste(nyf,y) 61 | # don't write options stored as NA 62 | s <- s[ which( is.na(y) == FALSE ) ] 63 | write(s, file, append=TRUE,file=file, ncolumns = 1 ) 64 | } else if( tag == "[PATTERNS]"){ 65 | np <- length(y) 66 | for( i in 1:np){ 67 | s <- paste( names(y)[i], y[[i]]) 68 | write(s,file,append=TRUE,file=file,ncolumns=1) 69 | } 70 | } else if( tag == "[CURVES]") { 71 | 72 | ynames <- names(y) 73 | NC <- length(ynames) 74 | 75 | for( i in 1:NC){ 76 | curv <- y[[i]] 77 | cname <- ynames[i] 78 | cx <- as.numeric( curv[[1]] ) 79 | cy <- as.numeric( curv[[2]] ) 80 | N <- length(cx) 81 | s <- cbind( rep(cname,N), cx, cy) 82 | utils::write.table(s, file, append=TRUE, 83 | quote = F, row.names=F, col.names = F ) 84 | } 85 | 86 | 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /data/Net1.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradleyjeck/epanetReader/b0a2c6ff1e71841f17fc95d2cd81de484b104d53/data/Net1.rdata -------------------------------------------------------------------------------- /data/Net1rpt.rdata: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradleyjeck/epanetReader/b0a2c6ff1e71841f17fc95d2cd81de484b104d53/data/Net1rpt.rdata -------------------------------------------------------------------------------- /img/Net1cl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradleyjeck/epanetReader/b0a2c6ff1e71841f17fc95d2cd81de484b104d53/img/Net1cl.png -------------------------------------------------------------------------------- /img/Net1inp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradleyjeck/epanetReader/b0a2c6ff1e71841f17fc95d2cd81de484b104d53/img/Net1inp.png -------------------------------------------------------------------------------- /img/Net1rpt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bradleyjeck/epanetReader/b0a2c6ff1e71841f17fc95d2cd81de484b104d53/img/Net1rpt.png -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | bibentry('article', 2 | year="2016", 3 | title = "An R package for reading EPANET files", 4 | pages = "149-154", 5 | doi = "10.1016/j.envsoft.2016.06.027", 6 | author = "Bradley J. Eck", 7 | journal = "Environmental Modeling and Software", 8 | volume = "86", 9 | publisher = "Elsevier") 10 | 11 | 12 | bibentry('InProceedings', 13 | year = "2016", 14 | title = "epanetReader: A Package for Reading EPANET Files into R", 15 | pages = "487-496", 16 | doi = "10.1061/9780784479865.051", 17 | author = "Bradley J. Eck", 18 | booktitle = "World Environmental and Water Resources Congress 2016", 19 | publisher = "ASCE") 20 | -------------------------------------------------------------------------------- /inst/extdata/Net1.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | EPANET Example Network 1 3 | A simple example of modeling chlorine decay. Both bulk and 4 | wall reactions are included. 5 | 6 | [JUNCTIONS] 7 | ;ID Elev Demand Pattern 8 | 10 710 0 ; 9 | 11 710 150 ; 10 | 12 700 150 ; 11 | 13 695 100 ; 12 | 21 700 150 ; 13 | 22 695 200 ; 14 | 23 690 150 ; 15 | 31 700 100 ; 16 | 32 710 100 ; 17 | 18 | [RESERVOIRS] 19 | ;ID Head Pattern 20 | 9 800 ; 21 | 22 | [TANKS] 23 | ;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve 24 | 2 850 120 100 150 50.5 0 ; 25 | 26 | [PIPES] 27 | ;ID Node1 Node2 Length Diameter Roughness MinorLoss Status 28 | 10 10 11 10530 18 100 0 Open ; 29 | 11 11 12 5280 14 100 0 Open ; 30 | 12 12 13 5280 10 100 0 Open ; 31 | 21 21 22 5280 10 100 0 Open ; 32 | 22 22 23 5280 12 100 0 Open ; 33 | 31 31 32 5280 6 100 0 Open ; 34 | 110 2 12 200 18 100 0 Open ; 35 | 111 11 21 5280 10 100 0 Open ; 36 | 112 12 22 5280 12 100 0 Open ; 37 | 113 13 23 5280 8 100 0 Open ; 38 | 121 21 31 5280 8 100 0 Open ; 39 | 122 22 32 5280 6 100 0 Open ; 40 | 41 | [PUMPS] 42 | ;ID Node1 Node2 Parameters 43 | 9 9 10 HEAD 1 ; 44 | 45 | [VALVES] 46 | ;ID Node1 Node2 Diameter Type Setting MinorLoss 47 | 48 | [TAGS] 49 | 50 | [DEMANDS] 51 | ;Junction Demand Pattern Category 52 | 53 | [STATUS] 54 | ;ID Status/Setting 55 | 56 | [PATTERNS] 57 | ;ID Multipliers 58 | ;Demand Pattern 59 | 1 1.0 1.2 1.4 1.6 1.4 1.2 60 | 1 1.0 0.8 0.6 0.4 0.6 0.8 61 | 62 | [CURVES] 63 | ;ID X-Value Y-Value 64 | ;PUMP: Pump Curve for Pump 9 65 | 1 1500 250 66 | 67 | [CONTROLS] 68 | LINK 9 OPEN IF NODE 2 BELOW 110 69 | LINK 9 CLOSED IF NODE 2 ABOVE 140 70 | 71 | 72 | [RULES] 73 | 74 | [ENERGY] 75 | Global Efficiency 75 76 | Global Price 0.0 77 | Demand Charge 0.0 78 | 79 | [EMITTERS] 80 | ;Junction Coefficient 81 | 82 | [QUALITY] 83 | ;Node InitQual 84 | 10 0.5 85 | 11 0.5 86 | 12 0.5 87 | 13 0.5 88 | 21 0.5 89 | 22 0.5 90 | 23 0.5 91 | 31 0.5 92 | 32 0.5 93 | 9 1.0 94 | 2 1.0 95 | 96 | [SOURCES] 97 | ;Node Type Quality Pattern 98 | 99 | [REACTIONS] 100 | ;Type Pipe/Tank Coefficient 101 | Order Bulk 1 102 | Order Tank 1 103 | Order Wall 1 104 | Global Bulk -.5 105 | Global Wall -1 106 | Limiting Potential 0.0 107 | Roughness Correlation 0.0 108 | 109 | [MIXING] 110 | ;Tank Model 111 | 112 | [TIMES] 113 | Duration 24:00 114 | Hydraulic Timestep 1:00 115 | Quality Timestep 0:05 116 | Pattern Timestep 2:00 117 | Pattern Start 0:00 118 | Report Timestep 1:00 119 | Report Start 0:00 120 | Start ClockTime 12 am 121 | Statistic None 122 | 123 | [REPORT] 124 | Status Yes 125 | Summary No 126 | Page 0 127 | Links All 128 | Nodes All 129 | Energy Yes 130 | 131 | [OPTIONS] 132 | Units GPM 133 | Headloss H-W 134 | Specific Gravity 1.0 135 | Viscosity 1.0 136 | Trials 40 137 | Accuracy 0.001 138 | CHECKFREQ 2 139 | MAXCHECK 10 140 | DAMPLIMIT 0 141 | Unbalanced Continue 10 142 | Pattern 1 143 | Demand Multiplier 1.0 144 | Emitter Exponent 0.5 145 | Quality Chlorine mg/L 146 | Diffusivity 1.0 147 | Tolerance 0.01 148 | 149 | [COORDINATES] 150 | ;Node X-Coord Y-Coord 151 | 10 20.00 70.00 152 | 11 30.00 70.00 153 | 12 50.00 70.00 154 | 13 70.00 70.00 155 | 21 30.00 40.00 156 | 22 50.00 40.00 157 | 23 70.00 40.00 158 | 31 30.00 10.00 159 | 32 50.00 10.00 160 | 9 10.00 70.00 161 | 2 50.00 90.00 162 | 163 | [VERTICES] 164 | ;Link X-Coord Y-Coord 165 | 166 | [LABELS] 167 | ;X-Coord Y-Coord Label & Anchor Node 168 | 6.99 73.63 "Source" 169 | 13.48 68.13 "Pump" 170 | 43.85 91.21 "Tank" 171 | 172 | [BACKDROP] 173 | DIMENSIONS 7.00 6.00 73.00 94.00 174 | UNITS None 175 | FILE 176 | OFFSET 0.00 0.00 177 | 178 | [END] 179 | -------------------------------------------------------------------------------- /man/Net1.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Net1-data.r 3 | \docType{data} 4 | \name{Net1} 5 | \alias{Net1} 6 | \title{Epanet's Net1 Example} 7 | \format{An object of class \code{epanet.inp} created by \link{read.inp}.} 8 | \source{ 9 | http://www.epa.gov/sites/production/files/2014-06/en2setup_0.exe 10 | } 11 | \usage{ 12 | Net1 13 | } 14 | \description{ 15 | A dataset created by reading the Net1.inp file 16 | distributed with Epanet using this package's 17 | read.inp() function. 18 | } 19 | \examples{ 20 | #confirm built-in dataset matches output of read.inp 21 | inp <- file.path( find.package("epanetReader"), "extdata","Net1.inp") 22 | n1 <- suppressWarnings( read.inp(inp) ) 23 | ok <- isTRUE( all.equal(Net1, n1)) 24 | if( ok==FALSE) stop("built-in Net1 doesn't match read.inp") 25 | } 26 | -------------------------------------------------------------------------------- /man/Net1rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/Net1rpt-data.r 3 | \docType{data} 4 | \name{Net1rpt} 5 | \alias{Net1rpt} 6 | \title{Epanet's Net1 Example} 7 | \format{An object of class \code{epanet.rpt} created by \link{read.rpt}.} 8 | \usage{ 9 | Net1rpt 10 | } 11 | \description{ 12 | A dataset created by reading the Net1.rpt file 13 | distributed with Epanet using this package's 14 | read.rpt() function. 15 | } 16 | \examples{ 17 | #confirm built-in dataset matches output of read.rpt 18 | rpt <- file.path( find.package("epanetReader"), "extdata","Net1.rpt") 19 | n1r <- read.rpt(rpt) 20 | ok <- isTRUE( all.equal(Net1rpt, n1r)) 21 | if( ok==FALSE) stop("built-in Net1rpt doesn't match read.rpt") 22 | } 23 | -------------------------------------------------------------------------------- /man/binBreaker.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/rptFuncs.r 3 | \name{binBreaker} 4 | \alias{binBreaker} 5 | \title{Bin Breaker} 6 | \usage{ 7 | binBreaker(x, nbin) 8 | } 9 | \arguments{ 10 | \item{x}{vector to find cuts for} 11 | 12 | \item{nbin}{number of bins} 13 | } 14 | \value{ 15 | list with elements Breaks and Labels 16 | } 17 | \description{ 18 | Generate break points for use with cut() 19 | and range labels based on sample max and min 20 | } 21 | \details{ 22 | Helpful in making labels use the acutal max and min rather than 23 | the +/- 1% cut() uses by default. 24 | } 25 | -------------------------------------------------------------------------------- /man/epanetDefaultOptions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/inpFuncs.r 3 | \name{epanetDefaultOptions} 4 | \alias{epanetDefaultOptions} 5 | \title{Epanet Default Options} 6 | \usage{ 7 | epanetDefaultOptions() 8 | } 9 | \description{ 10 | A list of Epanet's default options 11 | } 12 | \details{ 13 | Provides a named list in the form of OPTION = default_value where the 14 | values are taken from pages 152-154 of the manual. 15 | } 16 | \examples{ 17 | epanetDefaultOptions() 18 | } 19 | \references{ 20 | Rossman, L. A. (2000). Epanet 2 users manual. US EPA, Cincinnati, Ohio. 21 | http://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf 22 | } 23 | -------------------------------------------------------------------------------- /man/epanetReader.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanetReader.r 3 | \docType{package} 4 | \name{epanetReader} 5 | \alias{epanetReader} 6 | \alias{epanetReader-package} 7 | \title{Read text files from Epanet into R} 8 | \description{ 9 | \pkg{epanetReader} is a package for reading water network information 10 | and simulation results in Epanet's .inp 11 | and .rpt files into R. See functions \link{read.inp}, 12 | \link{read.rpt}, and \link{read.msxrpt} for some examples. 13 | } 14 | \author{ 15 | Bradley J. Eck 16 | } 17 | -------------------------------------------------------------------------------- /man/expandedLinkTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/expandedLinkTable-s3.r 3 | \name{expandedLinkTable} 4 | \alias{expandedLinkTable} 5 | \title{Expanded Link Table} 6 | \usage{ 7 | expandedLinkTable(Links, Coordinates) 8 | } 9 | \arguments{ 10 | \item{Links}{data frame of Pipes, Pumps or Valves of from epanet.inp} 11 | 12 | \item{Coordinates}{table of epanet.inp} 13 | } 14 | \value{ 15 | an expandedLinkTable object 16 | } 17 | \description{ 18 | Create an expandedLinkTable object by adding node coordinates to a 19 | data frame of pipes, pumps, or valves. 20 | } 21 | \examples{ 22 | x <- expandedLinkTable(Net1$Pipes, Net1$Coordinates) 23 | print(x) 24 | plot(x) 25 | } 26 | -------------------------------------------------------------------------------- /man/is.epanet.inp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.inp-s3.r 3 | \name{is.epanet.inp} 4 | \alias{is.epanet.inp} 5 | \title{Check if an object as class 'epanet.inp'} 6 | \usage{ 7 | is.epanet.inp(x) 8 | } 9 | \arguments{ 10 | \item{x}{an R object} 11 | } 12 | \description{ 13 | Check if an object as class 'epanet.inp' 14 | } 15 | -------------------------------------------------------------------------------- /man/is.epanet.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.rpt-s3.r 3 | \name{is.epanet.rpt} 4 | \alias{is.epanet.rpt} 5 | \title{Check if an object has class 'epanet.rpt'} 6 | \usage{ 7 | is.epanet.rpt(x) 8 | } 9 | \arguments{ 10 | \item{x}{an R object} 11 | } 12 | \description{ 13 | Check if an object has class 'epanet.rpt' 14 | } 15 | -------------------------------------------------------------------------------- /man/is.epanetmsx.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanetmsx.rpt-s3.r 3 | \name{is.epanetmsx.rpt} 4 | \alias{is.epanetmsx.rpt} 5 | \title{Check if an object has class 'epanetmsx.rpt'} 6 | \usage{ 7 | is.epanetmsx.rpt(x) 8 | } 9 | \arguments{ 10 | \item{x}{an R object} 11 | } 12 | \description{ 13 | Check if an object has class 'epanetmsx.rpt' 14 | } 15 | -------------------------------------------------------------------------------- /man/is.expandedLinkTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/expandedLinkTable-s3.r 3 | \name{is.expandedLinkTable} 4 | \alias{is.expandedLinkTable} 5 | \title{Check if an object has class 'expandedLinkTable'} 6 | \usage{ 7 | is.expandedLinkTable(x) 8 | } 9 | \arguments{ 10 | \item{x}{an R object} 11 | } 12 | \description{ 13 | Check if an object has class 'expandedLinkTable' 14 | } 15 | -------------------------------------------------------------------------------- /man/is.sparkline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sparkline-s3.r 3 | \name{is.sparkline} 4 | \alias{is.sparkline} 5 | \title{Check if an object has class 'sparkline'} 6 | \usage{ 7 | is.sparkline(x) 8 | } 9 | \arguments{ 10 | \item{x}{an R object} 11 | } 12 | \description{ 13 | Check if an object has class 'sparkline' 14 | } 15 | -------------------------------------------------------------------------------- /man/is.sparklineTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sparklineTable-s3.r 3 | \name{is.sparklineTable} 4 | \alias{is.sparklineTable} 5 | \title{Check if an object has class 'sparklineTable'} 6 | \usage{ 7 | is.sparklineTable(x) 8 | } 9 | \arguments{ 10 | \item{x}{an R object} 11 | } 12 | \description{ 13 | Check if an object has class 'sparklineTable' 14 | } 15 | -------------------------------------------------------------------------------- /man/plot.epanet.inp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.inp-s3.r 3 | \name{plot.epanet.inp} 4 | \alias{plot.epanet.inp} 5 | \title{Plot Method for epanet.inp} 6 | \usage{ 7 | \method{plot}{epanet.inp}(x, plot.junctions = TRUE, 8 | legend.locn = "topright", plot.labels = FALSE, link.lwd = 3, 9 | link.col = "black", ...) 10 | } 11 | \arguments{ 12 | \item{x}{object of class epanet.inp} 13 | 14 | \item{plot.junctions}{logical indicating whether to plot junctions} 15 | 16 | \item{legend.locn}{character string passed to legend() specifying 17 | the location of the legend on the plot} 18 | 19 | \item{plot.labels}{logical indicating whether to plot the labels using text()} 20 | 21 | \item{link.lwd}{value of lwd passed to segments()} 22 | 23 | \item{link.col}{value of col passed to segments()} 24 | 25 | \item{...}{other arguments passed to plot()} 26 | } 27 | \description{ 28 | Make a plot of the network using base graphics 29 | } 30 | \details{ 31 | Implements the generic plot function for S3 objects of class epanet.inp. 32 | The plot is built from base graphics by creating a blank plot and then calling 33 | the helper functions plotInpLinks(), plotInpNodes(), plotElementsLegend(). 34 | } 35 | \examples{ 36 | plot(Net1) 37 | plot(Net1, plot.labels=TRUE) 38 | } 39 | -------------------------------------------------------------------------------- /man/plot.epanet.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.rpt-s3.r 3 | \name{plot.epanet.rpt} 4 | \alias{plot.epanet.rpt} 5 | \title{Plot Simulation Results} 6 | \usage{ 7 | \method{plot}{epanet.rpt}(x, inp, Timestep = "0:00:00", juncQty = "Demand", 8 | linkQty = "Velocity", legend1.locn = "topright", 9 | legend2.locn = "topleft", ...) 10 | } 11 | \arguments{ 12 | \item{x}{epanet.rpt object} 13 | 14 | \item{inp}{epanet.inp object associated with x} 15 | 16 | \item{Timestep}{string indicating the time to plot} 17 | 18 | \item{juncQty}{string specifying which column of x$nodeResults 19 | (Demand, Head, Pressure, Chlorine, etc.) 20 | to show by circle size at network junctions} 21 | 22 | \item{linkQty}{string specifying which column of x$linkResults 23 | (Flow, Velocity, Headloss) 24 | to show by line width on network links} 25 | 26 | \item{legend1.locn}{string passed to legend() for placing legend of network elements} 27 | 28 | \item{legend2.locn}{string passed to legend() for placing legend of junction and link quantities} 29 | 30 | \item{...}{further arguments passed to plot} 31 | } 32 | \description{ 33 | Plots simulation results for a single time step in map form 34 | } 35 | \details{ 36 | juncQty plots and values for Junctions only; Tanks and Reservoirs are not included. 37 | In contrast, linkQty is scaled over all of the link types: Pipes, Pumps & Valves. 38 | These choices aim at a map showing demand at junctions and velocity in links. 39 | } 40 | -------------------------------------------------------------------------------- /man/plot.epanetmsx.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanetmsx.rpt-s3.r 3 | \name{plot.epanetmsx.rpt} 4 | \alias{plot.epanetmsx.rpt} 5 | \title{Plot method for epanetmsx.rpt} 6 | \usage{ 7 | \method{plot}{epanetmsx.rpt}(x, elementType = "Nodes", ...) 8 | } 9 | \arguments{ 10 | \item{x}{epanetmsx.rpt object} 11 | 12 | \item{elementType}{character indicating whether results for "nodes" or links" should be plotted} 13 | 14 | \item{...}{further arguments passed to plotSparklineTable} 15 | } 16 | \description{ 17 | Plots a sparkline table of Epanet-msx results 18 | } 19 | \seealso{ 20 | plotSparklineTable 21 | } 22 | -------------------------------------------------------------------------------- /man/plot.expandedLinkTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/expandedLinkTable-s3.r 3 | \name{plot.expandedLinkTable} 4 | \alias{plot.expandedLinkTable} 5 | \title{plot an expanded link table} 6 | \usage{ 7 | \method{plot}{expandedLinkTable}(x, add = FALSE, label = FALSE, 8 | linewidths = 3, color = "black", ...) 9 | } 10 | \arguments{ 11 | \item{x}{object of type expandedLinkTable} 12 | 13 | \item{add}{logical indicating whether to add to the currently active plot. 14 | add=FALSE creates a new plot.} 15 | 16 | \item{label}{logical indicating if the links should be labeled at the mid points} 17 | 18 | \item{linewidths}{passed to lwd argument in segments()} 19 | 20 | \item{color}{passed to col argument in segments()} 21 | 22 | \item{...}{further arguments passed to segments()} 23 | } 24 | \description{ 25 | plot an expanded link table 26 | } 27 | \details{ 28 | An implementation of the generic plot function for 29 | expandedLinkTable objects. Links are drawn using segments(). 30 | Useful for building up network plots. 31 | } 32 | -------------------------------------------------------------------------------- /man/plot.sparkline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sparkline-s3.r 3 | \name{plot.sparkline} 4 | \alias{plot.sparkline} 5 | \title{Plot a sparkline} 6 | \usage{ 7 | \method{plot}{sparkline}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{sparkline object} 11 | 12 | \item{...}{further arguments passed to plot.default} 13 | } 14 | \description{ 15 | Plot a sparkline 16 | } 17 | \details{ 18 | Implementation of the generic plot function for a single sparkline object. 19 | The primarily used to build up plots of a sparklineTable 20 | } 21 | \seealso{ 22 | sparkline 23 | } 24 | -------------------------------------------------------------------------------- /man/plot.sparklineTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sparklineTable-s3.r 3 | \name{plot.sparklineTable} 4 | \alias{plot.sparklineTable} 5 | \title{Plot Sparkline Table} 6 | \usage{ 7 | \method{plot}{sparklineTable}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{object of class sparklineTable} 11 | 12 | \item{...}{further arguments passed to par} 13 | } 14 | \description{ 15 | Plot Sparkline Table 16 | } 17 | -------------------------------------------------------------------------------- /man/plotElementsLegend.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.inp-s3.r 3 | \name{plotElementsLegend} 4 | \alias{plotElementsLegend} 5 | \title{Plot Legend of Network Elements} 6 | \usage{ 7 | plotElementsLegend(legend.locn) 8 | } 9 | \arguments{ 10 | \item{legend.locn}{keyword for location of legend. See details of legend() 11 | function.} 12 | } 13 | \description{ 14 | Add legend of network elements to the active plot 15 | } 16 | \details{ 17 | Helper function for adding a legend to the active plot. 18 | Uses plot characters 16, 15, 8 and 25 for Tanks, Reservoirs, Pumps and Valves 19 | for compatibility with plotInpNodes() 20 | } 21 | \examples{ 22 | ## make a new blank plot 23 | plot( c(0,1), c(0,1), type = 'n') 24 | ## add the nodes, including junctions 25 | plotElementsLegend('topright') 26 | } 27 | -------------------------------------------------------------------------------- /man/plotInpLinks.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.inp-s3.r 3 | \name{plotInpLinks} 4 | \alias{plotInpLinks} 5 | \title{Plot .inp Links} 6 | \usage{ 7 | plotInpLinks(x, lwd = 3, col = "black") 8 | } 9 | \arguments{ 10 | \item{x}{epanet.inp object} 11 | 12 | \item{lwd}{width of lines} 13 | 14 | \item{col}{color of lines} 15 | } 16 | \description{ 17 | Add lines for pipes, pumps and valves 18 | from an epanet.inp object to an existing plot 19 | } 20 | \details{ 21 | Helper function for building up a plot of the network by 22 | adding links to an existing plot. 23 | } 24 | \examples{ 25 | ## make a new blank plot 26 | plot( range(Net1$Coordinates$X), range(Net1$Coordinates$Y), type = 'n') 27 | ## add the links 28 | plotInpLinks(Net1) 29 | } 30 | -------------------------------------------------------------------------------- /man/plotInpNodes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.inp-s3.r 3 | \name{plotInpNodes} 4 | \alias{plotInpNodes} 5 | \title{Plot Node Elements} 6 | \usage{ 7 | plotInpNodes(x, plot.junctions) 8 | } 9 | \arguments{ 10 | \item{x}{epanet.inp object} 11 | 12 | \item{plot.junctions}{logical indicating whether to plot junctions} 13 | } 14 | \description{ 15 | Adds node elements from epanet.inp object to an existing plot 16 | } 17 | \details{ 18 | Helper function for building up a network plot. Tanks and 19 | Reservoirs are shown using plot characters (pch) ' 16 and 15. 20 | Junctions, if plotted, appear as pch ="." 21 | } 22 | \examples{ 23 | ## make a new blank plot 24 | plot( range(Net1$Coordinates$X), range(Net1$Coordinates$Y), type = 'n') 25 | ## add the nodes, including junctions 26 | plotInpNodes(Net1, TRUE ) 27 | } 28 | -------------------------------------------------------------------------------- /man/plotSparklineTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/plotSparklineTable.r 3 | \name{plotSparklineTable} 4 | \alias{plotSparklineTable} 5 | \title{Plot Sparkline Table} 6 | \usage{ 7 | plotSparklineTable(df, row.var, col.vars, xvar = NULL, xrange.labels = NULL) 8 | } 9 | \arguments{ 10 | \item{df}{data.frame of values to plot.} 11 | 12 | \item{row.var}{variable for rows of the table} 13 | 14 | \item{col.vars}{variables for columns of the table} 15 | 16 | \item{xvar}{optional name of variable for horizontal axis of sparkline plots} 17 | 18 | \item{xrange.labels}{optional vector of length 2 with labels for the first 19 | and last quantities plotted on x-axis, often a date and/or time} 20 | } 21 | \description{ 22 | Generate a table of sparkline plots 23 | } 24 | \details{ 25 | Generates a table of 'sparkline' plots of data in df. rows the table correspond to 26 | different values of row.var. The table's first column gives the value of row.var. The 27 | remaining columns contain sparkline plots for the values of col.vars. When xvar is not 28 | provided values are plotted against their index in the extracted vector. The starting 29 | and ending values are labeled. 30 | Uses layout() function to arrange plots. 31 | } 32 | \examples{ 33 | plotSparklineTable( Orange, row.var = 'Tree', col.vars = c('age','circumference')) 34 | plotSparklineTable( Loblolly, row.var = 'Seed', col.vars = 'height') 35 | ## specify the x variable if you have it, especially if it differs 36 | plotSparklineTable(Theoph, row.var = 'Subject', col.vars = 'conc') 37 | ## a warning is normally issued with the ranges of xvar differ 38 | suppressWarnings( plotSparklineTable(Theoph, row.var = 'Subject', col.vars = 'conc', xvar = 'Time')) 39 | } 40 | \references{ 41 | E. Tufte, Beautiful Evidence, Graphics Press, 2006. 42 | } 43 | \seealso{ 44 | yaletoolkit and sparkTable packages 45 | } 46 | -------------------------------------------------------------------------------- /man/print.summary.epanet.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.rpt-s3.r 3 | \name{print.summary.epanet.rpt} 4 | \alias{print.summary.epanet.rpt} 5 | \title{Print rpt summary} 6 | \usage{ 7 | \method{print}{summary.epanet.rpt}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{a summary.epanet.rpt object} 11 | 12 | \item{...}{further arguments passed to print} 13 | } 14 | \description{ 15 | The function prints a summary of simulation results 16 | contained in the rpt file. 17 | } 18 | -------------------------------------------------------------------------------- /man/print.summary.epanetmsx.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanetmsx.rpt-s3.r 3 | \name{print.summary.epanetmsx.rpt} 4 | \alias{print.summary.epanetmsx.rpt} 5 | \title{Print msx rpt summary} 6 | \usage{ 7 | \method{print}{summary.epanetmsx.rpt}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{a summary.epanetmsx.rpt object} 11 | 12 | \item{...}{further arguments passed to print} 13 | } 14 | \description{ 15 | The function prints a summary of multi-species simulation results 16 | contained in the report file 17 | } 18 | -------------------------------------------------------------------------------- /man/read.inp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.inp-s3.r 3 | \name{read.inp} 4 | \alias{read.inp} 5 | \alias{epanet.inp} 6 | \title{Read .inp file} 7 | \usage{ 8 | read.inp(file) 9 | } 10 | \arguments{ 11 | \item{file}{the name of the file to read} 12 | } 13 | \value{ 14 | Returns an epanet.inp S3 object with 15 | elements of the following names and types corresponding to sections 16 | of the .inp file. Sections missing from the .inp file have a value of NULL. 17 | \item{Title}{character} 18 | \item{Junctions}{data.frame} 19 | \item{Tanks}{data.frame} 20 | \item{Reservoirs}{data.frame} 21 | \item{Pipes}{data.frame} 22 | \item{Pumps}{data.frame} 23 | \item{Valves}{data.frame} 24 | \item{Demands}{data.frame} 25 | \item{Status}{data.frame} 26 | \item{Emitters}{data.frame} 27 | \item{Quality}{data.frame} 28 | \item{Sources}{data.frame} 29 | \item{Reactions}{character} 30 | \item{Mixing}{data.frame} 31 | \item{Patterns}{list} 32 | \item{Curves}{list} 33 | \item{Controls}{character} 34 | \item{Rules}{character} 35 | \item{Energy}{character} 36 | \item{Times}{character} 37 | \item{Report}{character} 38 | \item{Options}{list} 39 | \item{Coordinates}{data.frame} 40 | \item{Vertices}{data.frame} 41 | \item{Labels}{data.frame} 42 | \item{Backdrop}{character} 43 | \item{Tags}{character} 44 | } 45 | \description{ 46 | Read an Epanet .inp file into R 47 | } 48 | \details{ 49 | This function reads a text file in Epanet's .inp format 50 | and returns an S3 object with entries for 51 | sections of the .inp file. Sections of the .inp file that are implemented 52 | appear in the Value section. 53 | 54 | Fields for node or link ID are stored as characters not factors or integers. 55 | However, some fields are stored as factors 56 | to allow more informative summaries. Examples include valve type and pipe status. 57 | 58 | Sections that are absent from the .inp file are NULL in the list. 59 | 60 | Columns of data.frames use the headings exported by 61 | the Epanet GUI. 62 | 63 | The [OPTIONS] section in the .inp file is used to update 64 | a list of Epanet's default options. In this way if an option such as 65 | units is not specified by the .inp file, the units that would be used by 66 | default are provided. 67 | 68 | In the [PATTERNS] and [CURVES] sections, integers used as names of list elements are backquoted 69 | according to the default behavior in R. So if the .inp file has a pattern "1" 70 | this pattern will appear as element `1` in the list that is returned. A warning is issued in this case. 71 | } 72 | \examples{ 73 | # path to Net1.inp example file included with this package 74 | inp <- file.path( find.package("epanetReader"), "extdata","Net1.inp") 75 | 76 | #read the network file into R 77 | n1 <- read.inp(inp) 78 | summary(n1) 79 | names(n1) 80 | summary(n1$Junctions) 81 | summary(n1$Pipes) 82 | plot(n1) 83 | } 84 | \references{ 85 | Rossman, L. A. (2000). Epanet 2 users manual. US EPA, Cincinnati, Ohio. 86 | 87 | http://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf 88 | } 89 | -------------------------------------------------------------------------------- /man/read.msxrpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanetmsx.rpt-s3.r 3 | \name{read.msxrpt} 4 | \alias{read.msxrpt} 5 | \alias{epanetmsx.rpt} 6 | \title{Read msx results} 7 | \usage{ 8 | read.msxrpt(file) 9 | } 10 | \arguments{ 11 | \item{file}{the name of the file to read} 12 | } 13 | \value{ 14 | Returns an epanetmsx.rpt S3 object . 15 | 16 | \item{nodeResults}{data.frame} 17 | \item{linkResults}{data.frame} 18 | } 19 | \description{ 20 | reads an Epanet-msx .rpt file into R 21 | } 22 | \details{ 23 | Specify the needed outputs from an Epanet-msx simulation in the 24 | [REPORT] section of the .msx file to create reports for reading with 25 | with this function. 26 | 27 | The function returns an S3 object (list) with a data.frame for node results and 28 | data.frame for link results. These data.frames contain results from all 29 | the time periods to facilitate time series plots. 30 | } 31 | \examples{ 32 | # path to example file included with this package 33 | msr <- file.path( find.package("epanetReader"), "extdata","example.rpt") 34 | 35 | #read the results into R 36 | x <- read.msxrpt(msr) 37 | names(x) 38 | summary(x) 39 | plot(x) 40 | } 41 | \references{ 42 | Shang, F., Uber, J.G., Rossman, L.A. (2011) 43 | EPANET Multi-species Extension User's Manual. 44 | US Environmental Protection Agency, Cincinnati. 45 | } 46 | -------------------------------------------------------------------------------- /man/read.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.rpt-s3.r 3 | \name{read.rpt} 4 | \alias{read.rpt} 5 | \title{Read .rpt file} 6 | \usage{ 7 | read.rpt(file) 8 | } 9 | \arguments{ 10 | \item{file}{the name of the file to read} 11 | } 12 | \value{ 13 | Returns an epanet.rpt S3 object with two data.frame elements. 14 | 15 | \item{nodeResults}{data.frame} 16 | \item{linkResults}{data.frame} 17 | \item{energyUsage}{data.frame} 18 | } 19 | \description{ 20 | reads an Epanet .rpt file into R 21 | } 22 | \details{ 23 | add lines "Page 0", "Links All" and "Nodes All" to the 24 | [REPORT] section of the .inp file to output info to read in 25 | with this function 26 | 27 | In contrast to the treatment of .inp files, data from .rpt 28 | files is stored using a slightly different structure than the .rpt file. The 29 | function returns an object (list) with a data.frame for node results and 30 | data.frame for link results and a data.frame for energy usage. The node and 31 | link results data frames contain results from all the time periods to 32 | facilitate time series plots. 33 | } 34 | \examples{ 35 | # path to Net1.rpt example file included with this package 36 | rpt <- file.path( find.package("epanetReader"), "extdata","Net1.rpt") 37 | n1r <- read.rpt(rpt) 38 | summary(n1r) 39 | names(n1r) 40 | 41 | #Results for a chosen time period can be retrieved using the subset function. 42 | subset(n1r$nodeResults, Timestamp == "0:00:00") 43 | 44 | # time series plot for a nodal value 45 | plot( Chlorine ~ timeInSeconds, 46 | data = subset(n1r$nodeResults, ID == "22")) 47 | 48 | # Plotting the epanet.rpt object itself gives a map. 49 | # Note that the object created from the .inp file is required. 50 | inp <- file.path( find.package("epanetReader"), "extdata","Net1.inp") 51 | n1 <- read.inp(inp) 52 | plot( n1r, n1) 53 | 54 | # Energy Usage table 55 | print(n1r$energyUsage) 56 | } 57 | \references{ 58 | Rossman, L. A. (2000). Epanet 2 users manual. US EPA, Cincinnati, Ohio. 59 | 60 | http://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf 61 | } 62 | -------------------------------------------------------------------------------- /man/read_lines_wrapper.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/text_file_reader.r 3 | \name{read_lines_wrapper} 4 | \alias{read_lines_wrapper} 5 | \title{Read lines wrapper} 6 | \usage{ 7 | read_lines_wrapper(file) 8 | } 9 | \arguments{ 10 | \item{file}{the name of the file to read} 11 | } 12 | \value{ 13 | character vector where each entry corresponds to 14 | a line in the file. 15 | } 16 | \description{ 17 | Wrapper function for different implementations of 18 | readlines functions 19 | } 20 | \details{ 21 | calls Kmisc::readlines if available and base::readLines otherwise 22 | } 23 | -------------------------------------------------------------------------------- /man/sparkline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sparkline-s3.r 3 | \name{sparkline} 4 | \alias{sparkline} 5 | \title{Sparkline} 6 | \usage{ 7 | sparkline(df, id.var, ID, yvar, xvar) 8 | } 9 | \arguments{ 10 | \item{df}{data.frame from which data for the sparkline is extracted} 11 | 12 | \item{id.var}{variable in df with IDs} 13 | 14 | \item{ID}{value in id.var on which to extract} 15 | 16 | \item{yvar}{name of variable for the y values in the sparkline} 17 | 18 | \item{xvar}{optional name of variable for horizontal axis of sparkline plots} 19 | } 20 | \description{ 21 | Create sparkline object by extracting from a data frame 22 | } 23 | \details{ 24 | Creates an object with info for a single sparkline by extracting 25 | from a data.frame. The function works on data.frames with one column of ID variables 26 | and possibly several columns of other variables. The main use is 27 | as a helper function for building up a \link{sparklineTable}. 28 | } 29 | \examples{ 30 | ## look at the names in the built-in data set Theoph 31 | names(Theoph) 32 | ## make sparkline object for the concentration over time in subject 2 33 | sl <- sparkline(df= Theoph, id.var = 'Subject', ID = 2, yvar='conc', xvar = 'Time') 34 | plot(sl) 35 | } 36 | -------------------------------------------------------------------------------- /man/sparklineTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/sparklineTable-s3.r 3 | \name{sparklineTable} 4 | \alias{sparklineTable} 5 | \title{Sparkline Table} 6 | \usage{ 7 | sparklineTable(df, row.var, col.vars, xvar = NULL, xrange.labels = NULL) 8 | } 9 | \arguments{ 10 | \item{df}{data.frame of values to plot.} 11 | 12 | \item{row.var}{variable for rows of the table} 13 | 14 | \item{col.vars}{variables for columns of the table} 15 | 16 | \item{xvar}{optional name of variable for horizontal axis of sparkline plots} 17 | 18 | \item{xrange.labels}{optional vector of length 2 with labels for the first 19 | and last quantities plotted on x-axis, often a date and/or time} 20 | } 21 | \description{ 22 | Create S3 object of data for table of sparklines 23 | } 24 | \seealso{ 25 | plotSparklineTable 26 | } 27 | -------------------------------------------------------------------------------- /man/summary.epanet.inp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.inp-s3.r 3 | \name{summary.epanet.inp} 4 | \alias{summary.epanet.inp} 5 | \title{Summary Method for epanet.inp} 6 | \usage{ 7 | \method{summary}{epanet.inp}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{of class epanet.inp} 11 | 12 | \item{...}{futher arguments} 13 | } 14 | \description{ 15 | Summarizes the network by printing the Title of the 16 | network and the number of each type of elements. 17 | } 18 | -------------------------------------------------------------------------------- /man/summary.epanet.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanet.rpt-s3.r 3 | \name{summary.epanet.rpt} 4 | \alias{summary.epanet.rpt} 5 | \title{Summary of Epanet Simulation Results} 6 | \usage{ 7 | \method{summary}{epanet.rpt}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{of epanet.rpt class} 11 | 12 | \item{...}{further arguments passed to summary()} 13 | } 14 | \description{ 15 | Provides a basic summary of simulation results 16 | } 17 | \details{ 18 | Summary of pipe results shows positive and negative 19 | values of flow but only positive values of velocity 20 | as in the rpt file. 21 | } 22 | -------------------------------------------------------------------------------- /man/summary.epanetmsx.rpt.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/epanetmsx.rpt-s3.r 3 | \name{summary.epanetmsx.rpt} 4 | \alias{summary.epanetmsx.rpt} 5 | \title{Summary of Epanet-msx Simulation Results} 6 | \usage{ 7 | \method{summary}{epanetmsx.rpt}(object, ...) 8 | } 9 | \arguments{ 10 | \item{object}{of epanetmsx.rpt class} 11 | 12 | \item{...}{further arguments passed to summary()} 13 | } 14 | \description{ 15 | Provides a basic summary of simulation results 16 | } 17 | -------------------------------------------------------------------------------- /man/write.inp.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/write.inp.r 3 | \name{write.inp} 4 | \alias{write.inp} 5 | \title{Write .inp file} 6 | \usage{ 7 | write.inp(x, file) 8 | } 9 | \arguments{ 10 | \item{x}{epanet.inp object to write} 11 | 12 | \item{file}{the name of the file where object is written} 13 | } 14 | \value{ 15 | nothing 16 | } 17 | \description{ 18 | Write an epanet.inp object to a file 19 | } 20 | \details{ 21 | Writes an epanet.inp object to a file suitable for simulation 22 | with EPANET. 23 | } 24 | \examples{ 25 | write.inp(Net1, "Net1-fromR.inp") 26 | n1 <- read.inp("Net1-fromR.inp") 27 | all.equal(Net1, n1) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /tests/testthat.r: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(epanetReader) 3 | 4 | test_check("epanetReader") 5 | -------------------------------------------------------------------------------- /tests/testthat/Net1-gui.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | EPANET Example Network 1 3 | A simple example of modeling chlorine decay. Both bulk and 4 | wall reactions are included. 5 | 6 | [JUNCTIONS] 7 | ;ID Elev Demand Pattern 8 | 10 710 0 ; 9 | 11 710 150 ; 10 | 12 700 150 ; 11 | 13 695 100 ; 12 | 21 700 150 ; 13 | 22 695 200 ; 14 | 23 690 150 ; 15 | 31 700 100 ; 16 | 32 710 100 ; 17 | 18 | [RESERVOIRS] 19 | ;ID Head Pattern 20 | 9 800 ; 21 | 22 | [TANKS] 23 | ;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve 24 | 2 850 120 100 150 50.5 0 ; 25 | 26 | [PIPES] 27 | ;ID Node1 Node2 Length Diameter Roughness MinorLoss Status 28 | 10 10 11 10530 18 100 0 Open ; 29 | 11 11 12 5280 14 100 0 Open ; 30 | 12 12 13 5280 10 100 0 Open ; 31 | 21 21 22 5280 10 100 0 Open ; 32 | 22 22 23 5280 12 100 0 Open ; 33 | 31 31 32 5280 6 100 0 Open ; 34 | 110 2 12 200 18 100 0 Open ; 35 | 111 11 21 5280 10 100 0 Open ; 36 | 112 12 22 5280 12 100 0 Open ; 37 | 113 13 23 5280 8 100 0 Open ; 38 | 121 21 31 5280 8 100 0 Open ; 39 | 122 22 32 5280 6 100 0 Open ; 40 | 41 | [PUMPS] 42 | ;ID Node1 Node2 Parameters 43 | 9 9 10 HEAD 1 ; 44 | 45 | [VALVES] 46 | ;ID Node1 Node2 Diameter Type Setting MinorLoss 47 | 48 | [TAGS] 49 | 50 | [DEMANDS] 51 | ;Junction Demand Pattern Category 52 | 53 | [STATUS] 54 | ;ID Status/Setting 55 | 56 | [PATTERNS] 57 | ;ID Multipliers 58 | ;Demand Pattern 59 | 1 1.0 1.2 1.4 1.6 1.4 1.2 60 | 1 1.0 0.8 0.6 0.4 0.6 0.8 61 | 62 | [CURVES] 63 | ;ID X-Value Y-Value 64 | ;PUMP: Pump Curve for Pump 9 65 | 1 1500 250 66 | 67 | [CONTROLS] 68 | LINK 9 OPEN IF NODE 2 BELOW 110 69 | LINK 9 CLOSED IF NODE 2 ABOVE 140 70 | 71 | 72 | [RULES] 73 | 74 | [ENERGY] 75 | Global Efficiency 75 76 | Global Price 0.0 77 | Demand Charge 0.0 78 | 79 | [EMITTERS] 80 | ;Junction Coefficient 81 | 82 | [QUALITY] 83 | ;Node InitQual 84 | 10 0.5 85 | 11 0.5 86 | 12 0.5 87 | 13 0.5 88 | 21 0.5 89 | 22 0.5 90 | 23 0.5 91 | 31 0.5 92 | 32 0.5 93 | 9 1.0 94 | 2 1.0 95 | 96 | [SOURCES] 97 | ;Node Type Quality Pattern 98 | 99 | [REACTIONS] 100 | ;Type Pipe/Tank Coefficient 101 | 102 | 103 | [REACTIONS] 104 | Order Bulk 1 105 | Order Tank 1 106 | Order Wall 1 107 | Global Bulk -.5 108 | Global Wall -1 109 | Limiting Potential 0.0 110 | Roughness Correlation 0.0 111 | 112 | [MIXING] 113 | ;Tank Model 114 | 115 | [TIMES] 116 | Duration 24:00 117 | Hydraulic Timestep 1:00 118 | Quality Timestep 0:05 119 | Pattern Timestep 2:00 120 | Pattern Start 0:00 121 | Report Timestep 1:00 122 | Report Start 0:00 123 | Start ClockTime 12 am 124 | Statistic None 125 | 126 | [REPORT] 127 | Status Yes 128 | Summary No 129 | Page 0 130 | 131 | [OPTIONS] 132 | Units GPM 133 | Headloss H-W 134 | Specific Gravity 1.0 135 | Viscosity 1.0 136 | Trials 40 137 | Accuracy 0.001 138 | CHECKFREQ 2 139 | MAXCHECK 10 140 | DAMPLIMIT 0 141 | Unbalanced Continue 10 142 | Pattern 1 143 | Demand Multiplier 1.0 144 | Emitter Exponent 0.5 145 | Quality Chlorine mg/L 146 | Diffusivity 1.0 147 | Tolerance 0.01 148 | 149 | [COORDINATES] 150 | ;Node X-Coord Y-Coord 151 | 10 20.00 70.00 152 | 11 30.00 70.00 153 | 12 50.00 70.00 154 | 13 70.00 70.00 155 | 21 30.00 40.00 156 | 22 50.00 40.00 157 | 23 70.00 40.00 158 | 31 30.00 10.00 159 | 32 50.00 10.00 160 | 9 10.00 70.00 161 | 2 50.00 90.00 162 | 163 | [VERTICES] 164 | ;Link X-Coord Y-Coord 165 | 166 | [LABELS] 167 | ;X-Coord Y-Coord Label & Anchor Node 168 | 6.99 73.63 "Source" 169 | 13.48 68.13 "Pump" 170 | 43.85 91.21 "Tank" 171 | 172 | [BACKDROP] 173 | DIMENSIONS 7.00 6.00 73.00 94.00 174 | UNITS None 175 | FILE 176 | OFFSET 0.00 0.00 177 | 178 | [END] 179 | -------------------------------------------------------------------------------- /tests/testthat/Net1-noLinks-noNodes.rpt: -------------------------------------------------------------------------------- 1 | Page 1 Fri Jun 19 11:40:14 2015 2 | 3 | ****************************************************************** 4 | * E P A N E T * 5 | * Hydraulic and Water Quality * 6 | * Analysis for Pipe Networks * 7 | * Version 2.00.12 * 8 | ****************************************************************** 9 | 10 | Analysis begun Fri Jun 19 11:40:14 2015 11 | 12 | 13 | Hydraulic Status: 14 | ----------------------------------------------------------------------- 15 | 0:00:00: Balanced after 4 trials 16 | 0:00:00: Reservoir 9 is emptying 17 | 0:00:00: Tank 2 is filling at 120.00 ft 18 | 19 | 1:00:00: Balanced after 2 trials 20 | 21 | 2:00:00: Balanced after 3 trials 22 | 23 | 3:00:00: Balanced after 2 trials 24 | 25 | 4:00:00: Balanced after 3 trials 26 | 27 | 5:00:00: Balanced after 2 trials 28 | 29 | 6:00:00: Balanced after 2 trials 30 | 31 | 7:00:00: Balanced after 1 trials 32 | 33 | 8:00:00: Balanced after 2 trials 34 | 35 | 9:00:00: Balanced after 2 trials 36 | 37 | 10:00:00: Balanced after 2 trials 38 | 39 | 11:00:00: Balanced after 2 trials 40 | 41 | 12:00:00: Balanced after 3 trials 42 | 43 | 12:32:34: Pump 9 changed by Tank 2 control 44 | 12:32:34: Balanced after 4 trials 45 | 12:32:34: Reservoir 9 is closed 46 | 12:32:34: Tank 2 is emptying at 140.00 ft 47 | 12:32:34: Pump 9 changed from open to closed 48 | 49 | 13:00:00: Balanced after 1 trials 50 | 51 | 14:00:00: Balanced after 2 trials 52 | 53 | 15:00:00: Balanced after 1 trials 54 | 55 | 16:00:00: Balanced after 2 trials 56 | 57 | 17:00:00: Balanced after 1 trials 58 | 59 | 18:00:00: Balanced after 2 trials 60 | 61 | 19:00:00: Balanced after 1 trials 62 | 63 | 20:00:00: Balanced after 2 trials 64 | 65 | 21:00:00: Balanced after 1 trials 66 | 67 | 22:00:00: Balanced after 2 trials 68 | 69 | 22:41:30: Pump 9 changed by Tank 2 control 70 | 22:41:30: Balanced after 15 trials 71 | 22:41:30: Reservoir 9 is emptying 72 | 22:41:30: Tank 2 is filling at 110.00 ft 73 | 22:41:30: Pump 9 changed from closed to open 74 | 75 | 23:00:00: Balanced after 2 trials 76 | 77 | 24:00:00: Balanced after 3 trials 78 | 79 | 80 | 81 | Energy Usage: 82 | ---------------------------------------------------------------- 83 | Usage Avg. Kw-hr Avg. Peak Cost 84 | Pump Factor Effic. /Mgal Kw Kw /day 85 | ---------------------------------------------------------------- 86 | 9 57.71 75.00 880.42 96.25 96.71 0.00 87 | ---------------------------------------------------------------- 88 | Demand Charge: 0.00 89 | Total Cost: 0.00 90 | 91 | Analysis ended Fri Jun 19 11:40:14 2015 92 | -------------------------------------------------------------------------------- /tests/testthat/Net1-noResult.rpt: -------------------------------------------------------------------------------- 1 | Page 1 Fri Jun 19 11:40:14 2015 2 | 3 | ****************************************************************** 4 | * E P A N E T * 5 | * Hydraulic and Water Quality * 6 | * Analysis for Pipe Networks * 7 | * Version 2.00.12 * 8 | ****************************************************************** 9 | 10 | Analysis begun Fri Jun 19 11:40:14 2015 11 | 12 | 13 | Hydraulic Status: 14 | ----------------------------------------------------------------------- 15 | 0:00:00: Balanced after 4 trials 16 | 0:00:00: Reservoir 9 is emptying 17 | 0:00:00: Tank 2 is filling at 120.00 ft 18 | 19 | 1:00:00: Balanced after 2 trials 20 | 21 | 2:00:00: Balanced after 3 trials 22 | 23 | 3:00:00: Balanced after 2 trials 24 | 25 | 4:00:00: Balanced after 3 trials 26 | 27 | 5:00:00: Balanced after 2 trials 28 | 29 | 6:00:00: Balanced after 2 trials 30 | 31 | 7:00:00: Balanced after 1 trials 32 | 33 | 8:00:00: Balanced after 2 trials 34 | 35 | 9:00:00: Balanced after 2 trials 36 | 37 | 10:00:00: Balanced after 2 trials 38 | 39 | 11:00:00: Balanced after 2 trials 40 | 41 | 12:00:00: Balanced after 3 trials 42 | 43 | 12:32:34: Pump 9 changed by Tank 2 control 44 | 12:32:34: Balanced after 4 trials 45 | 12:32:34: Reservoir 9 is closed 46 | 12:32:34: Tank 2 is emptying at 140.00 ft 47 | 12:32:34: Pump 9 changed from open to closed 48 | 49 | 13:00:00: Balanced after 1 trials 50 | 51 | 14:00:00: Balanced after 2 trials 52 | 53 | 15:00:00: Balanced after 1 trials 54 | 55 | 16:00:00: Balanced after 2 trials 56 | 57 | 17:00:00: Balanced after 1 trials 58 | 59 | 18:00:00: Balanced after 2 trials 60 | 61 | 19:00:00: Balanced after 1 trials 62 | 63 | 20:00:00: Balanced after 2 trials 64 | 65 | 21:00:00: Balanced after 1 trials 66 | 67 | 22:00:00: Balanced after 2 trials 68 | 69 | 22:41:30: Pump 9 changed by Tank 2 control 70 | 22:41:30: Balanced after 15 trials 71 | 22:41:30: Reservoir 9 is emptying 72 | 22:41:30: Tank 2 is filling at 110.00 ft 73 | 22:41:30: Pump 9 changed from closed to open 74 | 75 | 23:00:00: Balanced after 2 trials 76 | 77 | 24:00:00: Balanced after 3 trials 78 | 79 | 80 | Analysis ended Fri Jun 19 11:40:14 2015 81 | -------------------------------------------------------------------------------- /tests/testthat/Net1.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | EPANET Example Network 1 3 | A simple example of modeling chlorine decay. Both bulk and 4 | wall reactions are included. 5 | 6 | [JUNCTIONS] 7 | ;ID Elev Demand Pattern 8 | 10 710 0 ; 9 | 11 710 150 ; 10 | 12 700 150 ; 11 | 13 695 100 ; 12 | 21 700 150 ; 13 | 22 695 200 ; 14 | 23 690 150 ; 15 | 31 700 100 ; 16 | 32 710 100 ; 17 | 18 | [RESERVOIRS] 19 | ;ID Head Pattern 20 | 9 800 ; 21 | 22 | [TANKS] 23 | ;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve 24 | 2 850 120 100 150 50.5 0 ; 25 | 26 | [PIPES] 27 | ;ID Node1 Node2 Length Diameter Roughness MinorLoss Status 28 | 10 10 11 10530 18 100 0 Open ; 29 | 11 11 12 5280 14 100 0 Open ; 30 | 12 12 13 5280 10 100 0 Open ; 31 | 21 21 22 5280 10 100 0 Open ; 32 | 22 22 23 5280 12 100 0 Open ; 33 | 31 31 32 5280 6 100 0 Open ; 34 | 110 2 12 200 18 100 0 Open ; 35 | 111 11 21 5280 10 100 0 Open ; 36 | 112 12 22 5280 12 100 0 Open ; 37 | 113 13 23 5280 8 100 0 Open ; 38 | 121 21 31 5280 8 100 0 Open ; 39 | 122 22 32 5280 6 100 0 Open ; 40 | 41 | [PUMPS] 42 | ;ID Node1 Node2 Parameters 43 | 9 9 10 HEAD 1 ; 44 | 45 | [VALVES] 46 | ;ID Node1 Node2 Diameter Type Setting MinorLoss 47 | 48 | [TAGS] 49 | 50 | [DEMANDS] 51 | ;Junction Demand Pattern Category 52 | 53 | [STATUS] 54 | ;ID Status/Setting 55 | 56 | [PATTERNS] 57 | ;ID Multipliers 58 | ;Demand Pattern 59 | 1 1.0 1.2 1.4 1.6 1.4 1.2 60 | 1 1.0 0.8 0.6 0.4 0.6 0.8 61 | 62 | [CURVES] 63 | ;ID X-Value Y-Value 64 | ;PUMP: Pump Curve for Pump 9 65 | 1 1500 250 66 | 67 | [CONTROLS] 68 | LINK 9 OPEN IF NODE 2 BELOW 110 69 | LINK 9 CLOSED IF NODE 2 ABOVE 140 70 | 71 | 72 | [RULES] 73 | 74 | [ENERGY] 75 | Global Efficiency 75 76 | Global Price 0.0 77 | Demand Charge 0.0 78 | 79 | [EMITTERS] 80 | ;Junction Coefficient 81 | 82 | [QUALITY] 83 | ;Node InitQual 84 | 10 0.5 85 | 11 0.5 86 | 12 0.5 87 | 13 0.5 88 | 21 0.5 89 | 22 0.5 90 | 23 0.5 91 | 31 0.5 92 | 32 0.5 93 | 9 1.0 94 | 2 1.0 95 | 96 | [SOURCES] 97 | ;Node Type Quality Pattern 98 | 99 | [REACTIONS] 100 | ;Type Pipe/Tank Coefficient 101 | Order Bulk 1 102 | Order Tank 1 103 | Order Wall 1 104 | Global Bulk -.5 105 | Global Wall -1 106 | Limiting Potential 0.0 107 | Roughness Correlation 0.0 108 | 109 | [MIXING] 110 | ;Tank Model 111 | 112 | [TIMES] 113 | Duration 24:00 114 | Hydraulic Timestep 1:00 115 | Quality Timestep 0:05 116 | Pattern Timestep 2:00 117 | Pattern Start 0:00 118 | Report Timestep 1:00 119 | Report Start 0:00 120 | Start ClockTime 12 am 121 | Statistic None 122 | 123 | [REPORT] 124 | Status Yes 125 | Summary No 126 | Page 0 127 | Links All 128 | Nodes All 129 | Energy Yes 130 | 131 | [OPTIONS] 132 | Units GPM 133 | Headloss H-W 134 | Specific Gravity 1.0 135 | Viscosity 1.0 136 | Trials 40 137 | Accuracy 0.001 138 | CHECKFREQ 2 139 | MAXCHECK 10 140 | DAMPLIMIT 0 141 | Unbalanced Continue 10 142 | Pattern 1 143 | Demand Multiplier 1.0 144 | Emitter Exponent 0.5 145 | Quality Chlorine mg/L 146 | Diffusivity 1.0 147 | Tolerance 0.01 148 | 149 | [COORDINATES] 150 | ;Node X-Coord Y-Coord 151 | 10 20.00 70.00 152 | 11 30.00 70.00 153 | 12 50.00 70.00 154 | 13 70.00 70.00 155 | 21 30.00 40.00 156 | 22 50.00 40.00 157 | 23 70.00 40.00 158 | 31 30.00 10.00 159 | 32 50.00 10.00 160 | 9 10.00 70.00 161 | 2 50.00 90.00 162 | 163 | [VERTICES] 164 | ;Link X-Coord Y-Coord 165 | 166 | [LABELS] 167 | ;X-Coord Y-Coord Label & Anchor Node 168 | 6.99 73.63 "Source" 169 | 13.48 68.13 "Pump" 170 | 43.85 91.21 "Tank" 171 | 172 | [BACKDROP] 173 | DIMENSIONS 7.00 6.00 73.00 94.00 174 | UNITS None 175 | FILE 176 | OFFSET 0.00 0.00 177 | 178 | [END] 179 | -------------------------------------------------------------------------------- /tests/testthat/Net4.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | 3 | 4 | [JUNCTIONS] 5 | ;ID Elev Demand Pattern 6 | 0022 0 0 ; 7 | 3 0 0 ; 8 | 004 0 0.2 ; 9 | 5 0 0.1 ; 10 | 11 | [RESERVOIRS] 12 | ;ID Head Pattern 13 | N1 100 ; 14 | 15 | [TANKS] 16 | ;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve 17 | 18 | [PIPES] 19 | ;ID Node1 Node2 Length Diameter Roughness MinorLoss Status 20 | 1 N1 0022 1000 12 100 0 Open ; 21 | 2 0022 3 1000 12 100 0 Open ; 22 | A3 3 004 1000 12 100 0 Open ; 23 | 04 0022 5 1000 12 100 0 Open ; 24 | 5 004 5 1000 12 100 0 Open ; 25 | 26 | [PUMPS] 27 | ;ID Node1 Node2 Parameters 28 | 29 | [VALVES] 30 | ;ID Node1 Node2 Diameter Type Setting MinorLoss 31 | 32 | [TAGS] 33 | 34 | [DEMANDS] 35 | ;Junction Demand Pattern Category 36 | 37 | [STATUS] 38 | ;ID Status/Setting 39 | 40 | [PATTERNS] 41 | ;ID Multipliers 42 | 43 | [CURVES] 44 | ;ID X-Value Y-Value 45 | 46 | [CONTROLS] 47 | 48 | [RULES] 49 | 50 | [ENERGY] 51 | Global Efficiency 75 52 | Global Price 0 53 | Demand Charge 0 54 | 55 | [EMITTERS] 56 | ;Junction Coefficient 57 | 58 | [QUALITY] 59 | ;Node InitQual 60 | 61 | [SOURCES] 62 | ;Node Type Quality Pattern 63 | 64 | [REACTIONS] 65 | Order Bulk 1 66 | Order Tank 1 67 | Order Wall 1 68 | Global Bulk 0 69 | Global Wall 0 70 | Limiting Potential 0 71 | Roughness Correlation 0 72 | 73 | [MIXING] 74 | ;Tank Model 75 | 76 | [TIMES] 77 | Duration 0 78 | Hydraulic Timestep 1:00 79 | Quality Timestep 0:05 80 | Pattern Timestep 1:00 81 | Pattern Start 0:00 82 | Report Timestep 1:00 83 | Report Start 0:00 84 | Start ClockTime 12 am 85 | Statistic None 86 | 87 | [REPORT] 88 | Status No 89 | Summary No 90 | Page 0 91 | 92 | [OPTIONS] 93 | Units GPM 94 | Headloss H-W 95 | Specific Gravity 1 96 | Viscosity 1 97 | Trials 40 98 | Accuracy 0.001 99 | CHECKFREQ 2 100 | MAXCHECK 10 101 | DAMPLIMIT 0 102 | Unbalanced Continue 10 103 | Pattern 1 104 | Demand Multiplier 1.0 105 | Emitter Exponent 0.5 106 | Quality None mg/L 107 | Diffusivity 1 108 | Tolerance 0.01 109 | 110 | [COORDINATES] 111 | ;Node X-Coord Y-Coord 112 | 0022 145.90 7317.62 113 | 3 897.87 6588.10 114 | 004 2188.55 6296.30 115 | 5 2884.40 7048.26 116 | 1 -673.40 8013.47 117 | N1 0 0 118 | 119 | [VERTICES] 120 | ;Link X-Coord Y-Coord 121 | 122 | [LABELS] 123 | ;X-Coord Y-Coord Label & Anchor Node 124 | 125 | [BACKDROP] 126 | DIMENSIONS 0.00 0.00 10000.00 10000.00 127 | UNITS None 128 | FILE 129 | OFFSET 0.00 0.00 130 | 131 | [END] 132 | -------------------------------------------------------------------------------- /tests/testthat/README.rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | 6 | 7 | [![Build Status](https://travis-ci.org/bradleyjeck/epanetReader.svg?branch=master)](https://travis-ci.org/bradleyjeck/epanetReader) 8 | [![Coverage Status](https://codecov.io/gh/bradleyjeck/epanetReader/branch/master/graph/badge.svg)](https://codecov.io/gh/bradleyjeck/epanetReader) 9 | [![CRAN RStudio mirror downloads](http://cranlogs.r-pkg.org/badges/epanetReader)](https://cran.r-project.org/package=epanetReader) 10 | [![CRAN version](http://www.r-pkg.org/badges/version/epanetReader)](https://cran.r-project.org/package=epanetReader) 11 | 12 | # epanetReader 13 | 14 | epanetReader is an R package for reading water network simulation data in 15 | Epanet's .inp and .rpt formats into R. Some basic summary information and 16 | plots are also provided. 17 | 18 | Epanet is a highly popular tool for water network simulation. But, it can be difficult 19 | to access network information for subsequent analysis and visualization. This 20 | is a real strength of R however, and there many tools already existing in R to 21 | support analysis and visualization. 22 | 23 | In addition to this README page, information about epanetReader is available from 24 | [Environmental Modelling & Software](http://www.sciencedirect.com/science/article/pii/S1364815216302870) [(pdf)](http://bradeck.net/docs/Eck2016epanetReaderEMS.pdf) 25 | and 26 | [ASCE Conference Proceedings](http://ascelibrary.org/doi/abs/10.1061/9780784479865.051) [(pdf)](http://bradeck.net/docs/Eck2016epanetReader-ewri.pdf). 27 | 28 | 29 | ## Installation 30 | 31 | * the latest released version: install.packages("epanetReader") 32 | * the development version: devtools::install_github("bradleyjeck/epanetReader") 33 | 34 | ## Getting Started 35 | 36 | ### Network files 37 | 38 | Read network information from an .inp file with a similar syntax as the popular read.table or read.csv functions. 39 | Note that the example network one that ships with Epanet causes a warning. The warning is just a reminder 40 | of how R deals with integer IDs. 41 | 42 | ```{r} 43 | library(epanetReader) 44 | n1 <- read.inp("Net1.inp") 45 | ``` 46 | 47 | Retrieve summary information about the network. 48 | ```{r} 49 | summary(n1) 50 | ``` 51 | 52 | A basic network plot is also available 53 | ```{r,eval=FALSE} 54 | plot(n1) 55 | ``` 56 | ![Net 1 plot](https://github.com/bradleyjeck/epanetReader/blob/master/img/Net1inp.png) 57 | 58 | The read.inp function returns an object with structure similar to the .inp file 59 | itself. A section in the .inp file corresponds to a named entry in the list. 60 | These entries are accessed using the \$ syntax of R. 61 | ```{r} 62 | names(n1) 63 | ``` 64 | 65 | Sections of the .inp file are stored as a data.frame or character vector. For 66 | example, the junction table is stored as a data.frame and retrieved as follows. 67 | In this case patterns were not specified in the junction table and so are 68 | marked NA. 69 | ```{r} 70 | n1$Junctions 71 | ``` 72 | 73 | A summary of the junction table shows that Net1.inp has nine junctions with 74 | elevations ranging from 690 to 710 and demands ranging from 0 to 200. Note that 75 | the node ID is stored as a character rather than an integer or factor. 76 | ```{r} 77 | summary(n1$Junctions) 78 | ``` 79 | 80 | ### Epanet Simulation Results 81 | 82 | Results of the network simulation specified in Net.inp may be stored in 83 | Net1.rpt by running Epanet from the command line. Note that the report section 84 | of the .inp file should contain the following lines in order to generate output 85 | readable by this package. 86 | 87 | >[REPORT] 88 | >Page 0 89 | >Links All 90 | >Nodes All 91 | 92 | On windows, calling the epanet executable epanet2d runs the simulation. 93 | ``` 94 | >epanet2d Net1.inp Net1.rpt 95 | 96 | ... EPANET Version 2.0 97 | 98 | o Retrieving network data 99 | o Computing hydraulics 100 | o Computing water quality 101 | o Writing output report to Net1.rpt 102 | 103 | ... EPANET completed. 104 | ``` 105 | 106 | The .rpt file generated by Epanet may be read into R using read.rpt(). The 107 | simulation is summarized over junctions, tanks and pipes. 108 | ```{r} 109 | n1r <- read.rpt("Net1.rpt") 110 | summary(n1r) 111 | ``` 112 | 113 | The default plot of simulation results is a map for time period 00:00:00. Note that the 114 | object created from the .inp file is a required argument to make the plot. 115 | ```{r,eval=FALSE} 116 | plot( n1r, n1) 117 | ``` 118 | ![Net 1 plot](https://github.com/bradleyjeck/epanetReader/blob/master/img/Net1rpt.png) 119 | 120 | In contrast to the treatment of .inp files described above, data from .rpt 121 | files is stored using a slightly different structure than the .rpt file. The 122 | function returns an object (list) with a data.frame for node results and 123 | data.frame for link results. These two data frames contain results from all 124 | the time periods. This storage choice was made to facilitate time series plots. 125 | 126 | Entries in the epanet.rpt object (list) created by read.rpt() are found using the names() function. 127 | ```{r} 128 | names(n1r) 129 | ``` 130 | 131 | Results for a chosen time period can be retrieved using the subset function. 132 | ```{r} 133 | subset(n1r$nodeResults, Timestamp == "0:00:00") 134 | ``` 135 | 136 | A comparison with the corresponding entry of the .rpt file, shown below for 137 | reference, shows that four columns have been added to the table. These pieces of extra 138 | info make visualizing the results easier. 139 | 140 | ``` 141 | Node Results at 0:00:00 hrs: 142 | -------------------------------------------------------- 143 | Demand Head Pressure Chlorine 144 | Node gpm ft psi mg/L 145 | -------------------------------------------------------- 146 | 10 0.00 1004.35 127.54 0.50 147 | 11 150.00 985.23 119.26 0.50 148 | 12 150.00 970.07 117.02 0.50 149 | 13 100.00 968.87 118.67 0.50 150 | 21 150.00 971.55 117.66 0.50 151 | 22 200.00 969.08 118.76 0.50 152 | 23 150.00 968.65 120.74 0.50 153 | 31 100.00 967.39 115.86 0.50 154 | 32 100.00 965.69 110.79 0.50 155 | 9 -1866.18 800.00 0.00 1.00 Reservoir 156 | 2 766.18 970.00 52.00 1.00 Tank 157 | ``` 158 | 159 | ### Epanet-msx simulation results 160 | 161 | Results of a multi-species simulation by Epanet-msx can be read as well. 162 | 163 | The read.msxrpt() function creates an s3 object of class epanetmsx.rpt. 164 | Similar to the approach above, there is a data frame for node results 165 | and link results. 166 | 167 | 168 | 169 | ## Usage with other packages 170 | 171 | ### ggplot2 172 | The ggplot2 package makes it easy to create complex graphics by allowing users 173 | to describe the plot in terms of the data. Continuing the Net1 example Here we 174 | plot chlorine concentration over time at each node in the network. 175 | 176 | ```{r,eval=FALSE} 177 | library(ggplot2) 178 | qplot( data= n1r$nodeResults, 179 | x = timeInSeconds/3600, y = Chlorine, 180 | facets = ~ID, xlab = "Hour") 181 | ``` 182 | 183 | ![Net 1 Cl plot](https://github.com/bradleyjeck/epanetReader/blob/master/img/Net1cl.png) 184 | 185 | ### Animation 186 | The animation package is useful for creating a video from successive plots. 187 | 188 | ```R 189 | # example with animation package 190 | library(animation) 191 | 192 | #unique time stamps 193 | ts <- unique((n1r$nodeResults$Timestamp)) 194 | imax <- length(ts) 195 | 196 | # generate animation of plots at each time step 197 | saveHTML( 198 | for( i in 1:imax){ 199 | plot(n1r, n1, Timestep = ts[i]) 200 | } 201 | ) 202 | ``` 203 | ## References 204 | 205 | Rossman, L. A. (2000) [Epanet 2 users manual](http://nepis.epa.gov/Adobe/PDF/P1007WWU.pdf). 206 | US EPA, Cincinnati, Ohio. 207 | 208 | 209 | -------------------------------------------------------------------------------- /tests/testthat/empty.inp: -------------------------------------------------------------------------------- 1 | 2 | [JUNCTIONS] 3 | 4 | 5 | [END] 6 | -------------------------------------------------------------------------------- /tests/testthat/example-noLinks.rpt: -------------------------------------------------------------------------------- 1 | Page 1 Mon Oct 05 20:58:05 2015 2 | 3 | ****************************************************************** 4 | * E P A N E T * 5 | * Hydraulic and Water Quality * 6 | * Analysis for Pipe Networks * 7 | * Version 2.00.12 * 8 | ****************************************************************** 9 | 10 | EPANET-MSX Example Network 11 | 12 | Input Data File ................... example.inp 13 | Number of Junctions................ 4 14 | Number of Reservoirs............... 1 15 | Number of Tanks ................... 0 16 | Number of Pipes ................... 5 17 | Number of Pumps ................... 0 18 | Number of Valves .................. 0 19 | Headloss Formula .................. Hazen-Williams 20 | Hydraulic Timestep ................ 1.00 hrs 21 | Hydraulic Accuracy ................ 0.001000 22 | Status Check Frequency ............ 2 23 | Maximum Trials Checked ............ 10 24 | Damping Limit Threshold ........... 0.000000 25 | Maximum Trials .................... 200 26 | Quality Analysis .................. None 27 | Specific Gravity .................. 1.00 28 | Relative Kinematic Viscosity ...... 1.00 29 | Relative Chemical Diffusivity ..... 1.00 30 | Demand Multiplier ................. 1.00 31 | Total Duration .................... 48.00 hrs 32 | Reporting Criteria: 33 | No Nodes 34 | No Links 35 | 36 | Analysis begun Mon Oct 05 20:58:05 2015 37 | 38 | Processing MSX input file example.msx 39 | 40 | 41 | Page 1 EPANET-MSX 1.1 42 | 43 | ****************************************************************** 44 | * E P A N E T - M S X * 45 | * Multi-Species Water Quality * 46 | * Analysis for Pipe Networks * 47 | * Version 1.1 * 48 | ****************************************************************** 49 | 50 | Arsenic Oxidation/Adsorption Example 51 | 52 | 53 | <<< Node C >>> 54 | 55 | Time AS5 AStot NH2CL 56 | hr:min UG/L UG/L MG/L 57 | ------- ---------- ---------- ---------- 58 | 0:00 0.00 0.00 0.00 59 | 2:00 0.00 0.00 0.00 60 | 4:00 0.00 0.00 0.00 61 | 6:00 0.00 0.00 0.00 62 | 8:00 0.00 0.00 1.10 63 | 10:00 9.17 9.17 1.10 64 | 12:00 9.17 9.17 1.10 65 | 14:00 9.17 9.17 1.10 66 | 16:00 9.17 9.17 1.10 67 | 18:00 9.17 9.17 1.10 68 | 20:00 9.17 9.17 1.10 69 | 22:00 9.17 9.17 1.10 70 | 24:00 9.17 9.17 1.10 71 | 26:00 9.17 9.17 1.10 72 | 28:00 9.17 9.17 1.10 73 | 30:00 9.17 9.17 1.10 74 | 32:00 9.17 9.17 1.10 75 | 34:00 9.17 9.17 1.11 76 | 36:00 9.17 9.17 1.11 77 | 38:00 10.03 10.03 1.11 78 | 40:00 10.03 10.03 1.11 79 | 42:00 10.03 10.03 1.11 80 | 44:00 10.03 10.03 1.11 81 | 46:00 10.03 10.03 1.11 82 | 48:00 10.03 10.03 1.11 83 | 84 | <<< Node D >>> 85 | 86 | Time AS5 AStot NH2CL 87 | hr:min UG/L UG/L MG/L 88 | ------- ---------- ---------- ---------- 89 | 0:00 0.00 0.00 0.00 90 | 2:00 0.00 0.00 0.00 91 | 4:00 0.00 0.00 0.00 92 | 6:00 0.00 0.00 0.00 93 | 8:00 0.00 0.00 0.00 94 | 10:00 0.00 0.00 0.00 95 | 12:00 0.00 0.00 0.00 96 | 14:00 0.00 0.00 0.00 97 | 16:00 0.00 0.00 0.00 98 | 18:00 0.00 0.00 0.00 99 | 20:00 0.00 0.00 0.00 100 | 22:00 0.00 0.00 0.00 101 | 24:00 0.00 0.00 0.24 102 | 26:00 0.00 0.00 0.24 103 | 28:00 9.17 9.17 0.24 104 | 30:00 9.17 9.17 0.24 105 | 32:00 9.17 9.17 0.24 106 | 34:00 9.17 9.17 0.24 107 | 36:00 9.17 9.17 0.24 108 | 38:00 9.17 9.17 0.24 109 | 40:00 9.17 9.17 0.24 110 | 42:00 9.17 9.17 0.24 111 | 44:00 9.17 9.17 0.24 112 | 46:00 9.17 9.17 0.24 113 | 48:00 9.17 9.17 0.24 114 | 115 | 116 | 117 | Analysis ended Mon Oct 05 20:58:05 2015 118 | -------------------------------------------------------------------------------- /tests/testthat/example-noNodes.rpt: -------------------------------------------------------------------------------- 1 | Page 1 Mon Oct 05 20:58:05 2015 2 | 3 | ****************************************************************** 4 | * E P A N E T * 5 | * Hydraulic and Water Quality * 6 | * Analysis for Pipe Networks * 7 | * Version 2.00.12 * 8 | ****************************************************************** 9 | 10 | EPANET-MSX Example Network 11 | 12 | Input Data File ................... example.inp 13 | Number of Junctions................ 4 14 | Number of Reservoirs............... 1 15 | Number of Tanks ................... 0 16 | Number of Pipes ................... 5 17 | Number of Pumps ................... 0 18 | Number of Valves .................. 0 19 | Headloss Formula .................. Hazen-Williams 20 | Hydraulic Timestep ................ 1.00 hrs 21 | Hydraulic Accuracy ................ 0.001000 22 | Status Check Frequency ............ 2 23 | Maximum Trials Checked ............ 10 24 | Damping Limit Threshold ........... 0.000000 25 | Maximum Trials .................... 200 26 | Quality Analysis .................. None 27 | Specific Gravity .................. 1.00 28 | Relative Kinematic Viscosity ...... 1.00 29 | Relative Chemical Diffusivity ..... 1.00 30 | Demand Multiplier ................. 1.00 31 | Total Duration .................... 48.00 hrs 32 | Reporting Criteria: 33 | No Nodes 34 | No Links 35 | 36 | Analysis begun Mon Oct 05 20:58:05 2015 37 | 38 | Processing MSX input file example.msx 39 | 40 | 41 | Page 1 EPANET-MSX 1.1 42 | 43 | ****************************************************************** 44 | * E P A N E T - M S X * 45 | * Multi-Species Water Quality * 46 | * Analysis for Pipe Networks * 47 | * Version 1.1 * 48 | ****************************************************************** 49 | 50 | Arsenic Oxidation/Adsorption Example 51 | 52 | 53 | <<< Link 5 >>> 54 | 55 | Time AS5 AStot AS5s NH2CL 56 | hr:min UG/L UG/L UG/M2 MG/L 57 | ------- ---------- ---------- ---------- ---------- 58 | 0:00 0.00 0.00 0.00 0.00 59 | 2:00 0.00 0.00 0.00 0.00 60 | 4:00 0.00 0.00 0.00 0.00 61 | 6:00 0.00 0.00 0.00 0.00 62 | 8:00 0.00 0.00 0.00 0.05 63 | 10:00 0.85 0.85 4.51 0.17 64 | 12:00 1.86 1.86 9.88 0.27 65 | 14:00 2.87 2.87 15.27 0.35 66 | 16:00 3.87 3.87 20.64 0.42 67 | 18:00 4.88 4.88 26.02 0.47 68 | 20:00 5.89 5.89 31.39 0.52 69 | 22:00 6.89 6.89 36.75 0.55 70 | 24:00 7.90 7.90 42.12 0.56 71 | 26:00 8.91 8.91 47.50 0.56 72 | 28:00 9.17 9.17 48.93 0.56 73 | 30:00 9.17 9.17 48.93 0.56 74 | 32:00 9.17 9.17 48.93 0.56 75 | 34:00 9.17 9.17 48.93 0.56 76 | 36:00 9.17 9.17 48.93 0.57 77 | 38:00 9.19 9.19 48.93 0.57 78 | 40:00 9.30 9.30 48.95 0.57 79 | 42:00 9.41 9.41 48.96 0.57 80 | 44:00 9.52 9.52 48.97 0.57 81 | 46:00 9.64 9.64 48.98 0.57 82 | 48:00 9.75 9.75 48.99 0.57 83 | 84 | Analysis ended Mon Oct 05 20:58:05 2015 85 | -------------------------------------------------------------------------------- /tests/testthat/example-noTitle.rpt: -------------------------------------------------------------------------------- 1 | Page 1 Mon Oct 05 20:58:05 2015 2 | 3 | ****************************************************************** 4 | * E P A N E T * 5 | * Hydraulic and Water Quality * 6 | * Analysis for Pipe Networks * 7 | * Version 2.00.12 * 8 | ****************************************************************** 9 | 10 | EPANET-MSX Example Network 11 | 12 | Input Data File ................... example.inp 13 | Number of Junctions................ 4 14 | Number of Reservoirs............... 1 15 | Number of Tanks ................... 0 16 | Number of Pipes ................... 5 17 | Number of Pumps ................... 0 18 | Number of Valves .................. 0 19 | Headloss Formula .................. Hazen-Williams 20 | Hydraulic Timestep ................ 1.00 hrs 21 | Hydraulic Accuracy ................ 0.001000 22 | Status Check Frequency ............ 2 23 | Maximum Trials Checked ............ 10 24 | Damping Limit Threshold ........... 0.000000 25 | Maximum Trials .................... 200 26 | Quality Analysis .................. None 27 | Specific Gravity .................. 1.00 28 | Relative Kinematic Viscosity ...... 1.00 29 | Relative Chemical Diffusivity ..... 1.00 30 | Demand Multiplier ................. 1.00 31 | Total Duration .................... 48.00 hrs 32 | Reporting Criteria: 33 | No Nodes 34 | No Links 35 | 36 | Analysis begun Mon Oct 05 20:58:05 2015 37 | 38 | Processing MSX input file example.msx 39 | 40 | 41 | Page 1 EPANET-MSX 1.1 42 | 43 | ****************************************************************** 44 | * E P A N E T - M S X * 45 | * Multi-Species Water Quality * 46 | * Analysis for Pipe Networks * 47 | * Version 1.1 * 48 | ****************************************************************** 49 | 50 | 51 | 52 | <<< Node C >>> 53 | 54 | Time AS5 AStot NH2CL 55 | hr:min UG/L UG/L MG/L 56 | ------- ---------- ---------- ---------- 57 | 0:00 0.00 0.00 0.00 58 | 2:00 0.00 0.00 0.00 59 | 4:00 0.00 0.00 0.00 60 | 6:00 0.00 0.00 0.00 61 | 8:00 0.00 0.00 1.10 62 | 10:00 9.17 9.17 1.10 63 | 12:00 9.17 9.17 1.10 64 | 14:00 9.17 9.17 1.10 65 | 16:00 9.17 9.17 1.10 66 | 18:00 9.17 9.17 1.10 67 | 20:00 9.17 9.17 1.10 68 | 22:00 9.17 9.17 1.10 69 | 24:00 9.17 9.17 1.10 70 | 26:00 9.17 9.17 1.10 71 | 28:00 9.17 9.17 1.10 72 | 30:00 9.17 9.17 1.10 73 | 32:00 9.17 9.17 1.10 74 | 34:00 9.17 9.17 1.11 75 | 36:00 9.17 9.17 1.11 76 | 38:00 10.03 10.03 1.11 77 | 40:00 10.03 10.03 1.11 78 | 42:00 10.03 10.03 1.11 79 | 44:00 10.03 10.03 1.11 80 | 46:00 10.03 10.03 1.11 81 | 48:00 10.03 10.03 1.11 82 | 83 | <<< Node D >>> 84 | 85 | Time AS5 AStot NH2CL 86 | hr:min UG/L UG/L MG/L 87 | ------- ---------- ---------- ---------- 88 | 0:00 0.00 0.00 0.00 89 | 2:00 0.00 0.00 0.00 90 | 4:00 0.00 0.00 0.00 91 | 6:00 0.00 0.00 0.00 92 | 8:00 0.00 0.00 0.00 93 | 10:00 0.00 0.00 0.00 94 | 12:00 0.00 0.00 0.00 95 | 14:00 0.00 0.00 0.00 96 | 16:00 0.00 0.00 0.00 97 | 18:00 0.00 0.00 0.00 98 | 20:00 0.00 0.00 0.00 99 | 22:00 0.00 0.00 0.00 100 | 24:00 0.00 0.00 0.24 101 | 26:00 0.00 0.00 0.24 102 | 28:00 9.17 9.17 0.24 103 | 30:00 9.17 9.17 0.24 104 | 32:00 9.17 9.17 0.24 105 | 34:00 9.17 9.17 0.24 106 | 36:00 9.17 9.17 0.24 107 | 38:00 9.17 9.17 0.24 108 | 40:00 9.17 9.17 0.24 109 | 42:00 9.17 9.17 0.24 110 | 44:00 9.17 9.17 0.24 111 | 46:00 9.17 9.17 0.24 112 | 48:00 9.17 9.17 0.24 113 | 114 | <<< Link 5 >>> 115 | 116 | Time AS5 AStot AS5s NH2CL 117 | hr:min UG/L UG/L UG/M2 MG/L 118 | ------- ---------- ---------- ---------- ---------- 119 | 0:00 0.00 0.00 0.00 0.00 120 | 2:00 0.00 0.00 0.00 0.00 121 | 4:00 0.00 0.00 0.00 0.00 122 | 6:00 0.00 0.00 0.00 0.00 123 | 8:00 0.00 0.00 0.00 0.05 124 | 10:00 0.85 0.85 4.51 0.17 125 | 12:00 1.86 1.86 9.88 0.27 126 | 14:00 2.87 2.87 15.27 0.35 127 | 16:00 3.87 3.87 20.64 0.42 128 | 18:00 4.88 4.88 26.02 0.47 129 | 20:00 5.89 5.89 31.39 0.52 130 | 22:00 6.89 6.89 36.75 0.55 131 | 24:00 7.90 7.90 42.12 0.56 132 | 26:00 8.91 8.91 47.50 0.56 133 | 28:00 9.17 9.17 48.93 0.56 134 | 30:00 9.17 9.17 48.93 0.56 135 | 32:00 9.17 9.17 48.93 0.56 136 | 34:00 9.17 9.17 48.93 0.56 137 | 36:00 9.17 9.17 48.93 0.57 138 | 38:00 9.19 9.19 48.93 0.57 139 | 40:00 9.30 9.30 48.95 0.57 140 | 42:00 9.41 9.41 48.96 0.57 141 | 44:00 9.52 9.52 48.97 0.57 142 | 46:00 9.64 9.64 48.98 0.57 143 | 48:00 9.75 9.75 48.99 0.57 144 | 145 | Analysis ended Mon Oct 05 20:58:05 2015 146 | -------------------------------------------------------------------------------- /tests/testthat/example.rpt: -------------------------------------------------------------------------------- 1 | Page 1 Mon Oct 05 20:58:05 2015 2 | 3 | ****************************************************************** 4 | * E P A N E T * 5 | * Hydraulic and Water Quality * 6 | * Analysis for Pipe Networks * 7 | * Version 2.00.12 * 8 | ****************************************************************** 9 | 10 | EPANET-MSX Example Network 11 | 12 | Input Data File ................... example.inp 13 | Number of Junctions................ 4 14 | Number of Reservoirs............... 1 15 | Number of Tanks ................... 0 16 | Number of Pipes ................... 5 17 | Number of Pumps ................... 0 18 | Number of Valves .................. 0 19 | Headloss Formula .................. Hazen-Williams 20 | Hydraulic Timestep ................ 1.00 hrs 21 | Hydraulic Accuracy ................ 0.001000 22 | Status Check Frequency ............ 2 23 | Maximum Trials Checked ............ 10 24 | Damping Limit Threshold ........... 0.000000 25 | Maximum Trials .................... 200 26 | Quality Analysis .................. None 27 | Specific Gravity .................. 1.00 28 | Relative Kinematic Viscosity ...... 1.00 29 | Relative Chemical Diffusivity ..... 1.00 30 | Demand Multiplier ................. 1.00 31 | Total Duration .................... 48.00 hrs 32 | Reporting Criteria: 33 | No Nodes 34 | No Links 35 | 36 | Analysis begun Mon Oct 05 20:58:05 2015 37 | 38 | Processing MSX input file example.msx 39 | 40 | 41 | Page 1 EPANET-MSX 1.1 42 | 43 | ****************************************************************** 44 | * E P A N E T - M S X * 45 | * Multi-Species Water Quality * 46 | * Analysis for Pipe Networks * 47 | * Version 1.1 * 48 | ****************************************************************** 49 | 50 | Arsenic Oxidation/Adsorption Example 51 | 52 | 53 | <<< Node C >>> 54 | 55 | Time AS5 AStot NH2CL 56 | hr:min UG/L UG/L MG/L 57 | ------- ---------- ---------- ---------- 58 | 0:00 0.00 0.00 0.00 59 | 2:00 0.00 0.00 0.00 60 | 4:00 0.00 0.00 0.00 61 | 6:00 0.00 0.00 0.00 62 | 8:00 0.00 0.00 1.10 63 | 10:00 9.17 9.17 1.10 64 | 12:00 9.17 9.17 1.10 65 | 14:00 9.17 9.17 1.10 66 | 16:00 9.17 9.17 1.10 67 | 18:00 9.17 9.17 1.10 68 | 20:00 9.17 9.17 1.10 69 | 22:00 9.17 9.17 1.10 70 | 24:00 9.17 9.17 1.10 71 | 26:00 9.17 9.17 1.10 72 | 28:00 9.17 9.17 1.10 73 | 30:00 9.17 9.17 1.10 74 | 32:00 9.17 9.17 1.10 75 | 34:00 9.17 9.17 1.11 76 | 36:00 9.17 9.17 1.11 77 | 38:00 10.03 10.03 1.11 78 | 40:00 10.03 10.03 1.11 79 | 42:00 10.03 10.03 1.11 80 | 44:00 10.03 10.03 1.11 81 | 46:00 10.03 10.03 1.11 82 | 48:00 10.03 10.03 1.11 83 | 84 | <<< Node D >>> 85 | 86 | Time AS5 AStot NH2CL 87 | hr:min UG/L UG/L MG/L 88 | ------- ---------- ---------- ---------- 89 | 0:00 0.00 0.00 0.00 90 | 2:00 0.00 0.00 0.00 91 | 4:00 0.00 0.00 0.00 92 | 6:00 0.00 0.00 0.00 93 | 8:00 0.00 0.00 0.00 94 | 10:00 0.00 0.00 0.00 95 | 12:00 0.00 0.00 0.00 96 | 14:00 0.00 0.00 0.00 97 | 16:00 0.00 0.00 0.00 98 | 18:00 0.00 0.00 0.00 99 | 20:00 0.00 0.00 0.00 100 | 22:00 0.00 0.00 0.00 101 | 24:00 0.00 0.00 0.24 102 | 26:00 0.00 0.00 0.24 103 | 28:00 9.17 9.17 0.24 104 | 30:00 9.17 9.17 0.24 105 | 32:00 9.17 9.17 0.24 106 | 34:00 9.17 9.17 0.24 107 | 36:00 9.17 9.17 0.24 108 | 38:00 9.17 9.17 0.24 109 | 40:00 9.17 9.17 0.24 110 | 42:00 9.17 9.17 0.24 111 | 44:00 9.17 9.17 0.24 112 | 46:00 9.17 9.17 0.24 113 | 48:00 9.17 9.17 0.24 114 | 115 | <<< Link 5 >>> 116 | 117 | Time AS5 AStot AS5s NH2CL 118 | hr:min UG/L UG/L UG/M2 MG/L 119 | ------- ---------- ---------- ---------- ---------- 120 | 0:00 0.00 0.00 0.00 0.00 121 | 2:00 0.00 0.00 0.00 0.00 122 | 4:00 0.00 0.00 0.00 0.00 123 | 6:00 0.00 0.00 0.00 0.00 124 | 8:00 0.00 0.00 0.00 0.05 125 | 10:00 0.85 0.85 4.51 0.17 126 | 12:00 1.86 1.86 9.88 0.27 127 | 14:00 2.87 2.87 15.27 0.35 128 | 16:00 3.87 3.87 20.64 0.42 129 | 18:00 4.88 4.88 26.02 0.47 130 | 20:00 5.89 5.89 31.39 0.52 131 | 22:00 6.89 6.89 36.75 0.55 132 | 24:00 7.90 7.90 42.12 0.56 133 | 26:00 8.91 8.91 47.50 0.56 134 | 28:00 9.17 9.17 48.93 0.56 135 | 30:00 9.17 9.17 48.93 0.56 136 | 32:00 9.17 9.17 48.93 0.56 137 | 34:00 9.17 9.17 48.93 0.56 138 | 36:00 9.17 9.17 48.93 0.57 139 | 38:00 9.19 9.19 48.93 0.57 140 | 40:00 9.30 9.30 48.95 0.57 141 | 42:00 9.41 9.41 48.96 0.57 142 | 44:00 9.52 9.52 48.97 0.57 143 | 46:00 9.64 9.64 48.98 0.57 144 | 48:00 9.75 9.75 48.99 0.57 145 | 146 | Analysis ended Mon Oct 05 20:58:05 2015 147 | -------------------------------------------------------------------------------- /tests/testthat/for-various-tests.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | This file is for testing parts of the epanetReader package. 3 | It's not intended to run. 4 | 5 | [TANKS] 6 | ;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve 7 | A 123 11 10 20 50.5 0 vc1 ; 8 | 9 | [RESERVOIRS] 10 | ;ID Head Pattern 11 | C 321 respat ; 12 | 13 | [EMITTERS] 14 | ;ID FlowCoef 15 | D 1.1 16 | EE 3.3 17 | 18 | [SOURCES] 19 | ;Node Type Strength Pattern 20 | ;-------------------------------- 21 | N1 CONCEN 1.2 Pat1 ;Concentration varies with time 22 | N44 MASS 12 ;Constant mass injection 23 | 24 | [REACTIONS] 25 | ORDER WALL 0 ;Wall reactions are zero-order 26 | GLOBAL BULK -0.5 ;Global bulk decay coeff. 27 | GLOBAL WALL -1.0 ;Global wall decay coeff. 28 | WALL P220 -0.5 ;Pipe-specific wall coeffs. 29 | WALL P244 -0.7 30 | 31 | [MIXING] 32 | ;Tank Model 33 | ;----------------------- 34 | T12 LIFO 35 | T23 2COMP 0.2 36 | 37 | [END] 38 | 39 | -------------------------------------------------------------------------------- /tests/testthat/icdm13.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | Network from 2013 ICDM Paper 3 | 4 | [JUNCTIONS] 5 | ;ID Elev Demand 6 | 1 1 0.3 7 | 2 1 0.3 8 | 3 1 0.3 9 | 4 1 0.3 10 | 5 1 0.3 11 | 6 1 0.3 12 | 7 1 0.3 13 | 8 1 0.3 14 | 9 1 0.3 15 | 10 1 0.3 16 | 11 1 0.3 17 | 12 1 0.3 18 | 13 1 0.3 19 | 14 1 0.3 20 | 15 1 0.3 21 | 16 1 0.3 22 | 23 | 24 | [RESERVOIRS] 25 | ;ID Elev 26 | R 2 27 | 28 | [PIPES] 29 | ;ID Node1 Node2 Length Diam Roughness 30 | ; [M] [mm] [mm] 31 | 12 1 2 100 100 0.03 32 | 23 2 3 100 90 0.03 33 | 1R 1 R 200 120 0.02 34 | 34 3 4 200 100 0.02 35 | 45 4 5 300 100 0.02 36 | 78 7 8 40 90 0.04 37 | 58 5 8 120 80 0.04 38 | 56 5 6 80 90 0.03 39 | 79 7 9 100 120 0.01 40 | 910 9 10 80 80 0.02 41 | 1011 10 11 90 80 0.02 42 | 913 9 13 100 90 0.01 43 | 1314 13 14 80 80 0.05 44 | 1214 12 14 50 80 0.06 45 | 1416 14 16 60 80 0.02 46 | 1514 15 14 1 80 0.02 47 | 13 1 3 1000 100 0.02 48 | 57 5 7 150 90 0.03 49 | 1113 11 13 120 80 0.03 50 | 1615 16 15 90 80 0.03 51 | 912 9 12 200 90 0.03 52 | 53 | [OPTIONS] 54 | Units LPS 55 | Headloss H-W 56 | 57 | [END] 58 | -------------------------------------------------------------------------------- /tests/testthat/inp-pipe-table-some-statuses-empty.txt: -------------------------------------------------------------------------------- 1 | [PIPES] 2 | 197 190 191 88.6880 82.0400 0.0015 1.7738 3 | 197 190 191 88.6880 82.0400 0.0015 1.7738 4 | 201 196 5495 49.0300 500.0000 0.0300 0.9806 5 | 202 198 199 26.6800 500.0000 0.0300 0.5336 6 | 201 196 5495 49.0300 500.0000 0.0300 0.9806 7 | 202 198 199 26.6800 500.0000 0.0300 0.5336 8 | 197 190 191 88.6880 82.0400 0.0015 1.7738 9 | 201 196 5495 49.0300 500.0000 0.0300 0.9806 10 | 202 198 199 26.6800 500.0000 0.0300 0.5336 11 | 203 207 Tank_1 7.3900 600.0000 0.0015 0.2332 CLOSED 12 | 204 9545 9544 6.7800 150.0000 0.0300 0.1740 13 | 226 238 239 3.4174 250.0000 0.1200 0.0683 14 | 227 238 240 104.9083 75.0000 0.1200 2.0982 15 | 228 241 242 119.7500 75.0000 0.0300 2.3950 16 | 229 241 243 75.1203 75.0000 0.0300 1.5024 17 | 230 244 245 7.4668 75.0000 0.0300 0.1493 CLOSED 18 | 231 246 247 114.6285 150.0000 0.0300 2.2926 19 | 232 6382 6366 2.0000 100.0000 0.0300 0.0400 20 | 233 250 251 141.0686 82.0400 0.0015 2.8214 21 | 234 252 253 77.4107 100.0000 0.0300 1.5482 22 | 235 254 255 88.7250 150.0000 0.0300 1.7745 23 | 236 256 257 47.1455 75.0000 0.0300 0.9429 24 | 237 258 259 77.2425 150.0000 0.1200 1.5448 CLOSED 25 | 238 260 261 5.2920 200.0000 0.1200 0.1058 26 | 239 6880 263 11.1200 100.0000 0.1200 0.2224 27 | 240 264 265 4.9000 82.0400 0.0015 0.0980 28 | 241 266 267 68.9582 75.0000 0.0300 1.3792 29 | 30 | [END] 31 | -------------------------------------------------------------------------------- /tests/testthat/oneprv.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | 3 | 4 | [JUNCTIONS] 5 | ;ID Elev Demand Pattern 6 | 2 0 0 ; 7 | 3 0 0 ; 8 | 4 0 23 ; 9 | 5 0 32 ; 10 | 11 | [RESERVOIRS] 12 | ;ID Head Pattern 13 | 1 100 ; 14 | 15 | [TANKS] 16 | ;ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve 17 | 18 | [PIPES] 19 | ;ID Node1 Node2 Length Diameter Roughness MinorLoss Status 20 | 1 1 2 1000 12 100 0 Open ; 21 | 3 3 4 1000 12 100 0 Open ; 22 | 4 4 5 1000 12 100 0 Open ; 23 | 5 5 3 1000 12 100 0 Open ; 24 | 25 | [PUMPS] 26 | ;ID Node1 Node2 Parameters 27 | 28 | [VALVES] 29 | ;ID Node1 Node2 Diameter Type Setting MinorLoss 30 | 2 2 3 12 PRV 50 0 ; 31 | 32 | [TAGS] 33 | 34 | [DEMANDS] 35 | ;Junction Demand Pattern Category 36 | 2 1.1 P1 37 | 2 0.1 P2 38 | 2 0.2 P3 39 | 40 | 41 | 42 | [STATUS] 43 | ;ID Status/Setting 44 | 45 | [PATTERNS] 46 | ;ID Multipliers 47 | 48 | [CURVES] 49 | ;ID X-Value Y-Value 50 | 51 | [CONTROLS] 52 | 53 | [RULES] 54 | 55 | [ENERGY] 56 | Global Efficiency 75 57 | Global Price 0 58 | Demand Charge 0 59 | 60 | [EMITTERS] 61 | ;Junction Coefficient 62 | 63 | [QUALITY] 64 | ;Node InitQual 65 | 66 | [SOURCES] 67 | ;Node Type Quality Pattern 68 | 69 | [REACTIONS] 70 | ;Type Pipe/Tank Coefficient 71 | Order Bulk 1 72 | Order Tank 1 73 | Order Wall 1 74 | Global Bulk 0 75 | Global Wall 0 76 | Limiting Potential 0 77 | Roughness Correlation 0 78 | 79 | [MIXING] 80 | ;Tank Model 81 | 82 | [TIMES] 83 | Duration 0 84 | Hydraulic Timestep 1:00 85 | Quality Timestep 0:05 86 | Pattern Timestep 1:00 87 | Pattern Start 0:00 88 | Report Timestep 1:00 89 | Report Start 0:00 90 | Start ClockTime 12 am 91 | Statistic None 92 | 93 | [REPORT] 94 | Status No 95 | Summary No 96 | Page 0 97 | 98 | [OPTIONS] 99 | Units GPM 100 | Headloss H-W 101 | Specific Gravity 1 102 | Viscosity 1 103 | Trials 40 104 | Accuracy 0.001 105 | CHECKFREQ 2 106 | MAXCHECK 10 107 | DAMPLIMIT 0 108 | Unbalanced Continue 10 109 | Pattern 1 110 | Demand Multiplier 1.0 111 | Emitter Exponent 0.5 112 | Quality None mg/L 113 | Diffusivity 1 114 | Tolerance 0.01 115 | 116 | [COORDINATES] 117 | ;Node X-Coord Y-Coord 118 | 2 2618.64 5677.97 119 | 3 5788.14 5677.97 120 | 4 7720.34 7067.80 121 | 5 7957.63 4016.95 122 | 1 -584.75 5745.76 123 | 124 | [VERTICES] 125 | ;Link X-Coord Y-Coord 126 | 1 59.32 6406.78 127 | 1 449.15 6711.86 128 | 1 1025.42 6966.10 129 | 1 1228.81 6728.81 130 | 1 1703.39 6694.92 131 | 1 1822.03 6406.78 132 | 1 2177.97 6271.19 133 | 1 2550.85 6067.80 134 | 3 6449.15 5627.12 135 | 3 6686.44 5762.71 136 | 3 6584.75 6152.54 137 | 3 6991.53 6271.19 138 | 3 7398.31 6389.83 139 | 3 7110.17 6796.61 140 | 3 7466.10 6745.76 141 | 3 7788.14 6711.86 142 | 3 7262.71 6949.15 143 | 4 8550.85 6457.63 144 | 4 9144.07 5915.25 145 | 4 9245.76 5372.88 146 | 4 8906.78 4966.10 147 | 4 8889.83 4610.17 148 | 4 9127.12 3966.10 149 | 4 8754.24 3830.51 150 | 4 8381.36 4101.69 151 | 4 8347.46 3830.51 152 | 4 8076.27 3559.32 153 | 4 8008.47 3677.97 154 | 4 7754.24 3728.81 155 | 5 7398.31 4101.69 156 | 5 6838.98 4135.59 157 | 5 6669.49 4288.14 158 | 5 6449.15 4322.03 159 | 5 6754.24 4627.12 160 | 5 5805.08 4661.02 161 | 5 5686.44 4898.31 162 | 5 6076.27 5033.90 163 | 5 5618.64 5186.44 164 | 165 | [LABELS] 166 | ;X-Coord Y-Coord Label & Anchor Node 167 | 168 | [BACKDROP] 169 | DIMENSIONS 0.00 0.00 10000.00 10000.00 170 | UNITS None 171 | FILE 172 | OFFSET 0.00 0.00 173 | 174 | [END] 175 | -------------------------------------------------------------------------------- /tests/testthat/oneprv.rpt: -------------------------------------------------------------------------------- 1 | Page 1 Tue Dec 15 12:34:58 2015 2 | 3 | ****************************************************************** 4 | * E P A N E T * 5 | * Hydraulic and Water Quality * 6 | * Analysis for Pipe Networks * 7 | * Version 2.00.12 * 8 | ****************************************************************** 9 | 10 | Analysis begun Tue Dec 15 12:34:58 2015 11 | 12 | 13 | Node Results: 14 | ---------------------------------------------- 15 | Demand Head Pressure 16 | Node gpm ft psi 17 | ---------------------------------------------- 18 | 2 0.00 99.97 43.32 19 | 3 0.00 99.97 43.32 20 | 4 23.00 99.96 43.31 21 | 5 50.00 99.96 43.31 22 | 1 -73.00 100.00 0.00 Reservoir 23 | 24 | 25 | Link Results: 26 | ---------------------------------------------- 27 | Flow Velocity Headloss 28 | Link gpm fps /1000ft 29 | ---------------------------------------------- 30 | 1 73.00 0.21 0.03 31 | 2 35.20 0.10 0.01 32 | 3 12.20 0.03 0.00 33 | 4 -37.80 0.11 0.01 34 | 5 73.00 0.21 0.00 PRV 35 | 36 | Analysis ended Tue Dec 15 12:34:58 2015 37 | -------------------------------------------------------------------------------- /tests/testthat/test_epanet.inp-s3.r: -------------------------------------------------------------------------------- 1 | #****************************************** 2 | # 3 | # (C) Copyright IBM Corp. 2014 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #****************************************** 8 | 9 | context("epanet.inp s3 object") 10 | test_that("net1.inp reads correctly", 11 | { 12 | Net1 <- suppressWarnings( read.inp( "Net1.inp") ) 13 | expect_that( class(Net1), equals("epanet.inp")) 14 | expect_that( Net1$Curves$`1`$Y , equals(250)) 15 | expect_that( length(Net1$Controls), equals(2)) 16 | expect_that( dim(Net1$Quality)[1], equals(11)) 17 | 18 | expect_true( is.epanet.inp( Net1) ) 19 | 20 | }) 21 | 22 | test_that("Net1-gui.inp reads with warning",{ 23 | 24 | expect_warning( n1 <- read.inp("Net1-gui.inp")) 25 | 26 | }) 27 | 28 | test_that("Net2.inp reads correctly", { 29 | 30 | Net2 <- suppressWarnings( read.inp("Net2.inp") ) 31 | 32 | expect_that( class(Net2), equals("epanet.inp")) 33 | expect_that( Net2$Junctions$Demand[1] , equals(-694.4)) 34 | expect_that( Net2$Sources$Type[1], equals("CONCEN")) 35 | expect_false( is.null(Net2$Report)) 36 | 37 | }) 38 | 39 | test_that("read Net3.inp",{ 40 | 41 | Net3 <- suppressWarnings( read.inp("Net3.inp")) 42 | 43 | expect_false( is.null(Net3$Status)) 44 | expect_true(Net3$Status$Status[1] == 'Closed') 45 | }) 46 | 47 | test_that("icdm.inp",{ 48 | 49 | 50 | net <- suppressWarnings( read.inp("icdm13.inp") ) 51 | 52 | numPipes <- dim( net$Pipes)[1] 53 | expect_equal( numPipes, 21 ) 54 | 55 | }) 56 | 57 | test_that("read Net4.inp loads correct ids", { 58 | Net4 <- suppressWarnings(read.inp("Net4.inp")) 59 | 60 | expect_equal(Net4$Junctions$ID, c("0022", "3", "004", "5")) 61 | 62 | expect_equal(Net4$Pipes$Node1, c("N1", "0022", "3", "0022", "004")) 63 | expect_equal(Net4$Pipes$Node2, c("0022", "3", "004", "5", "5")) 64 | }) 65 | 66 | 67 | context("summary.epanet.inp s3 object") 68 | test_that(" summary works for Net1 ", 69 | { 70 | 71 | Net1 <- suppressWarnings( read.inp( "Net1.inp")) 72 | sn1 <- summary(Net1) 73 | expect_that(sn1$entryCounts[1,1], equals(9)) 74 | }) 75 | 76 | test_that(" summary prints correctly for Net 1",{ 77 | 78 | Net1 <- suppressWarnings( read.inp( "Net1.inp")) 79 | sn1 <- summary(Net1) 80 | expect_output(print(sn1), "EPANET Example Network 1") 81 | expect_output(print(sn1), "Junctions \\s+ 9") 82 | expect_output(print(sn1), "Coordinates \\s+ 11") 83 | }) 84 | 85 | test_that("summary works for Net2",{ 86 | 87 | Net2 <- suppressWarnings( read.inp("Net2.inp") ) 88 | sn2 <- summary(Net2) 89 | expect_output(print(sn2), "Pipes\\s+40") 90 | }) 91 | 92 | test_that("Net3 summary",{ 93 | Net3 <- suppressWarnings( read.inp("Net3.inp")) 94 | n3s <- summary(Net3) 95 | expect_output(print(n3s),"Junctions\\s+92") 96 | expect_output(print(n3s),"Pumps\\s+2") 97 | }) 98 | 99 | context("plot.epanet.inp works") 100 | test_that("Plot Net 1 labels",{ 101 | x <- suppressWarnings(read.inp("Net1.inp")) 102 | plot(x , plot.labels=T) 103 | }) 104 | test_that("Plot Net 2 labels",{ 105 | x <- suppressWarnings(read.inp("Net2.inp")) 106 | plot(x , plot.labels=T) 107 | }) 108 | test_that("Plot Net 3 labels",{ 109 | x <- suppressWarnings(read.inp("Net3.inp")) 110 | plot(x , plot.labels=T, link.lwd=1, link.col='red') 111 | }) 112 | -------------------------------------------------------------------------------- /tests/testthat/test_epanet.rpt-s3.r: -------------------------------------------------------------------------------- 1 | #****************************************** 2 | # 3 | # (C) Copyright IBM Corp. 2014 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #****************************************** 8 | # File: rptFuncs_tests.r 9 | # 10 | # By: bradley.eck@ie.ibm.com 11 | # 12 | # Purpose: tests for reading .rpt files 13 | # 14 | 15 | 16 | context("epanet.rpt s3 object") 17 | test_that("net1.rpt reads correctly", 18 | { 19 | Net1res <- read.rpt("Net1.rpt") 20 | 21 | expect_that( Net1res, is_a("epanet.rpt")) 22 | 23 | expect_that( class(Net1res$nodeResults), equals("data.frame")) 24 | 25 | # get the value of P in node 22 for timestep 1:00 26 | p <- subset(Net1res$nodeResults, Timestamp == "1:00:00" & ID == "22", select = Pressure) 27 | expect_that( as.numeric(p), equals(120.07) ) 28 | 29 | # flow in pump 9 at 24 hrs 30 | q <- subset( Net1res$linkResults, Timestamp =="24:00:00" & ID == "9", select = Flow) 31 | expect_that(as.numeric(q), equals(1892.24)) 32 | 33 | expect_true( is.epanet.rpt( Net1res)) 34 | 35 | # Energy Usage is correct 36 | avgpower <- subset( Net1res$energyUsage, Pump == "9", select = avg_kW ) 37 | expect_that(as.numeric(avgpower), equals(96.25)) 38 | 39 | }) 40 | 41 | test_that("net1-gui.rpt reads correctly", 42 | { 43 | Net1res <- read.rpt("Net1-gui.rpt") 44 | 45 | expect_that( Net1res, is_a("epanet.rpt")) 46 | 47 | expect_that( class(Net1res$nodeResults), equals("data.frame")) 48 | 49 | # get the value of P in node 22 for timestep 1:00 50 | p <- subset(Net1res$nodeResults, Timestamp == "1:00" & ID == "22", select = Pressure) 51 | expect_that( as.numeric(p), equals(120.07) ) 52 | 53 | # flow in pump 9 at 24 hrs 54 | q <- subset( Net1res$linkResults, Timestamp =="24:00" & ID == "9", select = Flow) 55 | expect_that(as.numeric(q), equals(1892.24)) 56 | 57 | # Energy Usage is correct 58 | avgpower <- subset( Net1res$energyUsage, Pump == "9", select = avg_kW ) 59 | expect_that(as.numeric(avgpower), equals(96.25)) 60 | }) 61 | 62 | test_that("another version of net1 with page breaks reads ",{ 63 | 64 | Net1res <- read.rpt("Net1-pagebrks.rpt") 65 | expect_that( Net1res, is_a("epanet.rpt")) 66 | 67 | expect_that( class(Net1res$nodeResults), equals("data.frame")) 68 | 69 | # get the value of P in node 22 for timestep 1:00 70 | p <- subset(Net1res$nodeResults, Timestamp == "1:00:00" & ID == "22", select = Pressure) 71 | expect_that( as.numeric(p), equals(120.07) ) 72 | 73 | # flow in pump 9 at 24 hrs 74 | q <- subset( Net1res$linkResults, Timestamp =="24:00:00" & ID == "9", select = Flow) 75 | expect_that(as.numeric(q), equals(1892.24)) 76 | 77 | # Energy Usage is correct 78 | avgpower <- subset( Net1res$energyUsage, Pump == "9", select = avg_kW ) 79 | expect_that(as.numeric(avgpower), equals(96.25)) 80 | 81 | }) 82 | test_that("Net1.rpt and Net1-gui.rpt are equivalent",{ 83 | 84 | n1r <- read.rpt("Net1.rpt") 85 | n1rg <- read.rpt("Net1-gui.rpt") 86 | actual <- all.equal(n1r,n1rg) 87 | expected <- c( "Component \"nodeResults\": Names: 1 string mismatch", 88 | "Component \"nodeResults\": Component \"Timestamp\": 275 string mismatches", 89 | "Component \"linkResults\": Names: 4 string mismatches", 90 | "Component \"linkResults\": Length mismatch: comparison on first 8 components", 91 | "Component \"linkResults\": Component 5: Modes: character, numeric", 92 | "Component \"linkResults\": Component 5: Attributes: < target is NULL, current is list >", 93 | "Component \"linkResults\": Component 5: target is character, current is factor", 94 | "Component \"linkResults\": Component 6: 325 string mismatches", 95 | "Component \"linkResults\": Component 7: Modes: numeric, character", 96 | "Component \"linkResults\": Component 7: target is numeric, current is character", 97 | "Component \"linkResults\": Component 8: 'current' is not a factor") 98 | 99 | 100 | 101 | expect_equal(length(actual), length(expected)) 102 | }) 103 | 104 | 105 | 106 | test_that("Net2.rpt reads correctly",{ 107 | net2res <- read.rpt("Net2.rpt") 108 | expect_true( is.null( net2res$energyUsage) ) 109 | }) 110 | 111 | test_that("Net2-gui.rpt reads",{ 112 | 113 | Net2res <- read.rpt("Net2-gui.rpt") 114 | expect_true( is.null( Net2res$energyUsage) ) 115 | }) 116 | 117 | test_that("Net2.rpt and Net2-gui.rpt are equivalent",{ 118 | 119 | n2r <- read.rpt("Net2.rpt") 120 | n2rg <- read.rpt("Net2-gui.rpt") 121 | 122 | s <- summary(n2r) 123 | 124 | sg <- summary(n2rg) 125 | 126 | actual <- all.equal(s, sg) 127 | 128 | expected <-c("Component \"juncSummary\": Attributes: < Component \"dimnames\": Component 2: 1 string mismatch >", 129 | "Component \"tankSummary\": Attributes: < Component \"dimnames\": Component 2: 1 string mismatch >" ) 130 | 131 | expect_equal(length(actual), length(expected)) 132 | 133 | }) 134 | 135 | test_that("Net3.rpt reads",{ 136 | expect_warning(read.rpt("Net3.rpt"), "Node results not found") 137 | }) 138 | 139 | 140 | test_that("Net3-nodes.rpt has correct col names",{ 141 | 142 | n3nr <- read.rpt("Net3-nodes.rpt") 143 | node_result_names <- names(n3nr$nodeResults) 144 | expect_equal(node_result_names[1], "ID" ) 145 | expect_equal(node_result_names[2], "Demand" ) 146 | expect_equal(node_result_names[3], "Head" ) 147 | expect_equal(node_result_names[4], "Pressure" ) 148 | expect_equal(node_result_names[5], "Pct_from_Lake" ) 149 | 150 | }) 151 | test_that("Net3-gui.rpt reads",{ 152 | 153 | n3r <- read.rpt("Net3-gui.rpt") 154 | node_result_names <- names(n3r$nodeResults) 155 | expect_equal(node_result_names[1], "ID" ) 156 | expect_equal(node_result_names[2], "Demand" ) 157 | expect_equal(node_result_names[3], "Head" ) 158 | expect_equal(node_result_names[4], "Pressure" ) 159 | expect_equal(node_result_names[5], "Quality" ) 160 | 161 | expect_equal( dim(n3r$energyUsage)[1], 2) 162 | 163 | }) 164 | 165 | test_that("Net3.rpt and Net3-gui.rpt are equivalent",{ 166 | 167 | n3r <- read.rpt("Net3-nodes.rpt") 168 | n3rg <- read.rpt("Net3-gui.rpt") 169 | actual <- 170 | all.equal(n3r$nodeResults,n3rg$nodeResults) 171 | expected <- c( "Names: 1 string mismatch", 172 | "Component \"Timestamp\": 2425 string mismatches") 173 | expect_equal(length(actual),length( expected)) 174 | }) 175 | 176 | 177 | 178 | 179 | context("read.rpt error checking") 180 | 181 | 182 | test_that("missing node, link, and energy results gives error",{ 183 | 184 | expect_error( suppressWarnings( read.rpt("Net1-noResult.rpt") ) ) 185 | 186 | }) 187 | 188 | test_that("missing node and link results gives warning",{ 189 | expect_warning( read.rpt("Net1-noLinks-noNodes.rpt") ) 190 | 191 | }) 192 | 193 | test_that("missing node results gives warning",{ 194 | 195 | expect_warning( read.rpt("Net1-noNodes.rpt") , "Node results not found" ) 196 | 197 | }) 198 | 199 | test_that("missing link results gives warning",{ 200 | 201 | expect_warning( read.rpt("Net1-noLinks.rpt"), "Link results not found") 202 | 203 | }) 204 | 205 | 206 | 207 | context("summary.epanet.rpt s3 object") 208 | test_that("net1.rpt summary is ok", 209 | { 210 | n1res <- read.rpt( "Net1.rpt") 211 | n1rs <- summary(n1res) 212 | expect_output( print(n1rs), "25 time steps") 213 | expect_output( print(n1rs), "Median :\\s+113.08" ) 214 | expect_output( print(n1rs), "Max.\\s+:3.210" ) 215 | expect_output( print(n1rs), "usageFactor" ) 216 | }) 217 | 218 | test_that("Net2.rpt summary is ok",{ 219 | 220 | Net2res <- read.rpt("Net2.rpt") 221 | sn2r <- summary(Net2res) 222 | expect_output(print(sn2r), "Fluoride") 223 | expect_output(print(sn2r), "Mean\\s+:0.2767") 224 | 225 | 226 | }) 227 | 228 | 229 | test_that("Net3.rpt summary is ok",{ 230 | Net3res <- suppressWarnings( read.rpt("Net3.rpt") ) 231 | sn3 <- summary(Net3res) 232 | expect_output(print(sn3), "0 time steps") 233 | expect_output(print(sn3), "25 time steps") 234 | expect_output(print(sn3), "13205.64") 235 | }) 236 | 237 | 238 | context("plotting simulation results") 239 | 240 | test_that("plot args for Net1.rpt",{ 241 | 242 | Net1res <- read.rpt("Net1.rpt") 243 | inp <- suppressWarnings( read.inp("Net1.inp")) 244 | 245 | expect_error(plot(Net1res,inp,juncQty="junk"), "juncQty not present in nodeResults") 246 | expect_error(plot(Net1res,inp,linkQty="junk"), "linkQty not present in linkResults") 247 | expect_error(plot(Net1res,inp,juncQty=NA), "use NULL") 248 | expect_error(plot(Net1res,inp,linkQty=NA), "use NULL") 249 | 250 | plot(Net1res,inp) 251 | 252 | }) 253 | 254 | test_that("plot Net2.rpt",{ 255 | n2 <- suppressWarnings( read.inp("Net2.inp") ) 256 | n2r <- read.rpt("Net2.rpt") 257 | plot(n2r,n2) 258 | 259 | }) 260 | 261 | test_that("rpt plot w valves",{ 262 | 263 | v <- read.inp("oneprv.inp") 264 | vr <- read.rpt("oneprv.rpt") 265 | plot(vr,v) 266 | }) 267 | 268 | 269 | context("IDs are characters in rpt") 270 | 271 | test_that("node IDs are characters",{ 272 | 273 | # Net 1 274 | rpt <- read.rpt("Net1.rpt") 275 | expect_true( class(rpt$nodeResults$ID) == "character") 276 | 277 | # Net 2 278 | rpt <- read.rpt("Net2.rpt") 279 | expect_true( class(rpt$nodeResults$ID) == "character") 280 | 281 | 282 | }) 283 | 284 | test_that("link IDs are characters ",{ 285 | # Net 3 286 | rpt <- suppressWarnings(read.rpt("Net3.rpt")) 287 | expect_true( class(rpt$linkResults$ID) == "character") 288 | 289 | }) 290 | -------------------------------------------------------------------------------- /tests/testthat/test_epanetmsx.rpt-s3.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | context("epanetmsx.rpt object") 10 | test_that( "epanetmsx.rpt-s3 reads",{ 11 | 12 | mr <- epanetmsx.rpt( "example.rpt") 13 | expect_equal("epanetmsx.rpt", class(mr)) 14 | 15 | # check some specifics around results for link 5 16 | expect_equal("5", unique(mr$linkResults$ID)) 17 | expect_equal(0, min(mr$linkResults$timeInSeconds)) 18 | expect_equal(172800, max(mr$linkResults$timeInSeconds)) 19 | 20 | expect_true( is.epanetmsx.rpt( mr)) 21 | }) 22 | 23 | test_that( "timeInSeconds ",{ 24 | 25 | mr <- epanetmsx.rpt( "example.rpt") 26 | expect_equal("integer", class(mr$nodeResults$timeInSeconds)) 27 | }) 28 | 29 | test_that("no links",{ 30 | mr <- epanetmsx.rpt( "example-noLinks.rpt") 31 | mrs <- summary(mr) 32 | 33 | expect_equal( 0, mrs$numLinks) 34 | expect_true( is.null( mrs$uniqueLinkIDs)) 35 | expect_true( is.null( mrs$linkTimeRangeInSeconds)) 36 | expect_true( is.null( mrs$linkTimestep)) 37 | expect_true( is.null( mrs$linkResSmry)) 38 | }) 39 | 40 | 41 | test_that("no nodes",{ 42 | mr <- epanetmsx.rpt( "example-noNodes.rpt") 43 | mrs <- summary(mr) 44 | 45 | expect_equal( 0, mrs$numNodes) 46 | expect_true( is.null( mrs$uniqueNodeIDs)) 47 | expect_true( is.null( mrs$nodeTimeRangeInSeconds)) 48 | expect_true( is.null( mrs$nodeTimestep)) 49 | expect_true( is.null( mrs$nodeResSmry)) 50 | }) 51 | 52 | test_that(" no title works ",{ 53 | 54 | 55 | mr <- epanetmsx.rpt( "example-noTitle.rpt") 56 | mrs <- summary(mr) 57 | expect_true( is.null( mrs$Title)) 58 | }) 59 | 60 | test_that(" plot works" ,{ 61 | 62 | x <- epanetmsx.rpt( "example.rpt") 63 | expect_true( is.epanetmsx.rpt( x) ) 64 | plot(x) 65 | }) 66 | 67 | test_that("plot works for another case",{ 68 | x <- read.msxrpt("5deg.msxrpt") 69 | expect_true( is.epanetmsx.rpt( x) ) 70 | plot(x) 71 | }) 72 | -------------------------------------------------------------------------------- /tests/testthat/test_expandedLinkTable-s3.r: -------------------------------------------------------------------------------- 1 | #****************************************** 2 | # 3 | # (C) Copyright IBM Corp. 2014 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #****************************************** 8 | 9 | # File: test_expandedLinkTable-s3.r 10 | # By : bradley.eck@ie.ibm.com 11 | 12 | context("expandedlinkTable s3 object") 13 | test_that("expanedLinkTable works for Net1", 14 | { 15 | Net1 <- suppressWarnings(read.inp( "Net1.inp")) 16 | 17 | # pipes 18 | ept <- expandedLinkTable( Net1$Pipes, Net1$Coordinates) 19 | y2111 <- subset(ept, ID == '111', select = 'y2') 20 | expect_that(as.numeric(y2111), equals(40)) 21 | expect_true( is.expandedLinkTable( ept) ) 22 | 23 | # pumps 24 | ept <- expandedLinkTable( Net1$Pumps, Net1$Coordinates) 25 | expect_that(ept$x1[1], equals(10)) 26 | expect_true( is.expandedLinkTable( ept) ) 27 | 28 | # valves 29 | evt <- expandedLinkTable( Net1$Valvesves, Net1$Coordinates) 30 | expect_that(evt, equals(NA)) 31 | 32 | } 33 | ) 34 | 35 | test_that("expanedLinkTable handles correctly node ids", 36 | { 37 | Net4 <- suppressWarnings(read.inp( "Net4.inp")) 38 | 39 | # we expect that source INP contains valid coordinates for all junctions 40 | expect_false(any(is.na(Net4$Coordinates$X.coord))) 41 | expect_false(any(is.na(Net4$Coordinates$Y.coord))) 42 | 43 | ept <- expandedLinkTable(Net4$Pipes, Net4$Coordinates) 44 | expect_true( is.expandedLinkTable(ept) ) 45 | 46 | # assert valid coordinates in expandedLinkTable 47 | expect_false(any(is.na(ept$x1))) 48 | expect_false(any(is.na(ept$x2))) 49 | expect_false(any(is.na(ept$y1))) 50 | expect_false(any(is.na(ept$y2))) 51 | } 52 | ) -------------------------------------------------------------------------------- /tests/testthat/test_inpFuncs.r: -------------------------------------------------------------------------------- 1 | #****************************************** 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #****************************************** 8 | 9 | # File: inpFuncs_tests.r 10 | # Purpose: test reading of .inp files 11 | 12 | context("functions for inp parts") 13 | test_that("semi-colon at end of line is removed", 14 | { 15 | l <- .processCommentsAndClean(" 40 10 ;") 16 | expect_that(grepl(";",l), equals(FALSE)) 17 | }) 18 | 19 | 20 | test_that("Net1 JUNCTIONs table", 21 | { 22 | jt <- JUNCTIONS(readLines("Net1.inp")) 23 | expect_that(class(jt), equals("data.frame")) 24 | }) 25 | 26 | test_that("Net2 JUNCTIONS table", 27 | { 28 | jt <- JUNCTIONS(readLines("Net2.inp")) 29 | expect_true( jt$Pattern[1] == 2 ) 30 | }) 31 | 32 | 33 | 34 | test_that("IDs are character",{ 35 | 36 | # Net 1 37 | jt <- JUNCTIONS(readLines("Net1.inp")) 38 | expect_true( class(jt$ID) == "character") 39 | # Net 2 40 | jt <- JUNCTIONS(readLines("Net2.inp")) 41 | expect_true( class(jt$ID) == "character") 42 | }) 43 | 44 | 45 | test_that("Net3 RESERVOIRSs table", 46 | { 47 | res <- RESERVOIRS(readLines("Net3.inp")) 48 | expect_that(class(res), equals("data.frame")) 49 | expect_that(res$Pattern[1], equals(NA)) 50 | expect_true( class(res$ID) == "character") 51 | }) 52 | 53 | 54 | test_that("RESERVOIR table has patterns",{ 55 | 56 | res <- RESERVOIRS(c("[RESERVOIRS]"," R1 55.5 R1Pat", "[END]")) 57 | expect_that(names(res)[3], equals("Pattern")) 58 | }) 59 | 60 | test_that("Net3 TANKS table", 61 | { 62 | tt <- TANKS(readLines("Net3.inp")) 63 | expect_that(class(tt), equals("data.frame")) 64 | expect_that(dim(tt)[1], equals(3)) 65 | expect_that(tt$VolCurve[1], equals(NA)) 66 | }) 67 | 68 | 69 | test_that("Net3 PIPES table", 70 | { 71 | pip <- PIPES(readLines("Net3.inp")) 72 | expect_that(dim(pip)[1], equals(117)) 73 | }) 74 | 75 | test_that("pipes table missing status",{ 76 | pip <- PIPES(readLines("inp-pipe-table-some-statuses-empty.txt")) 77 | expect_equal( class(pip$Status), "factor") 78 | }) 79 | 80 | 81 | 82 | test_that("Net3 PUMPS table", 83 | { 84 | pmpt <- PUMPS(readLines("Net3.inp")) 85 | expect_that(dim(pmpt)[1], equals(2)) 86 | }) 87 | 88 | test_that("Net3 ENERGY table is ok ", 89 | { 90 | engy <-ENERGY(readLines("Net3.inp")) 91 | expect_that(length(engy),equals(3)) 92 | }) 93 | 94 | 95 | 96 | test_that("Net3 TIMES", 97 | { 98 | tms <- TIMES(readLines("Net3.inp")) 99 | expect_that(length(tms),equals(9)) 100 | }) 101 | 102 | test_that("Net3 OPTIONS", 103 | { 104 | opts <- OPTIONS(readLines("Net3.inp")) 105 | expect_that(class(opts),equals("list")) 106 | }) 107 | test_that("Net3 COORDINATES", 108 | { 109 | coord <- COORDINATES(readLines("Net3.inp")) 110 | expect_that(dim(coord)[1],equals(96)) 111 | }) 112 | 113 | test_that("two word options are picked up", 114 | { 115 | newList <- .listUpdater( list( a_b = 4 ), "a b 5") 116 | expect_that(newList[[1]], equals("5")) 117 | }) 118 | 119 | 120 | test_that("for options case doesn't matter", 121 | { 122 | newList <- .listUpdater( list( A_B = 4 ), "a b 5") 123 | expect_that(newList$A_B, equals("5")) 124 | }) 125 | 126 | 127 | test_that(" patterns work", 128 | { 129 | pats <- suppressWarnings( PATTERNS(readLines("Net3.inp")) ) 130 | expect_that(length(pats),equals(5)) 131 | expect_that(pats$`1`[16],equals(.83)) 132 | expect_warning(PATTERNS(readLines("Net3.inp"))) 133 | }) 134 | 135 | test_that("curves work", 136 | { 137 | crvs <- suppressWarnings( CURVES(readLines("Net3.inp")) ) 138 | expect_that(length(crvs),equals(2)) 139 | expect_warning( CURVES(readLines("Net3.inp")) ) 140 | }) 141 | 142 | test_that("some pattern entries in junc table can be missing", 143 | { 144 | junc <- JUNCTIONS(readLines("Net2.inp")) 145 | }) 146 | 147 | 148 | test_that("title reads correctly", 149 | { 150 | titl <- TITLE( readLines("Net1.inp")) 151 | expect_that( titl[1], equals("EPANET Example Network 1")) 152 | }) 153 | 154 | 155 | test_that("[STATUS] reads ok" ,{ 156 | 157 | stat <- STATUS( readLines("Net3.inp")) 158 | expect_that( stat[1,1], equals('10') ) 159 | expect_true( stat[1,2] =="Closed") 160 | 161 | 162 | }) 163 | 164 | test_that("[DEMANDS] reads ok",{ 165 | 166 | dmd <- DEMANDS( readLines("oneprv.inp")) 167 | expect_that( dmd[1,2], equals(1.1) ) 168 | expect_that( dim(dmd)[1], equals(3)) 169 | 170 | }) 171 | 172 | test_that("[CONTROLS] reads ok",{ 173 | ctrl <- CONTROLS( readLines("Net1.inp")) 174 | expect_equal( length(ctrl), 2) 175 | }) 176 | 177 | test_that("[EMITTERS] reads ok",{ 178 | 179 | emit <- EMITTERS( readLines("for-various-tests.inp")) 180 | expect_equal( dim(emit)[1], 2) 181 | expect_equal( class(emit), "data.frame") 182 | }) 183 | test_that("[QUALITY] reads ok",{ 184 | 185 | qlty <- QUALITY( readLines("Net1.inp")) 186 | expect_equal( dim(qlty)[1], 11) 187 | expect_equal( class(qlty), "data.frame") 188 | }) 189 | 190 | test_that("[SOURCES] reads ok",{ 191 | x <- SOURCES( readLines("for-various-tests.inp")) 192 | expect_equal( class(x), "data.frame") 193 | expect_equal( as.character(x$Pattern[1]), "Pat1") 194 | }) 195 | 196 | test_that("[REACTIONS] reads ok",{ 197 | x <- REACTIONS( readLines("for-various-tests.inp")) 198 | expect_equal( class(x), "character") 199 | expect_equal( length(x) , 5) 200 | }) 201 | test_that("[MIXING] reads ok",{ 202 | x <- MIXING( readLines("for-various-tests.inp")) 203 | expect_equal( class(x), "data.frame") 204 | expect_equal( dim(x)[1] , 2) 205 | }) 206 | test_that("[REPORT] reads ok",{ 207 | x <- REPORT( readLines("Net1.inp")) 208 | expect_equal( class(x), "character") 209 | expect_equal( length(x) , 6) 210 | }) 211 | 212 | test_that("[LABELS] reads as data frame",{ 213 | x <- LABELS(readLines("Net1.inp")) 214 | expect_equal( class(x), "data.frame") 215 | expect_equal(x$X.coord[3], 43.85) 216 | expect_equal(x$Y.coord[3], 91.21) 217 | expect_equal( x$Label[3], "Tank") 218 | expect_true( is.na(x$Anchor[3])) 219 | 220 | }) 221 | 222 | context("missing inp tables are null") 223 | test_that("Net1 valves table is missing", 224 | { 225 | vlv <- VALVES(readLines("Net1.inp")) 226 | expect_that(vlv, equals(NULL)) 227 | }) 228 | 229 | test_that("Net2.inp has no reservoirs",{ 230 | 231 | resr <- RESERVOIRS(readLines("Net2.inp")) 232 | expect_that(resr, equals(NULL)) 233 | }) 234 | 235 | test_that("Net2.inp has no pumps",{ 236 | pmp <- PUMPS(readLines("Net2.inp")) 237 | expect_that(pmp, equals(NULL)) 238 | }) 239 | 240 | 241 | test_that("TITLE is null",{ 242 | t <- TITLE(readLines("empty.inp")) 243 | expect_that(t, equals(NULL)) 244 | }) 245 | 246 | test_that("JUNCTIONS is null",{ 247 | s <- JUNCTIONS(readLines("empty.inp")) 248 | expect_that(s, equals(NULL)) 249 | }) 250 | test_that("TANKS is null",{ 251 | s <- TANKS(readLines("empty.inp")) 252 | expect_that(s, equals(NULL)) 253 | }) 254 | 255 | test_that("RESERVOIRS is null",{ 256 | s <- RESERVOIRS(readLines("empty.inp")) 257 | expect_that(s, equals(NULL)) 258 | }) 259 | test_that("PIPES is null",{ 260 | s <- PIPES(readLines("empty.inp")) 261 | expect_that(s, equals(NULL)) 262 | }) 263 | 264 | test_that("PUMPS is null",{ 265 | s <- PUMPS(readLines("empty.inp")) 266 | expect_that(s, equals(NULL)) 267 | }) 268 | test_that("VALVES is null",{ 269 | s <- VALVES(readLines("empty.inp")) 270 | expect_that(s, equals(NULL)) 271 | }) 272 | 273 | test_that("DEMANDS is null",{ 274 | s <- DEMANDS(readLines("empty.inp")) 275 | expect_that(s, equals(NULL)) 276 | }) 277 | 278 | test_that("PATTERNS is null",{ 279 | s <- PATTERNS(readLines("empty.inp")) 280 | expect_that(s, equals(NULL)) 281 | }) 282 | 283 | test_that("CURVES is null",{ 284 | s <- CURVES(readLines("empty.inp")) 285 | expect_that(s, equals(NULL)) 286 | }) 287 | 288 | test_that("CONTROLS is null",{ 289 | s <- CONTROLS(readLines("empty.inp")) 290 | expect_that(s, equals(NULL)) 291 | }) 292 | 293 | test_that("ENERGY is null",{ 294 | t <- ENERGY(readLines("empty.inp")) 295 | expect_that(t, equals(NULL)) 296 | }) 297 | 298 | test_that("ENERGY is null",{ 299 | t <- ENERGY(readLines("empty.inp")) 300 | expect_that(t, equals(NULL)) 301 | }) 302 | 303 | test_that("TIMES is null",{ 304 | t <- TIMES(readLines("empty.inp")) 305 | expect_that(t, equals(NULL)) 306 | }) 307 | 308 | test_that("COORDINATES is null",{ 309 | t <- COORDINATES(readLines("empty.inp")) 310 | expect_that(t, equals(NULL)) 311 | }) 312 | 313 | test_that("EMITTERS is null",{ 314 | t <- EMITTERS(readLines("empty.inp")) 315 | expect_that(t, equals(NULL)) 316 | }) 317 | 318 | 319 | test_that("missing OPTIONS give default options",{ 320 | t <- OPTIONS( readLines("empty.inp")) 321 | expect_equal(t, epanetDefaultOptions() ) 322 | }) 323 | 324 | context("IDs in inp sections are character") 325 | 326 | test_that(" junction IDs are char",{ 327 | 328 | junc <- JUNCTIONS(readLines("Net1.inp")) 329 | expect_true( class(junc$ID) == "character") 330 | }) 331 | 332 | context("some non-ID columns in inp sections are factors") 333 | test_that("[Junctions] Pattern is factor",{ 334 | 335 | junc <- JUNCTIONS(readLines("Net2.inp")) 336 | expect_true( class(junc$Pattern) == 'factor') 337 | }) 338 | 339 | test_that("[Tanks] Curve ID is factor",{ 340 | 341 | tank <- TANKS(readLines("for-various-tests.inp")) 342 | expect_true( class(tank$VolCurve) == 'factor') 343 | 344 | }) 345 | 346 | test_that("[Reservoirs] Pattern is factor",{ 347 | 348 | res <- RESERVOIRS(readLines("for-various-tests.inp")) 349 | expect_true( class(res$Pattern) == 'factor') 350 | }) 351 | 352 | test_that("[Pipes] status is factor",{ 353 | 354 | pipe <- PIPES(readLines("Net3.inp")) 355 | expect_true(class(pipe$Status) == 'factor') 356 | }) 357 | 358 | test_that("[Pumps] keyword is factor",{ 359 | 360 | pmp <- PUMPS(readLines("Net3.inp")) 361 | expect_true(class(pmp$Parameters) == 'factor') 362 | }) 363 | 364 | test_that("[Valves] type is factor",{ 365 | 366 | vlv <- VALVES(readLines("oneprv.inp")) 367 | expect_true(class(vlv$Type) == 'factor') 368 | }) 369 | 370 | test_that("[Status] Status is factor",{ 371 | 372 | stat <- STATUS(readLines("Net3.inp")) 373 | expect_true(class(stat$Status) == 'factor') 374 | }) 375 | 376 | test_that("[Demands] Pattern is factor",{ 377 | 378 | dmd <- DEMANDS(readLines("oneprv.inp")) 379 | expect_true(class(dmd$Pattern) == 'factor') 380 | 381 | }) 382 | 383 | 384 | context("inp helper funcs") 385 | test_that( ".lineRange returns same for missing and duplicate sections",{ 386 | 387 | allLines <- c("[JUNCTIONS]", 388 | "A 1 2 ", 389 | "[REACTIONS]", 390 | "some param", 391 | "[REACTIONS]", 392 | "another param", 393 | "[END]") 394 | 395 | p <- .lineRange("\\[PIPES\\]", allLines) 396 | 397 | expect_warning( r <- .lineRange("\\[REACTIONS\\]", allLines)) 398 | 399 | ok <- all.equal(p,r) 400 | 401 | expect_true( ok ) 402 | 403 | }) 404 | -------------------------------------------------------------------------------- /tests/testthat/test_msxFuncs.r: -------------------------------------------------------------------------------- 1 | #****************************************** 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #****************************************** 8 | 9 | 10 | context("msx funcs") 11 | test_that( "getID func works",{ 12 | 13 | marker1 <- "<<< Node 1 >>>" 14 | expect_equal("1", getID(marker1)) 15 | 16 | marker2<- "<<< Node D >>>" 17 | expect_equal("D", getID(marker2)) 18 | 19 | }) 20 | 21 | 22 | test_that("msxSection2df",{ 23 | 24 | 25 | sect <-c( 26 | " <<< Node D >>> ", 27 | " ", 28 | " Time AS5 AStot NH2CL ", 29 | " hr:min UG/L UG/L MG/L ", 30 | " ------- ---------- ---------- ---------- ", 31 | " 0:00 0.00 0.00 0.00 ", 32 | " 2:00 0.00 0.00 0.00 ", 33 | " 4:00 0.00 0.00 0.00 ", 34 | " 6:00 0.00 0.00 0.00 ", 35 | " 8:00 0.00 0.00 0.00 ", 36 | " 10:00 0.00 0.00 0.00 " ) 37 | 38 | 39 | df <- msxSection2df( sect ) 40 | 41 | expect_equal("data.frame", class(df) ) 42 | 43 | expect_equal("integer", class(df$timeInSeconds)) 44 | expect_equal("ID", names(df)[1]) 45 | }) 46 | 47 | 48 | test_that("getTitle",{ 49 | 50 | 51 | t <- getTitle( readLines("example.rpt")) 52 | actual <- grepl("Arsenic Oxidation/Adsorption Example", t) 53 | expect_true(actual) 54 | 55 | }) 56 | 57 | test_that(" no title is null",{ 58 | 59 | t <- getTitle( readLines("example-noTitle.rpt")) 60 | expect_true(is.null(t)) 61 | 62 | }) 63 | -------------------------------------------------------------------------------- /tests/testthat/test_plotSparklineTable.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | 10 | context("Plot Sparkline Table") 11 | 12 | test_that("msx example is ok",{ 13 | 14 | mr <- read.msxrpt("example.rpt") 15 | #windows() 16 | plotSparklineTable( mr$nodeResults, row.var = 'ID', col.vars = c("AS5", "AStot", "NH2CL")) 17 | 18 | }) 19 | 20 | test_that("5deg example is ok",{ 21 | mr <- read.msxrpt("5deg.msxrpt") 22 | 23 | 24 | plotSparklineTable( mr$nodeResults, row.var = 'ID', col.vars = names(mr$nodeResults)[3:7], ) 25 | 26 | }) 27 | 28 | test_that("datasets::Orange",{ 29 | plotSparklineTable( Orange, row.var = 'Tree', col.vars = c('age','circumference')) 30 | plotSparklineTable( Orange, row.var = 'Tree', col.vars = 'circumference', xvar = 'age' ) 31 | }) 32 | 33 | test_that("datasets::CO2",{ 34 | 35 | plotSparklineTable( CO2, row.var = 'Plant', col.vars = c('conc', 'uptake')) 36 | }) 37 | test_that("datasets::Loglolly",{ 38 | 39 | plotSparklineTable( Loblolly, row.var = 'Seed', col.vars = 'height', xvar = 'age') 40 | 41 | }) 42 | 43 | test_that("datasets::Theoph",{ 44 | 45 | plotSparklineTable( Theoph, 'Subject', 'conc') 46 | 47 | expect_warning( plotSparklineTable( Theoph, 'Subject', 'conc', xvar = 'Time') ) 48 | }) 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /tests/testthat/test_rptFuncs.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | # File: test_rptFuncs.r 10 | # 11 | 12 | context("test helper functions used with rpt ") 13 | 14 | test_that("testing binBreaker",{ 15 | vals1 <- c(-1,0,1,2,3,4,5) 16 | v1bb <- binBreaker(vals1, 4) 17 | expect_true( v1bb$Breaks[1] < min(vals1), "first break point is less than min value") 18 | 19 | expect_equal( (substr(v1bb$Labels[1], 2,3)), as.character(min(vals1)), "lower range of first bin is sample min") 20 | 21 | expect_equal( ( substr( v1bb$Labels[4], 6,6)) , 22 | as.character(max(vals1)), 23 | "upper end of last bin is sample max") 24 | 25 | vals2 <- c(0,1.1, 2.2, 3.3, NA, 2, 3, 4, 5, 6.6) 26 | expect_true ( class(binBreaker(vals2, 3)) == "list", "function returns even with NA inpus ") 27 | 28 | }) 29 | 30 | 31 | test_that("two line heading for ID works",{ 32 | 33 | #some sample input 34 | aFewLines <- c( 35 | "Node Results at 0:00 Hrs: ", 36 | " ---------------------------------------------------------------------- ", 37 | " Node Demand Head Pressure Quality ", 38 | " ID GPM ft psi mg/L ", 39 | " ---------------------------------------------------------------------- ", 40 | " 10 0.00 1004.35 127.54 0.50 ", 41 | " 11 150.00 985.23 119.26 0.50 ", 42 | " 12 150.00 970.07 117.02 0.50 ", 43 | " 13 100.00 968.87 118.67 0.50 ", 44 | " 21 150.00 971.55 117.66 0.50 ", 45 | " 22 200.00 969.08 118.76 0.50 " ) 46 | 47 | df <- .section2df(aFewLines) 48 | 49 | expect_equal( names(df)[1], expected = "ID") 50 | expect_equal( names(df)[5], expected = "Quality") 51 | 52 | }) 53 | 54 | 55 | test_that("one line heading for ID works",{ 56 | 57 | #some sample input 58 | aFewLines <- c( 59 | "Node Results at 0:00:00 hrs: ", 60 | " -------------------------------------------------------- ", 61 | " Demand Head Pressure Chlorine ", 62 | " Node gpm ft psi mg/L ", 63 | " -------------------------------------------------------- ", 64 | " 10 0.00 1004.35 127.54 0.50 ", 65 | " 11 150.00 985.23 119.26 0.50 ", 66 | " 12 150.00 970.07 117.02 0.50 ", 67 | " 13 100.00 968.87 118.67 0.50 ", 68 | " 21 150.00 971.55 117.66 0.50 ", 69 | " 22 200.00 969.08 118.76 0.50 " ) 70 | 71 | df <- .section2df(aFewLines) 72 | 73 | expect_equal( names(df)[1], expected = "ID") 74 | expect_equal( names(df)[5], expected = "Chlorine") 75 | 76 | }) 77 | 78 | 79 | test_that(" pct sign in heading",{ 80 | #some sample input 81 | aFewLines <- c( 82 | " Node Results at 0:00:00 hrs: ", 83 | " --------------------------------------------------------", 84 | " Demand Head Pressure % from ", 85 | " Node gpm ft psi Lake ", 86 | " --------------------------------------------------------", 87 | " 10 0.00 145.52 -0.64 0.00 ", 88 | " 15 620.00 125.81 40.65 0.00 ", 89 | " 20 0.00 158.00 12.57 0.00 ", 90 | " 35 1637.00 145.74 57.73 0.00 ") 91 | 92 | df <- .section2df(aFewLines) 93 | 94 | expect_equal( names(df)[1] , "ID") 95 | expect_equal( names(df)[5] , "Pct_from_Lake") 96 | 97 | }) 98 | 99 | 100 | 101 | test_that("IDs are characters",{ 102 | 103 | ## Manually input due to complexity of reading and breaking into sections 104 | aFewLines <- c( 105 | "Node Results at 0:00:00 hrs: ", 106 | " -------------------------------------------------------- ", 107 | " Demand Head Pressure Chlorine ", 108 | " Node gpm ft psi mg/L ", 109 | " -------------------------------------------------------- ", 110 | " 10 0.00 1004.35 127.54 0.50 ", 111 | " 11 150.00 985.23 119.26 0.50 ", 112 | " 12 150.00 970.07 117.02 0.50 ", 113 | " 13 100.00 968.87 118.67 0.50 ", 114 | " 21 150.00 971.55 117.66 0.50 ", 115 | " 22 200.00 969.08 118.76 0.50 " ) 116 | 117 | df <- .section2df(aFewLines) 118 | 119 | expect_true(class(df$ID) == "character") 120 | }) 121 | 122 | test_that(" gui rpt file cleaner",{ 123 | 124 | 125 | allLines <- readLines("Net1-gui.rpt") 126 | cleanLines <- cleanRptLines(allLines) 127 | expect_equal(class(cleanLines), "character") 128 | x <- length(allLines) - 19 - 20 - 35 129 | expect_equal(length(cleanLines), x) 130 | }) 131 | 132 | test_that(" gui rpt file cleaner on a clean file",{ 133 | 134 | 135 | allLines <- readLines("Net1.rpt") 136 | cleanLines <- cleanRptLines(allLines) 137 | expect_equal(class(cleanLines), "character") 138 | x <- length(allLines) -1 139 | expect_equal(length(cleanLines), x) 140 | }) 141 | 142 | 143 | 144 | test_that("energy usage table exists",{ 145 | 146 | allLines <- readLines("Net1.rpt") 147 | cleanLines <- cleanRptLines(allLines) 148 | df <- getEnergyUsage( cleanLines) 149 | expect_true( is.data.frame(df)) 150 | expect_true( grepl( "Mgal", names(df))[4]) 151 | 152 | }) 153 | 154 | test_that("energy usage table doesn't exist returns NULL",{ 155 | 156 | allLines <- readLines("Net2-gui.rpt") 157 | cleanLines <- cleanRptLines(allLines) 158 | df <- getEnergyUsage( cleanLines) 159 | expect_true( is.null(df)) 160 | 161 | }) 162 | 163 | context("converting timestamps to seconds") 164 | 165 | test_that(" two colons parse to HH:MM:SS",{ 166 | 167 | ts <- " 2:30:44" 168 | x <- 2*3600+30*60+44 169 | a<- .timeStampToSeconds(ts) 170 | 171 | expect_equal( x, a) 172 | }) 173 | 174 | 175 | test_that(" 0:00 parses as HH:MM",{ 176 | 177 | ts <- " 2:30" 178 | x <- 2*3600+30*60 179 | a <- .timeStampToSeconds(ts) 180 | 181 | expect_equal( x, a) 182 | }) 183 | 184 | test_that( " Node Results at 2:00 Hrs:",{ 185 | 186 | tsl <- " Node Results at 2:00 Hrs:" 187 | a <- .getTimeStamp(tsl) 188 | expect_equal( "2:00", a) 189 | 190 | }) 191 | 192 | test_that(" 00:00:00:00 gives error",{ 193 | 194 | ts <- " 2:30:11:22" 195 | expect_error( .timeStampToSeconds(ts) ) 196 | }) 197 | 198 | test_that(" 00 gives error",{ 199 | 200 | ts <- " 22" 201 | expect_error( .timeStampToSeconds(ts) ) 202 | }) 203 | 204 | test_that(" returns integer",{ 205 | 206 | ts <- " 2:33" 207 | x <- .timeStampToSeconds(ts) 208 | expect_equal('integer', class(x)) 209 | 210 | }) 211 | -------------------------------------------------------------------------------- /tests/testthat/test_sparkline-s3.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | context("sparkline-s3") 10 | 11 | test_that("sparkline construction",{ 12 | 13 | df = Theoph 14 | id.var = 'Subject' 15 | ID = '1' 16 | yvar = 'conc' 17 | xvar = NULL 18 | 19 | M <- sparkline( Theoph, 'Subject', 1, 'conc', xvar = NULL) 20 | expect_equal(M[1,1], 1, check.names = FALSE) 21 | expect_equal(class(M), 'sparkline') 22 | expect_true(is.sparkline(M)) 23 | 24 | M <- sparkline( Theoph, 'Subject', 1, 'conc', xvar = 'Time') 25 | expect_equal(M[1,1], 0) 26 | expect_equal(class(M), 'sparkline') 27 | expect_true(is.sparkline(M)) 28 | 29 | }) 30 | 31 | test_that("sparkline plotting",{ 32 | 33 | 34 | 35 | xy <- sparkline( Theoph, 'Subject', 1, 'conc', xvar = 'Time') 36 | expect_true(is.sparkline(xy)) 37 | plot(xy ) 38 | 39 | }) 40 | -------------------------------------------------------------------------------- /tests/testthat/test_sparklineTable-s3.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2015 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | 10 | context("sparklineTable-s3") 11 | 12 | test_that("argument checking works",{ 13 | 14 | expect_error( sparklineTable( 1:3, "id", c("p1", "p2") ), "df must be a data.frame" ) 15 | 16 | df <- data.frame( ID = c(1,1,1,2,2,2), Param1 = c(1,2,3,4,5,6), Param2 = c(6,5,4,3,2,1)) 17 | row.var = 'ID' 18 | col.vars = c("Param1","Param2") 19 | 20 | expect_error( sparklineTable(df, "node", c("Param1", "Param2")), "node is not a column" ) 21 | expect_error( sparklineTable(df, "ID", c("Param1", "Param3")), "is not a column" ) 22 | 23 | 24 | slt <- sparklineTable( df, 'ID', c('Param1', 'Param2')) 25 | expect_true( is.sparklineTable( slt)) 26 | }) 27 | 28 | 29 | 30 | test_that("xvar warning",{ 31 | 32 | m1 <- matrix( rnorm(4), 2,2,) 33 | m2 <- matrix( rnorm(4), 2,2,) 34 | 35 | slt <- list( m1, m2) 36 | 37 | expect_warning( sparklineDataCheck( slt )) 38 | 39 | }) 40 | 41 | 42 | test_that('plotting works',{ 43 | 44 | 45 | slt <- sparklineTable( Loblolly, row.var = 'Seed', col.vars = 'height', xvar = 'age') 46 | expect_true( is.sparklineTable( slt) ) 47 | plot(slt) 48 | 49 | 50 | 51 | }) 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /tests/testthat/test_text_file_reader.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2016 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | context("text file reader") 10 | 11 | test_that("same result as readLines",{ 12 | 13 | x <- "Net1.inp" 14 | rl <- readLines(x) 15 | rlw <- read_lines_wrapper(x) 16 | pass <- identical( rl, rlw) 17 | expect_true(pass) 18 | }) 19 | 20 | test_that(" Net2.rpt same result as readLines",{ 21 | 22 | x <- "Net2.rpt" 23 | rl <- readLines( x) 24 | rlw <- read_lines_wrapper(x) 25 | pass <- identical( rl, rlw) 26 | expect_true(pass) 27 | }) 28 | -------------------------------------------------------------------------------- /tests/testthat/test_write-pkg-data.r: -------------------------------------------------------------------------------- 1 | context("write the data that ships with the package") 2 | test_that("Net1",{ 3 | 4 | Net1 <- suppressWarnings( read.inp("Net1.inp")) 5 | 6 | expect_true( is.epanet.inp(Net1)) 7 | save(Net1, file="Net1.rdata") 8 | 9 | }) 10 | 11 | test_that("Net1rpt",{ 12 | 13 | Net1rpt <- suppressWarnings( read.rpt("Net1.rpt")) 14 | 15 | expect_true( is.epanet.rpt(Net1rpt)) 16 | save(Net1rpt, file="Net1rpt.rdata") 17 | 18 | }) -------------------------------------------------------------------------------- /tests/testthat/test_write.inp.r: -------------------------------------------------------------------------------- 1 | #************************************ 2 | # 3 | # (C) Copyright IBM Corp. 2016 4 | # 5 | # Author: Bradley J Eck 6 | # 7 | #************************************ 8 | 9 | 10 | context("write.inp") 11 | 12 | test_that("class check works",{ 13 | expect_error( write.inp(mtcars), file = "mtcars" ) 14 | 15 | }) 16 | 17 | 18 | test_that("Net1 writes",{ 19 | 20 | NET1 <- suppressWarnings(read.inp("Net1.inp" )) 21 | 22 | write.inp(NET1, file = "writeNet1.inp") 23 | n1 <- suppressWarnings( read.inp("writeNet1.inp") ) 24 | 25 | expect_true( identical( NET1$Junctions, n1$Junctions) ) 26 | expect_true( all.equal(NET1, n1) ) 27 | 28 | }) 29 | 30 | test_that("Net 2", { 31 | 32 | NET2 <- suppressWarnings( read.inp("Net2.inp")) 33 | write.inp(NET2, "writeNet2.inp") 34 | n2 <- suppressWarnings( read.inp( "writeNet2.inp")) 35 | expect_true(all.equal(NET2, n2) ) 36 | }) 37 | 38 | test_that("Net 3", { 39 | 40 | NET3 <- suppressWarnings( read.inp("Net3.inp")) 41 | write.inp(NET3, "writeNet3.inp") 42 | n3 <- suppressWarnings( read.inp( "writeNet3.inp") ) 43 | expect_true(all.equal(NET3, n3) ) 44 | }) 45 | 46 | 47 | test_that("oneprv",{ 48 | op <- read.inp("oneprv.inp") 49 | write.inp(op, "writeOneprv.inp") 50 | xx <- read.inp("writeOneprv.inp") 51 | expect_true( all.equal(op, xx) ) 52 | }) 53 | -------------------------------------------------------------------------------- /tests/testthat/writeNet1.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | EPANET Example Network 1 3 | A simple example of modeling chlorine decay. Both bulk and 4 | wall reactions are included. 5 | 6 | [JUNCTIONS] 7 | 10 710 0 8 | 11 710 150 9 | 12 700 150 10 | 13 695 100 11 | 21 700 150 12 | 22 695 200 13 | 23 690 150 14 | 31 700 100 15 | 32 710 100 16 | 17 | [TANKS] 18 | 2 850 120 100 150 50.5 0 19 | 20 | [RESERVOIRS] 21 | 9 800 22 | 23 | [PIPES] 24 | 10 10 11 10530 18 100 0 Open 25 | 11 11 12 5280 14 100 0 Open 26 | 12 12 13 5280 10 100 0 Open 27 | 21 21 22 5280 10 100 0 Open 28 | 22 22 23 5280 12 100 0 Open 29 | 31 31 32 5280 6 100 0 Open 30 | 110 2 12 200 18 100 0 Open 31 | 111 11 21 5280 10 100 0 Open 32 | 112 12 22 5280 12 100 0 Open 33 | 113 13 23 5280 8 100 0 Open 34 | 121 21 31 5280 8 100 0 Open 35 | 122 22 32 5280 6 100 0 Open 36 | 37 | [PUMPS] 38 | 9 9 10 HEAD 1 39 | 40 | [VALVES] 41 | 42 | [DEMANDS] 43 | 44 | [PATTERNS] 45 | 1 1 46 | 1 1.2 47 | 1 1.4 48 | 1 1.6 49 | 1 1.4 50 | 1 1.2 51 | 1 1 52 | 1 0.8 53 | 1 0.6 54 | 1 0.4 55 | 1 0.6 56 | 1 0.8 57 | 58 | [CURVES] 59 | 1 1500 250 60 | 61 | [CONTROLS] 62 | LINK 9 OPEN IF NODE 2 BELOW 110 63 | LINK 9 CLOSED IF NODE 2 ABOVE 140 64 | 65 | [RULES] 66 | 67 | [ENERGY] 68 | Global Efficiency 75 69 | Global Price 0.0 70 | Demand Charge 0.0 71 | 72 | [STATUS] 73 | 74 | [EMITTERS] 75 | 76 | [QUALITY] 77 | 10 0.5 78 | 11 0.5 79 | 12 0.5 80 | 13 0.5 81 | 21 0.5 82 | 22 0.5 83 | 23 0.5 84 | 31 0.5 85 | 32 0.5 86 | 9 1 87 | 2 1 88 | 89 | [SOURCES] 90 | 91 | [REACTIONS] 92 | Order Bulk 1 93 | Order Tank 1 94 | Order Wall 1 95 | Global Bulk -.5 96 | Global Wall -1 97 | Limiting Potential 0.0 98 | Roughness Correlation 0.0 99 | 100 | [MIXING] 101 | 102 | [TIMES] 103 | Duration 24:00 104 | Hydraulic Timestep 1:00 105 | Quality Timestep 0:05 106 | Pattern Timestep 2:00 107 | Pattern Start 0:00 108 | Report Timestep 1:00 109 | Report Start 0:00 110 | Start ClockTime 12 am 111 | Statistic None 112 | 113 | [REPORT] 114 | Status Yes 115 | Summary No 116 | Page 0 117 | Links All 118 | Nodes All 119 | Energy Yes 120 | 121 | [OPTIONS] 122 | UNITS GPM 123 | HEADLOSS H-W 124 | QUALITY NONE 125 | VISCOSITY 1.0 126 | DIFFUSIVITY 1.0 127 | SPECIFIC GRAVITY 1.0 128 | TRIALS 40 129 | ACCURACY 0.001 130 | UNBALANCED STOP 131 | PATTERN 1 132 | DEMAND MULTIPLIER 1.0 133 | EMITTER EXPONENT 0.5 134 | TOLERANCE 0.01 135 | 136 | [COORDINATES] 137 | 10 20 70 138 | 11 30 70 139 | 12 50 70 140 | 13 70 70 141 | 21 30 40 142 | 22 50 40 143 | 23 70 40 144 | 31 30 10 145 | 32 50 10 146 | 9 10 70 147 | 2 50 90 148 | 149 | [VERTICES] 150 | 151 | [LABELS] 152 | 6.99 73.63 Source 153 | 13.48 68.13 Pump 154 | 43.85 91.21 Tank 155 | 156 | [BACKDROP] 157 | DIMENSIONS 7.00 6.00 73.00 94.00 158 | UNITS None 159 | FILE 160 | OFFSET 0.00 0.00 161 | 162 | [TAGS] 163 | 164 | [END] 165 | -------------------------------------------------------------------------------- /tests/testthat/writeNet2.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | EPANET Example Network 2 3 | Example of modeling a 55-hour fluoride tracer study. 4 | Measured fluoride data is contained in the file Net2-FL.dat 5 | and should be registered with the project to produce a 6 | Calibration Report (select Calibration Data from the Project 7 | menu). 8 | 9 | [JUNCTIONS] 10 | 1 50 -694.4 2 11 | 2 100 8 12 | 3 60 14 13 | 4 60 8 14 | 5 100 8 15 | 6 125 5 16 | 7 160 4 17 | 8 110 9 18 | 9 180 14 19 | 10 130 5 20 | 11 185 34.78 21 | 12 210 16 22 | 13 210 2 23 | 14 200 2 24 | 15 190 2 25 | 16 150 20 26 | 17 180 20 27 | 18 100 20 28 | 19 150 5 29 | 20 170 19 30 | 21 150 16 31 | 22 200 10 32 | 23 230 8 33 | 24 190 11 34 | 25 230 6 35 | 27 130 8 36 | 28 110 0 37 | 29 110 7 38 | 30 130 3 39 | 31 190 17 40 | 32 110 17 41 | 33 180 1.5 42 | 34 190 1.5 43 | 35 110 0 44 | 36 110 1 45 | 46 | [TANKS] 47 | 26 235 56.7 50 70 50 0 48 | 49 | [RESERVOIRS] 50 | 51 | [PIPES] 52 | 1 1 2 2400 12 100 0 Open 53 | 2 2 5 800 12 100 0 Open 54 | 3 2 3 1300 8 100 0 Open 55 | 4 3 4 1200 8 100 0 Open 56 | 5 4 5 1000 12 100 0 Open 57 | 6 5 6 1200 12 100 0 Open 58 | 7 6 7 2700 12 100 0 Open 59 | 8 7 8 1200 12 140 0 Open 60 | 9 7 9 400 12 100 0 Open 61 | 10 8 10 1000 8 140 0 Open 62 | 11 9 11 700 12 100 0 Open 63 | 12 11 12 1900 12 100 0 Open 64 | 13 12 13 600 12 100 0 Open 65 | 14 13 14 400 12 100 0 Open 66 | 15 14 15 300 12 100 0 Open 67 | 16 13 16 1500 8 100 0 Open 68 | 17 15 17 1500 8 100 0 Open 69 | 18 16 17 600 8 100 0 Open 70 | 19 17 18 700 12 100 0 Open 71 | 20 18 32 350 12 100 0 Open 72 | 21 16 19 1400 8 100 0 Open 73 | 22 14 20 1100 12 100 0 Open 74 | 23 20 21 1300 8 100 0 Open 75 | 24 21 22 1300 8 100 0 Open 76 | 25 20 22 1300 8 100 0 Open 77 | 26 24 23 600 12 100 0 Open 78 | 27 15 24 250 12 100 0 Open 79 | 28 23 25 300 12 100 0 Open 80 | 29 25 26 200 12 100 0 Open 81 | 30 25 31 600 12 100 0 Open 82 | 31 31 27 400 8 100 0 Open 83 | 32 27 29 400 8 100 0 Open 84 | 34 29 28 700 8 100 0 Open 85 | 35 22 33 1000 8 100 0 Open 86 | 36 33 34 400 8 100 0 Open 87 | 37 32 19 500 8 100 0 Open 88 | 38 29 35 500 8 100 0 Open 89 | 39 35 30 1000 8 100 0 Open 90 | 40 28 35 700 8 100 0 Open 91 | 41 28 36 300 8 100 0 Open 92 | 93 | [PUMPS] 94 | 95 | [VALVES] 96 | 97 | [DEMANDS] 98 | 99 | [PATTERNS] 100 | 1 1.26 101 | 1 1.04 102 | 1 0.97 103 | 1 0.97 104 | 1 0.89 105 | 1 1.19 106 | 1 1.28 107 | 1 0.67 108 | 1 0.67 109 | 1 1.34 110 | 1 2.46 111 | 1 0.97 112 | 1 0.92 113 | 1 0.68 114 | 1 1.43 115 | 1 0.61 116 | 1 0.31 117 | 1 0.78 118 | 1 0.37 119 | 1 0.67 120 | 1 1.26 121 | 1 1.56 122 | 1 1.19 123 | 1 1.26 124 | 1 0.6 125 | 1 1.1 126 | 1 1.03 127 | 1 0.73 128 | 1 0.88 129 | 1 1.06 130 | 1 0.99 131 | 1 1.72 132 | 1 1.12 133 | 1 1.34 134 | 1 1.12 135 | 1 0.97 136 | 1 1.04 137 | 1 1.15 138 | 1 0.91 139 | 1 0.61 140 | 1 0.68 141 | 1 0.46 142 | 1 0.51 143 | 1 0.74 144 | 1 1.12 145 | 1 1.34 146 | 1 1.26 147 | 1 0.97 148 | 1 0.82 149 | 1 1.37 150 | 1 1.03 151 | 1 0.81 152 | 1 0.88 153 | 1 0.81 154 | 1 0.81 155 | 2 0.96 156 | 2 0.96 157 | 2 0.96 158 | 2 0.96 159 | 2 0.96 160 | 2 0.96 161 | 2 0.62 162 | 2 0 163 | 2 0 164 | 2 0 165 | 2 0 166 | 2 0 167 | 2 0.8 168 | 2 1 169 | 2 1 170 | 2 1 171 | 2 1 172 | 2 0.15 173 | 2 0 174 | 2 0 175 | 2 0 176 | 2 0 177 | 2 0 178 | 2 0 179 | 2 0.55 180 | 2 0.92 181 | 2 0.92 182 | 2 0.92 183 | 2 0.92 184 | 2 0.9 185 | 2 0.9 186 | 2 0.45 187 | 2 0 188 | 2 0 189 | 2 0 190 | 2 0 191 | 2 0 192 | 2 0.7 193 | 2 1 194 | 2 1 195 | 2 1 196 | 2 1 197 | 2 0.2 198 | 2 0 199 | 2 0 200 | 2 0 201 | 2 0 202 | 2 0 203 | 2 0 204 | 2 0.74 205 | 2 0.92 206 | 2 0.92 207 | 2 0.92 208 | 2 0.92 209 | 2 0.92 210 | 3 0.98 211 | 3 1.02 212 | 3 1.05 213 | 3 0.99 214 | 3 0.64 215 | 3 0.46 216 | 3 0.35 217 | 3 0.35 218 | 3 0.35 219 | 3 0.35 220 | 3 0.35 221 | 3 0.35 222 | 3 0.17 223 | 3 0.17 224 | 3 0.13 225 | 3 0.13 226 | 3 0.13 227 | 3 0.15 228 | 3 0.15 229 | 3 0.15 230 | 3 0.15 231 | 3 0.15 232 | 3 0.15 233 | 3 0.15 234 | 3 0.15 235 | 3 0.12 236 | 3 0.1 237 | 3 0.08 238 | 3 0.11 239 | 3 0.09 240 | 3 0.09 241 | 3 0.08 242 | 3 0.08 243 | 3 0.08 244 | 3 0.08 245 | 3 0.08 246 | 3 0.08 247 | 3 0.09 248 | 3 0.07 249 | 3 0.07 250 | 3 0.09 251 | 3 0.09 252 | 3 0.09 253 | 3 0.09 254 | 3 0.09 255 | 3 0.09 256 | 3 0.09 257 | 3 0.09 258 | 3 0.09 259 | 3 0.08 260 | 3 0.35 261 | 3 0.72 262 | 3 0.82 263 | 3 0.92 264 | 3 1 265 | 266 | [CURVES] 267 | 268 | [CONTROLS] 269 | 270 | [RULES] 271 | 272 | [ENERGY] 273 | Global Efficiency 75 274 | Global Price 0.0 275 | Demand Charge 0.0 276 | 277 | [STATUS] 278 | 279 | [EMITTERS] 280 | 281 | [QUALITY] 282 | 1 1 283 | 2 1 284 | 3 1 285 | 4 1 286 | 5 1 287 | 6 1 288 | 7 1 289 | 8 1 290 | 9 1 291 | 10 1 292 | 11 1 293 | 12 1 294 | 13 1 295 | 14 1 296 | 15 1 297 | 16 1 298 | 17 1 299 | 18 1 300 | 19 1 301 | 20 1 302 | 21 1 303 | 22 1 304 | 23 1 305 | 24 1 306 | 25 1 307 | 27 1 308 | 28 1 309 | 29 1 310 | 30 1 311 | 31 1 312 | 32 1 313 | 33 1 314 | 34 1 315 | 35 1 316 | 36 1 317 | 26 1 318 | 319 | [SOURCES] 320 | 1 CONCEN 1 3 321 | 322 | [REACTIONS] 323 | Order Bulk 1 324 | Order Tank 1 325 | Order Wall 1 326 | Global Bulk 0.0 327 | Global Wall 0.0 328 | Limiting Potential 0.0 329 | Roughness Correlation 0.0 330 | 331 | [MIXING] 332 | 333 | [TIMES] 334 | Duration 55:00 335 | Hydraulic Timestep 1:00 336 | Quality Timestep 0:05 337 | Pattern Timestep 1:00 338 | Pattern Start 0:00 339 | Report Timestep 1:00 340 | Report Start 0:00 341 | Start ClockTime 8 am 342 | Statistic None 343 | 344 | [REPORT] 345 | Status No 346 | Summary No 347 | Page 0 348 | Links All 349 | Nodes All 350 | 351 | [OPTIONS] 352 | UNITS GPM 353 | HEADLOSS H-W 354 | QUALITY NONE 355 | VISCOSITY 1.0 356 | DIFFUSIVITY 1.0 357 | SPECIFIC GRAVITY 1.0 358 | TRIALS 40 359 | ACCURACY 0.001 360 | UNBALANCED STOP 361 | PATTERN 1 362 | DEMAND MULTIPLIER 1.0 363 | EMITTER EXPONENT 0.5 364 | TOLERANCE 0.01 365 | 366 | [COORDINATES] 367 | 1 21 4 368 | 2 19 20 369 | 3 11 21 370 | 4 14 28 371 | 5 19 25 372 | 6 28 23 373 | 7 36 39 374 | 8 38 30 375 | 9 36 42 376 | 10 37 23 377 | 11 37 49 378 | 12 39 60 379 | 13 38 64 380 | 14 38 66 381 | 15 37 69 382 | 16 27 65 383 | 17 27 69 384 | 18 23 68 385 | 19 21 59 386 | 20 45 68 387 | 21 51 62 388 | 22 54 69 389 | 23 35 74 390 | 24 37 71 391 | 25 35 76 392 | 27 39 87 393 | 28 49 85 394 | 29 42 86 395 | 30 47 80 396 | 31 37 80 397 | 32 23 64 398 | 33 56 73 399 | 34 56 77 400 | 35 43 81 401 | 36 53 87 402 | 26 33 76 403 | 404 | [VERTICES] 405 | 406 | [LABELS] 407 | 24 7 Pump 408 | 24 4 Station 409 | 26.76 77.42 Tank 410 | 411 | [BACKDROP] 412 | DIMENSIONS 8.75 -0.15 58.25 91.15 413 | UNITS None 414 | FILE 415 | OFFSET 0.00 0.00 416 | 417 | [TAGS] 418 | 419 | [END] 420 | -------------------------------------------------------------------------------- /tests/testthat/writeNet3.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | EPANET Example Network 3 3 | Example showing how the percent of Lake water in a dual-source 4 | system changes over time. 5 | 6 | [JUNCTIONS] 7 | 10 147 0 8 | 15 32 1 3 9 | 20 129 0 10 | 35 12.5 1 4 11 | 40 131.9 0 12 | 50 116.5 0 13 | 60 0 0 14 | 601 0 0 15 | 61 0 0 16 | 101 42 189.95 17 | 103 43 133.2 18 | 105 28.5 135.37 19 | 107 22 54.64 20 | 109 20.3 231.4 21 | 111 10 141.94 22 | 113 2 20.01 23 | 115 14 52.1 24 | 117 13.6 117.71 25 | 119 2 176.13 26 | 120 0 0 27 | 121 -2 41.63 28 | 123 11 1 2 29 | 125 11 45.6 30 | 127 56 17.66 31 | 129 51 0 32 | 131 6 42.75 33 | 139 31 5.89 34 | 141 4 9.85 35 | 143 -4.5 6.2 36 | 145 1 27.63 37 | 147 18.5 8.55 38 | 149 16 27.07 39 | 151 33.5 144.48 40 | 153 66.2 44.17 41 | 157 13.1 51.79 42 | 159 6 41.32 43 | 161 4 15.8 44 | 163 5 9.42 45 | 164 5 0 46 | 166 -2 2.6 47 | 167 -5 14.56 48 | 169 -5 0 49 | 171 -4 39.34 50 | 173 -4 0 51 | 177 8 58.17 52 | 179 8 0 53 | 181 8 0 54 | 183 11 0 55 | 184 16 0 56 | 185 16 25.65 57 | 187 12.5 0 58 | 189 4 107.92 59 | 191 25 81.9 60 | 193 18 71.31 61 | 195 15.5 0 62 | 197 23 17.04 63 | 199 -2 119.32 64 | 201 0.1 44.61 65 | 203 2 1 5 66 | 204 21 0 67 | 205 21 65.36 68 | 206 1 0 69 | 207 9 69.39 70 | 208 16 0 71 | 209 -2 0.87 72 | 211 7 8.67 73 | 213 7 13.94 74 | 215 7 92.19 75 | 217 6 24.22 76 | 219 4 41.32 77 | 225 8 22.8 78 | 229 10.5 64.18 79 | 231 5 16.48 80 | 237 14 15.61 81 | 239 13 44.61 82 | 241 13 0 83 | 243 14 4.34 84 | 247 18 70.38 85 | 249 18 0 86 | 251 30 24.16 87 | 253 36 54.52 88 | 255 27 40.39 89 | 257 17 0 90 | 259 25 0 91 | 261 0 0 92 | 263 0 0 93 | 265 0 0 94 | 267 21 0 95 | 269 0 0 96 | 271 6 0 97 | 273 8 0 98 | 275 10 0 99 | 100 | [TANKS] 101 | 1 131.9 13.1 0.1 32.1 85 0 102 | 2 116.5 23.5 6.5 40.3 50 0 103 | 3 129 29 4 35.5 164 0 104 | 105 | [RESERVOIRS] 106 | River 220 107 | Lake 167 108 | 109 | [PIPES] 110 | 20 3 20 99 99 199 0 Open 111 | 40 1 40 99 99 199 0 Open 112 | 50 2 50 99 99 199 0 Open 113 | 60 River 60 1231 24 140 0 Open 114 | 101 10 101 14200 18 110 0 Open 115 | 103 101 103 1350 16 130 0 Open 116 | 105 101 105 2540 12 130 0 Open 117 | 107 105 107 1470 12 130 0 Open 118 | 109 103 109 3940 16 130 0 Open 119 | 111 109 111 2000 12 130 0 Open 120 | 112 115 111 1160 12 130 0 Open 121 | 113 111 113 1680 12 130 0 Open 122 | 114 115 113 2000 8 130 0 Open 123 | 115 107 115 1950 8 130 0 Open 124 | 116 113 193 1660 12 130 0 Open 125 | 117 263 105 2725 12 130 0 Open 126 | 119 115 117 2180 12 130 0 Open 127 | 120 119 120 730 12 130 0 Open 128 | 121 120 117 1870 12 130 0 Open 129 | 122 121 120 2050 8 130 0 Open 130 | 123 121 119 2000 30 141 0 Open 131 | 125 123 121 1500 30 141 0 Open 132 | 129 121 125 930 24 130 0 Open 133 | 131 125 127 3240 24 130 0 Open 134 | 133 20 127 785 20 130 0 Open 135 | 135 127 129 900 24 130 0 Open 136 | 137 129 131 6480 16 130 0 Open 137 | 145 129 139 2750 8 130 0 Open 138 | 147 139 141 2050 8 130 0 Open 139 | 149 143 141 1400 8 130 0 Open 140 | 151 15 143 1650 8 130 0 Open 141 | 153 145 141 3510 12 130 0 Open 142 | 155 147 145 2200 12 130 0 Open 143 | 159 147 149 880 12 130 0 Open 144 | 161 149 151 1020 8 130 0 Open 145 | 163 151 153 1170 12 130 0 Open 146 | 169 125 153 4560 8 130 0 Open 147 | 171 119 151 3460 12 130 0 Open 148 | 173 119 157 2080 30 141 0 Open 149 | 175 157 159 2910 30 141 0 Open 150 | 177 159 161 2000 30 141 0 Open 151 | 179 161 163 430 30 141 0 Open 152 | 180 163 164 150 14 130 0 Open 153 | 181 164 166 490 14 130 0 Open 154 | 183 265 169 590 30 141 0 Open 155 | 185 167 169 60 8 130 0 Open 156 | 186 187 204 99.9 8 130 0 Open 157 | 187 169 171 1270 30 141 0 Open 158 | 189 171 173 50 30 141 0 Open 159 | 191 271 171 760 24 130 0 Open 160 | 193 35 181 30 24 130 0 Open 161 | 195 181 177 30 12 130 0 Open 162 | 197 177 179 30 12 130 0 Open 163 | 199 179 183 210 12 130 0 Open 164 | 201 40 179 1190 12 130 0 Open 165 | 202 185 184 99.9 8 130 0 Open 166 | 203 183 185 510 8 130 0 Open 167 | 204 184 205 4530 12 130 0 Open 168 | 205 204 185 1325 12 130 0 Open 169 | 207 189 183 1350 12 130 0 Open 170 | 209 189 187 500 8 130 0 Open 171 | 211 169 269 646 12 130 0 Open 172 | 213 191 187 2560 12 130 0 Open 173 | 215 267 189 1230 12 130 0 Open 174 | 217 191 193 520 12 130 0 Open 175 | 219 193 195 360 12 130 0 Open 176 | 221 161 195 2300 8 130 0 Open 177 | 223 197 191 1150 12 130 0 Open 178 | 225 111 197 2790 12 130 0 Open 179 | 229 173 199 4000 24 141 0 Open 180 | 231 199 201 630 24 141 0 Open 181 | 233 201 203 120 24 130 0 Open 182 | 235 199 273 725 12 130 0 Open 183 | 237 205 207 1200 12 130 0 Open 184 | 238 207 206 450 12 130 0 Open 185 | 239 275 207 1430 12 130 0 Open 186 | 240 206 208 510 12 130 0 Open 187 | 241 208 209 885 12 130 0 Open 188 | 243 209 211 1210 16 130 0 Open 189 | 245 211 213 990 16 130 0 Open 190 | 247 213 215 4285 16 130 0 Open 191 | 249 215 217 1660 16 130 0 Open 192 | 251 217 219 2050 14 130 0 Open 193 | 257 217 225 1560 12 130 0 Open 194 | 261 213 229 2200 8 130 0 Open 195 | 263 229 231 1960 12 130 0 Open 196 | 269 211 237 2080 12 130 0 Open 197 | 271 237 229 790 8 130 0 Open 198 | 273 237 239 510 12 130 0 Open 199 | 275 239 241 35 12 130 0 Open 200 | 277 241 243 2200 12 130 0 Open 201 | 281 241 247 445 10 130 0 Open 202 | 283 239 249 430 12 130 0 Open 203 | 285 247 249 10 12 130 0 Open 204 | 287 247 255 1390 10 130 0 Open 205 | 289 50 255 925 10 130 0 Open 206 | 291 255 253 1100 10 130 0 Open 207 | 293 255 251 1100 8 130 0 Open 208 | 295 249 251 1450 12 130 0 Open 209 | 297 120 257 645 8 130 0 Open 210 | 299 257 259 350 8 130 0 Open 211 | 301 259 263 1400 8 130 0 Open 212 | 303 257 261 1400 8 130 0 Open 213 | 305 117 261 645 12 130 0 Open 214 | 307 261 263 350 12 130 0 Open 215 | 309 265 267 1580 8 130 0 Open 216 | 311 193 267 1170 12 130 0 Open 217 | 313 269 189 646 12 130 0 Open 218 | 315 181 271 260 24 130 0 Open 219 | 317 273 275 2230 8 130 0 Open 220 | 319 273 205 645 12 130 0 Open 221 | 321 163 265 1200 30 141 0 Open 222 | 323 201 275 300 12 130 0 Open 223 | 325 269 271 1290 8 130 0 Open 224 | 329 61 123 45500 30 140 0 Open 225 | 330 60 601 1 30 140 0 Closed 226 | 333 601 61 1 30 140 0 Open 227 | 228 | [PUMPS] 229 | 10 Lake 10 HEAD 1 230 | 335 60 61 HEAD 2 231 | 232 | [VALVES] 233 | 234 | [DEMANDS] 235 | 236 | [PATTERNS] 237 | 1 1.34 238 | 1 1.94 239 | 1 1.46 240 | 1 1.44 241 | 1 0.76 242 | 1 0.92 243 | 1 0.85 244 | 1 1.07 245 | 1 0.96 246 | 1 1.1 247 | 1 1.08 248 | 1 1.19 249 | 1 1.16 250 | 1 1.08 251 | 1 0.96 252 | 1 0.83 253 | 1 0.79 254 | 1 0.74 255 | 1 0.64 256 | 1 0.64 257 | 1 0.85 258 | 1 0.96 259 | 1 1.24 260 | 1 1.67 261 | 2 0 262 | 2 0 263 | 2 0 264 | 2 0 265 | 2 0 266 | 2 1219 267 | 2 0 268 | 2 0 269 | 2 0 270 | 2 1866 271 | 2 1836 272 | 2 1818 273 | 2 1818 274 | 2 1822 275 | 2 1822 276 | 2 1817 277 | 2 1824 278 | 2 1816 279 | 2 1833 280 | 2 1817 281 | 2 1830 282 | 2 1814 283 | 2 1840 284 | 2 1859 285 | 3 620 286 | 3 620 287 | 3 620 288 | 3 620 289 | 3 620 290 | 3 360 291 | 3 360 292 | 3 0 293 | 3 0 294 | 3 0 295 | 3 0 296 | 3 360 297 | 3 360 298 | 3 360 299 | 3 360 300 | 3 360 301 | 3 0 302 | 3 0 303 | 3 0 304 | 3 0 305 | 3 0 306 | 3 0 307 | 3 360 308 | 3 360 309 | 4 1637 310 | 4 1706 311 | 4 1719 312 | 4 1719 313 | 4 1791 314 | 4 1819 315 | 4 1777 316 | 4 1842 317 | 4 1815 318 | 4 1825 319 | 4 1856 320 | 4 1801 321 | 4 1819 322 | 4 1733 323 | 4 1664 324 | 4 1620 325 | 4 1613 326 | 4 1620 327 | 4 1616 328 | 4 1647 329 | 4 1627 330 | 4 1627 331 | 4 1671 332 | 4 1668 333 | 5 4439 334 | 5 4531 335 | 5 4511 336 | 5 4582 337 | 5 4531 338 | 5 4582 339 | 5 4572 340 | 5 4613 341 | 5 4643 342 | 5 4643 343 | 5 4592 344 | 5 4613 345 | 5 4531 346 | 5 4521 347 | 5 4449 348 | 5 4439 349 | 5 4449 350 | 5 4460 351 | 5 4439 352 | 5 4419 353 | 5 4368 354 | 5 4399 355 | 5 4470 356 | 5 4480 357 | 358 | [CURVES] 359 | 1 0 104 360 | 1 2000 92 361 | 1 4000 63 362 | 2 0 200 363 | 2 8000 138 364 | 2 14000 86 365 | 366 | [CONTROLS] 367 | Link 10 OPEN AT TIME 1 368 | Link 10 CLOSED AT TIME 15 369 | Link 335 OPEN IF Node 1 BELOW 17.1 370 | Link 335 CLOSED IF Node 1 ABOVE 19.1 371 | Link 330 CLOSED IF Node 1 BELOW 17.1 372 | Link 330 OPEN IF Node 1 ABOVE 19.1 373 | 374 | [RULES] 375 | 376 | [ENERGY] 377 | Global Efficiency 75 378 | Global Price 0.0 379 | Demand Charge 0.0 380 | 381 | [STATUS] 382 | 10 Closed 383 | 384 | [EMITTERS] 385 | 386 | [QUALITY] 387 | 388 | [SOURCES] 389 | 390 | [REACTIONS] 391 | Order Bulk 1 392 | Order Tank 1 393 | Order Wall 1 394 | Global Bulk 0.0 395 | Global Wall 0.0 396 | Limiting Potential 0.0 397 | Roughness Correlation 0.0 398 | 399 | [MIXING] 400 | 401 | [TIMES] 402 | Duration 24:00 403 | Hydraulic Timestep 1:00 404 | Quality Timestep 0:05 405 | Pattern Timestep 1:00 406 | Pattern Start 0:00 407 | Report Timestep 1:00 408 | Report Start 0:00 409 | Start ClockTime 12 am 410 | Statistic None 411 | 412 | [REPORT] 413 | Status Yes 414 | Summary No 415 | Page 0 416 | Links All 417 | Nodes All 418 | 419 | [OPTIONS] 420 | UNITS GPM 421 | HEADLOSS H-W 422 | QUALITY NONE 423 | VISCOSITY 1.0 424 | DIFFUSIVITY 1.0 425 | SPECIFIC GRAVITY 1.0 426 | TRIALS 40 427 | ACCURACY 0.001 428 | UNBALANCED STOP 429 | PATTERN 1 430 | DEMAND MULTIPLIER 1.0 431 | EMITTER EXPONENT 0.5 432 | TOLERANCE 0.01 433 | 434 | [COORDINATES] 435 | 10 9 27.85 436 | 15 38.68 23.76 437 | 20 29.44 26.91 438 | 35 25.46 10.52 439 | 40 27.02 9.81 440 | 50 33.01 3.01 441 | 60 23.9 29.94 442 | 601 23 29.49 443 | 61 23.71 29.03 444 | 101 13.81 22.94 445 | 103 12.96 21.31 446 | 105 16.97 21.28 447 | 107 18.45 20.46 448 | 109 17.64 18.92 449 | 111 20.21 17.53 450 | 113 22.04 16.61 451 | 115 20.98 19.18 452 | 117 21.69 21.28 453 | 119 23.7 22.76 454 | 120 22.08 23.1 455 | 121 23.54 25.5 456 | 123 23.37 27.31 457 | 125 24.59 25.64 458 | 127 29.29 26.4 459 | 129 30.32 26.39 460 | 131 37.89 29.55 461 | 139 33.28 24.54 462 | 141 35.68 23.08 463 | 143 37.47 21.97 464 | 145 33.02 19.29 465 | 147 30.24 20.38 466 | 149 29.62 20.74 467 | 151 28.29 21.39 468 | 153 28.13 22.63 469 | 157 24.85 20.16 470 | 159 23.12 17.5 471 | 161 25.1 15.28 472 | 163 25.39 14.98 473 | 164 25.98 15.14 474 | 166 26.48 15.13 475 | 167 25.88 12.98 476 | 169 25.68 12.74 477 | 171 26.65 11.8 478 | 173 26.87 11.59 479 | 179 25.71 10.4 480 | 181 25.72 10.74 481 | 183 25.45 10.18 482 | 184 25.15 9.52 483 | 185 25.01 9.67 484 | 187 23.64 11.04 485 | 189 24.15 11.37 486 | 191 22.1 14.07 487 | 193 22.88 14.35 488 | 195 23.18 14.72 489 | 197 20.97 15.18 490 | 199 29.42 8.44 491 | 201 30.89 8.57 492 | 203 31.14 8.89 493 | 204 23.8 10.9 494 | 205 29.2 6.46 495 | 206 31.66 6.64 496 | 207 31 6.61 497 | 208 32.54 6.81 498 | 209 33.76 6.59 499 | 211 34.2 5.54 500 | 213 35.26 6.16 501 | 215 39.95 8.73 502 | 217 42.11 8.67 503 | 219 44.86 9.32 504 | 225 43.53 7.38 505 | 229 36.16 3.49 506 | 231 38.38 2.54 507 | 237 35.37 3.08 508 | 239 35.76 2.31 509 | 241 35.87 2.11 510 | 243 37.04 0 511 | 247 35.02 2.05 512 | 249 35.02 1.81 513 | 251 34.15 1.1 514 | 253 32.17 1.88 515 | 255 33.51 2.45 516 | 257 21.17 23.32 517 | 259 20.8 23.4 518 | 261 20.79 21.45 519 | 263 20.32 21.57 520 | 265 25.39 13.6 521 | 267 23.38 12.95 522 | 269 25.03 12.14 523 | 271 25.97 11 524 | 273 29.16 7.38 525 | 275 31.07 8.29 526 | River 24.15 31.06 527 | Lake 8 27.53 528 | 1 27.46 9.84 529 | 2 32.99 3.45 530 | 3 29.41 27.27 531 | 532 | [VERTICES] 533 | 534 | [LABELS] 535 | 8 29.42 LAKE 536 | 25 31.1 RIVER 537 | 538 | [BACKDROP] 539 | DIMENSIONS 6.16 -1.55 46.70 32.61 540 | UNITS None 541 | FILE 542 | OFFSET 0.00 0.00 543 | 544 | [TAGS] 545 | 546 | [END] 547 | -------------------------------------------------------------------------------- /tests/testthat/writeOneprv.inp: -------------------------------------------------------------------------------- 1 | [TITLE] 2 | 3 | [JUNCTIONS] 4 | 2 0 0 5 | 3 0 0 6 | 4 0 23 7 | 5 0 32 8 | 9 | [TANKS] 10 | 11 | [RESERVOIRS] 12 | 1 100 13 | 14 | [PIPES] 15 | 1 1 2 1000 12 100 0 Open 16 | 3 3 4 1000 12 100 0 Open 17 | 4 4 5 1000 12 100 0 Open 18 | 5 5 3 1000 12 100 0 Open 19 | 20 | [PUMPS] 21 | 22 | [VALVES] 23 | 2 2 3 12 PRV 50 0 24 | 25 | [DEMANDS] 26 | 2 1.1 P1 27 | 2 0.1 P2 28 | 2 0.2 P3 29 | 30 | [PATTERNS] 31 | 32 | 33 | 34 | [CURVES] 35 | 36 | [CONTROLS] 37 | 38 | [RULES] 39 | 40 | [ENERGY] 41 | Global Efficiency 75 42 | Global Price 0 43 | Demand Charge 0 44 | 45 | [STATUS] 46 | 47 | [EMITTERS] 48 | 49 | [QUALITY] 50 | 51 | [SOURCES] 52 | 53 | [REACTIONS] 54 | Order Bulk 1 55 | Order Tank 1 56 | Order Wall 1 57 | Global Bulk 0 58 | Global Wall 0 59 | Limiting Potential 0 60 | Roughness Correlation 0 61 | 62 | [MIXING] 63 | 64 | [TIMES] 65 | Duration 0 66 | Hydraulic Timestep 1:00 67 | Quality Timestep 0:05 68 | Pattern Timestep 1:00 69 | Pattern Start 0:00 70 | Report Timestep 1:00 71 | Report Start 0:00 72 | Start ClockTime 12 am 73 | Statistic None 74 | 75 | [REPORT] 76 | Status No 77 | Summary No 78 | Page 0 79 | 80 | [OPTIONS] 81 | UNITS GPM 82 | HEADLOSS H-W 83 | QUALITY NONE 84 | VISCOSITY 1 85 | DIFFUSIVITY 1 86 | SPECIFIC GRAVITY 1 87 | TRIALS 40 88 | ACCURACY 0.001 89 | UNBALANCED STOP 90 | PATTERN 1 91 | DEMAND MULTIPLIER 1.0 92 | EMITTER EXPONENT 0.5 93 | TOLERANCE 0.01 94 | 95 | [COORDINATES] 96 | 2 2618.64 5677.97 97 | 3 5788.14 5677.97 98 | 4 7720.34 7067.8 99 | 5 7957.63 4016.95 100 | 1 -584.75 5745.76 101 | 102 | [VERTICES] 103 | 1 59.32 6406.78 104 | 1 449.15 6711.86 105 | 1 1025.42 6966.1 106 | 1 1228.81 6728.81 107 | 1 1703.39 6694.92 108 | 1 1822.03 6406.78 109 | 1 2177.97 6271.19 110 | 1 2550.85 6067.8 111 | 3 6449.15 5627.12 112 | 3 6686.44 5762.71 113 | 3 6584.75 6152.54 114 | 3 6991.53 6271.19 115 | 3 7398.31 6389.83 116 | 3 7110.17 6796.61 117 | 3 7466.1 6745.76 118 | 3 7788.14 6711.86 119 | 3 7262.71 6949.15 120 | 4 8550.85 6457.63 121 | 4 9144.07 5915.25 122 | 4 9245.76 5372.88 123 | 4 8906.78 4966.1 124 | 4 8889.83 4610.17 125 | 4 9127.12 3966.1 126 | 4 8754.24 3830.51 127 | 4 8381.36 4101.69 128 | 4 8347.46 3830.51 129 | 4 8076.27 3559.32 130 | 4 8008.47 3677.97 131 | 4 7754.24 3728.81 132 | 5 7398.31 4101.69 133 | 5 6838.98 4135.59 134 | 5 6669.49 4288.14 135 | 5 6449.15 4322.03 136 | 5 6754.24 4627.12 137 | 5 5805.08 4661.02 138 | 5 5686.44 4898.31 139 | 5 6076.27 5033.9 140 | 5 5618.64 5186.44 141 | 142 | [LABELS] 143 | 144 | [BACKDROP] 145 | DIMENSIONS 0.00 0.00 10000.00 10000.00 146 | UNITS None 147 | FILE 148 | OFFSET 0.00 0.00 149 | 150 | [TAGS] 151 | 152 | [END] 153 | --------------------------------------------------------------------------------