### Install npm Packages Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/prototype_frontend/README.md Run this command to install the necessary packages for the Electron app. This should be done before starting the development server. ```bash npm install ``` -------------------------------- ### Display Example DataFrames Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/prototyping_notebooks/Statistical Analysis (Latest).ipynb Prints and displays example dataframes for GelGenie and GelAnalyzer to show the structure of the loaded data. ```python print('Example gelgenie data:') gg_dfs['gg_0'] ``` ```python print('Example gelanalyzer data:') ga_dfs['ga_31'] ``` -------------------------------- ### Install GelGenie QuPath Extension Source: https://context7.com/mattaq31/gelgenie/llms.txt Instructions for installing the QuPath software and adding the GelGenie extension by downloading and dragging the .jar file. ```text 1. Install QuPath v0.6.x from https://qupath.readthedocs.io/en/0.6/ 2. Download the latest GelGenie .jar from https://github.com/mattaq31/GelGenie/releases 3. Drag-and-drop the .jar file onto the QuPath main window 4. Run via Extensions → Activate GelGenie ``` -------------------------------- ### Install GelGenie Python Package Source: https://context7.com/mattaq31/gelgenie/llms.txt Steps to set up a Conda environment, install PyTorch, dependencies, and GelGenie in editable mode. Verifies CLI commands. ```bash # 1. Create environment (Python 3.7+) conda create -n gelgenie python=3.9 conda activate gelgenie # 2. Install PyTorch (example: CPU-only) pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu # 3. Install dependencies pip install -r python-gelgenie/requirements.txt # 4. Install GelGenie in editable mode cd python-gelgenie pip install -e . # Verify CLI commands are available gelseg_train --help quick_seg --help export_model --help ``` -------------------------------- ### TOML Configuration for Training Source: https://context7.com/mattaq31/gelgenie/llms.txt Example TOML configuration file for setting up training parameters, data paths, and model architecture. ```toml experiment_name = "unet_experiment" base_dir = "/output/models" [processing] base_hardware = "PC" device = "GPU" pe = 1 [data] n_channels = 1 batch_size = 2 num_workers = 2 dir_train_img = ["/data/train_images"] dir_train_mask = ["/data/train_masks"] dir_val_img = ["/data/val_images"] dir_val_mask = ["/data/val_masks"] split_training_dataset = false apply_augmentations = true padding = false individual_padding = true [model] model_name = "smp_unet" classes = 2 encoder_name = "resnet18" [training] loss = ["dice", "crossentropy"] lr = 1e-4 epochs = 600 grad_scaler = true load_checkpoint = false optimizer_type = "adam" save_checkpoint = true checkpoint_frequency = 1 model_cleanup_frequency = 20 scheduler_type = "CosineAnnealingWarmRestarts" wandb_track = false [training.scheduler_specs] restart_period = 100 ``` -------------------------------- ### Start Development Server Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/prototype_frontend/README.md Execute this command to launch the Electron app in development mode. The Python server needs to be initialized separately. ```bash npm start ``` -------------------------------- ### Seaborn FacetGrid Example with KDE Plots Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/Figure 3 Test Set Analysis.ipynb Demonstrates creating a FacetGrid with overlapping Kernel Density Estimate (KDE) plots using Seaborn. This example generates synthetic data and customizes plot aesthetics, including labels and line styles. ```python sns.set(style="white", rc={"axes.facecolor": (0, 0, 0, 0)}) # Create the data rs = np.random.RandomState(1979) x = rs.randn(500) g = np.tile(list("ABCDEFGHIJ"), 50) df = pd.DataFrame(dict(x=x, g=g)) m = df.g.map(ord) df["x"] += m # Initialize the FacetGrid object pal = sns.cubehelix_palette(10, rot=-.25, light=.7) g = sns.FacetGrid(df, row="g", hue="g", aspect=15, height=.5, palette=pal) # Draw the densities in a few steps g.map(sns.kdeplot, "x", clip_on=False, shade=True, alpha=1, lw=1.5, bw=.2) g.map(sns.kdeplot, "x", clip_on=False, color="w", lw=2, bw=.2) g.map(plt.axhline, y=0, lw=2, clip_on=False) # Define and use a simple function to label the plot in axes coordinates def label(x, color, label): ax = plt.gca() ax.text(0, .2, label, fontweight="bold", color=color, ha="left", va="center", transform=ax.transAxes) g.map(label, "x") # # Changes from seaborn example below this point # # Set the subplots to overlap g.fig.subplots_adjust(hspace=-.25, right=0.9) ``` -------------------------------- ### Display Example Gel Analyzer Data Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/prototyping_notebooks/Data Prep.ipynb Prints and displays an example of the loaded Gel Analyzer data, specifically for the 'ga_31' entry. ```python print('Example gelanalyzer data:') ga_dfs['ga_31'] ``` -------------------------------- ### Quantitative Evaluation Setup Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/prototyping_notebooks/Gel Band Analysis v3.ipynb Sets up parameters and loads datasets for quantitative evaluation of image segmentation models. Requires pandas, os, seaborn, and matplotlib. ```python # fixed terms metrics = ['Dice Score', 'MultiClass Dice Score', 'True Negatives', 'False Positives', 'False Negatives','True Positives'] data_folder = '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/quantitative_evaluation/full_test_set_eval' output_folder = '/Users/matt/Documents/PhD/output' sns.set(style="whitegrid") plt.rcParams['font.family'] = 'Helvetica' title_fontsize = 20 axis_fontsize = 40 tick_fontsize = 22 label_fontsize = 22 metric_of_interest = 'Dice Score' # just dice score is required # images corresponding to each dataset dataset_titles = ['Matthew Gels 1', 'Matthew Gels 2', 'Nathan Gels', 'LSDB Gels', 'Quantitation Gels'] mg_1 = ['8', '13', '38', '62', '81', '105', '108', '114', '128', '132', '140', '143', '146', '161', '168', '179', '183', '187', '205', '214', '220', '230', '235', '242', '251', '257', '263', '292', '307', '312'] mg_2 = ['0', '7', '11', '32', '49', '176', '201', '216', 'mg2_214'] ng = ['UVP01944May172019', 'UVP01947May172019', 'UVP01949May172019', 'UVP02164June252019'] lsdb = ['C50-4', 'C30194', 'C51416', 'C53007', 'C60248', 'C61344', 'E864'] quantg = ['1_Thermo', '8_Thermo', '25_NEB', '29_NEB'] selection = mg_1 + mg_2 + ng + quantg + lsdb # just put in all gels from the test set # loading and gathering datasets datasets = {} for m in metrics: datasets[m] = pd.read_csv(os.path.join(data_folder, 'metrics', m + '.csv'), index_col=0) # custom name for each column/model models = datasets[m].columns custom_names = ['Old U-Net', 'Custom\n U-Net', 'Custom U-Net\n (Extended)', 'LSDB-only\n U-Net', 'LSDB-only U-Net\n (Extended)', 'Watershed', 'Multi-Otsu', 'nnU-Net', 'nnU-Net\n (Extended)'] # actual data for plotting zoom_slice = [1, 7, 3, 5, 6] tick_points = [0, 0.2, 0.4, 0.6, 0.8, 1] zoom_names = [custom_names[i] for i in zoom_slice] zoom_columns = [models[i] for i in zoom_slice] target_df = datasets[metric_of_interest].iloc[:, zoom_slice] ``` -------------------------------- ### Display Example Gel Genie Data Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/prototyping_notebooks/Data Prep.ipynb Prints and displays an example of the loaded Gel Genie data, specifically for the 'gg_0' entry. ```python print('Example gelgenie data:') gg_dfs['gg_0'] ``` -------------------------------- ### Setup for Dice Score Analysis Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/prototyping_notebooks/Gel Band Analysis v3-test-abs.ipynb Initializes parameters and loads datasets for quantitative evaluation. Sets up plotting styles and defines image selections for analysis. ```python # fixed terms metrics = ['Dice Score', 'MultiClass Dice Score', 'True Negatives', 'False Positives', 'False Negatives','True Positives'] data_folder = '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/quantitative_evaluation/full_test_set_eval' output_folder = '/Users/matt/Desktop' sns.set(style="whitegrid") plt.rcParams['font.family'] = 'Helvetica' title_fontsize = 20 axis_fontsize = 40 tick_fontsize = 22 label_fontsize = 22 metric_of_interest = 'Dice Score' # just dice score is required # images corresponding to each dataset dataset_titles = ['Matthew Gels 1', 'Matthew Gels 2', 'Nathan Gels', 'LSDB Gels', 'Quantitation Gels'] mg_1 = ['8', '13', '38', '62', '81', '105', '108', '114', '128', '132', '140', '143', '146', '161', '168', '179', '183', '187', '205', '214', '220', '230', '235', '242', '251', '257', '263', '292', '307', '312'] mg_2 = ['0', '7', '11', '32', '49', '176', '201', '216', 'mg2_214'] ng = ['UVP01944May172019', 'UVP01947May172019', 'UVP01949May172019', 'UVP02164June252019'] lsdb = ['C50-4', 'C30194', 'C51416', 'C53007', 'C60248', 'C61344', 'E864'] quantg = ['1_Thermo', '8_Thermo', '25_NEB', '29_NEB'] selection = mg_1 + mg_2 + ng + quantg + lsdb # just put in all gels from the test set # loading and gathering datasets datasets = {} for m in metrics: datasets[m] = pd.read_csv(os.path.join(data_folder, 'metrics', m + '.csv'), index_col=0) # custom name for each column/model models = datasets[m].columns custom_names = ['Old U-Net', 'Custom\n U-Net', 'Custom U-Net\n (Extended)', 'LSDB-only\n U-Net', 'LSDB-only U-Net\n (Extended)', 'Watershed', 'Multi-Otsu', 'nnU-Net', 'nnU-Net\n (Extended)'] # actual data for plotting zoom_slice = [1, 7, 3, 5, 6] tick_points = [0, 0.2, 0.4, 0.6, 0.8, 1] zoom_names = [custom_names[i] for i in zoom_slice] zoom_columns = [models[i] for i in zoom_slice] target_df = datasets[metric_of_interest].iloc[:, zoom_slice] ``` -------------------------------- ### Full Model Training Pipeline with TrainingHandler Source: https://context7.com/mattaq31/gelgenie/llms.txt Orchestrates dataset loading, model initialization, optimizer/scheduler setup, checkpoint management, and optional Weights & Biases tracking. Instantiate with parameter dictionaries and call `full_training()`. ```python from gelgenie.segmentation.training.core_training import TrainingHandler training_parameters = { 'loss': ['dice', 'crossentropy'], 'loss_component_weighting': [1.0, 1.0], 'lr': 1e-4, 'epochs': 600, 'grad_scaler': True, 'load_checkpoint': False, 'optimizer_type': 'adam', 'scheduler_type': 'CosineAnnealingWarmRestarts', 'scheduler_specs': {'restart_period': 100}, 'save_checkpoint': True, 'checkpoint_frequency': 1, 'model_cleanup_frequency': 20, 'model_cleanup_metric': 'Dice Score', 'class_loss_weighting': False, 'class_loss_weight_damper': 1.0, 'wandb_track': False, 'restart_wandb': False, 'wandb_id': None, } data_parameters = { 'dir_train_img': ['/data/train_images'], 'dir_train_mask': ['/data/train_masks'], 'dir_val_img': ['/data/val_images'], 'dir_val_mask': ['/data/val_masks'], 'split_training_dataset': False, 'n_channels': 1, 'batch_size': 2, 'num_workers': 2, 'apply_augmentations': True, 'weak_augmentations': False, 'padding': False, 'individual_padding': True, } model_parameters = { 'model_name': 'smp_unet', 'classes': 2, 'encoder_name': 'resnet18', 'in_channels': 1, } processing_parameters = { 'device': 'GPU', # 'GPU' or 'CPU' 'base_hardware': 'PC', 'pe': 1, } trainer = TrainingHandler( experiment_name='my_unet_experiment', base_dir='/path/to/output_models', training_parameters=training_parameters, data_parameters=data_parameters, model_parameters=model_parameters, processing_parameters=processing_parameters, ) trainer.full_training() # Checkpoints saved to: /path/to/output_models/my_unet_experiment/checkpoints/ # Training logs: /path/to/output_models/my_unet_experiment/training_logs/ # Segmentation samples: /path/to/output_models/my_unet_experiment/segmentation_samples/ ``` -------------------------------- ### Setup Training and Validation Epoch Runners Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Model Testing.ipynb Creates `TrainEpoch` and `ValidEpoch` objects for iterating through data and performing training/validation steps. Specifies the model, loss, metrics, optimizer, and device. ```python # create epoch runners # it is a simple loop of iterating over dataloader`s samples train_epoch = smp.utils.train.TrainEpoch( model, loss=loss, metrics=metrics, optimizer=optimizer, device=torch.device('cuda' if torch.cuda.is_available() else 'cpu'), verbose=True, ) valid_epoch = smp.utils.train.ValidEpoch( model, loss=loss, metrics=metrics, device=torch.device('cuda' if torch.cuda.is_available() else 'cpu'), verbose=True, ) ``` -------------------------------- ### Initial Band Intensity Summation and Plotting Setup Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/early_attempts_at_band_data_analysis/lab_gel_quantitation.ipynb Initializes figure and axes for plotting, and begins iterating through unique labeled bands to calculate intensity sums. This is part of the early attempts at band data analysis. ```python # checking to see if order of bands matches actual ladder order fig,ax = plt.subplots(2,10,figsize=(10,8)) seg_intensity_sum = [] for sel_val in np.unique(labeled_bands): if sel_val == 0: continue pixel_intensities = np.sum(im_snapshot[labeled_bands==sel_val]) seg_intensity_sum.append(pixel_intensities) pixel_count = len(im_snapshot[labeled_bands==sel_val]) combined = pixel_intensities / pixel_count # combined_all.append(combined) # pixel_all.append(pixel_intensities) if sel_val == 1: ref_val = combined id_text = 'Band %s,\n area: %s \n pixels: %s,\n ratio: %.2f' % (sel_val, pixel_intensities, pixel_count, combined/ref_val) new_im = np.zeros((im_snapshot.shape)) new_im[labeled_bands==sel_val] = sel_val if sel_val > 10: col = 1 sel_val -= 11 else: sel_val -= 1 col = 0 ax[col,sel_val].imshow(new_im) ax[col,sel_val].axis('off') # ax[col,sel_val].set_title(id_text) ax[col,9].axis('off') plt.tight_layout() ``` -------------------------------- ### Initialize Data Structures and Define Intensity Lists Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/paper_revisions/image_studio_figure_1.ipynb Initializes defaultdicts for storing prediction and error data, and defines lists for high and low intensity gel names. This setup is crucial for organizing the data processing pipeline. ```python blind_pred_dict = defaultdict(list) all_error_dict = defaultdict(list) all_error_no_abs_dict = defaultdict(list) descriptor_dict = defaultdict(list) high_intensity = ['3_Thermo', '4_Thermo', '6_Thermo', '7_Thermo', '8_Thermo', '10_Thermo', '11_Thermo', '12_Thermo', '17_NEB', '19_NEB', '20_NEB', '21_NEB', '24_NEB', '29_NEB', '31_NEB', '32_Thermo', '33_NEB'] low_intensity = ['0_Thermo', '1_Thermo', '2_Thermo', '5_Thermo', '9_Thermo', '13_NEB', '14_NEB', '15_NEB', '16_NEB', '18_NEB', '22_NEB', '23_NEB', '34_Thermo'] ``` -------------------------------- ### Initialize UNet Model and Paths Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Eval Testing.ipynb Sets up the image path, checkpoint file path, and initializes a smp_UNet model. This is a prerequisite for running model inference or testing. Ensure 'smp_UNet' is imported and available. ```python images_path = "C:/2022_Summer_Intern/NEB_Gel_Images" # checkpoint_file_path = "C:/Users/s2137314/Downloads/checkpoint_epoch450.pth" # checkpoint_file_path = "C:/Users/s2137314/Downloads/smp-UNet-with-augmentations-checkpoint_epoch300.pth" # checkpoint_file_path = "C:/2022_Summer_Intern/smp-UNet_No_Augmentations_epoch_180/smp-UNet-no-augmentations-checkpoint_epoch180.pth" checkpoint_file_path = "C:/2022_Summer_Intern/smp-UNet_No_pretrain_epoch_260_0.8553/smp-UNet_pretrain_imagenet_checkpoint_epoch260.pth" n_channels = 1 # net = UNet(n_channels=1, n_classes=2, bilinear=False) net = smp_UNet( encoder_name="resnet18", # choose encoder, e.g. mobilenet_v2 or efficientnet-b7 in_channels=1, # model input channels (1 for gray-scale images, 3 for RGB, etc.) classes=2, # model output channels (number of classes in your dataset) ) ``` -------------------------------- ### Initialize Paths and Data Mappings Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/early_attempts_at_band_data_analysis/final_quantitation.ipynb Sets up base directories for data, output, and image storage. Defines a dictionary to map sample types to their respective ladder manufacturers and a dictionary containing the mass ladder data for each manufacturer. This configuration is essential for organizing and processing gel images. ```python common_base = '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer' base_data_folder = '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/quantitation' output_folder = '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/quantitative_results' image_dump = join(output_folder, 'base_data') data_keys = { 'dynabeads': 'Thermo', 'origami': 'NEB', 'nathan': 'NEB', 'others': 'NEB' } # NEB: https://www.neb.com/en-gb/products/n0550-quick-load-purple-1-kb-plus-dna-ladder#Product%20Information # Thermo: https://www.thermofisher.com/order/catalog/product/10787018?SID=srch-srp-10787018 ladder_masses = { 'NEB': [40, 40, 48, 40, 32, 120, 40, 57, 45, 122, 34, 31, 27, 23, 124, 49, 37, 32, 61], 'Thermo':[20, 20, 20, 20, 20, 20, 20, 20, 20, 70, 30, 30, 30, 30, 30, 30, 30, 40] } ladder_dict = {} ``` -------------------------------- ### Get image shape Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Model Threshold Testing.ipynb Retrieves and displays the shape of the loaded image. ```python image.shape ``` -------------------------------- ### Get Label Array Shape Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/early_attempts_at_band_data_analysis/lab_gel_quantitation_v2.ipynb Retrieves the dimensions of the 'e_direct_labels' array. ```python e_direct_labels.shape ``` -------------------------------- ### Get Length of Ladder Errors Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/prototyping_notebooks/Gel Band Analysis v3-test-abs.ipynb Retrieves the number of error entries recorded for the 'Ladder' column. ```python len(error_dict['Ladder']) ``` -------------------------------- ### Prepare and Display Image for Viewing Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/PhD Thesis Image Generation.ipynb Prepares an image for viewing by setting pixel values below a threshold to zero and displays the input marker array using a grayscale colormap. ```python view_image = np.copy(original_image) view_image[view_image < 0.15] = 0 plt.figure(figsize=(10,10)) plt.imshow(input_marker_array,cmap='gray') ``` -------------------------------- ### Get Image Shape Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/early_attempts_at_band_data_analysis/lab_gel_quantitation_v2.ipynb Retrieves the dimensions (height, width, channels) of the masked image array. ```python masked_im.shape ``` -------------------------------- ### Resume Training from Epoch Source: https://context7.com/mattaq31/gelgenie/llms.txt Resumes model training from a specified checkpoint. Requires a TOML configuration file. ```bash gelseg_train \ --parameter_config my_config.toml \ --load_checkpoint 100 ``` -------------------------------- ### Getting Pixel Count in a Region Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/early_attempts_at_band_data_analysis/lab_gel_quantitation_v2.ipynb Calculates the number of pixels within a specified rectangular region of the image. ```python len(e_im[890:960,397:468]) ``` -------------------------------- ### Get Mask Dimensions Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Model Threshold Testing.ipynb Extracts the height and width from the processed mask array. These dimensions are used for iterating through the mask pixels. ```python height, width = mask_pred_array.shape[0], mask_pred_array.shape[1] ``` -------------------------------- ### Initialize UNet Segmentation Model and Data Paths Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/PhD Thesis Image Generation.ipynb Sets up the paths for images and a pre-trained checkpoint, and initializes a UNet model. This is typically done before training or inference. ```python images_path = "../../../scratch_data/q2" checkpoint_file_path = "/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/segmentation_models/smp-UNet_No_Augmentations/checkpoints/checkpoint_epoch390.pth" n_channels = 1 net = smp_UNet( ``` -------------------------------- ### Get Shape of Processed Image Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Testing Augmentations.ipynb Retrieves and prints the shape of the processed image array after squeezing and converting to a NumPy array. ```python images.squeeze().numpy().shape ``` -------------------------------- ### Initialize Data Structures for High and Low Band Analysis Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/prototyping_notebooks/Analysis on Merged DF.ipynb Sets up dictionaries to store data for high and low bands separately and defines a cutoff band value. This is a preparatory step for a more granular analysis of algorithm performance based on band intensity. ```python sel_quantities = [ 'Normalized_GG Raw Difference', 'Normalized_GA Raw Difference', 'GA Background Difference', 'Local Difference', 'Global Difference', 'Rolling Ball Difference'] data_package_high = defaultdict(list) data_package_low = defaultdict(list) cutoff_band = 8 ``` -------------------------------- ### Invert Image using PIL Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Moving and Renaming Matthew Gels.ipynb Inverts an image using PIL and saves it to a specified path. Ensure the PIL library is installed. ```python im = im.convert('RGB') inverted_image = PIL.ImageOps.invert(im) inverted_image.save('/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/originals/newly_inv/288.tif') ``` -------------------------------- ### Get Segmentation Mask Shape Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/early_attempts_at_band_data_analysis/lab_gel_quantitation.ipynb Prints the shape of the generated segmentation mask. This is useful for debugging and understanding the output dimensions of the model. ```python segmentation_mask.shape ``` -------------------------------- ### Define Data Directories and Parameters Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Testing Augmentations.ipynb Sets up paths for training and validation image/mask data, and defines parameters for data loading and augmentation. ```python dir_train_img = 'C:/2022_Summer_Intern/Gel_Images_UNet_Test/Final_Set/Training_Set/Images' dir_train_mask = 'C:/2022_Summer_Intern/Gel_Images_UNet_Test/Final_Set/Training_Set/Masks' dir_val_img = 'C:/2022_Summer_Intern/Gel_Images_UNet_Test/Final_Set/Validation_Set/Images' dir_val_mask = 'C:/2022_Summer_Intern/Gel_Images_UNet_Test/Final_Set/Validation_Set/Masks' n_channels = 1 img_scale = 1 val_percent = 0.1 batch_size = 4 num_workers = 1 apply_augmentations = True padding = True ``` -------------------------------- ### Define and Run Training Loop Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Training.ipynb Sets up and executes the neural network training process. This includes data preparation, optimizer and loss function initialization, and iterating through epochs with validation steps. Mixed precision and image scaling are configurable. ```python def train_net(net, device, epochs: int = 5, batch_size: int = 1, learning_rate: float = 1e-5, val_percent: float = 0.1, save_checkpoint: bool = True, img_scale: float = 0.5, amp: bool = False): # 1. Create dataset dataset = BasicDataset(dir_img, dir_mask, img_scale) # 2. Split into train / validation partitions n_val = int(len(dataset) * val_percent) n_train = len(dataset) - n_val train_set, val_set = random_split(dataset, [n_train, n_val], generator=torch.Generator().manual_seed(0)) # 3. Create data loaders loader_args = dict(batch_size=batch_size, num_workers=4, pin_memory=True) train_loader = DataLoader(train_set, shuffle=True, **loader_args) val_loader = DataLoader(val_set, shuffle=False, drop_last=True, **loader_args) # (Initialize logging) experiment = wandb.init(project='U-Net', resume='allow', anonymous='must') experiment.config.update(dict(epochs=epochs, batch_size=batch_size, learning_rate=learning_rate, val_percent=val_percent, save_checkpoint=save_checkpoint, img_scale=img_scale, amp=amp)) logging.info(f'''Starting training: Epochs: {epochs} Batch size: {batch_size} Learning rate: {learning_rate} Training size: {n_train} Validation size: {n_val} Checkpoints: {save_checkpoint} Device: {device.type} Images scaling: {img_scale} Mixed Precision: {amp} ''') # 4. Set up the optimizer, the loss, the learning rate scheduler and the loss scaling for AMP optimizer = optim.RMSprop(net.parameters(), lr=learning_rate, weight_decay=1e-8, momentum=0.9) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'max', patience=2) # goal: maximize Dice score grad_scaler = torch.cuda.amp.GradScaler(enabled=amp) criterion = nn.CrossEntropyLoss() global_step = 0 # 5. Begin training for epoch in range(1, epochs+1): net.train() epoch_loss = 0 with tqdm(total=n_train, desc=f'Epoch {epoch}/{epochs}', unit='img') as pbar: for batch in train_loader: images = batch['image'] true_masks = batch['mask'] assert images.shape[1] == net.n_channels, \ f'Network has been defined with {net.n_channels} input channels, ' \ f'but loaded images have {images.shape[1]} channels. Please check that ' \ 'the images are loaded correctly.' images = images.to(device=device, dtype=torch.float32) true_masks = true_masks.to(device=device, dtype=torch.long) with torch.cuda.amp.autocast(enabled=amp): masks_pred = net(images) loss = criterion(masks_pred, true_masks) \ + dice_loss(F.softmax(masks_pred, dim=1).float(), F.one_hot(true_masks, net.n_classes).permute(0, 3, 1, 2).float(), multiclass=True) optimizer.zero_grad(set_to_none=True) grad_scaler.scale(loss).backward() grad_scaler.step(optimizer) grad_scaler.update() pbar.update(images.shape[0]) global_step += 1 epoch_loss += loss.item() experiment.log({ 'train loss': loss.item(), 'step': global_step, 'epoch': epoch }) pbar.set_postfix(**{'loss (batch)': loss.item()}) # Evaluation round division_step = (n_train // (10 * batch_size)) if division_step > 0: if global_step % division_step == 0: histograms = {} for tag, value in net.named_parameters(): tag = tag.replace('/', '.') histograms['Weights/' + tag] = wandb.Histogram(value.data.cpu()) histograms['Gradients/' + tag] = wandb.Histogram(value.grad.data.cpu()) val_score = evaluate(net, val_loader, device) scheduler.step(val_score) logging.info('Validation Dice score: {}'.format(val_score)) experiment.log({ 'learning rate': optimizer.param_groups[0]['lr'], ``` -------------------------------- ### Get Number of Labels Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Eval Testing.ipynb Retrieves the total number of labels identified. This is typically used to control loops or set array sizes. ```python nlabels ``` -------------------------------- ### Define Dataset Directory Paths and Parameters Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Model Testing.ipynb Sets up directory paths for training and validation images/masks, along with parameters like number of channels, image scale, validation split, batch size, and augmentation settings. ```python dir_train_img = 'C:/2022_Summer_Intern/Gel_Images_UNet_Test/Final_Set/Training_Set/Images' dir_train_mask = 'C:/2022_Summer_Intern/Gel_Images_UNet_Test/Final_Set/Training_Set/Masks' dir_val_img = 'C:/2022_Summer_Intern/Gel_Images_UNet_Test/Final_Set/Validation_Set/Images' dir_val_mask = 'C:/2022_Summer_Intern/Gel_Images_UNet_Test/Final_Set/Validation_Set/Masks' n_channels = 1 img_scale = 0.5 val_percent = 0.1 batch_size = 1 num_workers = 0 apply_augmentations = False padding = True ``` -------------------------------- ### Prepare DataLoader and Visualize Augmentations Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Testing Augmentations.ipynb Prepares the data loader and iterates through a batch to visualize augmented images, superimposed masks, and true masks. ```python train_loader, val_loader, n_train, n_val = prep_dataloader( dir_train_img, dir_train_mask, dir_val_img, dir_val_mask, n_channels, img_scale, val_percent, batch_size, num_workers, apply_augmentations, padding) # nrows = n_train fig, axs = plt.subplots(nrows = 4, ncols = 3, figsize=(20,60)) count = 0 for batch in train_loader: images = batch['image'] true_masks = batch['mask'] for image, true_mask in zip(images, true_masks): image_array = image.squeeze().numpy() true_mask_array = true_mask.squeeze().numpy() combi_mask_array = np.zeros((1360, 1360, 3)) for row in range(1360): for column in range(1360): if true_mask_array[row][column] == 1: combi_mask_array[row][column] = [1, 0, 0] else: combi_mask_array[row][column] = np.repeat(image_array[row][column], 3) axs[count][0].imshow(image_array, cmap='gray') axs[count][1].imshow(combi_mask_array) axs[count][2].imshow(true_mask_array, cmap='gray') print(count) count += 1 break # axs[0][0].set_title('Augmented Image') # axs[0][1].set_title('Augmented Mask Superimposed') # axs[0][2].set_title('Augmented Mask') plt.setp(plt.gcf().get_axes(), xticks=[], yticks=[]) # remove ticks plt.tight_layout() ``` -------------------------------- ### Import Libraries for GelGenie Analysis Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/Figure 4 GelGenie Paper Re-Analysis.ipynb Imports all necessary libraries for data manipulation, plotting, and file operations. Ensure these libraries are installed in your environment. ```python from pathlib import Path import os from os.path import join import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from matplotlib.backends.backend_pdf import PdfPages import re from gelgenie.segmentation.helper_functions.general_functions import create_dir_if_empty, index_converter from collections import defaultdict import pickle import math from scipy.stats import linregress import pingouin import matplotlib as mpl ``` -------------------------------- ### Prepare DataLoaders for Kiros Model Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Model Testing.ipynb Sets up training and validation datasets and creates PyTorch DataLoaders. Ensure `BasicDataset` and necessary directories are defined. ```python from torch.utils.data import DataLoader train_set = BasicDataset(dir_train_img, dir_train_mask, n_channels, img_scale, augmentations=None, padding=padding) val_set = BasicDataset(dir_val_img, dir_val_mask, n_channels, img_scale, augmentations=None, padding=padding) n_train = int(len(train_set)) n_val = int(len(val_set)) # 3. Create data loaders loader_args = dict(batch_size=batch_size, num_workers=num_workers, pin_memory=True) train_loader = DataLoader(train_set, shuffle=True, **loader_args) val_loader = DataLoader(val_set, shuffle=False, drop_last=True, batch_size=1, num_workers=1, pin_memory=True) ``` -------------------------------- ### Get Type of Tensor Scalar Value Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Kiros Training.ipynb Determines the Python type of the scalar value extracted from a PyTorch tensor using the '.item()' method. ```python type(tensorfloat.item()) ``` -------------------------------- ### Get Albumentations Augmentation Pipelines Source: https://context7.com/mattaq31/gelgenie/llms.txt Use `get_training_augmentation` for full augmentation or `get_nondestructive_training_augmentation` for fine-tuning. These can be attached to datasets or applied manually to NumPy arrays. ```python from gelgenie.segmentation.data_handling.augmentations import ( get_training_augmentation, get_nondestructive_training_augmentation ) from gelgenie.segmentation.data_handling.dataloaders import ImageMaskDataset # Full augmentation pipeline (recommended for training from scratch) augmentations = get_training_augmentation() # Lightweight pipeline (flips + rotations only, for fine-tuning) light_augmentations = get_nondestructive_training_augmentation() # Attach augmentations to dataset dataset = ImageMaskDataset( images_dir='/data/train_images', masks_dir='/data/train_masks', n_channels=1, individual_padding=True, augmentations=augmentations, ) # Manually apply to a numpy image + mask import numpy as np image = np.random.rand(512, 256).astype(np.float32) mask = np.random.randint(0, 2, (512, 256)).astype(np.uint8) sample = augmentations(image=image, mask=mask) augmented_image = sample['image'] # numpy array, same dtype augmented_mask = sample['mask'] # numpy array, integer labels preserved ``` -------------------------------- ### Get Input Tensor Shape Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Testing and Debugging Converting a PyTorch Model to ONNX Format.ipynb Retrieves the shape of the input tensor for a model. This is often useful for debugging or understanding model input requirements. ```python batch['image'].shape ``` -------------------------------- ### Initialize Dataset and DataLoader Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Early Dataset Prototyping.ipynb Sets up the ImageMaskDataset and DataLoader for processing gel images and masks. Ensure input and mask folders are correctly specified. ```python input_folder = [ '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/matthew_gels/val_images', '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/matthew_gels_2/val_images', '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/nathan_gels/val_images', '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/quantitation_ladder_gels/val_images', '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/lsdb_gels/val_images'] mask_folder = [ '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/matthew_gels/val_masks', '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/matthew_gels_2/val_masks', '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/nathan_gels/val_masks', '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/quantitation_ladder_gels/val_masks', '/Users/matt/Documents/PhD/research_output/Automatic_Gel_Analyzer/data/processed_gels/maximal_set/lsdb_gels/val_masks'] dataset = ImageMaskDataset(input_folder, mask_folder, 1, padding=False, individual_padding=True) dataloader = DataLoader(dataset, shuffle=False, batch_size=1, num_workers=0, pin_memory=True) ``` -------------------------------- ### Get Input Image Shape Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Testing and Debugging Converting a PyTorch Model to ONNX Format.ipynb Prints the shape of the input image tensor from a batch. This is useful for verifying data dimensions before model inference. ```python batch['image'].shape ``` -------------------------------- ### Import Libraries for Data Preparation Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/prototyping_notebooks/Data Prep.ipynb Imports essential Python libraries for data manipulation, file system operations, and plotting. Ensure these are installed before running. ```python from pathlib import Path import os from os.path import join import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from matplotlib.backends.backend_pdf import PdfPages import re from gelgenie.segmentation.helper_functions.general_functions import create_dir_if_empty ``` -------------------------------- ### Initialize Training Image and Mask Arrays Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Testing a Random Forest Segmenter.ipynb Initializes NumPy arrays to store training images and masks. This is a placeholder and noted as potentially too slow for actual use. ```python # not worth doing - too slow train_images = np.zeros((99, 1376, 1376)) train_masks = np.zeros((99, 1376, 1376)) for index, batch in enumerate(tqdm(t_data)): train_images[index, :] = batch['image'].numpy() train_masks[index, :] = batch['mask'].numpy() ``` -------------------------------- ### Import Libraries for Gel Analysis Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/early_attempts_at_band_data_analysis/lab_gel_quantitation_v2.ipynb Imports necessary Python libraries for image processing, data manipulation, and plotting. Ensure these libraries are installed before running. ```python import numpy as np from PIL import Image import matplotlib.pyplot as plt from scipy import ndimage as ndi from skimage.color import label2rgb import scipy from torch.utils.data import DataLoader import torch.nn.functional as F from gelgenie.segmentation.networks.UNets.model_gateway import smp_UNetPlusPlus from gelgenie.segmentation.data_handling.dataloaders import ImageDataset import torch from scipy import ndimage as ndi import pandas as pd from os.path import join import toml from gelgenie.segmentation.networks import model_configure from tqdm.notebook import tqdm as tqdm from gelgenie.segmentation.evaluation.core_functions import model_predict_and_process import ipywidgets as wdg ``` -------------------------------- ### Load Data, Evaluate Model, and Visualize Segmentation Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/PhD Thesis Image Generation.ipynb Sets up a dataset and dataloader, evaluates a neural network on test data, processes predictions to identify and label regions, calculates centers of mass and distances, and visualizes the segmentation overlay. ```python test_set = BasicDataset(images_path, n_channels, padding=True) n_test = int(len(test_set)) test_loader = DataLoader(test_set, shuffle=False, batch_size=1, num_workers=0, pin_memory=True) net2.eval() # net.load_state_dict(saved_dict) # fig, ax = plt.subplots(n_test, 3, figsize=(10, 120)) plot_row = 0 for image in test_loader: with torch.no_grad(): mask_pred = net2(image) image = image.squeeze() mask_pred.squeeze() mask_pred_array = np.transpose(mask_pred.detach().squeeze().cpu().numpy(), (1, 2, 0)) # CHW to HWC height, width = mask_pred_array.shape[0], mask_pred_array.shape[1] threshold = 0.8 thresholded = np.zeros((height, width)) for row in range(height): for column in range(width): if mask_pred_array[row][column][0] < (1-threshold) and mask_pred_array[row][column][1] > threshold: thresholded[row][column] = 1 # use a boolean condition to find where pixel values are > 0.75 blobs = thresholded == 1 # label connected regions that satisfy this condition labels, nlabels = ndimage.label(blobs, structure=[[1,1,1],[1,1,1],[1,1,1]]) # find their centres of mass. in this case I'm weighting by the pixel values in # `img`, but you could also pass the boolean values in `blobs` to compute the # unweighted centroids. r, c = np.vstack(ndimage.center_of_mass(thresholded, labels, np.arange(nlabels) + 1)).T # find their distances from the top-left corner d = np.sqrt(r*r + c*c) # Get coordinates for each unique band # create array of intensities volume_labels = np.zeros((nlabels+1), float) area_labels = np.zeros((nlabels+1), int) for h in range(height): for w in range(width): volume_labels[labels[h][w]] += image[h][w] # index = label, value += intensity(between 0 and 1) area_labels[labels[h][w]] += 1 original_image = image.detach().squeeze().cpu().numpy() plt.figure(figsize=(10, 10)) plt.imshow(original_image, cmap='gray') plt.imshow(np.ma.masked_array(labels, ~blobs), cmap=plt.cm.rainbow) ``` -------------------------------- ### Import Libraries for Gel Analysis Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/paper_figure_generation/early_attempts_at_band_data_analysis/lab_gel_quantitation.ipynb Imports necessary libraries for image processing, numerical operations, deep learning, and plotting. Ensure all these libraries are installed. ```python import numpy as np from PIL import Image import matplotlib.pyplot as plt from scipy import ndimage as ndi from skimage.color import label2rgb import scipy from torch.utils.data import DataLoader import torch.nn.functional as F from gelgenie.segmentation.networks.UNets.model_gateway import smp_UNetPlusPlus from gelgenie.segmentation.data_handling.dataloaders import ImageDataset import torch from scipy import ndimage as ndi ``` -------------------------------- ### Run Inference with OpenCV DNN Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Testing and Debugging Converting a PyTorch Model to ONNX Format.ipynb Sets the input for an OpenCV DNN model and performs a forward pass to get predictions. The output shape is then printed. ```python cv_net.setInput(np_im) out = cv_net.forward() out.shape ``` -------------------------------- ### Prepare for ONNX Model Creation Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/Testing and Debugging Converting a PyTorch Model to ONNX Format.ipynb Sets the PyTorch model to evaluation mode and prepares a sample batch of data for exporting to ONNX. This step is crucial before the actual ONNX export. ```python # ONNX MODEL CREATION net.eval() def to_numpy(tensor): return tensor.detach().cpu().numpy() if tensor.requires_grad else tensor.cpu().numpy() for im_index, batch in enumerate(dataloader): torch_out = net(batch['image']) break ``` -------------------------------- ### Initialize UNet Model and Set Paths Source: https://github.com/mattaq31/gelgenie/blob/main/python-gelgenie/gelgenie/segmentation/notebook_testing_and_evaluation/PhD Thesis Image Generation.ipynb Initializes a U-Net model with a specified encoder, encoder weights, input channels, and number of classes. Also sets the path for image data. ```python from torchinfo import summary net2 = smp_UNet( encoder_name="resnet18", # choose encoder, e.g. mobilenet_v2 or efficientnet-b7 encoder_weights="ssl", # use `imagenet` pretreined weights for encoder initialization in_channels=1, # model input channels (1 for gray-scale images, 3 for RGB, etc.) classes=2, # model output channels (number of classes in your dataset) ) images_path = "../../../scratch_data/q2" ```