Unlocking the Power of Ruby with ChatGPT: Streamlining Subcatchment Analysis in InfoWorks ICM Network
Robert Dickinson
Autodesk Water Technologist for Storm Sewer and Flood | Expert in ICM InfoWorks/SWMM/Ruby | 18 Years at Innovyze/Autodesk | 51 Years with EPASWMM | Autodesk EBCS | SWMM5+
1/ This code snippet performs the following tasks in the context of an InfoWorks ICM network (Note: The script is in subfolder 70 on my Github repository):
The main purpose of this code is to create a hash map connecting node IDs to their associated subcatchments.
net = WSApplication.current_network
# Get all subcatchments from the network and assign them to the variable all_subs
all_subs=net.row_objects('_subcatchments')
# Create an empty hash variable named node_sub_hash_map
node_sub_hash_map={}
# Get all nodes from the network and assign them to the variable all_nodes
all_nodes=net.row_objects('_nodes')
# Assign node ID's as hash keys in the node_sub_hash_map
all_nodes.each do |h|
? ? node_sub_hash_map[h.node_id]=[]
end
# Get all subcatchments again and assign them to the variable all_subs
all_subs=net.row_objects('_subcatchments')
2/ This code snippet performs the following tasks in the context of an InfoWorks ICM network:
The main purpose of this code is to access the selected nodes in the network and initialize an empty array that will be used to store unprocessed links, likely for further processing in the script.
# Get all the selected rows in the _nodes collection and assign them to the variable ro
roc = net.row_object_collection_selection('_nodes')
# Create an empty array named unprocessedLinks
unprocessedLinks = Array.new
3/ This code snippet iterates through a collection of selected nodes in the InfoWorks ICM network and performs the following tasks:
The main purpose of this code is to identify and process all upstream subcatchments connected to the selected nodes in the network.
roc.each do |ro
? ? # Iterate through all the upstream links of the current row object
? ? ro.us_links.each do |l|
? ? ? ? # if the link has not been seen before, add it to the unprocessedLinks array
? ? ? ? if !l._seen
? ? ? ? ? ? unprocessedLinks << l
? ? ? ? ? ? l._seen=true
? ? ? ? end
? ? end
? ? # While there are still unprocessed links in the array
? ? while unprocessedLinks.size>0
? ? ? ? # take the first link in the array and assign it to the variable working
? ? ? ? working = unprocessedLinks.shift
? ? ? ? working.selected=true
? ? ? ? # get the upstream node of the current link
? ? ? ? workingUSNode = working.us_node
? ? ? ? # if the upstream node is not nil and has not been seen before
? ? ? ? if !workingUSNode.nil? && !workingUSNode._seen
? ? ? ? ? ? workingUSNode.selected=true
? ? ? ? ? ? # Now that hash is ready with node id's as key and upstream subcatchments as paired values, keys can be used to get an array containing upstream subcathments
? ? ? ? ? ? # In the below code id's of subcatchments upstream of node 'node_1' are printed. The below code can be reused multiple times for different nodes within the script without being computationally expensive
? ? ? ? ? ? node_sub_hash_map[workingUSNode.id].each ?do |sub|
? ? ? ? ? ? ? ? puts "Found Upstream Subcatchment #{sub.id} connected to Node #{workingUSNode.id}"
? ? ? ? ? ? ? ? sub.selected=true
? ? ? ? ? ? end
? ? ? ? ? ? # Iterate through all the upstream links of the current node and add them to the unprocessedLinks array
? ? ? ? ? ? workingUSNode.us_links.each do |l|
? ? ? ? ? ? ? ? if !l._seen
? ? ? ? ? ? ? ? ? ? unprocessedLinks << l
? ? ? ? ? ? ? ? ? ? l.selected=true
? ? ? ? ? ? ? ? ? ? l._seen=true
? ? ? ? ? ? ? ? end
? ? ? ? ? ? end
? ? ? ? end
? ? end
end|
领英推荐
4/ You do need to select at least one node to find the upstream Subcatchments.
5/ Now let us use ChatGPT to find the total area and total number of found Subcatchments
ChatGPT Prompt - I have already used the Ruby code in ChatGPT to summarize the code (see above)
add a final table that tells me the total number of found Subcatchments and the total area
The response from ChatGPT Note the area variable is not correct so I need to change it to "total_area += sub.total_area" for ICM
The output now looks like with the total number of Subcatchemntns and total area.
Code for printing the "The output now looks like with the total number of Subs and total area.
# Initialize a counter variable for th" e total number of subcatchments and a variable for the total ar
total_subcatchments = 0
total_area = 0.0
roc.each do |ro|
? ? # The existing code goes here
? ? # ...
end
# Add the found upstream subcatchment's area to the total area
node_sub_hash_map.each_value do |subcatchments|
? subcatchments.each do |sub|
? ? total_area += sub.area
? ? total_subcatchments += 1
? end
end
# Print the total number of subcatchments and the total area
puts "Total number of found Subcatchments: #{total_subcatchments}"
puts "Total area of found Subcatchments: #{total_area}"e
My reasoning about this elephant story list of blogs.
Bottom-up technical blogs can be highly beneficial for engineering, particularly when it comes to explaining deep dive features. These blogs often present detailed insights, experiences, and practical examples from engineers and industry professionals, making them an excellent resource for understanding complex engineering concepts. Some of the reasons why bottom-up technical blogs are good for engineering when explaining deep dive features include:
Adviseur drinkwatervoorziening at WML
1 年Wim Lafeber ter inspiratie ??
Freelance tender, content and communications wizard/ endlessly curious / lover of all things engineering / advocate for a natural hazards resilient New Zealand
1 年Andrew Wilson
Chartered Professional (MCIWEM C.WEM) | Climate Change, Risk, & Emergency Management
1 年Simon Aiken
Regional Technical Business Specialist Autodesk Water Infrastructure - META (Middle East, Turkey, Africa), Helping achieve digital transformation for private & public water sectors
1 年Wow Bob! Amazing work ????
Data Engineer on team Earth ??
1 年Super cool!