Skip to content

Commit

Permalink
saving work on nastester
Browse files Browse the repository at this point in the history
  • Loading branch information
Bruno02468 committed Apr 8, 2024
1 parent 02f92c2 commit 048467a
Show file tree
Hide file tree
Showing 8 changed files with 221 additions and 2 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ members = [
"f06",
"f06info",
"f06diff"
, "nas_csv", "f06csv"]
, "nas_csv", "f06csv", "nastester"]
21 changes: 21 additions & 0 deletions f06/src/blocks/indexing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,30 @@ macro_rules! gen_nasindex {
};
}
}

impl NasIndex {
/// Returns the name of the type of this index.
pub fn type_name(&self) -> &'static str {
return match self {
$(Self::$tn(_) => <$tn as IndexType>::INDEX_NAME,)*
};
}
}
};
}

impl NasIndex {
/// Returns the grid point associated with this index, if it has one.
pub fn grid_point_id(&self) -> Option<GridPointRef> {
todo!()
}

/// Returns the element associated with this index, if it has one.
pub fn element_id(&self) -> Option<ElementRef> {
todo!()
}
}

gen_nasindex!(
Dof,
GridPointRef,
Expand Down
1 change: 1 addition & 0 deletions f06/src/f06file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! it, and its submodules are responsible for specific parsing subroutines.
pub mod diff;
pub mod extraction;

use std::collections::{BTreeSet, BTreeMap};

Expand Down
175 changes: 175 additions & 0 deletions f06/src/f06file/extraction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
//! This module implements data structures to specify ways to extract data
//! subsets from F06 files.
use std::error::Error;
use std::fmt::Display;
use std::mem::discriminant;

use serde::{Deserialize, Serialize};

use crate::prelude::*;

/// This specifies a value or sets thereof.
#[derive(
Debug, Clone, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq
)]
pub enum Specifier<A> {
/// Use all in the file.
All,
/// Use a list.
List(Vec<A>),
/// Use an exclusion list.
AllExcept(Vec<A>)
}

impl<A: PartialEq> Specifier<A> {
/// Use this as a filter for an iterator.
fn filter_fn(&self, item: &A) -> bool {
return match self {
Self::All => true,
Self::List(l) => l.contains(item),
Self::AllExcept(l) => !l.contains(item),
};
}
}

/// This is a "full index", it refers to a single datum in an F06 file.
#[derive(
Debug, Copy, Clone, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq
)]
pub struct DatumIndex {
/// The block reference.
pub block_ref: BlockRef,
/// The row.
pub row: NasIndex,
/// The column.
pub col: NasIndex
}

impl DatumIndex {
/// Attempts to get the value at this index from a data block.
pub fn get_from(
&self,
file: &F06File
) -> Result<F06Number, ExtractionError> {
let block = file.block_search(
Some(self.block_ref.block_type),
Some(self.block_ref.subcase),
true
).nth(0).ok_or(ExtractionError::NoSuchBlock(self.block_ref))?;
let ri_ex = block.row_indexes.keys().nth(0)
.ok_or(ExtractionError::BlockIsEmpty)?;
let ci_ex = block.col_indexes.keys().nth(0)
.ok_or(ExtractionError::BlockIsEmpty)?;
if discriminant(&self.row) != discriminant(ri_ex) {
return Err(ExtractionError::RowTypeMismatch {
tried: self.row,
against: *ri_ex
});
}
if discriminant(&self.col) != discriminant(ci_ex) {
return Err(ExtractionError::ColumnTypeMismatch {
tried: self.col,
against: *ci_ex
});
}
if !block.row_indexes.contains_key(&self.row) {
return Err(ExtractionError::MissingRow(self.row));
}
if !block.col_indexes.contains_key(&self.col) {
return Err(ExtractionError::MissingColumn(self.col));
}
return Ok(block.get(self.row, self.col).expect("row & col check failed!"));
}
}

/// This is the kind of error that can be returned when extracting a datum.
#[derive(
Debug, Copy, Clone, Serialize, Deserialize
)]
pub enum ExtractionError {
/// The F06 file has no block matching a subcase and type.
NoSuchBlock(BlockRef),
/// The block was found but there was an index type mismatch for the rows.
RowTypeMismatch {
/// A row index we tried to use.
tried: NasIndex,
/// An example of row index from the block.
against: NasIndex
},
/// The block was found but there was an index type mismatch for the columns.
ColumnTypeMismatch {
/// A column index we tried to use.
tried: NasIndex,
/// An example of column index from the block.
against: NasIndex
},
/// A row index is the correct type but is not part of the matrix.
MissingRow(NasIndex),
/// A column index is the correct type but is not part of the matrix.
MissingColumn(NasIndex),
/// The block has no data.
BlockIsEmpty
}

impl Display for ExtractionError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
return match self {
Self::NoSuchBlock(bref) => write!(
f,
"no such block ({}, subcase {})",
bref.block_type.short_name(),
bref.subcase
),
Self::RowTypeMismatch { tried, against } => write!(
f,
"wrong row type (tried a {}, block uses {})",
tried.type_name(),
against.type_name()
),
Self::ColumnTypeMismatch { tried, against } => write!(
f,
"wrong column type (tried a {}, block uses {})",
tried.type_name(),
against.type_name()
),
Self::MissingRow(ri) => write!(f, "no such row ({})", ri),
Self::MissingColumn(ci) => write!(f, "no such column ({})", ci),
Self::BlockIsEmpty => write!(f, "block is empty")
};
}
}

impl Error for ExtractionError {}

/// This structure represents a way to extract a subset of the data from an F06
/// so one can apply comparison criteria to it.
#[derive(
Debug, Clone, Serialize, Deserialize, PartialOrd, Ord, PartialEq, Eq
)]
pub struct Extraction {
/// Subcases to get data from.
subcases: Specifier<usize>,
/// Block types to get data from.
blocks: Specifier<BlockType>,
/// Grid point filter (filters out grid points if present).
grid_points: Specifier<GridPointRef>,
/// Element filter (filters out element IDs if present).
elements: Specifier<ElementRef>,
/// Row filter (for when you want very specific data).
rows: Specifier<NasIndex>,
/// Column filter (for when you want very specific data).
cols: Specifier<NasIndex>
}

impl Extraction {
/// Produces an iterator over the indices resulting from applying an
/// extraction to a file. This assumes the file has already had its blocks
/// sorted and merged.
pub fn lookup(
&self,
file: &F06File
) -> impl Iterator<Item = F06Number> + '_ {
todo!()
}
}
2 changes: 1 addition & 1 deletion f06csv/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ fn main() -> Result<(), Box<dyn Error>> {
.terminator(term)
.from_writer(output);
/// Filter only if there is at least one in the filter.
fn lax_filter<T: PartialEq>(v: &Vec<T>, x: &Option<T>) -> bool {
fn lax_filter<T: PartialEq>(v: &[T], x: &Option<T>) -> bool {
return v.is_empty()
|| x.is_none()
|| x.as_ref().is_some_and(|k| v.contains(k));
Expand Down
12 changes: 12 additions & 0 deletions nastester/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "nastester"
authors = ["Bruno Borges Paschoalinoto <[email protected]>"]
version = "0.1.0"
edition = "2021"

[dependencies]


[dependencies.f06]
version = "0.3"
path = "../f06"
3 changes: 3 additions & 0 deletions nastester/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}

0 comments on commit 048467a

Please sign in to comment.