Commit dc400d5620c31401c560fd81cdaed79abad7e503

Authored by L. Tibaldo
1 parent e55c60c7

ported residual computation to obsutils

cscripts/csresmap.py
... ... @@ -19,9 +19,9 @@
19 19 #
20 20 # ==========================================================================
21 21 import sys
22   -import math
23 22 import gammalib
24 23 import ctools
  24 +from cscripts import obsutils
25 25  
26 26  
27 27 # ============== #
... ... @@ -209,67 +209,15 @@ class csresmap(ctools.csobservation):
209 209 # Get model map into GSkyMap object
210 210 modelmap = model.cube().counts().copy()
211 211  
212   - # Store counts map as residual map. Note that we need a special
  212 + # Calculate residual maps
  213 + # Note that we need a special
213 214 # construct here to avoid memory leaks. This seems to be a SWIG feature
214 215 # as SWIG creates a new object when calling binning.cube()
215   - self._resmap = countmap.copy()
216   - self._resmap.stack_maps()
  216 + countmap1 = countmap.copy()
  217 + countmap1.stack_maps()
  218 + print("TEST",countmap1.classname())
217 219 modelmap.stack_maps()
218   -
219   - # Get residual map algorithm type
220   - algorithm = self['algorithm'].string()
221   -
222   - # Subtract maps
223   - if algorithm == 'SUB':
224   - self._resmap -= modelmap
225   -
226   - # Subtract and divide by model map
227   - elif algorithm == 'SUBDIV':
228   - self._resmap -= modelmap
229   - self._resmap /= modelmap
230   -
231   - # Subtract and divide by sqrt of model map
232   - elif algorithm == 'SUBDIVSQRT':
233   - self._resmap -= modelmap
234   - self._resmap /= modelmap.sqrt()
235   -
236   - # Calculate significance from Li&Ma derivation
237   - elif algorithm == 'SIGNIFICANCE':
238   -
239   - # Compute sign map
240   - signmap = (self._resmap - modelmap).sign()
241   -
242   - # Loop over every bin in the map
243   - for i in range(self._resmap.npix()):
244   -
245   - # If the model value > 0.0 do the computation as normal ...
246   - model_val = modelmap[i]
247   - if model_val > 0.0:
248   -
249   - # If the data value is also > 0 then compute the
250   - # significance^2 and save it to the map ...
251   - data_val = self._resmap[i]
252   - if data_val > 0.0:
253   - log_val = math.log(data_val/model_val)
254   - self._resmap[i] = (data_val*log_val) + model_val - data_val
255   -
256   - # ... otherwise compute the reduced value of the above
257   - # expression. This is necessary to avoid computing log(0).
258   - else:
259   - self._resmap[i] = model_val
260   -
261   - # ... otherwise hard-code the significance to 0
262   - else:
263   - self._resmap[i] = 0.0
264   -
265   - # Compute significance map
266   - self._resmap *= 2.0
267   - self._resmap = self._resmap.sqrt()
268   - self._resmap = self._resmap * signmap
269   -
270   - # Raise exception if algorithm is unknown
271   - else:
272   - raise TypeError('Algorithm "'+algorithm+'" not known')
  220 + self._resmap = obsutils.residuals(self,countmap1,modelmap)
273 221  
274 222 # Optionally publish map
275 223 if self['publish'].boolean():
... ...
cscripts/obsutils.py
... ... @@ -828,3 +828,92 @@ def get_onoff_obs(cls, obs):
828 828  
829 829 # Return On/Off oberservation container
830 830 return onoff_obs
  831 +
  832 +# ========================================= #
  833 +# Calculate residuals from counts and model #
  834 +# ========================================= #
  835 +def residuals(cls,counts,model):
  836 + """
  837 + Calculate residuals given counts and models,
  838 + according to algorithm specified by user.
  839 + Can handle GSkyMap or GNdarray objects
  840 + :param cls: `~ctools.cscript`
  841 + cscript class
  842 + :param counts: `~gammalib.GSkyMap/~gammalib.GNdarray' data counts
  843 + :param model: `~gammalib.GSkyMap/~gammalib.GNdarray' model counts
  844 + :return residuals: `~gammalib.GSkyMap/~gammalib.GNdarray' residuals
  845 + """
  846 + # Find type of objects we are manipulating
  847 + # and set size to iterate later
  848 +
  849 + # If GNdarray
  850 + if counts.classname() == 'GNdarray':
  851 + nelem = counts.size()
  852 + elif counts.classname() == 'GSkyMap':
  853 + nelem = counts.npix()
  854 + else:
  855 + msg = 'obsutils.residuals only handles ' \
  856 + + 'GNdarray or GSkyMap objects.\n'
  857 + raise RuntimeError(msg)
  858 +
  859 + # Copy counts to initialise residuals
  860 + residuals = counts.copy()
  861 +
  862 + # Get residual map algorithm type
  863 + algorithm = cls['algorithm'].string()
  864 +
  865 + # Subtract
  866 + if algorithm == 'SUB':
  867 + residuals -= model
  868 +
  869 + # Subtract and divide by model
  870 + elif algorithm == 'SUBDIV':
  871 + residuals -= model
  872 + residuals /= model
  873 +
  874 + # Subtract and divide by sqrt of model
  875 + elif algorithm == 'SUBDIVSQRT':
  876 + residuals -= model
  877 + residuals /= model.sqrt()
  878 +
  879 + # Calculate significance from Li&Ma
  880 + elif algorithm == 'SIGNIFICANCE':
  881 +
  882 + # Compute sign
  883 + sign = (residuals - model).sign()
  884 +
  885 + # Loop over every bin
  886 + for i in range(nelem):
  887 +
  888 + # If the model value > 0.0 do the computation as normal ...
  889 + model_val = model[i]
  890 + if model_val > 0.0:
  891 +
  892 + # If the data value is also > 0 then compute the
  893 + # significance^2 and save it ...
  894 + data_val = residuals[i]
  895 + if data_val > 0.0:
  896 + log_val = math.log(data_val / model_val)
  897 + residuals[i] = (
  898 + data_val * log_val) + model_val - data_val
  899 +
  900 + # ... otherwise compute the reduced value of the above
  901 + # expression. This is necessary to avoid computing log(0).
  902 + else:
  903 + residuals[i] = model_val
  904 +
  905 + # ... otherwise hard-code the significance to 0
  906 + else:
  907 + residuals[i] = 0.0
  908 +
  909 + # Compute significance map
  910 + residuals *= 2.0
  911 + residuals = residuals.sqrt()
  912 + residuals = residuals * sign
  913 +
  914 + # Raise exception if algorithm is unknown
  915 + else:
  916 + raise TypeError('Algorithm "' + algorithm + '" not known')
  917 +
  918 + # Return
  919 + return residuals
831 920 \ No newline at end of file
... ...