Content area
Virological plaque assays are the primary method for quantifying infectious particles in a suspension, achieved by incubating a serial dilution of the virus with a monolayer of indicator cells. Existing software tools for quantification of plaque assay images lack modularity, show measurements disagreement or are closed-source - a common hurdle in bioimage analysis. We introduce PyPlaque, an open-source Python package focusing on flexibility and modularity rather than a bulky graphic user interface. Unlike previous methods, an abstracted architecture using object-oriented programming allows accommodation of various experimental containers and specimen carriers as data structures while focusing on phenotype-specific information. Aligned with the logical flow of experimental design and desired quantifications, it delivers insights at multiple granularity levels, facilitating detailed analysis. We demonstrate how this approach allows to focus on alleviating the disagreement in measurements. Furthermore, similar design is generalisable to diverse datasets in various biological contexts that fit our structural paradigm.
Introduction
The ongoing SARS-CoV-2 pandemic proved that our ability to detect and quantify viruses is vital for stepping up our efforts to both diagnose and research emerging pathogens in a timely fashion. Yet, while a number of novel assays have been developed or improved1, 2–3, the virological plaque assay4,5 remains the only existing way to measure infectious virus isolates and quantify viral spread in tissue culture6, 7–8. Unlike other assays aiming to quantify a proxy of infection like viral proteins (antigen), gene products (PCR or rtPCR) or disease manifestations (chest X-Ray), the virological plaque assay measures the ability of the isolated or cultured infectious virus to infect cells and produce progeny infectious virions infecting the cells thereafter - a property remaining at the very core of virus virulence.
While slight variations of the plaque assay exist depending on the pathogen, tissue culture, format, or recording method, at its core, every plaque assay requires two main components, a highly diluted (low multiplicity of infection) inoculum and cultured indicator cells4,5. An infection assay set up in such a way will result in only a few infected cells, typically, within a confluent monolayer of indicator cells4. Upon incubation for the duration of at least one full replication cycle of the pathogen, the initially infected cells will release their infectious progeny. These will, in turn, infect the neighbouring indicator cells leading to the emergence of the clonal patterns of spread. At the right dilution of the inoculum, these patterns will not overlap, allowing the observer to simply count them, thus quantifying the number of infectious particles in the inoculum measured as the number of plaque-forming units (PFU) per unit of volume. As the pathogen spreading patterns may often be intricate, measurements are often performed manually by a trained specialist.
Beyond the quantification of infectious particles, however, virological plaque assay represents a model system allowing to study virus spread phenotypes9, 10–11. Specifically, the size, shape, and consistency of plaques, as well as the patterns and motion trajectories of the infected cells constituting the virological plaque may reveal a great deal of information about the underlying biological mechanisms leading to the formation of such phenotypes10, 11–12. Therefore, harnessing this information through computational analysis of biomedical images is an invaluable tool for analysing known and emerging viruses.
To analyse virological plaque images computationally, apart from custom project-related or closed-source code, several approaches have been proposed9,11,13, 14, 15, 16, 17–18. However, while useful for a broad range of applications, the vast majority of these tools remain highly specialised. For example, Plaque 2.09,11, Infection Counter14, and SCFQ16 are aimed exclusively at fluorescence microscopy. At the same time, the ViralPlaque13 plugin for ImageJ/Fiji19 software is highly tuned for well-separated crystal-violet-stained plaques. Additionally, Plaque 2.09,11, and SCFQ16 specialise in high-content images. Plaque Size Tool17, in turn, while more versatile from the image source perspective requires only well-separated plaques. Other tools, like Viridot15 are dedicated to one specific virus only. Finally, all tools existing thus far, are highly reliant on user input via the graphic user interface and don’t support modern open-source data analysis languages like Python.
Such a highly scattered landscape of tools indicates that despite the seeming similarity, all these tools were developed for their own purpose. Being a fundamental assay in Infection Biology, plaque assay is performed slightly differently depending on the pathogen, imaging techniques, indicator cell types, throughput requirements, and reagent availability. Furthermore, should the purpose of the assay lay beyond the quantification of PFU, more often than not the plaque assay would be specialised to the final requirements of the study. Evidently, should a unified solution exist in such a case, it would require a great degree of flexibility while taking care of the complexity of plaque assay.
To address this, here we propose PyPlaque20 - an open-source Python package allowing to simplify plaque assay analysis. Unlike the graphic-user-interface-based tools mentioned above, PyPlaque takes a radically different approach. Instead of a no-code solution, we provide a convenient library that lowers the amount of code required to analyse plaque assay data while maintaining ultimate analysis flexibility. We achieve this by providing Python data structures (akin to Pandas21 for tabular data). Using these data structures, PyPlaque allows users to account for experiments, dishes or plates and plaque phenotypes. Utilising Python features like IPython/Jupyter22,23 interactive notebooks, such scripts or notebooks could be rapidly created and shared.
All of PyPlaque’s properties mentioned above give it the following important advantages. Firstly, integrability with modern-day data science tools like Jupyter notebooks23, Pandas24, and Matplotlib25. Secondly, simplicity of maintenance and flexibility of user contributions through the use of the most popular coding language to date – i.e. Python26. Thirdly, modularity – PyPlaque is built from individual importable modules which can be used, mixed and matched at will. This also means that the addition of modules, classes, methods and functions is easier and does not disrupt existing functionality. Finally, flexibility to build own workflows and choose a way to interact. Users are free to choose whether they would like to use Jupyter or Python scripts and interact with the package.
PyPlaque is aimed at programming-savvy biologists and significantly simplifies the development of highly-optimised plaque assay quantification scripts. Leveraging the vast data analysis package ecosystem of Python, notebooks can be adapted by fellow researchers, who may need a set of specialised modifications. We demonstrate the versatility of our approach on several examples, including different variations of plaque staining, and imaging. Furthermore, our examples employ diverse viruses. Lastly, PyPlaque is open-source and requires only open-source software to run.
Results
PyPlaque design principles
To develop a highly customisable computational tool for virological plaque analysis we followed several design choices. Firstly, we aimed for the tool to be based upon modern and widespread open-source programming language in order to fit seamlessly into the tool-set of Data Science. This led to Python being the language of choice. Secondly, we aimed to use object-oriented programming (OOP) to create logic and structures allowing us to seamlessly capture the experiment and specimen details. We set out to create structures as seamless as Pandas dataframes21 to connect important aspects of data acquisition through easy-to-follow abstractions. Finally, we aimed to be minimalistic from the perspective of package dependencies and from the perspective of re-using already existing tools in Python - for example, the said dataframes.
The first key OOP abstractions we have singled out are the Experiment, the Specimen and the Phenotypes (Fig. 1A). In this sense, the Experiment can be viewed as a logical container for several Petri dishes or multi-titre plates united by a similar experimental purpose. For example, an Experiment could be a virus titre determination performed in three biological replicas, which would combine three dishes into one OOP object. A Specimen in this example would constitute an individual dish or biological replicate. Within this dish, one may expect to find several plaques - i.e. Phenotypes in our abstraction. Combined, such a hierarchical structure is highly versatile and can cover a great variety of biological data. For example, irrespective of whether the experiment aims to perform the plaque assay by the means of an end-point Crytal Violet staining or fluorescence microscopy, data can make use of the structure described above (Fig. 1B).
The final key OOP abstraction we propose is the View classes. In our design, the View module aims to contain any kind of OOP class aimed for analysis or visualisation obtained from the classes in the three modules mentioned above (see Fig. 1B). The choice of the class to be used in order to construct a specific View defines the granularity of the results. For example, if the View is constructed for the granularity of the Phenotypes, it would contain measurements of an individual plaque. Whereas if a View is constructed for the entire Experiment it would contain average measurements of plaques in this experiment. Once the classes are instantiated, this information is stored as nested dictionaries. A comprehensive overview of PyPlaque’s modules as described above, classes and methods/functions can be found in Fig. 2.
Fig. 1 [Images not available. See PDF.]
Object-oriented programming design of the PyPlaque package. (A) Schematic depiction of nested classes (grey rectangles with titles) representing the structure of PyPlaque abstractions accompanied by pictorial examples. (B) Flow diagram of the classes available to represent the experimental data. An example demonstrates how the Fluorescence Microscopy experiment or Crystal Violet experiment could make use of the same structures: Experiment> Specimen> Phenotypes. A View module gives access to classes and methods for analysing different cross-sections of the experimental data for e.g., the whole plate, the well or the plaque.
Fig. 2 [Images not available. See PDF.]
Modules, classes/methods, and functions in PyPlaque. Here BIA stands for bioimage analysis.
Phenotypic measurements validation using synthetic data
Once plaque assay images are loaded into the respective data structures, measurements can be performed using a respective View. Measurements can include count or morphological properties of the plaque phenotypes such as area or perimeter. However, different software platforms may perform such measurements differently, leading to a lack of comparability. To date, the most popular platforms for biomedical image analysis include ImageJ/Fiji19, Matlab27 and Python (using packages like scikit-image28). Thus far, existing specialised packages for plaque quantification have been based on these platforms.
Fig. 3 [Images not available. See PDF.]
Analysis of Synthetic Images. Synthetic images generated with randomly located shapes of an ellipse, a circle, overlapping circles and a square with IDs, 1, 2, 3 and 4 respectively. 5 such images were generated and used for analysis and comparison between computation software (Tables 1 and 2) of which 3 are shown.
To understand how such measurements could be compared between these major platforms we have constructed a set of synthetic binary images, Fig. 3 (see Methods, Synthetic image generation). Next, we performed two basic measurements of each object in the synthetic images using ImageJ/Fiji19, Matlab27, OpenCV29 and our Python-based PyPlaque. Specifically, we have quantified the area and perimeter of these objects, as both of these measurements can be used to describe the extent of the virological plaques. In the case of PyPlaque, we used two different methods to estimate the area and perimeter. The first employed is a built-in measurement using the scikit-image package28. Second, was the method based on Pick’s theorem (see Methods, Pick’s area and perimeter), which we developed specifically for PyPlaque.
Table 1. Object Area in Synthetic Images.
Area | ||||
|---|---|---|---|---|
Software | ID | |||
Ellipse | Circle | Overlapping circles | Square | |
GT | 28274.334 | 70685.835 | 113733.351 | 160000.000 |
PyPlaque (Pick’s) | 27588.000 | 69812.000 | 100779.000 | 158403.000 |
Matlab27 | 28233.000 | 70661.000 | 101806.000 | 160000.000 |
ImageJ/Fiji19 | 28233.000 | 70661.000 | 101806.000 | 160000.000 |
PyPlaque (scikit-image)28 | 28233.000 | 70661.000 | 101806.000 | 160000.000 |
OpenCV29 | 28233.000 | 70661.000 | 101806.000 | 160000.000 |
Estimated values are averaged over 5 images where the objects were seeded in random locations. GT stands for ground truth. The performance closest to GT is marked in bold.
Area measurement results presented in Table 1 suggest that all three platforms performed equally slightly underestimating the area compared to GT. Notably, while the PyPlaque area measurement using scikit-image28 functionality performed equally to Matlab27 and ImageJ/Fiji19, the area measurement using Pick’s theorem led to even further underestimation. A visual representation of Tables 1 and 2 can be found in figures S1 and S2 of the supplementary file.
Table 2. Object Perimeter in Synthetic Images.
Perimeter | ||||
|---|---|---|---|---|
Software | ID | |||
Ellipse | Circle | Overlapping circles | Square | |
GT | 690.384 | 942.478 | 1256.637 | 1600.000 |
PyPlaque (Pick’s) | 704.000 | 988.000 | 1238.828 | 1604.000 |
Matlab27 | 686.456 | 939.000 | 1155.220 | 1563.716 |
ImageJ/Fiji19 | 722.943 | 991.561 | 1218.923 | 1597.657 |
PyPlaque (scikit-image)28 | 721.872 | 990.489 | 1219.024 | 1596.000 |
OpenCV29 | 721.872 | 990.489 | 1219.024 | 1596.000 |
Estimated values are averaged over 5 images where the objects were seeded in random locations. GT stands for ground truth. The performance closest to GT is marked in bold. Second-best is underlined.
Surprisingly, the perimeter measurement results presented in Table 2 demonstrated an entirely different picture. In the case of ellipse and circle shapes, Matlab-based measurements were the closest to the GT with PyPlaque measurement based on Pick’s theorem showing the second-best results. In the case of the square shape, ImageJ/Fiji demonstrated the best performance, with PyPlaque measurement based on scikit-image showing the second-best results. Finally, in the case of overlapping circles, PyPlaque measurement based on Pick’s theorem provided the measurement closest to the GT, with scikit-image performing second best. Crucially, Matlab, Image/Fiji and scikit-image measurements underestimated the perimeter severely on the overlapping circles.
Together, our results suggest a surprising incomparability of simple shape measurements across modern bioimage analysis platforms. However, due to the flexibility coming with using a Python package, the user is free to choose the measurement approach depending on the needs of the project. It is worth noting that we have additionally performed the area and perimeter measurements with another popular Python library OpenCV29. The results of these measurements were largely identical to scikit-image differing only after the 3rd decimal point and therefore looks identical to scikit-image results in Tables 1 and 2.
The computational steps of the analysis and comparison performed and showcased in this subsection can be found in the synthetic data analysis notebook in the GitHub page of the project. Understandably, Matlab and Fiji values from Tables 1 and 2 are external to our Python-based workflow and therefore needs to be read into the notebook from previously generated csvs.
Crystal violet plaque assay measurements at varying granularity using PyPlaque
To demonstrate how the structure depicted in Fig. 1 can be used to store and analyse data from a conventional plaque assay we performed an analysis of a conventional plaque assay of Vaccinia Virus (VACV) stained with Crystal Violet. The images of the assay plates were taken from the dataset published in our recent work30. This dataset consists of mobile photographs of the plaque assay plates accompanied by binary masks for wells and individual plaques. Each image of the dataset contains objects of increasing granularity containing quantitative information about the assay.
Specifically, Fig. 4A, shows a 6-well plate (left) and a masked version of the full 6-well plate (right). Such data can be handled by the PlateImage class of PyPlaque. Fig. 4B goes further in granularity showing a single well from the plate (left) and the corresponding masked version of the well (centre). Such data is handled by our classes PlaquesWell. The rightmost column of Fig. 4B inset is a single viral plaque from the well. We have the functionality using our class PlaquesMask to extract readouts such as the average size of all the plaques in the well, the total count of plaques, and the area of an individual plaque, as also shown in the figure. This class also enables us to establish size filters (via the get_plaques function with real-valued arguments min_area and max_area denoting the lower and upper thresholds of plaque area respectively) during the detection of plaques that are then used to create readouts. This helps users filter and distinguish between plaques in a quantitative manner.
The usage of the classes mentioned above are further explained in the crystal violet plaque notebook found in the GitHub page of the project. The computational steps related to this section has been depicted visually in Fig. 5.
The granularity provided by PyPlaque readouts could be beneficial in comparing plaques across wells treated with virus inoculum at different dilutions. Furthermore, it may allow comparing measurements across plates and different experiments.
Fig. 4 [Images not available. See PDF.]
Granularity in the Detection of Objects in Crystal Violet Plaque Assay Images of VACV. Objects with increasing granularity are stored and analysed by PyPlaque. (A) Shows a 6-well plate (left) and a masked version of the full 6-well plate (right). (B) Shows a single well from the plate (left), corresponding masked version of the well (centre) and a single viral plaque from the well (right-inset) with average size of the plaques in the well, the number of plaques (top-left) and area of an individual plaque (inset bottom-right).
Fig. 5 [Images not available. See PDF.]
Workflow for Crystal Violet Microscopy data using PyPlaque. The input at the first step are directory paths for plate images and plate binary masks where subdirectories at the first level contain images and binary masks for single plates and subdirectories at the second level contain the same for individual wells of a single plate. Here the existence of binary detection masks for plaque objects, one for each well of the plate has been assumed. To note, the final step Full plate well retrieval can also be the first step and all other steps could be carried out subsequently in order. But since we had readily available individual well images and plaque detection masks corresponding to each well image, we started with them first. The get_plaques() function mentioned here uses real-valued arguments min_area and max_area denoting the lower and upper thresholds of plaque area respectively which are used during the detection of a filtered set of plaques that are then used to create readouts. For details of input arguments, and arguments to subsequent function calls please check the crystal violet microscopy workflow notebook and corresponding documentation from the GitHub page.
Scalable plaque analysis using PyPlaque in high-content fluorescence microscopy
Beyond measuring the titre in the virus inoculum, the plaque assay can be employed to measure virus spread under conditions of perturbation. Techniques like high-content fluorescence microscopy allow for scaling up of such efforts11,31. To illustrate how PyPlaque can be employed in quantifying such experiments we have performed an analysis of a control 384-well plate half of which was infected with GFP-transgenic human coronavirus OC43 (CoV-GFP). This plate was obtained from a published dataset32. The control well plate we used is imaged for two fluorescence channels: CoV-GFP and Nuclei (Hoechst 33342 dye).
Comparably to the PyPlaque workflow constructed for Crystal Violet Microscopy, information in high-content fluorescence microscopy exists at several levels of granularity Fig. 6A. In contrast to the Crystal Violet plates, however, individual images in fluorescence microscopy are obtained at the level of wells. That means that the lower granularity plate overview of measurements is not available and must be constructed dynamically. This can be achieved using the View classes. A literal visual full/partial plate overview can also be dynamically generated using the “stitch_wells” function in Utils which given a raster order set of wells and a given row and column number for a plate would return a composite plate generated from the individual well images (see fluorescence microscopy workflow notebook from the GitHub repository for usage example). Results in the Fig. 6A show that, as expected, the left-hand half of the control plate has visible GFP-positive cells, some of which are clustered into fluorescent CoV plaques. Notably, some wells on the right-hand side contain sample preparation artefacts (e.g. dust and fibres)33, which may contribute to the background detection due to autofluorescence (Fig. 6A, zoomed insets).
Fig. 6 [Images not available. See PDF.]
Pyplaque measurements at image and object level. PyPlaque20 includes methods to provide readouts at an image and object level. (A) Example 384-well Fluorescence microscopy imaged plate. Insets show examples of two wells from two vertical halves of the entire 384-well plate. Left column of the insets show the CoV-GFP channel and right column shows the Nuclei (Hoechst dye) channel. Insets within the insets show a section of a single well for the CoV-GFP and Nuclei channel on the left and right respectively. (B) Plot of readout values at the well level from the software for the plate shown in panel (A). (C) Plot of readout values at the object level for the plate, averaged first over wells. For each plot, we have the infected wells (left) and control wells (right) indicated as virus and control in the legend. Such readouts could be generated by the classes and methods from the View module (see Fig. 1 and Results, PyPlaque design principles).
Fig. 7 [Images not available. See PDF.]
Systematic comparison between viral and control wells from Fluorescence Microscopy 384-well plate using PyPlaque. This figure explains the class instance assignments and function calls for the steps taken and results explained in subsection Scalable plaque analysis using PyPlaque in high-content fluorescence microscopy. The input to the first step are directory paths for plate images and plate binary masks where subdirectories at the first level contain images and binary masks for virus or nuclei for single plates and subdirectories at the second level contain the same for individual wells of a single plate. The first example readout contains the readouts for all wells of a plate. After filtering via a regular expression applied on the names of well columns (assuming viral and control wells can be separated as such) we have separate readouts for viral and control wells. The barplots shown in the final section are effectively barplots based on similar measurements at equivalent granularity levels as in Fig. 6B and C. For details of input arguments, and arguments to subsequent function calls please check the example analysis notebook and corresponding documentation from the GitHub page..
Fig. 8 [Images not available. See PDF.]
Workflow for Fluorescence Microscopy data using PyPlaque. The input at the first step are directory paths for plate images and plate binary masks where subdirectories at the first level contain images and binary masks for virus or nuclei for single plates and subdirectories at the second level contain the same for individual wells of a single plate. Here we get readouts at the plate level (i.e. all wells of a plate) and the plaque level. There are readouts for the nuclei and virus channels at both levels, although some readouts such as column and row identifiers for the same well remains the same for both channels. For details of input arguments, and arguments to subsequent function calls please check the fluorescence microscopy workflow notebook and corresponding documentation from the GitHub page.
Noteworthy, fluorescence microscopy does not usually come with binary detection or segmentation masks. While segmentation masks can be obtained through advanced deep learning models, as we show in our recent work30, in some cases rule-based algorithms like Otsu34 are sufficient. Both cases are supported by PyPlaque. However, while rule-based thresholding and connectivity handling is built-in via get_all_plaque_regions method, the former requires an external model. An example of such a deep learning model can be found in our above-mentioned work30 where we simultaneously detect the circular area of a well and the irregular area of plaques from 8-bit RGB images of Vaccinia Virus (VACV), shown as the Raw 6-well plate image in Fig. 4 .This is similar to data used in our Crystal Violet Microscopy experiments here. As mentioned before, such models are external to our framework and does not need to be incorporated into the code repository of PyPlaque. Rather, in our work we have provided code to compute these detection masks for wells and encompassed plaques simultaneously that can stored and then used in analysis via PyPlaque in a similar fashion as when they are readily available. Since the scope of this paper is limited to our rule-based bioimage analysis tool and not our deep learning model, we do not discuss it here any further. By support for both which we mentioned above, we simply mean that PyPlaque can handle detection masks generated via deep learning models as well as its own rule-based detections.
Results of quantifications using built-in methods can be seen in Fig. 6B and C. Specifically, Fig. 6B demonstrates differences between the infected and uninfected halves of the plate (denoted as virus and control respectively) at the granularity of a well. Measurements like plaque count, infected nuclei count and the mean intensity of the virus signal can be obtained using the built-in methods of the PyPlaque package. Figure 6C demonstrates that such analysis is also possible at the level of individual plaque. Measurements such as nuclei count in the plaque, and infected nuclei count in the plaque, as well as mean GFP intensity can be obtained. The latter, in turn, could facilitate the separation of real plaque from a sample preparation artefact by simply filtering out the objects with very low fluorescence during the post-processing of the analysis results. For full list of measurements, please see subsection Generation of well and plaque level readouts.
Importantly, workflows for the data sources as different as mobile photography and high-content fluorescence microscopy can be flexibly constructed using the OOP structure we propose for PyPlaque20. In the spirit of Python-based Data Science, these workflows can be implemented as Jupyter23 notebooks. That means that PyPlaque functionality can be mixed and matched at will with the vast selection of image analysis packages available in the open-source Python community. For example, instead of using rule-based segmentation algorithms provided by the PyPlaque, a mask can be obtained from a machine learning model and fed to the respective class. An example of such analysis can be found in the example analysis notebook GitHub page of the project. The computational steps in the above notebook lead to visualising the analysis results as the barplots in Fig. 6B and C and the steps of the analysis can be found explained in Fig. 7. An additional computational analysis of fluorescence microscopy plaques focusing on the granularity and properties of individual plaques or plaques in individual wells of a plate can be found in fluorescence microscopy workflow notebook from the GitHub repository and is shown semantically in Fig. 8.
Discussion
Quantification of phenotypes in the virological assays plays an important role in Virology research and our search for novel antivirals35,36. In the case of the virological plaque assay, several quantification tools have been proposed in the past9,11,13, 14, 15, 16, 17–18. However, the overall focus on the graphical user interface (GUI) makes these tools unflexible and hard to maintain. In many cases, the GUI part of the software is as complex as all the other functionalities11. Furthermore, GUI shifts the focus of the package, forcing a particular workflow design.
The PyPlaque20 package developed in this work takes a different approach to the quantification of virological assays. Rather than providing a GUI-based solution, we propose a Python package rooted in the Data Science technological stack. Instead of forcing the user to follow a particular workflow, we provide an abstract OOP container for experimental data that can be integrated into Pythonic workflow constructors like Jupyter22,23. We argue that by making the data constructs available in the Jupyter environment, our approach is more scalable and flexible due to its compatibility with modern Data Science tools like Pandas21. In this sense, once the data is ingested, users can easily apply custom analyses programmatically, for example, by iterating over plate/well/plaque objects in a Python loop, making the workflow both flexible and scriptable within standard tools like Jupyter notebooks.
Incidentally, this approach allowed us to focus on the actual measurements providing users with the choice of methods. In a series of comparisons we demonstrated the lack of agreement in a seemingly trivial task of perimeter measurement in the leading bioimage analysis platforms including Matlab27, ImageJ/Fiji19 and Python scikit-image28. Notably, the go-to Python approach showed significant deviation from the ground truth in the perimeter measurement. To remedy this, we propose an alternative perimeter measurement approach alleviating the disagreement in certain cases.
Furthermore, we argue that the approach proposed here can be generalised to other biological assays yielding a new paradigm. Similar structures of classes at varying granularities from Experiment to Phenotypes can be constructed for many kinds of experiments. In the particular case of experiments conducted with sample carriers shown here, PyPlaque can be used for assays other than plaque assay already. We hope to receive open-source community contributions to further expand this scope.
Methods
PyPlaque installation
The release version of the PyPlaque package can be installed using PyPi package manager by invoking the following command in the command line interface:
pip install pyplaque
Multi-granularity level design
As mentioned above the design of the PyPlaque classes follows a multi-level granularity approach. This means that the structures of the package allow to group data and metadata at different levels, preserving semantic relationships. These structures are detailed in the subsequent sections. To have a visual presentation of this multi-level granularity approach see Fig. 1A.
Experiment granularity level classes
At the highest level of granularity, we defined classes CrystalViolet and FluorescenceMicroscopy which are designed to contain metadata of multiple instances of a multi-titre plate of Crystal Violet Plaque and Fluorescence Plaque respectively. To aid in having a better overview of all of the multi-titre plates in the experiment, both of these classes contain methods get_individual_plates, get_number_of_plates and read_from_path that identify the individual plates, their total count and read each individual well image respectively.
Single plate granularity level classes
At the next level of granularity are the classes aimed at containing data and metadata for one experimental container, for example corresponding to a single multi-titre plate. The PlateImage class accepts an image and corresponding binary masks of individual wells of a single full multi-titre plate. Using class properties such as the number of rows, number of columns and a flag indicating whether or not the plate was imaged inverted or not, given by the user, methods of the class return the following:
get_wells - returns a list of the images of individual wells of the plate stored as binary Numpy arrays.
get_well_positions - returns a dictionary where individual wells of the plate are the units. For each individual well, the image, mask, masked image, bounding box x-y values, row and column number estimated from the well positions are stored with the rows and columns numbered starting from 0.
plot_well_positions - returns a plot with bounding boxes drawn around individual wells of the plate (inferred from the plate mask), with rows and columns numbered starting from 0.
Single well granularity level classes
The class PlaquesWell is aimed at containing an individual well of a multi-titre plate. It expects information about the row and column numbers, the well image and mask. It has the method get_image which returns a masked image of the individual well.
The PlaquesMask is a feature-enriched class designed with the aim of holding a single binary mask containing multiple plaque instances from an individual well. Using the binary mask of plaques and a name to identify this plaque mask (usually derived from the plate name and the well position that the mask corresponds to), methods of the class return the following:
get_plaques - returns a list of individual plaques stored as binary Numpy arrays.
get_measure - returns measures based on the individual plaques in a well as a dictionary. This is more appropriate for cumulative measurements as compared to the measure method under class Plaque (see subsection Single phenotype granularity level classes) that gives granular measurements based on each plaque.
plot_centroid - plots a dotted ring around all the plaques that are found in a well. This ring is centred at the centroid (see subsection Generation of well and plaque level readouts, get_centroid) of all the centres of individual plaques found.
Single phenotype granularity level classes
The class Plaque is designed to contain a single virological plaque phenotype as an object. It encapsulates the properties related to a specific plaque, including its mask, centroid coordinates and bounding box, and offers methods for the calculation of the area, eccentricity and roundness of this plaque object. Methods of the class return the following:
measure - returns the bounding box area (in pixels) of a plaque object, as well as an approximation of its actual area based on the proportion of white pixels in the mask.
eccentricity - calculates and returns the eccentricity37 of an individual plaque object. The eccentricity is determined by fitting an ellipse to the plaque’s boundary contour and using the formula,
1
where b represents the length of the semi-minor axis, and a represents the length of the semi-major axis.roundness - returns the roundness38 of an individual plaque object. The roundness is calculated using the formula,
2
where area is estimated as , and perimeter is calculated as , R being the radius estimated from the centre to the top-right corner of the bounding box. This method can alternatively use Pick’s (see subsection, Pick’s area and perimeter) area and perimeter estimates. This value is 1 in the case of a perfect circle. The classes CrystalVioletPlaque and FluorescencePlaque are child classes of the class Plaque. They allow for the storage of data and metadata of crystal violet or fluorescent dye stained plaques imaged using mobile photography or brightfield microscopy and fluorescence microscopy respectively. Since the masks are binary in both cases, both of these classes are able to use the methods such as measure, eccentricity, and roundness from the parent class.Artefact Removal (based on Intensity) - if else , where is the ’artefact_threshold’ for the nuclei channel.
Background Noise Removal (based on Structure) -
Dilation
, where is the translation of X by b.
To be more specific,
Erosion
, where is the translation of by .
To be more specific,
when we choose B as a sub-matrix of C it leads to the removal of the background noise. B and C are chosen for the matrix representation of a circle of diameter, ’correction_ball_radius’ for the nuclei channel.Binarise - if else 0, where is the ’manual_threshold’ for the nuclei channel.
To see the practical usage of the above mentioned steps and their outcome please see the fluorescence microscopy workflow notebook where the detection masks are generated during loading of the well images for a plate for the nuclei channel. It is created using the an instance of the FluorescenceMicroscopy class based on the dictionary of parameters passed via the argument “params”, otherwise a default dictionary of parameters are used. For readouts relating to the nuclei channel please look at the subsection Generation of well and plaque level readouts.Binarise - if else 0, where is the ’virus_threshold’ for the virus channel.
Connected Components - if else 1, where is the distance to the nearest foreground object and is the ’plaque_connectivity’ for the virus channel.
Gaussian Blurring - , where
where (w, h) is the shape of X and is the ’sigma’ passed to PlaquesImageGray Specimen class.
Binarise - if else 0, where is the ’threshold’ passed to PlaquesImageGray Specimen class.
To see the practical usage of the above mentioned steps and their outcome please see the fluorescence microscopy workflow notebook where the detection masks are generated during loading of the well images for a plate for the virus channel. It is created using the an instance of the FluorescenceMicroscopy class based on the dictionary of parameters passed via the argument “params”, otherwise a default dictionary of parameters are used. For readouts relating to the virus channel please look at the next subsection Generation of well and plaque level readouts.get_max_plaque_intensity - returns , where is the image from the virus channel for the well.
get_mean_plaque_intensity - returns , where is as above with shape (w, h).
get_total_plaque_intensity - returns , where is as above.
get_median_plaque_intensity - returns q s.t. , where is as above and is the indicator function taking value 1 when the condition is satisfied and zero otherwise.
get_nuclei_count - returns where is the mask from the nuclei channel for the well and are the upper and lower bounds for the area of a nucleus.
get_plaque_count - returns the length l of the list of global maxima coordinates identified from which is as described above. It is an extension of the steps mentioned in subsection Virus mask generation for fluorescence microscopy above (under Detection mask for virus signal), the further steps being,
Individual Plaques - getting regionprops (from scikit-image28) objects based on Connected Components40 that are greater than , the lower bound for the area of a plaque from an image like mentioned in subsection Virus mask generation for fluorescence microscopy above (under Detection mask for virus signal).
Counting global maxima in blurred masked plaque image - For each plaque object, where and are the image and mask of a single plaque p respectively. Then we use Gaussian blurring with a specified as described in subsection Virus mask generation for mobile photography or brightfield microscopy above (under Detection mask for virus signal) to get . is then used to identify global maxima (from scikit-image28) within it that are identified based on the hyper-parameter so that the distance between two global maxima found is at least indicating that the spread of the area for which a global maxima is found is at least of radius . This operation dilates (see subsection Detection mask for nuclei) and merges neighbouring maxima that become part of the same connected component after dilation. Coordinates (x, y) of the locations where is equal to the dilated image are returned as global maxima. The length of this list of coordinates can therefore be measured.
get_infected_nuclei_count - returns where {plaques identified from using step 3 under get_plaque_count mentioned previously}, being the mask of the virus channel for the well, are as described previously and is simply the area of the plaque .
get_lesion_area - returns , where is as mentioned above.
get_plaque_objects - returns the regionprops (from scikit-image28) objects identified from , where is as mentioned above, using step 3 under get_plaque_count mentioned above.
Other than the methods mentioned above, the class provides the following methods such as get_nuclei_image_name, get_plaque_image_name, get_row, get_column, get_max_nuclei_intensity, get_mean_nuclei_intensity, get_total_nuclei_intensity, get_median_nuclei_intensity as well. They have not been described in detail since they are either similar to the ones described and can be thought of analogously or they are self-explanatory from their names.get_area - returns regionprops (from scikit-image28) area of the plaque, , where is the mask of the plaque or if indicated by a flag the Pick’s area (see subsection Pick’s Area and Perimeter below) based on is returned.
get_perimeter - returns regionprops perimeter of the plaque, or if indicated by a flag the Pick’s perimeter (see subsection Pick’s area and perimeter below) based on is returned.
get_centroid - returns regionprops centroid of the plaque, where and are the number of pixel rows and columns of the plaque mask or the plaque image .
get_bbox - returns a tuple where (x, y) are the bounding box coordinates from the top left corner of the plaque and is the shape of bounding box of the plaque.
get_major_minor_axis_length - returns a tuple (4a, 4b) where a and b are as described in Eq. (1).
get_eccentricity - returns the value of eccentricity as described in Eq. (1).
get_roundness - returns the value of roundness38 as described in Eq. (2).
get_number_of_peaks - returns the length of a list of coordinates (x, y) of the global maxima found in the masked image of the plaque (similar to ) using the method mentioned in step 4, Counting global maxima in blurred masked plaque image of get_plaque_count under the well level readouts.
get_nuclei_in_plaque - returns where are as described previously and area(Nuc) is either the sum of non-zero pixels or if indicated by a flag, the Pick’s area (see subsection Pick’s area and perimeter below) of a masked image Nuc defined as where is the regionprops convex-hull41 of the plaque mask and is the corresponding nuclei mask from the nuclei channel.
get_infected_nuclei_in_plaque - where , and are all as described previously.
get_convex_area - returns regionprops convex area of the plaque which is the sum of non-zero pixels in a binary image of the convex hull41 of the plaque.
max_GFP_intensity - , where and are the image and mask of the plaque p.
total_GFP_intensity - , where and is as above.
mean_GFP_intensity - , where and is as above and represents a non-zero pixel in .
Other than the methods mentioned above, the class provides the following methods such as get_row, get_column as well. For getting the means, maximums and totals and storing readouts in dataframes, implementations available from Numpy42 and Pandas21 are used. The readouts at the plaque level are averaged for all plaques within a well before being stored in a dataframe but individual plaque measurements can be accessed as shown in our fluorescence plaque detailed notebook meant for advanced users of the software.Creating a border image using Dilation or Erosion (see subsection Detection mask for nuclei) and subtracting the original from it or subtracting it from the original respectively. The eroded image forms the interior of the polygon. The neighbourhood definition N(i, j) defines the result of these operations. For our purposes,
We embolden the resulting border image by convolution46, where,
Taking a weighted average of the histogram of the above-mentioned convolved image , giving appropriate weightage to the intensity values in the bins of the histogram. For computational simplicity, we keep the number of bins at 50.
The comparison of this measurement to the ground truth measurements for area and perimeter for synthetically generated known polygons can be found in Tables 1 and 2 and the practical usage of these measurements via PyPlaque can be seen in the synthetic data analysis notebook in the GitHub page of the project.
The WellImageReadout class calls the PlaqueObjectReadout class via the call_plaque_object_readout method to generate the readouts at the plaque level. An example of readouts at the plaque level obtained by methods under PlaqueObjectReadout are:
To see the practical usage of the above classes to generate readouts and to see examples of readouts returned please see the fluorescence microscopy workflow notebook and the example analysis notebook. Further details of the classes and readouts at both levels can be found in the documentation of the view module in the GitHub page of the project.
Synthetic image generation
To compare PyPlaque’s ability to perform measurements to existing bioimage analysis software, we generated binary synthetic images depicting simple geometric shapes: an ellipse, a circle, two overlapping circles and a square (Fig. 3) and assigned them to the numbers 1, 2, 3 and 4, respectively. These shapes were chosen to represent both regular and irregular shapes in the simplest way possible for ease of interpretation. To ensure comparability amongst the measurement systems, the shape parameters were identical while their location was chosen at random. Figure 3 shows 3 of 5 images used in the comparison.
Pick’s area and perimeter
The Pick’s Area and Perimeter used here is the main result of Pick’s theorem43, first showcased by Georg Alexander Pick. It is a geometric result for calculating the area and perimeter of irregular polygons on integer lattices44. We have implemented the calculation of the area and perimeter of plaque objects which computationally are essentially irregular polygons on a discrete lattice. The usage of this measurement has been implemented in several classes throughout the software where such measurements are needed via the boolean argument “use_picks” which by default is set to False. The theorem states that given a simple lattice polygon P, if i is the number of integer lattice points inside it and p is the number of integer lattice points on its perimeter, then the area of the polygon area(P), is given by,
3
where a point is an integer lattice point, or simply lattice point, iff both x and y are integers. We define a lattice polygon to be a polygon all of whose vertices are at integer lattice points.It is important to note that the same formula does not apply for polygons with holes where it changes to,
4
where q depends on the number of holes. For a proof of the theorem please look at the work here45.As for the perimeter and area calculations in our code, we calculate the perimeter in both cases and use it along with the interior measurements to get the total area and simply return the perimeter estimate for the perimeter. We can do so using the following steps:
Acknowledgements
This work was partially funded by the Center for Advanced Systems Understanding (CASUS) which is financed by Germany’s Federal Ministry of Education and Research (BMBF) and by the Saxon Ministry for Science, Culture, and Tourism (SMWK) with tax funds on the basis of the budget approved by the Saxon State Parliament. We thank Urs Greber (University of Zürich, Switzerland) for access to raw data of32. The authors acknowledge the financial support by the Federal Ministry of Education and Research of Germany and by Sächsische Staatsministerium für Wissenschaft, Kultur und Tourismus in the programme Center of Excellence for AI-research “Center for Scalable Data Analytics and Artificial Intelligence Dresden/Leipzig”, project identification number: ScaDS.AI.
Author contributions
AY, VA, and TD conceived the concept, wrote the program code and the manuscript. TD and VA performed computational experiments. AY and VA collected image data. All authors reviewed the manuscript.
Funding
Open Access funding enabled and organized by Projekt DEAL.
Data availability
The datasets analysed during the current study are available in the RODARE repository, https://rodare.hzdr.de/record/3003/ and https://rodare.hzdr.de/record/3742.
Code availability
The source code of the PyPlaque20 package is available under the GPL-3.0 open-source license in the following GitHub repository at https://github.com/plaque2/PyPlaque and via Zenodo at https://doi.org/10.5281/zenodo.13149371.
Declarations
Competing interests
TD, VA declare no competing interests. AY declares the following competing interest: role as an Editorial Board Member in Scientific Data.
Supplementary Information
The online version contains supplementary material available at https://doi.org/10.1038/s41598-025-20075-w.
Publisher’s note
Springer Nature remains neutral with regard to jurisdictional claims in published maps and institutional affiliations.
References1. Delpuech, O et al. Heat inactivation of clinical COVID-19 samples on an industrial scale for low risk and efficient high-throughput qRT-PCR diagnostic testing. Sci. Rep.; 2022; 12, 2883.1:CAS:528:DC%2BB38Xktl2htL4%3D [DOI: https://dx.doi.org/10.1038/s41598-022-06888-z] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/35190592][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8861189]
2. Smyrlaki, I et al. Massive and rapid COVID-19 testing is feasible by extraction-free SARS-CoV-2 RT-PCR. Nat. Commun.; 2020; 11, 4812.1:CAS:528:DC%2BB3cXhvFOhsrfL [DOI: https://dx.doi.org/10.1038/s41467-020-18611-5] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/32968075][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7511968]
3. Vandenberg, O; Martiny, D; Rochas, O; van Belkum, A; Kozlakidis, Z. Considerations for diagnostic COVID-19 tests. Nat. Rev. Microbiol.; 2020; 19, pp. 171-183.1:CAS:528:DC%2BB3cXit1yjurbM [DOI: https://dx.doi.org/10.1038/s41579-020-00461-z] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/33057203][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7556561]
4. Dulbecco, R. Production of plaques in monolayer tissue cultures by single particles of an animal virus. Proc. Natl. Acad. Sci. U. S. A.; 1952; 38, pp. 747-752.1:STN:280:DC%2BD28zitVemtQ%3D%3D [DOI: https://dx.doi.org/10.1073/pnas.38.8.747] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/16589172][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC1063645]
5. d’Herelle, F. & H.Smith, G. The bacteriophage and its behaviour. Nature118, 183–185, https://doi.org/10.1038/118183a0 (1926).
6. Kevadiya, BD et al. Diagnostics for SARS-CoV-2 infections. Nat. Mater.; 2021; 20, pp. 593-605.1:CAS:528:DC%2BB3MXktlais7s%3D [DOI: https://dx.doi.org/10.1038/s41563-020-00906-z] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/33589798][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8264308]
7. Muruato, AE et al. A high-throughput neutralizing antibody assay for COVID-19 diagnosis and vaccine evaluation. Nat. Commun.; 2020; 11, 4059.1:CAS:528:DC%2BB3cXhs1Sjt7%2FP [DOI: https://dx.doi.org/10.1038/s41467-020-17892-0] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/32792628][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7426916]
8. Natale, A et al. SARS-cov-2 natural infection in a symptomatic cat: Diagnostic, clinical and medical management in a one health vision. Animals (Basel); 2021; 11, 1640. [DOI: https://dx.doi.org/10.3390/ani11061640] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/34205893]
9. Yakimovich, A; Mercer, J. High-content analyses of vaccinia plaque formation. Methods Mol. Biol.; 2023; 237–253, 2019.1:CAS:528:DC%2BB3cXjtVKqu7Y%3D [DOI: https://dx.doi.org/10.1007/978-1-4939-9593-6_15]
10. Yakimovich, A et al. Cell-free transmission of human adenovirus by passive mass transfer in cell culture simulated in a computer model. J. Virol.; 2012; 86, pp. 10123-10137.1:CAS:528:DC%2BC38XhtlChsLrM [DOI: https://dx.doi.org/10.1128/jvi.01102-12] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/22787215][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3446567]
11. Yakimovich, A et al. Plaque2.0–a high-throughput analysis framework to score virus-cell transmission and clonal cell expansion. PLOS ONE; 2015; 10, e0138760.1:CAS:528:DC%2BC28XptVGksg%3D%3D [DOI: https://dx.doi.org/10.1371/journal.pone.0138760] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/26413745][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4587671]
12. Beerli, C et al. Vaccinia virus hijacks EGFR signalling to enhance virus spread through rapid and directed infected cell motility. Nat. Microbiol.; 2019; 4, pp. 216-225.1:CAS:528:DC%2BC1cXit1Sgur%2FL [DOI: https://dx.doi.org/10.1038/s41564-018-0288-2] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/30420785]
13. Cacciabue, M; Currá, A; Gismondi, MI. ViralPlaque: A fiji macro for automated assessment of viral plaque statistics. PeerJ; 2019; 7, [DOI: https://dx.doi.org/10.7717/peerj.7729] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/31579606][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6764358]e7729.
14. Culley, S; Towers, G; Selwood, D; Henriques, R; Grove, J. Infection counter: Automated quantification of in vitro virus replication by fluorescence microscopy. Viruses; 2016; 8, 201.1:CAS:528:DC%2BC2sXhsFyjsbfF [DOI: https://dx.doi.org/10.3390/v8070201] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/27455304][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4974536]
15. Katzelnick, LC et al. Viridot: An automated virus plaque (immunofocus) counter for the measurement of serological neutralizing responses with application to dengue virus. PLoS Negl. Trop. Dis.; 2018; 12, [DOI: https://dx.doi.org/10.1371/journal.pntd.0006862] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/30356267][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6226209]e0006862.
16. Kerkhoff, Y et al. A fast open-source fiji-macro to quantify virus infection and transfection on single-cell level by fluorescence microscopy. MethodsX; 2022; 9, 1:CAS:528:DC%2BB38XisFGjsrzP [DOI: https://dx.doi.org/10.1016/j.mex.2022.101834] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/36160109][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9490200]101834.
17. Trofimova, E; Jaschke, PR. Plaque size tool: An automated plaque analysis tool for simplifying and standardising bacteriophage plaque morphology measurements. Virology; 2021; 561, pp. 1-5.1:CAS:528:DC%2BB3MXht1KhtbrN [DOI: https://dx.doi.org/10.1016/j.virol.2021.05.011] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/34089996]
18. Phanomchoeng, G et al. Machine-learning-based automated quantification machine for virus plaque assay counting. PeerJ Comput. Sci.; 2022; 8, [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/35494866][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC9044226]e878.
19. Schindelin, J et al. Fiji: An open-source platform for biological-image analysis. Nat. Methods; 2012; 9, pp. 676-682.1:CAS:528:DC%2BC38XhtVKnurbJ [DOI: https://dx.doi.org/10.1038/nmeth.2019] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/22743772]
20. Trina De, A. Y., Vardan Andriasyan. Pyplaque: v0.2.1, https://doi.org/10.5281/zenodo.13149371 (2024).
21. McKinney, W. Data structures for statistical computing in python. In: Proc. 9th Python in Science Conference, 56–61, https://doi.org/10.25080/majora-92bf1922-00a (SciPy, 2010).
22. Perez, F; Granger, BE. IPython: A system for interactive scientific computing. Comput. Sci. Eng.; 2007; 9, pp. 21-29.1:CAS:528:DC%2BD2sXltVWiur0%3D [DOI: https://dx.doi.org/10.1109/mcse.2007.53]
23. Kluyver, T et al. Loizides, F; Schmidt, B et al. Jupyter notebooks—A publishing format for reproducible computational workflows. Positioning and Power in Academic Publishing: Players, Agents and Agendas; 2016; IOS Press: pp. 87-90.
24. pandas development team. T. pandas-dev/pandas: Pandashttps://doi.org/10.5281/zenodo.7549438 (2023).
25. Hunter, JD. Matplotlib: A 2d graphics environment. Comput. Sci. Eng.; 2007; 9, pp. 90-95. [DOI: https://dx.doi.org/10.1109/MCSE.2007.55]
26. Rossum, G; Drake, FL. Python tutorial; 1995; Centrum voor Wiskunde en Informatica Amsterdam:
27. Inc., T. M. Matlab version: 9.13.0 (r2022b) (2022).
28. Walt, S et al. scikit-image: Image processing in python. PeerJ; 2014; 2, [DOI: https://dx.doi.org/10.7717/peerj.453] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/25024921][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4081273]e453.
29. Bradski, G. The opencv library. Dr. Dobb’s Journal of Software Tools (2000).
30. De, T; Thangamani, S; Urbański, A; Yakimovich, A. A digital photography dataset for vaccinia virus plaque quantification using deep learning. Sci. Data; 2025; 12, 719. [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/40307255][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC12043936]
31. Georgi, F et al. The fda-approved drug nelfinavir inhibits lytic cell-free but not cell-associated nonlytic transmission of human adenovirus. Antimicrob. Agents Chemother.; 2020; 64, pp. 10-1128.
32. Murer, L et al. Identification of broad anti-coronavirus chemical agents for repurposing against sars-cov-2 and variants of concern. Curr. Res. Virol. Sci.; 2022; 3, 1:CAS:528:DC%2BB38XislGhsbbL [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/35072124][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8760634]100019.
33. Sharma, V; Yakimovich, A. A deep learning dataset for sample preparation artefacts detection in multispectral high-content microscopy. Sci. Data; 2024; 11, 232. [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/38395957][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC10891121]
34. Otsu, N et al. A threshold selection method from gray-level histograms. Automatica; 1975; 11, pp. 23-27.
35. Witte, R; Andriasyan, V; Georgi, F; Yakimovich, A; Greber, UF. Concepts in light microscopy of viruses. Viruses; 2018; 10, 202. [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/29670029][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC5923496]
36. Yakimovich, A. Artificial intelligence in infection biology. Artificial Intelligence in Medicine 1–9 (2020).
37. Ayoub, AB. The eccentricity of a conic section. Coll. Math. J.; 2003; 34, pp. 116-121. [DOI: https://dx.doi.org/10.1080/07468342.2003.11921994]
38. Bottema, M. J. Circularity of objects in images, 2247–2250. IEEE International Conference on Acoustics, Speech and Signal Processing. Proceedings (Institute of Electrical and Electronics Engineers, 2000).
39. Virtanen, P et al. SciPy 1.0: Fundamental algorithms for scientific computing in python. Nat. Methods; 2020; 17, pp. 261-272.1:CAS:528:DC%2BB3cXislCjuro%3D [DOI: https://dx.doi.org/10.1038/s41592-019-0686-2] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/32015543][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7056644]
40. He, L et al. The connected-component labeling problem: A review of state-of-the-art algorithms. Pattern Recogn.; 2017; 70, pp. 25-43. [DOI: https://dx.doi.org/10.1016/j.patcog.2017.04.018]
41. Viswanathan, V. K., Mansouri, S. S. & Kanellakis, C. Chapter 11 - aerial infrastructures inspection. In Nikolakopoulos, G., Mansour, S. S. & Kanellakis, C. (eds.) Aerial Robotic Workers, 175–211, https://doi.org/10.1016/B978-0-12-814909-6.00017-2 (Butterworth-Heinemann, 2023).
42. Harris, CR et al. Array programming with NumPy. Nature; 2020; 585, pp. 357-362.1:CAS:528:DC%2BB3cXitlWmsbbN [DOI: https://dx.doi.org/10.1038/s41586-020-2649-2] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/32939066][PubMedCentral: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7759461]
43. Pick, G. Geometrisches zur Zahlenlehre. (1899).
44. Sullivan, JJ. Polygons on a lattice. Arithm. Teacher; 1973; 20, pp. 673-675.
45. Funkenbusch, WW. From euler’s formula to pick’s formula using an edge theorem. Am. Math. Mon.; 1974; 81, pp. 647-648.1537447 [DOI: https://dx.doi.org/10.1080/00029890.1974.11993639]
46. Fukushima, K. Neocognitron: A self-organizing neural network model for a mechanism of pattern recognition unaffected by shift in position. Biol. Cybern.; 1980; 36, pp. 193-202.1:STN:280:DyaL3c7nsFKntw%3D%3D [DOI: https://dx.doi.org/10.1007/BF00344251] [PubMed: https://www.ncbi.nlm.nih.gov/pubmed/7370364]
Detection mask for virus signal
The analysis of the virus signal begins similarly to nuclei with the acceptance of a well image corresponding to the virus channel stained with crystal violet or fluorescent dye and imaged via brightfield or fluorescence microscopy. In case a pre-generated mask is available, it is also read simultaneously with the images into the plate dictionary structure provided by our method load_wells_for_plate_virus() available under the class FluorescenceMicroscopy or load_well_images_and_masks_for_plate() available under the class CrystalViolet. Given below are relevant notebooks from the GitHub repository that contain practical usage examples.
In case a mask isn’t present, it is generated at runtime just like nuclei. But since there is a difference in how virus channel appears in crystal violet or fluorescent dye stained samples and also under mobile photography, bright-field or fluorescence microscopy, we have two different workflows for mask generation for plaques. Once again, part of these workflows are implemented in Python in the packages OpenCV29, Scikit-Image28 and SciPy39. The workflows are as follows:
Virus mask generation for fluorescence microscopy
Virus mask generation for mobile photography or brightfield microscopy
Generation of well and plaque level readouts
PyPlaque returns readouts at the well and plaque level for nuclei and virus signal. It is worth mentioning that the modules described in this subsection are intended for and designed to work for fluorescence microscopy images. In this section, we discuss the classes that are used for such analysis and proceed to describe how we compute each of the readouts including those that are showcased in Fig. 6B and C.
The classes PlateReadout,WellImageReadout and PlaqueObjectReadout under the View module can be used to deal with the analysis at different granularity levels. They are used to generate readouts pertaining to multiple wells of a single plate of fluorescence plaques, multiple instances of plaques within a single well and finally a single instance of a plaque from a fluorescence plaque well respectively. It is possible to obtain readouts at the well and/or plaque level based on arguments passed to PlateReadout via the boolean valued arguments well_level_readouts and object_level_readouts both of which default to true, returning both well and plaque level readouts as a result, respectively. PlateReadout in turn calls WellImageReadout and PlaqueObjectReadout to generate the well and plaque level readouts respectively.
Examples of readouts at the well level obtained by methods under well and plaque level WellImageReadout are:
Detection mask for nuclei
The analysis of nuclei begins with the acceptance of a well image corresponding to the nuclei channel stained with fluorescent dye and imaged via fluorescence microscopy. In case a pre-generated mask is available, it is also read simultaneously with the images into the plate dictionary structure provided by our method load_wells_for_plate_nuclei() available under the class FluorescenceMicroscopy. In case a mask isn’t present, it is generated at runtime, using the following steps, some of which are implemented in Python in the package OpenCV29.
© The Author(s) 2025. This work is published under http://creativecommons.org/licenses/by/4.0/ (the "License"). Notwithstanding the ProQuest Terms and Conditions, you may use this content in accordance with the terms of the License.