55import array
66import tempfile
77import os
8+ import math
89from ctypes import c_char_p
910from hepdata_converter .writers .utils import error_value_processor
1011
@@ -55,31 +56,36 @@ def _create_empty_hist(self, dependent_var_title, index, yval):
5556
5657 name = "Hist%sD_y%s_e%s" % (self .dim , self .dependent_variable_index + 1 , index )
5758
58- # order bin values of independent variables
59+ # order bin values of independent variables and check if underflow/overflow bins present
5960 xval_ordered = []
61+ underflow = []
62+ overflow = []
6063 for i in range (self .dim ):
6164 xval_ordered .append ([])
6265 xval_ordered [i ] = sorted (xval [i ])
66+ nbinsi = len (xval_ordered [i ]) - 1
67+ underflow .append (1 if not math .isfinite (xval_ordered [i ][0 ]) else 0 )
68+ overflow .append (1 if not math .isfinite (xval_ordered [i ][nbinsi ]) else 0 )
6369
6470 if 1 == self .dim :
65- nbinsx = len (xval_ordered [0 ]) - 1
66- binsx = array .array ('d' , xval_ordered [0 ])
71+ nbinsx = len (xval_ordered [0 ]) - 1 - underflow [ 0 ] - overflow [ 0 ]
72+ binsx = array .array ('d' , xval_ordered [0 ][ underflow [ 0 ]: nbinsx + 2 ] )
6773 hist = self .get_hist_classes ()[self .dim - 1 ](self .sanitize_name (name ), '' , nbinsx , binsx )
6874
6975 if 2 == self .dim :
70- nbinsx = len (xval_ordered [0 ]) - 1
71- binsx = array .array ('d' , xval_ordered [0 ])
72- nbinsy = len (xval_ordered [1 ]) - 1
73- binsy = array .array ('d' , xval_ordered [1 ])
76+ nbinsx = len (xval_ordered [0 ]) - 1 - underflow [ 0 ] - overflow [ 0 ]
77+ binsx = array .array ('d' , xval_ordered [0 ][ underflow [ 0 ]: nbinsx + 2 ] )
78+ nbinsy = len (xval_ordered [1 ]) - 1 - underflow [ 1 ] - overflow [ 1 ]
79+ binsy = array .array ('d' , xval_ordered [1 ][ underflow [ 1 ]: nbinsy + 2 ] )
7480 hist = self .get_hist_classes ()[self .dim - 1 ](self .sanitize_name (name ), '' , nbinsx , binsx , nbinsy , binsy )
7581
7682 if 3 == self .dim :
77- nbinsx = len (xval_ordered [0 ]) - 1
78- binsx = array .array ('d' , xval_ordered [0 ])
79- nbinsy = len (xval_ordered [1 ]) - 1
80- binsy = array .array ('d' , xval_ordered [1 ])
81- nbinsz = len (xval_ordered [2 ]) - 1
82- binsz = array .array ('d' , xval_ordered [2 ])
83+ nbinsx = len (xval_ordered [0 ]) - 1 - underflow [ 0 ] - overflow [ 0 ]
84+ binsx = array .array ('d' , xval_ordered [0 ][ underflow [ 0 ]: nbinsx + 2 ] )
85+ nbinsy = len (xval_ordered [1 ]) - 1 - underflow [ 1 ] - overflow [ 1 ]
86+ binsy = array .array ('d' , xval_ordered [1 ][ underflow [ 1 ]: nbinsy + 2 ] )
87+ nbinsz = len (xval_ordered [2 ]) - 1 - underflow [ 2 ] - overflow [ 2 ]
88+ binsz = array .array ('d' , xval_ordered [2 ][ underflow [ 2 ]: nbinsz + 2 ] )
8389 hist = self .get_hist_classes ()[self .dim - 1 ](self .sanitize_name (name ), '' , nbinsx , binsx , nbinsy , binsy , nbinsz , binsz )
8490
8591 for i in range (self .dim ):
@@ -105,31 +111,36 @@ def _create_hist(self, xval):
105111 name = "Hist%sD_y%s" % (self .dim , self .dependent_variable_index + 1 )
106112 args = []
107113
108- # order bin values of independent variables
114+ # order bin values of independent variables and check if underflow/overflow bins present
109115 xval_ordered = []
116+ underflow = []
117+ overflow = []
110118 for i in range (self .dim ):
111119 xval_ordered .append ([])
112120 xval_ordered [i ] = sorted (xval [i ])
121+ nbinsi = len (xval_ordered [i ]) - 1
122+ underflow .append (1 if not math .isfinite (xval_ordered [i ][0 ]) else 0 )
123+ overflow .append (1 if not math .isfinite (xval_ordered [i ][nbinsi ]) else 0 )
113124
114125 if 1 == self .dim :
115- nbinsx = len (xval_ordered [0 ]) - 1
116- binsx = array .array ('d' , xval_ordered [0 ])
126+ nbinsx = len (xval_ordered [0 ]) - 1 - underflow [ 0 ] - overflow [ 0 ]
127+ binsx = array .array ('d' , xval_ordered [0 ][ underflow [ 0 ]: nbinsx + 2 ] )
117128 hist = self .get_hist_classes ()[self .dim - 1 ](self .sanitize_name (name ), '' , nbinsx , binsx )
118129
119130 if 2 == self .dim :
120- nbinsx = len (xval_ordered [0 ]) - 1
121- binsx = array .array ('d' , xval_ordered [0 ])
122- nbinsy = len (xval_ordered [1 ]) - 1
123- binsy = array .array ('d' , xval_ordered [1 ])
131+ nbinsx = len (xval_ordered [0 ]) - 1 - underflow [ 0 ] - overflow [ 0 ]
132+ binsx = array .array ('d' , xval_ordered [0 ][ underflow [ 0 ]: nbinsx + 2 ] )
133+ nbinsy = len (xval_ordered [1 ]) - 1 - underflow [ 1 ] - overflow [ 1 ]
134+ binsy = array .array ('d' , xval_ordered [1 ][ underflow [ 1 ]: nbinsy + 2 ] )
124135 hist = self .get_hist_classes ()[self .dim - 1 ](self .sanitize_name (name ), '' , nbinsx , binsx , nbinsy , binsy )
125136
126137 if 3 == self .dim :
127- nbinsx = len (xval_ordered [0 ]) - 1
128- binsx = array .array ('d' , xval_ordered [0 ])
129- nbinsy = len (xval_ordered [1 ]) - 1
130- binsy = array .array ('d' , xval_ordered [1 ])
131- nbinsz = len (xval_ordered [2 ]) - 1
132- binsz = array .array ('d' , xval_ordered [2 ])
138+ nbinsx = len (xval_ordered [0 ]) - 1 - underflow [ 0 ] - overflow [ 0 ]
139+ binsx = array .array ('d' , xval_ordered [0 ][ underflow [ 0 ]: nbinsx + 2 ] )
140+ nbinsy = len (xval_ordered [1 ]) - 1 - underflow [ 1 ] - overflow [ 1 ]
141+ binsy = array .array ('d' , xval_ordered [1 ][ underflow [ 1 ]: nbinsy + 2 ] )
142+ nbinsz = len (xval_ordered [2 ]) - 1 - underflow [ 2 ] - overflow [ 2 ]
143+ binsz = array .array ('d' , xval_ordered [2 ][ underflow [ 2 ]: nbinsz + 2 ] )
133144 hist = self .get_hist_classes ()[self .dim - 1 ](self .sanitize_name (name ), '' , nbinsx , binsx , nbinsy , binsy , nbinsz , binsz )
134145
135146 for i in range (self .dim ):
@@ -246,6 +257,9 @@ def create_objects(self):
246257 if x ['high' ] not in xval [i ]:
247258 xval [i ].append (x ['high' ])
248259
260+ if not any (xval ):
261+ return []
262+
249263 try :
250264 hist = self ._create_hist (xval )
251265 except :
@@ -280,7 +294,7 @@ def match(cls, independent_variables_map, dependent_variable):
280294 return False
281295
282296 def create_objects (self ):
283- self .calculate_total_errors ()
297+ self .calculate_total_errors (for_tgraph = True )
284298
285299 # check that errors are symmetric (within a tolerance to allow for numerical rounding)
286300 tol = 1e-15
@@ -335,7 +349,7 @@ def match(cls, independent_variables_map, dependent_variable):
335349 return False
336350
337351 def create_objects (self ):
338- self .calculate_total_errors ()
352+ self .calculate_total_errors (for_tgraph = True )
339353
340354 if len (self .xval [0 ]):
341355 graph = ROOTModule .TGraphAsymmErrors (len (self .xval [0 ]),
0 commit comments