Exemple #1
0
def SpecialProcessingFlags(cube: HiccdStitchCube):
    """Set the special processing flags in the ISIS label."""
    status = "NOMINAL"

    if cube.hical_status == "BadCal":
        status = "BADCAL"

    if cube.cubenormstep:
        status = "CUBENORM"

    try:
        isis.getkey_k(cube.nextpath, "Instrument", "Special_Processing_Flag")
        option = "MODKEY"
    except subprocess.CalledProcessError:
        option = "ADDKEY"

    isis.editlab(
        cube.nextpath,
        option=option,
        grpname="Instrument",
        keyword="Special_Processing_Flag",
        value=status,
    )
Exemple #2
0
def fix_labels(cubes: list, path: os.PathLike, matched_cube: str,
               prodid: str) -> None:
    isis.editlab(
        path,
        option="modkey",
        grpname="Archive",
        keyword="ProductId",
        value=prodid,
    )
    isis.editlab(
        path,
        option="modkey",
        grpname="Instrument",
        keyword="MatchedCube",
        value=str(matched_cube),
    )

    # Fix ck kernel in InstrumentPointing in RED label
    # This doesn't seem to be needed, maybe it was HiROC-specific.

    #  Add SourceProductIds to Archive group in label
    logger.info("Original Perl just assumes that both channels are included "
                "in the balance cube.")
    source_ids = list()
    for c in cubes:
        source_ids.append(
            isis.getkey_k(c.path, "Instrument", "StitchedProductIds"))

    isis.editlab(
        path,
        option="ADDKEY",
        grpname="Archive",
        keyword="SourceProductId",
        value="({})".format(", ".join(source_ids)),
    )
    return
Exemple #3
0
def match_red(cubes: list, base_cube, flat_path, elargement_ratio=1.0006):
    """Prepare cubs for hijitreg by matching size and binning to center red
    ccds.
    """
    # Where does the 1.0006 value for OPTICAL_ENLARGEMENT_RATIO come from?
    # Not sure.

    red4 = list(filter(lambda x: int(x.ccdnumber) == 4, cubes))[0]
    red5 = list(filter(lambda x: int(x.ccdnumber) == 5, cubes))[0]

    if red4.bin != red5.bin:
        raise ValueError("RED4 and RED5 binning not equal.")

    for c in cubes:
        bin_ratio = c.bin / base_cube.bin

        # Differences in field of view between color and red are corrected
        # for by multiplying bin ratio by pre-determined constant for BG and
        # dividing bin ratio by that constant for IR

        mag = bin_ratio
        if c.ccdname == "BG":
            mag = bin_ratio * elargement_ratio
        elif c.ccdname == "IR":
            mag = bin_ratio / elargement_ratio

        # scale cubes as needed
        if mag > 1:
            isis.enlarge(
                c.path,
                to=c.next_path,
                sscale=mag,
                lscale=bin_ratio,
                interp="BILINEAR",
            )
        elif mag < 1:
            isis.reduce(
                c.path,
                to=c.next_path,
                sscale=1 / mag,
                lscale=bin_ratio,
                mode="SCALE",
            )
        else:
            shutil.copy(c.path, c.next_path)

        if c.ccdname != "RED":
            offset = int(
                (200 * (c.bin - base_cube.bin) + c.tdi - base_cube.tdi)
                / base_cube.bin
            )
            mos_path = c.next_path.with_suffix(".mosaiced.cub")
            isis.handmos(
                c.next_path,
                mosaic=mos_path,
                create="Y",
                nlines=base_cube.lines,
                nsamples=base_cube.samps,
                nbands=1,
                outline=offset,
                outsamp=1,
                outband=1,
            )
            shutil.move(mos_path, c.next_path)

        if bin_ratio != 1:
            isis.editlab(
                c.next_path,
                options="MODKEY",
                grpname="INSTRUMENT",
                KEYWORD="SUMMING",
                value=base_cube.bin,
            )

    # This section creates flat.tabs for RED4-RED5 pair only
    rows = int(red5.lines / 50)
    isis.hijitreg(
        red4.next_path, match=red5.next_path, row=rows, flat=flat_path
    )

    return
Exemple #4
0
def make_dummy_IR(red: hicolor.HiColorCube, bg: hicolor.HiColorCube):
    bg_slither_path = get_slither_path(bg)
    ir_name = bg_slither_path.name.replace(bg.get_ccd(),
                                           "IR" + str(int(bg.ccdnumber) - 2))
    ir_path = bg_slither_path.parent / ir_name

    if ir_path.exists():
        raise FileExistsError("{} exists ".format(str(ir_path)) +
                              "and we don't want to overwrite it.")

    ir_ccd = "IR" + str(int(red.ccdnumber) + 6)

    isis.mask(red.path, mask=red.path, to=ir_path, preserve="outside")
    isis.editlab(
        ir_path,
        options="modkey",
        grpname="Instrument",
        keyword="CpmmNumber",
        value=int(red.ccdnumber) + 2,
    )
    isis.editlab(
        ir_path,
        options="modkey",
        grpname="Instrument",
        keyword="CcdId",
        value=ir_ccd,
    )
    isis.editlab(
        ir_path,
        options="modkey",
        grpname="Archive",
        keyword="ProductID",
        value="{}_{}".format(red.get_obsid(), ir_ccd),
    )
    isis.editlab(
        ir_path,
        options="modkey",
        grpname="BandBin",
        keyword="Name",
        value="NearInfrared",
    )
    isis.editlab(
        ir_path,
        options="modkey",
        grpname="BandBin",
        keyword="Center",
        value=900,
        units="NANOMETERS",
    )
    isis.editlab(
        ir_path,
        options="modkey",
        grpname="BandBin",
        keyword="Width",
        value=200,
        units="NANOMETERS",
    )
    return ir_path
Exemple #5
0
def HiNoProj(cubes: list,
             conf: dict,
             output="_RED.NOPROJ.cub",
             base=5,
             keep=False):
    logger.info(f"HiNoProj start: {', '.join(map(str, cubes))}")

    cubes = list(map(Cube, cubes))
    cubes.sort()

    if not all(c.ccdname == "RED" for c in cubes):
        raise ValueError("Not all of the input files are RED CCD files.")

    sequences = list()
    for k, g in itertools.groupby(
        (int(c.ccdnumber) for c in cubes),
            lambda x, c=itertools.count(): next(c) - x,
    ):
        sequences.append(list(g))

    if len(sequences) != 1:
        raise ValueError("The given cubes are not a single run of sequential "
                         "HiRISE CCDs, instead there are "
                         f"{len(sequences)} groups with these "
                         f"CCD numbers: {sequences}.")

    if not isinstance(base, int):
        base = hirise.get_CCDID_fromfile(base)
    base_ccd = list(filter(lambda x: x.ccdnumber == str(base), cubes))
    if len(base_ccd) != 1:
        raise ValueError(f"The base ccd, number {base}, "
                         "is not one of the given cubes.")
    base_cube = base_ccd[0]

    conf_check(conf["HiNoProj"])
    conf = conf["HiNoProj"]

    out_p = hcn.set_outpath(output, cubes)

    temp_token = datetime.now().strftime("HiNoProj-%y%m%d%H%M%S")
    to_del = isis.PathSet()

    polar = False
    if conf["Shape"] == "USER":
        polar = is_polar(cubes, conf["Pole_Tolerance"], temp_token)

    for c in cubes:

        temp_p = to_del.add(c.path.with_suffix(f".{temp_token}.spiced.cub"))
        copy_and_spice(c.path, temp_p, conf, polar)

        isis.spicefit(temp_p)

        c.next_path = to_del.add(
            c.path.with_suffix(f".{temp_token}.noproj.cub"))
        c.path = temp_p

    for c in cubes:
        isis.noproj(c.path,
                    match=base_cube.path,
                    to=c.next_path,
                    source="frommatch")

    # Run hijitreg on adjacent noproj'ed ccds to get average line/sample offset
    (cubes, _) = add_offsets(cubes,
                             int(base_cube.ccdnumber),
                             temp_token,
                             keep=keep)

    # Mosaic noproj'ed ccds using average line/sample offset
    shutil.copyfile(base_cube.next_path, out_p)
    logger.info("Original Perl hard codes this file copy from RED5, even if "
                "another cube is selected as the base_ccd.")

    handmos_side(cubes, base_cube, out_p, left=True)
    handmos_side(cubes, base_cube, out_p, left=False)

    isis.editlab(
        out_p,
        option="addkey",
        grpname="Instrument",
        keyword="ImageJitterCorrected",
        value=0,
    )
    fix_labels(
        cubes,
        out_p,
        base_cube,
        "{}_{}".format(str(cubes[0].get_obsid()), cubes[0].ccdname),
    )

    if not keep:
        to_del.unlink()

    logger.info(f"HiNoProj done: {out_p}")

    return
Exemple #6
0
def HiBeautify(cube_paths: list,
               conf: dict,
               out_irb="_IRB.cub",
               out_rgb="_RGB.cub",
               keep=False):
    logger.info(f"HiBeautify start: {', '.join(map(str, cube_paths))}")

    # GetConfigurationParameters()
    cubes = list(map(hcn.ColorCube, cube_paths))
    cubes.sort()

    irb_out_p = hcn.set_outpath(out_irb, cubes)
    rgb_out_p = hcn.set_outpath(out_rgb, cubes)

    temp_token = datetime.now().strftime("HiBeautify-%y%m%d%H%M%S")
    to_del = isis.PathSet()

    # Create an IRB mosaic from the HiColorNorm halves.

    # If a half is missing, we create a mosaic with the proper width and place
    # the half in it at the proper location.
    # Logic ofr image_midpoint and total_width come from original HiColorInit
    # irbmerged_p = to_del.add(out_p.with_suffix(f'.{temp_token}_IRB.cub'))
    image_midpoint = int((2000 / cubes[0].red_bin) + 1)
    outsample = image_midpoint
    if cubes[0].ccdnumber == "4":
        outsample = 1
    total_width = int(2 * cubes[0].samps - (48 / cubes[0].red_bin))

    isis.handmos(
        cubes[0].path,
        mosaic=irb_out_p,
        outline=1,
        outsample=outsample,
        outband=1,
        create="Y",
        nlines=cubes[0].lines,
        nsamp=total_width,
        nbands=3,
    )

    if len(cubes) == 1:
        logger.info("Warning, missing one half!")
    else:
        logger.info("Using both halves")
        isis.handmos(
            cubes[1].path,
            mosaic=irb_out_p,
            outline=1,
            outsample=image_midpoint,
            outband=1,
        )

    # Nothing is actually done to the pixels here regarding the FrostStats, so
    # I'm just going to skip them here.
    #
    # # Determine if Frost/ICE may be present using FrostStats module.
    # frost = None
    # if args.frost:
    #     frost = True
    #     logging.info('Frost override: disabling auto-detection and using '
    #                  'the frost/ice color stretch')
    # if args.nofrost:
    #     frost = False
    #     logging.info('Frost override: disable auto-detection and not using '
    #                  'the frost/ice color stretch')
    # if frost is None:
    #     pass
    #     # get frost stats

    # Subtract the unaltered RED band from the high pass filtered BG for
    # synthetic blue.
    logger.info("Creating synthetic B, subtracting RED from BG")
    rgbsynthb_p = to_del.add(irb_out_p.with_suffix(f".{temp_token}_B.cub"))
    isis.algebra(
        f"{irb_out_p}+3",
        from2=f"{irb_out_p}+2",
        op="subtract",
        to=rgbsynthb_p,
        A=conf["Beautify"]["Synthetic_A_Coefficient"],
        B=conf["Beautify"]["Synthetic_B_Coefficient"],
    )

    # Adjust the BandBin group
    isis.editlab(rgbsynthb_p,
                 grpname="BandBin",
                 keyword="Name",
                 value="Synthetic Blue")
    isis.editlab(rgbsynthb_p, grpname="BandBin", keyword="Center", value="0")
    isis.editlab(rgbsynthb_p, grpname="BandBin", keyword="Width", value="0")

    # HiBeautify gathers and writes a bunch of statistics to PVL that is
    # important to the HiRISE GDS, but not relevant to just producing pixels
    # so I'm omitting it.
    #
    # # Determine the min and max DN values of each band (RED, IR, BG, B) we're
    # # working with.
    # (upper, lower) = conf['Beautify']['Stretch_Exclude_Lines']
    # if upper == 0 and lower == 0:
    #     synthbcrp_p = rgbsynthb_p
    #     irbmrgcrp_p = irbmerged_p
    # else:
    #     synthbcrp_p = to_del.add(
    #           out_p.with_suffix(f'.{temp_token}_Bx.cub'))
    #     irbmrgcrp_p = to_del.add(
    #           out_p.with_suffix(f'.{temp_token}_IRBx.cub'))
    #
    #     for (f, t) in ((rgbsynthb_p, synthbcrp_p),
    #                    (irbmerged_p, irbmrgcrp_p)):
    #         logging.info(isis.crop(f, to=t, propspice=False,
    #                                line=(1 + upper),
    #                                nlines=(
    #                                   cubes[0].lines - lower + upper)).args)
    #
    # stats = dict()
    # stats['B'] = Get_MinMax(synthbcrp_p,
    #                         conf['Beautify']['Stretch_Reduction_Factor'],
    #                         temp_token, keep=keep)
    #
    # for band in cubes[0].band.keys():
    #     stats[band] = Get_MinMax('{}+{}'.format(str(irbmrgcrp_p),
    #                                             cubes[0].band[band]),
    #                              conf['Beautify']['Stretch_Reduction_Factor'],
    #                              temp_token, keep=keep)

    # Create an RGB cube using the RED from the IRB mosaic,
    # the BG from the IRB mosaic and the synthetic B that we just made.
    isis.cubeit_k([f"{irb_out_p}+2", f"{irb_out_p}+3", rgbsynthb_p],
                  to=rgb_out_p)

    if not keep:
        to_del.unlink()

    return
Exemple #7
0
def process_set(
    red: HiColorCube,
    ir: HiColorCube,
    bg: HiColorCube,
    outsuffix: str,
    keep=False,
):
    """Do all of the scaling and cropping for a RED/IR/BG set."""

    if (len(
            set(
                map(
                    lambda c: c.get_obsid(),
                    filter(lambda x: x is not None, [red, ir, bg]),
                ))) != 1):
        raise ValueError("These cube files don't all have the same "
                         f"Observation ID: {red}, {ir}, {bg}")

    temp_token = datetime.now().strftime("HiColorInit-%y%m%d%H%M%S")

    # These two values are calculated but only written to a PVL file,
    # which I think we can skip.
    # # in bin1 there are 48 pixels of overlap
    # total_width = 2 * red.samps - (48 / red.bin)
    #
    # # in bin1, the right half starts at pixel 2001
    # image_midpoint = 2000 / red.bin + 1

    for c in filter(lambda x: x is not None, [ir, bg]):
        # Calculate delta offset in lines between red and color ccd
        offset = int((200 * (c.bin - red.bin) + c.tdi - red.tdi) / red.bin)

        bin_ratio = c.bin / red.bin
        # tdi_ratio = c.tdi / red.tdi
        mag_ratio = bin_ratio / 1.0006
        # ratio of color to red for enlargement, correction of optical
        # distortion from OPTICAL_ENLARGEMENT_RATIO constant in original
        # HiColor.pm

        # Rescale the color by the bin ratio and mag ratio, to match the red.
        # These will be the BG and IR "pre-color" cubes.
        rescaled = c.path.with_suffix(f".{temp_token}.rescaled" + outsuffix)

        if mag_ratio < 1:
            s = 1 / mag_ratio
            isis.reduce(
                c.path,
                to=rescaled,
                sscale=s,
                lscale=bin_ratio,
                validper=1,
                algorithm="nearest",
                vper_replace="nearest",
            )
        else:
            isis.enlarge(
                c.path,
                to=rescaled,
                sscale=mag_ratio,
                lscale=bin_ratio,
                interp="bilinear",
            )

        # The original Perl had an additional step to divide c.bin by the
        # bin_ratio, and provide that to value= below, but that's
        # mathematically just red.bin, so we'll skip a calculation:
        isis.editlab(
            rescaled,
            options="modkey",
            grpname="Instrument",
            keyword="Summing",
            value=red.bin,
        )

        # trim by placing in a new image
        isis.handmos(
            rescaled,
            mosaic=c.path.with_suffix(outsuffix),
            create="Y",
            nlines=red.lines,
            nsamp=red.samps,
            nband=1,
            outline=offset,
            outsamp=1,
            outband=1,
        )

        if not keep:
            rescaled.unlink()

        logger.info(f"Created {c.path.with_suffix(outsuffix)}")
    return