FdsnPlugs.SourceIdentifier (fdsn_plugs v0.8.3)
View SourceThis modules defines a source identifier type and all logic for validation and manipulation.
Summary
Functions
Builds a list of FDSN source identifiers. The date is parsed. In case of failures, returns {:error, message}. On success, returns a list of FdsnPlugs.SourceIdentifier.
If the stream has multiple values on :net, :sta, :loc or :cha, then the function splits the stream and returns a list of stream. If there is nothing to expand, it returns a list with only the stream given in parameter.
Parse a date from all accepted formats in the FDSN norm.
Splits securely the channel code in 3 parts, even if the channel code is just one or two characters.
This function tests if a channel is correctly specified. If the length is not full, then it should contain a star
Types
@type t() :: %FdsnPlugs.SourceIdentifier{ cha: String.t(), end: DateTime.t(), loc: String.t(), net: String.t(), sta: String.t(), start: DateTime.t() }
An FdsnPlugs.SourceIdentifier describes an NSLC and time boundaries.
Functions
@spec build_list( String.t(), String.t(), String.t(), String.t(), String.t(), String.t() ) :: {:ok, [t()]} | {:error, String.t()}
Builds a list of FDSN source identifiers. The date is parsed. In case of failures, returns {:error, message}. On success, returns a list of FdsnPlugs.SourceIdentifier.
Examples
iex> FdsnPlugs.SourceIdentifier.build_list("FR,RA","*","*","H?Z")
{:ok,
[
%FdsnPlugs.SourceIdentifier{
net: "FR",
sta: "*",
loc: "*",
cha: "H?Z",
start: ~U[1000-01-01 00:00:00Z],
end: ~U[3000-01-01 00:00:00Z]
},
%FdsnPlugs.SourceIdentifier{
net: "RA",
sta: "*",
loc: "*",
cha: "H?Z",
start: ~U[1000-01-01 00:00:00Z],
end: ~U[3000-01-01 00:00:00Z]
}
]}
iex> FdsnPlugs.SourceIdentifier.build_list()
{:error, "Requesting all nslc is not allowed. Provide at least one of net, sta, loc, cha"}
iex> FdsnPlugs.SourceIdentifier.build_list("*", "*", "--", "*")
{:ok,
[
%FdsnPlugs.SourceIdentifier{
net: "*",
sta: "*",
loc: "",
cha: "*",
start: ~U[1000-01-01 00:00:00Z],
end: ~U[3000-01-01 00:00:00Z]
}
]}
iex> FdsnPlugs.SourceIdentifier.build_list("*", "*", " ", "*")
{:ok,
[
%FdsnPlugs.SourceIdentifier{
net: "*",
sta: "*",
loc: "",
cha: "*",
start: ~U[1000-01-01 00:00:00Z],
end: ~U[3000-01-01 00:00:00Z]
}
]}
iex> FdsnPlugs.SourceIdentifier.build_list("*", "*", " ", "*", "2024-01-01", "2025-01-01")
{:ok,
[
%FdsnPlugs.SourceIdentifier{
net: "*",
sta: "*",
loc: "",
cha: "*",
start: ~U[2024-01-01 00:00:00Z],
end: ~U[2025-01-01 00:00:00Z]
}
]}
iex> FdsnPlugs.SourceIdentifier.build_list("*", "STA", " ", "*", "2024-01-01")
{:ok,
[
%FdsnPlugs.SourceIdentifier{
net: "*",
sta: "STA",
loc: "",
cha: "*",
start: ~U[2024-01-01 00:00:00Z],
end: ~U[3000-01-01 00:00:00Z]
}
]}
iex> FdsnPlugs.SourceIdentifier.build_list("*", "STA", " ")
{:ok,
[
%FdsnPlugs.SourceIdentifier{
net: "*",
sta: "STA",
loc: "",
cha: "*",
start: ~U[1000-01-01 00:00:00Z],
end: ~U[3000-01-01 00:00:00Z]
}
]}
iex> FdsnPlugs.SourceIdentifier.build_list("*", "STA")
{:ok,
[
%FdsnPlugs.SourceIdentifier{
net: "*",
sta: "STA",
loc: "*",
cha: "*",
start: ~U[1000-01-01 00:00:00Z],
end: ~U[3000-01-01 00:00:00Z]
}
]}
iex> FdsnPlugs.SourceIdentifier.build_list("XX")
{:ok,
[
%FdsnPlugs.SourceIdentifier{
net: "XX",
sta: "*",
loc: "*",
cha: "*",
start: ~U[1000-01-01 00:00:00Z],
end: ~U[3000-01-01 00:00:00Z]
}
]}
iex> FdsnPlugs.SourceIdentifier.build_list("*", "*", " ", "*", "2024-01-01", "2025-01-0")
If the stream has multiple values on :net, :sta, :loc or :cha, then the function splits the stream and returns a list of stream. If there is nothing to expand, it returns a list with only the stream given in parameter.
Parameters
- stream: a %FdsnPlugs.SourceIdentifier{} structure
Examples
iex> FdsnPlugs.SourceIdentifier.expand_multi_values(%{net: "FR,RA", sta: "CIEL,ABCD", loc: "00,01", cha: "HNZ,HNE"})
[
%{cha: "HNZ", loc: "00", net: "FR", sta: "CIEL"},
%{cha: "HNZ", loc: "00", net: "RA", sta: "CIEL"},
%{cha: "HNZ", loc: "00", net: "FR", sta: "ABCD"},
%{cha: "HNZ", loc: "00", net: "RA", sta: "ABCD"},
%{cha: "HNZ", loc: "01", net: "FR", sta: "CIEL"},
%{cha: "HNZ", loc: "01", net: "RA", sta: "CIEL"},
%{cha: "HNZ", loc: "01", net: "FR", sta: "ABCD"},
%{cha: "HNZ", loc: "01", net: "RA", sta: "ABCD"},
%{cha: "HNE", loc: "00", net: "FR", sta: "CIEL"},
%{cha: "HNE", loc: "00", net: "RA", sta: "CIEL"},
%{cha: "HNE", loc: "00", net: "FR", sta: "ABCD"},
%{cha: "HNE", loc: "00", net: "RA", sta: "ABCD"},
%{cha: "HNE", loc: "01", net: "FR", sta: "CIEL"},
%{cha: "HNE", loc: "01", net: "RA", sta: "CIEL"},
%{cha: "HNE", loc: "01", net: "FR", sta: "ABCD"},
%{cha: "HNE", loc: "01", net: "RA", sta: "ABCD"}
]
@spec parse_date(DateTime.t() | String.t()) :: {:ok, DateTime.t(), integer()} | {:error, atom()}
Parse a date from all accepted formats in the FDSN norm.
- just a date
- a date with time separated by T All dates are assumed to be UTC Return a tupple {:ok, DateTime} or {:error, "error message"}
Examples
FDSN supported:
iex> FdsnPlugs.SourceIdentifier.parse_date("2023-01-01")
{:ok, ~U[2023-01-01 00:00:00Z], 0}
iex> FdsnPlugs.SourceIdentifier.parse_date("2023-01-01T23:59:59")
{:ok, ~U[2023-01-01 23:59:59Z], 0}
iex> FdsnPlugs.SourceIdentifier.parse_date("2023-01-01T23:59:59.999000")
{:ok, ~U[2023-01-01 23:59:59.999000Z], 0}Extra formats supported:
iex> FdsnPlugs.SourceIdentifier.parse_date("2023-01-01T23:59:59Z")
{:ok, ~U[2023-01-01 23:59:59Z], 0}
iex> FdsnPlugs.SourceIdentifier.parse_date("2023-01-01T23:59:59.999")
{:ok, ~U[2023-01-01 23:59:59.999Z], 0}
iex> FdsnPlugs.SourceIdentifier.parse_date(~U[2023-01-01 23:59:59.999Z])
{:ok, ~U[2023-01-01 23:59:59.999Z], 0}
iex> FdsnPlugs.SourceIdentifier.parse_date("2023-01-01T23:59:59.999000Z")
{:ok, ~U[2023-01-01 23:59:59.999000Z], 0}Catch errors:
iex> FdsnPlugs.SourceIdentifier.parse_date("2023-02-31T23:59:59.999")
{:error, :invalid_date}
Splits securely the channel code in 3 parts, even if the channel code is just one or two characters.
Examples
iex> FdsnPlugs.SourceIdentifier.split_channel(%FdsnPlugs.SourceIdentifier{cha: "*"})
{:ok, ["*", "*", "*"]}
iex> FdsnPlugs.SourceIdentifier.split_channel(%FdsnPlugs.SourceIdentifier{cha: "HN*"})
{:ok, ["H", "N", "*"]}
iex> FdsnPlugs.SourceIdentifier.split_channel(%FdsnPlugs.SourceIdentifier{cha: "H*"})
{:ok, ["H", "*", "*"]}
iex> FdsnPlugs.SourceIdentifier.split_channel(%FdsnPlugs.SourceIdentifier{cha: "*H"})
{:ok, ["*", "*", "H"]}
iex> FdsnPlugs.SourceIdentifier.split_channel(%FdsnPlugs.SourceIdentifier{cha: "*H*"})
{:ok, ["*", "H", "*"]}
iex> FdsnPlugs.SourceIdentifier.split_channel(%FdsnPlugs.SourceIdentifier{cha: "H"})
{:error, "Missing two characters on channel specification. Did you mean H* ?"}
iex> FdsnPlugs.SourceIdentifier.split_channel(%FdsnPlugs.SourceIdentifier{cha: "HH"})
{:error, "Missing one character on channel specification. Did you mean HH* ?"}
iex> FdsnPlugs.SourceIdentifier.split_channel(%FdsnPlugs.SourceIdentifier{cha: "HHHH"})
{:error, "Channel HHHH has more than 3 characters !"}
This function tests if a channel is correctly specified. If the length is not full, then it should contain a star
Examples
iex> FdsnPlugs.SourceIdentifier.valid_channel?(%FdsnPlugs.SourceIdentifier{cha: "*"})
true
iex> FdsnPlugs.SourceIdentifier.valid_channel?(%FdsnPlugs.SourceIdentifier{cha: "HH"})
false