def _photometricErrors(self, catalog=None, n_per_bin=100):
        """
        Realistic photometric errors estimated from catalog objects and mask.
        Extend below the magnitude threshold with a flat extrapolation.
        """

        if catalog is None:
            # Simple proxy for photometric errors
            release = self.config['data']['release']
            band_1 = self.config['catalog'].get('mag_1_band')
            if not band_1: band_1 = self.config['isochrone']['mag_1_field']
            band_2 = self.config['catalog'].get('mag_2_band')
            if not band_2: band_2 = self.config['isochrone']['mag_2_field']
            
            DELMIN = 0.0
            pars_1 = MAGERR_PARAMS[release][band_1]
            
            def photo_err_1(delta):
                p = pars_1
                return np.clip(np.exp(p[0]*delta+p[1])+p[2], 0, np.exp(p[0]*(DELMIN)+p[1])+p[2])

            pars_2 = MAGERR_PARAMS[release][band_2]
            def photo_err_2(delta):
                p = pars_2
                return np.clip(np.exp(p[0]*delta+p[1])+p[2], 0, np.exp(p[0]*(DELMIN)+p[1])+p[2])

        else:
            catalog.spatialBin(self.roi)

            if len(catalog.mag_1) < n_per_bin:
                logger.warning("Catalog contains fewer objects than requested to calculate errors.")
                #n_per_bin = int(len(catalog.mag_1) / 3)
                return self._photometricErrors(catalog=None)
             
            # Band 1
            mag_1_thresh = self.mask_1.mask_roi_sparse[catalog.pixel_roi_index] - catalog.mag_1
            sorting_indices = np.argsort(mag_1_thresh)
            mag_1_thresh_sort = mag_1_thresh[sorting_indices]
            mag_err_1_sort = catalog.mag_err_1[sorting_indices]
             
            # ADW: Can't this be done with np.median(axis=?)
            mag_1_thresh_medians = []
            mag_err_1_medians = []
            for i in range(0, int(len(mag_1_thresh) / float(n_per_bin))):
                mag_1_thresh_medians.append(np.median(mag_1_thresh_sort[n_per_bin * i: n_per_bin * (i + 1)]))
                mag_err_1_medians.append(np.median(mag_err_1_sort[n_per_bin * i: n_per_bin * (i + 1)]))
             
            if mag_1_thresh_medians[0] > 0.:
                mag_1_thresh_medians = np.insert(mag_1_thresh_medians, 0, -99.)
                mag_err_1_medians = np.insert(mag_err_1_medians, 0, mag_err_1_medians[0])
             
            photo_err_1 = scipy.interpolate.interp1d(mag_1_thresh_medians, mag_err_1_medians,
                                                     bounds_error=False, fill_value=mag_err_1_medians[-1])
             
            # Band 2
            mag_2_thresh = self.mask_2.mask_roi_sparse[catalog.pixel_roi_index] - catalog.mag_2
            sorting_indices = np.argsort(mag_2_thresh)
            mag_2_thresh_sort = mag_2_thresh[sorting_indices]
            mag_err_2_sort = catalog.mag_err_2[sorting_indices]
             
            mag_2_thresh_medians = []
            mag_err_2_medians = []
            for i in range(0, int(len(mag_2_thresh) / float(n_per_bin))):
                mag_2_thresh_medians.append(np.median(mag_2_thresh_sort[n_per_bin * i: n_per_bin * (i + 1)]))
                mag_err_2_medians.append(np.median(mag_err_2_sort[n_per_bin * i: n_per_bin * (i + 1)]))
             
            if mag_2_thresh_medians[0] > 0.:
                mag_2_thresh_medians = np.insert(mag_2_thresh_medians, 0, -99.)
                mag_err_2_medians = np.insert(mag_err_2_medians, 0, mag_err_2_medians[0])
             
            photo_err_2 = scipy.interpolate.interp1d(mag_2_thresh_medians, mag_err_2_medians,
                                                     bounds_error=False, fill_value=mag_err_2_medians[-1])
             
        self.photo_err_1=photo_err_1
        self.photo_err_2=photo_err_2

        return self.photo_err_1, self.photo_err_2