Compare commits
No commits in common. "v11" and "main" have entirely different histories.
3541
Cargo.lock
generated
3541
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
11
Cargo.toml
@ -1,11 +0,0 @@
|
|||||||
[package]
|
|
||||||
edition = "2024"
|
|
||||||
name = "web"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
fathom-function = { git = "ssh://git@github.com/fathom-io/pipeline-calculations.git", branch = "FTHM-10784/clusting-visulization" }
|
|
||||||
pipeline-application = { git = "ssh://git@github.com/fathom-io/pipeline-calculations.git", branch = "FTHM-10784/clusting-visulization" }
|
|
||||||
serde = { version = "1.0.219", features = ["derive"] }
|
|
||||||
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread"] }
|
|
||||||
uuid = { version = "1" }
|
|
||||||
121
README.md
121
README.md
@ -1,121 +1,2 @@
|
|||||||
# Runs the ILI clustering algorithm
|
# 38c96dacac3a4b8398099282ad92ad9a
|
||||||
|
|
||||||
Clustering criteria for pipeline defects refer to the guidelines or criteria that are used to
|
|
||||||
determine whether a group of defects in a pipeline should be considered a "cluster." These
|
|
||||||
criteria are typically based on a combination of factors, including the size, location, and
|
|
||||||
severity of the defects, as well as the spacing between them.
|
|
||||||
There are several different clustering criteria that can be used for pipeline defects,
|
|
||||||
depending on the specific context and application. Some common clustering criteria include:
|
|
||||||
|
|
||||||
- *Percentage of wall loss*: This criterion considers the percentage of the pipeline wall that has
|
|
||||||
been lost due to corrosion or other defects. A group of defects that collectively represent a
|
|
||||||
certain percentage of wall loss (e.g., 10%) may be considered a cluster.
|
|
||||||
- *Spacing between defects*: This criterion considers the distance between individual defects in a
|
|
||||||
pipeline. If the spacing between defects falls below a certain threshold (e.g., 1 meter), they
|
|
||||||
may be considered a cluster.
|
|
||||||
- *Geographic location*: This criterion considers the geographic location of defects within a
|
|
||||||
pipeline. If defects are clustered within a certain area of the pipeline (e.g., a bend or a
|
|
||||||
weld), they may be considered a cluster.
|
|
||||||
- *Severity of defects*: This criterion considers the severity or consequence of individual
|
|
||||||
defects. If a group of defects collectively represent a significant risk of failure or leakage,
|
|
||||||
they may be considered a cluster.
|
|
||||||
|
|
||||||
Pipeline operators typically use clustering criteria as part of their inspection and
|
|
||||||
maintenance programs to identify and prioritize areas of the pipeline that require attention.
|
|
||||||
By identifying and addressing clusters of defects, operators can help prevent failures and
|
|
||||||
ensure the safe and reliable operation of their pipelines.
|
|
||||||
|
|
||||||
Examining the clustering of pipeline defects is a crucial aspect of pipeline integrity
|
|
||||||
management. This involves evaluating the spacing between defects in a pipeline to determine the
|
|
||||||
likelihood of larger defects clustering together. Specific conditions must be met for this
|
|
||||||
distance to be considered acceptable. If these conditions are met, the possibility of defect
|
|
||||||
clustering cannot be overlooked.
|
|
||||||
|
|
||||||
## Clustering rules
|
|
||||||
|
|
||||||
Rules are used to configure the clustering algorithm. There are 11 standard rules and then a 12th custom rule.
|
|
||||||
|
|
||||||
Each rule is based on a length and circumferential criteria. If any two anomalies have a horizontal
|
|
||||||
separation less than the length criteria and a circumferential separation less than the circumferential
|
|
||||||
criteria the should be clustered.
|
|
||||||
|
|
||||||
The rules are details in the table below.
|
|
||||||
|
|
||||||
| Rule no. | Length Criteria | Circumferential Criteria |
|
|
||||||
| -------- | ------------------------------------------- | ------------------------------------------- |
|
|
||||||
| Rule 1 | Minimum (L1,L2) | Minimum (W1,W2) |
|
|
||||||
| Rule 2 | Minimum (6*wall thickness, Minimum (L1,L2)) | Minimum (6*wall thickness, Minimum (W1,W2)) |
|
|
||||||
| Rule 3 | Minimum (wall thickness, Minimum (L1,L2)) | Minimum (wall thickness, Minimum (W1,W2)) |
|
|
||||||
| Rule 4 | Minimum (L1,L2) | Minimum (wall thickness, Minimum (W1,W2)) |
|
|
||||||
| Rule 5 | Average (L1,L2) | Average (W1,W2) |
|
|
||||||
| Rule 6 | Wall thickness | Wall thickness |
|
|
||||||
| Rule 7 | 3*Wall thickness | 3*Wall thickness |
|
|
||||||
| Rule 8 | 2*Minimum (L1,L2) | 2*Minimum (W1,W2) |
|
|
||||||
| Rule 9 | Minimum (6*wall thickness, Average (L1,L2)) | Minimum (6*wall thickness, Average (W1,W2)) |
|
|
||||||
| Rule 10 | 1 inch = 25.4 mm | 6*wall thickness |
|
|
||||||
| Rule 11 | 1 inch = 25.4 mm | (3 × MAOP × OD) / (SF × SMYS × WJF) |
|
|
||||||
| Rule 12 | User Configurations | User Configurations |
|
|
||||||
|
|
||||||
|
|
||||||
## Input
|
|
||||||
|
|
||||||
### Arguments
|
|
||||||
|
|
||||||
- `org_id`: as string which should be a valid `uuid` for the organization
|
|
||||||
- `project_id`: the id of the data project where the pipeline data is found
|
|
||||||
- `pipeline_id`: an `array` of `strings` which should be valid UUIDs for pipelines
|
|
||||||
- `size_settings`: a string representing the size setting for clustering, possible values
|
|
||||||
- `original`
|
|
||||||
- `tolerance`
|
|
||||||
- `interaction`: a string representing the interaction setting for clustering, possible values
|
|
||||||
- `enabled`
|
|
||||||
- `disabled`
|
|
||||||
- `surface_location`: a string representing the surface location setting for clustering, possible values
|
|
||||||
- `matching`
|
|
||||||
- `any`
|
|
||||||
- `rule`: a string representing the clustering rule to use, possible values
|
|
||||||
- `rule1`
|
|
||||||
- `rule2`
|
|
||||||
- `rule3`
|
|
||||||
- `rule4`
|
|
||||||
- `rule5`
|
|
||||||
- `rule6`
|
|
||||||
- `rule7`
|
|
||||||
- `rule8`
|
|
||||||
- `rule9`
|
|
||||||
- `rule10`
|
|
||||||
- `rule11`
|
|
||||||
|
|
||||||
## Creating the function on the platform
|
|
||||||
|
|
||||||
To create this function on the platform using the `cli` set up the port forwarding as shown in README.
|
|
||||||
|
|
||||||
Then run the following command to create the function.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run functions create \
|
|
||||||
-f functions/ili_clustering \
|
|
||||||
-d "Runs the ILI clustering algorithm" \
|
|
||||||
-i org_id=string \
|
|
||||||
-i project_id=string \
|
|
||||||
-i pipeline_id=array \
|
|
||||||
-i ili_id=array \
|
|
||||||
-i size_settings=string \
|
|
||||||
-i interaction=string \
|
|
||||||
-i surface_location=string \
|
|
||||||
-i rule=string
|
|
||||||
```
|
|
||||||
|
|
||||||
## Testing the function locally
|
|
||||||
|
|
||||||
You can run and test the function locally by running
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run
|
|
||||||
```
|
|
||||||
|
|
||||||
Then you can check it work with `curl` as follows
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl localhost:8080 -d $(jq '. | tojson' functions/ili_clustering/example_input.json)
|
|
||||||
```
|
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"ili_id": [
|
|
||||||
"d0dd7c6b-6c54-4149-b46c-5e5b033fe6dd"
|
|
||||||
],
|
|
||||||
"interaction": "disabled",
|
|
||||||
"org_id": "2cbfe270-d195-48ad-aed1-24145924635c",
|
|
||||||
"pipeline_id": [
|
|
||||||
"01966d47-1d4c-7751-a1f1-0617caa3a00d"
|
|
||||||
],
|
|
||||||
"project_id": "680b61b0aedd6f9e639d8699",
|
|
||||||
"rule": "rule1",
|
|
||||||
"size_settings": "original",
|
|
||||||
"surface_location": "matching"
|
|
||||||
}
|
|
||||||
141
src/main.rs
141
src/main.rs
@ -1,141 +0,0 @@
|
|||||||
use fathom_function::tracing;
|
|
||||||
use pipeline_application::application::{
|
|
||||||
AnomalySizeSetting, Application, ClusteringConfig, Interaction as ClusteringInteraction,
|
|
||||||
Rule as ClusteringRule, SurfaceLocationSensitivity,
|
|
||||||
};
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
#[fathom_function::function]
|
|
||||||
async fn ili_clustering(input: Input) -> Result<Output, String> {
|
|
||||||
let app = Application::new_from_compile_env(input.org_id, input.project_id).unwrap();
|
|
||||||
|
|
||||||
for (pipeline_id, ili_id) in input.pipeline_id.into_iter().zip(input.ili_id) {
|
|
||||||
app.ili_clustering(pipeline_id, ili_id, &input.config)
|
|
||||||
.await
|
|
||||||
.map_err(|err| {
|
|
||||||
tracing::error!(%pipeline_id, %ili_id, ?err, "Error running clustering algorithm");
|
|
||||||
format!("{err:?}")
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Output {
|
|
||||||
status: "Success".to_owned(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
|
||||||
struct Output {
|
|
||||||
status: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
enum Rule {
|
|
||||||
Rule1,
|
|
||||||
Rule2,
|
|
||||||
Rule3,
|
|
||||||
Rule4,
|
|
||||||
Rule5,
|
|
||||||
Rule6,
|
|
||||||
Rule7,
|
|
||||||
Rule8,
|
|
||||||
Rule9,
|
|
||||||
Rule10,
|
|
||||||
Rule11,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
enum SizeSettings {
|
|
||||||
Original,
|
|
||||||
Tolerance,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum Interaction {
|
|
||||||
Enabled,
|
|
||||||
Disabled,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Deserialize)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum SurfaceLocation {
|
|
||||||
Matching,
|
|
||||||
Any,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
struct Input {
|
|
||||||
org_id: Uuid,
|
|
||||||
project_id: String,
|
|
||||||
pipeline_id: Vec<Uuid>,
|
|
||||||
ili_id: Vec<Uuid>,
|
|
||||||
#[serde(flatten)]
|
|
||||||
config: Config,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
struct Config {
|
|
||||||
size_settings: SizeSettings,
|
|
||||||
interaction: Interaction,
|
|
||||||
surface_location: SurfaceLocation,
|
|
||||||
rule: Rule,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Rule> for ClusteringRule {
|
|
||||||
fn from(value: Rule) -> Self {
|
|
||||||
match value {
|
|
||||||
Rule::Rule1 => Self::Rule1,
|
|
||||||
Rule::Rule2 => Self::Rule2,
|
|
||||||
Rule::Rule3 => Self::Rule3,
|
|
||||||
Rule::Rule4 => Self::Rule4,
|
|
||||||
Rule::Rule5 => Self::Rule5,
|
|
||||||
Rule::Rule6 => Self::Rule6,
|
|
||||||
Rule::Rule7 => Self::Rule7,
|
|
||||||
Rule::Rule8 => Self::Rule8,
|
|
||||||
Rule::Rule9 => Self::Rule9,
|
|
||||||
Rule::Rule10 => Self::Rule10,
|
|
||||||
Rule::Rule11 => Self::Rule11,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SizeSettings> for AnomalySizeSetting {
|
|
||||||
fn from(value: SizeSettings) -> Self {
|
|
||||||
match value {
|
|
||||||
SizeSettings::Original => Self::Original,
|
|
||||||
SizeSettings::Tolerance => Self::WithTolerance,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<SurfaceLocation> for SurfaceLocationSensitivity {
|
|
||||||
fn from(value: SurfaceLocation) -> Self {
|
|
||||||
match value {
|
|
||||||
SurfaceLocation::Matching => Self::Matching,
|
|
||||||
SurfaceLocation::Any => Self::Any,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Interaction> for ClusteringInteraction {
|
|
||||||
fn from(value: Interaction) -> Self {
|
|
||||||
match value {
|
|
||||||
Interaction::Enabled => Self::Enabled,
|
|
||||||
Interaction::Disabled => Self::Disabled,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Config> for ClusteringConfig {
|
|
||||||
fn from(value: &Config) -> Self {
|
|
||||||
Self {
|
|
||||||
interaction: value.interaction.into(),
|
|
||||||
surface_location: value.surface_location.into(),
|
|
||||||
size_settings: value.size_settings.into(),
|
|
||||||
rule: value.rule.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user