Skip to content

Commit 3511cd6

Browse files
committed
Add first version of a fix for #361
1 parent f6ff7c3 commit 3511cd6

3 files changed

Lines changed: 146 additions & 1 deletion

File tree

pineappl/src/grid.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,128 @@ impl Grid {
628628
.for_each(|subgrid| subgrid.scale(factor));
629629
}
630630

631+
/// TODO
632+
///
633+
/// # Errors
634+
///
635+
/// TODO
636+
pub fn reint_node_opt(&mut self) -> Result<bool> {
637+
let mut modified = false;
638+
639+
let self_interpolations = self.interpolations().to_vec();
640+
let grid_node_values: Vec<_> = self_interpolations
641+
.iter()
642+
.map(|interps| interps.node_values())
643+
.collect();
644+
645+
for subgrid in &mut self.subgrids {
646+
if let SubgridEnum::ImportSubgridV1(subgrid) = subgrid {
647+
let node_values = subgrid.node_values();
648+
let mut affected_indices = vec![None; node_values.len()];
649+
650+
for ((values, grid_values), affected) in node_values
651+
.iter()
652+
.zip(&grid_node_values)
653+
.zip(&mut affected_indices)
654+
{
655+
if let Some(index) = values.iter().copied().position(|value| {
656+
!grid_values
657+
.iter()
658+
.find(|&&grid_value| subgrid::node_value_eq(value, grid_value))
659+
.is_some()
660+
}) {
661+
if affected.is_some() {
662+
// TODO: return an error
663+
todo!();
664+
} else {
665+
*affected = Some(index);
666+
}
667+
}
668+
}
669+
670+
if affected_indices.iter().any(Option::is_some) {
671+
// filter out affected node values
672+
let new_node_values: Vec<_> = affected_indices
673+
.iter()
674+
.zip(&node_values)
675+
.map(|(affected, values)| {
676+
if let &Some(index) = affected {
677+
values[..index]
678+
.iter()
679+
.copied()
680+
.chain(values[index + 1..].iter().copied())
681+
.collect()
682+
} else {
683+
values.to_vec()
684+
}
685+
})
686+
.collect();
687+
let mut array = super::packed_array::PackedArray::new(
688+
new_node_values.iter().map(|values| values.len()).collect(),
689+
);
690+
691+
let mut filtered = Vec::new();
692+
693+
for (index, value) in subgrid.indexed_iter() {
694+
let Some(new_index): Option<Vec<_>> = index
695+
.iter()
696+
.copied()
697+
.zip(affected_indices.iter().copied())
698+
.map(|(idx, affected)| {
699+
if let Some(filter) = affected {
700+
if idx < filter {
701+
Some(idx)
702+
} else if idx > filter {
703+
Some(idx - 1)
704+
} else {
705+
None
706+
}
707+
} else {
708+
Some(idx)
709+
}
710+
})
711+
.collect()
712+
else {
713+
filtered.push(index);
714+
continue;
715+
};
716+
717+
array[new_index.as_slice()] = value;
718+
}
719+
720+
let mut subg = InterpSubgridV1::new(&self_interpolations);
721+
let weight = subgrid
722+
.indexed_iter()
723+
.filter_map(|(index, value)| {
724+
filtered
725+
.iter()
726+
.find(|&filter| *filter == index)
727+
.map(|_| value)
728+
})
729+
.sum();
730+
dbg!(weight);
731+
let ntuple: Vec<_> = affected_indices
732+
.iter()
733+
.zip(&node_values)
734+
.map(|(affected, node_value)| affected.map(|index| node_value[index]))
735+
.collect::<Option<_>>()
736+
// TODO: generalize this to include interpolated dimensions
737+
.unwrap();
738+
dbg!(&ntuple);
739+
subg.fill(&self_interpolations, &ntuple, weight);
740+
741+
let mut new_subgrid = ImportSubgridV1::new(array, new_node_values);
742+
new_subgrid.merge_impl(&subg.into(), None);
743+
744+
*subgrid = new_subgrid;
745+
modified = true;
746+
}
747+
}
748+
}
749+
750+
Ok(modified)
751+
}
752+
631753
/// Repair the grid if it was written by bugged versions to disk.
632754
///
633755
/// Returns `true` if this operations did anything. Currently, this scans for these problems:

pineappl_cli/src/write.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ enum OpsArg {
4141
MulBinNorm(f64),
4242
Optimize(bool),
4343
OptimizeFkTable(FkAssumptions),
44+
ReintNodeOpt(bool),
4445
Repair(bool),
4546
RewriteChannel((usize, Channel)),
4647
RewriteOrder((usize, Order)),
@@ -86,7 +87,12 @@ impl FromArgMatches for MoreArgs {
8687
});
8788
}
8889
}
89-
"merge_channel_factors" | "optimize" | "repair" | "split_channels" | "upgrade" => {
90+
"merge_channel_factors"
91+
| "optimize"
92+
| "reint_node_opt"
93+
| "repair"
94+
| "split_channels"
95+
| "upgrade" => {
9096
let arguments: Vec<Vec<_>> = matches
9197
.remove_occurrences(&id)
9298
.unwrap()
@@ -99,6 +105,7 @@ impl FromArgMatches for MoreArgs {
99105
args[index] = Some(match id.as_str() {
100106
"merge_channel_factors" => OpsArg::MergeChannelFactors(arg[0]),
101107
"optimize" => OpsArg::Optimize(arg[0]),
108+
"reint_node_opt" => OpsArg::ReintNodeOpt(arg[0]),
102109
"repair" => OpsArg::Repair(arg[0]),
103110
"split_channels" => OpsArg::SplitChannels(arg[0]),
104111
"upgrade" => OpsArg::Upgrade(arg[0]),
@@ -396,6 +403,17 @@ impl Args for MoreArgs {
396403
.try_map(|s| s.parse::<FkAssumptions>()),
397404
),
398405
)
406+
.arg(
407+
Arg::new("reint_node_opt")
408+
.action(ArgAction::Append)
409+
.default_missing_value("true")
410+
.help("TODO")
411+
.long("reint-node-opt")
412+
.num_args(0..=1)
413+
.require_equals(true)
414+
.value_name("ENABLE")
415+
.value_parser(clap::value_parser!(bool)),
416+
)
399417
.arg(
400418
Arg::new("repair")
401419
.action(ArgAction::Append)
@@ -596,6 +614,9 @@ impl Subcommand for Opts {
596614
// UNWRAP: this cannot fail because we only modify the normalizations
597615
.unwrap();
598616
}
617+
OpsArg::ReintNodeOpt(true) => {
618+
grid.reint_node_opt()?;
619+
}
599620
OpsArg::Repair(true) => {
600621
grid.repair();
601622
}
@@ -635,6 +656,7 @@ impl Subcommand for Opts {
635656
OpsArg::Upgrade(true) => grid.upgrade(),
636657
OpsArg::MergeChannelFactors(false)
637658
| OpsArg::Repair(false)
659+
| OpsArg::ReintNodeOpt(false)
638660
| OpsArg::Optimize(false)
639661
| OpsArg::SplitChannels(false)
640662
| OpsArg::Upgrade(false) => {}

pineappl_cli/tests/write.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Options:
2424
--mul-bin-norm <NORM> Multiply all bin normalizations with the given factor
2525
--optimize[=<ENABLE>] Optimize internal data structure to minimize memory and disk usage [possible values: true, false]
2626
--optimize-fk-table <OPTIMI> Optimize internal data structure of an FkTable to minimize memory and disk usage [possible values: Nf6Ind, Nf6Sym, Nf5Ind, Nf5Sym, Nf4Ind, Nf4Sym, Nf3Ind, Nf3Sym]
27+
--reint-node-opt[=<ENABLE>] TODO [possible values: true, false]
2728
--repair[=<ENABLE>] Repair bugs saved in the grid [possible values: true, false]
2829
--rewrite-channel <IDX> <CHAN> Rewrite the definition of the channel with index IDX
2930
--rewrite-order <IDX> <ORDER> Rewrite the definition of the order with index IDX

0 commit comments

Comments
 (0)