///|
/// Provenance link from an event result to its source trace.
pub struct EventProvenanceLink {
event_id : String
station : String
channel : String
start_time : Double
end_time : Double
sample_count : Int
processing_plan : String
checksum : String
}
///|
/// Create a provenance link from a processed trace.
pub fn make_event_provenance(
event_id : String,
trace : Trace,
processing_plan : String,
) -> EventProvenanceLink {
{
event_id,
station: trace.station,
channel: trace.channel,
start_time: trace.start_time,
end_time: trace.start_time + trace.duration(),
sample_count: trace.npts(),
processing_plan,
checksum: waveform_checksum(trace.data),
}
}
///|
/// Validate a provenance link against a trace.
pub fn validate_event_provenance(
link : EventProvenanceLink,
trace : Trace,
) -> Result[Unit, String] {
if link.station != trace.station || link.channel != trace.channel {
return Err("provenance station or channel does not match trace")
}
if link.sample_count != trace.npts() {
return Err("provenance sample count does not match trace")
}
if link.checksum != waveform_checksum(trace.data) {
return Err("provenance checksum does not match trace")
}
Ok(())
}
///|
/// Export provenance links for audit storage.
pub fn event_provenance_to_csv(links : Array[EventProvenanceLink]) -> String {
let mut output = "event_id,station,channel,start_time,end_time,sample_count,processing_plan,checksum\n"
for link in links {
output = output +
link.event_id +
"," +
link.station +
"," +
link.channel +
"," +
link.start_time.to_string() +
"," +
link.end_time.to_string() +
"," +
link.sample_count.to_string() +
"," +
link.processing_plan +
"," +
link.checksum +
"\n"
}
output
}
///|
/// Format a provenance link for logs.
pub fn event_provenance_text(link : EventProvenanceLink) -> String {
"event=" +
link.event_id +
" station=" +
link.station +
" channel=" +
link.channel +
" samples=" +
link.sample_count.to_string() +
" checksum=" +
link.checksum +
" plan=" +
link.processing_plan
}