FdsnPlugs.SourceIdentifier (fdsn_plugs v0.8.3)

View Source

This modules defines a source identifier type and all logic for validation and manipulation.

Summary

Types

t()

An FdsnPlugs.SourceIdentifier describes an NSLC and time boundaries.

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

t()

@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

build_list(net \\ "*", sta \\ "*", loc \\ "*", cha \\ "*", starttime \\ "1000-01-01", endtime \\ "3000-01-01")

@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")

expand_multi_values(stream)

@spec expand_multi_values(t()) :: [t()]

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"}
]

parse_date(d)

@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}

split_channel(s)

@spec split_channel(t()) :: {:ok, [...]} | {:error, String.t()}

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 !"}

valid_channel?(sid)

@spec valid_channel?(t()) :: boolean()

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