Source code for chimcla.cli

"""
**Important**

Command line interface.
"""

import os
import sys
import argparse
import glob
import random
import tqdm

import addict

from ipydex import IPS, activate_ips_on_exception

# simplify debugging (turn of for production)
activate_ips_on_exception()


# TODO: move this to chimcla interface
[docs] def create_groups(): N = 500 # number of p = 0.4 # fraction of repeated images q = 1 - p # fraction of group specific images Np = int(N*p) # number of Nq = N - Np parser = argparse.ArgumentParser( prog=sys.argv[0], description=f'This program creates directories with {N} cell images each. It also creates a json report', ) parser.add_argument( 'dir', help="root directory", ) args = parser.parse_args() dircontent = os.listdir(args.dir) subdirs = [] elt: str for elt in os.listdir(args.dir): if elt.startswith("_"): continue path = os.path.join(args.dir, elt) if os.path.isdir(path): subdirs.append(path) image_paths = [] for subdir in subdirs: imgs = glob.glob(f"{subdir}/s*.jpg") image_paths.extend(imgs) random.seed(1246) random.shuffle(image_paths) T = len(image_paths) nbr_of_groups = (T // Nq) + 1 groups = [] for i in range(nbr_of_groups): i0 = i*Nq i1 = (i+1)*Nq group = image_paths[i0:i1] rest = image_paths[:i0] + image_paths[i1:] random.shuffle(rest) # the last group might be incomplete, thus we have to determine length every time L = len(group) group.extend(rest[:(N-L)]) groups.append(group) for i, group in tqdm.tqdm(enumerate(groups, start=1)): gdir = os.path.join(args.dir, "_results", f"gruppe{i:04d}") os.makedirs(gdir, exist_ok=True) for fpath in group: fname = os.path.split(fpath)[1] cell_key = fname[:-4].split("_")[-1] target_path = os.path.join(gdir, f"{cell_key}_{fname}") cmd = f"cp {fpath} {target_path}" os.system(cmd)
[docs] def build_parser(): parser = argparse.ArgumentParser( prog="chimcla", description="chimcla main command line interface " "(for all functions which do not have their own script)", ) subparsers = parser.add_subparsers(dest="command", help="") parser_prepare_docs = subparsers.add_parser("prepare-docs", help="prepare automatic generation of docs") parser_build_docs = subparsers.add_parser( "build-docs", help="automatic generation of docs (after preparation)" ) parser_build_docs.add_argument( "docfile", type=str, help="optional file to build (otherwise: build all)", nargs="?", default=None ) parser_continuously_build_docs = subparsers.add_parser( "continuously-build-docs", help="continuous automatic generation of docs (after preparation)" ) parser_bgr_convert = subparsers.add_parser( "bgr-convert", help="convert jpg files from BGR to RGB and vice versa" ) parser_bgr_convert.add_argument("img_dir", type=str, help="directory containing jpg files to convert") parser_split_into_lots = subparsers.add_parser( "split-into-lots", help="distribute a big list of files into subdirectories", ) parser_split_into_lots.add_argument("pathlist", help="txt file containing the paths") parser_split_into_lots.add_argument( "part_size", type=int, help="number of files per part-subdirectory (default: 1000)", nargs="?", default=1000, ) parser_create_work_images = subparsers.add_parser( "create-work-images", help="perform stage 1: creating images for further evaluation", description="perform stage 1: size adaption, empty slot detection, " "incomplete form detection, shading correction", ) parser_create_work_images.add_argument( "img_dir", type=str, help="e.g. /home/ck/mnt/XAI-DIA-gl/Carsten/data_images/lots/2025-09-15_06-17-16__1d__27.9k/part001", ) parser_create_work_images.add_argument( "prefix", help="prefix for newly created dirs during preprocessing", nargs="?", default="pp_" ) parser_create_work_images.add_argument( "--no-parallel", "-np", help="sequential mode (no parallelization)", action="store_true", ) parser.add_argument("--version", action="store_true", help="show chimcla version and exit") # Set description to match help string for subparsers that don't have a description for action in parser._subparsers._actions: if isinstance(action, argparse._SubParsersAction): for choice, subparser in action.choices.items(): if not hasattr(subparser, 'description') or subparser.description is None: # Get the help string from the subparser action for subaction in action._choices_actions: if subaction.dest == choice: subparser.description = subaction.help break return parser
[docs] def main(): parser = build_parser() args = parser.parse_args() if args.version: from .release import __version__ print(__version__) elif args.command == "prepare-docs": from .util_doc import generate_module_docs generate_module_docs() elif args.command == "build-docs": from .util_doc import make_html_doc make_html_doc(args.docfile) elif args.command == "continuously-build-docs": from .util_doc import make_html_doc make_html_doc() elif args.command == "bgr-convert": from .util import bgr_convert bgr_convert(args.img_dir) elif args.command == "split-into-lots": from .util_file_sorting import split_into_lots split_into_lots(pathlist=args.pathlist, part_size=args.part_size) elif args.command == "create-work-images": from . import stage_1a_preprocessing as s1a s1a.main(args=args) else: msg = f"unknown chimcla command: {args.command}" print(msg) sys.exit(1)
[docs] def rename_cell_imgs(): parser = argparse.ArgumentParser( prog=sys.argv[0], description='This program renames image files, such that the cell comes first', ) parser.add_argument( 'dir', help="directory", ) args = parser.parse_args() _rename_cell_imgs(args.dir)
[docs] def _rename_cell_imgs(dirname): fnames = os.listdir(dirname) fnames.sort() for fname in fnames: if not fname.endswith("jpg"): continue cell_key = fname[:-4].split("_")[-1] old_path = os.path.join(dirname, fname) new_path = os.path.join(dirname, f"{cell_key}_{fname}") cmd = f"mv {old_path} {new_path}" os.system(cmd)
# print(cmd) # break
[docs] def pipeline(): """ This is the entry point of the main processing pipeline """ msg =""" Idea: it might be convenient to start the "whole" pipeline with one command However, currently it is unclear whether there will be a use case for this. """ print(msg)