diff --git a/README.md b/README.md index 6006160..1dacc92 100644 --- a/README.md +++ b/README.md @@ -56,9 +56,7 @@ Extras tutorials python3 language: Extras tutorials for other languages than python3: + [pcdl and julia](https://github.com/elmbeech/physicelldataloader/tree/master/man/TUTORIAL_julia.md) - ++ [pcdl and matlab](https://github.com/elmbeech/physicelldataloader/tree/master/man/TUTORIAL_matlab_octave.md) + [pcdl and R](https://github.com/elmbeech/physicelldataloader/tree/master/man/TUTORIAL_r.md) Extras tutorials for GUI software: @@ -104,6 +102,8 @@ Within the pcdl library, we tried to stick to the documentation policy laid out Nick Oldfather (unit test model), Thierry-Pascal Fleurant (plot\_timeseries) +Developers, please make pull requests to the https://github.com/elmbeech/physicelldataloader/tree/development branch. Thanks! + ## Cite: @@ -121,12 +121,21 @@ Within the pcdl library, we tried to stick to the documentation policy laid out ## Road Map: -+ add make\_conc\_vtk visualization parameter. -+ new next generation unit test dataset. -+ rewrite make\_ome\_tiff to use less RAM. ++ evt generate lineage tree graph output files. + evt add neuroglancer ome.tiff support. ++ switch from aicsimageio to bioio library, when the library is ripe (napari has switched to bioio). + ## Release Notes: ++ version 3.3.3 (2025-01-10): elmbeech/physicelldataloader + + bug fix **plot_contour** plot orientation. special thanks to Marco Ruscone! + + add test data for new improved **unittest physicell model**. special thanks to Nick Oldfather! + + add pyMCDS **make_conc_vtk** on the fly visualization. special thanks to Randy Heiland and Nick Oldfather! + + pyMCDS and pyMCDSts **make_graph_gml** and pyAnnData **get_anndata** handles now spring\_attached\_cells graph too. + ++ version 3.3.2 (2024-11-24): elmbeech/physicelldataloader + + **Warnings** will no longer be piped to standard output if verbose is set to False. + + pyMCDS **make_ome_tiff** function rewriten to be less RAM hungry and more versatile. + version 3.3.1 (2024-09-22): elmbeech/physicelldataloader + bugfix pyMCDS custom vectors loading. @@ -170,11 +179,11 @@ Within the pcdl library, we tried to stick to the documentation policy laid out + new pyMCDS **set_verbosity_false** function, to complete pcdl.TimeStep(verbosity=True/False) experience. + new pyMCDSts **get_cell_df** function, to extract one big dataframe or a list of dataframes from the whole time series. + new pyMCDSts **get_conc_df** function, to extract one big dataframe or a list of dataframes from the whole time series. - + new pyMCDSts **make_cell_vtk** function, to save substrate data as rectilinear grid vtk files. - + new pyMCDSts **make_conc_vtk** function, to save cell data as glyph vtk files. - + new pyMCDSts **make_graph_gml** function, to save graphs in a networkx and igraph compatible files format. + + new pyMCDSts **make_cell_vtk** function, to save substrate data as rectilinear grid vtk files. special thanks to Furkan Kurtoglu! + + new pyMCDSts **make_conc_vtk** function, to save cell data as glyph vtk files. special thanks to Furkan Kurtoglu! + + new pyMCDSts **make_graph_gml** function, to save graphs in a networkx and igraph compatible files format. special thanks to Benjamin Jacobs! + new pyMCDSts **make_ome_tiff** function, to save the output data in ome tiff file format. - + new pyMCDSts **plot_timeseries** function, to plot time series. + + new pyMCDSts **plot_timeseries** function, to plot time series. special thanks to Thierry-Pascal Fleurant! + new pyMCDSts **set_verbosity_true** function, to complete the pcdl.TimeSeries(verbosity=True/False) experience. + new pyMCDSts **set_verbosity_false** function to complete the pcdl.TimeSeries(verbosity=True/False) experience. @@ -247,7 +256,7 @@ Within the pcdl library, we tried to stick to the documentation policy laid out given the computer is connected to the internet, test data can easily be installed and removed with the **pcdl.install_data()** and **pcdl.uninstall_data()** functions now. + version 3.0.7 (2023-06-08): elmbeech/physicelldataloader - + pyMCDSts: replaces the svg dependent **mcdsts.make_jpeg**, **mcdsts.make_png**, and **mcdsts.make_tiff** with **mcdsts.make_imgcell** and **mcdsts.make_imgsubs** which generate images straight out of the loaded data. the **mcdsts.make_gif** and **mcdsts.make_movie** functions were adjusted accordingly. + + pyMCDSts: replaces the svg dependent **mcdsts.make_jpeg**, **mcdsts.make_png**, and **mcdsts.make_tiff** with **mcdsts.make_imgcell** and **mcdsts.make_imgsubs** which generate images straight out of the loaded data. the **mcdsts.make_gif** and **mcdsts.make_movie** functions were adjusted accordingly. special thanks to Marshal Gress! + pyMCDSts: **mcdsts.read_mcds** loads now automatically all mcds snapshots if no xmlfile\_list is provided (default). + version 3.0.6 (2023-04-29): elmbeech/physicelldataloader diff --git a/data_timeseries_2d.tar.gz b/data_timeseries_2d.tar.gz deleted file mode 100644 index f5ac93d..0000000 Binary files a/data_timeseries_2d.tar.gz and /dev/null differ diff --git a/data_timeseries_3d.tar.gz b/data_timeseries_3d.tar.gz deleted file mode 100644 index 6121992..0000000 Binary files a/data_timeseries_3d.tar.gz and /dev/null differ diff --git a/man/TUTORIAL_commandline.md b/man/TUTORIAL_commandline.md index 7ed82d2..3023a39 100644 --- a/man/TUTORIAL_commandline.md +++ b/man/TUTORIAL_commandline.md @@ -29,7 +29,7 @@ cd path/to/PhysiCell ``` ```bash make data-cleanup -python3 -c"import pathlib, pcdl, shutil; pcdl.install_data(); s_ipath=str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_2d'); shutil.copytree(s_ipath, 'output', dirs_exist_ok=True)" +python3 -c"import pathlib, pcdl, shutil; pcdl.install_data(); s_ipath=str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_2d'); shutil.copytree(s_ipath, 'output', dirs_exist_ok=True)" ``` diff --git a/man/TUTORIAL_julia.md b/man/TUTORIAL_julia.md index 7570ec8..b766b79 100644 --- a/man/TUTORIAL_julia.md +++ b/man/TUTORIAL_julia.md @@ -26,7 +26,7 @@ Package installation. ```julia using Pkg -Pkg.add("CSV") +Pkdg.add("CSV") Pkdg.add("DataFrames") ``` diff --git a/man/TUTORIAL_matlab_octave.md b/man/TUTORIAL_matlab_octave.md index cf1f127..0a9a74f 100644 --- a/man/TUTORIAL_matlab_octave.md +++ b/man/TUTORIAL_matlab_octave.md @@ -1,11 +1,11 @@ -# PhysiCell Data Loader Tutorial: pcdl and the Matlab and Octave programming language +# PhysiCell Data Loader Tutorial: pcdl and the Matlab programming language -[Matlab](https://www.mathworks.com/products/matlab.html) / GNU [Octave](https://octave.org/) + + +[Matlab](https://www.mathworks.com/products/matlab.html) is a scientific programming language used by some engineers. The earliest predecessor of pcdl was actually a Matlab implementation. -Coming full circle, this is how you can load some pcdl data constructs into Matlab and GNU Octave. - - +Coming full circle, this is how you can load some pcdl data constructs into Matlab. ## ✨ Handle csv files @@ -22,7 +22,7 @@ pcdl_get_conc_df output pcdl_get_cell_df output ``` -### Load a csv file into Matlab or Octave as a tabel +### Load a csv file into Matlab as a tabel ⚠ **bue 2024-09-22:** the readtable function is not yet implemented in Octave. @@ -51,7 +51,7 @@ pcdl_get_conc_attribute output 2 pcdl_get_cell_attribute output 2 ``` -### Load json files into Matlab or Octave +### Load json files into Matlab ```matlab struct_conc = jsondecode(fileread("output/timeseries_conc_attribute_minmax.json")) @@ -72,10 +72,10 @@ cd path/to/PhysiCell pcdl_make_graph_gml output/output00000024.xml neighbor --node_attribute cell_type dead oxygen pressure ``` -### Load gml files into a Matlab or Octave data construct +### Load gml files into a Matlab data construct -We will use the [matlab-igraph](https://www.mathworks.com/matlabcentral/fileexchange/159001-matlab-igraph) toolbox to load gml files into Matlab or Octave. -+ https://github.com/DavidRConnell/matlab-igraph/releases/tag/v0.2.0 +We will use the [matlab-igraph](https://www.mathworks.com/matlabcentral/fileexchange/159001-matlab-igraph) toolbox to load gml files into Matlab. ++ https://github.com/DavidRConnell/matlab-igraph + https://igraph.org/ Install matlab-igaph toolbox. @@ -101,14 +101,14 @@ pcdl_make_conc_vtk output/output00000024.xml pcdl_make_cell_vtk output/output00000024.xml ``` -### Load a vtr and vtp file into Matlab or Octave data construct +### Load a vtr and vtp file into Matlab data construct + https://www.mathworks.com/matlabcentral/fileexchange/94993-vtktoolbox + https://github.com/KIT-IBT/vtkToolbox -Install matlab-igaph toolbox. +Install vtk toolbox. -Load vtkfile into Matlab or Octave. +Load vtkfile into Matlab. ```matlab output/output00000024_conc.vtr diff --git a/man/TUTORIAL_paraview.md b/man/TUTORIAL_paraview.md index 3a4b0ef..8d94ced 100644 --- a/man/TUTORIAL_paraview.md +++ b/man/TUTORIAL_paraview.md @@ -1,5 +1,11 @@ # PhysiCell Data Loader Tutorial: pcdl and Paraview + + [Paraview](https://www.paraview.org/) is a free and open source scientific visualization software, that lets us load and analyze vtk rectilinear grid data and vtk polynomial data. diff --git a/man/TUTORIAL_python3_graph.md b/man/TUTORIAL_python3_graph.md index 84fdbaa..4f31bef 100644 --- a/man/TUTORIAL_python3_graph.md +++ b/man/TUTORIAL_python3_graph.md @@ -3,7 +3,7 @@ [Gml](https://github.com/elmbeech/physicelldataloader/blob/master/man/publication/himsolt1996gml_a_portable_graph_file_format.pdf) (graph modeling language) is a portable plain text file format for graphs, that can be read by the popular graph libraries [networkx](https://networkx.org/) (python), [igraph](https://igraph.org/) (C, C++, mathematica, python, R) , and possible other graph analysis software too. -Pcdl can export neighborhood graphs in gml format for downstream analysis. +Pcdl can export neighborhood graphs in gml format for downstream analysis. If you are new to graph theory, then I recommend reading [A Simple Introduction to Graph Theory](https://www.brianheinold.net/graph_theory/A_Simple_Introduction_to_Graph_Theory_Heinold.pdf) from Prof. Brian Heinold from Mount Saint Mary's University in Emmitsburg, Maryland, USA. @@ -48,7 +48,7 @@ print(sorted(g.edges.keys())[0:4]) g.nodes['node_0'] # {'cell_type': 'cancer_cell', 'dead': 0, 'oxygen': 25.304510426523084, 'pressure': 10.519314516003435} ``` ```python -g.edgea[('node_0', 'node_1')] # {'label': 'edge_0_1', 'distance_microns': 15} +g.edges[('node_0', 'node_1')] # {'label': 'edge_0_1', 'distance_microns': 15} ``` @@ -60,7 +60,7 @@ import igraph as ig g = ig.Graph.Read_GML('output/output00000024_neighbor.gml') print(g) ``` -``python +```python ig.summary(g) ``` diff --git a/man/TUTORIAL_python3_json.md b/man/TUTORIAL_python3_json.md index ed92274..eae2a53 100644 --- a/man/TUTORIAL_python3_json.md +++ b/man/TUTORIAL_python3_json.md @@ -9,7 +9,7 @@ The [json library](https://docs.python.org/3/library/json.html) is a part of cor Json is the ideal data format for unstructured data constructs that not can be stored in csv file format, like a dictionary of lists. Please note, python objecta are not per se json comaptible. For example: -Complex numbers are a standard data type in python, but complex numbers can not be stored in json. +Complex numbers are a standard data type in python, but complex numbers cannot be stored in json. Python dictionary keys can be of almost any data type, but json object keys have to be strings. diff --git a/man/TUTORIAL_python3_napari.md b/man/TUTORIAL_python3_napari.md index 2aacaa5..8dc3706 100644 --- a/man/TUTORIAL_python3_napari.md +++ b/man/TUTORIAL_python3_napari.md @@ -1,6 +1,6 @@ # PhysiCell Data Loader Tutorial: pcdl and Python and Napari -[Napari](https://napari.org/stable/) is both, a python library and a GUI software. +[Napari](https://napari.org/stable/) is both a python library and a GUI software. Napari is used by wetlab scientists and bioinformatician to analyze fluorescent microscopy data. Napari can read [ome.tiff](https://www.openmicroscopy.org/ome-files/) files. https://github.com/AllenCellModeling/napari-aicsimageio @@ -8,7 +8,7 @@ https://github.com/AllenCellModeling/napari-aicsimageio ## Install napari -And install the [aicsimageio](https://allencellmodeling.github.io/aicsimageio/) library, +And install the [aicsimageio](https://github.com/AllenCellModeling/aicsimageio) library, which installs the "ome-types" napari plugin, that napari can read ome.tiff images inclusive ome metadata. diff --git a/man/TUTORIAL_python3_ometiff.md b/man/TUTORIAL_python3_ometiff.md index 0598261..abb3dd6 100644 --- a/man/TUTORIAL_python3_ometiff.md +++ b/man/TUTORIAL_python3_ometiff.md @@ -14,7 +14,7 @@ and [TUTORIAL_fiji_imagej.md](https://github.com/elmbeech/physicelldataloader/bl Additionally ome.tiff, tiff, png, and jpeg files can as well be loaded back in to python as [numpy](https://numpy.org/) array, for example with the [sci-kit image](https://scikit-image.org/) library (image data only). -Besides that, ome.tiff files can be loaded with Allen Institute for Cell Science's [aicsiamgeio](https://github.com/AllenCellModeling/aicsimageio) library (image and metadata). +Besides that, ome.tiff files can be loaded with Allen Institute for Cell Science's [aicsimageio](https://github.com/AllenCellModeling/aicsimageio) library and possibly with its successor library [bioio](https://github.com/bioio-devs/bioio) (image and metadata). ### Save pcdl data constructs from the command line into tiff and ome.tiff files @@ -60,7 +60,7 @@ a_cell.shape # (480, 640, 4) from skimage import io a_ome = io.imread('output/timeseries_ID.ome.tiff') -a_ome.shape (25, 2, 200, 300) +a_ome.shape # (25, 2, 200, 300) ``` diff --git a/man/TUTORIAL_python3_scverse.md b/man/TUTORIAL_python3_scverse.md index 4873cca..a73dd43 100644 --- a/man/TUTORIAL_python3_scverse.md +++ b/man/TUTORIAL_python3_scverse.md @@ -28,7 +28,7 @@ Let's install the required analysis libraries pip3 install -U scanpy[leiden] # single cell analysis inclusive leiden graph clustering algorithm. ``` -To runs thi tutorial, +To runs this tutorial, you can install the 3D unit test dataset into your PhysiCell output folder, by executing the following command sequence. @@ -39,7 +39,7 @@ cd path/to/PhysiCell ``` ```bash make data-cleanup -python3 -c"import pathlib, pcdl, shutil; pcdl.install_data(); s_ipath=str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_3d'); shutil.copytree(s_ipath, 'output', dirs_exist_ok=True)" +python3 -c"import pathlib, pcdl, shutil; pcdl.install_data(); s_ipath=str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_3d'); shutil.copytree(s_ipath, 'output', dirs_exist_ok=True)" ``` diff --git a/man/TUTORIAL_python3_timeseries.md b/man/TUTORIAL_python3_timeseries.md index e696ca6..5950eaf 100644 --- a/man/TUTORIAL_python3_timeseries.md +++ b/man/TUTORIAL_python3_timeseries.md @@ -65,7 +65,7 @@ cd path/to/PhysiCell ``` ```bash make data-cleanup -python3 -c"import pathlib, pcdl, shutil; pcdl.install_data(); s_ipath=str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_2d'); shutil.copytree(s_ipath, 'output', dirs_exist_ok=True)" +python3 -c"import pathlib, pcdl, shutil; pcdl.install_data(); s_ipath=str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_2d'); shutil.copytree(s_ipath, 'output', dirs_exist_ok=True)" ``` diff --git a/man/TUTORIAL_python3_timestep.md b/man/TUTORIAL_python3_timestep.md index 1d29eda..0f37503 100644 --- a/man/TUTORIAL_python3_timestep.md +++ b/man/TUTORIAL_python3_timestep.md @@ -1,6 +1,6 @@ # PhysiCell Data Loader Tutorial: pcdl and python and MCDS TimeSteps -In this chapter, we will load the pcdl library and use its TimeStep class to load the data snapshot 00000012, from [data\_timeseries\_ 2d](https://github.com/elmbeech/physicelldataloader/tree/master/pcdl/data_timeseries_2d) from the 2D time series test dataset. +In this chapter, we will load the pcdl library and use its TimeStep class to load the data snapshot 00000012, from [data\_timeseries\_ 2d](https://github.com/elmbeech/physicelldataloader/tree/master/pcdl/output_2d) from the 2D time series test dataset. First, please install the latest version of physicelldataloader (pcdl), as described in the [HowTo](https://github.com/elmbeech/physicelldataloader/blob/master/man/HOWTO.md) chapter. @@ -23,7 +23,7 @@ cd path/to/PhysiCell ``` ```bash make data-cleanup -python3 -c"import pathlib, pcdl, shutil; pcdl.install_data(); s_ipath=str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_2d'); shutil.copytree(s_ipath, 'output', dirs_exist_ok=True)" +python3 -c"import pathlib, pcdl, shutil; pcdl.install_data(); s_ipath=str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_2d'); shutil.copytree(s_ipath, 'output', dirs_exist_ok=True)" ``` @@ -292,7 +292,7 @@ with the agent's position (xyz), the related mesh center coordinate (mnp), the r ```python df_cell = mcds.get_cell_df() -df_cel.info() +df_cell.info() ``` ``` df_cell.shape # (992, 95) this means: 992 agents, 96 tracked variables @@ -343,7 +343,7 @@ print(ann) # AnnData object with n_obs × n_vars = 992 × 26 variables: ```python -ann.var_name # numerical cell attributes: Index(['cell_BM_repulsion_strength', ... , 'total_volume'], dtype='object') +ann.var_names # numerical cell attributes: Index(['cell_BM_repulsion_strength', ... , 'total_volume'], dtype='object') ``` observation: @@ -375,7 +375,7 @@ ann.uns['neighbor'] # metadata about the neighborhood graph. The output tells us that we have loaded a time step with 992 cell agents and 26 numerical attributes (vars). Further, we have 4 categorical cell agent attributes (obs). -We have each cell agnet's xy spatial coordinate information (obsm). +We have each cell agent's xy spatial coordinate information (obsm). And we have cell neighbor graph infromation (obsp, uns). Please have a look at [TUTORIAL_python3_scverse.md](https://github.com/elmbeech/physicelldataloader/blob/master/man/TUTORIAL_python3_scverse.md) to learn more. diff --git a/man/TUTORIAL_python3_vtk.md b/man/TUTORIAL_python3_vtk.md index fd8ff4c..efdb49a 100644 --- a/man/TUTORIAL_python3_vtk.md +++ b/man/TUTORIAL_python3_vtk.md @@ -65,7 +65,7 @@ pip3 install fury ``` -Unfortunately, rectiliniar grid files are not supported, conc.vtr files can't be loaded. +Unfortunately, rectiliniar grid files are not supported, conc.vtr files cannot be loaded. Load and display cell.vtp ploydata files. diff --git a/man/docstring/mcds.make_ome_tiff.md b/man/docstring/mcds.make_ome_tiff.md index cf7796e..8e278af 100644 --- a/man/docstring/mcds.make_ome_tiff.md +++ b/man/docstring/mcds.make_ome_tiff.md @@ -3,13 +3,26 @@ ## input: ``` - cell_attribute: strings; default is 'ID', which will result in a segmentation mask. - column name within cell dataframe. - the column data type has to be numeric (bool, int, float) and can't be string. + cell_attribute: strings; default is 'ID', which will result in a + cell segmentation mask. + column name within the cell dataframe. + the column data type has to be numeric (bool, int, float) + and cannot be string. + the result will be stored as 32 bit float. + + conc_cutoff: dictionary string to real; default is an empty dictionary. + if a contour from a substrate not should be cut by greater + than zero (shifted to integer 1), another cutoff value can be + specified here. + + focus: set of strings; default is a None + set of substrate and cell_type names to specify what will be + translated into ome tiff format. + if None, all substrates and cell types will be processed. file: boolean; default True - if True, an ome tiff file is output. - if False, a numpy array with shape czyx is output. + if True, an ome tiff file is the output. + if False, a numpy array with shape czyx is the output. ``` diff --git a/man/docstring/mcdsts.make_ome_tiff.md b/man/docstring/mcdsts.make_ome_tiff.md index 2a75a25..f9b9ca9 100644 --- a/man/docstring/mcdsts.make_ome_tiff.md +++ b/man/docstring/mcdsts.make_ome_tiff.md @@ -3,13 +3,25 @@ ## input: ``` - cell_attribute: strings; default is 'ID', with will result in a segmentation mask. - column name within cell dataframe. - the column data type has to be numeric (bool, int, float) and can't be string. + cell_attribute: strings; default is 'ID', which will result in a + cell segmentation mask. + column name within the cell dataframe. + the column data type has to be numeric (bool, int, float) + and cannot be string. + the result will be stored as 32 bit float. + + conc_cutoff: dictionary string to real; default is an empty dictionary. + if a contour from a substrate not should be cut by greater + than zero (shifted to integer 1), another cutoff value can be specified here. + + focus: set of strings; default is a None + set of substrate and cell_type names to specify what will be + translated into ome tiff format. + if None, all substrates and cell types will be processed. file: boolean; default True - if True, an ome tiff file is output. - if False, a numpy array with shape tczyx is output. + if True, an ome tiff file is the output. + if False, a numpy array with shape tczyx is the output. collapse: boole; default True should all mcds time steps from the time series be collapsed @@ -22,6 +34,7 @@ ``` a_tczyx_img: numpy array or ome tiff file. + ``` ## description: diff --git a/man/docstring/pcdl_make_ome_tiff.md b/man/docstring/pcdl_make_ome_tiff.md index a01eba7..edf2f68 100644 --- a/man/docstring/pcdl_make_ome_tiff.md +++ b/man/docstring/pcdl_make_ome_tiff.md @@ -1,21 +1,23 @@ ``` usage: pcdl_make_ome_tiff [-h] [--microenv MICROENV] [--physiboss PHYSIBOSS] [--settingxml SETTINGXML] [-v VERBOSE] - [--collapse COLLAPSE] + [--conc_cutoff [CONC_CUTOFF ...]] + [--focus FOCUS [FOCUS ...]] [--collapse COLLAPSE] [path] [cell_attribute] -function to transform chosen mcds output into an 1[um] spaced czyx (channel, -z-axis, y-axis, x-axis) ome tiff file, one substrate or cell_type per channel. -the ome tiff file format can for example be read by the napari +function to transform chosen mcdsts output into an 1[um] spaced tczyx (time, +channel, z-axis, y-axis, x-axis) ome tiff file, one substrate or cell_type per +channel. the ome tiff file format can for example be read by the napari (https://napari.org/stable/) or fiji imagej (https://fiji.sc/) software. positional arguments: path path to the PhysiCell output directory or a outputnnnnnnnn.xml file. default is . . - cell_attribute mcds.get_cell_df dataframe columns, used for + cell_attribute mcds.get_cell_df dataframe column, used for cell_attribute. the column data type has to be numeric - (bool, int, float) and can not be string. default is - ID, with will result in a segmentation mask. + (bool, int, float) and cannot be string. the result + will be stored as 32 bit float. default is ID, with + will result in a segmentation mask. options: -h, --help show this help message and exit @@ -35,6 +37,17 @@ options: -v VERBOSE, --verbose VERBOSE setting verbose to False for less text output, while processing. default is True. + --conc_cutoff [CONC_CUTOFF ...] + if a contour from a substrate not should be cut by + greater than zero (shifted to integer 1), another + cutoff value can be specified here like this: + substarte:value substrate:value substarte:value . + default is and empty string. + --focus FOCUS [FOCUS ...] + set of substrate and cell_type names to specify what + will be translated into ome tiff format. if None, all + substrates and cell types will be processed. default + is a None. --collapse COLLAPSE should all mcds time steps from the time series be collapsed into one big ome.tiff, or a many ome.tiff, one ome.tiff for each time step?, default is True. diff --git a/man/scarab.py b/man/scarab.py index f7cf2b5..f17908f 100644 --- a/man/scarab.py +++ b/man/scarab.py @@ -93,13 +93,13 @@ def docstring_md(s_function, ls_doc, s_header=None, s_opath='man/docstring/'): # load data mcds = pcdl.TimeStep( - 'pcdl/data_timeseries_2d/output00000000.xml', + 'pcdl/output_2d/output00000000.xml', custom_data_type={'oncoprotein': str}, verbose=False, ) mcdsts = pcdl.TimeSeries( - 'pcdl/data_timeseries_2d/', + 'pcdl/output_2d/', custom_data_type={'oncoprotein': str}, verbose=False, ) diff --git a/output_2d.tar.gz b/output_2d.tar.gz new file mode 100644 index 0000000..5d365a6 Binary files /dev/null and b/output_2d.tar.gz differ diff --git a/output_3d.tar.gz b/output_3d.tar.gz new file mode 100644 index 0000000..2d6b45f Binary files /dev/null and b/output_3d.tar.gz differ diff --git a/pcdl/VERSION.py b/pcdl/VERSION.py index 310a75d..6093f83 100644 --- a/pcdl/VERSION.py +++ b/pcdl/VERSION.py @@ -1 +1 @@ -__version__ = '3.3.1' +__version__ = '3.3.2' diff --git a/pcdl/data_timeseries.py b/pcdl/data_timeseries.py index 1fae7df..9358cd6 100644 --- a/pcdl/data_timeseries.py +++ b/pcdl/data_timeseries.py @@ -7,18 +7,16 @@ # authors: Patrick Wall, Randy Heiland, Paul Macklin, Elmar Bucher # # description: -# code to download the data_timeseries.tar.gz files +# code to download the output.tar.gz files # from the source code repository, and extract them to where # the pcdl library is installed, and code to remove the installed -# data_timeseries folders. -# the extracted data_timeseries_2d and data_timeseries_3d folder contains +# output folders. +# the extracted output_2d and output_3d folder contains # example PhysiCell output, necessary to run the pytest unit tests # and useful to run through the tutorial. ######### -# bue 20240822: in future (with the next mcds version) in need a better dataset: -# 2d and 3d, 2 substrates, 2 cell_types -# mcds time step 60[min], total time 24[h] +# bue 20240822: in future: # maybe physiboss output? # library @@ -47,8 +45,8 @@ def __init__(self): # for each timeseries for s_url in [ - 'https://raw.githubusercontent.com/elmbeech/physicelldataloader/master/data_timeseries_2d.tar.gz', - 'https://raw.githubusercontent.com/elmbeech/physicelldataloader/master/data_timeseries_3d.tar.gz', + 'https://raw.githubusercontent.com/elmbeech/physicelldataloader/master/output_2d.tar.gz', + 'https://raw.githubusercontent.com/elmbeech/physicelldataloader/master/output_3d.tar.gz', ]: # get path and filename s_file = s_url.split('/')[-1] @@ -88,7 +86,7 @@ def __init__(self): # for each obsolet timeserie for s_file in sorted(os.listdir(s_path)): - if s_file.startswith('data_timeseries_'): + if s_file.startswith('output_'): # get path and filename s_pathfile = s_path + s_file diff --git a/pcdl/pyAnnData.py b/pcdl/pyAnnData.py index dddfac2..51757ea 100644 --- a/pcdl/pyAnnData.py +++ b/pcdl/pyAnnData.py @@ -117,7 +117,7 @@ def scaler(df_x, scale='maxabs'): return df_x -def _anndextract(df_cell, scale='maxabs', graph_attached={}, graph_neighbor={}, graph_method='PhysiCell'): +def _anndextract(df_cell, scale='maxabs', graph_attached={}, graph_neighbor={}, graph_spring={}, graph_method='PhysiCell'): """ input: df_cell: pandas dataframe @@ -129,15 +129,19 @@ def _anndextract(df_cell, scale='maxabs', graph_attached={}, graph_neighbor={}, for more input, check out: help(pcdl.scaler). graph_attached: dict; default {} - graph dictionary that, if loaded, can be - fetched with mcds.get_attched_graph(). + attached graph dictionary, retrieved with + with the mcds.get_attched_graph() function. graph_neighbor: dict; default {} - graph dictionary that, if loaded, can be - fetched with mcds.get_neighbor_graph(). + neighbor graph dictionary, retrieved + with the mcds.get_neighbor_graph() function. + + graph_spring: dict; default {} + spring_attached graph dictionary, retrieved + with the mcds.get_spring_graph_dict() function. graph_method: string; default PhysiCell - method how the graph was generated. + method how the graphs were generated. output: df_count, df_obs, d_obsm, d_obsp, d_uns dataframes and dictionaries, @@ -177,7 +181,7 @@ def _anndextract(df_cell, scale='maxabs', graph_attached={}, graph_neighbor={}, # transform cell id graph dict to index matrix and pack for anndata d_obsp = {} # pairwise annotation of obeservation d_uns = {} # unstructured data - for s_graph, dei_graph in [('neighbor', graph_neighbor), ('attached', graph_attached)]: + for s_graph, dei_graph in [('neighbor', graph_neighbor), ('attached', graph_attached), ('spring', graph_spring)]: lli_edge = [] lr_distance = [] for i_src, ei_dst in dei_graph.items(): @@ -282,8 +286,9 @@ def __init__(self, xmlfile, output_path='.', custom_data_type={}, microenv=True, processing, similar to the original pyMCDS_cells.py script. graph: boole; default True - should neighbor garph and attached graph be loaded? - setting graph to False will use less memory and speed up processing. + should neighbor garph, attached graph, and spring attached graph + be loaded? setting graph to False will use less memory and + speed up processing. physiboss: boole; default True should physiboss state data be loaded, if found? @@ -404,8 +409,9 @@ def __init__(self, output_path='.', custom_data_type={}, load=True, microenv=Tru processing, similar to the original pyMCDS_cells.py script. graph: boole; default True - should neighbor graph and attached graph be loaded? - setting graph to False will use less memory and speed up processing. + should neighbor garph, attached graph, and spring attached graph + be loaded? setting graph to False will use less memory and + speed up processing. physiboss: boole; default True should physiboss state data be loaded, if found? @@ -500,7 +506,7 @@ def get_anndata(self, values=1, drop=set(), keep=set(), scale='maxabs', collapse ls_column.extend(sorted(self.get_cell_attribute(values=values, drop=drop, keep=keep, allvalues=False).keys())) # collapse warning - if collapse: + if collapse and self.verbose: print('Warning @ mcdsts.get_anndata : only df_cell data, but not graph data, can be collapsed.') # processing @@ -529,6 +535,7 @@ def get_anndata(self, values=1, drop=set(), keep=set(), scale='maxabs', collapse scale = scale, #graph_attached = {}, #graph_neighbor = {}, + #graph_spring = {}, #graph_method = s_physicellv, ) # count @@ -564,6 +571,7 @@ def get_anndata(self, values=1, drop=set(), keep=set(), scale='maxabs', collapse scale = scale, graph_attached = mcds.get_attached_graph_dict(), graph_neighbor = mcds.get_neighbor_graph_dict(), + graph_spring = mcds.get_spring_graph_dict(), graph_method = s_physicellv, ) # annmcds diff --git a/pcdl/pyCLI.py b/pcdl/pyCLI.py index 8a5e1b4..41ad527 100644 --- a/pcdl/pyCLI.py +++ b/pcdl/pyCLI.py @@ -71,6 +71,10 @@ def get_version(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -139,6 +143,10 @@ def get_unit_dict(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -206,6 +214,10 @@ def get_substrate_list(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -291,6 +303,10 @@ def get_conc_attribute(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -388,6 +404,10 @@ def get_conc_df(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -574,6 +594,10 @@ def plot_contour(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -697,6 +721,10 @@ def make_conc_vtk(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -717,7 +745,9 @@ def make_conc_vtk(): settingxml = None, verbose = False if args.verbose.lower().startswith('f') else True ) - s_opathfile = mcds.make_conc_vtk() + s_opathfile = mcds.make_conc_vtk( + visualize = False, + ) # going home return s_opathfile @@ -732,7 +762,9 @@ def make_conc_vtk(): settingxml = None, verbose = False if args.verbose.lower().startswith('f') else True, ) - ls_opathfile = mcdsts.make_conc_vtk() + ls_opathfile = mcdsts.make_conc_vtk( + visualize = False, + ) # going home return ls_opathfile @@ -780,6 +812,10 @@ def get_celltype_list(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -886,6 +922,10 @@ def get_cell_attribute(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -1031,6 +1071,10 @@ def get_cell_df(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -1125,7 +1169,7 @@ def get_anndata(): parser.add_argument( '--graph', default = 'true', - help = 'should neighbor graph and attach graph be extracted and loaded into the anndata object? default is True.' + help = 'should neighbor graph, attach graph, and attached spring graph be extracted and loaded into the anndata object? default is True.' ) # TimeSeries physiboss parser.add_argument( @@ -1186,6 +1230,10 @@ def get_anndata(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -1313,7 +1361,7 @@ def make_graph_gml(): parser.add_argument( 'graph_type', nargs = '?', - help = 'to specify which physicell output data should be processed. attached: processes mcds.get_attached_graph_dict dictionary. neighbor: processes mcds.get_neighbor_graph_dict dictionary.', + help = 'to specify which physicell output data should be processed. attached: processes mcds.get_attached_graph_dict dictionary. neighbor: processes mcds.get_neighbor_graph_dict dictionary spring: processes mcds.get_spring_graph_dict dictionary.', ) # make_graph_gml edge_attribute parser.add_argument( @@ -1335,6 +1383,10 @@ def make_graph_gml(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -1548,6 +1600,10 @@ def plot_scatter(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -1698,6 +1754,10 @@ def make_cell_vtk(): # process arguments s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -1958,6 +2018,12 @@ def plot_timeseries(): print(args) # process arguments + s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] + args.path = s_path # path if not os.path.exists(args.path + '/initial.xml'): @@ -2039,7 +2105,7 @@ def make_ome_tiff(): # argv parser = argparse.ArgumentParser( prog = 'pcdl_make_ome_tiff', - description = 'function to transform chosen mcds output into an 1[um] spaced czyx (channel, z-axis, y-axis, x-axis) ome tiff file, one substrate or cell_type per channel. the ome tiff file format can for example be read by the napari (https://napari.org/stable/) or fiji imagej (https://fiji.sc/) software.', + description = 'function to transform chosen mcdsts output into an 1[um] spaced tczyx (time, channel, z-axis, y-axis, x-axis) ome tiff file, one substrate or cell_type per channel. the ome tiff file format can for example be read by the napari (https://napari.org/stable/) or fiji imagej (https://fiji.sc/) software.', epilog = 'homepage: https://github.com/elmbeech/physicelldataloader', ) @@ -2082,7 +2148,21 @@ def make_ome_tiff(): 'cell_attribute', nargs = '?', default = 'ID', - help = 'mcds.get_cell_df dataframe columns, used for cell_attribute. the column data type has to be numeric (bool, int, float) and can not be string. default is ID, with will result in a segmentation mask.', + help = 'mcds.get_cell_df dataframe column, used for cell_attribute. the column data type has to be numeric (bool, int, float) and cannot be string. the result will be stored as 32 bit float. default is ID, with will result in a segmentation mask.', + ) + # make_ome_tiff conc_cutoff + parser.add_argument( + '--conc_cutoff', + nargs = '*', + default = [], + help = 'if a contour from a substrate not should be cut by greater than zero (shifted to integer 1), another cutoff value can be specified here like this: substarte:value substrate:value substarte:value . default is and empty string.', + ) + # make_ome_tiff focus + parser.add_argument( + '--focus', + nargs = '+', + default = ['none'], + help = 'set of substrate and cell_type names to specify what will be translated into ome tiff format. if None, all substrates and cell types will be processed. default is a None.', ) # make_ome_tiff file True # make_ome_tiff collapse @@ -2096,8 +2176,12 @@ def make_ome_tiff(): args = parser.parse_args() print(args) - # process arguments + # path s_path = args.path + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] s_pathfile = s_path if not s_pathfile.endswith('.xml'): s_pathfile = s_pathfile + '/initial.xml' @@ -2106,6 +2190,22 @@ def make_ome_tiff(): if not os.path.exists(s_pathfile): sys.exit(f'Error @ pyCLI.make_ome_tiff : {s_pathfile} path does not look like a outputnnnnnnnn.xml file or physicell output directory ({s_path}/initial.xml is missing).') + # conc_cutoff + d_conccutoff = {} + for s_conccutoff in args.conc_cutoff: + s_substrate, s_value = s_conccutoff.split(':') + if (s_value.find('.') > -1): + o_value = float(s_value) + else: + o_value = int(s_value) + d_conccutoff.update({s_substrate : o_value}) + + # focus + if (args.focus[0].lower() == 'none'): + es_focus = None + else: + es_focus = set( args.focus) + # run if os.path.isfile(args.path): mcds = pcdl.pyMCDS( @@ -2120,6 +2220,8 @@ def make_ome_tiff(): ) s_opathfile = mcds.make_ome_tiff( cell_attribute = args.cell_attribute, + conc_cutoff = d_conccutoff, + focus = es_focus, file = True, ) # going home @@ -2138,6 +2240,8 @@ def make_ome_tiff(): ) o_opathfile = mcdsts.make_ome_tiff( cell_attribute = args.cell_attribute, + conc_cutoff = d_conccutoff, + focus = es_focus, file = True, collapse = False if args.collapse.lower().startswith('f') else True, ) @@ -2177,6 +2281,13 @@ def make_gif(): print(args) # process arguments + s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] + args.path = s_path + # run s_opathfile = pcdl.make_gif( path = args.path, @@ -2221,6 +2332,13 @@ def make_movie(): print(args) # process arguments + s_path = args.path.replace('\\','/') + while (s_path.find('//') > -1): + s_path = s_path.replace('//','/') + if (s_path.endswith('/')) and (len(s_path) > 1): + s_path = s_path[:-1] + args.path = s_path + # run s_opathfile = pcdl.make_movie( path = args.path, diff --git a/pcdl/pyMCDS.py b/pcdl/pyMCDS.py index cd09a53..1c1c33e 100644 --- a/pcdl/pyMCDS.py +++ b/pcdl/pyMCDS.py @@ -15,7 +15,7 @@ # load library -import aicsimageio +import aicsimageio # bioio, bioio_base from aicsimageio.writers import OmeTiffWriter import matplotlib.pyplot as plt from matplotlib import cm @@ -610,13 +610,16 @@ def is_in_mesh(self, x, y, z, halt=False): tr_x, tr_y, tr_z = self.get_xyz_range() if (x < tr_x[0]) or (x > tr_x[1]): - print(f'Warning @ pyMCDS.is_in_mesh : x = {x} out of bounds: x-range is {tr_x}.') + if self.verbose: + print(f'Warning @ pyMCDS.is_in_mesh : x = {x} out of bounds: x-range is {tr_x}.') b_isinmesh = False elif (y < tr_y[0]) or (y > tr_y[1]): - print(f'Warning @ pyMCDS.is_in_mesh : y = {y} out of bounds: y-range is {tr_y}.') + if self.verbose: + print(f'Warning @ pyMCDS.is_in_mesh : y = {y} out of bounds: y-range is {tr_y}.') b_isinmesh = False elif (z < tr_z[0]) or (z > tr_z[1]): - print(f'Warning @ pyMCDS.is_in_mesh : z = {z} out of bounds: z-range is {tr_z}.') + if self.verbose: + print(f'Warning @ pyMCDS.is_in_mesh : z = {z} out of bounds: z-range is {tr_z}.') b_isinmesh = False # output @@ -847,7 +850,8 @@ def get_concentration(self, substrate, z_slice=None, halt=False): if not (z_slice is None): _, _, ar_p_axis = self.get_mesh_mnp_axis() if not (z_slice in ar_p_axis): - print(f'Warning @ pyMCDS.get_concentration : specified z_slice {z_slice} is not an element of the z-axis mesh centers set {ar_p_axis}.') + if self.verbose: + print(f'Warning @ pyMCDS.get_concentration : specified z_slice {z_slice} is not an element of the z-axis mesh centers set {ar_p_axis}.') if halt: sys.exit('Processing stopped!') else: @@ -956,7 +960,8 @@ def get_conc_df(self, z_slice=None, halt=False, values=1, drop=set(), keep=set() if not (z_slice is None): _, _, ar_p_axis = self.get_mesh_mnp_axis() if not (z_slice in ar_p_axis): - print(f'Warning @ pyMCDS.get_conc_df : specified z_slice {z_slice} is not an element of the z-axis mesh centers set {ar_p_axis}.') + if self.verbose: + print(f'Warning @ pyMCDS.get_conc_df : specified z_slice {z_slice} is not an element of the z-axis mesh centers set {ar_p_axis}.') if halt: sys.exit('Processing stopped!') else: @@ -1106,7 +1111,7 @@ def plot_contour(self, focus, z_slice=0.0, vmin=None, vmax=None, alpha=1, fill=T """ # handle initial.svg for s and figsizepx if (figsizepx is None): - s_pathfile = self.path + 'initial.svg' + s_pathfile = self.path + '/initial.svg' try: x_tree = etree.parse(s_pathfile) x_root = x_tree.getroot() @@ -1114,7 +1119,8 @@ def plot_contour(self, focus, z_slice=0.0, vmin=None, vmax=None, alpha=1, fill=T i_height = int(np.ceil(float(x_root.get('height')))) # px figsizepx = [i_width, i_height] except FileNotFoundError: - print(f'Warning @ pyMCDS.plot_contour : could not load {s_pathfile} to auto detect figsizepx. take default.') + if self.verbose: + print(f'Warning @ pyMCDS.plot_contour : could not load {s_pathfile} to auto detect figsizepx. take default.') figsizepx = [640, 480] # handle figure size @@ -1152,7 +1158,7 @@ def plot_contour(self, focus, z_slice=0.0, vmin=None, vmax=None, alpha=1, fill=T df_conc.sort_values(['mesh_center_m', 'mesh_center_n', 'mesh_center_p'], inplace=True) # meshgrid shape - df_mesh = df_conc.pivot(index='mesh_center_m', columns='mesh_center_n', values=focus) + df_mesh = df_conc.pivot(index='mesh_center_n', columns='mesh_center_m', values=focus) # handle vmin and vmax input if (vmin is None): @@ -1206,7 +1212,7 @@ def plot_contour(self, focus, z_slice=0.0, vmin=None, vmax=None, alpha=1, fill=T else: # handle output path and filename - s_path = f'{self.path}/conc_{focus}_z{round(z_slice,9)}/' + s_path = self.path + f'/conc_{focus}_z{round(z_slice,9)}/' os.makedirs(s_path, exist_ok=True) s_file = self.xmlfile.replace('.xml', f'_{focus}.{ext}') s_pathfile = f'{s_path}{s_file}' @@ -1221,13 +1227,15 @@ def plot_contour(self, focus, z_slice=0.0, vmin=None, vmax=None, alpha=1, fill=T return s_pathfile - def make_conc_vtk(self): + def make_conc_vtk(self, visualize=True): """ input: + visualize: boolean; default is True + additionally, visualize cells using vtk renderer. output: s_vtkpathfile: vtk rectilinear grid file that contains - 3D distributions of all substrates over the microenvironment. + 3D distributions of all substrates over the microenvironment. description: function generates a vtk rectilinear grid file that contains @@ -1242,71 +1250,177 @@ def make_conc_vtk(self): print(f'processing: {s_vtkfile} ...') # get microenviornment data frame - df_micenv = self.get_conc_df() - - # generate a rectilinear grid - vr_grid = vtk.vtkRectilinearGrid() + df_conc = self.get_conc_df() # define dimensions of the grid - ti_dim = (df_micenv.loc[:, 'voxel_i'].unique().shape[0], df_micenv.loc[:, 'voxel_j'].unique().shape[0], df_micenv.loc[:, 'voxel_k'].unique().shape[0]) + ti_dim = ( + self.get_voxel_ijk_range()[0][1] + 1, + self.get_voxel_ijk_range()[1][1] + 1, + self.get_voxel_ijk_range()[2][1] + 1, + ) - # define coordinates for the grid - vf_x = vtk.vtkFloatArray() - vf_y = vtk.vtkFloatArray() - vf_z = vtk.vtkFloatArray() + # generate a rectilinear grid + vrg_data = vtk.vtkRectilinearGrid() - # assign coordinates for the grid - vf_x.SetNumberOfTuples(ti_dim[0]) - vf_y.SetNumberOfTuples(ti_dim[1]) - vf_z.SetNumberOfTuples(ti_dim[2]) + # generate and populate coordinates for the grid + vfa_x = vtk.vtkFloatArray() + vfa_y = vtk.vtkFloatArray() + vfa_z = vtk.vtkFloatArray() + vfa_x.SetNumberOfTuples(ti_dim[0]) + vfa_y.SetNumberOfTuples(ti_dim[1]) + vfa_z.SetNumberOfTuples(ti_dim[2]) - # populate the coordinates - for m, x in enumerate(sorted(df_micenv.loc[:, 'mesh_center_m'].unique())): - vf_x.SetValue(m, x) + for i, m in enumerate(self.get_mesh_mnp_axis()[0]): + vfa_x.SetValue(i, m) - for n, y in enumerate(sorted(df_micenv.loc[:, 'mesh_center_n'].unique())): - vf_y.SetValue(n, y) + for j, n in enumerate(self.get_mesh_mnp_axis()[1]): + vfa_y.SetValue(j, n) - for p, z in enumerate(sorted(df_micenv.loc[:, 'mesh_center_p'].unique())): - vf_z.SetValue(p, z) + for k, p in enumerate(self.get_mesh_mnp_axis()[2]): + vfa_z.SetValue(k, p) - # grid dimensions - vr_grid.SetDimensions(ti_dim) - vr_grid.SetXCoordinates(vf_x) - vr_grid.SetYCoordinates(vf_y) - vr_grid.SetZCoordinates(vf_z) + # generate and populate grid dimensions + vrg_data.SetDimensions(ti_dim) + vrg_data.SetXCoordinates(vfa_x) + vrg_data.SetYCoordinates(vfa_y) + vrg_data.SetZCoordinates(vfa_z) - # loop over substartes to fill rectilinear grid + # loop over substartes to populate rectilinear grid b_first = True for s_substrate in self.get_substrate_list(): - vf_values = vtk.vtkFloatArray() - vf_values.SetNumberOfComponents(1) - vf_values.SetNumberOfTuples(ti_dim[0] * ti_dim[1] * ti_dim[2]) - vf_values.SetName(s_substrate) # set the name of the array + vfa_value = vtk.vtkFloatArray() + vfa_value.SetNumberOfComponents(1) + vfa_value.SetNumberOfTuples(ti_dim[0] * ti_dim[1] * ti_dim[2]) + vfa_value.SetName(s_substrate) # populate the substrate values for k in range(ti_dim[2]): for j in range(ti_dim[1]): for i in range(ti_dim[0]): i_index = i + ti_dim[0] * (j + ti_dim[1] * k) - r_conc = df_micenv.loc[ - (df_micenv.loc[:,'voxel_k'] == k) & (df_micenv.loc[:,'voxel_j'] == j) & (df_micenv.loc[:,'voxel_i'] == i), + r_conc = df_conc.loc[ + (df_conc.loc[:,'voxel_k'] == k) & (df_conc.loc[:,'voxel_j'] == j) & (df_conc.loc[:,'voxel_i'] == i), s_substrate - ] - vf_values.SetValue(i_index, r_conc) # bue 20240821: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead. + ].values[0] + #vfa_value.InsertNextValue(r_conc) + vfa_value.SetValue(i_index, r_conc) if b_first: - vr_grid.GetPointData().SetScalars(vf_values) + #vrg_data.GetCellData().SetScalars(vfa_value) + vrg_data.GetPointData().SetScalars(vfa_value) b_first = False else: - vr_grid.GetPointData().AddArray(vf_values) - del vf_values + #vrg_data.GetCellData().AddArray(vfa_value) + vrg_data.GetPointData().AddArray(vfa_value) + + # visualize on the fly + if (visualize): + # get scalar range + r_vmin = np.floor(df_conc.loc[:, s_substrate].min()) + r_vmax = np.ceil(df_conc.loc[:, s_substrate].max()) + + # generate the structured grid. + vsp_data = vtk.vtkStructuredPoints() + vsp_data.SetDimensions(ti_dim[0]+1, ti_dim[1]+1, ti_dim[2]+1) + vsp_data.SetSpacing( + self.get_voxel_spacing()[0], + self.get_voxel_spacing()[1], + self.get_voxel_spacing()[2], + ) + vsp_data.SetOrigin( + self.get_mesh_mnp_range()[0][0], + self.get_mesh_mnp_range()[1][0], + self.get_mesh_mnp_range()[2][0], + ) # lower-left-front point of domain bounding box + + # mapp grid and values + vdsm_data = vtk.vtkDataSetMapper() + vsp_data.GetCellData().SetScalars(vfa_value) + vdsm_data.SetInputData(vsp_data) + vdsm_data.Update() + vdsm_data.SetScalarRange(r_vmin, r_vmax) + vdsm_data.SetScalarModeToUseCellData() + + # build VTKLooktupTable (color scheme) + vlt_color = vtk.vtkLookupTable() + vlt_color.SetNumberOfTableValues(256) + vlt_color.SetHueRange(0.667, 0.0) # blue-to-red rainbow + vlt_color.Build() + + # generate xy cutting plane actor + vp_canvas = vtk.vtkPlane() + vp_canvas.SetOrigin(0, 0, 0) # xyz + vp_canvas.SetNormal(0, 0, 1) + + vc_canvas = vtk.vtkCutter() + vc_canvas.SetInputData(vsp_data) + vc_canvas.SetCutFunction(vp_canvas) + vc_canvas.GeneratePolygons = 1 + + vpdm_canvas = vtk.vtkPolyDataMapper() + vpdm_canvas.SetInputConnection(vc_canvas.GetOutputPort()) + vpdm_canvas.ScalarVisibilityOn() + vpdm_canvas.SetScalarRange(r_vmin, r_vmax) + vpdm_canvas.SetLookupTable(vlt_color) + vpdm_canvas.SetScalarModeToUseCellData() + + va_canvas = vtk.vtkActor() + va_canvas.SetMapper(vpdm_canvas) + va_canvas.GetProperty().EdgeVisibilityOn() + + # generate outline actor + vof_frame = vtk.vtkOutlineFilter() + vof_frame.SetInputData(vsp_data) + + vpdm_frame = vtk.vtkPolyDataMapper() + vpdm_frame.SetInputConnection(vof_frame.GetOutputPort()) + + va_frame = vtk.vtkActor() + va_frame.SetMapper(vpdm_frame) + va_frame.GetProperty().SetColor(1, 1, 1) + + # generate scalar bar actor + vsba_spectrum = vtk.vtkScalarBarActor() + vsba_spectrum.SetTitle(s_substrate) + vsba_spectrum.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport() + vsba_spectrum.GetPositionCoordinate().SetValue(0.1, 0.01) + vsba_spectrum.SetOrientationToHorizontal() + vsba_spectrum.SetWidth(0.8) + vsba_spectrum.SetHeight(0.1) + vsba_spectrum.GetProperty().SetColor(0, 0, 0) + vsba_spectrum.GetTitleTextProperty().SetColor(0, 0, 0) + vsba_spectrum.GetTitleTextProperty().SetFontSize(22) + vsba_spectrum.SetLookupTable(vpdm_canvas.GetLookupTable()) + + # do render setup + ren = vtk.vtkRenderer() + renWin = vtk.vtkRenderWindow() + renWin.AddRenderer(ren) + renWin.SetSize(800, 600) + iren = vtk.vtkRenderWindowInteractor() + iren.SetRenderWindow(renWin) + + # add the actor to the renderer + #ren.ResetCamera() + ren.SetBackground(1/3, 1/3, 1/3) # gray + ren.AddActor(va_canvas) + ren.AddActor(va_frame) + ren.AddActor2D(vsba_spectrum) + + # render + iren.Initialize() + renWin.Render() + iren.Start() + + # free memory + del vfa_value # save vtk file s_vtkpathfile = self.path + '/' + s_vtkfile vw_writer = vtk.vtkXMLRectilinearGridWriter() vw_writer.SetFileName(s_vtkpathfile) - vw_writer.SetInputData(vr_grid) + vw_writer.SetInputData(vrg_data) vw_writer.Write() + return s_vtkpathfile @@ -1698,7 +1812,8 @@ def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cma r_radius = float(circle_element.get('r')) # px s = int(round((r_radius)**2)) else: - print(f'Warning @ pyMCDSts.plot_scatter : these agents are not circles.') + if self.verbose: + print(f'Warning @ pyMCDSts.plot_scatter : these agents are not circles.') s = plt.rcParams['lines.markersize']**2 if self.verbose: print(f's set to {s}.') @@ -1707,7 +1822,8 @@ def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cma i_height = int(np.ceil(float(x_root.get('height')))) # px figsizepx = [i_width, i_height] except FileNotFoundError: - print(f'Warning @ pyMCDSts.plot_scatter : could not load {s_pathfile}.') + if self.verbose: + print(f'Warning @ pyMCDSts.plot_scatter : could not load {s_pathfile}.') if s is None: s = plt.rcParams['lines.markersize']**2 if self.verbose: @@ -1782,7 +1898,7 @@ def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cma else: fig = plt.gcf() - # layout the canavas + # layout the canvas if xyequal: ax.axis('equal') @@ -1848,7 +1964,7 @@ def plot_scatter(self, focus='cell_type', z_slice=0.0, z_axis=None, alpha=1, cma else: # handle output path and filename - s_path = f'{self.path}/cell_{focus}_z{round(z_slice,9)}/' + s_path = self.path + f'/cell_{focus}_z{round(z_slice,9)}/' os.makedirs(s_path, exist_ok=True) s_file = self.xmlfile.replace('.xml', f'_{focus}.{ext}') s_pathfile = f'{s_path}{s_file}' @@ -1896,103 +2012,99 @@ def make_cell_vtk(self, attribute=['cell_type'], visualize=True): df_cell = df_cell.reset_index() # generate VTK instances to fill for positions and radii - vp_points = vtkPoints() - vf_radii = vtk.vtkFloatArray() - vf_radii.SetName('radius') + vp_points = vtk.vtkPoints() + vfa_radii = vtk.vtkFloatArray() + vfa_radii.SetName('radius') # fill VTK instance with positions and radii for i in df_cell.index: - vp_points.InsertNextPoint(df_cell.loc[i, 'position_x'], df_cell.loc[i, 'position_y'], df_cell.loc[i, 'position_z']) - vf_radii.InsertNextValue(df_cell.loc[i, 'radius']) + vp_points.InsertNextPoint( + df_cell.loc[i, 'position_x'], + df_cell.loc[i, 'position_y'], + df_cell.loc[i, 'position_z'] + ) + vfa_radii.InsertNextValue(df_cell.loc[i, 'radius']) # generate data instances - vf_data = vtk.vtkFloatArray() - vf_data.SetNumberOfComponents(2) - vf_data.SetNumberOfTuples(df_cell.shape[0]) - vf_data.CopyComponent(0, vf_radii, 0) - vf_data.SetName('positions_and_radii') + vfa_data = vtk.vtkFloatArray() + vfa_data.SetNumberOfComponents(2) + vfa_data.SetNumberOfTuples(df_cell.shape[0]) + vfa_data.CopyComponent(0, vfa_radii, 0) + vfa_data.SetName('positions_and_radii') # generate unstructred grid for data - vu_grid = vtk.vtkUnstructuredGrid() - vu_grid.SetPoints(vp_points) - vu_grid.GetPointData().AddArray(vf_data) - vu_grid.GetPointData().SetActiveScalars('positions_and_radii') + vug_data = vtk.vtkUnstructuredGrid() + vug_data.SetPoints(vp_points) + vug_data.GetPointData().AddArray(vfa_data) + vug_data.GetPointData().SetActiveScalars('positions_and_radii') # fill this grid with given attributes for s_attribute in attribute: b_bool = False if (df_cell.loc[:, s_attribute].dtype == bool): #in {bool, np.bool_, np.bool}): b_bool = True - custom_data_vtk = vtk.vtkStringArray() - custom_data_vtk.SetName(s_attribute) + voa_data = vtk.vtkStringArray() elif (df_cell.loc[:, s_attribute].dtype == str) or (df_cell.loc[:, s_attribute].dtype == np.object_): # in {str, np.str_, np.object_}): - custom_data_vtk = vtk.vtkStringArray() - custom_data_vtk.SetName(s_attribute) + voa_data = vtk.vtkStringArray() elif (df_cell.loc[:, s_attribute].dtype == int) or (df_cell.loc[:, s_attribute].dtype == float): # in {int, np.int_, np.int8, np.int16, np.int32, np.int64, float, np.float16, np.float32, np.float64, np.float128}): - custom_data_vtk = vtk.vtkFloatArray() - custom_data_vtk.SetName(s_attribute) + voa_data = vtk.vtkFloatArray() else: sys.exit(f'Error @ pyMCDS.make_cell_vtk : {s_attribute} {df_cell.loc[:, s_attribute].dtype} unknown df_cell column data type.') + voa_data.SetName(s_attribute) for i in df_cell.index: if b_bool: if (df_cell.loc[i, s_attribute]): - custom_data_vtk.InsertNextValue('True') + voa_data.InsertNextValue('True') else: - custom_data_vtk.InsertNextValue('False') + voa_data.InsertNextValue('False') else: - custom_data_vtk.InsertNextValue(df_cell.loc[i, s_attribute]) + voa_data.InsertNextValue(df_cell.loc[i, s_attribute]) - vu_grid.GetPointData().AddArray(custom_data_vtk) - del custom_data_vtk + vug_data.GetPointData().AddArray(voa_data) + del voa_data # generate sphere source - vsp_sphere = vtk.vtkSphereSource() - vsp_sphere.SetRadius(1.0) - vsp_sphere.SetPhiResolution(16) - vsp_sphere.SetThetaResolution(32) + vss_data = vtk.vtkSphereSource() + vss_data.SetRadius(1.0) + vss_data.SetPhiResolution(16) + vss_data.SetThetaResolution(32) # generate Glyph to save - vg_glyph = vtk.vtkGlyph3D() - vg_glyph.SetInputData(vu_grid) - vg_glyph.SetSourceConnection(vsp_sphere.GetOutputPort()) + vg_data = vtk.vtkGlyph3D() + vg_data.SetInputData(vug_data) + vg_data.SetSourceConnection(vss_data.GetOutputPort()) # define important preferences for VTK - vg_glyph.ClampingOff() - vg_glyph.SetScaleModeToScaleByScalar() - vg_glyph.SetScaleFactor(1.0) - vg_glyph.SetColorModeToColorByScalar() - vg_glyph.Update() - - # write VTK - s_vtkpathfile = self.path + '/' + s_vtkfile - vw_writer = vtk.vtkXMLPolyDataWriter() - vw_writer.SetFileName(s_vtkpathfile) - vw_writer.SetInputData(vg_glyph.GetOutput()) - vw_writer.Write() + vg_data.ClampingOff() + vg_data.SetScaleModeToScaleByScalar() + vg_data.SetScaleFactor(1.0) + vg_data.SetColorModeToColorByScalar() + vg_data.Update() # visualize if (visualize): # set up the mapper - mapper = vtk.vtkPolyDataMapper() - #mapper.SetInput(glyph.GetOutput()) - mapper.SetInputConnection(vg_glyph.GetOutputPort()) - mapper.ScalarVisibilityOn() - mapper.ColorByArrayComponent('data', 1) + vpdm_data = vtk.vtkPolyDataMapper() + vpdm_data.SetInputConnection(vg_data.GetOutputPort()) + vpdm_data.ScalarVisibilityOn() + #vpdm_data.ColorByArrayComponent(s_attribute, 0) # bue 20250110: not working and legacy better to do this in the lookup table. # set up the actor actor = vtk.vtkActor() - actor.SetMapper(mapper) + actor.SetMapper(vpdm_data) - # do renderer setup stuff + # do renderer setup ren = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren) - renWin.SetSize(640, 480) + renWin.SetSize(800, 600) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) # add the actor to the renderer + #ren.ResetCamera() + ren.SetBackground(1/3, 1/3, 1/3) # gray ren.AddActor(actor) # render @@ -2000,21 +2112,41 @@ def make_cell_vtk(self, attribute=['cell_type'], visualize=True): renWin.Render() iren.Start() + # write VTK + s_vtkpathfile = self.path + '/' + s_vtkfile + vw_writer = vtk.vtkXMLPolyDataWriter() + vw_writer.SetFileName(s_vtkpathfile) + vw_writer.SetInputData(vg_data.GetOutput()) + vw_writer.Write() + return s_vtkpathfile ## MICROENVIRONMENT AND CELL AGENT RELATED FUNCTIONS ## - def make_ome_tiff(self, cell_attribute='ID', file=True): + def make_ome_tiff(self, cell_attribute='ID', conc_cutoff={}, focus=None, file=True): """ input: - cell_attribute: strings; default is 'ID', which will result in a segmentation mask. - column name within cell dataframe. - the column data type has to be numeric (bool, int, float) and can't be string. + cell_attribute: strings; default is 'ID', which will result in a + cell segmentation mask. + column name within the cell dataframe. + the column data type has to be numeric (bool, int, float) + and cannot be string. + the result will be stored as 32 bit float. + + conc_cutoff: dictionary string to real; default is an empty dictionary. + if a contour from a substrate not should be cut by greater + than zero (shifted to integer 1), another cutoff value can be + specified here. + + focus: set of strings; default is a None + set of substrate and cell_type names to specify what will be + translated into ome tiff format. + if None, all substrates and cell types will be processed. file: boolean; default True - if True, an ome tiff file is output. - if False, a numpy array with shape czyx is output. + if True, an ome tiff file is the output. + if False, a numpy array with shape czyx is the output. output: a_czyx_img: numpy array or ome tiff file. @@ -2033,7 +2165,16 @@ def make_ome_tiff(self, cell_attribute='ID', file=True): https://napari.org/stable/ https://fiji.sc/ """ - # bue jenny: 20240904: a 16[bit] ome.tiff is good enough! + # handle channels + ls_substrate = self.get_substrate_list() + ls_celltype = self.get_celltype_list() + + if not (focus is None): + ls_substrate = [s_substrate for s_substrate in ls_substrate if s_substrate in set(focus)] + ls_celltype = [s_celltype for s_celltype in ls_celltype if s_celltype in set(focus)] + if (set(focus) != set(ls_substrate).union(set(ls_celltype))): + sys.exit(f'Error : {focus} not found in {ls_substrate} {ls_celltype}') + # const ls_coor_mnp = ['mesh_center_m', 'mesh_center_n', 'mesh_center_p'] # xyz ls_coor_xyz = ['position_x', 'position_y', 'position_z'] # xyz @@ -2052,72 +2193,66 @@ def make_ome_tiff(self, cell_attribute='ID', file=True): df_coor = pd.DataFrame(lll_coor, columns=ls_coor[:2]) lr_axis_z[-1] += 1 - # get ordered substrate listing - ls_substrate = self.get_substrate_list() - - # get substrate dataframe - df_conc = self.get_conc_df() - # extract voxel radius - i_conc_grow = int(np.round(np.mean(self.get_voxel_spacing()[:2])) - 1) + di_grow = {} + for s_substarte in ls_substrate: + di_grow.update({ + s_substarte : int(np.round(np.mean(self.get_voxel_spacing()[:2])) - 1) + }) - # extract input from data frame + # get and shift substrate xy data + df_conc = self.get_conc_df() df_conc = df_conc.loc[:, ls_coor_mnp + ls_substrate] - - # shift substrate xy data df_conc.loc[:, 'mesh_center_m'] = (df_conc.loc[:, 'mesh_center_m'] - self.get_xyz_range()[0][0]).round() df_conc.loc[:, 'mesh_center_n'] = (df_conc.loc[:, 'mesh_center_n'] - self.get_xyz_range()[1][0]).round() - - # relabel and retype xyz coordiantes df_conc.rename({'mesh_center_m':'voxel_x', 'mesh_center_n':'voxel_y', 'mesh_center_p':'voxel_z'}, axis=1, inplace=True) df_conc = df_conc.astype({'voxel_x': int, 'voxel_y': int, 'voxel_z': float}) + # level the cake + for s_channel in conc_cutoff.keys(): + try: + df_conc.loc[:, s_channel] = df_conc.loc[:, s_channel] - conc_cutoff[s_channel] + 1 # positive values starting at > 0 + df_conc.loc[(df_conc.loc[:, s_channel] <= conc_cutoff[s_channel]), s_channel] = 0 + except KeyError: + pass - # get ordered cell type listing - ls_celltype = self.get_celltype_list() - # get cell dataframe + # get cell data df_cell = self.get_cell_df().reset_index() # extract cell radius - di_cell_grow = {} for s_celltype in ls_celltype: try: i_cell_grow = int(round(df_cell.loc[(df_cell.cell_type == s_celltype), 'radius'].mean()) - 1) except: i_cell_grow = 0 - di_cell_grow.update({s_celltype: i_cell_grow}) + di_grow.update({s_celltype : i_cell_grow}) - # extract and manipulate input from dataframe + # filter and shift df_cell = df_cell.loc[:, ls_coor_xyz + ['cell_type', cell_attribute]] - - # manipulate cell_attribute value if (cell_attribute == 'cell_type'): - sys.exit(f'Error @ pyMCDS.make_ome_tiff : cell_attribute can not be cell_type.') + sys.exit(f'Error @ pyMCDS.make_ome_tiff : cell_attribute cannot be cell_type.') elif (df_cell.loc[:, cell_attribute].dtype == str) or (df_cell.loc[:, cell_attribute].dtype == np.object_): # in {str, np.str_, np.object_}): - sys.exit(f'Error @ pyMCDS.make_ome_tiff : {cell_attribute} {df_cell.loc[:, cell_attribute].dtype} cell_attribute can not be string or object. cell_attribute has to be boolean, integer, or float.') + sys.exit(f'Error @ pyMCDS.make_ome_tiff : {cell_attribute} {df_cell.loc[:, cell_attribute].dtype} cell_attribute cannot be string or object. cell_attribute has to be boolean, integer, or float.') elif (df_cell.loc[:, cell_attribute].dtype == bool): # in {bool, np.bool_, np.bool}): df_cell = df_cell.astype({cell_attribute: int}) - df_cell.loc[:, cell_attribute] = df_cell.loc[:, cell_attribute] - df_cell.loc[:, cell_attribute].min() + 1 # positive values starting at 1 + df_cell.loc[:, 'position_x'] = (df_cell.loc[:, 'position_x'] - self.get_xyz_range()[0][0]).round() + df_cell.loc[:, 'position_y'] = (df_cell.loc[:, 'position_y'] - self.get_xyz_range()[1][0]).round() + df_cell.rename({'position_x':'voxel_x', 'position_y':'voxel_y', 'position_z':'voxel_z'}, axis=1, inplace=True) + df_cell = df_cell.astype({'voxel_x': int, 'voxel_y': int, 'voxel_z': float}) + # level the cake + df_cell.loc[:, cell_attribute] = df_cell.loc[:, cell_attribute] - df_cell.loc[:, cell_attribute].min() + 1 # positive values starting at > 0 # check for duplicates: two cell at exactelly the same xyz position. - if self.verbose and df_cell.loc[:,['position_x', 'position_y', 'position_z']].duplicated().any(): - df_duplicate = df_cell.loc[(df_cell.loc[:, ['position_x', 'position_y', 'position_z']].duplicated()), :] - print(f"Warning @ pyMCDS.make_ome_tiff : {df_duplicate} cells at exactely the same xyz position detected!") + #if self.verbose and df_cell.loc[:,['voxel_x', 'voxel_y', 'voxel_z']].duplicated().any(): + # df_duplicate = df_cell.loc[(df_cell.loc[:, ['voxel_x', 'voxel_y', 'voxel_z']].duplicated()), :] + # sys.exit(f"Error @ pyMCDS.make_ome_tiff : {df_duplicate} cells at exactely the same xyz voxel position detected. cannot pivot!") # pivot cell_type - df_cell = df_cell.pivot_table(index=ls_coor_xyz, columns='cell_type', values=cell_attribute, aggfunc='sum').reset_index() # fill_value is na + df_cell = df_cell.pivot_table(index=ls_coor, columns='cell_type', values=cell_attribute, aggfunc='sum').reset_index() # fill_value is na for s_celltype in ls_celltype: if not s_celltype in set(df_cell.columns): df_cell[s_celltype] = 0 - # shift cell position xy data - df_cell.loc[:, 'position_x'] = (df_cell.loc[:, 'position_x'] - self.get_xyz_range()[0][0]).round() - df_cell.loc[:, 'position_y'] = (df_cell.loc[:, 'position_y'] - self.get_xyz_range()[1][0]).round() - - # relabel and retype xyz coordiantes - df_cell.rename({'position_x':'voxel_x', 'position_y':'voxel_y', 'position_z':'voxel_z'}, axis=1, inplace=True) - df_cell = df_cell.astype({'voxel_x': int, 'voxel_y': int, 'voxel_z': float}) - # each C channel - time step tensors la_czyx_img = [] ls_channel = ls_substrate + ls_celltype @@ -2129,7 +2264,7 @@ def make_ome_tiff(self, cell_attribute='ID', file=True): elif s_channel in set(ls_celltype): df_channel = df_cell.loc[:, ls_coor + [s_channel]] else: - sys.exit(f'Error @ pyMCDS.make_ome_tiff : {s_channel} unknowen channel detected. not in substrate and cell type list!') + sys.exit(f'Error @ pyMCDS.make_ome_tiff : {s_channel} unknown channel detected. not in substrate and cell type list {ls_substrate} {ls_celltype}!') # each z axis la_zyx_img = [] @@ -2149,24 +2284,27 @@ def make_ome_tiff(self, cell_attribute='ID', file=True): # merge with coooridnates and get image # bue 20240811: df_coor left side merge will cut off reset cell that are out of the xyz domain range, which is what we want. df_yxchannel = pd.merge(df_coor, df_yxchannel, on=ls_coor[:2], how='left').replace({np.nan: 0}) - df_yxchannel = df_yxchannel.pivot(columns=ls_coor[0], index=ls_coor[1], values=s_channel) + try: + df_yxchannel = df_yxchannel.pivot(columns=ls_coor[0], index=ls_coor[1], values=s_channel) + except ValueError: # two cells from the same cell type very close to each other detetced. + if self.verbose: + df_duplicate = df_cell.loc[(df_yxchannel.loc[:, ['voxel_x', 'voxel_y']].duplicated()), :] + print(f'Warning: {s_channel} {df_duplicate} cells within 1[um] distance form each detected. cannot pivot. erase cell type from this timestep.') + df_yxchannel.loc[:,s_channel] = 0 # erase cells + df_yxchannel = df_yxchannel.drop_duplicates() + df_yxchannel = df_yxchannel.pivot(columns=ls_coor[0], index=ls_coor[1], values=s_channel) a_yx_img = df_yxchannel.values # grow - if s_channel in set(ls_substrate): - a_yx_img = imagine.grow(a_yx_img, i_step=i_conc_grow, b_verbose=False) - elif s_channel in set(ls_celltype): - a_yx_img = imagine.grow_seed(a_yx_img, i_step=di_cell_grow[s_channel], b_verbose=False) - else: - sys.exit(f'Error @ pyMCDS.make_ome_tiff : {s_channel} unknowen channel detected. not in substrate and cell type list!') + a_yx_img = imagine.grow_seed(a_yx_img, i_step=di_grow[s_channel], b_verbose=False) # update output la_zyx_img.append(a_yx_img) - a_zyx_img = np.array(la_zyx_img) - la_czyx_img.append(np.array(a_zyx_img)) + a_zyx_img = np.array(la_zyx_img, np.float32) + la_czyx_img.append(np.array(a_zyx_img, np.float32)) # output - a_czyx_img = np.array(la_czyx_img) + a_czyx_img = np.array(la_czyx_img, dtype=np.float32) # numpy array if not file: @@ -2174,10 +2312,23 @@ def make_ome_tiff(self, cell_attribute='ID', file=True): # write to file else: - s_tifffile = self.xmlfile.replace('.xml', f'_{cell_attribute}.ome.tiff') - s_tiffpathfile = self.path + '/' + s_tifffile if self.verbose: print('a_czyx_img shape:', a_czyx_img.shape) + # generate filename + s_channel = '' + for s_substrate in ls_substrate: + try: + r_value = conc_cutoff[s_substrate] + s_channel += f'_{s_substrate}{r_value}' + except KeyError: + s_channel += f'_{s_substrate}' + for s_celltype in ls_celltype: + s_channel += f'_{s_celltype}' + if len(ls_celltype) > 0: + s_channel += f'_{cell_attribute}' + s_tifffile = self.xmlfile.replace('.xml', f'{s_channel}.ome.tiff') + s_tiffpathfile = self.path + '/' + s_tifffile + # save to file OmeTiffWriter.save( a_czyx_img, s_tiffpathfile, @@ -2185,7 +2336,7 @@ def make_ome_tiff(self, cell_attribute='ID', file=True): #ome_xml=x_img, channel_names = ls_channel, image_names = [s_tifffile.replace('.ome.tiff','')], - physical_pixel_sizes = aicsimageio.types.PhysicalPixelSizes(self.get_voxel_spacing()[2], 1.0, 1.0), #z,y,x [um] + physical_pixel_sizes = aicsimageio.types.PhysicalPixelSizes(self.get_voxel_spacing()[2], 1.0, 1.0), # z,y,x [um] #channel_colors=, #fs_kwargs={}, ) @@ -2222,6 +2373,20 @@ def get_neighbor_graph_dict(self): return self.data['discrete_cells']['graph']['neighbor_cells'] + def get_spring_graph_dict(self): + """ + input: + + output: + dei_graph: dictionary of sets of integers + maps each cell ID to the attached connected cell IDs. + + description: + function returns the attached spring cell graph as a dictionary object. + """ + return self.data['discrete_cells']['graph']['spring_attached_cells'] + + def make_graph_gml(self, graph_type, edge_attribute=True, node_attribute=[]): """ input: @@ -2229,6 +2394,7 @@ def make_graph_gml(self, graph_type, edge_attribute=True, node_attribute=[]): to specify which physicell output data should be processed. neighbor, touch: processes mcds.get_neighbor_graph_dict dictionary. attached: processes mcds.get_attached_graph_dict dictionary. + spring: processes mcds.get_spring_graph_dict dictionary. edge_attribute: boolean; default True specifies if the spatial Euclidean distance is used for @@ -2265,10 +2431,12 @@ def make_graph_gml(self, graph_type, edge_attribute=True, node_attribute=[]): dei_graph = self.get_attached_graph_dict() elif (graph_type in {'neighbor', 'touch'}): dei_graph = self.get_neighbor_graph_dict() + elif (graph_type in {'spring'}): + dei_graph = self.get_spring_graph_dict() #elif (graph_type in {'evo','devo','lineage'}): # dei_graph = self.get_lineage_graph_dict() else: - sys.exit(f'Erro @ make_graph_gml : unknowen graph_type {graph_type}. knowen are attached, neighbor, and touch.') + sys.exit(f'Erro @ make_graph_gml : unknown graph_type {graph_type}. known are attached, neighbor, spring, and touch.') # generate filename s_gmlpathfile = self.path + '/' + self.xmlfile.replace('.xml',f'_{graph_type}.gml') @@ -2348,6 +2516,10 @@ def _read_xml(self, xmlfile, output_path='.'): ls_xmlfile = xmlfile.split('/') s_xmlfile = ls_xmlfile.pop(-1) output_path = '/'.join(ls_xmlfile) + while (output_path.find('//') > -1): + output_path = output_path.replace('//','/') + if (output_path.endswith('/')) and (len(output_path) > 1): + output_path = output_path[:-1] self.path = output_path self.xmlfile = s_xmlfile @@ -2681,7 +2853,8 @@ def _read_xml(self, xmlfile, output_path='.'): if self.verbose: print(f'reading: {s_cellpathfile}') except ValueError: # hack: some old PhysiCell versions generates a corrupt cells.mat file, if there are zero cells. - print(f'Warning @ pyMCDS._read_xml : corrupt {s_cellpathfile} detected!\nassuming time step with zero cells because of a known bug in PhysiCell MultiCellDS version 0.5 output.') + if self.verbose: + print(f'Warning @ pyMCDS._read_xml : corrupt {s_cellpathfile} detected!\nassuming time step with zero cells because of a known bug in PhysiCell MultiCellDS version 0.5 output.') ar_cell = np.empty([len(ls_variable),0]) # check for column label mapping error (as good as it gets) @@ -2708,6 +2881,7 @@ def _read_xml(self, xmlfile, output_path='.'): d_mcds['discrete_cells']['graph'] = {} d_mcds['discrete_cells']['graph'].update({'neighbor_cells': {}}) d_mcds['discrete_cells']['graph'].update({'attached_cells': {}}) + d_mcds['discrete_cells']['graph'].update({'spring_attached_cells': {}}) if self.graph: if self.verbose: @@ -2731,6 +2905,18 @@ def _read_xml(self, xmlfile, output_path='.'): # store data d_mcds['discrete_cells']['graph'].update({'attached_cells': dei_graph}) + # spring attached cell graph + try: + s_cellpathfile = self.path + '/' + x_cell.find('spring_attached_cells_graph').find('filename').text + dei_graph = graphfile_parser(s_pathfile=s_cellpathfile) + if self.verbose: + print(f'reading: {s_cellpathfile}') + + # store data + d_mcds['discrete_cells']['graph'].update({'spring_attached_cells': dei_graph}) + except AttributeError: + pass + ######################### # handle physiboss data # @@ -2744,7 +2930,7 @@ def _read_xml(self, xmlfile, output_path='.'): # intracellular file (hack because this is not yet in output.xml) df_physiboss = None - s_intracellpathfile = self.path + '/' + f'states_{self.xmlfile.replace("output","").replace(".xml",".csv")}' + s_intracellpathfile = self.path + f'/states_{self.xmlfile.replace("output","").replace(".xml",".csv")}' if os.path.exists(s_intracellpathfile): if self.verbose: print(f'reading: {s_intracellpathfile}') @@ -2761,9 +2947,12 @@ def _read_xml(self, xmlfile, output_path='.'): for s_node in sorted(es_node): df_physiboss[f'node_{s_node}'] = df_physiboss.state.str.find(s_node) > -1 - else: + elif self.verbose: print(f'Warning @ pyMCDS._read_xml : physiboss file missing {s_intracellpathfile}.') + else: + pass + # store data d_mcds['discrete_cells']['physiboss'] = df_physiboss diff --git a/pcdl/pyMCDSts.py b/pcdl/pyMCDSts.py index 512f705..0ff04ba 100644 --- a/pcdl/pyMCDSts.py +++ b/pcdl/pyMCDSts.py @@ -20,7 +20,7 @@ # load libraries -import aicsimageio +import aicsimageio # bioio, bioio_base from aicsimageio.writers import OmeTiffWriter import glob import matplotlib.pyplot as plt @@ -211,12 +211,14 @@ def __init__(self, output_path='.', custom_data_type={}, load=True, microenv=Tru functions to process all time steps in the output_path directory. """ output_path = output_path.replace('\\','/') - if (output_path[-1] != '/'): - output_path = output_path + '/' + while (output_path.find('//') > -1): + output_path = output_path.replace('//','/') + if (output_path.endswith('/')) and (len(output_path) > 1): + output_path = output_path[:-1] if not os.path.isdir(output_path): print(f'Error @ pyMCDSts.__init__ : this is not a path! could not load {output_path}.') self.path = output_path - self.ls_xmlfile = [s_pathfile.replace('\\','/').split('/')[-1] for s_pathfile in sorted(glob.glob(f'{self.path}output*.xml'))] # bue 2022-10-22: is output*.xml always the correct pattern? + self.ls_xmlfile = [s_pathfile.replace('\\','/').split('/')[-1] for s_pathfile in sorted(glob.glob(self.path + f'/output*.xml'))] # bue 2022-10-22: is output*.xml always the correct pattern? self.custom_data_type = custom_data_type self.microenv = microenv self.graph = graph @@ -310,7 +312,7 @@ def read_mcds(self, xmlfile_list=None): if (xmlfile_list is None): xmlfile_list = self.get_xmlfile_list() ls_xmlfile = sorted([s_xmlfile.replace('\\','/').split('/')[-1] for s_xmlfile in xmlfile_list]) - ls_xmlpathfile = [f'{self.path}{s_xmlfile}' for s_xmlfile in ls_xmlfile] + ls_xmlpathfile = [self.path + f'/{s_xmlfile}' for s_xmlfile in ls_xmlfile] # load mcds objects into list l_mcds = [] @@ -613,7 +615,7 @@ def plot_contour(self, focus, z_slice=0.0, extrema=None, alpha=1, fill=True, cma print(f'ylim set to {ylim}.') # handle output path - s_path = f'{self.path}conc_{focus}_z{round(z_slice,9)}/' + s_path = self.path + f'/conc_{focus}_z{round(z_slice,9)}/' # plotting lo_output = [] @@ -642,9 +644,11 @@ def plot_contour(self, focus, z_slice=0.0, extrema=None, alpha=1, fill=True, cma return lo_output - def make_conc_vtk(self): + def make_conc_vtk(self, visualize=True): """ input: + visualize: boolean; default is False + additionally, visualize cells using vtk renderer. output: ls_vtkpathfile: one vtk file per mcds time step that contains @@ -662,7 +666,7 @@ def make_conc_vtk(self): # processing ls_vtkpathfile = [] for mcds in self.get_mcds_list(): - s_vtkpathfile = mcds.make_conc_vtk() + s_vtkpathfile = mcds.make_conc_vtk(visualize=visualize) ls_vtkpathfile.append(s_vtkpathfile) # output @@ -984,16 +988,28 @@ def make_cell_vtk(self, attribute=['cell_type'], visualize=False): ## OME TIFF RELATED FUNCTIONS ## - def make_ome_tiff(self, cell_attribute='ID', file=True, collapse=True): + def make_ome_tiff(self, cell_attribute='ID', conc_cutoff={}, focus=None, file=True, collapse=True): """ input: - cell_attribute: strings; default is 'ID', with will result in a segmentation mask. - column name within cell dataframe. - the column data type has to be numeric (bool, int, float) and can't be string. + cell_attribute: strings; default is 'ID', which will result in a + cell segmentation mask. + column name within the cell dataframe. + the column data type has to be numeric (bool, int, float) + and cannot be string. + the result will be stored as 32 bit float. + + conc_cutoff: dictionary string to real; default is an empty dictionary. + if a contour from a substrate not should be cut by greater + than zero (shifted to integer 1), another cutoff value can be specified here. + + focus: set of strings; default is a None + set of substrate and cell_type names to specify what will be + translated into ome tiff format. + if None, all substrates and cell types will be processed. file: boolean; default True - if True, an ome tiff file is output. - if False, a numpy array with shape tczyx is output. + if True, an ome tiff file is the output. + if False, a numpy array with shape tczyx is the output. collapse: boole; default True should all mcds time steps from the time series be collapsed @@ -1003,6 +1019,7 @@ def make_ome_tiff(self, cell_attribute='ID', file=True, collapse=True): output: a_tczyx_img: numpy array or ome tiff file. + description: function to transform chosen mcdsts output into an 1[um] spaced tczyx (time, channel, z-axis, y-axis, x-axis) ome tiff file or numpy array, @@ -1017,22 +1034,33 @@ def make_ome_tiff(self, cell_attribute='ID', file=True, collapse=True): https://napari.org/stable/ https://fiji.sc/ """ - # each T time step + # for each T time step l_tczyx_img = [] for i, mcds in enumerate(self.get_mcds_list()): + # processing + b_file = True # 10 if (not file and not collapse) or (not file and collapse) or (file and collapse): # 00, 01, 11 - a_czyx_img = mcds.make_ome_tiff(cell_attribute=cell_attribute, file=False) - l_tczyx_img.append(a_czyx_img) + b_file = False + o_tczyx_img = mcds.make_ome_tiff( + cell_attribute = cell_attribute, + conc_cutoff = conc_cutoff, + focus = focus, + file = b_file + ) + l_tczyx_img.append(o_tczyx_img) - elif (file and not collapse): # 10 - s_pathfile = mcds.make_ome_tiff(cell_attribute=cell_attribute, file=True) - l_tczyx_img.append(s_pathfile) + # handle channels + ls_substrate = mcds.get_substrate_list() + ls_celltype = mcds.get_celltype_list() - else: - sys.exit(f'Error @ make_ome_tiff :.') + if not (focus is None): + ls_substrate = [s_substrate for s_substrate in ls_substrate if s_substrate in set(focus)] + ls_celltype = [s_celltype for s_celltype in ls_celltype if s_celltype in set(focus)] + if (set(focus) != set(ls_substrate).union(set(ls_celltype))): + sys.exit(f'Error : {focus} not found in {ls_substrate} {ls_celltype}') # output 00 list of numpy arrays - if (not file and not collapse): + if (not file and not collapse): # 00 if self.verbose: print(f'la_tczyx_img shape: {len(l_tczyx_img)} * {l_tczyx_img[0].shape}') return l_tczyx_img @@ -1046,7 +1074,7 @@ def make_ome_tiff(self, cell_attribute='ID', file=True, collapse=True): return a_tczyx_img # output 10 list of pathfile strings - elif (file and not collapse): # 01 + elif (file and not collapse): # 10 return l_tczyx_img # output 11 ometiff file @@ -1054,16 +1082,28 @@ def make_ome_tiff(self, cell_attribute='ID', file=True, collapse=True): a_tczyx_img = np.array(l_tczyx_img) if self.verbose: print('a_tczyx_img shape:', a_tczyx_img.shape) - ls_channel = mcds.get_substrate_list() + mcds.get_celltype_list() - s_tiffpathfile = f'{self.path}timeseries_{cell_attribute}.ome.tiff' + # generate filename + s_channel = '' + for s_substrate in ls_substrate: + try: + r_value = conc_cutoff[s_substrate] + s_channel += f'_{s_substrate}{r_value}' + except KeyError: + s_channel += f'_{s_substrate}' + for s_celltype in ls_celltype: + s_channel += f'_{s_celltype}' + if len(ls_celltype) > 0: + s_channel += f'_{cell_attribute}' + s_tiffpathfile = self.path + f'/timeseries{s_channel}.ome.tiff' + # save to file OmeTiffWriter.save( a_tczyx_img, s_tiffpathfile, dim_order = 'TCZYX', #ome_xml=x_img, - channel_names = ls_channel, + channel_names = ls_substrate + ls_celltype, image_names = [f'timeseries_{cell_attribute}'], - physical_pixel_sizes = aicsimageio.types.PhysicalPixelSizes(mcds.get_voxel_spacing()[2], 1.0, 1.0), #z,y,x [um] + physical_pixel_sizes = aicsimageio.types.PhysicalPixelSizes(mcds.get_voxel_spacing()[2], 1.0, 1.0), # z,y,x [um] #channel_colors=, #fs_kwargs={}, ) @@ -1071,7 +1111,7 @@ def make_ome_tiff(self, cell_attribute='ID', file=True, collapse=True): # error case else: - sys.exit(f'Error @ make_ome_tiff :.') + sys.exit(f'Error @ make_ome_tiff : {file} {collapse} strange file collapse combination.') ## TIME SERIES RELATED FUNCTIONS ## @@ -1244,7 +1284,7 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme mcds.set_verbose_true() # error else: - sys.exit(f"Error @ pyMCDSts.plot_timeseries : unknowen frame {frame}. knowen are cell_df and conc_df.") + sys.exit(f"Error @ pyMCDSts.plot_timeseries : unknown frame {frame}. known are cell_df and conc_df.") # handle z_slize if not (z_slice is None): df_frame = df_frame.loc[(df_frame.mesh_center_p == z_slice),:] @@ -1344,9 +1384,9 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme return fig else: if (focus_num == 'count'): - s_pathfile = f'{self.path}timeseries_{frame}_{focus_cat}_{focus_num}.{ext}' + s_pathfile = self.path + f'/timeseries_{frame}_{focus_cat}_{focus_num}.{ext}' else: - s_pathfile = f"{self.path}timeseries_{frame}_{focus_cat}_{focus_num}_{aggregate_num.__name__.replace('np.nan','')}.{ext}" + s_pathfile = self.path + f"/timeseries_{frame}_{focus_cat}_{focus_num}_{aggregate_num.__name__.replace('np.nan','')}.{ext}" if figbgcolor is None: figbgcolor = 'auto' plt.tight_layout() @@ -1357,15 +1397,16 @@ def plot_timeseries(self, focus_cat=None, focus_num=None, aggregate_num=np.nanme ## GRAPH RELATED FUNCTIONS ## - def make_graph_gml(self, graph_type='neighbor', edge_attribute=True, node_attribute=[]): + def make_graph_gml(self, graph_type, edge_attribute=True, node_attribute=[]): """ input: self: pyMCDS class instance. - graph_type: string; default is neighbor + graph_type: string to specify which physicell output data should be processed. - attached: processes mcds.get_attached_graph_dict dictionary. + attached, touch: processes mcds.get_attached_graph_dict dictionary. neighbor: processes mcds.get_neighbor_graph_dict dictionary. + spring: processes mcds.get_spring_graph_dict dictionary. edge_attribute: boolean; default True specifies if the spatial Euclidean distance is used for diff --git a/pyproject.toml b/pyproject.toml index 471240f..a9048d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,14 +68,15 @@ classifiers = [ "Topic :: Scientific/Engineering :: Bio-Informatics", ] +# bue 2024-12-06: enforcing some versions dependencies = [ "aicsimageio", - "anndata", + "anndata>=0.10.8", "matplotlib", - "numpy", - "pandas", + "numpy<2.0.0", + "pandas>=2.2.2", "requests", - "scipy", + "scipy>=1.13.0", "vtk", ] @@ -128,7 +129,7 @@ include = [ "/test", ] exclude = [ - "/data_timeseries_2d.tar.gz", - "/data_timeseries_3d.tar.gz", + "/output_2d.tar.gz", + "/output_3d.tar.gz", "/.pytest_cache", ] diff --git a/test/pcmodel/Makefile b/test/pcmodel/Makefile new file mode 100644 index 0000000..7aa7d18 --- /dev/null +++ b/test/pcmodel/Makefile @@ -0,0 +1,323 @@ +VERSION := $(shell grep . VERSION.txt | cut -f1 -d:) +PROGRAM_NAME := project + +CC := g++ +# CC := g++-mp-7 # typical macports compiler name +# CC := g++-7 # typical homebrew compiler name + +# Check for environment definitions of compiler +# e.g., on CC = g++-7 on OSX +ifdef PHYSICELL_CPP + CC := $(PHYSICELL_CPP) +endif + +ifndef STATIC_OPENMP + STATIC_OPENMP = -fopenmp +endif + +ARCH := native # best auto-tuning +# ARCH := core2 # a reasonably safe default for most CPUs since 2007 +# ARCH := corei7 +# ARCH := corei7-avx # earlier i7 +# ARCH := core-avx-i # i7 ivy bridge or newer +# ARCH := core-avx2 # i7 with Haswell or newer +# ARCH := nehalem +# ARCH := westmere +# ARCH := sandybridge # circa 2011 +# ARCH := ivybridge # circa 2012 +# ARCH := haswell # circa 2013 +# ARCH := broadwell # circa 2014 +# ARCH := skylake # circa 2015 +# ARCH := bonnell +# ARCH := silvermont +# ARCH := skylake-avx512 +# ARCH := nocona #64-bit pentium 4 or later + +# CFLAGS := -march=$(ARCH) -Ofast -s -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 +CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -mfpmath=both -fopenmp -m64 -std=c++11 + +ifeq ($(OS),Windows_NT) +else + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Darwin) + UNAME_P := $(shell uname -p) + var := $(shell which $(CC) | xargs file) + ifeq ($(lastword $(var)),arm64) + CFLAGS := -march=$(ARCH) -O3 -fomit-frame-pointer -fopenmp -m64 -std=c++11 + endif + endif +endif + +CFLAGS_LINK := $(shell echo $(CFLAGS) | sed -e "s/-fopenmp//g") +COMPILE_COMMAND := $(CC) $(CFLAGS) $(EXTRA_FLAGS) +LINK_COMMAND := $(CC) $(CFLAGS_LINK) $(EXTRA_FLAGS) + +BioFVM_OBJECTS := BioFVM_vector.o BioFVM_mesh.o BioFVM_microenvironment.o BioFVM_solvers.o BioFVM_matlab.o \ +BioFVM_utilities.o BioFVM_basic_agent.o BioFVM_MultiCellDS.o BioFVM_agent_container.o + +PhysiCell_core_OBJECTS := PhysiCell_phenotype.o PhysiCell_cell_container.o PhysiCell_standard_models.o \ +PhysiCell_cell.o PhysiCell_custom.o PhysiCell_utilities.o PhysiCell_constants.o PhysiCell_basic_signaling.o \ +PhysiCell_signal_behavior.o PhysiCell_rules.o + +PhysiCell_module_OBJECTS := PhysiCell_SVG.o PhysiCell_pathology.o PhysiCell_MultiCellDS.o PhysiCell_various_outputs.o \ +PhysiCell_pugixml.o PhysiCell_settings.o PhysiCell_geometry.o + +# put your custom objects here (they should be in the custom_modules directory) + +PhysiCell_custom_module_OBJECTS := custom.o + +pugixml_OBJECTS := pugixml.o + +PhysiCell_OBJECTS := $(BioFVM_OBJECTS) $(pugixml_OBJECTS) $(PhysiCell_core_OBJECTS) $(PhysiCell_module_OBJECTS) +ALL_OBJECTS := $(PhysiCell_OBJECTS) $(PhysiCell_custom_module_OBJECTS) + +# compile the project + +all: main.cpp $(ALL_OBJECTS) + $(COMPILE_COMMAND) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp + make name + +static: main.cpp $(ALL_OBJECTS) $(MaBoSS) + $(LINK_COMMAND) $(INC) -o $(PROGRAM_NAME) $(ALL_OBJECTS) main.cpp $(LIB) -static-libgcc -static-libstdc++ $(STATIC_OPENMP) + +name: + @echo "" + @echo "Executable name is" $(PROGRAM_NAME) + @echo "" + +# PhysiCell core components + +PhysiCell_phenotype.o: ./core/PhysiCell_phenotype.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_phenotype.cpp + +PhysiCell_digital_cell_line.o: ./core/PhysiCell_digital_cell_line.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_digital_cell_line.cpp + +PhysiCell_cell.o: ./core/PhysiCell_cell.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_cell.cpp + +PhysiCell_cell_container.o: ./core/PhysiCell_cell_container.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_cell_container.cpp + +PhysiCell_standard_models.o: ./core/PhysiCell_standard_models.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_standard_models.cpp + +PhysiCell_utilities.o: ./core/PhysiCell_utilities.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_utilities.cpp + +PhysiCell_custom.o: ./core/PhysiCell_custom.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_custom.cpp + +PhysiCell_constants.o: ./core/PhysiCell_constants.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_constants.cpp + +PhysiCell_signal_behavior.o: ./core/PhysiCell_signal_behavior.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_signal_behavior.cpp + +PhysiCell_rules.o: ./core/PhysiCell_rules.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_rules.cpp + +# BioFVM core components (needed by PhysiCell) + +BioFVM_vector.o: ./BioFVM/BioFVM_vector.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_vector.cpp + +BioFVM_agent_container.o: ./BioFVM/BioFVM_agent_container.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_agent_container.cpp + +BioFVM_mesh.o: ./BioFVM/BioFVM_mesh.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_mesh.cpp + +BioFVM_microenvironment.o: ./BioFVM/BioFVM_microenvironment.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_microenvironment.cpp + +BioFVM_solvers.o: ./BioFVM/BioFVM_solvers.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_solvers.cpp + +BioFVM_utilities.o: ./BioFVM/BioFVM_utilities.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_utilities.cpp + +BioFVM_basic_agent.o: ./BioFVM/BioFVM_basic_agent.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_basic_agent.cpp + +BioFVM_matlab.o: ./BioFVM/BioFVM_matlab.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_matlab.cpp + +BioFVM_MultiCellDS.o: ./BioFVM/BioFVM_MultiCellDS.cpp + $(COMPILE_COMMAND) -c ./BioFVM/BioFVM_MultiCellDS.cpp + +pugixml.o: ./BioFVM/pugixml.cpp + $(COMPILE_COMMAND) -c ./BioFVM/pugixml.cpp + +# standard PhysiCell modules + +PhysiCell_SVG.o: ./modules/PhysiCell_SVG.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_SVG.cpp + +PhysiCell_pathology.o: ./modules/PhysiCell_pathology.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_pathology.cpp + +PhysiCell_MultiCellDS.o: ./modules/PhysiCell_MultiCellDS.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_MultiCellDS.cpp + +PhysiCell_various_outputs.o: ./modules/PhysiCell_various_outputs.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_various_outputs.cpp + +PhysiCell_pugixml.o: ./modules/PhysiCell_pugixml.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_pugixml.cpp + +PhysiCell_settings.o: ./modules/PhysiCell_settings.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_settings.cpp + +PhysiCell_basic_signaling.o: ./core/PhysiCell_basic_signaling.cpp + $(COMPILE_COMMAND) -c ./core/PhysiCell_basic_signaling.cpp + +PhysiCell_geometry.o: ./modules/PhysiCell_geometry.cpp + $(COMPILE_COMMAND) -c ./modules/PhysiCell_geometry.cpp + +# user-defined PhysiCell modules + +custom.o: ./custom_modules/custom.cpp + $(COMPILE_COMMAND) -c ./custom_modules/custom.cpp + +# cleanup + +reset: + rm -f *.cpp + cp ./sample_projects/Makefile-default Makefile + rm -f ./custom_modules/* + touch ./custom_modules/empty.txt + touch ALL_CITATIONS.txt + touch ./core/PhysiCell_cell.cpp + rm ALL_CITATIONS.txt + cp ./config/PhysiCell_settings-backup.xml ./config/PhysiCell_settings.xml + touch ./config/empty.csv + rm -f ./config/*.csv + +clean: + rm -f *.o + rm -f $(PROGRAM_NAME)* + +data-cleanup: + rm -rf ./output + mkdir ./output + touch ./output/empty.txt + +# archival + +checkpoint: + zip -r $$(date +%b_%d_%Y_%H%M).zip Makefile *.cpp *.h config/*.xml custom_modules/* + +zip: + zip -r latest.zip Makefile* *.cpp *.h BioFVM/* config/* core/* custom_modules/* matlab/* modules/* sample_projects/* + cp latest.zip $$(date +%b_%d_%Y_%H%M).zip + cp latest.zip VERSION_$(VERSION).zip + mv *.zip archives/ + +tar: + tar --ignore-failed-read -czf latest.tar Makefile* *.cpp *.h BioFVM/* config/* core/* custom_modules/* matlab/* modules/* sample_projects/* + cp latest.tar $$(date +%b_%d_%Y_%H%M).tar + cp latest.tar VERSION_$(VERSION).tar + mv *.tar archives/ + +unzip: + cp ./archives/latest.zip . + unzip latest.zip + +untar: + cp ./archives/latest.tar . + tar -xzf latest.tar + +# easier animation + +FRAMERATE := 24 +OUTPUT := output + +jpeg: + @magick identify -format "%h" $(OUTPUT)/initial.svg > __H.txt + @magick identify -format "%w" $(OUTPUT)/initial.svg > __W.txt + @expr 2 \* \( $$(grep . __H.txt) / 2 \) > __H1.txt + @expr 2 \* \( $$(grep . __W.txt) / 2 \) > __W1.txt + @echo "$$(grep . __W1.txt)!x$$(grep . __H1.txt)!" > __resize.txt + @magick mogrify -format jpg -resize $$(grep . __resize.txt) $(OUTPUT)/s*.svg + rm -f __H*.txt __W*.txt __resize.txt + +gif: + magick convert $(OUTPUT)/s*.svg $(OUTPUT)/out.gif + +movie: + ffmpeg -r $(FRAMERATE) -f image2 -i $(OUTPUT)/snapshot%08d.jpg -vcodec libx264 -pix_fmt yuv420p -strict -2 -tune animation -crf 15 -acodec none $(OUTPUT)/out.mp4 + +# upgrade rules + +SOURCE := PhysiCell_upgrade.zip +get-upgrade: + @echo $$(curl https://raw.githubusercontent.com/MathCancer/PhysiCell/master/VERSION.txt) > VER.txt + @echo https://github.com/MathCancer/PhysiCell/releases/download/$$(grep . VER.txt)/PhysiCell_V.$$(grep . VER.txt).zip > DL_FILE.txt + rm -f VER.txt + $$(curl -L $$(grep . DL_FILE.txt) --output PhysiCell_upgrade.zip) + rm -f DL_FILE.txt + +PhysiCell_upgrade.zip: + make get-upgrade + +upgrade: $(SOURCE) + unzip $(SOURCE) PhysiCell/VERSION.txt + mv -f PhysiCell/VERSION.txt . + unzip $(SOURCE) PhysiCell/core/* + cp -r PhysiCell/core/* core + unzip $(SOURCE) PhysiCell/modules/* + cp -r PhysiCell/modules/* modules + unzip $(SOURCE) PhysiCell/sample_projects/* + cp -r PhysiCell/sample_projects/* sample_projects + unzip $(SOURCE) PhysiCell/BioFVM/* + cp -r PhysiCell/BioFVM/* BioFVM + unzip $(SOURCE) PhysiCell/documentation/User_Guide.pdf + mv -f PhysiCell/documentation/User_Guide.pdf documentation + rm -f -r PhysiCell + rm -f $(SOURCE) + +# use: make save PROJ=your_project_name +PROJ := my_project + +save: + echo "Saving project as $(PROJ) ... " + mkdir -p ./user_projects + mkdir -p ./user_projects/$(PROJ) + mkdir -p ./user_projects/$(PROJ)/custom_modules + mkdir -p ./user_projects/$(PROJ)/config + cp main.cpp ./user_projects/$(PROJ) + cp Makefile ./user_projects/$(PROJ) + cp VERSION.txt ./user_projects/$(PROJ) + cp ./config/* ./user_projects/$(PROJ)/config + cp ./custom_modules/* ./user_projects/$(PROJ)/custom_modules + +load: + echo "Loading project from $(PROJ) ... " + cp ./user_projects/$(PROJ)/main.cpp . + cp ./user_projects/$(PROJ)/Makefile . + cp ./user_projects/$(PROJ)/config/* ./config/ + cp ./user_projects/$(PROJ)/custom_modules/* ./custom_modules/ + +pack: + @echo " " + @echo "Preparing project $(PROJ) for sharing ... " + @echo " " + cd ./user_projects && zip -r $(PROJ).zip $(PROJ) + @echo " " + @echo "Share ./user_projects/$(PROJ).zip ... " + @echo "Other users can unzip $(PROJ).zip in their ./user_projects, compile, and run." + @echo " " + +unpack: + @echo " " + @echo "Preparing shared project $(PROJ).zip for use ... " + @echo " " + cd ./user_projects && unzip $(PROJ).zip + @echo " " + @echo "Load this project via make load PROJ=$(PROJ) ... " + @echo " " + +list-user-projects: + @echo "user projects::" + @cd ./user_projects && ls -dt1 * | grep . | sed 's!empty.txt!!' diff --git a/test/pcmodel/README.txt b/test/pcmodel/README.txt new file mode 100644 index 0000000..1853977 --- /dev/null +++ b/test/pcmodel/README.txt @@ -0,0 +1,15 @@ +# how to + ++ install and run the pcdl unit test pcmodel +cp -r ../physicelldataloader/test/pcmodel/ user_projects/ +make load PROJ=pcmodel +make +./project + ++ set 2d or 3d in config/PhysiCell_settings.xml +true +false + ++ tar gz the output folders +tar -czvf output_2d.tar.gz output_2d/ +tar -czvf output_3d.tar.gz output_3d/ diff --git a/test/pcmodel/VERSION.txt b/test/pcmodel/VERSION.txt new file mode 100644 index 0000000..cd99d38 --- /dev/null +++ b/test/pcmodel/VERSION.txt @@ -0,0 +1 @@ +1.14.0 \ No newline at end of file diff --git a/test/pcmodel/config/PhysiCell_settings-backup.xml b/test/pcmodel/config/PhysiCell_settings-backup.xml new file mode 100644 index 0000000..e69de29 diff --git a/test/pcmodel/config/PhysiCell_settings.xml b/test/pcmodel/config/PhysiCell_settings.xml new file mode 100644 index 0000000..e499d1e --- /dev/null +++ b/test/pcmodel/config/PhysiCell_settings.xml @@ -0,0 +1,405 @@ + + + + -30 + 300 + -20 + 200 + -10 + 100 + 30 + 20 + 10 + true + + + + 1440.0 + min + micron + 0.01 + 0.1 + 6 + + + + 1 + + + + output + + 60 + true + + + 60 + false + + water + YlOrRd + 0 + 1 + + + + false + + + + + false + true + false + 0 + + + + + + 1e3 + 1 + + 1e3 + 0.0 + + + + + + + + + + + + 1e6 + 0.001 + + 1e3 + 1e3 + + 1e3 + 1e3 + 1e3 + 1e3 + 1e3 + 1e3 + + + + true + true + + ./config/initial.mat + + + ./config/dirichlet.mat + + + + + + + + + + 0.003333 + 0.002083 + 0.004167 + 0.016667 + + + + + 5.31667e-05 + + 516 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 0 + 86400 + + + 1.11667e-2 + 8.33333e-4 + 5.33333e-5 + 2.16667e-3 + 0 + 2.0 + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0 + 0 + 2.0 + + + 0.4 + 10.0 + 1.25 + + 1.0 + 1 + + + 1.8 + 15.12 + + 0.01 + 0.05 + 0.03 + 12 + + + 1 + 1 + .2 + + true + true + + true + oxygen + 1 + + + false + false + + 0.0 + 0.0 + + + + + + + 0 + 0 + 10 + 0.0 + + + 5 + 15 + 0 + 0 + + + + 0.0 + 0.0 + 0.0 + + 0.001 + 0.0 + + + 0.0025 + 0.0 + + 1.0 + 0.1 + + 0.0 + 0.005 + + + + + 0.0 + 0.0 + + + + 0.0 + 0.0 + + + + 1.0 + + + + + + + + + 1388.888889 + + + + + 5.31667e-05 + + 0.001938 + + + 0.05 + 0 + 1.66667e-02 + 5.83333e-03 + 0 + 2.0 + + + + 0.0 + + 9000000000.0 + 1.15741e-05 + + + 1.11667e-02 + 8.33333e-4 + 5.33333e-05 + 2.16667e-4 + 7e-05 + 2.0 + + + + + 2494 + 0.75 + 540 + 0.05 + 0.0045 + 0.0055 + 0.0 + 0.0 + 2 + + + 0.4 + 10.0 + 1.25 + + 1.0 + 1.0 + + + 1.8 + 15.12 + + 0.01 + 0.0 + 0.0 + 12 + + + 2.5 + 1.0 + .5 + + true + true + + true + water + 1 + + + false + false + + 0.0 + 0.0 + + + + + + + 1000 + 50000 + 0 + 0.0 + + + 0 + 1.0 + 10 + 0.0 + + + + 0.0 + 0.0 + 0.0 + + 0.0 + 0.0005 + + + 0 + 0.006 + + 1.0 + 0.1 + + 0.0 + 0.0 + + + + + 0.0 + 0.0 + + + + 0.0 + 0.0 + + + + 0.0 + + + + + + + + + ./config + cells.csv + + + + + + + ./config + cell_rules.csv + + + + + + + 0 + 64 + + diff --git a/test/pcmodel/config/cell_rules.csv b/test/pcmodel/config/cell_rules.csv new file mode 100644 index 0000000..21e2fb0 --- /dev/null +++ b/test/pcmodel/config/cell_rules.csv @@ -0,0 +1,2 @@ +default,oxygen,decreases,apoptosis,5.3167e-06,0.5,4,0 +blood_cells,water,increases,oxygen secretion,10000.0,0.5,4,0 diff --git a/test/pcmodel/config/cells.csv b/test/pcmodel/config/cells.csv new file mode 100644 index 0000000..e69de29 diff --git a/test/pcmodel/custom_modules/custom.cpp b/test/pcmodel/custom_modules/custom.cpp new file mode 100644 index 0000000..59b23bd --- /dev/null +++ b/test/pcmodel/custom_modules/custom.cpp @@ -0,0 +1,214 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2021, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include "./custom.h" + +void create_cell_types( void ) +{ + // set the random seed + if (parameters.ints.find_index("random_seed") != -1) + { + SeedRandom(parameters.ints("random_seed")); + } + + /* + Put any modifications to default cell definition here if you + want to have "inherited" by other cell types. + + This is a good place to set default functions. + */ + + initialize_default_cell_definition(); + cell_defaults.phenotype.secretion.sync_to_microenvironment( µenvironment ); + + cell_defaults.functions.volume_update_function = standard_volume_update_function; + cell_defaults.functions.update_velocity = standard_update_cell_velocity; + + cell_defaults.functions.update_migration_bias = NULL; + cell_defaults.functions.update_phenotype = NULL; // update_cell_and_death_parameters_O2_based; + cell_defaults.functions.custom_cell_rule = NULL; + cell_defaults.functions.contact_function = NULL; + + cell_defaults.functions.add_cell_basement_membrane_interactions = NULL; + cell_defaults.functions.calculate_distance_to_membrane = NULL; + + /* + This parses the cell definitions in the XML config file. + */ + + initialize_cell_definitions_from_pugixml(); + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + build_cell_definitions_maps(); + + /* + This intializes cell signal and response dictionaries + */ + + setup_signal_behavior_dictionaries(); + + /* + Cell rule definitions + */ + + setup_cell_rules(); + + /* + Put any modifications to individual cell definitions here. + + This is a good place to set custom functions. + */ + + cell_defaults.functions.update_phenotype = phenotype_function; + cell_defaults.functions.custom_cell_rule = custom_function; + cell_defaults.functions.contact_function = contact_function; + + /* + This builds the map of cell definitions and summarizes the setup. + */ + + display_cell_definitions( std::cout ); + + return; +} + +void setup_microenvironment( void ) +{ + // set domain parameters + + // put any custom code to set non-homogeneous initial conditions or + // extra Dirichlet nodes here. + + // initialize BioFVM + + initialize_microenvironment(); + + return; +} + +void setup_tissue( void ) +{ + double Xmin = microenvironment.mesh.bounding_box[0]; + double Ymin = microenvironment.mesh.bounding_box[1]; + double Zmin = microenvironment.mesh.bounding_box[2]; + + double Xmax = microenvironment.mesh.bounding_box[3]; + double Ymax = microenvironment.mesh.bounding_box[4]; + double Zmax = microenvironment.mesh.bounding_box[5]; + + if( default_microenvironment_options.simulate_2D == true ) + { + Zmin = 0.0; + Zmax = 0.0; + } + + double Xrange = Xmax - Xmin; + double Yrange = Ymax - Ymin; + double Zrange = Zmax - Zmin; + + // create some of each type of cell + + Cell* pC; + + for( int k=0; k < cell_definitions_by_index.size() ; k++ ) + { + Cell_Definition* pCD = cell_definitions_by_index[k]; + std::cout << "Placing cells of type " << pCD->name << " ... " << std::endl; + for( int n = 0 ; n < parameters.ints("number_of_cells") ; n++ ) + { + std::vector position = {0,0,0}; + position[0] = Xmin + UniformRandom()*Xrange; + position[1] = Ymin + UniformRandom()*Yrange; + position[2] = Zmin + UniformRandom()*Zrange; + + pC = create_cell( *pCD ); + pC->assign_position( position ); + } + } + std::cout << std::endl; + + // load cells from your CSV file (if enabled) + load_cells_from_pugixml(); + set_parameters_from_distributions(); + + return; +} + +std::vector my_coloring_function( Cell* pCell ) +{ return paint_by_number_cell_coloring(pCell); } + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ) +{ return; } + +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ) +{ return; } + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ) +{ return; } \ No newline at end of file diff --git a/test/pcmodel/custom_modules/custom.h b/test/pcmodel/custom_modules/custom.h new file mode 100644 index 0000000..0e6df8d --- /dev/null +++ b/test/pcmodel/custom_modules/custom.h @@ -0,0 +1,92 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2021, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include "../core/PhysiCell.h" +#include "../modules/PhysiCell_standard_modules.h" + +using namespace BioFVM; +using namespace PhysiCell; + +// setup functions to help us along + +void create_cell_types( void ); +void setup_tissue( void ); + +// set up the BioFVM microenvironment +void setup_microenvironment( void ); + +// custom pathology coloring function + +std::vector my_coloring_function( Cell* ); + +// custom functions can go here + +void phenotype_function( Cell* pCell, Phenotype& phenotype, double dt ); +void custom_function( Cell* pCell, Phenotype& phenotype , double dt ); + +void contact_function( Cell* pMe, Phenotype& phenoMe , Cell* pOther, Phenotype& phenoOther , double dt ); + diff --git a/test/pcmodel/custom_modules/empty.txt b/test/pcmodel/custom_modules/empty.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/pcmodel/main.cpp b/test/pcmodel/main.cpp new file mode 100644 index 0000000..2f7e98c --- /dev/null +++ b/test/pcmodel/main.cpp @@ -0,0 +1,254 @@ +/* +############################################################################### +# If you use PhysiCell in your project, please cite PhysiCell and the version # +# number, such as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1]. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# See VERSION.txt or call get_PhysiCell_version() to get the current version # +# x.y.z. Call display_citations() to get detailed information on all cite-# +# able software used in your PhysiCell application. # +# # +# Because PhysiCell extensively uses BioFVM, we suggest you also cite BioFVM # +# as below: # +# # +# We implemented and solved the model using PhysiCell (Version x.y.z) [1], # +# with BioFVM [2] to solve the transport equations. # +# # +# [1] A Ghaffarizadeh, R Heiland, SH Friedman, SM Mumenthaler, and P Macklin, # +# PhysiCell: an Open Source Physics-Based Cell Simulator for Multicellu- # +# lar Systems, PLoS Comput. Biol. 14(2): e1005991, 2018 # +# DOI: 10.1371/journal.pcbi.1005991 # +# # +# [2] A Ghaffarizadeh, SH Friedman, and P Macklin, BioFVM: an efficient para- # +# llelized diffusive transport solver for 3-D biological simulations, # +# Bioinformatics 32(8): 1256-8, 2016. DOI: 10.1093/bioinformatics/btv730 # +# # +############################################################################### +# # +# BSD 3-Clause License (see https://opensource.org/licenses/BSD-3-Clause) # +# # +# Copyright (c) 2015-2022, Paul Macklin and the PhysiCell Project # +# All rights reserved. # +# # +# Redistribution and use in source and binary forms, with or without # +# modification, are permitted provided that the following conditions are met: # +# # +# 1. Redistributions of source code must retain the above copyright notice, # +# this list of conditions and the following disclaimer. # +# # +# 2. Redistributions in binary form must reproduce the above copyright # +# notice, this list of conditions and the following disclaimer in the # +# documentation and/or other materials provided with the distribution. # +# # +# 3. Neither the name of the copyright holder nor the names of its # +# contributors may be used to endorse or promote products derived from this # +# software without specific prior written permission. # +# # +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE # +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR # +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN # +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # +# POSSIBILITY OF SUCH DAMAGE. # +# # +############################################################################### +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "./core/PhysiCell.h" +#include "./modules/PhysiCell_standard_modules.h" + +// put custom code modules here! + +#include "./custom_modules/custom.h" + +using namespace BioFVM; +using namespace PhysiCell; + +int main( int argc, char* argv[] ) +{ + // load and parse settings file(s) + + bool XML_status = false; + char copy_command [1024]; + if( argc > 1 ) + { + XML_status = load_PhysiCell_config_file( argv[1] ); + sprintf( copy_command , "cp %s %s" , argv[1] , PhysiCell_settings.folder.c_str() ); + } + else + { + XML_status = load_PhysiCell_config_file( "./config/PhysiCell_settings.xml" ); + sprintf( copy_command , "cp ./config/PhysiCell_settings.xml %s" , PhysiCell_settings.folder.c_str() ); + } + if( !XML_status ) + { exit(-1); } + + // copy config file to output directry + system( copy_command ); + + // OpenMP setup + omp_set_num_threads(PhysiCell_settings.omp_num_threads); + + // time setup + std::string time_units = "min"; + + /* Microenvironment setup */ + + setup_microenvironment(); // modify this in the custom code + + /* PhysiCell setup */ + + // set mechanics voxel size, and match the data structure to BioFVM + double mechanics_voxel_size = 30; + Cell_Container* cell_container = create_cell_container_for_microenvironment( microenvironment, mechanics_voxel_size ); + + /* Users typically start modifying here. START USERMODS */ + + create_cell_types(); + + setup_tissue(); + + /* Users typically stop modifying here. END USERMODS */ + + // set MultiCellDS save options + + set_save_biofvm_mesh_as_matlab( true ); + set_save_biofvm_data_as_matlab( true ); + set_save_biofvm_cell_data( true ); + set_save_biofvm_cell_data_as_custom_matlab( true ); + + // save a simulation snapshot + + char filename[1024]; + sprintf( filename , "%s/initial" , PhysiCell_settings.folder.c_str() ); + save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); + + // save a quick SVG cross section through z = 0, after setting its + // length bar to 200 microns + + PhysiCell_SVG_options.length_bar = 200; + + // for simplicity, set a pathology coloring function + + std::vector (*cell_coloring_function)(Cell*) = my_coloring_function; + std::string (*substrate_coloring_function)(double, double, double) = paint_by_density_percentage; + + sprintf( filename , "%s/initial.svg" , PhysiCell_settings.folder.c_str() ); + SVG_plot( filename , microenvironment, 0.0 , PhysiCell_globals.current_time, cell_coloring_function, substrate_coloring_function ); + + sprintf( filename , "%s/legend.svg" , PhysiCell_settings.folder.c_str() ); + create_plot_legend( filename , cell_coloring_function ); + + display_citations(); + + // set the performance timers + + BioFVM::RUNTIME_TIC(); + BioFVM::TIC(); + + std::ofstream report_file; + if( PhysiCell_settings.enable_legacy_saves == true ) + { + sprintf( filename , "%s/simulation_report.txt" , PhysiCell_settings.folder.c_str() ); + + report_file.open(filename); // create the data log file + report_file<<"simulated time\tnum cells\tnum division\tnum death\twall time"<update_all_cells( PhysiCell_globals.current_time ); + + /* + Custom add-ons could potentially go here. + */ + + PhysiCell_globals.current_time += diffusion_dt; + } + + if( PhysiCell_settings.enable_legacy_saves == true ) + { + log_output(PhysiCell_globals.current_time, PhysiCell_globals.full_output_index, microenvironment, report_file); + report_file.close(); + } + } + catch( const std::exception& e ) + { // reference to the base of a polymorphic object + std::cout << e.what(); // information from length_error printed + } + + // save a final simulation snapshot + + sprintf( filename , "%s/final" , PhysiCell_settings.folder.c_str() ); + save_PhysiCell_to_MultiCellDS_v2( filename , microenvironment , PhysiCell_globals.current_time ); + + sprintf( filename , "%s/final.svg" , PhysiCell_settings.folder.c_str() ); + SVG_plot(filename, microenvironment, 0.0, PhysiCell_globals.current_time, cell_coloring_function, substrate_coloring_function); + + // timer + + std::cout << std::endl << "Total simulation runtime: " << std::endl; + BioFVM::display_stopwatch_value( std::cout , BioFVM::runtime_stopwatch_value() ); + + return 0; +} diff --git a/test/test_anndata_2d.py b/test/test_anndata_2d.py index 5758764..bbbcb44 100644 --- a/test/test_anndata_2d.py +++ b/test/test_anndata_2d.py @@ -27,7 +27,7 @@ # const -s_path_2d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_2d') +s_path_2d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_2d') s_file_2d = 'output00000024.xml' s_pathfile_2d = f'{s_path_2d}/{s_file_2d}' @@ -80,11 +80,14 @@ def test_mcds_get_anndata(self): ann = mcds.get_anndata(values=1, drop=set(), keep=set(), scale='maxabs') assert(str(type(mcds)) == "") and \ (str(type(ann)) == "") and \ - (ann.X.shape == (1099, 78)) and \ - (ann.obs.shape == (1099, 7)) and \ - (ann.obsm['spatial'].shape == (1099, 2)) and \ + (ann.X.shape[0] > 9) and \ + (ann.X.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ + (ann.obsm['spatial'].shape[0] > 9) and \ + (ann.obsm['spatial'].shape[1] == 2) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 1) @@ -108,11 +111,14 @@ def test_mcdsts_get_anndata(self): (l_annmcds == mcdsts.l_annmcds) and \ (mcdsts.l_annmcds is None) and \ (str(type(ann)) == "") and \ - (ann.X.shape == (24758, 78)) and \ - (ann.obs.shape == (24758, 8)) and \ - (ann.obsm['spatial'].shape == (24758, 2)) and \ + (ann.X.shape[0] > 9) and \ + (ann.X.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ + (ann.obsm['spatial'].shape[0] > 9) and \ + (ann.obsm['spatial'].shape[1] == 2) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) def test_mcdsts_get_anndata_value(self): @@ -124,11 +130,14 @@ def test_mcdsts_get_anndata_value(self): (l_annmcds == mcdsts.l_annmcds) and \ (mcdsts.l_annmcds is None) and \ (str(type(ann)) == "") and \ - (ann.X.shape == (24758, 26)) and \ - (ann.obs.shape == (24758, 5)) and \ - (ann.obsm['spatial'].shape == (24758, 2)) and \ + (ann.X.shape[0] > 9) and \ + (ann.X.shape[1] == 50) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ + (ann.obsm['spatial'].shape[0] > 9) and \ + (ann.obsm['spatial'].shape[1] == 2) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (26, 0)) and \ + (ann.var.shape == (50, 0)) and \ (len(ann.uns) == 0) def test_mcdsts_get_anndata_collapsefalse(self): @@ -141,12 +150,15 @@ def test_mcdsts_get_anndata_collapsefalse(self): (str(type(mcdsts.l_annmcds)) == "") and \ (len(mcdsts.l_annmcds) == 25) and \ (all([str(type(ann)) == "" for ann in mcdsts.l_annmcds])) and \ - (mcdsts.l_annmcds[24].X.shape == (1099, 78)) and \ - (mcdsts.l_annmcds[24].obs.shape == (1099, 7)) and \ - (mcdsts.l_annmcds[24].obsm['spatial'].shape == (1099, 2)) and \ - (len(mcdsts.l_annmcds[24].obsp) == 2) and \ - (mcdsts.l_annmcds[24].var.shape == (78, 0)) and \ - (len(mcdsts.l_annmcds[24].uns) == 1) + (mcdsts.l_annmcds[24].X.shape[0] > 9) and \ + (mcdsts.l_annmcds[24].X.shape[1] == 105) and \ + (mcdsts.l_annmcds[24].obs.shape[0] > 9) and \ + (mcdsts.l_annmcds[24].obs.shape[1] == 7) and \ + (mcdsts.l_annmcds[24].obsm['spatial'].shape[0] > 9) and \ + (mcdsts.l_annmcds[24].obsm['spatial'].shape[1] == 2) and \ + (len(mcdsts.l_annmcds[24].obsp) == 4) and \ + (mcdsts.l_annmcds[24].var.shape == (105, 0)) and \ + (len(mcdsts.l_annmcds[24].uns) == 2) def test_mcdsts_get_anndata_keepmcdsfalse(self): mcdsts = pcdl.TimeSeries(s_path_2d, verbose=True) @@ -157,10 +169,13 @@ def test_mcdsts_get_anndata_keepmcdsfalse(self): (l_annmcds == mcdsts.l_annmcds) and \ (mcdsts.l_annmcds is None) and \ (str(type(ann)) == "") and \ - (ann.X.shape == (24758, 78)) and \ - (ann.obs.shape == (24758, 8)) and \ - (ann.obsm['spatial'].shape == (24758, 2)) and \ + (ann.X.shape[0] > 9) and \ + (ann.X.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ + (ann.obsm['spatial'].shape[0] > 9) and \ + (ann.obsm['spatial'].shape[1] == 2) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) diff --git a/test/test_anndata_3d.py b/test/test_anndata_3d.py index d389430..27743e2 100644 --- a/test/test_anndata_3d.py +++ b/test/test_anndata_3d.py @@ -27,7 +27,7 @@ # const -s_path_3d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_3d') +s_path_3d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_3d') s_file_3d = 'output00000024.xml' s_pathfile_3d = f'{s_path_3d}/{s_file_3d}' @@ -51,11 +51,14 @@ def test_mcds_get_anndata(self): ann = mcds.get_anndata(values=1, drop=set(), keep=set(), scale='maxabs') assert(str(type(mcds)) == "") and \ (str(type(ann)) == "") and \ - (ann.X.shape == (20460, 101)) and \ - (ann.obs.shape == (20460, 7)) and \ - (ann.obsm['spatial'].shape == (20460, 3)) and \ + (ann.X.shape[0] > 9) and \ + (ann.X.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ + (ann.obsm['spatial'].shape[0] > 9) and \ + (ann.obsm['spatial'].shape[1] == 3) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (101, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 1) @@ -84,11 +87,14 @@ def test_mcdsts_get_anndata(self): (l_annmcds == mcdsts.l_annmcds) and \ (mcdsts.l_annmcds is None) and \ (str(type(ann)) == "") and \ - (ann.X.shape == (481651, 101)) and \ - (ann.obs.shape == (481651, 8)) and \ - (ann.obsm['spatial'].shape == (481651, 3)) and \ + (ann.X.shape[0] > 9) and \ + (ann.X.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ + (ann.obsm['spatial'].shape[0] > 9) and \ + (ann.obsm['spatial'].shape[1] == 3) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (101, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) def test_mcdsts_get_anndata_value(self): @@ -100,11 +106,14 @@ def test_mcdsts_get_anndata_value(self): (l_annmcds == mcdsts.l_annmcds) and \ (mcdsts.l_annmcds is None) and \ (str(type(ann)) == "") and \ - (ann.X.shape == (481651, 21)) and \ - (ann.obs.shape == (481651, 3)) and \ - (ann.obsm['spatial'].shape == (481651, 3)) and \ + (ann.X.shape[0] > 9) and \ + (ann.X.shape[1] == 56) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ + (ann.obsm['spatial'].shape[0] > 9) and \ + (ann.obsm['spatial'].shape[1] == 3) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (21, 0)) and \ + (ann.var.shape == (56, 0)) and \ (len(ann.uns) == 0) def test_mcdsts_get_anndata_collapsefalse(self): @@ -117,12 +126,15 @@ def test_mcdsts_get_anndata_collapsefalse(self): (str(type(mcdsts.l_annmcds)) == "") and \ (len(mcdsts.l_annmcds) == 25) and \ (all([str(type(ann)) == "" for ann in mcdsts.l_annmcds])) and \ - (mcdsts.l_annmcds[24].X.shape == (20460, 101)) and \ - (mcdsts.l_annmcds[24].obs.shape == (20460, 7)) and \ - (mcdsts.l_annmcds[24].obsm['spatial'].shape == (20460, 3)) and \ - (len(mcdsts.l_annmcds[24].obsp) == 2) and \ - (mcdsts.l_annmcds[24].var.shape == (101, 0)) and \ - (len(mcdsts.l_annmcds[24].uns) == 1) + (mcdsts.l_annmcds[24].X.shape[0] > 9) and \ + (mcdsts.l_annmcds[24].X.shape[1] == 105) and \ + (mcdsts.l_annmcds[24].obs.shape[0] > 9) and \ + (mcdsts.l_annmcds[24].obs.shape[1] == 7) and \ + (mcdsts.l_annmcds[24].obsm['spatial'].shape[0] > 9) and \ + (mcdsts.l_annmcds[24].obsm['spatial'].shape[1] == 3) and \ + (len(mcdsts.l_annmcds[24].obsp) == 4) and \ + (mcdsts.l_annmcds[24].var.shape == (105, 0)) and \ + (len(mcdsts.l_annmcds[24].uns) == 2) def test_mcdsts_get_anndata_keepmcdsfalse(self): mcdsts = pcdl.TimeSeries(s_path_3d, verbose=True) @@ -133,10 +145,13 @@ def test_mcdsts_get_anndata_keepmcdsfalse(self): (l_annmcds == mcdsts.l_annmcds) and \ (mcdsts.l_annmcds is None) and \ (str(type(ann)) == "") and \ - (ann.X.shape == (481651, 101)) and \ - (ann.obs.shape == (481651, 8)) and \ - (ann.obsm['spatial'].shape == (481651, 3)) and \ + (ann.X.shape[0] > 9) and \ + (ann.X.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ + (ann.obsm['spatial'].shape[0] > 9) and \ + (ann.obsm['spatial'].shape[1] == 3) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (101, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) diff --git a/test/test_cli_2d.py b/test/test_cli_2d.py index cf3215d..dded686 100644 --- a/test/test_cli_2d.py +++ b/test/test_cli_2d.py @@ -29,7 +29,7 @@ import subprocess # const -s_path_2d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_2d') +s_path_2d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_2d') s_file_2d = 'output00000024.xml' s_pathfile_2d = f'{s_path_2d}/{s_file_2d}' print("s_path_2d", s_path_2d) @@ -82,7 +82,7 @@ def test_pcdl_get_unit_dict_timeseries(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_unit.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_unit.csv')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -91,7 +91,7 @@ def test_pcdl_get_unit_dict_timestep(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_unit.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_unit.csv')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -101,7 +101,7 @@ def test_pcdl_get_unit_dict_timestep_microenv(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_unit.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_unit.csv')) and \ (not set(df_cell.index).issuperset({'oxygen'})) os.remove(s_opathfile) @@ -111,8 +111,8 @@ def test_pcdl_get_unit_dict_timestep_settingxmlfalse(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_unit.csv')) and \ - (set(df_cell.index).issuperset({'0_attack_rates'})) + assert (s_opathfile.endswith('output_2d/timeseries_unit.csv')) and \ + (set(df_cell.index).issuperset({'default_fusion_rates'})) os.remove(s_opathfile) def test_pcdl_get_unit_dict_timestep_settingxmlnone(self): @@ -121,8 +121,8 @@ def test_pcdl_get_unit_dict_timestep_settingxmlnone(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_unit.csv')) and \ - (set(df_cell.index).issuperset({'0_attack_rates'})) + assert (s_opathfile.endswith('output_2d/timeseries_unit.csv')) and \ + (set(df_cell.index).issuperset({'default_fusion_rates'})) os.remove(s_opathfile) @@ -142,14 +142,14 @@ def test_pcdl_get_substrate_list_timeseries(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_listing = s_result.stderr.decode('UTF8').replace('\r','') - assert (s_listing.startswith("['oxygen']")) + assert (s_listing.startswith("['oxygen', 'water']")) def test_pcdl_get_substrate_list_timestep(self): s_result = subprocess.run(['pcdl_get_substrate_list', s_pathfile_2d], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_listing = s_result.stderr.decode('UTF8').replace('\r','') - assert (s_listing.startswith("['oxygen']")) + assert (s_listing.startswith("['oxygen', 'water']")) class TestPyCliConcDfAttribute(object): @@ -168,7 +168,7 @@ def test_pcdl_get_conc_attribute_timeseries(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc_attribute_minmax.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_conc_attribute_minmax.json')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -178,8 +178,8 @@ def test_pcdl_get_conc_attribute_timeseries_value(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc_attribute_minmax.json')) and \ - (len(d_attribute) == 1) + assert (s_opathfile.endswith('output_2d/timeseries_conc_attribute_minmax.json')) and \ + (len(d_attribute) == 2) os.remove(s_opathfile) def test_pcdl_get_conc_attribute_timeseries_drop(self): @@ -188,9 +188,9 @@ def test_pcdl_get_conc_attribute_timeseries_drop(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc_attribute_minmax.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_conc_attribute_minmax.json')) and \ (not set(d_attribute.keys()).issuperset({'oxygen'})) and \ - (len(d_attribute) == 0) + (len(d_attribute) == 1) os.remove(s_opathfile) def test_pcdl_get_conc_attribute_timeseries_keep(self): @@ -199,7 +199,7 @@ def test_pcdl_get_conc_attribute_timeseries_keep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc_attribute_minmax.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_conc_attribute_minmax.json')) and \ (set(d_attribute.keys()).issuperset({'oxygen'})) and \ (len(d_attribute) == 1) os.remove(s_opathfile) @@ -209,7 +209,7 @@ def test_pcdl_get_conc_attribute_timeseries_allvalues(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc_attribute_all.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_conc_attribute_all.json')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -231,7 +231,7 @@ def test_pcdl_get_conc_df_timeseries(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_conc.csv')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -242,8 +242,8 @@ def test_pcdl_get_conc_df_timeseries_collapsed(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print(ls_opathfile, len(ls_opathfile)) assert len(ls_opathfile) == 25 and \ - ls_opathfile[0].endswith('data_timeseries_2d/output00000000_conc.csv') and \ - ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_conc.csv') and \ + ls_opathfile[0].endswith('output_2d/output00000000_conc.csv') and \ + ls_opathfile[-1].endswith('output_2d/output00000024_conc.csv') and \ os.path.exists(ls_opathfile[12]) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -254,8 +254,9 @@ def test_pcdl_get_conc_df_timeseries_value(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_conc = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc.csv')) and \ - (df_conc.shape == (3025, 10)) + assert (s_opathfile.endswith('output_2d/timeseries_conc.csv')) and \ + (df_conc.shape[0] > 9) and \ + (df_conc.shape[1] == 11) os.remove(s_opathfile) def test_pcdl_get_conc_df_timeseries_drop(self): @@ -264,9 +265,10 @@ def test_pcdl_get_conc_df_timeseries_drop(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_conc = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_conc.csv')) and \ (not set(df_conc.columns).issuperset({'oxygen'})) and \ - (df_conc.shape == (3025, 9)) + (df_conc.shape[0] > 9) and \ + (df_conc.shape[1] == 10) os.remove(s_opathfile) def test_pcdl_get_conc_df_timeseries_keep(self): @@ -275,9 +277,10 @@ def test_pcdl_get_conc_df_timeseries_keep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_conc = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_conc.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_conc.csv')) and \ (set(df_conc.columns).issuperset({'oxygen'})) and \ - (df_conc.shape == (3025, 10)) + (df_conc.shape[0] > 9) and \ + (df_conc.shape[1] == 10) os.remove(s_opathfile) def test_pcdl_get_conc_df_timestep(self): @@ -285,7 +288,7 @@ def test_pcdl_get_conc_df_timestep(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_conc.csv')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_conc.csv')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -295,8 +298,9 @@ def test_pcdl_get_conc_df_timestep_value(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_conc = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_conc.csv')) and \ - (df_conc.shape == (121, 10)) + assert (s_opathfile.endswith('output_2d/output00000024_conc.csv')) and \ + (df_conc.shape[0] > 9) and \ + (df_conc.shape[1] == 11) os.remove(s_opathfile) def test_pcdl_get_conc_df_timestep_drop(self): @@ -305,9 +309,10 @@ def test_pcdl_get_conc_df_timestep_drop(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_conc = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_conc.csv')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_conc.csv')) and \ (not set(df_conc.columns).issuperset({'oxygen'})) and \ - (df_conc.shape == (121, 9)) + (df_conc.shape[0] > 9) and \ + (df_conc.shape[1] == 10) os.remove(s_opathfile) def test_pcdl_get_conc_df_timestep_keep(self): @@ -316,9 +321,10 @@ def test_pcdl_get_conc_df_timestep_keep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_conc = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_conc.csv')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_conc.csv')) and \ (set(df_conc.columns).issuperset({'oxygen'})) and \ - (df_conc.shape == (121, 10)) + (df_conc.shape[0] > 9) and \ + (df_conc.shape[1] == 10) os.remove(s_opathfile) @@ -354,7 +360,7 @@ def test_pcdl_plot_contour_default(self): s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') s_opath = '/'.join(s_opathfile.split('/')[:-1]) assert (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/conc_oxygen_z0.0/output00000024_oxygen.jpeg')) and \ + (s_opathfile.endswith('pcdl/output_2d/conc_oxygen_z0.0/output00000024_oxygen.jpeg')) and \ (s_stdout.find("focus='oxygen'") > -1) and \ (s_stdout.find("z_slice=0.0") > -1) and \ (s_stdout.find("extrema=['none']") > -1) and \ @@ -395,7 +401,7 @@ def test_pcdl_plot_contour_set(self): s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') s_opath = '/'.join(s_opathfile.split('/')[:-1]) assert (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/conc_oxygen_z0.0/output00000024_oxygen.tiff')) and \ + (s_opathfile.endswith('pcdl/output_2d/conc_oxygen_z0.0/output00000024_oxygen.tiff')) and \ (s_stdout.find("focus='oxygen'") > -1) and \ (s_stdout.find("z_slice=1.1") > -1) and \ (s_stdout.find("extrema=['0.0', '40.0']") > -1) and \ @@ -413,35 +419,35 @@ def test_pcdl_plot_contour_set(self): shutil.rmtree(s_opath) -# bue 20240822: mcds broken! PhysiCell_settings.xml and microenvironment0.mat file are incompatible. -#class TestPyCliConcVtk(object): -# ''' tests for one pcdl.pyCli function. ''' +# bue 20250107: broken! FutureWarning causes troubles. +class TestPyCliConcVtk(object): + ''' tests for one pcdl.pyCli function. ''' # timestep and timeseries: # + path nop # + verbose (true, _false_) nop -# def test_pcdl_make_conc_vtk_timeseries_default(self): -# s_result = subprocess.run(['pcdl_make_conc_vtk', s_path_2d], check=False, capture_output=True) -# print(f'\ns_result.stdout: {s_result.stdout}\n') -# print(f'\ns_result.stderr: {s_result.stderr}\n') -# ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") -# #print('ls_opathfile:', ls_opathfile) -# assert (len(ls_opathfile) == 25) and \ -# (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_conc.vtr')) and \ -# (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_conc.vtr')) and \ -# (os.path.exists(ls_opathfile[12])) -# for s_opathfile in ls_opathfile: -# os.remove(s_opathfile) - -# def test_pcdl_make_conc_vtk_timestep_default(self): -# s_result = subprocess.run(['pcdl_make_conc_vtk', s_pathfile_2d], check=False, capture_output=True) -# print(f'\ns_result.stdout: {s_result.stdout}\n') -# print(f'\ns_result.stderr: {s_result.stderr}\n') -# s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') -# assert (s_opathfile.endswith('data_timeseries_2d/output00000024_conc.vtr')) and \ -# (os.path.exists(s_opathfile)) -# os.remove(s_opathfile) + def test_pcdl_make_conc_vtk_timeseries_default(self): + s_result = subprocess.run(['pcdl_make_conc_vtk', s_path_2d], check=False, capture_output=True) + #print(f'\ns_result.stdout: {s_result.stdout}\n') + #print(f'\ns_result.stderr: {s_result.stderr}\n') + ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead.\n")[-1].split("', '") + #print('ls_opathfile:', ls_opathfile) + assert (len(ls_opathfile) == 25) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_conc.vtr')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_conc.vtr')) and \ + (os.path.exists(ls_opathfile[12])) + for s_opathfile in ls_opathfile: + os.remove(s_opathfile) + + def test_pcdl_make_conc_vtk_timestep_default(self): + s_result = subprocess.run(['pcdl_make_conc_vtk', s_pathfile_2d], check=False, capture_output=True) + #print(f'\ns_result.stdout: {s_result.stdout}\n') + #print(f'\ns_result.stderr: {s_result.stderr}\n') + s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','').split("FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead.")[-1] + assert (s_opathfile.endswith('output_2d/output00000024_conc.vtr')) and \ + (os.path.exists(s_opathfile)) + os.remove(s_opathfile) ################################ @@ -460,14 +466,14 @@ def test_pcdl_get_celltype_list_timeseries(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_listing = s_result.stderr.decode('UTF8').replace('\r','') - assert (s_listing.startswith("['cancer_cell']")) + assert (s_listing.startswith("['default', 'blood_cells']")) def test_pcdl_get_celltype_list_timestep(self): s_result = subprocess.run(['pcdl_get_celltype_list', s_pathfile_2d], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_listing = s_result.stderr.decode('UTF8').replace('\r','') - assert (s_listing.startswith("['cancer_cell']")) + assert (s_listing.startswith("['default', 'blood_cells']")) class TestPyCliCellDfAttribute(object): @@ -475,7 +481,7 @@ class TestPyCliCellDfAttribute(object): # timeseries collapsed: # + path (str) nop - # + customtype ([], _oncoprotein:str_) ok + # + customtype ([], _sample:bool_) ok # + microenv (true, _false_) ok # + physiboss (true, _false_) # + settingxml (string, _none_, _false_) ok @@ -490,18 +496,18 @@ def test_pcdl_get_cell_attribute_timeseries(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) def test_pcdl_get_cell_attribute_timeseries_customtype(self): - s_result = subprocess.run(['pcdl_get_cell_attribute', s_path_2d, '--custom_data_type', 'oncoprotein:str'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_get_cell_attribute', s_path_2d, '--custom_data_type', 'sample:bool'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_cell = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ - (d_cell['oncoprotein'] == ['0','1','2']) + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ + (d_cell['sample'] == [False, True]) os.remove(s_opathfile) def test_pcdl_get_cell_attribute_timeseries_microenv(self): @@ -510,9 +516,9 @@ def test_pcdl_get_cell_attribute_timeseries_microenv(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ (not set(d_attribute.keys()).issuperset({'oxygen'})) and \ - (len(d_attribute) == 80) + (len(d_attribute) == 104) os.remove(s_opathfile) def test_pcdl_get_cell_attribute_timeseries_physiboss(self): @@ -520,7 +526,7 @@ def test_pcdl_get_cell_attribute_timeseries_physiboss(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -530,9 +536,9 @@ def test_pcdl_get_cell_attribute_timeseries_settingxmlfalse(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ - (set(d_attribute.keys()).issuperset({'0_attack_rates'})) and \ - (len(d_attribute) == 83) + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ + (set(d_attribute.keys()).issuperset({'default_fusion_rates'})) and \ + (len(d_attribute) == 110) os.remove(s_opathfile) def test_pcdl_get_cell_attribute_timeseries_settingxmlnone(self): @@ -541,9 +547,9 @@ def test_pcdl_get_cell_attribute_timeseries_settingxmlnone(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ - (set(d_attribute.keys()).issuperset({'0_attack_rates'})) and \ - (len(d_attribute) == 83) + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ + (set(d_attribute.keys()).issuperset({'default_fusion_rates'})) and \ + (len(d_attribute) == 110) os.remove(s_opathfile) def test_pcdl_get_cell_attribute_timeseries_value(self): @@ -552,8 +558,8 @@ def test_pcdl_get_cell_attribute_timeseries_value(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ - (len(d_attribute) == 28) + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ + (len(d_attribute) == 54) os.remove(s_opathfile) def test_pcdl_get_cell_attribute_timeseries_drop(self): @@ -562,9 +568,9 @@ def test_pcdl_get_cell_attribute_timeseries_drop(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ (not set(d_attribute.keys()).issuperset({'cell_type', 'oxygen'})) and \ - (len(d_attribute) == 81) + (len(d_attribute) == 108) os.remove(s_opathfile) def test_pcdl_get_cell_attribute_timeseries_keep(self): @@ -573,7 +579,7 @@ def test_pcdl_get_cell_attribute_timeseries_keep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') d_attribute = json.load(open(s_opathfile)) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_minmax.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_minmax.json')) and \ (set(d_attribute.keys()).issuperset({'cell_type', 'oxygen'})) and \ (len(d_attribute) == 2) os.remove(s_opathfile) @@ -583,7 +589,7 @@ def test_pcdl_get_cell_attribute_timeseries_allvalues(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_attribute_all.json')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_attribute_all.json')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -610,7 +616,7 @@ def test_pcdl_get_cell_df_timeseries(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell.csv')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -621,8 +627,8 @@ def test_pcdl_get_cell_df_timeseries_collapsed(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print(ls_opathfile, len(ls_opathfile)) assert len(ls_opathfile) == 25 and \ - ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell.csv') and \ - ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell.csv') and \ + ls_opathfile[0].endswith('output_2d/output00000000_cell.csv') and \ + ls_opathfile[-1].endswith('output_2d/output00000024_cell.csv') and \ os.path.exists(ls_opathfile[12]) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -633,7 +639,7 @@ def test_pcdl_get_cell_df_timeseries_microenv(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell.csv')) and \ (not set(df_cell.columns).issuperset({'oxygen'})) os.remove(s_opathfile) @@ -642,7 +648,7 @@ def test_pcdl_get_cell_df_timeseries_physiboss(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell.csv')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -652,8 +658,8 @@ def test_pcdl_get_cell_df_timeseries_settingxmlfalse(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell.csv')) and \ - (set(df_cell.columns).issuperset({'0_attack_rates'})) + assert (s_opathfile.endswith('output_2d/timeseries_cell.csv')) and \ + (set(df_cell.columns).issuperset({'default_fusion_rates'})) os.remove(s_opathfile) def test_pcdl_get_cell_df_timeseries_settingxmlnone(self): @@ -662,8 +668,8 @@ def test_pcdl_get_cell_df_timeseries_settingxmlnone(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell.csv')) and \ - (set(df_cell.columns).issuperset({'0_attack_rates'})) + assert (s_opathfile.endswith('output_2d/timeseries_cell.csv')) and \ + (set(df_cell.columns).issuperset({'default_fusion_rates'})) os.remove(s_opathfile) def test_pcdl_get_cell_df_timeseries_value(self): @@ -672,8 +678,9 @@ def test_pcdl_get_cell_df_timeseries_value(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell.csv')) and \ - (df_cell.shape == (24758, 41)) + assert (s_opathfile.endswith('output_2d/timeseries_cell.csv')) and \ + (df_cell.shape[0] > 9 ) and \ + (df_cell.shape[1] == 67) os.remove(s_opathfile) def test_pcdl_get_cell_df_timeseries_drop(self): @@ -682,9 +689,10 @@ def test_pcdl_get_cell_df_timeseries_drop(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell.csv')) and \ (not set(df_cell.columns).issuperset({'cell_type', 'oxygen'})) and \ - (df_cell.shape == (24758, 94)) + (df_cell.shape[0] > 9 ) and \ + (df_cell.shape[1] == 121) os.remove(s_opathfile) def test_pcdl_get_cell_df_timeseries_keep(self): @@ -693,9 +701,10 @@ def test_pcdl_get_cell_df_timeseries_keep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell.csv')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell.csv')) and \ (set(df_cell.columns).issuperset({'cell_type', 'oxygen'})) and \ - (df_cell.shape == (24758, 15)) + (df_cell.shape[0] > 9 ) and \ + (df_cell.shape[1] == 15) os.remove(s_opathfile) def test_pcdl_get_cell_df_timestep(self): @@ -703,7 +712,7 @@ def test_pcdl_get_cell_df_timestep(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.csv')) + assert (s_opathfile.endswith('output_2d/output00000024_cell.csv')) os.remove(s_opathfile) def test_pcdl_get_cell_df_timestep_microenv(self): @@ -712,7 +721,7 @@ def test_pcdl_get_cell_df_timestep_microenv(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.csv')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.csv')) and \ (not set(df_cell.columns).issuperset({'oxygen'})) os.remove(s_opathfile) @@ -721,7 +730,7 @@ def test_pcdl_get_cell_df_timestep_physiboss(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.csv')) + assert (s_opathfile.endswith('output_2d/output00000024_cell.csv')) os.remove(s_opathfile) def test_pcdl_get_cell_df_timestep_settingxmlfalse(self): @@ -730,8 +739,8 @@ def test_pcdl_get_cell_df_timestep_settingxmlfalse(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.csv')) and \ - (set(df_cell.columns).issuperset({'0_attack_rates'})) + assert (s_opathfile.endswith('output_2d/output00000024_cell.csv')) and \ + (set(df_cell.columns).issuperset({'default_fusion_rates'})) os.remove(s_opathfile) def test_pcdl_get_cell_df_timestep_settingxmlnone(self): @@ -740,8 +749,8 @@ def test_pcdl_get_cell_df_timestep_settingxmlnone(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.csv')) and \ - (set(df_cell.columns).issuperset({'0_attack_rates'})) + assert (s_opathfile.endswith('output_2d/output00000024_cell.csv')) and \ + (set(df_cell.columns).issuperset({'default_fusion_rates'})) os.remove(s_opathfile) def test_pcdl_get_cell_df_timestep_value(self): @@ -750,8 +759,9 @@ def test_pcdl_get_cell_df_timestep_value(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.csv')) and \ - (df_cell.shape == (1099, 40)) + assert (s_opathfile.endswith('output_2d/output00000024_cell.csv')) and \ + (df_cell.shape[0] > 9 ) and \ + (df_cell.shape[1] == 66) os.remove(s_opathfile) def test_pcdl_get_cell_df_timestep_drop(self): @@ -760,9 +770,10 @@ def test_pcdl_get_cell_df_timestep_drop(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.csv')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.csv')) and \ (not set(df_cell.columns).issuperset({'cell_type', 'oxygen'})) and \ - (df_cell.shape == (1099, 93)) + (df_cell.shape[0] > 9 ) and \ + (df_cell.shape[1] == 120) os.remove(s_opathfile) def test_pcdl_get_cell_df_timestep_keep(self): @@ -771,9 +782,10 @@ def test_pcdl_get_cell_df_timestep_keep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') df_cell = pd.read_csv(s_opathfile, index_col=0) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.csv')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.csv')) and \ (set(df_cell.columns).issuperset({'cell_type', 'oxygen'})) and \ - (df_cell.shape == (1099, 14)) + (df_cell.shape[0] > 9 ) and \ + (df_cell.shape[1] == 14) os.remove(s_opathfile) @@ -785,7 +797,7 @@ class TestPyCliAnndata(object): # timestep and timeseries: # + path nop - # + customtype ([], _oncoprotein:str_) ok + # + customtype ([], _sample:bool_) ok # + microenv (true, _false_) ok # + graph (true, _false_) ok # + physiboss (true, _false_) ok @@ -803,11 +815,13 @@ def test_pcdl_get_anndata_timeseries(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ - (ann.shape == (24758, 78)) and \ - (ann.obs.shape == (24758, 8)) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -817,24 +831,26 @@ def test_pcdl_get_anndata_timeseries_collapsed(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") assert len(ls_opathfile) == 25 and \ - ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell_maxabs.h5ad') and \ - ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad') and \ + ls_opathfile[0].endswith('output_2d/output00000000_cell_maxabs.h5ad') and \ + ls_opathfile[-1].endswith('output_2d/output00000024_cell_maxabs.h5ad') and \ os.path.exists(ls_opathfile[12]) for s_opathfile in ls_opathfile: os.remove(s_opathfile) def test_pcdl_get_anndata_timeseries_customtype(self): - s_result = subprocess.run(['pcdl_get_anndata', s_path_2d, '--custom_data_type', 'oncoprotein:str'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_get_anndata', s_path_2d, '--custom_data_type', 'sample:bool'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ - (set(ann.obs.columns).issuperset({'oncoprotein'})) and \ - (ann.shape == (24758, 77)) and \ - (ann.obs.shape == (24758, 9)) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ + (set(ann.var_names).issuperset({'sample'})) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (77, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -844,12 +860,14 @@ def test_pcdl_get_anndata_timeseries_microenv(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ (not set(ann.var_names).issuperset({'oxygen'})) and \ - (ann.shape == (24758, 75)) and \ - (ann.obs.shape == (24758, 8)) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 99) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (75, 0)) and \ + (ann.var.shape == (99, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -859,11 +877,13 @@ def test_pcdl_get_anndata_timeseries_graph(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ - (ann.shape == (24758, 78)) and \ - (ann.obs.shape == (24758, 8)) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -873,11 +893,13 @@ def test_pcdl_get_anndata_timeseries_physiboss(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ - (ann.shape == (24758, 78)) and \ - (ann.obs.shape == (24758, 8)) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -887,12 +909,14 @@ def test_pcdl_get_anndata_timeseries_settingxmlfalse(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ - (set(ann.var_names).issuperset({'0_attack_rates'})) and \ - (ann.shape == (24758, 78)) and \ - (ann.obs.shape == (24758, 8)) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ + (set(ann.var_names).issuperset({'default_fusion_rates'})) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -902,12 +926,14 @@ def test_pcdl_get_anndata_timeseries_settingxmlnone(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ - (set(ann.var_names).issuperset({'0_attack_rates'})) and \ - (ann.shape == (24758, 78)) and \ - (ann.obs.shape == (24758, 8)) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ + (set(ann.var_names).issuperset({'default_fusion_rates'})) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -917,11 +943,13 @@ def test_pcdl_get_anndata_timeseries_value(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ - (ann.shape == (24758, 26)) and \ - (ann.obs.shape == (24758, 5)) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 50) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (26, 0)) and \ + (ann.var.shape == (50, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -931,13 +959,15 @@ def test_pcdl_get_anndata_timeseries_drop(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ (not set(ann.var_names).issuperset({'cell_type'})) and \ (not set(ann.obs_keys()).issuperset({'oxygen'})) and \ - (ann.shape == (24758, 77)) and \ - (ann.obs.shape == (24758, 7)) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 104) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (77, 0)) and \ + (ann.var.shape == (104, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -947,11 +977,13 @@ def test_pcdl_get_anndata_timeseries_keep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_maxabs.h5ad')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_maxabs.h5ad')) and \ (set(ann.var_names).issuperset({'oxygen'})) and \ (set(ann.obs_keys()).issuperset({'cell_type'})) and \ - (ann.shape == (24758, 1)) and \ - (ann.obs.shape == (24758, 4)) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 1) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 4) and \ (len(ann.obsp) == 0) and \ (ann.var.shape == (1, 0)) and \ (len(ann.uns) == 0) @@ -963,11 +995,13 @@ def test_pcdl_get_anndata_timeseries_scale(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_std.h5ad')) and \ - (ann.shape == (24758, 78)) and \ - (ann.obs.shape == (24758, 8)) and \ + assert (s_opathfile.endswith('output_2d/timeseries_cell_std.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 8) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -978,11 +1012,13 @@ def test_pcdl_get_anndata_timestep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ - (ann.shape == (1099, 78)) and \ - (ann.obs.shape == (1099, 7)) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 1) os.remove(s_opathfile) @@ -992,12 +1028,14 @@ def test_pcdl_get_anndata_timestep_microenv(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ (not set(ann.var_names).issuperset({'oxygen'})) and \ - (ann.shape == (1099, 75)) and \ - (ann.obs.shape == (1099, 7)) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 99) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (75, 0)) and \ + (ann.var.shape == (99, 0)) and \ (len(ann.uns) == 1) os.remove(s_opathfile) @@ -1007,11 +1045,13 @@ def test_pcdl_get_anndata_timestep_graph(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ - (ann.shape == (1099, 78)) and \ - (ann.obs.shape == (1099, 7)) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 0) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 0) os.remove(s_opathfile) @@ -1021,11 +1061,13 @@ def test_pcdl_get_anndata_timestep_physiboss(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ - (ann.shape == (1099, 78)) and \ - (ann.obs.shape == (1099, 7)) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 1) os.remove(s_opathfile) @@ -1035,12 +1077,14 @@ def test_pcdl_get_anndata_timestep_settingxmlfalse(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ - (set(ann.var_names).issuperset({'0_attack_rates'})) and \ - (ann.shape == (1099, 78)) and \ - (ann.obs.shape == (1099, 7)) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ + (set(ann.var_names).issuperset({'default_fusion_rates'})) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 1) os.remove(s_opathfile) @@ -1050,12 +1094,14 @@ def test_pcdl_get_anndata_timestep_settingxmlnone(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ - (set(ann.var_names).issuperset({'0_attack_rates'})) and \ - (ann.shape == (1099, 78)) and \ - (ann.obs.shape == (1099, 7)) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ + (set(ann.var_names).issuperset({'default_fusion_rates'})) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 1) os.remove(s_opathfile) @@ -1065,11 +1111,13 @@ def test_pcdl_get_anndata_timestep_value(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ - (ann.shape == (1099, 26)) and \ - (ann.obs.shape == (1099, 4)) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 50) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 6) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (26, 0)) and \ + (ann.var.shape == (50, 0)) and \ (len(ann.uns) == 1) os.remove(s_opathfile) @@ -1079,13 +1127,15 @@ def test_pcdl_get_anndata_timestep_drop(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ (not set(ann.var_names).issuperset({'cell_type'})) and \ (not set(ann.obs_keys()).issuperset({'oxygen'})) and \ - (ann.shape == (1099, 77)) and \ - (ann.obs.shape == (1099, 6)) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 104) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 6) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (77, 0)) and \ + (ann.var.shape == (104, 0)) and \ (len(ann.uns) == 1) os.remove(s_opathfile) @@ -1095,11 +1145,13 @@ def test_pcdl_get_anndata_timestep_keep(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_maxabs.h5ad')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_maxabs.h5ad')) and \ (set(ann.var_names).issuperset({'oxygen'})) and \ (set(ann.obs_keys()).issuperset({'cell_type'})) and \ - (ann.shape == (1099, 1)) and \ - (ann.obs.shape == (1099, 3)) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 1) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 3) and \ (len(ann.obsp) == 2) and \ (ann.var.shape == (1, 0)) and \ (len(ann.uns) == 1) @@ -1111,11 +1163,13 @@ def test_pcdl_get_anndata_timestep_scale(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') ann = ad.read_h5ad(s_opathfile) - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_std.h5ad')) and \ - (ann.shape == (1099, 78)) and \ - (ann.obs.shape == (1099, 7)) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell_std.h5ad')) and \ + (ann.shape[0] > 9) and \ + (ann.shape[1] == 105) and \ + (ann.obs.shape[0] > 9) and \ + (ann.obs.shape[1] == 7) and \ (len(ann.obsp) == 2) and \ - (ann.var.shape == (78, 0)) and \ + (ann.var.shape == (105, 0)) and \ (len(ann.uns) == 1) os.remove(s_opathfile) @@ -1125,7 +1179,7 @@ class TestPyCliGraphGml(object): # timestep and timeseries: # + path nop - # + customtype ([], _oncoprotein:str_) ok + # + customtype ([], _sample:bool_) ok # + microenv (true, false) ok # + physiboss (true, _false_) # + settingxml (string, _none_, _false_) ok @@ -1141,21 +1195,21 @@ def test_pcdl_make_graph_gml_timeseries_default(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) - def test_pcdl_make_grah_gml_timeseries_customtype_nodeattribute_one(self): - s_result = subprocess.run(['pcdl_make_graph_gml', s_path_2d, 'neighbor', '--custom_data_type', 'oncoprotein:str', '--node_attribute', 'oncoprotein'], check=False, capture_output=True) + def test_pcdl_make_graph_gml_timeseries_customtype_nodeattribute_one(self): + s_result = subprocess.run(['pcdl_make_graph_gml', s_path_2d, 'neighbor', '--custom_data_type', 'sample:bool', '--node_attribute', 'sample'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1167,8 +1221,8 @@ def test_pcdl_make_graph_gml_timeseries_microenv(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1180,34 +1234,34 @@ def test_pcdl_make_graph_gml_timeseries_physiboss(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) def test_pcdl_make_graph_gml_timeseries_settingxmlfalse_nodeattribute_one(self): - s_result = subprocess.run(['pcdl_make_graph_gml', s_path_2d, 'neighbor', '--settingxml', 'false', '--node_attribute', '0_attack_rates'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_graph_gml', s_path_2d, 'neighbor', '--settingxml', 'false', '--node_attribute', 'default_fusion_rates'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) def test_pcdl_make_graph_gml_timeseries_settingxmlnone_nodeattribute_one(self): - s_result = subprocess.run(['pcdl_make_graph_gml', s_path_2d, 'neighbor', '--settingxml', 'none', '--node_attribute', '0_attack_rates'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_graph_gml', s_path_2d, 'neighbor', '--settingxml', 'none', '--node_attribute', 'default_fusion_rates'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1219,8 +1273,8 @@ def test_pcdl_make_graph_gml_timeseries_graph_type(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_attached.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_attached.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_attached.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_attached.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1232,8 +1286,8 @@ def test_pcdl_make_graph_gml_timeseries_edge_attribute(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1245,8 +1299,8 @@ def test_pcdl_make_graph_gml_timeseries_nodeattribute_one(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1258,8 +1312,8 @@ def test_pcdl_make_graph_gml_timeseries_nodeattribute_many(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_neighbor.gml')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1269,16 +1323,16 @@ def test_pcdl_make_graph_gml_timestep_default(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) def test_pcdl_make_graph_gml_timestep_customtype_nodeattribute_one(self): - s_result = subprocess.run(['pcdl_make_graph_gml', s_pathfile_2d, 'neighbor', '--custom_data_type', 'oncoprotein:str', '--node_attribute', 'oncoprotein'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_graph_gml', s_pathfile_2d, 'neighbor', '--custom_data_type', 'sample:bool', '--node_attribute', 'sample'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1287,7 +1341,7 @@ def test_pcdl_make_graph_gml_timestep_microenv(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1296,25 +1350,25 @@ def test_pcdl_make_graph_gml_timestep_physiboss(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) def test_pcdl_make_graph_gml_timestep_settingxmlfalse_nodeattribute_one(self): - s_result = subprocess.run(['pcdl_make_graph_gml', s_pathfile_2d, 'neighbor', '--settingxml', 'false', '--node_attribute', '0_attack_rates'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_graph_gml', s_pathfile_2d, 'neighbor', '--settingxml', 'false', '--node_attribute', 'default_fusion_rates'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) def test_pcdl_make_graph_gml_timestep_settingxmlnone_nodeattribute_one(self): - s_result = subprocess.run(['pcdl_make_graph_gml', s_pathfile_2d, 'neighbor', '--settingxml', 'none', '--node_attribute', '0_attack_rates'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_graph_gml', s_pathfile_2d, 'neighbor', '--settingxml', 'none', '--node_attribute', 'default_fusion_rates'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1323,7 +1377,7 @@ def test_pcdl_make_graph_gml_timestep_graph_type(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_attached.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_attached.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1332,7 +1386,7 @@ def test_pcdl_make_graph_gml_timestep_edge_attribute(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1341,7 +1395,7 @@ def test_pcdl_make_graph_gml_timestep_node_attribute_one(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1350,7 +1404,7 @@ def test_pcdl_make_graph_gml_timestep_node_attribute_many(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_neighbor.gml')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1360,7 +1414,7 @@ class TestPyCliPlotScatter(object): # time series and time steps. # + path nop - # + customtype ([], _oncoprotein:str_) ok + # + customtype ([], _sample:bool_) ok # + microenv (true, _false_) # + physiboss (true, _false_) # + settingxml (PhysiCell_settings.xml, _false_) @@ -1381,6 +1435,7 @@ class TestPyCliPlotScatter(object): # + ext (jpeg, _tiff_) # + figbgcolor (none, _yellow_) + # bue 20250107: broken by Ignoring def test_pcdl_plot_scatter_default(self): s_result = subprocess.run([ 'pcdl_plot_scatter', s_pathfile_2d, @@ -1389,10 +1444,10 @@ def test_pcdl_plot_scatter_default(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_stdout = s_result.stdout.decode('UTF8').replace('\r','') - s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') + s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','').split('Ignoring fixed x limits to fulfill fixed data aspect with adjustable data limits.')[-1] s_opath = '/'.join(s_opathfile.split('/')[:-1]) assert (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/cell_cell_type_z0.0/output00000024_cell_type.jpeg')) and \ + (s_opathfile.endswith('pcdl/output_2d/cell_cell_type_z0.0/output00000024_cell_type.jpeg')) and \ (s_stdout.find("custom_data_type=[]") > -1) and \ (s_stdout.find("microenv='true'") > -1) and \ (s_stdout.find("physiboss='true'") > -1) and \ @@ -1417,7 +1472,7 @@ def test_pcdl_plot_scatter_default(self): def test_pcdl_plot_scatter_set(self): s_result = subprocess.run([ 'pcdl_plot_scatter', s_pathfile_2d, 'oxygen', - '--custom_data_type', 'oncoprotein:str', + '--custom_data_type', 'sample:bool', '--microenv', 'True', '--physiboss', 'false', '--settingxml', 'false', @@ -1443,8 +1498,8 @@ def test_pcdl_plot_scatter_set(self): s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') s_opath = '/'.join(s_opathfile.split('/')[:-1]) assert (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/cell_oxygen_z0.0/output00000024_oxygen.tiff')) and \ - (s_stdout.find("custom_data_type=['oncoprotein:str']") > -1) and \ + (s_opathfile.endswith('pcdl/output_2d/cell_oxygen_z0.0/output00000024_oxygen.tiff')) and \ + (s_stdout.find("custom_data_type=['sample:bool']") > -1) and \ (s_stdout.find("microenv='True'") > -1) and \ (s_stdout.find("physiboss='false'") > -1) and \ (s_stdout.find("settingxml='false'") > -1) and \ @@ -1471,7 +1526,7 @@ class TestPyCliCellVtk(object): # timestep and timeseries: # + path nop - # + customtype ([], _oncoprotein:str_) ok + # + customtype ([], _sample:bool_) ok # + microenv (true, _false) ok # + physiboss (true, _false_) # + settingxml (string, _none_, _false_) ok @@ -1485,21 +1540,21 @@ def test_pcdl_make_cell_vtk_timeseries_default(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell.vtp')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_cell.vtp')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) def test_pcdl_make_cell_vtk_timeseries_customtype_attribute_one(self): - s_result = subprocess.run(['pcdl_make_cell_vtk', s_path_2d, 'oncoprotein', '--custom_data_type', 'oncoprotein:str'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_cell_vtk', s_path_2d, 'sample', '--custom_data_type', 'sample:bool'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell.vtp')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_cell.vtp')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1510,8 +1565,8 @@ def test_pcdl_make_cell_vtk_timeseries_microenv(self): #print(f'\ns_result.stderr: {s_result.stderr}\n') ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell.vtp')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_cell.vtp')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1523,34 +1578,34 @@ def test_pcdl_make_cell_vtk_timeseries_physiboss(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell.vtp')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_cell.vtp')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) def test_pcdl_make_cell_vtk_timeseries_settingxmlfalse_attribute_one(self): - s_result = subprocess.run(['pcdl_make_cell_vtk', s_path_2d, '0_attack_rates', '--settingxml', 'false'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_cell_vtk', s_path_2d, 'default_fusion_rates', '--settingxml', 'false'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell.vtp')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_cell.vtp')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) def test_pcdl_make_cell_vtk_timeseries_settingxmlnone_attribute_one(self): - s_result = subprocess.run(['pcdl_make_cell_vtk', s_path_2d, '0_attack_rates', '--settingxml', 'none'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_cell_vtk', s_path_2d, 'default_fusion_rates', '--settingxml', 'none'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell.vtp')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_cell.vtp')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1562,8 +1617,8 @@ def test_pcdl_make_cell_vtk_timeseries_attribute_many(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_cell.vtp')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_cell.vtp')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1573,16 +1628,16 @@ def test_pcdl_make_cell_vtk_timestep_default(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) def test_pcdl_make_cell_vtk_timestep_customtype_attribute_one(self): - s_result = subprocess.run(['pcdl_make_cell_vtk', s_pathfile_2d, 'oncoprotein', '--custom_data_type', 'oncoprotein:str'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_cell_vtk', s_pathfile_2d, 'sample', '--custom_data_type', 'sample:bool'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1591,7 +1646,7 @@ def test_pcdl_make_cell_vtk_timestep_microenv(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1600,25 +1655,25 @@ def test_pcdl_make_cell_vtk_timestep_physiboss(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) def test_pcdl_make_cell_vtk_timestep_settingxmlfalse_attribute_one(self): - s_result = subprocess.run(['pcdl_make_cell_vtk', s_pathfile_2d, '0_attack_rates', '--settingxml', 'false'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_cell_vtk', s_pathfile_2d, 'default_fusion_rates', '--settingxml', 'false'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) def test_pcdl_make_cell_vtk_timestep_settingxmlnone_attribute_one(self): - s_result = subprocess.run(['pcdl_make_cell_vtk', s_pathfile_2d, '0_attack_rates', '--settingxml', 'none'], check=False, capture_output=True) + s_result = subprocess.run(['pcdl_make_cell_vtk', s_pathfile_2d, 'default_fusion_rates', '--settingxml', 'none'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1627,7 +1682,7 @@ def test_pcdl_make_cell_vtk_timestep_attribute_many(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell.vtp')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1641,7 +1696,7 @@ class TestPyCliPlotTimeSeries(object): # time series. # + path nop - # + customtype ([], _oncoprotein:str_) ok + # + customtype ([], _sample:bool_) ok # + microenv (true, _false_) # + physiboss (true, _false_) # + settingxml (PhysiCell_settings.xml, _false_) @@ -1679,7 +1734,7 @@ def test_pcdl_plot_timeseries_default(self): s_stdout = s_result.stdout.decode('UTF8').replace('\r','') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') assert (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/timeseries_cell_total_count.jpeg')) and \ + (s_opathfile.endswith('pcdl/output_2d/timeseries_cell_total_count.jpeg')) and \ (s_stdout.find("custom_data_type=[]") > -1) and \ (s_stdout.find("microenv='true'") > -1) and \ (s_stdout.find("physiboss='true'") > -1) and \ @@ -1711,7 +1766,7 @@ def test_pcdl_plot_timeseries_default(self): def test_pcdl_plot_timeseries_set(self): s_result = subprocess.run([ 'pcdl_plot_timeseries', s_path_2d, 'None', 'oxygen', 'entropy', '-v', 'false', - '--custom_data_type', 'oncoprotein:str', + '--custom_data_type', 'sample:bool', '--microenv', 'True', '--physiboss', 'false', '--settingxml', 'false', @@ -1741,8 +1796,8 @@ def test_pcdl_plot_timeseries_set(self): s_stdout = s_result.stdout.decode('UTF8').replace('\r','') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') assert (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/timeseries_conc_total_oxygen_entropy.tiff')) and \ - (s_stdout.find("custom_data_type=['oncoprotein:str']") > -1) and \ + (s_opathfile.endswith('pcdl/output_2d/timeseries_conc_total_oxygen_entropy.tiff')) and \ + (s_stdout.find("custom_data_type=['sample:bool']") > -1) and \ (s_stdout.find("microenv='True'") > -1) and \ (s_stdout.find("physiboss='false'") > -1) and \ (s_stdout.find("settingxml='false'") > -1) and \ @@ -1789,7 +1844,7 @@ def test_pcdl_make_ome_tiff_timeseries_default(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1798,7 +1853,7 @@ def test_pcdl_make_ome_tiff_timeseries_microenv(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1807,7 +1862,7 @@ def test_pcdl_make_ome_tiff_timeseries_physiboss(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1816,7 +1871,7 @@ def test_pcdl_make_ome_tiff_timeseries_settingxmlfalse(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1825,7 +1880,7 @@ def test_pcdl_make_ome_tiff_timeseries_settingxmlnone(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1834,7 +1889,7 @@ def test_pcdl_make_ome_tiff_timeseries_cellattribute_dead(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_dead.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_oxygen_water_default_blood_cells_dead.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1843,7 +1898,7 @@ def test_pcdl_make_ome_tiff_timeseries_cellattribute_cellcountvoxel(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_cell_count_voxel.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_oxygen_water_default_blood_cells_cell_count_voxel.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1852,7 +1907,25 @@ def test_pcdl_make_ome_tiff_timeseries_cellattribute_pressure(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/timeseries_pressure.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/timeseries_oxygen_water_default_blood_cells_pressure.ome.tiff')) and \ + (os.path.exists(s_opathfile)) + os.remove(s_opathfile) + + def test_pcdl_make_ome_tiff_timeseries_conccutoff_oxygenminusone(self): + s_result = subprocess.run(['pcdl_make_ome_tiff', s_path_2d, '--conc_cutoff', 'oxygen:-1'], check=False, capture_output=True) + #print(f'\ns_result.stdout: {s_result.stdout}\n') + #print(f'\ns_result.stderr: {s_result.stderr}\n') + s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') + assert (s_opathfile.endswith('output_2d/timeseries_oxygen-1_water_default_blood_cells_ID.ome.tiff')) and \ + (os.path.exists(s_opathfile)) + os.remove(s_opathfile) + + def test_pcdl_make_ome_tiff_timeseries_focus_(self): + s_result = subprocess.run(['pcdl_make_ome_tiff', s_path_2d, '--focus', 'oxygen'], check=False, capture_output=True) + #print(f'\ns_result.stdout: {s_result.stdout}\n') + #print(f'\ns_result.stderr: {s_result.stderr}\n') + s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') + assert (s_opathfile.endswith('output_2d/timeseries_oxygen.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1863,8 +1936,8 @@ def test_pcdl_make_ome_tiff_timeseries_collapse_false(self): ls_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace("['","").replace("']\n","").split("', '") #print('ls_opathfile:', ls_opathfile) assert (len(ls_opathfile) == 25) and \ - (ls_opathfile[0].endswith('data_timeseries_2d/output00000000_ID.ome.tiff')) and \ - (ls_opathfile[-1].endswith('data_timeseries_2d/output00000024_ID.ome.tiff')) and \ + (ls_opathfile[0].endswith('output_2d/output00000000_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ + (ls_opathfile[-1].endswith('output_2d/output00000024_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(ls_opathfile[12])) for s_opathfile in ls_opathfile: os.remove(s_opathfile) @@ -1874,7 +1947,7 @@ def test_pcdl_make_ome_tiff_timestep_default(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1883,7 +1956,7 @@ def test_pcdl_make_ome_tiff_timestep_microenv(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1892,7 +1965,7 @@ def test_pcdl_make_ome_tiff_timestep_physiboss(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1901,7 +1974,7 @@ def test_pcdl_make_ome_tiff_timestep_settingxmlfalse(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1910,7 +1983,7 @@ def test_pcdl_make_ome_tiff_timestep_settingxmlnone(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_ID.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1919,7 +1992,7 @@ def test_pcdl_make_ome_tiff_timestep_cellattribute_dead(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_dead.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_oxygen_water_default_blood_cells_dead.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1928,7 +2001,7 @@ def test_pcdl_make_ome_tiff_timestep_cellattribute_cellcountvoxel(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_cell_count_voxel.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_oxygen_water_default_blood_cells_cell_count_voxel.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1937,7 +2010,7 @@ def test_pcdl_make_ome_tiff_timestep_cellattribute_pressure(self): #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').replace('\n','') - assert (s_opathfile.endswith('data_timeseries_2d/output00000024_pressure.ome.tiff')) and \ + assert (s_opathfile.endswith('output_2d/output00000024_oxygen_water_default_blood_cells_pressure.ome.tiff')) and \ (os.path.exists(s_opathfile)) os.remove(s_opathfile) @@ -1946,6 +2019,7 @@ def test_pcdl_make_ome_tiff_timestep_cellattribute_pressure(self): # making movies test code # ########################### +# bue 20250107: broken by Ignoring class TestPyCliMakeGif(object): ''' tests for one pcdl.pyCli function. ''' @@ -1955,27 +2029,28 @@ class TestPyCliMakeGif(object): def test_pcdl_make_gif_timeseries_default(self): s_path = subprocess.run(['pcdl_plot_scatter', s_path_2d], check=False, capture_output=True) - s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','') + s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','').split('Ignoring fixed x limits to fulfill fixed data aspect with adjustable data limits.')[-1] s_result = subprocess.run(['pcdl_make_gif', s_path], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').split('\n')[-2] - assert (s_opathfile.endswith('data_timeseries_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg.gif')) and \ + assert (s_opathfile.endswith('output_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg.gif')) and \ (os.path.exists(s_opathfile)) shutil.rmtree(s_path) def test_pcdl_make_gif_timeseries_interface(self): s_path = subprocess.run(['pcdl_plot_contour', s_path_2d, 'oxygen', '--ext', 'tiff'], check=False, capture_output=True) - s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','') + s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','').split('Ignoring fixed x limits to fulfill fixed data aspect with adjustable data limits.')[-1] s_result = subprocess.run(['pcdl_make_gif', s_path, 'tiff'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').split('\n')[-2] - assert (s_opathfile.endswith('data_timeseries_2d/conc_oxygen_z0.0/conc_oxygen_z0.0_tiff.gif')) and \ + assert (s_opathfile.endswith('output_2d/conc_oxygen_z0.0/conc_oxygen_z0.0_tiff.gif')) and \ (os.path.exists(s_opathfile)) shutil.rmtree(s_path) + # bue 20250107: broken by Ignoring class TestPyCliMakeMove(object): ''' tests for one pcdl.pyCli function. ''' @@ -1986,33 +2061,33 @@ class TestPyCliMakeMove(object): def test_pcdl_make_movie_timeseries_default(self): s_path = subprocess.run(['pcdl_plot_scatter', s_path_2d], check=False, capture_output=True) - s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','') + s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','').split('Ignoring fixed x limits to fulfill fixed data aspect with adjustable data limits.')[-1] s_result = subprocess.run(['pcdl_make_movie', s_path], check=False, capture_output=True) - #print(f'\ns_result.stdout: {s_result.stdout}\n') - #print(f'\ns_result.stderr: {s_result.stderr}\n') + print(f'\ns_result.stdout: {s_result.stdout}\n') + print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').split('\n')[-2] - assert (s_opathfile.endswith('data_timeseries_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg12.mp4')) and \ + assert (s_opathfile.endswith('output_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg12.mp4')) and \ (os.path.exists(s_opathfile)) shutil.rmtree(s_path) def test_pcdl_make_movie_timeseries_interface(self): s_path = subprocess.run(['pcdl_plot_contour', s_path_2d, 'oxygen', '--ext', 'tiff'], check=False, capture_output=True) - s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','') + s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','').split('Ignoring fixed x limits to fulfill fixed data aspect with adjustable data limits.')[-1] s_result = subprocess.run(['pcdl_make_movie', s_path, 'tiff'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').split('\n')[-2] - assert (s_opathfile.endswith('data_timeseries_2d/conc_oxygen_z0.0/conc_oxygen_z0.0_tiff12.mp4')) and \ + assert (s_opathfile.endswith('output_2d/conc_oxygen_z0.0/conc_oxygen_z0.0_tiff12.mp4')) and \ (os.path.exists(s_opathfile)) shutil.rmtree(s_path) def test_pcdl_make_movie_timeseries_farme(self): s_path = subprocess.run(['pcdl_plot_contour', s_path_2d, 'oxygen', '--ext', 'jpeg'], check=False, capture_output=True) - s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','') + s_path = s_path.stderr.decode('UTF8').replace('\r','').replace('\n','').split('Ignoring fixed x limits to fulfill fixed data aspect with adjustable data limits.')[-1] s_result = subprocess.run(['pcdl_make_movie', s_path, '--framerate', '9'], check=False, capture_output=True) #print(f'\ns_result.stdout: {s_result.stdout}\n') #print(f'\ns_result.stderr: {s_result.stderr}\n') s_opathfile = s_result.stderr.decode('UTF8').replace('\r','').split('\n')[-2] - assert (s_opathfile.endswith('data_timeseries_2d/conc_oxygen_z0.0/conc_oxygen_z0.0_jpeg9.mp4')) and \ + assert (s_opathfile.endswith('output_2d/conc_oxygen_z0.0/conc_oxygen_z0.0_jpeg9.mp4')) and \ (os.path.exists(s_opathfile)) shutil.rmtree(s_path) diff --git a/test/test_timeseries_2d.py b/test/test_timeseries_2d.py index c6a30b0..5dff0da 100644 --- a/test/test_timeseries_2d.py +++ b/test/test_timeseries_2d.py @@ -24,11 +24,12 @@ import os import pathlib import pcdl +import pytest import shutil # const -s_path_2d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_2d') +s_path_2d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_2d') ## download test data ## @@ -52,7 +53,7 @@ def test_mcdsts_make_gif_jpeg(self, mcdsts=mcdsts): ) assert(str(type(mcdsts)) == "") and \ (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg.gif')) + (s_opathfile.endswith('pcdl/output_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg.gif')) #os.remove(s_opathfile) shutil.rmtree(s_opath) @@ -65,7 +66,7 @@ def test_mcdsts_make_gif_tiff(self, mcdsts=mcdsts): ) assert(str(type(mcdsts)) == "") and \ (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_tiff.gif')) + (s_opathfile.endswith('pcdl/output_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_tiff.gif')) #os.remove(s_opathfile) shutil.rmtree(s_opath) @@ -80,7 +81,7 @@ def test_mcdsts_make_movie_jpeg12(self, mcdsts=mcdsts): ) assert(str(type(mcdsts)) == "") and \ (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg12.mp4')) + (s_opathfile.endswith('pcdl/output_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg12.mp4')) #os.remove(s_opathfile) shutil.rmtree(s_opath) @@ -94,7 +95,7 @@ def test_mcdsts_make_movie_tiff12(self, mcdsts=mcdsts): ) assert(str(type(mcdsts)) == "") and \ (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_tiff12.mp4')) + (s_opathfile.endswith('pcdl/output_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_tiff12.mp4')) #os.remove(s_opathfile) shutil.rmtree(s_opath) @@ -108,7 +109,7 @@ def test_mcdsts_make_movie_jpeg6(self, mcdsts=mcdsts): ) assert(str(type(mcdsts)) == "") and \ (os.path.exists(s_opathfile)) and \ - (s_opathfile.endswith('pcdl/data_timeseries_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg6.mp4')) + (s_opathfile.endswith('pcdl/output_2d/cell_cell_type_z0.0/cell_cell_type_z0.0_jpeg6.mp4')) #os.remove(s_opathfile) shutil.rmtree(s_opath) @@ -189,14 +190,14 @@ def test_mcdsts_get_conc_df(self, mcdsts=mcdsts): (str(type(ldf_conc)) == "") and \ (str(type(ldf_conc[0])) == "") and \ (ldf_conc[0].shape == (121, 9)) and \ - (ldf_conc[-1].shape == (121, 10)) and \ + (ldf_conc[-1].shape == (121, 11)) and \ (len(ldf_conc) == 25) def test_mcdsts_get_conc_df_collapse(self, mcdsts=mcdsts): df_conc = mcdsts.get_conc_df(values=2, drop=set(), keep=set(), collapse=True) assert(str(type(mcdsts)) == "") and \ (str(type(df_conc)) == "") and \ - (df_conc.shape == (3025, 10)) + (df_conc.shape == (3025, 11)) def test_mcdsts_get_conc_attribute(self, mcdsts=mcdsts): dl_conc = mcdsts.get_conc_attribute(values=1, drop=set(), keep=set(), allvalues=False) @@ -204,7 +205,7 @@ def test_mcdsts_get_conc_attribute(self, mcdsts=mcdsts): (str(type(dl_conc)) == "") and \ (str(type(dl_conc['oxygen'])) == "") and \ (str(type(dl_conc['oxygen'][0])) == "") and \ - (len(dl_conc.keys()) == 1) and \ + (len(dl_conc.keys()) == 2) and \ (len(dl_conc['oxygen']) == 2) def test_mcdsts_get_conc_attribute_values(self, mcdsts=mcdsts): @@ -213,7 +214,7 @@ def test_mcdsts_get_conc_attribute_values(self, mcdsts=mcdsts): (str(type(dl_conc)) == "") and \ (str(type(dl_conc['oxygen'])) == "") and \ (str(type(dl_conc['oxygen'][0])) == "") and \ - (len(dl_conc.keys()) == 1) and \ + (len(dl_conc.keys()) == 2) and \ (len(dl_conc['oxygen']) == 2) def test_mcdsts_get_conc_attribute_allvalues(self, mcdsts=mcdsts): @@ -222,7 +223,7 @@ def test_mcdsts_get_conc_attribute_allvalues(self, mcdsts=mcdsts): (str(type(dl_conc)) == "") and \ (str(type(dl_conc['oxygen'])) == "") and \ (str(type(dl_conc['oxygen'][0])) == "") and \ - (len(dl_conc.keys()) == 1) and \ + (len(dl_conc.keys()) == 2) and \ (len(dl_conc['oxygen']) > 2) ## plot_contour command ## @@ -244,16 +245,17 @@ def test_mcdsts_plot_contour_if(self, mcdsts=mcdsts): figbgcolor = None, # test if ) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].replace('\\','/').endswith('/pcdl/data_timeseries_2d/conc_oxygen_z0.0/output00000000_oxygen.jpeg')) and \ + (ls_pathfile[0].replace('\\','/').endswith('/pcdl/output_2d/conc_oxygen_z0.0/output00000000_oxygen.jpeg')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and \ - (ls_pathfile[-1].replace('\\','/').endswith('/pcdl/data_timeseries_2d/conc_oxygen_z0.0/output00000024_oxygen.jpeg')) and \ + (ls_pathfile[-1].replace('\\','/').endswith('/pcdl/output_2d/conc_oxygen_z0.0/output00000024_oxygen.jpeg')) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[-1]) > 2**10) and \ (len(ls_pathfile) == 25) for s_pathfile in ls_pathfile: os.remove(s_pathfile) + @pytest.mark.filterwarnings("ignore:More than 20 figures have been opened.") def test_mcdsts_plot_contour_else(self, mcdsts=mcdsts): l_fig = mcdsts.plot_contour( focus = 'oxygen', @@ -278,10 +280,10 @@ def test_mcdsts_plot_contour_else(self, mcdsts=mcdsts): plt.close() def test_mcdsts_make_conc_vtk(self, mcdsts=mcdsts): - ls_pathfile = mcdsts.make_conc_vtk() + ls_pathfile = mcdsts.make_conc_vtk(visualize=False) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_2d/output00000000_conc.vtr')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_2d/output00000024_conc.vtr')) and \ + (ls_pathfile[0].endswith('/pcdl/output_2d/output00000000_conc.vtr')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_2d/output00000024_conc.vtr')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and\ @@ -302,15 +304,18 @@ def test_mcdsts_get_cell_df(self, mcdsts=mcdsts): assert(str(type(mcdsts)) == "") and \ (str(type(ldf_cell)) == "") and \ (str(type(ldf_cell[0])) == "") and \ - (ldf_cell[0].shape == (889, 19)) and \ - (ldf_cell[-1].shape == (1099, 40)) and \ + (ldf_cell[0].shape[0] > 9) and \ + (ldf_cell[0].shape[1] == 36) and \ + (ldf_cell[-1].shape[0] > 9) and \ + (ldf_cell[-1].shape[1] == 66) and \ (len(ldf_cell) == 25) def test_mcdsts_get_cell_df_collapse(self, mcdsts=mcdsts): df_cell = mcdsts.get_cell_df(values=2, drop=set(), keep=set(), collapse=True) assert(str(type(mcdsts)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (24758, 41)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 67) def test_mcdsts_get_cell_attribute(self, mcdsts=mcdsts): dl_cell = mcdsts.get_cell_attribute(values=1, drop=set(), keep=set(), allvalues=False) @@ -324,17 +329,17 @@ def test_mcdsts_get_cell_attribute(self, mcdsts=mcdsts): (str(type(dl_cell['cell_density_micron3'][0])) == "") and \ (str(type(dl_cell['cell_type'])) == "") and \ (str(type(dl_cell['cell_type'][0])) == "") and \ - (len(dl_cell.keys()) == 83) and \ + (len(dl_cell.keys()) == 110) and \ (len(dl_cell['dead']) == 2) and \ (len(dl_cell['cell_count_voxel']) == 2) and \ (len(dl_cell['cell_density_micron3']) == 2) and \ - (len(dl_cell['cell_type']) == 1) + (len(dl_cell['cell_type']) == 2) def test_mcdsts_get_cell_attribute_values(self, mcdsts=mcdsts): dl_cell = mcdsts.get_cell_attribute(values=2, drop=set(), keep=set(), allvalues=False) assert(str(type(mcdsts)) == "") and \ (str(type(dl_cell)) == "") and \ - (len(dl_cell.keys()) == 28) + (len(dl_cell.keys()) == 54) def test_mcdsts_get_cell_attribute_allvalues(self, mcdsts=mcdsts): dl_cell = mcdsts.get_cell_attribute(values=1, drop=set(), keep=set(), allvalues=True) @@ -348,11 +353,11 @@ def test_mcdsts_get_cell_attribute_allvalues(self, mcdsts=mcdsts): (str(type(dl_cell['cell_density_micron3'][0])) == "") and \ (str(type(dl_cell['cell_type'])) == "") and \ (str(type(dl_cell['cell_type'][0])) == "") and \ - (len(dl_cell.keys()) == 83) and \ + (len(dl_cell.keys()) == 110) and \ (len(dl_cell['dead']) == 2) and \ (len(dl_cell['cell_count_voxel']) > 2) and \ (len(dl_cell['cell_density_micron3']) > 2) and \ - (len(dl_cell['cell_type']) == 1) + (len(dl_cell['cell_type']) == 2) ## plot_scatter command ## def test_mcdsts_plot_scatter_num(self, mcdsts=mcdsts): @@ -374,10 +379,10 @@ def test_mcdsts_plot_scatter_num(self, mcdsts=mcdsts): figbgcolor = None, # test if ) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].replace('\\','/').endswith('/pcdl/data_timeseries_2d/cell_pressure_z0.0/output00000000_pressure.jpeg')) and \ + (ls_pathfile[0].replace('\\','/').endswith('/pcdl/output_2d/cell_pressure_z0.0/output00000000_pressure.jpeg')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and \ - (ls_pathfile[-1].replace('\\','/').endswith('/pcdl/data_timeseries_2d/cell_pressure_z0.0/output00000024_pressure.jpeg')) and \ + (ls_pathfile[-1].replace('\\','/').endswith('/pcdl/output_2d/cell_pressure_z0.0/output00000024_pressure.jpeg')) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[-1]) > 2**10) and \ (len(ls_pathfile) == 25) @@ -411,8 +416,8 @@ def test_mcdsts_plot_scatter_cat(self, mcdsts=mcdsts): def test_mcdsts_make_cell_vtk(self, mcdsts=mcdsts): ls_pathfile = mcdsts.make_cell_vtk(visualize=False) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_2d/output00000000_cell.vtp')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_2d/output00000024_cell.vtp')) and \ + (ls_pathfile[0].endswith('/pcdl/output_2d/output00000000_cell.vtp')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_2d/output00000024_cell.vtp')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and\ @@ -431,8 +436,8 @@ class TestPyMcdsGraph(object): def test_mcdsts_get_graph_gml_attached_defaultattr(self, mcdsts=mcdsts): ls_pathfile = mcdsts.make_graph_gml(graph_type='attached', edge_attribute=True, node_attribute=[]) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_2d/output00000000_attached.gml')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_2d/output00000024_attached.gml')) and \ + (ls_pathfile[0].endswith('/pcdl/output_2d/output00000000_attached.gml')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_2d/output00000024_attached.gml')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (len(ls_pathfile) == 25) @@ -442,8 +447,8 @@ def test_mcdsts_get_graph_gml_attached_defaultattr(self, mcdsts=mcdsts): def test_mcdsts_get_graph_gml_neighbor_noneattr(self, mcdsts=mcdsts): ls_pathfile = mcdsts.make_graph_gml(graph_type='neighbor', edge_attribute=False, node_attribute=[]) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_pathfile[0].endswith('/pcdl/output_2d/output00000000_neighbor.gml')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (len(ls_pathfile) == 25) @@ -453,8 +458,8 @@ def test_mcdsts_get_graph_gml_neighbor_noneattr(self, mcdsts=mcdsts): def test_mcdsts_get_graph_gml_neighbor_allattr(self, mcdsts=mcdsts): ls_pathfile = mcdsts.make_graph_gml(graph_type='neighbor', edge_attribute=True, node_attribute=['dead','cell_count_voxel','cell_density_micron3','cell_type']) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_2d/output00000000_neighbor.gml')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_2d/output00000024_neighbor.gml')) and \ + (ls_pathfile[0].endswith('/pcdl/output_2d/output00000000_neighbor.gml')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (len(ls_pathfile) == 25) @@ -468,29 +473,29 @@ class TestPyMcdsOmeTiff(object): ## ome tiff related functions ## def test_mcdsts_make_ome_tiff_defaultattr_00(self, mcdsts=mcdsts): - la_ometiff = mcdsts.make_ome_tiff(cell_attribute='ID', file=False, collapse=False) + la_ometiff = mcdsts.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=False, collapse=False) assert(str(type(mcdsts)) == "") and \ (type(la_ometiff) is list) and \ (type(la_ometiff[0]) is np.ndarray) and \ (type(la_ometiff[-1]) is np.ndarray) and \ - (la_ometiff[0].dtype == float) and \ - (la_ometiff[-1].dtype == float) and \ - (la_ometiff[0].shape == (2, 1, 200, 300)) and \ - (la_ometiff[-1].shape == (2, 1, 200, 300)) and \ + (la_ometiff[0].dtype == np.float32) and \ + (la_ometiff[-1].dtype == np.float32) and \ + (la_ometiff[0].shape == (4, 1, 200, 300)) and \ + (la_ometiff[-1].shape == (4, 1, 200, 300)) and \ (len(la_ometiff) == 25) def test_mcdsts_make_ome_tiff_defaultattr_01(self, mcdsts=mcdsts): - a_ometiff = mcdsts.make_ome_tiff(cell_attribute='ID', file=False, collapse=True) + a_ometiff = mcdsts.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=False, collapse=True) assert(str(type(mcdsts)) == "") and \ (type(a_ometiff) is np.ndarray) and \ - (a_ometiff.dtype == float) and \ - (a_ometiff.shape == (25, 2, 1, 200, 300)) + (a_ometiff.dtype == np.float32) and \ + (a_ometiff.shape == (25, 4, 1, 200, 300)) def test_mcdsts_make_ome_tiff_defaultattr_10(self, mcdsts=mcdsts): - ls_pathfile = mcdsts.make_ome_tiff(cell_attribute='ID', file=True, collapse=False) + ls_pathfile = mcdsts.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=True, collapse=False) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_2d/output00000000_ID.ome.tiff')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_2d/output00000024_ID.ome.tiff')) and \ + (ls_pathfile[0].endswith('pcdl/output_2d/output00000000_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ + (ls_pathfile[-1].endswith('pcdl/output_2d/output00000024_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and\ @@ -500,9 +505,9 @@ def test_mcdsts_make_ome_tiff_defaultattr_10(self, mcdsts=mcdsts): os.remove(s_pathfile) def test_mcdsts_make_ome_tiff_defaultattr_11(self, mcdsts=mcdsts): - s_pathfile = mcdsts.make_ome_tiff(cell_attribute='ID', file=True, collapse=True) + s_pathfile = mcdsts.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=True, collapse=True) assert(str(type(mcdsts)) == "") and \ - (s_pathfile.endswith('/pcdl/data_timeseries_2d/timeseries_ID.ome.tiff')) and \ + (s_pathfile.endswith('pcdl/output_2d/timeseries_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10 ) os.remove(s_pathfile) @@ -543,7 +548,7 @@ def test_mcdsts_plot_timeseries_none_none_none_cell_ax_jpeg(self, mcdsts=mcdsts) figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (s_pathfile.endswith('/pcdl/data_timeseries_2d/timeseries_cell_total_count.jpeg')) and \ + (s_pathfile.endswith('/pcdl/output_2d/timeseries_cell_total_count.jpeg')) and \ (os.path.exists(s_pathfile)) os.remove(s_pathfile) @@ -665,7 +670,7 @@ def test_mcdsts_plot_timeseries_none_none_none_conc_ax_jpeg(self, mcdsts=mcdsts) figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (s_pathfile.endswith('/pcdl/data_timeseries_2d/timeseries_conc_total_count.jpeg')) and \ + (s_pathfile.endswith('/pcdl/output_2d/timeseries_conc_total_count.jpeg')) and \ (os.path.exists(s_pathfile)) os.remove(s_pathfile) plt.close() diff --git a/test/test_timeseries_3d.py b/test/test_timeseries_3d.py index 56aecb7..aad5a2a 100644 --- a/test/test_timeseries_3d.py +++ b/test/test_timeseries_3d.py @@ -28,7 +28,7 @@ # const -s_path_3d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_3d') +s_path_3d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_3d') ## download test data ## @@ -172,10 +172,10 @@ def test_mcdsts_plot_contour_if(self, mcdsts=mcdsts): figbgcolor = None, # test if ) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].replace('\\','/').endswith('/pcdl/data_timeseries_3d/conc_oxygen_z-5.0/output00000000_oxygen.jpeg')) and \ + (ls_pathfile[0].replace('\\','/').endswith('/pcdl/output_3d/conc_oxygen_z-5.0/output00000000_oxygen.jpeg')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and \ - (ls_pathfile[-1].replace('\\','/').endswith('/pcdl/data_timeseries_3d/conc_oxygen_z-5.0/output00000024_oxygen.jpeg')) and \ + (ls_pathfile[-1].replace('\\','/').endswith('/pcdl/output_3d/conc_oxygen_z-5.0/output00000024_oxygen.jpeg')) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[-1]) > 2**10) and \ (len(ls_pathfile) == 25) @@ -207,10 +207,10 @@ def test_mcdsts_plot_contour_else(self, mcdsts=mcdsts): def test_mcdsts_make_conc_vtk(self, mcdsts=mcdsts): - ls_pathfile = mcdsts.make_conc_vtk() + ls_pathfile = mcdsts.make_conc_vtk(visualize=False) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_3d/output00000000_conc.vtr')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_3d/output00000024_conc.vtr')) and \ + (ls_pathfile[0].endswith('/pcdl/output_3d/output00000000_conc.vtr')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_3d/output00000024_conc.vtr')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and\ @@ -231,15 +231,18 @@ def test_mcdsts_get_cell_df(self, mcdsts=mcdsts): assert(str(type(mcdsts)) == "") and \ (str(type(ldf_cell)) == "") and \ (str(type(ldf_cell[0])) == "") and \ - (ldf_cell[0].shape == (18317, 19)) and \ - (ldf_cell[-1].shape == (20460,33)) and \ + (ldf_cell[0].shape[0] > 9) and \ + (ldf_cell[0].shape[1] == 40) and \ + (ldf_cell[-1].shape[0] > 9) and \ + (ldf_cell[-1].shape[1] == 72) and \ (len(ldf_cell) == 25) def test_mcdsts_get_cell_df_collapse(self, mcdsts=mcdsts): df_cell = mcdsts.get_cell_df(values=2, drop=set(), keep=set(), collapse=True) assert(str(type(mcdsts)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (481651, 34)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 73) def test_mcdsts_get_cell_attribute(self, mcdsts=mcdsts): dl_cell = mcdsts.get_cell_attribute(values=1, drop=set(), keep=set(), allvalues=False) @@ -253,17 +256,17 @@ def test_mcdsts_get_cell_attribute(self, mcdsts=mcdsts): (str(type(dl_cell['cell_density_micron3'][0])) == "") and \ (str(type(dl_cell['cell_type'])) == "") and \ (str(type(dl_cell['cell_type'][0])) == "") and \ - (len(dl_cell.keys()) == 106) and \ - (len(dl_cell['dead']) == 1) and \ + (len(dl_cell.keys()) == 110) and \ + (len(dl_cell['dead']) == 2) and \ (len(dl_cell['cell_count_voxel']) == 2) and \ (len(dl_cell['cell_density_micron3']) == 2) and \ - (len(dl_cell['cell_type']) == 1) + (len(dl_cell['cell_type']) == 2) def test_mcdsts_get_cell_attribute_values(self, mcdsts=mcdsts): dl_cell = mcdsts.get_cell_attribute(values=2, drop=set(), keep=set(), allvalues=False) assert(str(type(mcdsts)) == "") and \ (str(type(dl_cell)) == "") and \ - (len(dl_cell.keys()) == 21) + (len(dl_cell.keys()) == 60) def test_mcdsts_get_cell_attribute_allvalues(self, mcdsts=mcdsts): dl_cell = mcdsts.get_cell_attribute(values=1, drop=set(), keep=set(), allvalues=True) @@ -277,11 +280,11 @@ def test_mcdsts_get_cell_attribute_allvalues(self, mcdsts=mcdsts): (str(type(dl_cell['cell_density_micron3'][0])) == "") and \ (str(type(dl_cell['cell_type'])) == "") and \ (str(type(dl_cell['cell_type'][0])) == "") and \ - (len(dl_cell.keys()) == 106) and \ - (len(dl_cell['dead']) == 1) and \ + (len(dl_cell.keys()) == 110) and \ + (len(dl_cell['dead']) == 2) and \ (len(dl_cell['cell_count_voxel']) > 2) and \ (len(dl_cell['cell_density_micron3']) > 2) and \ - (len(dl_cell['cell_type']) == 1) + (len(dl_cell['cell_type']) == 2) ## plot_scatter command ## def test_mcdsts_plot_scatter_num(self, mcdsts=mcdsts): @@ -303,10 +306,10 @@ def test_mcdsts_plot_scatter_num(self, mcdsts=mcdsts): figbgcolor = None, # test if ) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].replace('\\','/').endswith('/pcdl/data_timeseries_3d/cell_pressure_z-5.0/output00000000_pressure.jpeg')) and \ + (ls_pathfile[0].replace('\\','/').endswith('/pcdl/output_3d/cell_pressure_z-5.0/output00000000_pressure.jpeg')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and \ - (ls_pathfile[-1].replace('\\','/').endswith('/pcdl/data_timeseries_3d/cell_pressure_z-5.0/output00000024_pressure.jpeg')) and \ + (ls_pathfile[-1].replace('\\','/').endswith('/pcdl/output_3d/cell_pressure_z-5.0/output00000024_pressure.jpeg')) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[-1]) > 2**10) and \ (len(ls_pathfile) == 25) @@ -340,8 +343,8 @@ def test_mcdsts_plot_scatter_cat(self, mcdsts=mcdsts): def test_mcdsts_make_cell_vtk(self, mcdsts=mcdsts): ls_pathfile = mcdsts.make_cell_vtk(visualize=False) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_3d/output00000000_cell.vtp')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_3d/output00000024_cell.vtp')) and \ + (ls_pathfile[0].endswith('/pcdl/output_3d/output00000000_cell.vtp')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_3d/output00000024_cell.vtp')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (os.path.getsize(ls_pathfile[0]) > 2**10) and\ @@ -360,8 +363,8 @@ class TestPyMcds3DGraph(object): def test_mcdsts_get_graph_gml_attached_defaultattr(self, mcdsts=mcdsts): ls_pathfile = mcdsts.make_graph_gml(graph_type='attached', edge_attribute=True, node_attribute=[]) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_3d/output00000000_attached.gml')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_3d/output00000024_attached.gml')) and \ + (ls_pathfile[0].endswith('/pcdl/output_3d/output00000000_attached.gml')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_3d/output00000024_attached.gml')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (len(ls_pathfile) == 25) @@ -371,8 +374,8 @@ def test_mcdsts_get_graph_gml_attached_defaultattr(self, mcdsts=mcdsts): def test_mcdsts_get_graph_gml_neighbor_noneattr(self, mcdsts=mcdsts): ls_pathfile = mcdsts.make_graph_gml(graph_type='neighbor', edge_attribute=False, node_attribute=[]) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_3d/output00000000_neighbor.gml')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_3d/output00000024_neighbor.gml')) and \ + (ls_pathfile[0].endswith('/pcdl/output_3d/output00000000_neighbor.gml')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_3d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (len(ls_pathfile) == 25) @@ -382,8 +385,8 @@ def test_mcdsts_get_graph_gml_neighbor_noneattr(self, mcdsts=mcdsts): def test_mcdsts_get_graph_gml_neighbor_allattr(self, mcdsts=mcdsts): ls_pathfile = mcdsts.make_graph_gml(graph_type='neighbor', edge_attribute=True, node_attribute=['dead','cell_count_voxel','cell_density_micron3','cell_type']) assert(str(type(mcdsts)) == "") and \ - (ls_pathfile[0].endswith('/pcdl/data_timeseries_3d/output00000000_neighbor.gml')) and \ - (ls_pathfile[-1].endswith('/pcdl/data_timeseries_3d/output00000024_neighbor.gml')) and \ + (ls_pathfile[0].endswith('/pcdl/output_3d/output00000000_neighbor.gml')) and \ + (ls_pathfile[-1].endswith('/pcdl/output_3d/output00000024_neighbor.gml')) and \ (os.path.exists(ls_pathfile[0])) and \ (os.path.exists(ls_pathfile[-1])) and \ (len(ls_pathfile) == 25) @@ -397,22 +400,22 @@ class TestPyMcds3DGraph(object): ## graph related functions ## def test_mcdsts_make_ome_tiff_defaultattr_00(self, mcdsts=mcdsts): - la_ometiff = mcdsts.make_ome_tiff(cell_attribute='ID', file=False, collapse=False) + la_ometiff = mcdsts.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=False, collapse=False) assert(str(type(mcdsts)) == "") and \ (type(la_ometiff) is list) and \ (type(la_ometiff[0]) is np.ndarray) and \ (type(la_ometiff[-1]) is np.ndarray) and \ - (la_ometiff[0].dtype == float) and \ - (la_ometiff[-1].dtype == float) and \ + (la_ometiff[0].dtype == np.float32) and \ + (la_ometiff[-1].dtype == np.float32) and \ (la_ometiff[0].shape == (4, 11, 200, 300)) and \ (la_ometiff[-1].shape == (4, 11, 200, 300)) and \ (len(la_ometiff) == 25) def test_mcdsts_make_ome_tiff_defaultattr_01(self, mcdsts=mcdsts): - a_ometiff = mcdsts.make_ome_tiff(cell_attribute='ID', file=False, collapse=True) + a_ometiff = mcdsts.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=False, collapse=True) assert(str(type(mcdsts)) == "") and \ (type(a_ometiff) is np.ndarray) and \ - (a_ometiff.dtype == float) and \ + (a_ometiff.dtype == np.float32) and \ (a_ometiff.shape == (25, 4, 11, 200, 300)) @@ -451,7 +454,7 @@ def test_mcdsts_plot_timeseries_none_none_none_cell_ax_jpeg(self, mcdsts=mcdsts) figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (s_pathfile.endswith('/pcdl/data_timeseries_3d/timeseries_cell_total_count.jpeg')) and \ + (s_pathfile.endswith('/pcdl/output_3d/timeseries_cell_total_count.jpeg')) and \ (os.path.exists(s_pathfile)) os.remove(s_pathfile) @@ -573,7 +576,7 @@ def test_mcdsts_plot_timeseries_none_none_none_conc_ax_jpeg(self, mcdsts=mcdsts) figbgcolor = None # test if ) assert(str(type(mcdsts)) == "") and \ - (s_pathfile.endswith('/pcdl/data_timeseries_3d/timeseries_conc_total_count.jpeg')) and \ + (s_pathfile.endswith('/pcdl/output_3d/timeseries_conc_total_count.jpeg')) and \ (os.path.exists(s_pathfile)) os.remove(s_pathfile) plt.close() diff --git a/test/test_timestep_2d.py b/test/test_timestep_2d.py index f8e9820..92182bf 100644 --- a/test/test_timestep_2d.py +++ b/test/test_timestep_2d.py @@ -27,7 +27,7 @@ # const -s_path_2d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_2d') +s_path_2d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_2d') s_file_2d = 'output00000024.xml' s_pathfile_2d = f'{s_path_2d}/{s_file_2d}' @@ -46,14 +46,15 @@ class TestPyMcdsInit(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 95)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ - (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 1099) and \ - (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 1099) + (len(mcds.data['discrete_cells']['graph']['attached_cells']) > 9) and \ + (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) > 9) def test_mcds_init_physiboss(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -62,8 +63,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'cancer_cell_attack_rates'})) and \ - (df_cell.shape == (1099, 95)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) class TestPyMcdsInitMicroenvFalse(object): @@ -73,14 +75,15 @@ class TestPyMcdsInitMicroenvFalse(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 92)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 116) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ - (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 1099) and \ - (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 1099) + (len(mcds.data['discrete_cells']['graph']['attached_cells']) > 9) and \ + (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) > 9) def test_mcds_init_physiboss(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -89,8 +92,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'cancer_cell_attack_rates'})) and \ - (df_cell.shape == (1099, 92)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 116) class TestPyMcdsInitGraphFalse(object): @@ -100,7 +104,8 @@ class TestPyMcdsInitGraphFalse(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 95)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -116,8 +121,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'cancer_cell_attack_rates'})) and \ - (df_cell.shape == (1099, 95)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) class TestPyMcdsInitPhysibossFalse(object): @@ -127,14 +133,15 @@ class TestPyMcdsInitPhysibossFalse(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 95)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ - (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 1099) and \ - (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 1099) + (len(mcds.data['discrete_cells']['graph']['attached_cells']) > 9) and \ + (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) > 9) def test_mcds_init_physiboss(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -143,8 +150,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'cancer_cell_attack_rates'})) and \ - (df_cell.shape == (1099, 95)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) class TestPyMcdsInitSettingxmlFalse(object): @@ -154,14 +162,15 @@ class TestPyMcdsInitSettingxmlFalse(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 95)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ - (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 1099) and \ - (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 1099) + (len(mcds.data['discrete_cells']['graph']['attached_cells']) > 9) and \ + (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) > 9) def test_mcds_init_physiboss(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -170,8 +179,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'0_attack_rates'})) and \ - (df_cell.shape == (1099, 95)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) class TestPyMcdsInitSettingxmlNone(object): @@ -181,14 +191,15 @@ class TestPyMcdsInitSettingxmlNone(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 95)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ - (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 1099) and \ - (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 1099) + (len(mcds.data['discrete_cells']['graph']['attached_cells']) > 9) and \ + (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) > 9) def test_mcds_init_physiboss(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -197,8 +208,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'0_attack_rates'})) and \ - (df_cell.shape == (1099, 95)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) class TestPyMcdsInitVerboseTrue(object): @@ -245,13 +257,13 @@ def test_mcds_get_physicell_version(self, mcds=mcds): s_pcversion = mcds.get_physicell_version() assert(str(type(mcds)) == "") and \ (str(type(s_pcversion)) == "") and \ - (s_pcversion == 'PhysiCell_1.10.4') + (s_pcversion == 'PhysiCell_1.14.1') def test_mcds_get_timestamp(self, mcds=mcds): s_timestamp = mcds.get_timestamp() assert(str(type(mcds)) == "") and \ (str(type(s_timestamp)) == "") and \ - (s_timestamp == '2022-10-19T01:12:20Z') + (s_timestamp == '2025-01-05T08:08:22Z') def test_mcds_get_time(self, mcds=mcds): r_time = mcds.get_time() @@ -263,7 +275,7 @@ def test_mcds_get_runtime(self, mcds=mcds): r_runtime = mcds.get_runtime() assert(str(type(mcds)) == "") and \ (str(type(r_runtime)) == "") and \ - (r_runtime == 35.033598) + (r_runtime == 1.952156) ## setting related functions ## @@ -276,8 +288,8 @@ def test_mcds_get_unit_dict(self, mcds=mcds): ds_unit = mcds.get_unit_dict() assert(str(type(mcds)) == "") and \ (str(type(ds_unit)) == "") and \ - (len(ds_unit) == 82) and \ - (ds_unit['oxygen'] == 'mmHg') + (len(ds_unit) == 108) and \ + (ds_unit['oxygen'] == 'dimensionless') ## mesh related functions ## @@ -439,20 +451,20 @@ def test_mcds_get_substrate_name(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(ls_substrate)) == "") and \ (str(type(ls_substrate[0])) == "") and \ - (ls_substrate == ['oxygen']) + (ls_substrate == ['oxygen','water']) def test_mcds_get_substrate_dict(self, mcds=mcds): ds_substrate = mcds.get_substrate_dict() assert(str(type(mcds)) == "") and \ (str(type(ds_substrate)) == "") and \ (str(type(ds_substrate['0'])) == "") and \ - (len(ds_substrate) == 1) + (len(ds_substrate) == 2) def test_mcds_get_substrate_df(self, mcds=mcds): df_substrate = mcds.get_substrate_df() assert(str(type(mcds)) == "") and \ (str(type(df_substrate)) == "") and \ - (df_substrate.shape == (1, 2)) + (df_substrate.shape == (2, 2)) def test_mcds_get_concentration_zslice_none(self, mcds=mcds): ar_conc = mcds.get_concentration(substrate='oxygen', z_slice=None) @@ -480,7 +492,7 @@ def test_mcds_get_concentration_at_inmeash(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(ar_conc)) == "") and \ (ar_conc.dtype == np.float64) and \ - (ar_conc.shape == (1,)) + (ar_conc.shape == (2,)) def test_mcds_get_concentration_at_notinmeash(self, mcds=mcds): ar_conc = mcds.get_concentration_at(x=-31, y=-21, z=-6) @@ -491,31 +503,31 @@ def test_mcds_get_conc_df(self, mcds=mcds): df_conc = mcds.get_conc_df(z_slice=None, halt=False, values=1, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_conc)) == "") and \ - (df_conc.shape == (121, 10)) + (df_conc.shape == (121, 11)) def test_mcds_get_conc_df_zslice_center(self, mcds=mcds): df_conc = mcds.get_conc_df(z_slice=0, halt=False, values=1, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_conc)) == "") and \ - (df_conc.shape == (121, 10)) + (df_conc.shape == (121, 11)) def test_mcds_get_conc_df_zslice_outofcenter(self, mcds=mcds): df_conc = mcds.get_conc_df(z_slice=-6, halt=False, values=1, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_conc)) == "") and \ - (df_conc.shape == (121, 10)) + (df_conc.shape == (121, 11)) def test_mcds_get_conc_df_values(self, mcds=mcds): df_conc = mcds.get_conc_df(z_slice=None, halt=False, values=2, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_conc)) == "") and \ - (df_conc.shape == (121, 10)) + (df_conc.shape == (121, 11)) def test_mcds_get_conc_df_drop(self, mcds=mcds): df_conc = mcds.get_conc_df(z_slice=None, halt=False, values=1, drop={'oxygen'}, keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_conc)) == "") and \ - (df_conc.shape == (121, 9)) + (df_conc.shape == (121, 10)) def test_mcds_get_conc_df_keep(self, mcds=mcds): df_conc = mcds.get_conc_df(z_slice=None, halt=False, values=1, drop=set(), keep={'oxygen'}) @@ -567,15 +579,15 @@ def test_mcds_plot_contourf(self, mcds=mcds): figbgcolor = 'yellow', # jump over if ) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_2d/conc_oxygen_z0/output00000024_oxygen.tiff')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_2d/conc_oxygen_z0/output00000024_oxygen.tiff')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) def test_mcds_make_conc_vtk(self, mcds=mcds): - s_pathfile = mcds.make_conc_vtk() + s_pathfile = mcds.make_conc_vtk(visualize=False) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_2d/output00000024_conc.vtr')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_2d/output00000024_conc.vtr')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -591,44 +603,49 @@ def test_mcds_get_celltype_list(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(ls_celltype)) == "") and \ (str(type(ls_celltype[0])) == "") and \ - (len(ls_celltype) == 1) + (len(ls_celltype) == 2) def test_mcds_get_celltype_dict(self, mcds=mcds): ds_celltype = mcds.get_celltype_dict() assert(str(type(mcds)) == "") and \ (str(type(ds_celltype)) == "") and \ (str(type(ds_celltype['0'])) == "") and \ - (len(ds_celltype) == 1) + (len(ds_celltype) == 2) def test_mcds_get_cell_df(self, mcds=mcds): df_cell = mcds.get_cell_df(values=1, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 95)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_get_cell_df_values(self, mcds=mcds): df_cell = mcds.get_cell_df(values=2, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 40)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 66) def test_mcds_get_cell_df_drop(self, mcds=mcds): df_cell = mcds.get_cell_df(values=1, drop={'oxygen'}, keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 94)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 121) def test_mcds_get_cell_df_keep(self, mcds=mcds): df_cell = mcds.get_cell_df(values=1, drop=set(), keep={'oxygen'}) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (1099, 13)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 13) def test_mcds_get_cell_df_at_inmeash(self, mcds=mcds): df_cell = mcds.get_cell_df_at(x=0, y=0, z=0, values=1, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (5, 95)) + (df_cell.shape[0] > 0) and \ + (df_cell.shape[1] == 122) def test_mcds_get_cell_df_at_notinmeash(self, mcds=mcds): df_cell = mcds.get_cell_df_at(x=-31, y=-21, z=-6, values=1, drop=set(), keep=set()) @@ -679,7 +696,7 @@ def test_mcds_plot_scatter_cat_else1(self, mcds=mcds): figbgcolor = 'cyan', # jump over if ) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_2d/cell_cell_type_z0/output00000024_cell_type.tiff')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_2d/cell_cell_type_z0/output00000024_cell_type.tiff')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -761,7 +778,7 @@ def test_mcds_make_cell_vtk_attribute_default(self, mcds=mcds): visualize=False, ) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_2d/output00000024_cell.vtp')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -769,7 +786,7 @@ def test_mcds_make_cell_vtk_attribute_default(self, mcds=mcds): def test_mcds_make_cell_vtk_attribute_zero(self, mcds=mcds): s_pathfile = mcds.make_cell_vtk(attribute=[], visualize=False) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_2d/output00000024_cell.vtp')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -780,7 +797,7 @@ def test_mcds_make_cell_vtk_attribute_many(self, mcds=mcds): visualize=False, ) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_2d/output00000024_cell.vtp')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_2d/output00000024_cell.vtp')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -795,20 +812,22 @@ class TestPyMcdsGraph(object): # graph dictionatry def test_mcds_get_attached_graph_dict(self, mcds=mcds): dei_graph = mcds.data['discrete_cells']['graph']['attached_cells'] + #print('graph attached:', sorted(dei_graph.items())) assert(str(type(mcds)) == "") and \ (str(type(dei_graph)) == "") and \ - (str(type(dei_graph[0])) == "") and \ - (len(dei_graph[0]) == 0) and \ - (len(dei_graph) == 1099) + (str(type(dei_graph[10])) == "") and \ + (len(dei_graph[10]) == 0) and \ + (len(dei_graph) > 9) - def test_mcds_get_nighbor_graph_dict(self, mcds=mcds): + def test_mcds_get_neighbor_graph_dict(self, mcds=mcds): dei_graph = mcds.data['discrete_cells']['graph']['neighbor_cells'] + #print('graph neighbor:', sorted(dei_graph.items())) assert(str(type(mcds)) == "") and \ (str(type(dei_graph)) == "") and \ - (str(type(dei_graph[0])) == "") and \ - (len(dei_graph[0]) == 7) and \ + (str(type(dei_graph[10])) == "") and \ + (len(dei_graph[10]) == 6) and \ (str(type(next(iter(dei_graph)))) == "") and \ - (len(dei_graph) == 1099) + (len(dei_graph) > 9) # attached graph gml files def test_mcds_make_graph_gml_attached_defaultattr(self, mcds=mcds): @@ -817,15 +836,14 @@ def test_mcds_make_graph_gml_attached_defaultattr(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_2d/output00000024_attached.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_2d/output00000024_attached.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "attached_graph"\n directed 0\n') > -1) and \ (s_file.find('node [\n id') > -1) and \ (s_file.find('edge [\n source') == -1) and \ (s_file.find('distance_microns') == -1) - #os.remove(s_pathfile) - print("BUE here we go:", s_pathfile) + os.remove(s_pathfile) def test_mcds_make_graph_gml_attached_edgeattrfalse(self, mcds=mcds): s_pathfile = mcds.make_graph_gml(graph_type='attached', edge_attribute=False, node_attribute=[]) @@ -833,15 +851,14 @@ def test_mcds_make_graph_gml_attached_edgeattrfalse(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_2d/output00000024_attached.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_2d/output00000024_attached.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "attached_graph"\n directed 0\n') > -1) and \ (s_file.find('node [\n id') > -1) and \ (s_file.find('edge [\n source') == -1) and \ (s_file.find('distance_microns') == -1) - #os.remove(s_pathfile) - print("BUE here we go:", s_pathfile) + os.remove(s_pathfile) def test_mcds_make_graph_gml_neighbor_nodeattrtrue(self, mcds=mcds): s_pathfile = mcds.make_graph_gml(graph_type='neighbor', edge_attribute=True, node_attribute=['dead','cell_count_voxel','cell_density_micron3','cell_type']) # bool,int,float,str @@ -849,7 +866,7 @@ def test_mcds_make_graph_gml_neighbor_nodeattrtrue(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_2d/output00000024_neighbor.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "neighbor_graph"\n directed 0\n') > -1) and \ @@ -860,8 +877,7 @@ def test_mcds_make_graph_gml_neighbor_nodeattrtrue(self, mcds=mcds): (s_file.find('cell_type') == -1) and \ (s_file.find('edge [\n source') > -1) and \ (s_file.find('distance_microns')> -1) - #os.remove(s_pathfile) - print("BUE here we go:", s_pathfile) + os.remove(s_pathfile) # neighbor graph gml file def test_mcds_make_graph_gml_neighbor_defaultattr(self, mcds=mcds): @@ -870,15 +886,14 @@ def test_mcds_make_graph_gml_neighbor_defaultattr(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_2d/output00000024_neighbor.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "neighbor_graph"\n directed 0\n') > -1) and \ (s_file.find('node [\n id') > -1) and \ (s_file.find('edge [\n source') > -1) and \ (s_file.find('distance_microns') > -1) - #os.remove(s_pathfile) - print("BUE here we go:", s_pathfile) + os.remove(s_pathfile) def test_mcds_make_graph_gml_neighbor_edgeattrfalse(self, mcds=mcds): s_pathfile = mcds.make_graph_gml(graph_type='neighbor', edge_attribute=False, node_attribute=[]) @@ -886,15 +901,14 @@ def test_mcds_make_graph_gml_neighbor_edgeattrfalse(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_2d/output00000024_neighbor.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "neighbor_graph"\n directed 0\n') > -1) and \ (s_file.find('node [\n id') > -1) and \ (s_file.find('edge [\n source') > -1) and \ (s_file.find('distance_microns') == -1) - #os.remove(s_pathfile) - print("BUE here we go:", s_pathfile) + os.remove(s_pathfile) def test_mcds_make_graph_gml_neighbor_nodeattrtrue(self, mcds=mcds): s_pathfile = mcds.make_graph_gml(graph_type='neighbor', edge_attribute=True, node_attribute=['dead','cell_count_voxel','cell_density_micron3','cell_type']) # bool,int,float,str @@ -902,7 +916,7 @@ def test_mcds_make_graph_gml_neighbor_nodeattrtrue(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_2d/output00000024_neighbor.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_2d/output00000024_neighbor.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "neighbor_graph"\n directed 0\n') > -1) and \ @@ -913,8 +927,7 @@ def test_mcds_make_graph_gml_neighbor_nodeattrtrue(self, mcds=mcds): (s_file.find('cell_type') > -1) and \ (s_file.find('edge [\n source') > -1) and \ (s_file.find('distance_microns') > -1) - #os.remove(s_pathfile) - print("BUE here we go:", s_pathfile) + os.remove(s_pathfile) ## ome tiff related functions ## @@ -925,32 +938,71 @@ class TestPyMcdsOmeTiff(object): ## ome tiff related functions ## def test_mcds_make_ome_tiff_default(self, mcds=mcds): - s_pathfile = mcds.make_ome_tiff(cell_attribute='ID', file=True) + s_pathfile = mcds.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=True) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_2d/output00000024_ID.ome.tiff')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_2d/output00000024_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) - def test_mcds_make_ome_tiff_bool_0(self, mcds=mcds): - a_ometiff = mcds.make_ome_tiff(cell_attribute='dead', file=False) + def test_mcds_make_ome_tiff_bool(self, mcds=mcds): + a_ometiff = mcds.make_ome_tiff(cell_attribute='dead', conc_cutoff={}, focus=None, file=False) assert(str(type(mcds)) == "") and \ (str(type(a_ometiff)) == "") and \ - (a_ometiff.dtype == float) and \ - (a_ometiff.shape == (2, 1, 200, 300)) - - def test_mcds_make_ome_tiff_int_0(self, mcds=mcds): - a_ometiff = mcds.make_ome_tiff(cell_attribute='cell_count_voxel', file=False) + (a_ometiff.dtype == np.float32) and \ + (a_ometiff.shape == (4, 1, 200, 300)) and \ + (a_ometiff[2].min() == 0.0) and \ + (a_ometiff[3].min() == 0.0) and \ + (a_ometiff[0].max() >= 1.0) and \ + (a_ometiff[1].max() >= 1.0) and \ + (a_ometiff[2].max() >= 1.0) and \ + (a_ometiff[3].max() >= 1.0) + + def test_mcds_make_ome_tiff_int(self, mcds=mcds): + a_ometiff = mcds.make_ome_tiff(cell_attribute='cell_count_voxel', conc_cutoff={}, focus=None, file=False) assert(str(type(mcds)) == "") and \ (str(type(a_ometiff)) == "") and \ - (a_ometiff.dtype == float) and \ - (a_ometiff.shape == (2, 1, 200, 300)) - - - def test_mcds_make_ome_tiff_float_0(self, mcds=mcds): - a_ometiff = mcds.make_ome_tiff(cell_attribute='pressure', file=False) + (a_ometiff.dtype == np.float32) and \ + (a_ometiff.shape == (4, 1, 200, 300)) and \ + (a_ometiff[2].min() == 0.0) and \ + (a_ometiff[3].min() == 0.0) and \ + (a_ometiff[0].max() >= 1.0) and \ + (a_ometiff[1].max() >= 1.0) and \ + (a_ometiff[2].max() >= 1.0) and \ + (a_ometiff[3].max() >= 1.0) + + def test_mcds_make_ome_tiff_float(self, mcds=mcds): + a_ometiff = mcds.make_ome_tiff(cell_attribute='pressure', conc_cutoff={}, focus=None, file=False) + assert(str(type(mcds)) == "") and \ + (str(type(a_ometiff)) == "") and \ + (a_ometiff.dtype == np.float32) and \ + (a_ometiff.shape == (4, 1, 200, 300)) and\ + (a_ometiff[2].min() == 0.0) and \ + (a_ometiff[3].min() == 0.0) and \ + (a_ometiff[0].max() >= 1.0) and \ + (a_ometiff[1].max() >= 1.0) and \ + (a_ometiff[2].max() >= 1.0) and \ + (a_ometiff[3].max() >= 1.0) + + def test_mcds_make_ome_tiff_conccutoff(self, mcds=mcds): + a_ometiff = mcds.make_ome_tiff(cell_attribute='ID', conc_cutoff={'oxygen': -1}, focus=None, file=False) + assert(str(type(mcds)) == "") and \ + (str(type(a_ometiff)) == "") and \ + (a_ometiff.dtype == np.float32) and \ + (a_ometiff.shape == (4, 1, 200, 300)) and \ + (a_ometiff[2].min() == 0.0) and \ + (a_ometiff[3].min() == 0.0) and \ + (a_ometiff[0].max() >= 1.0) and \ + (a_ometiff[1].max() >= 1.0) and \ + (a_ometiff[2].max() >= 1.0) and \ + (a_ometiff[3].max() >= 1.0) + + def test_mcds_make_ome_tiff_focus(self, mcds=mcds): + a_ometiff = mcds.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus={'default'}, file=False) assert(str(type(mcds)) == "") and \ (str(type(a_ometiff)) == "") and \ - (a_ometiff.dtype == float) and \ - (a_ometiff.shape == (2, 1, 200, 300)) + (a_ometiff.dtype == np.float32) and \ + (a_ometiff.shape == (1, 1, 200, 300)) and \ + (a_ometiff[0].min() == 0.0) and \ + (a_ometiff[0].max() >= 1.0) diff --git a/test/test_timestep_3d.py b/test/test_timestep_3d.py index 6a1c755..7de347b 100644 --- a/test/test_timestep_3d.py +++ b/test/test_timestep_3d.py @@ -20,6 +20,7 @@ # load library +import numpy as np import os import pathlib import pcdl @@ -27,7 +28,7 @@ # const -s_path_3d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'data_timeseries_3d') +s_path_3d = str(pathlib.Path(pcdl.__file__).parent.resolve()/'output_3d') s_file_3d = 'output00000024.xml' s_pathfile_3d = f'{s_path_3d}/{s_file_3d}' @@ -68,14 +69,15 @@ class TestPyMcdsInit(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (20460, 118)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ - (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 20460) and \ - (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 20460) + (len(mcds.data['discrete_cells']['graph']['attached_cells']) > 9) and \ + (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) > 9) def test_mcds_init_physiboss(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -84,8 +86,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'cancer_cell_attack_rates'})) and \ - (df_cell.shape == (20460, 118)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) class TestPyMcdsInitMicroenvFalse(object): @@ -95,14 +98,15 @@ class TestPyMcdsInitMicroenvFalse(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (20460, 112)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 116) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ - (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 20460) and \ - (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 20460) + (len(mcds.data['discrete_cells']['graph']['attached_cells']) > 9) and \ + (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) > 9) def test_mcds_init_physiboss(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -111,8 +115,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'cancer_cell_attack_rates'})) and \ - (df_cell.shape == (20460, 112)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 116) class TestPyMcdsInitGraphFalse(object): @@ -122,7 +127,8 @@ class TestPyMcdsInitGraphFalse(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (20460, 118)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -138,8 +144,9 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'cancer_cell_attack_rates'})) and \ - (df_cell.shape == (20460, 118)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) class TestPyMcdsInitPhysibossFalse(object): @@ -149,14 +156,15 @@ class TestPyMcdsInitPhysibossFalse(object): def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (20460, 118)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_init_graph(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ - (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 20460) and \ - (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 20460) + (len(mcds.data['discrete_cells']['graph']['attached_cells']) > 9) and \ + (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) > 9) def test_mcds_init_physiboss(self, mcds=mcds): assert(str(type(mcds)) == "") and \ @@ -165,62 +173,19 @@ def test_mcds_init_physiboss(self, mcds=mcds): def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (set(df_cell.columns).issuperset({'cancer_cell_attack_rates'})) and \ - (df_cell.shape == (20460, 118)) + (set(df_cell.columns).issuperset({'default_fusion_rates'})) and \ + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) #class TestPyMcdsInitSettingxmlFalse(object): # ''' tests for loading a pcdl.pyMCDS data set with settingxml false. ''' -# mcds = pcdl.pyMCDS(xmlfile=s_file_3d, output_path=s_path_3d, custom_data_type={}, microenv=True, graph=True, physiboss=True, settingxml=False, verbose=True) -# df_cell = mcds.get_cell_df() -# def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): -# assert(str(type(mcds)) == "") and \ -# (str(type(df_cell)) == "") and \ -# (df_cell.shape == (20460, 118)) -# -# def test_mcds_init_graph(self, mcds=mcds): -# assert(str(type(mcds)) == "") and \ -# (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ -# (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ -# (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 20460) and \ -# (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 20460) -# -# def test_mcds_init_physiboss(self, mcds=mcds): -# assert(str(type(mcds)) == "") and \ -# (mcds.data['discrete_cells']['physiboss'] == None) -# -# def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): -# assert(str(type(mcds)) == "") and \ -# (str(type(df_cell)) == "") and \ -# (set(df_cell.columns).issuperset({'attack_rates_0'})) and \ -# (df_cell.shape == (20460, 118)) +# NOP PhysiCell >= v1.14.0 #class TestPyMcdsInitSettingxmlNone(object): # ''' tests for loading a pcdl.pyMCDS data set with settingxml none. ''' -# mcds = pcdl.pyMCDS(xmlfile=s_file_3d, output_path=s_path_3d, custom_data_type={}, microenv=True, graph=True, physiboss=True, settingxml=None, verbose=True) -# df_cell = mcds.get_cell_df() -# def test_mcds_init_microenv(self, mcds=mcds, df_cell=df_cell): -# assert(str(type(mcds)) == "") and \ -# (str(type(df_cell)) == "") and \ -# (df_cell.shape == (20460, 118)) -# -# def test_mcds_init_graph(self, mcds=mcds): -# assert(str(type(mcds)) == "") and \ -# (str(type(mcds.data['discrete_cells']['graph']['attached_cells'])) == "") and \ -# (str(type(mcds.data['discrete_cells']['graph']['neighbor_cells'])) == "") and \ -# (len(mcds.data['discrete_cells']['graph']['attached_cells']) == 20460) and \ -# (len(mcds.data['discrete_cells']['graph']['neighbor_cells']) == 20460) -# -# def test_mcds_init_physiboss(self, mcds=mcds): -# assert(str(type(mcds)) == "") and \ -# (mcds.data['discrete_cells']['physiboss'] == None) -# -# def test_mcds_init_settingxml(self, mcds=mcds, df_cell=df_cell): -# assert(str(type(mcds)) == "") and \ -# (str(type(df_cell)) == "") and \ -# (set(df_cell.columns).issuperset({'attack_rates_0'})) and \ -# (df_cell.shape == (20460, 118)) +# NOP PhysiCell >= v1.14.0 class TestPyMcdsInitVerboseTrue(object): @@ -259,8 +224,8 @@ def test_mcds_get_unit_dict(self, mcds=mcds): ds_unit = mcds.get_unit_dict() assert(str(type(mcds)) == "") and \ (str(type(ds_unit)) == "") and \ - (len(ds_unit) == 105) and \ - (ds_unit['oxygen'] == 'mmHg') + (len(ds_unit) > 9) and \ + (ds_unit['oxygen'] == 'dimensionless') class TestPyMcds3dMicroenvWorkhorse(object): @@ -273,6 +238,8 @@ def test_mcds_get_conc_df(self, mcds=mcds): assert(str(type(mcds)) == "") and \ (str(type(df_conc)) == "") and \ (df_conc.shape == (1331, 11)) + #(df_conc.shape[0] > 9) and \ + #(df_conc.shape[1] == 122) def test_mcds_get_conc_df_zslice_center(self, mcds=mcds): df_conc = mcds.get_conc_df(z_slice=0, halt=False, values=1, drop=set(), keep=set()) @@ -348,15 +315,15 @@ def test_mcds_plot_contourf(self, mcds=mcds): figbgcolor = 'orange', # jump over if ) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_3d/conc_oxygen_z-5.0/output00000024_oxygen.tiff')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_3d/conc_oxygen_z-5.0/output00000024_oxygen.tiff')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) def test_mcds_make_conc_vtk(self, mcds=mcds): - s_pathfile = mcds.make_conc_vtk() + s_pathfile = mcds.make_conc_vtk(visualize=False) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_3d/output00000024_conc.vtr')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_3d/output00000024_conc.vtr')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -371,25 +338,29 @@ def test_mcds_get_cell_df(self, mcds=mcds): df_cell = mcds.get_cell_df(values=1, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (20460, 118)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 122) def test_mcds_get_cell_df_values(self, mcds=mcds): df_cell = mcds.get_cell_df(values=2, drop=set(), keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (20460, 33)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 72) def test_mcds_get_cell_df_drop(self, mcds=mcds): df_cell = mcds.get_cell_df(values=1, drop={'oxygen'}, keep=set()) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (20460, 117)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 121) def test_mcds_get_cell_df_keep(self, mcds=mcds): df_cell = mcds.get_cell_df(values=1, drop=set(), keep={'oxygen'}) assert(str(type(mcds)) == "") and \ (str(type(df_cell)) == "") and \ - (df_cell.shape == (20460, 13)) + (df_cell.shape[0] > 9) and \ + (df_cell.shape[1] == 13) # scatter categorical def test_mcds_plot_scatter_cat_if(self, mcds=mcds): @@ -436,7 +407,7 @@ def test_mcds_plot_scatter_cat_else1(self, mcds=mcds): figbgcolor = 'lime', # jump over if ) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_3d/cell_cell_type_z-5.0/output00000024_cell_type.tiff')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_3d/cell_cell_type_z-5.0/output00000024_cell_type.tiff')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -518,7 +489,7 @@ def test_mcds_make_cell_vtk_attribute_default(self, mcds=mcds): visualize=False, ) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_3d/output00000024_cell.vtp')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_3d/output00000024_cell.vtp')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -526,7 +497,7 @@ def test_mcds_make_cell_vtk_attribute_default(self, mcds=mcds): def test_mcds_make_cell_vtk_attribute_zero(self, mcds=mcds): s_pathfile = mcds.make_cell_vtk(attribute=[], visualize=False) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_3d/output00000024_cell.vtp')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_3d/output00000024_cell.vtp')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -537,7 +508,7 @@ def test_mcds_make_cell_vtk_attribute_many(self, mcds=mcds): visualize=False, ) assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_3d/output00000024_cell.vtp')) and \ + (s_pathfile.replace('\\','/').endswith('/pcdl/output_3d/output00000024_cell.vtp')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) @@ -555,7 +526,7 @@ def test_mcds_make_graph_gml_attached_defaultattr(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_3d/output00000024_attached.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_3d/output00000024_attached.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "attached_graph"\n directed 0\n') > -1) and \ @@ -570,7 +541,7 @@ def test_mcds_make_graph_gml_attached_edgeattrfalse(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_3d/output00000024_attached.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_3d/output00000024_attached.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "attached_graph"\n directed 0\n') > -1) and \ @@ -585,7 +556,7 @@ def test_mcds_make_graph_gml_neighbor_nodeattrtrue(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_3d/output00000024_neighbor.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_3d/output00000024_neighbor.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "neighbor_graph"\n directed 0\n') > -1) and \ @@ -605,7 +576,7 @@ def test_mcds_make_graph_gml_neighbor_defaultattr(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_3d/output00000024_neighbor.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_3d/output00000024_neighbor.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "neighbor_graph"\n directed 0\n') > -1) and \ @@ -620,7 +591,7 @@ def test_mcds_make_graph_gml_neighbor_edgeattrfalse(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_3d/output00000024_neighbor.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_3d/output00000024_neighbor.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "neighbor_graph"\n directed 0\n') > -1) and \ @@ -635,7 +606,7 @@ def test_mcds_make_graph_gml_neighbor_nodeattrtrue(self, mcds=mcds): s_file = f.read() f.close() assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('pcdl/data_timeseries_3d/output00000024_neighbor.gml')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_3d/output00000024_neighbor.gml')) and \ (os.path.exists(s_pathfile)) and \ (s_file.find('Creator "pcdl_v') > -1) and \ (s_file.find('graph [\n id 1440\n comment "time_min"\n label "neighbor_graph"\n directed 0\n') > -1) and \ @@ -654,17 +625,18 @@ class TestPyMcds3dOmeTiffWorkhorse(object): mcds = pcdl.pyMCDS(xmlfile=s_pathfile_3d) # custom_data_type={}, microenv=True, graph=True, physiboss=True, settingxml='PhysiCell_settings.xml', verbose=True ## ome tiff related functions ## - def test_mcds_make_ome_tiff_default_0(self, mcds=mcds): - a_ometiff = mcds.make_ome_tiff(cell_attribute='ID', file=False) + def test_mcds_make_ome_tiff_default(self, mcds=mcds): + s_pathfile = mcds.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=True) assert(str(type(mcds)) == "") and \ - (str(type(a_ometiff)) == "") and \ - (a_ometiff.dtype == float) and \ - (a_ometiff.shape == (4, 11, 200, 300)) - - def test_mcds_make_ome_tiff_default_1(self, mcds=mcds): - s_pathfile = mcds.make_ome_tiff(cell_attribute='ID', file=True) - assert(str(type(mcds)) == "") and \ - (s_pathfile.replace('\\','/').endswith('/pcdl/data_timeseries_3d/output00000024_ID.ome.tiff')) and \ + (s_pathfile.replace('\\','/').endswith('pcdl/output_3d/output00000024_oxygen_water_default_blood_cells_ID.ome.tiff')) and \ (os.path.exists(s_pathfile)) and \ (os.path.getsize(s_pathfile) > 2**10) os.remove(s_pathfile) + + def test_mcds_make_ome_tiff_nofile(self, mcds=mcds): + a_ometiff = mcds.make_ome_tiff(cell_attribute='ID', conc_cutoff={}, focus=None, file=False) + assert(str(type(mcds)) == "") and \ + (str(type(a_ometiff)) == "") and \ + (a_ometiff.dtype == np.float32) and \ + (a_ometiff.shape == (4, 11, 200, 300)) +