<jupyter_start><jupyter_text>Understanding the Paltas Pipeline__Author:__ <NAME>__Goals:__ 1. Understand the basic structure of the `paltas` classes.2. Understand how to modify one of the main components of the `paltas` pipeline by working through an example class that inherits from the `paltas` SourceBase class. Table of Contents1. [The Basics](basics) 2. [Implementing a New Class](new_source)  The Basics  __Goal: Understand the basic structure of the `paltas` classes.__At a high level, the main deflector, line-of-sight, substructure, source, and point source classes in `paltas` are all built with the same philosophy. They inherit from a base class that implements the functions required by generate.py, and they have a set of required parameters that are a property of the class.To better understand this, let's take a look at a trimmed version of the base class for sources, which can be found in `paltas/Sources/source_base.py`.```class SourceBase:    """    Base class for producing lenstronomy LightModel arguments    Args:        cosmology_parameters (str,dict, or colossus.cosmology.Cosmology):            Either a name of colossus cosmology, a dict with 'cosmology name':            name of colossus cosmology, an instance of colussus cosmology, or a            dict with H0 and Om0 ( other parameters will be set to defaults).        source_parameters (dict): dictionary with source-specific parameters    """    required_parameters = tuple()    def __init__(self, cosmology_parameters, source_parameters):        self.cosmo = get_cosmology(cosmology_parameters)        self.source_parameters = copy.deepcopy(source_parameters)         Check that all the required parameters are present        self.check_parameterization(self.__class__.required_parameters)            ........    def draw_source(self):        """Return lenstronomy LightModel names and kwargs        Returns:            (list,list) A list containing the model name(s), and            a list containing the model kwargs dictionaries.        """        raise NotImplementedError```All of the source classes used in `paltas` must inherit from this base class, take as input `cosmology_parameters` and `source_parameters`, and implement the function `draw_source`. This is the function that `generate.py` expects to be able to call in order to get the list of `lenstronomy` models and kwargs associated to the source light. Similarly, there is a `required_parameters` property to the class. When the class is initialized, it will check that the `required_parameters` are all present within `source_parameters`. This list is also useful for users that want to know what parameters the class will expect. For this base class there are no required parameters, so the tuple is empty.--------------------  Implementing a New Class  __Goal: Understand how to modify one of the main components of the `paltas` pipeline by working through an example class that inherits from the `paltas` SourceBase class.__As discussed, Any source class we build for `paltas` needs to inherit from SourceBase to ensure that it interacts correctly with the dataset generation pipeline. One easy but interesting extension we can make is a source consisting of two seperate sersic profiles.<jupyter_code>class DoubleSersicSource(SourceBase):
    """Class to generate single Sersic profile light models

    Args:
        cosmology_parameters (str,dict, or
            colossus.cosmology.cosmology.Cosmology): Either a name
            of colossus cosmology, a dict with 'cosmology name': name of
            colossus cosmology, an instance of colussus cosmology, or a
            dict with H0 and Om0 ( other parameters will be set to defaults).
        source_parameters: dictionary with source-specific parameters.
    """

    # These are the required parameters. In this case we need the seven parameters for our two sersic profiles.
    required_parameters = ['amp_s1','R_sersic_s1','n_sersic_s1','e1_s1','e2_s1','center_x_s1','center_y_s1',
                           'amp_s2','R_sersic_s2','n_sersic_s2','e1_s2','e2_s2','center_x_s2','center_y_s2',
                           'z_source']

    # Our light model list and light kwargs are fairly simple, so we can pull them straight from our
    # source_parameters.
    def draw_source(self):
        """Return lenstronomy LightModel kwargs

        Returns:
            (list,list) A list containing the model names(s), and
                a list containing the model kwargs dictionaries.
        """
        light_model_list = ['SERSIC_ELLIPSE','SERSIC_ELLIPSE']
        light_kwargs_list = []
        # We can extract the kwargs for our two light models using the suffix
        for suffix in ['s1','s2']:
            kwargs_dict = {}
            for param_name in self.__class__.required_parameters:
                if suffix in param_name:
                    kwargs_dict[param_name[:-3]] = self.source_parameters[param_name]
            light_kwargs_list.append(kwargs_dict)
        
        return light_model_list, light_kwargs_list<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.06770320802991538, 'fraction_numerical': 0.005707537886242866, 'mean_word_length': 3.4038128249566726, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '191408', 'license': 'MIT', 'n_tokens_mistral': 1311, 'n_tokens_neox': 1283, 'n_words': 563, 'path': 'notebooks/Understanding_Pipeline.ipynb', 'repo_name': 'swagnercarena/paltas', 'size': '5098'}