Update tools

This commit is contained in:
Joshua Coles 2023-03-17 18:58:03 +00:00
parent be00b21905
commit b0b1a4ce43
4 changed files with 56 additions and 37 deletions

View File

@ -4,6 +4,7 @@ use bevy::tasks::ParallelSlice;
use crate::system::spaces::square_grid::{Grid2D, Grid3D};
use itertools::{Itertools, MinMaxResult};
use clap::Parser;
use serde::Serialize;
use crate::BoxCountCli;
use crate::cli::cli::OutputFormat;
use crate::system::{GriddedPosition, Position};
@ -15,30 +16,30 @@ fn bb(data: &Vec<Grid2D>) -> ((i32, i32), (i32, i32)) {
.iter().minmax_by(|a, b| a.x.cmp(&b.x));
let y = data
.iter().minmax_by(|a, b| a.x.cmp(&b.x));
.iter().minmax_by(|a, b| a.y.cmp(&b.y));
match (x, y) {
(MinMaxResult::MinMax(min_x, max_x), MinMaxResult::MinMax(min_y, max_y)) => {
((min_x.x, min_y.y), (max_x.x, max_y.y))
},
}
_ => panic!("Cannot determine bounding box")
}
}
fn box_count_2d(data: &Vec<Grid2D>, box_number: u32) -> usize {
let n = data.len();
let ((x_min, x_max), (y_min, y_max)) = bb(data);
fn box_count_2d(data: &Vec<Grid2D>, box_number: u32) -> (f64, usize) {
let ((x_min, y_min), (x_max, y_max)) = bb(data);
let x_range = (x_max - x_min) as f64;
let y_range = (y_max - y_min) as f64;
let w: f64 = x_range / (box_number as f64);
data.iter()
.map(|Grid2D { x, y }| [((x - x_min) as f64 / w) as u32, ((y - y_min) as f64 / w) as u32])
let boxes_occupied = data.iter()
.map(|Grid2D { x, y }| [((x - x_min) as f64 / w) as i32, ((y - y_min) as f64 / w) as i32])
.unique()
.count()
.count();
(w, boxes_occupied)
}
fn box_count_3d(data: &Vec<Grid3D>, size: u32) -> usize {
@ -110,6 +111,25 @@ fn box_count_nd<const N: usize>(data: &Vec<[f32; N]>, size: u32) -> usize {
.count();
}
pub fn main(cli: &BoxCountCli) {
let particles = read(&cli.path, cli.format);
#[derive(Serialize)]
struct FDRow {
w: f64,
n_occupied: usize,
}
pub(crate) fn main(cli: &BoxCountCli) {
let particles: Vec<Grid2D> = read(&cli.path, cli.format);
let n_particles = dbg!(particles.len());
let box_side_counts = 1..500;
let mut writer = csv::Writer::from_path(&cli.output)
.expect("Unable to create csv");
box_side_counts
.map(|box_side_count| box_count_2d(&particles, box_side_count))
// .filter(|(w, n_occupied)| *n_occupied < n_particles) // Remove saturated values
.map(|(w, n_occupied)| FDRow { w, n_occupied })
.for_each(|row| writer.serialize(row).expect("Failed to write row"));
writer.flush().unwrap();
}

View File

@ -1,3 +1,4 @@
use std::fs::File;
use std::path::Path;
use serde::de::DeserializeOwned;
use crate::cli::cli::OutputFormat;

View File

@ -12,8 +12,10 @@ use serde::de::DeserializeOwned;
use serde::Deserialize;
use svg::Node;
use svg::node::element::Rectangle;
use crate::RenderCli;
use crate::system::Position;
use crate::system::spaces::hexagonal::HexPosition;
use crate::tools::read;
#[derive(Debug, Parser)]
struct Args {
@ -60,30 +62,10 @@ impl ToSvg for HexPosition {
}
}
fn read_json<T: Position>(args: &Args) -> Vec<T> where T: DeserializeOwned {
serde_json::from_reader::<_, Vec<HistoryLine<T>>>(File::open(&args.path).expect("Failed to open file"))
.expect("Failed to read json")
.iter()
.map(|l| (l.position.clone()))
.collect::<Vec<_>>()
}
pub(crate) fn main(args: &RenderCli) {
let positions: Vec<Grid2D> = read::<Grid2D>(&args.path, args.format);
fn read_csv<T: Position>(args: &Args) -> Vec<T> where T: DeserializeOwned {
csv::Reader::from_path(&args.path).expect("Failed to read positions csv").deserialize::<T>()
.collect::<Result<Vec<T>, _>>()
.unwrap()
}
fn main() {
let args = Args::parse();
dbg!(&args);
let positions: Vec<Grid2D> = match args.format {
OutputFormat::FullDataJson => read_json::<Grid2D>(&args),
OutputFormat::Positions => read_csv::<Grid2D>(&args),
};
let size: i32 = 800;
let size: i32 = args.image_size as i32;
let max_x = positions.iter().max_by(|a, b| a.x.abs().cmp(&b.x.abs())).unwrap().x.abs();
let max_y = positions.iter().max_by(|a, b| a.y.abs().cmp(&b.y.abs())).unwrap().y.abs();
let max_size = max_x.max(max_y) * size;
@ -105,5 +87,5 @@ fn main() {
svg.append(position.to_svg(size));
}
svg::write(File::create(args.output).unwrap(), &svg).unwrap();
svg::write(File::create(&args.output).unwrap(), &svg).unwrap();
}

View File

@ -2,7 +2,7 @@
#![feature(let_chains)]
use std::fs::File;
use std::path::{Path, PathBuf};
use std::path::PathBuf;
use anyhow::Context;
use crate::cli::cli::OutputFormat;
use crate::system::model::HistoryLine;
@ -25,9 +25,24 @@ enum ToolsCli {
BoxCount(BoxCountCli)
}
#[derive(clap::ValueEnum, Clone, Debug, Copy)]
enum Space {
Grid2D,
}
#[derive(Debug, Args)]
struct RenderCli {
#[arg(value_enum, short, long, default_value_t = OutputFormat::Positions)]
format: OutputFormat,
#[arg(value_enum, short, long, default_value_t = Space::Grid2D)]
space: Space,
path: PathBuf,
output: PathBuf,
#[arg(short, long, default_value_t = 800)]
image_size: u32,
}
#[derive(Debug, Args)]
@ -35,6 +50,7 @@ struct BoxCountCli {
#[arg(value_enum, short, long, default_value_t = OutputFormat::Positions)]
format: OutputFormat,
path: PathBuf,
output: PathBuf,
}
fn main() {
@ -42,7 +58,7 @@ fn main() {
dbg!(&args);
match args {
ToolsCli::Render(_) => {}
ToolsCli::Render(cli) => tools::render::main(&cli),
ToolsCli::BoxCount(cli) => tools::boxcount::main(&cli),
}
}