@@ -3,7 +3,7 @@ use cxx::{let_cxx_string, UniquePtr};
33use float_cmp:: approx_eq;
44use lhapdf:: Pdf ;
55use ndarray:: { s, Axis } ;
6- use pineappl:: boc:: { Kinematics , Order } ;
6+ use pineappl:: boc:: { Channel , Kinematics , Order } ;
77use pineappl:: grid:: Grid ;
88use pineappl:: interpolation:: { Interp , InterpMeth , Map , ReweightMeth } ;
99use pineappl:: pids:: PidBasis ;
@@ -111,8 +111,17 @@ pub fn convert_into_applgrid(
111111 bail ! ( "grid has non-consecutive bin limits, which APPLgrid does not support" ) ;
112112 }
113113
114- if grid. convolutions ( ) . len ( ) > 2 {
115- bail ! ( "APPLgrid does not support grids with more than two convolutions" ) ;
114+ match grid. convolutions ( ) {
115+ [ _] => { }
116+ [ a, b] => {
117+ if ( a != b) && ( a. cc ( ) == * b) {
118+ // use charge conjugate to map hadron-anti-hadron grids to use the same single
119+ // convolution function
120+ let index = usize:: from ( a. pid ( ) < 0 ) ;
121+ grid. charge_conjugate ( index) ;
122+ }
123+ }
124+ _ => bail ! ( "APPLgrid does not support grids with more than two convolutions" ) ,
116125 }
117126
118127 // APPLgrid only understands PDG PIDs
@@ -121,7 +130,7 @@ pub fn convert_into_applgrid(
121130 let non_trivial_factors = grid
122131 . channels ( )
123132 . iter ( )
124- . flat_map ( |channel| channel . entry ( ) )
133+ . flat_map ( Channel :: entry)
125134 . any ( |& ( _, factor) | !approx_eq ! ( f64 , factor, 1.0 , ulps = 4 ) ) ;
126135
127136 // APPLgrid doesn't support non-trivial factors
@@ -156,9 +165,16 @@ pub fn convert_into_applgrid(
156165 . collect ( ) ;
157166
158167 // `id` must end with '.config' for APPLgrid to know its type is `lumi_pdf`
159- let id = "PineAPPL-Lumi.config" ;
168+ let id = format ! (
169+ "{}.config" ,
170+ output
171+ . file_stem( )
172+ // UNWRAP: because we write to that file in the end, there always must be a file name
173+ . unwrap( )
174+ . to_string_lossy( )
175+ ) ;
160176 // this object is managed by APPLgrid internally
161- ffi:: make_lumi_pdf ( id, & combinations) . into_raw ( ) ;
177+ ffi:: make_lumi_pdf ( & id, & combinations) . into_raw ( ) ;
162178
163179 let limits: Vec < _ > = grid
164180 . bwfl ( )
@@ -200,17 +216,17 @@ pub fn convert_into_applgrid(
200216 - lo_alphas;
201217
202218 let mut applgrid =
203- ffi:: make_empty_grid ( & limits, id, lo_alphas. into ( ) , loops. into ( ) , "f2" , "h0" ) ;
219+ ffi:: make_empty_grid ( & limits, & id, lo_alphas. into ( ) , loops. into ( ) , "f2" , "h0" ) ;
204220
205- let has_pdf1 = !grid . convolutions ( ) . is_empty ( ) ;
206- let has_pdf2 = grid. convolutions ( ) . get ( 1 ) . is_some ( ) ;
221+ // APPLgrid has either two or one convolution(s)
222+ let convolutions = grid. convolutions ( ) . len ( ) ;
207223
208- for ( appl_order , order) in order_mask
224+ for order in order_mask
209225 . iter ( )
210226 . enumerate ( )
211227 . filter_map ( |( index, keep) | keep. then_some ( index) )
212- . enumerate ( )
213228 {
229+ let appl_order = grid. orders ( ) [ order] . alphas - lo_alphas;
214230 let factor = TAU . powi ( grid. orders ( ) [ order] . alphas . into ( ) ) ;
215231
216232 for ( bin, subgrids) in grid
@@ -275,9 +291,7 @@ pub fn convert_into_applgrid(
275291 } )
276292 . collect :: < Result < _ > > ( ) ?;
277293
278- // in the DIS case APPLgrid always uses the first x dimension
279-
280- let ( x1_grid, x2_grid) = if has_pdf1 && has_pdf2 {
294+ let ( x1_grid, x2_grid) = if convolutions == 2 {
281295 (
282296 grid. kinematics ( )
283297 . iter ( )
@@ -298,26 +312,13 @@ pub fn convert_into_applgrid(
298312 // TODO: convert this into an error
299313 . unwrap ( ) ,
300314 )
301- } else if has_pdf1 {
302- (
303- grid. kinematics ( )
304- . iter ( )
305- . zip ( subgrid. node_values ( ) )
306- . find_map ( |( kin, node_values) | {
307- matches ! ( kin, & Kinematics :: X ( idx) if idx == 0 )
308- . then_some ( node_values)
309- } )
310- // TODO: convert this into an error
311- . unwrap ( ) ,
312- Vec :: new ( ) ,
313- )
314315 } else {
315316 (
316317 grid. kinematics ( )
317318 . iter ( )
318319 . zip ( subgrid. node_values ( ) )
319320 . find_map ( |( kin, node_values) | {
320- matches ! ( kin, & Kinematics :: X ( idx) if idx == 1 )
321+ matches ! ( kin, & Kinematics :: X ( idx) if idx == 0 )
321322 . then_some ( node_values)
322323 } )
323324 // TODO: convert this into an error
@@ -376,7 +377,7 @@ pub fn convert_into_applgrid(
376377 weightgrid. as_mut ( ) ,
377378 appl_q2_idx,
378379 appl_x1_idx[ indices[ 1 ] ] ,
379- if has_pdf1 && has_pdf2 {
380+ if convolutions == 2 {
380381 appl_x2_idx[ indices[ 2 ] ]
381382 } else {
382383 0
@@ -394,7 +395,7 @@ pub fn convert_into_applgrid(
394395 unsafe {
395396 applgrid. pin_mut ( ) . add_igrid (
396397 bin. try_into ( ) . unwrap ( ) ,
397- appl_order. try_into ( ) . unwrap ( ) ,
398+ appl_order. into ( ) ,
398399 igrid. into_raw ( ) ,
399400 ) ;
400401 }
0 commit comments