Beispiel #1
0
 def setUp(self):
     # arguments and keywords
     self.test_fits = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                                   'W3+3-2.U.12907_13034_7446_7573.fits')
     # __init__ test
     self.lobject = LensObject(self.test_fits)
     # verbosity
     self.v = {'verbose': 1}
     print("")
     print(self.separator)
     print(self.shortDescription())
Beispiel #2
0
 def test_LensObject(self):
     """ # LensObject """
     print(">>> {}".format(self.test_fits))
     lobject = LensObject(self.test_fits, **self.v)
     self.assertIsInstance(lobject, LensObject)
     self.assertEqual(lobject, self.lobject)
     kwargs = {'auto': True,
               'n': 5,
               'min_q': 0.1,
               'sigma': (1, 3),
               'centroid': 5}
     print(">>> {}, {}".format(self.test_fits, kwargs))
     auto = kwargs.pop('auto')
     lobject = LensObject(self.test_fits, auto=auto, finder_options=kwargs, **self.v)
     self.assertIsInstance(lobject, LensObject)
Beispiel #3
0
    def add_to_patch(self, filepath, index=None, verbose=False, **kwargs):
        """
        Add a file to the patch after initialization

        Args:
            filepath <str> - path to file which is to be added to the patch

        Kwargs:
            index <int> -  list index at which the file is inserted; default -1
            data <list/np.ndarray> - add the data of the .fits file directly
            hdr <dict> - add the header of the .fits file directly
            px2arcsec <float,float> - overwrite the pixel scale in the .fits header (in arcsecs)
            refpx <int,int> - overwrite reference pixel coordinates in .fits header (in pixels)
            refval <float,float> - overwrite reference pixel values in .fits header (in degrees)
            photzp <float> - overwrite photometric zero-point information
            lens <int,int> - overwrite the lens pixel coordinates
            srcimgs <list(int,int)> - overwrite the source image pixel coordinates
            auto <bool> - use LensFinder for automatic image recognition (can be unreliable)
            verbose <bool> - verbose mode; print command line statements
            glscfactory_options <dict> - options for the GLSCFactory encompassing the following:
                parameter <dict> - various parameters like redshifts, time delays, etc.;
                                   also contains parameters for the GLASS config generation
                text_file <str> - path to .txt file; shortcuts automatically resolved
                text <list(str)> - alternative to text_file; direct text input
                filter_ <bool> - apply filter from GLSCFactory.key_filter to text information
                reorder <str> - reorder the images relative to ABCD ordered bottom-up
                output <str> - output name of the .gls file
                name <str> - object name in the .gls file (extracted from output by default)
            finder_options <dict> - options for the LensFinder encompassing the following:
                n <int> - number of peak candidates allowed
                min_q <float> - a percentage quotient for the min. peak separation
                sigma <int(,int)> - lower/upper sigma for signal-to-noise estimate
                centroid <int> - use COM positions around a pixel slice of size of centroid
                                 around peak center if centroid > 1

        Return:
            filepath <str> - validated filepath which was added to the patch
        """
        filepath = super(MultiLens, self).add_to_patch(
            filepath, index=index, verbose=False,
            **{k: kwargs[k] for k in SkyF.params if k in kwargs})
        if index is None or index == -1:
            self.lens_objects.append(LensObject(filepath, **kwargs))
        else:
            self.lens_objects.insert(index, LensObject(filepath, **kwargs))
        if verbose:
            print(self.__v__)
        return filepath
Beispiel #4
0
 def test_parse_fitsfile(self):
     """ # parse_fitsfile """
     print(">>> {}".format(self.test_fits))
     pdta, phdr = LensObject.parse_fitsfile(self.test_fits, header=True, **self.v)
     self.assertIsNotNone(phdr)
     self.assertEqual(pdta.shape, (128, 128))
     self.assertIsInstance(pdta, np.ndarray)
     self.assertIsInstance(phdr, dict)
Beispiel #5
0
 def setUp(self):
     # arguments and keywords
     self.test_fits = os.path.abspath(os.path.dirname(__file__)) \
                      + '/W3+3-2.I.12907_13034_7446_7573.fits'
     self.kwargs = {'n': 5, 'min_q': 0.1, 'sigma': (1, 3), 'centroid': 5}
     self.v = {'verbose': 1}
     # __init__ test
     self.lo = LensObject(self.test_fits)
     self.finder = LensFinder(self.lo, **self.kwargs)
     # verbosity
     self.kwargs.update(self.v)
     print("")
     print(self.separator)
     print(self.shortDescription())
Beispiel #6
0
 def test_from_json(self):
     """ # from_json """
     filename = 'test.json'
     self.lobject.zl = 0.5
     self.lobject.add_srcimg((24, 36), unit='pixels')
     filename = self.lobject.jsonify(name='test.json')
     print(">>> {}".format(filename))
     with open(filename, 'r') as j:
         jcopy = LensObject.from_json(j, **self.v)
         self.assertEqual(jcopy, self.lobject)
         self.assertFalse(jcopy is self.lobject)
         self.assertEqual(jcopy.zl, self.lobject.zl)
         self.assertEqual(jcopy.srcimgs, self.lobject.srcimgs)
     try:
         os.remove(filename)
     except OSError:
         pass
Beispiel #7
0
class GLSCFactory(object):
    """
    Generate glass config file's with this class
    """
    # default search parameters; extend with append GLSCFactory.append_keywords
    keywords = {
        'px2arcsec': ['pixelsize', 'pixel-size', 'pixel size', 'scale'],
        'zl': [
            'redshift', 'lens redshift', 'lens/source redshift',
            'lens/src redshift', 'l/s redshift', 'source/lens redshift',
            'src/lens redshift', 's/l redshift'
        ],
        'zs': [
            'redshift', 'source redshift', 'lens/source redshift',
            'lens/src redshift', 'l/s redshift', 'source/lens redshift',
            'src/lens redshift', 's/l redshift'
        ],
        'lens': ['lens position', 'lens coordinates'],
        'srcimgs': ['image positions', 'image coordinates'],
        'photzp': ['zeropoint', 'zero-point', 'zero point', 'zp'],
        'mapr': ['map radius', 'map extent', 'extent'],
        'tdelay': ['time delay', 'delay', 'BCD - A', 'B - A'],
        'tderr': ['time delay', 'delay', 'BCD - A', 'B - A'],
        'delay_order': ['ordering', 'delay order'],
        'double': ['B - A'],
        'quad': ['BCD - A'],
        'kext': ['external convergence', 'ext. convergence'],
        'kext_error': ['external convergence', 'ext. convergence'],
        'v_disp': ['velocity', 'dispersion'],
        'v_disp_error': ['velocity', 'dispersion']
    }
    # additional filter to distinguish between values and errors on the same line
    # extend with GLSCFactory.append_filter
    key_filter = {
        'px2arcsec':
        lambda lst: [min(lst), min(lst)],
        'zl':
        min,
        'zs':
        max,
        'photzp':
        lambda lst: lst[0],
        'tdelay':
        lambda lst: lst[:int(len(lst) / 2)] + [0],
        'tderr':
        lambda lst: (lst[int(len(lst) / 2):] + [
            sum(lst[int(len(lst) / 2):]) / max(1, len(lst[int(len(lst) / 2):]))
        ]),
        'quad':
        lambda arg: True if arg else False,
        'double':
        lambda arg: True if arg else False,
        'kext':
        lambda lst: lst[:int(len(lst) / 2)],
        'kext_error':
        lambda lst: lst[int(len(lst) / 2):],
        'v_disp':
        lambda lst: lst[:int(len(lst) / 2)][0],
        'v_disp_error':
        lambda lst: lst[int(len(lst) / 2):][0]
    }
    # default index labeling of the positions
    labeling = {
        'A': 0,
        'B': 1,
        'C': 2,
        'D': 3,
        'E': 4,
        'F': 5,
        'G': 6,
        'H': 7,
        'I': 8
    }

    def __init__(self,
                 parameter=None,
                 text_file=None,
                 text=None,
                 filter_=True,
                 sync=True,
                 lensobject=None,
                 fits_file=None,
                 template_single=os.path.join(
                     os.path.abspath(os.path.dirname(__file__)),
                     'template.single.gls'),
                 template_multi=os.path.join(
                     os.path.abspath(os.path.dirname(__file__)),
                     'template.multi.gls'),
                 output=None,
                 name=None,
                 reorder=None,
                 verbose=False,
                 **kwargs):
        """
        Initialize a Glass Config Factory with information from .fits and/or .txt file

        Args:
            None

        Kwargs:
            parameter <dict> - parameter directly for the GLASS config generation
            text_file <str> - path to .txt file (shortcuts are automatically resolved)
            text <list(str)> - alternatively to text_file the text can be input directly
            lensobject <LensObject object> - a lens object for basic information about lens
            fits_file <str> - alternatively to a lens object, a path to .fits file
                              (shortcuts are automatically resolved) can be input
            override <bool> - change values in lensobject obtained from text
            output <str> - output name of the .gls file
            name <str> - object name in the .gls file (extracted from output by default)
            reorder <str> - reorder the image positions relative to ABCD ordered bottom-up
            verbose <bool> - verbose mode; print command line statements

        Return:
            None
        """
        # name/path parameters
        if output is None:
            output = 'autogen'
        if output.endswith('.gls'):
            output = os.path.splitext(output)[0]
        if output.endswith('/'):
            output = output + 'autogen'
        self.directory, self.fname = os.path.split(os.path.abspath(output))
        if name is not None:
            self.name = name
        else:
            self.name = self.fname
        self._parameter = parameter
        self.parameter = {
            'name': "'{}'".format(self.name),
            'fname': "'{}'".format(self.fname),
            'dpath': "'{}'".format(""),
            'reorder': reorder
        }

        # read text input
        if text is None:
            self.text = self.read(text_file)
        else:
            self.text = text

        # read lens input
        if lensobject is None:
            self.lensobject = None
            if fits_file is not None:
                from gleam.lensobject import LensObject
                self.lensobject = LensObject(fits_file, auto=True, **kwargs)
        else:
            self.lensobject = lensobject
        if sync:
            self.sync_lens_params()

        # glass config
        self.template = {}
        self.template['single'] = self.read(template_single)
        self.template['multi'] = self.read(template_multi)
        self._config = dict(self.template)  # copy template by default

        # some verbosity
        if verbose:
            print(self.__v__)

    def __str__(self):
        return "GLSCFactory({}, {}, {}, {}...)".format(
            *list(self.parameter.keys())[:4])

    @property
    def __v__(self):
        """
        Info string for test printing

        Args/Kwargs:
            None

        Return:
            <str> - test of GLSCFactory attributes
        """
        tests = [
            'lensobject', 'text', 'directory', 'name', 'parameter', 'template',
            'config'
        ]
        return "\n".join([
            t.ljust(20) + "\t{}".format(self.__getattribute__(t))
            for t in tests
        ])

    @property
    def parameter(self):
        """
        Parameter gathered from text and lens matching search parameters

        Args/Kwargs:
            None

        Return:
            parameter <dict> - a dictionary of information from text and lens
        """
        if self._parameter is None:
            self._parameter = dict()
        text_info = self.text_extract(self.text, filter_=True)
        lens_info = self.lens_extract(self.lensobject)
        # execution order is important!
        self._parameter.update(lens_info)
        self._parameter.update(text_info)
        return self._parameter

    @parameter.setter
    def parameter(self, parameter):
        """
        Update parameter extracted from both text and lens by search parameters

        Args:
            parameter <dict> - a dictionary of information intended for glass config file

        Kwargs/Return:
            None
        """
        if self._parameter is None:
            self._parameter = dict()
        self._parameter.update(parameter)

    @property
    def config(self):
        """
        Configurations based on text and lens parameter for the glass config file

        Args/Kwargs:
            None

        Return:
           config <list(str)> - configurations ready to be written to a file
        """
        if self._config is None:  # only copy if necessary
            self._config = dict(self.template)
        parameter = self.parameter  # update parameter by calling property
        # fill configs with parameter
        parameter_reordered = False
        for k in self._config.keys():
            for i, line in enumerate(self._config[k]):
                param = line[1:].split("=")[0].strip()
                if line[0] == "_" and param in parameter:
                    if param == 'ABCD' and parameter['reorder'] is not None \
                       and not parameter_reordered:
                        topbottom = list(parameter['ABCD'])  # not yet ABCD
                        parameter_reordered = True
                        for j, x in enumerate(parameter['reorder']):
                            parameter['ABCD'][
                                GLSCFactory.labeling[x]] = topbottom[j]
                    self._config[k][i] = param + " = " + str(
                        parameter[param]) + "\n"
                # None values
                elif line[0] == "_":
                    self._config[k][i] = param + " = " + "None\n"
        return self._config

    @staticmethod
    def append_keywords(keywords, verbose=False):
        """
        Append key/words to search parameters of GLSCFactory
        (one to many mapping of key and words)

        Args:
            keywords <dict> - additional search parameters to append to defaults

        Kwargs:
            verbose <bool> - verbose mode; print command line statements

        Return:
            GLSCFactory.keywords <dict> - search parameters of the class
        """
        if keywords is not None and isinstance(keywords, dict):
            for k, w in keywords.items():
                GLSCFactory.keywords[k] = w
        if verbose:
            print(GLSCFactory.keywords)
        return GLSCFactory.keywords

    @staticmethod
    def append_filter(filters, verbose=False):
        """
        Append keywords to search parameters of GLSCFactory (one to one mapping of key and func)

        Args:
            key <dict(str, callable)> - variable key of search matches on which
                                        the filter is applied

        Kwargs:
            verbose <bool> - verbose mode; print command line statements

        Return:
            GLSCfactory.key_filter <dict> - filter functions to apply to search matches
        """
        if filters is not None and isinstance(filters, dict):
            for k, f in filters.items():
                print(k, f)
                GLSCFactory.key_filter[k] = f
        if verbose:
            print(GLSCFactory.key_filter)
        return GLSCFactory.key_filter

    @staticmethod
    def read(filepath, check_ext=False, verbose=False):
        """
        Read a text file and return text

        Args:
            filepath <str> - path to .txt file (shortcuts are automatically resolved)

        Kwargs:
            check_ext <bool> - check path for .txt extension
            verbose <bool> - verbose mode; print command line statements

        Return:
            text <list(str)> - text from the .txt file
        """
        # validate input
        if filepath is None:
            return None
        if not isinstance(filepath, str):
            raise TypeError("Input path needs to be string")
        # expand shortcuts
        if '~' in filepath:
            filepath = os.path.expanduser(filepath)
        dirname = os.path.dirname(os.path.abspath(__file__))
        if not os.path.isabs(filepath):
            filepath = "/".join([dirname, filepath])
        # check if path exists
        if not os.path.exists(filepath):
            try:  # python 3
                FileNotFoundError
            except NameError:  # python 2
                FileNotFoundError = IOError
            raise FileNotFoundError("'{}' does not exist".format(filepath))
        # optionally check extension
        if check_ext and True not in [
                filepath.endswith(ext) for ext in ('.text', '.txt')
        ]:
            raise ValueError('Input file path need to be a .txt file')
        f = open(filepath, 'r')
        text = f.readlines()
        f.close()
        if verbose:
            print(text)
        return text

    @staticmethod
    def text_extract(text,
                     keywords=None,
                     filter_=False,
                     key_filter=None,
                     verbose=False):
        """
        Extract GLSCFactory's search parameters from text

        Args:
            text <list(str)> - list of strings in which the search parameters take effect

        Kwargs:
            keywords <dict> - additional strings to append to search parameters
            key_filter <dict> - additional functions to append to key filters
            filter_ <bool> - apply filters from GLSCFactory.key_filter
            verbose <bool> - verbose mode; print command line statements

        Return:
            info <dict> - dictionary of extracted information from the text
        """
        info = {}
        if text is None:
            return {}
        # get all search parameters
        GLSCFactory.append_keywords(keywords)
        keys = list(GLSCFactory.keywords.keys())
        key_groups = list(GLSCFactory.keywords.values())
        words = sum(GLSCFactory.keywords.values(), [])
        params = [re.compile(s, re.I)
                  for s in words]  # case-insensitive search parameters
        # search for parameters
        for i, line in enumerate(text):
            hits = [
                p.search(line).group() if p.search(line) else None
                for p in params
            ]
            idx_word = [n for n, h in enumerate(hits) if h]
            idx_keyg = [
                idx for w in idx_word for idx, g in enumerate(key_groups)
                if words[w] in g
            ]
            if line.strip()[-1] == ":":
                numbers = [
                    float(n) for n in re.findall(
                        "[-+]?[.]?[\d]+(?:,\d\d\d)*[\.]?\d*(?:[eE][-+]?\d+)?",
                        text[i + 1])
                ]
            else:
                numbers = [
                    float(n) for n in re.findall(
                        "[-+]?[.]?[\d]+(?:,\d\d\d)*[\.]?\d*(?:[eE][-+]?\d+)?",
                        line)
                ]
            for i in idx_keyg:
                info[keys[i]] = numbers
        # run filter through finds
        if filter_:
            GLSCFactory.append_filter(key_filter)
            for k in info:
                if GLSCFactory.key_filter[k]:
                    info[k] = GLSCFactory.key_filter[k](info[k])
        if verbose:
            print(info)
        return info

    def sync_lens_params(self, verbose=False):
        """
        Override attributes of the lens object with info from text parameters

        Args:
            None

        Kwargs:
            verbose <bool> - verbose mode; print command line statements

        Return:
            None
        """
        for k in self.parameter.keys():
            if k in dir(self.lensobject):
                self.lensobject.__setattr__(k, self.parameter[k])
                if verbose:
                    print(self.lensobject.__getattribute__(k))

    @staticmethod
    def lens_extract(lo,
                     directory=None,
                     use_order=False,
                     round_pos=True,
                     output=None,
                     verbose=False):
        """
        Extract GLSCFactory's search parameters from a LensObject object

        Args:
            lo <LensObject object> - holding information about the .fits file

        Kwargs:
            verbose <bool> - verbose mode; print command line statements

        Return:
            info <dict> - dictionary of extracted information from SkyF object
        """
        info = dict()
        if directory is not None:
            info.update({'dpath': "'{}'".format(directory)})
        # get info from lens object
        for k in GLSCFactory.keywords.keys():
            if k in dir(lo):
                par = lo.__getattribute__(k)
                info[k] = par
        # exceptional transformations and assignments
        # lens = lo.lens.xy if lo.lens else lo.center.xy
        # ABCD = lo.srcimgs_xy
        ABCD = gleam.lensfinder.LensFinder.relative_positions(
            lo.srcimgs, lo.lens if lo.lens else lo.center)
        # parity
        if len(lo.srcimgs) == 4:
            parity = ['min', 'min', 'sad', 'sad']
        elif len(lo.srcimgs) == 2:
            parity = ['min', 'sad']
        elif len(lo.srcimgs) == 5:
            parity = ['min', 'min', 'sad', 'sad', 'max']
        elif len(lo.srcimgs) == 3:
            parity = ['min', 'sad', 'max']
        else:
            ABCD = [ABCD[i] if len(ABCD) > i else [] for i in range(4)]
            parity = ['min', 'min', 'sad', 'sad']

        if round_pos:
            ABCD = np.round(ABCD, 4).tolist()

        if use_order:
            image_order = (np.asarray(lo.delay_order)+1) % len(ABCD) \
                          if np.any(lo.delay_order) else list(range(len(ABCD)))
        else:
            image_order = list(range(len(ABCD)))

        pos_par_td = [ABCD[image_order[0]], parity[0]]
        for i in range(1, len(ABCD)):
            pos_par_td.append(ABCD[image_order[i]])  # position
            pos_par_td.append(parity[i])  # parity
            pos_par_td.append(None)  # time delay default

        info.update({
            'ABCD': ABCD,
            'parity': parity,
            'mapr': round(lo.maprad, 4) if lo.maprad else lo.maprad,
            'pos_par_td': pos_par_td
        })

        # some defaults
        if not info['zl']:
            info['zl'] = 0.5
        if not info['zs']:
            info['zs'] = 3.0
        if verbose:
            print(info)
        return info

    def write(self, filename=None, adjust_paths=True, verbose=False):
        """
        Write glass configs to a new file

        Args:
            None

        Kwargs:
            filename <str> - save in a different location as given in output
            adjust_paths <bool> - change the output paths in the config file according to filename
            verbose <bool> - verbose mode; print command line statements

        Return:
            None
        """
        from gleam.utils.makedir import mkdir_p
        if filename is not None:
            if '~' in filename:
                filename = os.path.expanduser(filename)
            self.directory, self.fname = os.path.split(
                os.path.abspath(filename))
        if adjust_paths:
            fname = self.fname
            if fname.endswith('.config.gls'):
                fname = ".".join(self.fname.split('.')[:-2])
            elif fname.endswith('.gls'):
                fname = ".".join(self.fname.split('.')[:-1])
            self.parameter = {
                'dpath': "'{}'".format(self.directory),
                'fname': "'{}'".format(fname)
            }
        mkdir_p(self.directory)
        output = os.path.join(self.directory, self.fname)
        if not output.endswith(".gls"):
            output = output + ".gls"
        with open(output, 'w') as f:
            f.writelines(self.config['single'])
        if verbose:
            print('Writing configs to {}'.format(output))

    def append(self,
               filename=None,
               multi=True,
               last=False,
               adjust_paths=True,
               verbose=False):
        """
        Append only lens specific configs to an already existing file

        Args:
            None

        Kwargs:
            filename <str> - save in a different location as given in output
            multi <bool> - use multi template instead of single template
            last <bool> - complete file by attaching the last 4 lines
            adjust_paths <bool> - change the output paths in the config file according to filename
            verbose <bool> - verbose mode; print command line statements

        Return:
            None
        """
        from gleam.utils.makedir import mkdir_p
        if filename is not None:
            if '~' in filename:
                filename = os.path.expanduser(filename)
            self.directory, self.fname = os.path.split(
                os.path.abspath(filename))
        if adjust_paths:
            fname = self.fname
            if fname.endswith('.config.gls'):
                fname = ".".join(self.fname.split('.')[:-2])
            elif fname.endswith('.gls'):
                fname = ".".join(self.fname.split('.')[:-1])
            self.parameter = {
                'dpath': "'{}'".format(self.directory),
                'fname': "'{}'".format(fname)
            }
        mkdir_p(self.directory)
        output = self.directory + "/" + self.fname
        if not self.fname.endswith(".gls"):
            output = output + ".gls"
        lens_config = self.config['multi'] if multi else self.config['single']
        config_sections = [(i, line) for i, line in enumerate(lens_config)
                           if line.startswith('###')]
        if os.path.exists(output):
            lens_section = [
                config_sections[j - 1][0] if l.startswith('### Lens') else
                config_sections[j +
                                1][0] if l.startswith('### Source') else None
                for j, (i, l) in enumerate(config_sections)
            ]
            start, end = [i for i in lens_section if isinstance(i, int)]
        else:
            start, end = 0, config_sections[-1][0]
        if os.path.exists(output) and verbose:
            print("Appending configs to {}".format(output))
        elif verbose:
            print("Writing configs to {}".format(output))
        if last:
            print("Completing configs at {}".format(output))
        with open(output, 'a+') as f:
            f.writelines(lens_config[start:end])
            if last:
                f.writelines(lens_config[end:])

    @staticmethod
    def config_diff(*glsc):
        """
        Determine diff lines in gls configurations
        """
        NotImplemented  # yet
Beispiel #8
0
    def __init__(self,
                 parameter=None,
                 text_file=None,
                 text=None,
                 filter_=True,
                 sync=True,
                 lensobject=None,
                 fits_file=None,
                 template_single=os.path.join(
                     os.path.abspath(os.path.dirname(__file__)),
                     'template.single.gls'),
                 template_multi=os.path.join(
                     os.path.abspath(os.path.dirname(__file__)),
                     'template.multi.gls'),
                 output=None,
                 name=None,
                 reorder=None,
                 verbose=False,
                 **kwargs):
        """
        Initialize a Glass Config Factory with information from .fits and/or .txt file

        Args:
            None

        Kwargs:
            parameter <dict> - parameter directly for the GLASS config generation
            text_file <str> - path to .txt file (shortcuts are automatically resolved)
            text <list(str)> - alternatively to text_file the text can be input directly
            lensobject <LensObject object> - a lens object for basic information about lens
            fits_file <str> - alternatively to a lens object, a path to .fits file
                              (shortcuts are automatically resolved) can be input
            override <bool> - change values in lensobject obtained from text
            output <str> - output name of the .gls file
            name <str> - object name in the .gls file (extracted from output by default)
            reorder <str> - reorder the image positions relative to ABCD ordered bottom-up
            verbose <bool> - verbose mode; print command line statements

        Return:
            None
        """
        # name/path parameters
        if output is None:
            output = 'autogen'
        if output.endswith('.gls'):
            output = os.path.splitext(output)[0]
        if output.endswith('/'):
            output = output + 'autogen'
        self.directory, self.fname = os.path.split(os.path.abspath(output))
        if name is not None:
            self.name = name
        else:
            self.name = self.fname
        self._parameter = parameter
        self.parameter = {
            'name': "'{}'".format(self.name),
            'fname': "'{}'".format(self.fname),
            'dpath': "'{}'".format(""),
            'reorder': reorder
        }

        # read text input
        if text is None:
            self.text = self.read(text_file)
        else:
            self.text = text

        # read lens input
        if lensobject is None:
            self.lensobject = None
            if fits_file is not None:
                from gleam.lensobject import LensObject
                self.lensobject = LensObject(fits_file, auto=True, **kwargs)
        else:
            self.lensobject = lensobject
        if sync:
            self.sync_lens_params()

        # glass config
        self.template = {}
        self.template['single'] = self.read(template_single)
        self.template['multi'] = self.read(template_multi)
        self._config = dict(self.template)  # copy template by default

        # some verbosity
        if verbose:
            print(self.__v__)
Beispiel #9
0
 def test_check_path(self):
     """ # check_path """
     print(">>> {}".format(self.test_fits))
     fpath = LensObject.check_path(self.test_fits, **self.v)
     self.assertEqual(fpath, self.test_fits)
Beispiel #10
0
class TestLensObject(UnitTestPrototype):

    def setUp(self):
        # arguments and keywords
        self.test_fits = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                                      'W3+3-2.U.12907_13034_7446_7573.fits')
        # __init__ test
        self.lobject = LensObject(self.test_fits)
        # verbosity
        self.v = {'verbose': 1}
        print("")
        print(self.separator)
        print(self.shortDescription())

    def tearDown(self):
        print("")

    def test_LensObject(self):
        """ # LensObject """
        print(">>> {}".format(self.test_fits))
        lobject = LensObject(self.test_fits, **self.v)
        self.assertIsInstance(lobject, LensObject)
        self.assertEqual(lobject, self.lobject)
        kwargs = {'auto': True,
                  'n': 5,
                  'min_q': 0.1,
                  'sigma': (1, 3),
                  'centroid': 5}
        print(">>> {}, {}".format(self.test_fits, kwargs))
        auto = kwargs.pop('auto')
        lobject = LensObject(self.test_fits, auto=auto, finder_options=kwargs, **self.v)
        self.assertIsInstance(lobject, LensObject)
        # print(">>> {}".format(None))
        # lobject = LensObject(None, **self.v)
        # self.assertIsInstance(lobject, LensObject)

    def test_copy(self):
        """ # copy """
        print(">>> {}".format(self.lobject))
        self.lobject.zl = 0.5
        copy = self.lobject.copy(**self.v)
        self.assertEqual(copy, self.lobject)
        self.assertFalse(copy is self.lobject)
        self.assertEqual(copy.zl, self.lobject.zl)

    def test_deepcopy(self):
        """ # deepcopy """
        print(">>> {}".format(self.lobject))
        self.lobject.zl = 0.5
        copy = self.lobject.deepcopy(**self.v)
        self.assertEqual(copy, self.lobject)
        self.assertFalse(copy is self.lobject)
        self.assertEqual(copy.zl, self.lobject.zl)

    def test_from_json(self):
        """ # from_json """
        filename = 'test.json'
        self.lobject.zl = 0.5
        self.lobject.add_srcimg((24, 36), unit='pixels')
        filename = self.lobject.jsonify(name='test.json')
        print(">>> {}".format(filename))
        with open(filename, 'r') as j:
            jcopy = LensObject.from_json(j, **self.v)
            self.assertEqual(jcopy, self.lobject)
            self.assertFalse(jcopy is self.lobject)
            self.assertEqual(jcopy.zl, self.lobject.zl)
            self.assertEqual(jcopy.srcimgs, self.lobject.srcimgs)
        try:
            os.remove(filename)
        except OSError:
            pass

    def test_jsonify(self):
        """ # jsonify """
        print(">>> {}".format(self.lobject))
        self.lobject.zl = 0.5
        self.lobject.add_srcimg((24, 36), unit='pixels')
        jsnstr = self.lobject.jsonify(**self.v)
        self.assertIsInstance(jsnstr, str)

    def test_check_path(self):
        """ # check_path """
        print(">>> {}".format(self.test_fits))
        fpath = LensObject.check_path(self.test_fits, **self.v)
        self.assertEqual(fpath, self.test_fits)

    def test_parse_fitsfile(self):
        """ # parse_fitsfile """
        print(">>> {}".format(self.test_fits))
        pdta, phdr = LensObject.parse_fitsfile(self.test_fits, header=True, **self.v)
        self.assertIsNotNone(phdr)
        self.assertEqual(pdta.shape, (128, 128))
        self.assertIsInstance(pdta, np.ndarray)
        self.assertIsInstance(phdr, dict)

    def test_mag_formula(self):
        """ # mag_formula """
        print(">>> {}".format(1))
        self.assertEqual(self.lobject.mag_formula(1, **self.v), self.lobject.photzp)
        print(">>> {}".format(0))
        self.assertEqual(self.lobject.mag_formula(0, **self.v), np.inf)
        print(">>> {}".format(1e12))
        self.assertEqual(self.lobject.mag_formula(10**(self.lobject.photzp/2.5), **self.v), 0)
        print(">>> {}".format(10))
        self.assertEqual(self.lobject.mag_formula(10, **self.v), self.lobject.photzp-2.5)

    def test_total_magnitude(self):
        """ # total_magnitude """
        print(">>> {}".format(0))
        self.assertEqual(self.lobject.total_magnitude(0, **self.v), np.inf)
        print(">>> {}".format(128))
        self.assertEqual(self.lobject.total_magnitude(128, **self.v), 22.723195552825928)
        print(">>> {}".format(10000))
        self.assertEqual(self.lobject.total_magnitude(10000, **self.v), 22.723195552825928)

    def test_cutout(self):
        """ # cutout """
        print(">>> {}".format(10))
        self.assertEqual(self.lobject.cutout(10, **self.v).shape, (10, 10))
        print(">>> {}".format(5))
        self.assertEqual(self.lobject.cutout(5, **self.v).shape, (5, 5))
        print(">>> {}".format(1))
        self.assertEqual(self.lobject.cutout(1, **self.v).shape, (1, 1))
        print(">>> {}".format(0))
        self.assertEqual(self.lobject.cutout(0, **self.v).shape, (0, 0))

    def test_gain(self):
        """ # gain """
        print(">>> {}".format(5))
        gain = self.lobject.gain(5, **self.v)
        self.assertIsInstance(gain, float)
        self.assertGreater(gain, 0)
        print(">>> {}".format(10))
        gain = self.lobject.gain(10, **self.v)
        self.assertIsInstance(gain, float)
        self.assertGreater(gain, 0)
        print(">>> {}".format(20))
        gain = self.lobject.gain(20, **self.v)
        self.assertIsInstance(gain, float)
        self.assertGreater(gain, 0)
        print(">>> {}".format(40))
        gain = self.lobject.gain(40, (20, 20), **self.v)
        self.assertIsInstance(gain, float)
        self.assertGreater(gain, 0)

    def test_pxscale_from_hdr(self):
        """ # pxscale_from_hdr """
        print(">>> {}".format(self.lobject.hdr))
        scale = LensObject.pxscale_from_hdr(self.lobject.hdr)
        self.assertListEqual(scale, [0.185733387468, 0.185733387468])

    def test_crota2_from_hdr(self):
        """ # crota2_from_hdr """
        print(">>> {}".format(self.lobject.hdr))
        crota2 = LensObject.crota2_from_hdr(self.lobject.hdr, **self.v)
        self.assertListEqual(crota2, [0, 0])

    def test_refpx_from_hdr(self):
        """ # refpx_from_hdr """
        print(">>> {}".format(self.lobject.hdr))
        refpx = LensObject.refpx_from_hdr(self.lobject.hdr, **self.v)
        self.assertListEqual(refpx, [-2710.0, 3245.0])

    def test_mag_formula_from_hdr(self):
        """ # mag_formula_from_hdr """
        print(">>> {}".format(self.lobject.hdr))
        formula = LensObject.mag_formula_from_hdr(self.lobject.hdr, **self.v)
        self.assertTrue(hasattr(formula, '__call__'))

    def test_p2skycoords(self):
        """ # p2skycoords """
        print(">>> {}".format((-1.234, 0.567)))
        skyc = self.lobject.p2skycoords((-1.234, 0.567), unit='arcsec', relative=True, **self.v)
        self.assertIsInstance(skyc, SkyCoords)

    def test_add_srcimg(self):
        """ # add_srcimg """
        print(">>> {}".format((-1.234, 0.567)))
        before = self.lobject.srcimgs[:]
        srcp = self.lobject.add_srcimg((-1.234, 0.567), unit='arcsec', relative=True, **self.v)
        after = self.lobject.srcimgs
        self.assertIsInstance(srcp, SkyCoords)
        self.assertEqual(len(before)+1, len(after))

    def test_src_shifts(self):
        """ # src_shifts """
        print(">>> {}".format(()))
        self.lobject.add_srcimg((-1.234, 0.567), unit='arcsec', relative=True)
        shifts = self.lobject.src_shifts(unit='arcsec', **self.v)
        self.assertIsInstance(shifts, list)

    def test_show_f(self):
        """ # plot_f """
        print(">>> {}".format(self.lobject))
        fig, ax = self.lobject.show_f(savefig='test.pdf', lens=True, source_images=True, **self.v)
        self.assertIsNotNone(fig)
        self.assertIsNotNone(ax)
        try:
            os.remove('test.pdf')
        except OSError:
            pass

    def test_image_f(self):
        """ # image_f """
        self.lobject.roi.select['circle']((64, 64), 20, **self.v)
        self.lobject.roi.select['polygon']((64, 32), (32, 32), (32, 64), **self.v)
        self.lobject.roi.select['rect']((28, 28), (82, 82), **self.v)
        self.lobject.roi.close_all()
        self.lobject.lens = (96, 96)
        self.lobject.srcimgs_xy = [(70, 70)]
        img = self.lobject.image_f(draw_lens=True, draw_srcimgs=True, draw_roi=True)
        if 0:
            img.show()
Beispiel #11
0
 def test_mag_formula_from_hdr(self):
     """ # mag_formula_from_hdr """
     print(">>> {}".format(self.lobject.hdr))
     formula = LensObject.mag_formula_from_hdr(self.lobject.hdr, **self.v)
     self.assertTrue(hasattr(formula, '__call__'))
Beispiel #12
0
 def test_refpx_from_hdr(self):
     """ # refpx_from_hdr """
     print(">>> {}".format(self.lobject.hdr))
     refpx = LensObject.refpx_from_hdr(self.lobject.hdr, **self.v)
     self.assertListEqual(refpx, [-2710.0, 3245.0])
Beispiel #13
0
 def test_crota2_from_hdr(self):
     """ # crota2_from_hdr """
     print(">>> {}".format(self.lobject.hdr))
     crota2 = LensObject.crota2_from_hdr(self.lobject.hdr, **self.v)
     self.assertListEqual(crota2, [0, 0])
Beispiel #14
0
 def test_pxscale_from_hdr(self):
     """ # pxscale_from_hdr """
     print(">>> {}".format(self.lobject.hdr))
     scale = LensObject.pxscale_from_hdr(self.lobject.hdr)
     self.assertListEqual(scale, [0.185733387468, 0.185733387468])
Beispiel #15
0
    def __init__(self, files, auto=None, glscfactory_options=None, finder_options=None,
                 verbose=False, **kwargs):
        """
        Initialize parsing of a fits file with a directory name

        Args:
            files <str/list(str)> - list of .fits files or directory string containing the files

        Kwargs:
            data <list(list/np.ndarray)> - add the data of the .fits file directly
            hdr <list(dict)> - add the header of the .fits file directly
            px2arcsec <list(float,float)> - overwrite the pixel scale in the .fits header (in arcs)
            refpx <list(int,int)> - overwrite reference pixel coordinates in .fits header (in px)
            refval <list(float,float)> - overwrite reference pixel values in .fits header (in deg)
            photzp <list(float)> - overwrite photometric zero-point information

            lens <list(int,int)> - overwrite the lens pixel coordinates
            srcimgs <list(int,int)> - overwrite the source image pixel coordinates
            auto <list(bool)> - (finder) use automatic image recognition (can be unreliable)
            verbose <bool> - verbose mode; print command line statements

            glscfactory_options <list(dict)> - options for the GLSCFactory:
                parameter <dict> - various parameters like redshifts, time delays, etc.;
                                   also contains parameters for the GLASS config generation
                text_file <str> - path to .txt file; shortcuts automatically resolved
                text <list(str)> - alternative to text_file; direct text input
                filter_ <bool> - apply filter from GLSCFactory.key_filter to text information
                reorder <str> - reorder the images relative to ABCD ordered bottom-up
                output <str> - output name of the .gls file
                name <str> - object name in the .gls file (extracted from output by default)
            finder_options <list(dict)> - options for the LensFinder:
                n <int> - number of peak candidates allowed
                min_q <float> - a percentage quotient for the min. peak separation
                sigma <int(,int)> - lower/upper sigma for signal-to-noise estimate
                centroid <int> - use COM positions around a pixel slice of size of centroid
                                 around peak center if centroid > 1

        Return:
            <MultiLens object> - standard initializer
        """
        super(MultiLens, self).__init__(
            files, verbose=False, **{k: kwargs[k] for k in SkyF.params if k in kwargs})
        # keyword defaults
        for k in LensObject.params:
            kwargs.setdefault(k, [None]*self.N)
        if auto is None:
            auto = [False]*self.N
        if glscfactory_options is None:
            glscfactory_options = [{}]*self.N
        if finder_options is None:
            finder_options = [{}]*self.N
        # handle collective keyword inputs
        for k in LensObject.params:
            if not isinstance(kwargs[k], list):
                kwargs[k] = [kwargs[k]]*self.N
        if isinstance(auto, bool):
            auto = [auto]*self.N
        if isinstance(glscfactory_options, dict):
            glscfactory_options = [glscfactory_options]*self.N
        if isinstance(finder_options, dict):
            finder_options = [finder_options]*self.N
        # lensobject instances for all files
        self.lens_objects = [None]*self.N
        for i, f in enumerate(self.filepaths):
            self.lens_objects[i] = LensObject(
                f, auto=auto[i],
                glscfactory_options=glscfactory_options[i], finder_options=finder_options[i],
                **{k: kwargs[k][i] for k in kwargs})

        #TODO: unify different lens objects to have uniform information

        if verbose:
            print(self.__v__)