icecube / skyllh

https://icecube.github.io/skyllh/
GNU General Public License v3.0
11 stars 5 forks source link

Error in __str__ method of tdm after calculating source data fields #215

Open juanma-cano-vila opened 5 months ago

juanma-cano-vila commented 5 months ago

After one inicializates and instace of TrialDataManager(), the print function works as expected.

tdm = TrialDataManager()
print(tdm)
TrialDataManager:
    Base data fields:
        None
    Source data fields:
        None
    Pre-event-selection static data fields:
        None
    Static data fields:
        None
    Global fitparam data fields:
        None

After adding the data fields, it still works before initializing them:

tdm.add_source_data_field(
    name='src_array',
    func=pointlikesource_to_data_field_array)
tdm.add_data_field(
    name='psi',
    func=get_tdm_field_func_psi(),
    dt='dec',
    is_srcevt_data=True)

print(tdm)
    Base data fields:
        None
    Source data fields:
        DataField: src_array: {dtype: None, vmin:  nan, vmax:  nan}
    Pre-event-selection static data fields:
        None
    Static data fields:
        DataField: psi: {dtype: None, vmin:  nan, vmax:  nan}
    Global fitparam data fields:
        None

Nevertheless, after calculating the source data fields, it crashes:

tdm.calculate_source_data_fields(shg_mgr=shg_mgr,
                     pmm=pmm,
                     )
print(tdm)
{
    "name": "UFuncTypeError",
    "message": "ufunc 'minimum' did not contain a loop with signature matching types (dtype([('ra', '<f8'), ('dec', '<f8'), ('weight', '<f8')]), dtype([('ra', '<f8'), ('dec', '<f8'), ('weight', '<f8')])) -> None",
    "stack": "---------------------------------------------------------------------------
UFuncTypeError                            Traceback (most recent call last)
Cell In[20], line 1
----> 1 print(tdm)

File ~/LRZ Sync+Share/master_thesis/Projects/stack_analysis_masq_BLLacs/skyllh.stack_public/skyllh/core/trialdata.py:578, in TrialDataManager.__str__(self)
    574 s += '\
'
    576 s1 = 'Source data fields:\
'
    577 s2 = '\
'.join(
--> 578     [
    579         str(df)
    580         for (_, df) in self._source_data_fields_dict.items()
    581     ]
    582 )
    583 if s2 == '':
    584     s2 = 'None'

File ~/LRZ Sync+Share/master_thesis/Projects/stack_analysis_masq_BLLacs/skyllh.stack_public/skyllh/core/trialdata.py:579, in <listcomp>(.0)
    574 s += '\
'
    576 s1 = 'Source data fields:\
'
    577 s2 = '\
'.join(
    578     [
--> 579         str(df)
    580         for (_, df) in self._source_data_fields_dict.items()
    581     ]
    582 )
    583 if s2 == '':
    584     s2 = 'None'

File ~/LRZ Sync+Share/master_thesis/Projects/stack_analysis_masq_BLLacs/skyllh.stack_public/skyllh/core/trialdata.py:195, in DataField.__str__(self)
    193 if self._values is not None:
    194     dtype = str(self._values.dtype)
--> 195     vmin = np.min(self._values)
    196     vmax = np.max(self._values)
    198 s = f'{classname(self)}: {self.name}: '

File ~/envs/SkyLLH/lib/python3.10/site-packages/numpy/core/fromnumeric.py:2953, in min(a, axis, out, keepdims, initial, where)
   2836 @array_function_dispatch(_min_dispatcher)
   2837 def min(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
   2838         where=np._NoValue):
   2839     \"\"\"
   2840     Return the minimum of an array or minimum along an axis.
   2841 
   (...)
   2951     6
   2952     \"\"\"
-> 2953     return _wrapreduction(a, np.minimum, 'min', axis, None, out,
   2954                           keepdims=keepdims, initial=initial, where=where)

File ~/envs/SkyLLH/lib/python3.10/site-packages/numpy/core/fromnumeric.py:88, in _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs)
     85         else:
     86             return reduction(axis=axis, out=out, **passkwargs)
---> 88 return ufunc.reduce(obj, axis, dtype, out, **passkwargs)

UFuncTypeError: ufunc 'minimum' did not contain a loop with signature matching types (dtype([('ra', '<f8'), ('dec', '<f8'), ('weight', '<f8')]), dtype([('ra', '<f8'), ('dec', '<f8'), ('weight', '<f8')])) -> None"
}

The reason seems to be that the str method for DataField objects computes the minimun and maximum value. But for the Source Data Fields we don't have one parameter with a range of values, but rather two parameters with a single value, namely the declination and right ascension. Therefore, when trying to compute the minima on this special case, it crashes.

A possible solution could be to handle this case of source data fields separatedly, but I don't know if the same bug could arise for the other data fields, and therefore a more profound change is better.