use super::helpers;
use super::{GlobalConfiguration, Subcommand};
use anyhow::Result;
use clap::{Args, Parser, ValueHint};
use pineappl::boc::Kinematics;
use pineappl::subgrid::{Subgrid as _, SubgridEnum};
use prettytable::{cell, row};
use std::path::PathBuf;
use std::process::ExitCode;
#[derive(Args)]
#[group(required = true)]
struct Group {
#[arg(long = "type")]
type_: bool,
#[arg(long, require_equals = true, value_delimiter = ',', value_name = "IDX")]
scale: Vec<usize>,
#[arg(long, require_equals = true, value_delimiter = ',', value_name = "IDX")]
x: Vec<usize>,
#[arg(long)]
stats: bool,
}
#[derive(Parser)]
pub struct Opts {
#[arg(value_hint = ValueHint::FilePath)]
input: PathBuf,
#[arg(long)]
show_empty: bool,
#[command(flatten)]
group: Group,
#[arg(default_value_t = 3, long)]
digits: usize,
}
impl Subcommand for Opts {
fn run(&self, _: &GlobalConfiguration) -> Result<ExitCode> {
let grid = helpers::read_grid(&self.input)?;
let mut table = helpers::create_table();
let mut titles = row![c => "o", "b", "c"];
if self.group.type_ {
titles.add_cell(cell!(c->"type"));
}
for index in &self.group.scale {
titles.add_cell(cell!(c->format!("scale{index}")));
}
for index in &self.group.x {
titles.add_cell(cell!(c->format!("x{index}")));
}
if self.group.stats {
titles.add_cell(cell!(c->"total"));
titles.add_cell(cell!(c->"allocated"));
titles.add_cell(cell!(c->"zeros"));
titles.add_cell(cell!(c->"overhead"));
}
table.set_titles(titles);
for ((order, bin, channel), subgrid) in grid.subgrids().indexed_iter() {
if !self.show_empty && subgrid.is_empty() {
continue;
}
let row = table.add_empty_row();
row.add_cell(cell!(l->format!("{order}")));
row.add_cell(cell!(l->format!("{bin}")));
row.add_cell(cell!(l->format!("{channel}")));
if self.group.type_ {
row.add_cell(cell!(l->
match subgrid {
SubgridEnum::InterpSubgridV1(_) => "InterpSubgridV1",
SubgridEnum::EmptySubgridV1(_) => "EmptySubgridV1",
SubgridEnum::ImportSubgridV1(_) => "ImportSubgridV1",
}
));
}
for &index in &self.group.scale {
let values: Vec<_> = grid
.kinematics()
.iter()
.zip(subgrid.node_values())
.find_map(|(kin, node_values)| {
matches!(kin, &Kinematics::Scale(idx) if idx == index)
.then_some(node_values)
})
.unwrap()
.into_iter()
.map(|x| format!("{:.*}", self.digits, x))
.collect();
row.add_cell(cell!(l->values.join(", ")));
}
for &index in &self.group.x {
let values: Vec<_> = grid
.kinematics()
.iter()
.zip(subgrid.node_values())
.find_map(|(kin, node_values)| {
matches!(kin, &Kinematics::X(idx) if idx == index).then_some(node_values)
})
.unwrap()
.into_iter()
.map(|x| format!("{:.*e}", self.digits, x))
.collect();
row.add_cell(cell!(l->values.join(", ")));
}
if self.group.stats {
let stats = subgrid.stats();
row.add_cell(cell!(r->stats.total.to_string()));
row.add_cell(cell!(r->stats.allocated.to_string()));
row.add_cell(cell!(r->stats.zeros.to_string()));
row.add_cell(cell!(r->stats.overhead.to_string()));
}
}
table.printstd();
Ok(ExitCode::SUCCESS)
}
}