def _load_and_parse_file(self, pth):
        """ Loads a .IES file from a given filename, returns an IESDataset
        which is used by the load function later on. """
        self.debug("Loading ies profile from", pth)

        try:
            with open(pth, "r") as handle:
                lines = handle.readlines()
        except IOError as msg:
            self.error("Failed to open", pth, ":", msg)
            return None

        lines = [i.strip() for i in lines]

        # Parse version header
        self._check_version_header(lines.pop(0))

        # Parse arbitrary amount of keywords
        keywords = self._extract_keywords(lines)  # noqa

        # Next line should be TILT=NONE according to the spec
        if lines.pop(0) != "TILT=NONE":
            raise InvalidIESProfileException("Expected TILT=NONE line, but none found!")

        # From now on, lines do not matter anymore, instead everything is
        # space seperated
        new_parts = (' '.join(lines)).replace(",", " ").split()

        def read_int():
            return int(new_parts.pop(0))

        def read_float():
            return float(new_parts.pop(0))

        # Amount of Lamps
        if read_int() != 1:
            raise InvalidIESProfileException("Only 1 Lamp supported!")

        # Extract various properties
        lumen_per_lamp = read_float()  # noqa
        candela_multiplier = read_float()  # noqa
        num_vertical_angles = read_int()
        num_horizontal_angles = read_int()

        if num_vertical_angles < 1 or num_horizontal_angles < 1:
            raise InvalidIESProfileException("Invalid of vertical/horizontal angles!")

        photometric_type = read_int()  # noqa
        unit_type = read_int()

        # Check for a correct unit type, should be 1 for meters and 2 for feet
        if unit_type not in [1, 2]:
            raise InvalidIESProfileException("Invalid unit type")

        width = read_float()  # noqa
        length = read_float()  # noqa
        height = read_float()  # noqa
        ballast_factor = read_float()  # noqa
        future_use = read_float()  # Unused field for future usage  # noqa
        input_watts = read_float()  # noqa

        # Read vertical angles
        vertical_angles = [read_float() for i in range(num_vertical_angles)]
        horizontal_angles = [read_float() for i in range(num_horizontal_angles)]

        candela_values = []
        candela_scale = 0.0

        for i in range(num_horizontal_angles):
            vertical_data = [read_float() for i in range(num_vertical_angles)]
            candela_scale = max(candela_scale, max(vertical_data))
            candela_values += vertical_data

        # Rescale values, divide by maximum
        candela_values = [i / candela_scale for i in candela_values]

        if len(new_parts) != 0:
            self.warn("Unhandled data at file-end left:", new_parts)

            # Dont abort here, some formats like those from ERCO Leuchten GmbH
            # have an END keyword, just ignore everything after the data was
            # read in.

        dataset = IESDataset()
        dataset.set_vertical_angles(self._list_to_pta(vertical_angles))
        dataset.set_horizontal_angles(self._list_to_pta(horizontal_angles))
        dataset.set_candela_values(self._list_to_pta(candela_values))

        # Testing code to write out the LUT
        # from panda3d.core import Texture
        # tex = Texture("temp")
        # tex.setup_3d_texture(512, 512, 1, Image.T_float, Image.F_r16)
        # dataset.generate_dataset_texture_into(tex, 0)
        # tex.write("generated.png")

        return dataset
 Loads a .IES file from a given filename, returns an IESDataset
        which is used by the load function later on. 
metadrive/render_pipeline/rpcore/util/ies_profile_loader.py