diff --git a/CITATION.cff b/CITATION.cff new file mode 100644 index 0000000..be0a243 --- /dev/null +++ b/CITATION.cff @@ -0,0 +1,10 @@ +cff-version: 1.2.0 +message: "If you use this software, please cite it as below." +authors: + - family-names: Blundell + given-names: Benjamin + orcid: https://orcid.org/0000-0002-4634-4779 +title: "HOLLy - Hypothesised Object from Light Localisations" +version: 1.2 +doi: +date-released: 2021-08-31 \ No newline at end of file diff --git a/README.markdown b/README.markdown index 6545d9c..20ca3eb 100644 --- a/README.markdown +++ b/README.markdown @@ -6,18 +6,40 @@ A [PyTorch](https://pytorch.org/) based neural network program designed to recontruct single molecules in 3D from a series of 2D storm images. -The goal of this network is to take a set of 2D representations of a molecule (or other simulated object) and create a 3D pointcloud of the molecule. We predict the pose and structure using a Convolutional Neural Network. +The goal of this network is to take a set of 2D representations of a molecule (or other simulated object) and create a 3D pointcloud of the molecule. We predict the pose and structure using a Convolutional Neural Network. ## Overview -HOLLy takes a number of images, or generates images from a ground-truth point-cloud, trains on these attempting to improve it's own internal representation of what it thinks the ground-truth object is. At the end of training, an obj or ply file will be produced, representing the object the network converged upon. +HOLLy takes a number of images (it can also generate images from a ground-truth point-cloud) and trains on these attempting to improve it's own internal representation of what it thinks the ground-truth object is. At the end of training, an *obj* or **ply* file will be produced, representing the object the network converged upon. HOLLy is split into *train.py* and *run.py* with the actual net stored in in *net/net.py*. *eval.py* will evaluate a trained network, creating statistics and visualistions. *net/renderer.py* contains the code for the differentiable renderer. *data/loader.py*, along with *data/buffer.py* and *data/batcher.py* create our simulated data for all the tests, including adding noise. *data/imageload.py* is similar, but for pre-rendered images. +(The diagram below is animated and may take a little time to appear). ![Overview diagram](https://shutr.benjamin.computer/static/shutr_files/original/diagram.gif) +## Publication + +[3D Structure from 2D Microscopy images using Deep Learning - Frontiers in Bioinformatics](https://www.frontiersin.org/articles/10.3389/fbinf.2021.740342/abstract) + + @article{blundell3DStructure2D01, + title = {{{3D Structure}} from {{2D Microscopy}} Images Using {{Deep Learning}}}, + author = {Blundell, Benjamin James and Rosten, Ed and Ch'ng, QueeLim and Cox, Susan and Manley, Suliana and Sieben, Christian}, + year = {2021}, + journal = {Frontiers in Bioinformatics}, + volume = {0}, + publisher = {{Frontiers}}, + issn = {2673-7647}, + doi = {10.3389/fbinf.2021.740342}, + copyright = {All rights reserved}, + langid = {english}, + } + +### Citing with Bibtex + +See the CITATION.cff file. + ## Installation ### Requirements @@ -221,13 +243,10 @@ Individual tests can be run as follows: python -m unittest test.data.Data.test_wobble -## Our published paper and data - -Our paper "3D Structure from SMLM images using Deep Learning" is under review at the moment and hopefully will be available soon. +## Datasets in the Publication The CEP152 data we used in the paper with HOLLy can be found on Zenodo at [https://zenodo.org/record/4751057](https://zenodo.org/record/4751057) and the results we mention in the paper can also be downloaded from Zenodo at [https://zenodo.org/record/4836173](https://zenodo.org/record/4836173). - ## Command line and configuration options When running train.py, there are a number of options one can choose. diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..e69de29 diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..e69de29 diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000..e69de29 diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000..dd9e06e --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,16 @@ +Welcome to HOLLy's documentation! +=================================== + +** HOLLy ** is a PyTorch based program that attempts to recreate 3D structure from a series of 2D 'Single Molecule Localisation Microscopy' images. + +.. note:: + + This project is under active development. + +Contents +-------- + +.. toctree:: + + usage + diff --git a/stats/stats.py b/stats/stats.py index cad92b2..a9947f2 100644 --- a/stats/stats.py +++ b/stats/stats.py @@ -31,6 +31,7 @@ def __init__(self): def on(self, savedir: str): self.savedir = savedir + self._error_message = False path = os.path.normpath(savedir) parts = path.split(os.sep) self.exp_name = parts[-1] # WARNING - overwrite potential in the REDIS @@ -66,7 +67,7 @@ def watch(self, obj, name: str): def close(self): """ Make sure we write to the DB. """ - pass + self._error_message = False # TODO - will probably get rid # self.db.close() # Zip now happens in the generate_stats.sh script @@ -183,10 +184,9 @@ def write_immediate(self, obj, name, epoch, step, idx): try: self._conv(obj, name, epoch, step, idx) except Exception: - pass - # This is naughty but until I find a way for it to be less - # verbose I'm leaving it in for this version. - #print("No database to store statistic.") + if not self._error_message: + print("No database to store statistic. Stats will not be stored.") + self._error_message = True def save_jpg( self, @@ -239,6 +239,9 @@ def save_points( if not os.path.exists(savedir + "/objs"): os.makedirs(savedir + "/objs/") + if not os.path.exists(savedir + "/plys"): + os.makedirs(savedir + "/plys/") + path_obj = ( savedir + "/objs/shape_e" + str(epoch).zfill(3) + "_s" + str(step).zfill(5) ) @@ -294,4 +297,4 @@ def update(epoch: int, set_size: int, batch_size: int, step: int): def close(): - pass + stat.close()