Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env-coastal-lifecycle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CC_STORE_TYPE=FS
FSB_ROOT_PATH="/workspaces/consequences-runner/data/"
CC_PAYLOAD_ID=coastal
12 changes: 12 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [

{
"name": "Launch Package",
"type": "go",
Expand Down Expand Up @@ -43,6 +44,17 @@
"Test_Compute"
],
"envFile": "/workspaces/.env-milliman"
},{
"name": "Test Coastal Lifecycle",
"type": "go",
"request": "launch",
"mode": "test",
"program": "${workspaceFolder}",
"args": [
"-test.run",
"Test_Main"
],
"envFile": "/workspaces/consequences-runner/.env-coastal-lifecycle"
},{
"name": "Download",
"type": "go",
Expand Down
9 changes: 5 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
FROM ghcr.io/usace-cloud-compute/cc-tiledb-base:latest as dev
FROM ghcr.io/osgeo/gdal:ubuntu-full-3.8.3 as dev

ARG TILEDB_LIB=/usr/local/lib/tiledb
# ARG TILEDB_LIB=/usr/local/lib/tiledb
ARG GO_VERSION=1.24.5
ARG TARGETARCH

ENV PATH=/go/bin:$PATH
ENV CGO_LDFLAGS="-L${TILEDB_LIB}/lib"
ENV CGO_CFLAGS="-I${TILEDB_LIB}/include"
# ENV CGO_LDFLAGS="-L${TILEDB_LIB}/lib"
# ENV CGO_CFLAGS="-I${TILEDB_LIB}/include"
ENV GOROOT=/go
ENV GOPATH=/src/go

Expand All @@ -15,6 +15,7 @@ RUN echo "Building for arch: ${TARGETARCH}" &&\
tar -xvzf /go${GO_VERSION}.linux-${TARGETARCH}.tar.gz -C /

RUN apt update
RUN apt -y install git
RUN apt -y install gdal-data
RUN apt -y install gdal-bin
RUN apt -y install libgdal-dev
Expand Down
173 changes: 151 additions & 22 deletions actions/compute-payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (
"github.com/USACE/go-consequences/structureprovider"
"github.com/USACE/go-consequences/structures"
"github.com/usace-cloud-compute/cc-go-sdk"
"github.com/usace-cloud-compute/consequences-runner/crresultswriters"
lrw "github.com/usace-cloud-compute/consequences-runner/crresultswriters"
lhp "github.com/usace-cloud-compute/consequences-runner/hazardproviders"
"github.com/usace-cloud-compute/consequences-runner/structureproviders"
)

Expand All @@ -32,34 +34,46 @@ const (
outputLayerName string = "damages"
structureInventoryPathKey string = "Inventory" //plugin datasource name required
//seedsDatasourceName string = "seeds.json" //plugin datasource name required
depthgridDatasourceName string = "depth-grid" //plugin datasource name required
velocitygridDatasourceName string = "velocity-grid" //plugin datasource name required
durationgridDatasourceName string = "duration-grid" //plugin datasource name required
outputDatasourceName string = "Damages" //plugin output datasource name required
localData string = "/app/data"
pluginName string = "consequences"
DepthGridPathsKey string = "depth-grids" // expected to contain the fully qualified vsis3 path set comma separated or the local path if the resource is included as an inputdatasource
VelocityGridPathsKey string = "velocity-grids" // expected to contain the fully qualified vsis3 path set comma separated or the local path if the resource is included as an inputdatasource
FrequenciesKey string = "frequencies" //expected to be comma separated string
inventoryPathKey string = "Inventory" //expected this is local - needs to agree with the payload input datasource name
damageFunctionPathKey string = "damage-functions" //expected this is local - needs to agree with the payload input datasource name
projectIdKey string = "project-id"
runIdKey string = "run-id"
pgUserKey string = "PG_USER"
pgPasswordKey string = "PG_PASSWORD"
pgDbnameKey string = "PG_DBNAME"
pgHostKey string = "PG_HOST"
pgPortKey string = "PG_PORT"
pgSchemaKey string = "PG_SCHEMA"
computeEventActionName string = "compute-event"
computeFrequencyActionName string = "compute-frequency"
computeCoastalEventActionName string = "compute-coastal-event"
depthgridDatasourceName string = "depth-grid" //plugin datasource name required
velocitygridDatasourceName string = "velocity-grid" //plugin datasource name required
durationgridDatasourceName string = "duration-grid" //plugin datasource name required
stormSimEventsPath string = "ss-events" //
stormSimEventsDriver string = "ss-events-driver"
stormSimEventsLayer string = "ss-events-layer"
stormSimResponsesPath string = "ss-responses"
stormSimResponsesDriver string = "ss-responses-driver"
stormSimResponsesLayer string = "ss-responses-layer"
stormSimReachesPath string = "ss-reaches"
stormSimReachesDriver string = "ss-reaches-driver"
stormSimReachesLayer string = "ss-reaches-layer"
stormSimLifecycle string = "ss-lifecycle"
outputDatasourceName string = "Damages" //plugin output datasource name required
localData string = "/app/data"
pluginName string = "consequences"
DepthGridPathsKey string = "depth-grids" // expected to contain the fully qualified vsis3 path set comma separated or the local path if the resource is included as an inputdatasource
VelocityGridPathsKey string = "velocity-grids" // expected to contain the fully qualified vsis3 path set comma separated or the local path if the resource is included as an inputdatasource
FrequenciesKey string = "frequencies" //expected to be comma separated string
inventoryPathKey string = "Inventory" //expected this is local - needs to agree with the payload input datasource name
damageFunctionPathKey string = "damage-functions" //expected this is local - needs to agree with the payload input datasource name
projectIdKey string = "project-id"
runIdKey string = "run-id"
pgUserKey string = "PG_USER"
pgPasswordKey string = "PG_PASSWORD"
pgDbnameKey string = "PG_DBNAME"
pgHostKey string = "PG_HOST"
pgPortKey string = "PG_PORT"
pgSchemaKey string = "PG_SCHEMA"
computeEventActionName string = "compute-event"
computeFrequencyActionName string = "compute-frequency"
computeCoastalEventActionName string = "compute-coastal-event"
computeCoastalLifecycleActionName string = "compute-coastal-lifecycle"
)

func init() {
cc.ActionRegistry.RegisterAction(computeEventActionName, &ComputeEventAction{})
cc.ActionRegistry.RegisterAction(computeFrequencyActionName, &ComputeFrequencyAction{})
cc.ActionRegistry.RegisterAction(computeCoastalEventActionName, &ComputeCoastalEventAction{})
cc.ActionRegistry.RegisterAction(computeCoastalLifecycleActionName, &ComputeCoastalLifecycleAction{})
}

type ComputeEventAction struct {
Expand All @@ -71,6 +85,9 @@ type ComputeFrequencyAction struct {
type ComputeCoastalEventAction struct {
cc.ActionRunnerBase
}
type ComputeCoastalLifecycleAction struct {
cc.ActionRunnerBase
}

func (ar *ComputeEventAction) Run() error {
a := ar.Action
Expand Down Expand Up @@ -381,6 +398,118 @@ func (ar *ComputeFrequencyAction) Run() error {
ComputeMultiFrequency(hps, frequencies, abstractSP, rw)
return nil
}

func (ar *ComputeCoastalLifecycleAction) Run() error {
a := ar.Action
// get all relevant parameters
tablename := a.Attributes.GetStringOrFail(tablenameKey)
stormSimEventsPathString := a.Attributes.GetStringOrFail(stormSimEventsPath)
stormSimResponsesPathString := a.Attributes.GetStringOrFail(stormSimResponsesPath)
stormSimReachesPathString := a.Attributes.GetStringOrFail(stormSimReachesPath)

ssEventsDriverString := a.Attributes.GetStringOrFail(stormSimEventsDriver)
ssResponsesDriverString := a.Attributes.GetStringOrFail(stormSimResponsesDriver)
ssReachesDriverString := a.Attributes.GetStringOrFail(stormSimReachesDriver)

ssEventsLayerString := a.Attributes.GetStringOrDefault(stormSimEventsLayer, "")
ssResponsesLayerString := a.Attributes.GetStringOrDefault(stormSimResponsesLayer, "")
ssReachesLayerString := a.Attributes.GetStringOrDefault(stormSimReachesLayer, "")

ssLC := a.Attributes.GetStringOrFail(stormSimLifecycle)
ssLifecycle, err := strconv.Atoi(ssLC)
if err != nil {
panic(err)
}

inventoryPath := a.Attributes.GetStringOrFail(inventoryPathKey) //expected this is local - needs to agree with the payload input datasource name
inventoryDriver := a.Attributes.GetStringOrFail(inventoryDriverKey)

outputDriver := a.Attributes.GetStringOrFail(outputDriverKey)
outputFileName := a.Attributes.GetStringOrFail(outputFileNameKey) //expected this is local - needs to agree with the payload output datasource name
//useKnowledgeUncertainty, err := strconv.ParseBool(a.Parameters.GetStringOrFail(useKnowledgeUncertaintyKey))
damageFunctionPath := a.Attributes.GetStringOrFail(damageFunctionPathKey) //expected this is local - needs to agree with the payload input datasource name

ssi := lhp.StormSimInfo{
EventsFP: stormSimEventsPathString,
EventsDriver: ssEventsDriverString,
EventsLayername: ssEventsLayerString,
ResponsesFP: stormSimResponsesPathString,
ResponsesDriver: ssResponsesDriverString,
ResponsesLayername: ssResponsesLayerString,
ReachesFP: stormSimReachesPathString,
ReachesDriver: ssReachesDriverString,
ReachesLayername: ssReachesLayerString,
Lifecycle: ssLifecycle,
}

hp, err := lhp.InitStormSim(ssi)
if err != nil {
panic(err)
}
defer hp.Close()

var abstractSP consequences.StreamProvider
// var sr string
if inventoryDriver == "MILLIMAN" {
sp, err := structureproviders.InitMillimanStructureProviderwithOcctypePath(inventoryPath, damageFunctionPath)
sp.SetDeterministic(true)
if err != nil {
return err
}
fmt.Sprintln(sp.FilePath)
// sr = sp.SpatialReference()
abstractSP = sp
} else {
sp, err := structureprovider.InitStructureProviderwithOcctypePath(inventoryPath, tablename, inventoryDriver, damageFunctionPath)
sp.SetDeterministic(true)
if err != nil {
return err
}
fmt.Sprintln(sp.FilePath)
// sr = sp.SpatialReference()
abstractSP = sp
}

//initalize a results writer
//TODO: add more key-value pairs to payload for summary and events results writer details
summaryResultsFile := fmt.Sprintf("summary_%s", outputFileName)
eventsResultsFile := fmt.Sprintf("events_%s", outputFileName)
rw, err := crresultswriters.InitLifecycleResultsWriter(summaryResultsFile, "summary_results", outputDriver, eventsResultsFile, "event_results", outputDriver)
if err != nil {
panic(err)
}
defer rw.Close()

//compute results
//get boundingbox
fmt.Println("Getting bbox")
bbox, err := hp.HazardBoundary()
if err != nil {
log.Panicf("Unable to get the raster bounding box: %s", err)
}
fmt.Println(bbox.ToString())
abstractSP.ByBbox(bbox, func(f consequences.Receptor) {
//ProvideHazard works off of a geography.Location
d, err2 := hp.Hazard(geography.Location{X: f.Location().X, Y: f.Location().Y})

//compute damages based on hazard being able to provide depth
if err2 == nil {
r, err3 := f.Compute(d)
r.Headers = append(r.Headers, "multihazard")
bytes, err := json.Marshal(d)
s := ""
if err == nil {
s = string(bytes)
}
r.Result = append(r.Result, s)
if err3 == nil {
rw.Write(r)
}
}
})
return nil

}
func ComputeMultiFrequency(hps []hazardproviders.HazardProvider, freqs []float64, sp consequences.StreamProvider, w consequences.ResultsWriter) {
fmt.Printf("Computing %v frequencies\n", len(freqs))
//ASSUMPTION hazard providers and frequencies are in the same order
Expand Down
69 changes: 69 additions & 0 deletions crresultswriters/lifecycle-results-writer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package crresultswriters

import (
"github.com/USACE/go-consequences/consequences"
"github.com/USACE/go-consequences/resultswriters"
)

type lifecycleResultsWriter struct {
SummaryWriter consequences.ResultsWriter
EventsWriter consequences.ResultsWriter
}

func InitLifecycleResultsWriter(
summaryFilepath string,
summaryLayername string,
summaryDriver string,
eventsFilepath string,
eventsLayername string,
eventsDriver string,
) (*lifecycleResultsWriter, error) {
srw, err := resultswriters.InitSpatialResultsWriter(summaryFilepath, summaryLayername, summaryDriver)
if err != nil {
panic(err)
}
erw, err := resultswriters.InitSpatialResultsWriter(eventsFilepath, eventsLayername, eventsDriver)
if err != nil {
panic(err)
}
return &lifecycleResultsWriter{SummaryWriter: srw, EventsWriter: erw}, nil
}

func (lrw *lifecycleResultsWriter) Write(r consequences.Result) {
// Lifecycle compute includes a column which contains results for each event in the lifecycle
// 1. remove the event results column and parse them into a series of discrete Results
// 2. pass each event result to lrw.EventsWriter.Write()
// 3. pass the remaining columns to lrw.SummaryWriter.Write()
fd_id, err := r.Fetch("fd_id")
if err != nil {
panic(err)
}
e, err := r.Fetch("hazard results")
if err != nil {
panic(err)
}
eventResults := e.(consequences.Result)
for _, ei := range eventResults.Result {
er := ei.(consequences.Result)
hi := append([]string{"fd_id"}, er.Headers...)
ri := append([]interface{}{fd_id}, er.Result...)
lrw.EventsWriter.Write(consequences.Result{Headers: hi, Result: ri})
}

summaryHeaders := make([]string, 0)
summaryResults := make([]interface{}, 0)

for i, h := range r.Headers {
if h != "hazard results" {
summaryHeaders = append(summaryHeaders, h)
summaryResults = append(summaryResults, r.Result[i])
}
}
lrw.SummaryWriter.Write(consequences.Result{Headers: summaryHeaders, Result: summaryResults})
}

func (lrw *lifecycleResultsWriter) Close() {
// Will this fail if both writers are using the same geopackage?
lrw.SummaryWriter.Close()
lrw.EventsWriter.Close()
}
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ go 1.24

require (
github.com/HydrologicEngineeringCenter/go-statistics v0.0.0-20240126145250-a17483ae0981
github.com/USACE/go-consequences v0.0.0-20250731200338-7eee6afc377f
github.com/USACE/go-consequences v0.0.0-20260303155249-41dfc39dd84d
github.com/dewberry/gdal v0.3.4
github.com/google/uuid v1.6.0 // indirect
github.com/usace-cloud-compute/cc-go-sdk v0.0.0-20251124210849-b455e063a7ea
)

require github.com/usace-cloud-compute/filesapi v0.0.0-20251107191432-8084e0da4b5c

require (
github.com/aws/aws-sdk-go-v2 v1.39.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.1 // indirect
Expand Down Expand Up @@ -40,7 +42,6 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/shopspring/decimal v1.4.0 // indirect
github.com/spf13/cast v1.10.0 // indirect
github.com/usace-cloud-compute/filesapi v0.0.0-20251107191432-8084e0da4b5c // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
gonum.org/v1/gonum v0.16.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zum
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/HydrologicEngineeringCenter/go-statistics v0.0.0-20240126145250-a17483ae0981 h1:JFLYdHvF3mPN56AkXeaWm41bQ9eJFuSceCtXXtMWTNI=
github.com/HydrologicEngineeringCenter/go-statistics v0.0.0-20240126145250-a17483ae0981/go.mod h1:ABek1cDzTXjGA4uwrB91/NriEROj8AnUDaX7xU+1L2E=
github.com/USACE/go-consequences v0.0.0-20250731200338-7eee6afc377f h1:i4a5qJ/6ghF6VxJKCadp+Z6JHUzLgHwuoAXr7WEi2sQ=
github.com/USACE/go-consequences v0.0.0-20250731200338-7eee6afc377f/go.mod h1:+HMvu5PLsam+TS7GCpeiraeCWjwD04/hcgz85kuQTM4=
github.com/USACE/go-consequences v0.0.0-20260303155249-41dfc39dd84d h1:Fi60yreROXSA9kWDBdW8rvAJiDgNV4jj2VMZuDTc1eA=
github.com/USACE/go-consequences v0.0.0-20260303155249-41dfc39dd84d/go.mod h1:+HMvu5PLsam+TS7GCpeiraeCWjwD04/hcgz85kuQTM4=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/aws/aws-sdk-go-v2 v1.39.0 h1:xm5WV/2L4emMRmMjHFykqiA4M/ra0DJVSWUkDyBjbg4=
github.com/aws/aws-sdk-go-v2 v1.39.0/go.mod h1:sDioUELIUO9Znk23YVmIk86/9DOpkbyyVb1i/gUNFXY=
Expand Down Expand Up @@ -105,8 +105,6 @@ github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qq
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/usace-cloud-compute/cc-go-sdk v0.0.0-20251118163833-620acc79f197 h1:oM3e8JDPNyYjK3/aZHQkNDeWiE0D2/SPtFAr6haz3Hc=
github.com/usace-cloud-compute/cc-go-sdk v0.0.0-20251118163833-620acc79f197/go.mod h1:HZsGTrNUUdjfqqJJaLpSBEKoIDmu/vnye2KK/AwchDo=
github.com/usace-cloud-compute/cc-go-sdk v0.0.0-20251124210849-b455e063a7ea h1:tlM91GCRJ1gqc4dcFvfI6h8MI2l5FNR3Ehn+Rh4oDJw=
github.com/usace-cloud-compute/cc-go-sdk v0.0.0-20251124210849-b455e063a7ea/go.mod h1:HZsGTrNUUdjfqqJJaLpSBEKoIDmu/vnye2KK/AwchDo=
github.com/usace-cloud-compute/filesapi v0.0.0-20251107191432-8084e0da4b5c h1:1Srw2WpT9tcEIUY853oeojXJjPH8iTYFGLXPaIrUe+I=
Expand Down
Loading