Exemple #1
0
 def delete_sequence(name, force, verbose):
     if not read_sequence(name):
         click.echo(f"Sequence [{name}] does not exist")
         return
     elif not force:
         click.echo(
             f"Use --force to confirm action. Caution: This operation is not reversible"
         )
         return
     sequence = remove_sequence(name)
     pif(verbose, f"Sequence [{name}] removed:\n{', '.join(sequence)}")
 def printable_all(categories, transformations, gap, verbose):
     """ generate printable files with the transformed images """
     os.makedirs(os.path.join(ROOT_DIR, *printable_dir), exist_ok=True)
     for category in categories:
         for transformation in transformations:
             # read available level images
             pif(
                 verbose,
                 f"Generating printable for {category}, {transformation}..."
             )
             generate_pdf(category, transformation, gap, verbose)
    def transform_all(
            categories,
            transformations,
            verbose,
            override,
            circle,
            orientation,
            margin,
            border):
        """ Transform images with available transformations.

        if category is given, transform only the specified categories
        if transformation is given, transform with only the specified transformations
        by default, images will be cropped into a circle, can override this behavior with --no-circle
        if images are cropped, an orientation mark will by default be added, override this behavior with --no-orientation-mark


        """
        post_processors = []
        if circle:
            post_processors.append(crop_to_circle)
            if orientation:
                post_processors.append(add_orientation_marker)
        if margin:
            post_processors.append(
                lambda img: add_margin(
                    img, margin_width=margin))
        if border:
            post_processors.append(
                lambda img: add_border(
                    img, border_width=border))

        for category in categories:
            pif(verbose, f"Processing category {category}...")
            # generate the unmodified reference image
            orig = read_orig(category)
            out_path = os.path.join(
                ROOT_DIR, *image_dir, category, "output.jpg")
            write_image(
                orig,
                out_path,
                post_processors=post_processors,
                override=override,
                verbose=verbose)

            for transformation in transformations:
                pif(verbose, f"Transforming with {transformation}...")
                transform_image_by_category(
                    category,
                    transformation,
                    post_processors=post_processors,
                    override=override,
                    verbose=verbose)
Exemple #4
0
 def new_sequence(name, count, set_name, force, replacement, truncate,
                  verbose):
     if not force and read_sequence(name):
         click.echo(
             f"{name} already exists in sequence data, choose another one or use --force to override"
         )
         return
     sequence = generate_random_sequence(count, set_name, replacement,
                                         truncate)
     write_sequence(name, sequence)
     pif(
         verbose,
         f"Successfully added new sequence [{name}]: {', '.join(sequence)}")
 def rank(agents, categories, transformations, override, verbose):
     """ Calculate spearmanrank and p-value for each agent specified """
     path = os.path.join(ROOT_DIR, *ranked_data_dir)
     os.makedirs(path, exist_ok=True)
     file_path = os.path.join(path, "rank.csv")
     if os.path.isfile(file_path) and not override:
         pif(verbose, f"file at {file_path} exists, skipping...")
         return
     with open(file_path, "w", newline='') as f:
         rank_standard(f=f,
                       agents=agents,
                       categories=categories,
                       transformations=transformations,
                       override=override,
                       verbose=verbose)
     pif(verbose, f"data written into {file_path}")
def rank_standard(f, agents, categories, transformations, override, verbose):
    """ calculate spearman's rank of each category + transformation with each agent.
    comparisons are made against the standard order as listed in the header of each csv file (0-10),

    :f: the file to be written into
    :agents: the agents to be considered
    :categories: the categories to be considered
    :transformations: the transformations to be considered
    :override: override existing files
    :verbose: print output regarding writing status
    :returns: None

    """
    writer = csv.writer(f)
    # The header line
    writer.writerow(
        ['agent', 'category', 'transformation', 'coefficient', 'p-value'])
    for agent in agents:
        # set up data file path for the agent
        csv_file = agent2file(agent)
        if not is_csv(csv_file):
            pif(
                verbose,
                f"{csv_file} does not exist, use the 'decode' command to generate sorted data."
            )
            continue
        pif(verbose, f"calculating ranks for {agent}...")
        # read file
        # the header row and array of data rows
        header, *sorted_data = read_csv(csv_file)
        # TODO: split category_transformation into two separate fields
        # <2020-11-13, David Deng> #
        for category_transformation, *order in sorted_data:
            # get the reference order from the header row
            reference_order = header[1:]
            category, transformation = category_transformation.split(
                csv_subfield_delim)
            # filter category and transformation
            if categories and category not in categories:
                pif(
                    verbose,
                    f"Category {category} not specified, skipping {category}, {transformation}..."
                )
                continue
            if transformations and transformation not in transformations:
                pif(
                    verbose,
                    f"Transformation {transformation} not specified, skipping {category}, {transformation}..."
                )
                continue
            r, p = spearmanr(reference_order, order)  # calculate spm-rank
            writer.writerow([
                agent, category, transformation,
                str(numpy.round(r, decimals=3)),
                str(numpy.round(p, decimals=3))
            ])
def generate_pdf(category, transformation, gap, verbose):
    """generate pdf file with transformed images

    :category: the category of image
    :transformation: the transformation to be used
    :returns: None

    """
    # read available images
    image_paths = read_level_image_paths(category, transformation)
    if len(image_paths) == 0:
        pif(verbose,
            f"Skip {category}, {transformation}, no level images found")
        return None
    # generate pdf
    pdf = FPDF(orientation="L", unit="pt", format="letter")
    pdf.set_auto_page_break(False)
    pdf.set_margins(30, 30, 30)
    pdf.set_font('Arial', 'B', 20)
    pdf.add_page()
    pdf.cell(pdf.w,
             30,
             f"Category: {category}; Transformation: {transformation}",
             border=0,
             ln=1,
             align="C")
    pdf.set_font('Arial', '', 10)
    pdf.cell(
        pdf.w,
        30,
        f"Images to be sorted first from left to right, then from top to bottom. From level_0 to level_10",
        border=0,
        ln=1,
        align="C")
    lay_images(pdf, image_paths, width=240, space=gap)
    output_path = os.path.join(ROOT_DIR, *printable_dir,
                               f"{category}_{transformation}.pdf")
    pdf.output(output_path)
    pif(verbose, f"File written to {output_path}")
 def decode_command(file_names, verbose):
     for file_name in file_names:
         input_path = os.path.join(*raw_sorted_data_dir, file_name)
         output_path = os.path.join(*human_sorted_data_dir, file_name)
         header_line, *rows = read_csv(input_path)
         with open(output_path, "w") as output_file:
             writer = csv.writer(output_file)
             pif(verbose, f"Decoding {file_name}...")
             writer.writerow(
                 [header_line[0], *map(seq_num_formatter, range(1, 11))])
             for sequence_name, *sequence in rows:
                 try:
                     writer.writerow([
                         sequence_name,
                         *decode_sequence(sequence_name, sequence)
                     ])
                 except SequenceError as e:
                     click.echo(
                         f"Sequence Error in {input_path}: {sequence_name}")
                     click.echo(e)
         pif(verbose,
             f"Successfully written decoded sequences into {output_path}")
def transform_image_by_category(
        category,
        transformation,
        levels=range(11),
        extension='jpg',
        override=True,
        verbose=True,
        post_processors=[]):
    """ transform the image of a certain category

    :category: the category to be transformed, assumes that it is a valid category
    :transformation: the transformation to apply
    :levels: an iterable of integers
    :extension: the extension of the output file
    :returns: None

    """
    orig = read_orig(category)
    for level in levels:
        out_dir = os.path.join(ROOT_DIR, *image_dir, category, transformation)
        os.makedirs(out_dir, exist_ok=True)
        out_path = os.path.join(
            out_dir,
            f"level_{level:02}" +
            os.extsep +
            extension)
        # skip image computation if not overriding existing image
        if os.path.isfile(out_path) and not override:
            pif(verbose, f"skip image at {out_path}")
            continue
        out = transform_image(orig, transformation, level)
        write_image(
            out,
            out_path,
            post_processors=post_processors,
            verbose=verbose)
 def sort(categories, transformations, metrics, override, verbose):
     """sort the generated images by comparing them with output.jpg """
     os.makedirs(os.path.join(ROOT_DIR, *metric_sorted_data_dir),
                 exist_ok=True)
     for metric in metrics:
         pif(verbose, f"Metric: {metric}")
         # import the metric module
         mod = importlib.import_module('.'.join([*analysis_dir, metric]))
         Analyzer = getattr(mod, 'Analyzer', None)
         if not Analyzer:
             raise ModuleError(
                 f"no analyzer class implemented in metric {metric}")
         analyzer = Analyzer()
         pif(verbose, f"sorting images with {metric}...")
         # check if file exists
         path = os.path.join(ROOT_DIR, *metric_sorted_data_dir,
                             f"{metric}.csv")
         if os.path.isfile(path) and not override:
             pif(verbose, f"file at {path} exists, skipping...")
             continue
         with open(os.path.join(ROOT_DIR, *metric_sorted_data_dir,
                                f"{metric}.csv"),
                   'w',
                   newline='') as data_file:
             writer = csv.writer(data_file)
             # TODO: remove the subfield delimiter <2020-11-17, David Deng>
             writer.writerow([
                 csv_subfield_delim.join(['CATEGORY', 'TRANSFORMATION']),
                 *map(seq_num_formatter, range(11))
             ])  # header row
             for category in categories:
                 try:
                     orig = read_output(category)
                 except ModuleError as e:
                     pif(verbose, e)
                     pif(verbose, f"Skipping category {category}...")
                     continue
                 for transformation in transformations:
                     pif(
                         verbose,
                         f"category, transformation: {category},{transformation}..."
                     )
                     images = read_level_images(category, transformation)
                     if not images:
                         pif(
                             verbose,
                             f"no level images in {category}_{transformation}, skipping..."
                         )
                         continue
                     images = analyzer.sort(images, orig)  # sorted image
                     order = [
                         seq_num_formatter(get_level_numeric(
                             image.filename)) for image in images
                     ]
                     writer.writerow([
                         csv_subfield_delim.join([category,
                                                  transformation]), *order
                     ])
         pif(verbose, f"data written to {path}")