use clap::{Args, Parser, Subcommand};
use ndarray::{s, Axis};
use terminal_size::{terminal_size, Width};
#[derive(Parser, Clone)]
pub struct ReadCli {
#[command(subcommand)]
pub command: ReadCommands,
}
#[derive(Subcommand, Clone)]
pub enum ReadCommands {
#[command(name = "metadata")]
Metadata(MetadataArgs),
#[command(name = "num_subgrids")]
NumSubgrids(PdfNameArgs),
#[command(name = "subgrid-info")]
SubgridInfo(SubgridInfoArgs),
#[command(name = "subgrid")]
Subgrid(SubgridArgs),
#[command(name = "git-version")]
GitVersion(PdfNameArgs),
#[command(name = "code-version")]
CodeVersion(PdfNameArgs),
}
#[derive(Args, Clone)]
pub struct MetadataArgs {
pub pdf_name: String,
}
#[derive(Args, Clone)]
pub struct PdfNameArgs {
pub pdf_name: String,
}
#[derive(Args, Clone)]
pub struct SubgridInfoArgs {
pub pdf_name: String,
#[arg(short, long)]
pub member: usize,
#[arg(short, long)]
pub subgrid_index: usize,
}
#[derive(Args, Clone)]
pub struct SubgridArgs {
pub pdf_name: String,
#[arg(short, long, default_value_t = 0)]
pub member: usize,
#[arg(short, long)]
pub subgrid_index: usize,
#[arg(short = 'i', long)]
pub pid: i32,
#[arg(long, default_value_t = 0)]
pub nucleon_index: usize,
#[arg(long, default_value_t = 0)]
pub alphas_index: usize,
#[arg(long, default_value_t = 0)]
pub kt_index: usize,
}
#[allow(clippy::too_many_lines)]
#[allow(clippy::needless_pass_by_value)]
pub fn main(cli: ReadCli) {
match &cli.command {
ReadCommands::Metadata(args) => {
let pdf = neopdf::pdf::PDF::load(&args.pdf_name, 0);
println!("{}", pdf.metadata());
}
ReadCommands::NumSubgrids(args) => {
let pdf = neopdf::pdf::PDF::load(&args.pdf_name, 0);
println!("{}", pdf.num_subgrids());
}
ReadCommands::SubgridInfo(args) => {
let pdf = neopdf::pdf::PDF::load(&args.pdf_name, args.member);
let subgrid = pdf.subgrid(args.subgrid_index);
println!("Nucleon Numbers A: {:?}", subgrid.nucleons);
println!("Alphas values: {:?}", subgrid.alphas);
println!("kT values: {:?}", subgrid.kts);
println!("x values: {:?}", subgrid.xs);
println!("Q2 values: {:?}", subgrid.q2s);
}
ReadCommands::Subgrid(args) => {
let pdf = neopdf::pdf::PDF::load(&args.pdf_name, args.member);
let subgrid = pdf.subgrid(args.subgrid_index);
let pids = pdf.pids();
let pid_to_find = if args.pid == 0 { 21 } else { args.pid };
let pid_idx = pids
.iter()
.position(|&p| p == pid_to_find)
.unwrap_or_else(|| panic!("PID {} not found in the grid.", args.pid));
if subgrid.nucleons.len() > 1 {
println!(
"Displaying grid for Nucleon A = {}",
subgrid.nucleons[args.nucleon_index]
);
}
if subgrid.alphas.len() > 1 {
println!(
"Displaying grid for alpha_s = {}",
subgrid.alphas[args.alphas_index]
);
}
if subgrid.kts.len() > 1 {
println!("Displaying grid for kT = {}", subgrid.kts[args.kt_index]);
}
println!();
let grid_slice = match &subgrid.grid {
neopdf::subgrid::GridData::Grid6D(grid) => grid.slice(s![
args.nucleon_index,
args.alphas_index,
pid_idx,
args.kt_index,
..,
..
]),
neopdf::subgrid::GridData::Grid8D(grid) => {
grid.slice(s![
args.nucleon_index,
args.alphas_index,
0, 0, args.kt_index,
pid_idx,
..,
..
])
}
};
let width = if let Some((Width(w), _)) = terminal_size() {
w as usize
} else {
80 };
let col_width = 13;
let first_col_width = 13;
let num_cols = (width.saturating_sub(first_col_width)) / col_width;
if num_cols == 0 {
println!("Terminal too narrow to display the table.");
return;
}
let q2_chunks = subgrid.q2s.as_slice().unwrap().chunks(num_cols);
let grid_chunks = grid_slice.axis_chunks_iter(Axis(1), num_cols);
for (q2_chunk, grid_chunk) in q2_chunks.zip(grid_chunks) {
print!("{:>12}", "[x | Q2]");
for q2 in q2_chunk {
print!("{q2:>12.5e}");
}
println!();
for (ix, x) in subgrid.xs.iter().enumerate() {
print!("{x:>12.5e}");
for iq2 in 0..q2_chunk.len() {
print!("{:>12.5e}", grid_chunk[[ix, iq2]]);
}
println!();
}
println!();
}
}
ReadCommands::GitVersion(args) => {
let pdf = neopdf::pdf::PDF::load(&args.pdf_name, 0);
println!("{}", pdf.metadata().git_version);
}
ReadCommands::CodeVersion(args) => {
let pdf = neopdf::pdf::PDF::load(&args.pdf_name, 0);
println!("{}", pdf.metadata().code_version);
}
}
}