{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.14"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":84969,"databundleVersionId":10033515,"sourceType":"competition"}],"dockerImageVersionId":30804,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false},"papermill":{"default_parameters":{},"duration":405.246033,"end_time":"2024-12-09T03:41:37.024386","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2024-12-09T03:34:51.778353","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"06ed073c","cell_type":"markdown","source":"## Introduction\nThis work was originally forked from [David List's Notebook](https://www.kaggle.com/code/davidlist/experiment-ts-6-4-visualization), which is where the nice visualisations came from.  Thanks to David for this. I found the various public visualisation notebooks super helpful.\n\nMy goal with this notebook was to a little more EDA to get a feel for the data, and pre-process the tomograms into smaller chunks around the label centroids from which I plan to build my own models.\n\nI have also adding an 'empty' class, by randomly sampling from the remaining volume.\n\n**Update 30 January 2025**  \nI am still using this strategy, it is working OK but not as well as I had hoped.  I settled on 32x32x32 crops for my models.  I have updated this notebook to save the data in uint8 datatype.  At some point I realised that I had handicapped my models by working in float32, making them really slow.  It was a hard lesson in the importance of paying attention to efficient data use!","metadata":{"papermill":{"duration":0.01359,"end_time":"2024-12-09T03:34:54.610113","exception":false,"start_time":"2024-12-09T03:34:54.596523","status":"completed"},"tags":[]}},{"id":"ce46eb18-13c9-4194-af7f-b33dec8d1d97","cell_type":"code","source":"!pip install zarr","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"42dc4281","cell_type":"code","source":"from pathlib import Path\nimport random\nimport json\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport zarr","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.542267Z","iopub.execute_input":"2024-12-09T22:24:29.542696Z","iopub.status.idle":"2024-12-09T22:24:29.549981Z","shell.execute_reply.started":"2024-12-09T22:24:29.542650Z","shell.execute_reply":"2024-12-09T22:24:29.548731Z"},"papermill":{"duration":2.742429,"end_time":"2024-12-09T03:35:12.984241","exception":false,"start_time":"2024-12-09T03:35:10.241812","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"c2b77e5a","cell_type":"code","source":"class NotebookConfig:\n    CROP_SIZE = 16\n    NUM_EMPTY = 500\n    OBJECT_RADII_A = {'apo-ferritin': 60, \n                      'beta-amylase': 65, \n                      'beta-galactosidase': 90, \n                      'ribosome': 150,\n                      'thyroglobulin':130,\n                      'virus-like-particle':135}\n    ZARR_SCALE = 10.012444  #Maps the pixel scale to the physical scale in Angstroms.  Found in the .zarr attributes file.\n    def __init__(self):\n        self.OBJECT_RADII_VOX  = {name: int(round(rad / self.ZARR_SCALE))\n                                  for name, rad in self.OBJECT_RADII_A.items()}\n\nclass Paths:\n    def __init__(self, data_fldr, results_fldr):\n        _czii =  'czii-cryo-et-object-identification'\n        self.RESULTS_FLDR = results_fldr\n        self.TRAIN_FLDR = data_fldr / f'{_czii}/train'\n        self.TRAIN_LABELS_FLDR = self.TRAIN_FLDR / 'overlay/ExperimentRuns'\n        self.TRAIN_ZARS_FLDR = self.TRAIN_FLDR / 'static/ExperimentRuns'\n        self.TEST_ZARS_FLDR = data_fldr / f'{_czii}/test/static/ExperimentRuns'\n        self.TEST_NMS = [fldr.name for fldr in self.TEST_ZARS_FLDR.iterdir()]\n        self.TRAIN_NMS = [fldr.name for fldr in self.TRAIN_ZARS_FLDR.iterdir()]\n\n        self.TYPES = ['apo-ferritin', \n                      'beta-amylase', \n                      'beta-galactosidase', \n                      'ribosome',\n                      'thyroglobulin',\n                      'virus-like-particle']\n\n        _all_classes = self.TYPES + ['empty']\n        _label_rel_pths = {name : f'Picks/{name}.json' for name in self.TYPES}\n        _label_fldrs = [p for p in self.TRAIN_LABELS_FLDR.iterdir()]\n        self.DESTN_FLDRS  = {particle_type: self.RESULTS_FLDR / particle_type for particle_type in _all_classes}\n        [dir_path.mkdir(parents=True, exist_ok=True) for dir_path in self.DESTN_FLDRS.values()]\n\n        self.LABELS = {sub_dir.name: {key: str(sub_dir / val) for key, val in _label_rel_pths.items()}\n                        for sub_dir in _label_fldrs if sub_dir.is_dir()}\n        \n        self.TRAIN_DN_ZARS =  {dir_path.name: self.TRAIN_ZARS_FLDR / \n                               f'{dir_path.name}/VoxelSpacing10.000/denoised.zarr'\n                                for dir_path in self.TRAIN_ZARS_FLDR.iterdir()}\n        self.TRAIN_DCON_ZARS =  {dir_path.name: self.TRAIN_ZARS_FLDR / \n                               f'{dir_path.name}/VoxelSpacing10.000/ctfdeconvolved.zarr'\n                                for dir_path in self.TRAIN_ZARS_FLDR.iterdir()}\n        self.TRAIN_ISO_ZARS =  {dir_path.name: self.TRAIN_ZARS_FLDR / \n                               f'{dir_path.name}/VoxelSpacing10.000/isonetcorrected.zarr'\n                                for dir_path in self.TRAIN_ZARS_FLDR.iterdir()}\n        self.TRAIN_WBP_ZARS =  {dir_path.name: self.TRAIN_ZARS_FLDR / \n                                f'{dir_path.name}/VoxelSpacing10.000/wbp.zarr'\n                                for dir_path in self.TRAIN_ZARS_FLDR.iterdir()}\n\n        print(f'Test Folders: {self.TEST_NMS}')\n        print(f'Train Folders: {self.TRAIN_NMS}\\n')\n        _denoised_files = [f'{f.parent.parent.name}/{f.parent.name}/{f.name}'\n                              for f in self.TRAIN_DN_ZARS.values()]\n        print(f'Denoised Train Zarr Files:\\n{_denoised_files}')\n        print(f\"\\nLabels for 'TS_6_4':\\n{self.LABELS['TS_6_4']}\")\n\ninput_path = Path('/kaggle/input')\noutput_path = Path('/kaggle/working')\n\npaths = Paths(input_path, output_path)\ncfg = NotebookConfig()","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.552099Z","iopub.execute_input":"2024-12-09T22:24:29.552617Z","iopub.status.idle":"2024-12-09T22:24:29.588080Z","shell.execute_reply.started":"2024-12-09T22:24:29.552564Z","shell.execute_reply":"2024-12-09T22:24:29.586956Z"},"papermill":{"duration":0.053106,"end_time":"2024-12-09T03:35:13.050083","exception":false,"start_time":"2024-12-09T03:35:12.996977","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"d0d378b3","cell_type":"markdown","source":"## Explore Data dimensions and quantities\n### Summary\n**Train**\n* 7 Scans in total: *TS_5_4*, *TS_6_4*, *TS_6_6*, *TS_69_2*, *TS_73_6*, *TS_86_3*, *TS_99_9*\n* TS_6_4 has timensions 630 x 630 x 184  (Highest resolution)\n* Labels -Picks in `.json` format with seperate files for each of 6 classes\n* The scans in `.zarr` format, with 4 variations: *CTF Deconvolved*, *Denoised*, *IsoNetCorrected*, & *WPB*\n\n**Test Sample**\n* 3 Scans only: *TS_5_4*, *TS_6_4*, *TS_69_2*  (All present in the Train collection_\n* *Denoised* Only\n* No labels\n\n**Labels**\n* 1269 total object instances, with class sizes varying from 87 (beta-amylase) to 375 (apo-ferritin)\n* Nominal radii ranging from 60 (apo-ferritin) to 150 (ribosome)\n* With a voxel size of 10 Angstroms, the above is 6-15 voxel widths.  So could potentially be represented by 16x16x16 blocks.","metadata":{"papermill":{"duration":0.013143,"end_time":"2024-12-09T03:35:13.076004","exception":false,"start_time":"2024-12-09T03:35:13.062861","status":"completed"},"tags":[]}},{"id":"8ea71261","cell_type":"code","source":"all_samples = [key for key in paths.LABELS.keys()]\nall_types = paths.TYPES\nflattened = []\nfor sample in all_samples:\n    for particle_type in all_types: \n        json_path = Path(paths.LABELS[sample][particle_type])\n        with json_path.open(\"r\", encoding=\"utf-8\") as file:\n            data = json.load(file)['points']\n        for point in data:\n            new_entry = {}\n            new_entry['sample_id'] = sample\n            new_entry['object_type'] = particle_type\n            new_entry['x'] = point['location']['x']\n            new_entry['y'] = point['location']['y']\n            new_entry['z'] = point['location']['z']\n            new_entry['Size (A)'] = cfg.OBJECT_RADII_A[particle_type]\n            new_entry['Size (V)'] = cfg.OBJECT_RADII_VOX[particle_type]\n            flattened.append(new_entry)\ndf = pd.DataFrame(flattened)\ndf['Vol (V3)'] = round(4  * np.pi * (df['Size (V)']/2)** 3  / 3 ).astype(int)\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.590743Z","iopub.execute_input":"2024-12-09T22:24:29.591123Z","iopub.status.idle":"2024-12-09T22:24:29.693337Z","shell.execute_reply.started":"2024-12-09T22:24:29.591089Z","shell.execute_reply":"2024-12-09T22:24:29.692216Z"},"papermill":{"duration":0.289788,"end_time":"2024-12-09T03:35:13.378461","exception":false,"start_time":"2024-12-09T03:35:13.088673","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"87b19a25","cell_type":"code","source":"print(f'There are {len(df)} labelled particles')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.694672Z","iopub.execute_input":"2024-12-09T22:24:29.694986Z","iopub.status.idle":"2024-12-09T22:24:29.700688Z","shell.execute_reply.started":"2024-12-09T22:24:29.694957Z","shell.execute_reply":"2024-12-09T22:24:29.699562Z"},"papermill":{"duration":0.023476,"end_time":"2024-12-09T03:35:13.415040","exception":false,"start_time":"2024-12-09T03:35:13.391564","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"b529a262","cell_type":"markdown","source":"Let's consider what would happen if we cropped out cubes of small volume by using these labels, and worked with those instead of uniform patches of the whole volume.  If all these particles were non-contiguous, and I was to crop out just the cube around their centres, what proportion of the total volume would this represent?","metadata":{"papermill":{"duration":0.01243,"end_time":"2024-12-09T03:35:13.440568","exception":false,"start_time":"2024-12-09T03:35:13.428138","status":"completed"},"tags":[]}},{"id":"bec0b0c9","cell_type":"code","source":"total_vol = 630 * 630 * 184\ncropped_vol = len(df) * (cfg.CROP_SIZE)**3 \nfraction_cropped = cropped_vol / total_vol\nfraction_labelled = df['Vol (V3)'].sum() / total_vol\nfraction_cropped","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.702220Z","iopub.execute_input":"2024-12-09T22:24:29.702726Z","iopub.status.idle":"2024-12-09T22:24:29.714830Z","shell.execute_reply.started":"2024-12-09T22:24:29.702676Z","shell.execute_reply":"2024-12-09T22:24:29.713612Z"},"papermill":{"duration":0.025273,"end_time":"2024-12-09T03:35:13.478466","exception":false,"start_time":"2024-12-09T03:35:13.453193","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"810c53a3","cell_type":"code","source":"fraction_labelled","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.716259Z","iopub.execute_input":"2024-12-09T22:24:29.716729Z","iopub.status.idle":"2024-12-09T22:24:29.729929Z","shell.execute_reply.started":"2024-12-09T22:24:29.716679Z","shell.execute_reply":"2024-12-09T22:24:29.728811Z"},"papermill":{"duration":0.023579,"end_time":"2024-12-09T03:35:13.515136","exception":false,"start_time":"2024-12-09T03:35:13.491557","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"2ef57f74","cell_type":"markdown","source":"So with a cube size of 16, we are using 7% the provided volume for cubes in our training dataset.  But only 1.5% of the original volume is nominally occupied by the particles of interest by simplistically modelling the particles as spheres.\n\nIf it actually was this simple then we have no trouble finding some extra volume to make an 'empty' class.  However we were told by the competition hosts that the volume is under-labelled.  So there are some potential false negatives to be wary of in this extra space.\n\nOne other consideration here, is how much of a gain we can get by masking out the empty space with a first-stage 3d process, like U-net, or Classical convolutional methods, and classifying on a second step.  With 32x32x32, we *only* halve the volume of space to process, and that assumes that points of interest are perfectly recognised by a previous step.  On the other hand, if this second step was a 2d classifier, on for example a slice through the middle of the cube, then the speed gain would be enormous, and there is no need to consider smaller cubes, but we risk throwing away a lot of useful information.\n\nWith 16x16x16, we reduce the volume we need to process by a factor of 14.  This ought to be super fast.  We can then be generous with detection thresholds to have excessive proposed particle locations (low precision, high recall), just so long as we have an empty class in the subsequent classifier.\n\nNow let's take a look at potential class imbalance","metadata":{"papermill":{"duration":0.013196,"end_time":"2024-12-09T03:35:13.541614","exception":false,"start_time":"2024-12-09T03:35:13.528418","status":"completed"},"tags":[]}},{"id":"fb775d22","cell_type":"code","source":"df['object_type'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.731432Z","iopub.execute_input":"2024-12-09T22:24:29.731928Z","iopub.status.idle":"2024-12-09T22:24:29.746430Z","shell.execute_reply.started":"2024-12-09T22:24:29.731878Z","shell.execute_reply":"2024-12-09T22:24:29.745238Z"},"papermill":{"duration":0.03254,"end_time":"2024-12-09T03:35:13.587031","exception":false,"start_time":"2024-12-09T03:35:13.554491","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"3fece51a","cell_type":"code","source":"df['sample_id'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.747989Z","iopub.execute_input":"2024-12-09T22:24:29.748512Z","iopub.status.idle":"2024-12-09T22:24:29.761132Z","shell.execute_reply.started":"2024-12-09T22:24:29.748454Z","shell.execute_reply":"2024-12-09T22:24:29.760060Z"},"papermill":{"duration":0.028184,"end_time":"2024-12-09T03:35:13.628540","exception":false,"start_time":"2024-12-09T03:35:13.600356","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"1086cc29","cell_type":"markdown","source":"## Examine the Tomographs","metadata":{"papermill":{"duration":0.014572,"end_time":"2024-12-09T03:37:43.374071","exception":false,"start_time":"2024-12-09T03:37:43.359499","status":"completed"},"tags":[]}},{"id":"8273be58","cell_type":"code","source":"# Load the first zarr.\nz_ts_6_4 = zarr.open(str(paths.TRAIN_DN_ZARS['TS_6_4']), mode='r')\nz_ts_6_4_iso = zarr.open(str(paths.TRAIN_ISO_ZARS['TS_6_4']), mode='r')\nz_ts_6_4_dcon = zarr.open(str(paths.TRAIN_DCON_ZARS['TS_6_4']), mode='r')\nz_ts_6_4_wbp = zarr.open(str(paths.TRAIN_WBP_ZARS['TS_6_4']), mode='r')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.765931Z","iopub.execute_input":"2024-12-09T22:24:29.766281Z","iopub.status.idle":"2024-12-09T22:24:29.790456Z","shell.execute_reply.started":"2024-12-09T22:24:29.766250Z","shell.execute_reply":"2024-12-09T22:24:29.789205Z"},"papermill":{"duration":0.056214,"end_time":"2024-12-09T03:37:43.445161","exception":false,"start_time":"2024-12-09T03:37:43.388947","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"704d2e71","cell_type":"markdown","source":"/kaggle/input/czii-cryo-et-object-identification/train/static/ExperimentRuns/TS_6_4/VoxelSpacing10.000/denoised.zarr","metadata":{"papermill":{"duration":0.014914,"end_time":"2024-12-09T03:37:43.476118","exception":false,"start_time":"2024-12-09T03:37:43.461204","status":"completed"},"tags":[]}},{"id":"ed8c504f","cell_type":"code","source":"print(z_ts_6_4)\nprint(z_ts_6_4[0].shape)\nprint(z_ts_6_4[1].shape)\nprint(z_ts_6_4[2].shape)","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.792008Z","iopub.execute_input":"2024-12-09T22:24:29.792356Z","iopub.status.idle":"2024-12-09T22:24:29.808212Z","shell.execute_reply.started":"2024-12-09T22:24:29.792321Z","shell.execute_reply":"2024-12-09T22:24:29.806875Z"},"papermill":{"duration":0.038545,"end_time":"2024-12-09T03:37:43.529666","exception":false,"start_time":"2024-12-09T03:37:43.491121","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"f1c10cfd","cell_type":"markdown","source":"Looking only at the high resolution, let's check all the Zarr files are the same size","metadata":{"papermill":{"duration":0.015168,"end_time":"2024-12-09T03:37:43.560640","exception":false,"start_time":"2024-12-09T03:37:43.545472","status":"completed"},"tags":[]}},{"id":"e5f7b448","cell_type":"code","source":"for path in paths.TRAIN_DN_ZARS.values():\n    array = zarr.open(str(path), mode='r')[0]\n    print(array.shape)","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.809535Z","iopub.execute_input":"2024-12-09T22:24:29.810047Z","iopub.status.idle":"2024-12-09T22:24:29.862052Z","shell.execute_reply.started":"2024-12-09T22:24:29.809999Z","shell.execute_reply":"2024-12-09T22:24:29.860913Z"},"papermill":{"duration":0.050756,"end_time":"2024-12-09T03:37:43.626426","exception":false,"start_time":"2024-12-09T03:37:43.575670","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"5e4e1efa","cell_type":"markdown","source":"### High Resolution\nPlot the first image at 100 dpi.  Plot all 184 images in a grid after that.","metadata":{"papermill":{"duration":0.014859,"end_time":"2024-12-09T03:37:43.656508","exception":false,"start_time":"2024-12-09T03:37:43.641649","status":"completed"},"tags":[]}},{"id":"e83460c5","cell_type":"code","source":"fig = plt.figure(figsize=(6.3,6.3))\n_ = plt.imshow(z_ts_6_4[0][0])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:29.863128Z","iopub.execute_input":"2024-12-09T22:24:29.863419Z","iopub.status.idle":"2024-12-09T22:24:30.973685Z","shell.execute_reply.started":"2024-12-09T22:24:29.863385Z","shell.execute_reply":"2024-12-09T22:24:30.972435Z"},"papermill":{"duration":1.089958,"end_time":"2024-12-09T03:37:44.761524","exception":false,"start_time":"2024-12-09T03:37:43.671566","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"07031599","cell_type":"markdown","source":"Plot the first 25 of...not sure what we're looking at yet.  :)","metadata":{"papermill":{"duration":0.026747,"end_time":"2024-12-09T03:37:44.815000","exception":false,"start_time":"2024-12-09T03:37:44.788253","status":"completed"},"tags":[]}},{"id":"cc494a7c","cell_type":"code","source":"\nfig = plt.figure(figsize=(10,74))\nfor i in range(184):\n    ax = plt.subplot(37, 5, i + 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(z_ts_6_4[0][i])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:24:30.975103Z","iopub.execute_input":"2024-12-09T22:24:30.975437Z","iopub.status.idle":"2024-12-09T22:26:24.509045Z","shell.execute_reply.started":"2024-12-09T22:24:30.975401Z","shell.execute_reply":"2024-12-09T22:26:24.507173Z"},"papermill":{"duration":121.540507,"end_time":"2024-12-09T03:39:46.381264","exception":false,"start_time":"2024-12-09T03:37:44.840757","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"687bd0be","cell_type":"markdown","source":"### Medium Resolution\nPlot the first image at 100 dpi.  Plot all 92 images in a grid after that.","metadata":{"papermill":{"duration":0.113461,"end_time":"2024-12-09T03:39:46.609367","exception":false,"start_time":"2024-12-09T03:39:46.495906","status":"completed"},"tags":[]}},{"id":"e303526e","cell_type":"code","source":"fig = plt.figure(figsize=(3.15,3.15))\n_ = plt.imshow(z_ts_6_4[1][0])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:24.510927Z","iopub.execute_input":"2024-12-09T22:26:24.511280Z","iopub.status.idle":"2024-12-09T22:26:24.929343Z","shell.execute_reply.started":"2024-12-09T22:26:24.511245Z","shell.execute_reply":"2024-12-09T22:26:24.928154Z"},"papermill":{"duration":0.781252,"end_time":"2024-12-09T03:39:47.505119","exception":false,"start_time":"2024-12-09T03:39:46.723867","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"6b5cd4a2","cell_type":"code","source":"fig = plt.figure(figsize=(10,38))\nfor i in range(92):\n    ax = plt.subplot(19, 5, i + 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(z_ts_6_4[1][i])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:24.930825Z","iopub.execute_input":"2024-12-09T22:26:24.932523Z","iopub.status.idle":"2024-12-09T22:26:46.216189Z","shell.execute_reply.started":"2024-12-09T22:26:24.932479Z","shell.execute_reply":"2024-12-09T22:26:46.214761Z"},"papermill":{"duration":21.199278,"end_time":"2024-12-09T03:40:08.826957","exception":false,"start_time":"2024-12-09T03:39:47.627679","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"8cd1c86c","cell_type":"markdown","source":"### Low Resolution\nPlot the first image at 100 dpi.  Plot all 46 images in a grid after that.","metadata":{"papermill":{"duration":0.165518,"end_time":"2024-12-09T03:40:09.171772","exception":false,"start_time":"2024-12-09T03:40:09.006254","status":"completed"},"tags":[]}},{"id":"8d7109fe","cell_type":"code","source":"fig = plt.figure(figsize=(1.58,1.58))\n_ = plt.imshow(z_ts_6_4[2][0])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:46.217868Z","iopub.execute_input":"2024-12-09T22:26:46.218233Z","iopub.status.idle":"2024-12-09T22:26:46.470749Z","shell.execute_reply.started":"2024-12-09T22:26:46.218197Z","shell.execute_reply":"2024-12-09T22:26:46.469600Z"},"papermill":{"duration":0.394459,"end_time":"2024-12-09T03:40:09.721420","exception":false,"start_time":"2024-12-09T03:40:09.326961","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"2843ea9c","cell_type":"code","source":"fig = plt.figure(figsize=(10,20))\nfor i in range(46):\n    ax = plt.subplot(10, 5, i + 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(z_ts_6_4[2][i])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:46.472079Z","iopub.execute_input":"2024-12-09T22:26:46.472378Z","iopub.status.idle":"2024-12-09T22:26:51.194498Z","shell.execute_reply.started":"2024-12-09T22:26:46.472348Z","shell.execute_reply":"2024-12-09T22:26:51.193081Z"},"papermill":{"duration":4.68147,"end_time":"2024-12-09T03:40:14.560466","exception":false,"start_time":"2024-12-09T03:40:09.878996","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"ff09606e","cell_type":"markdown","source":"### Denoised, IsoNet Corrected, CTF Deconvolved, and Weighted Back Projection\n\nNext plot each of the different image types present in the training directories.  This time just one high resolution image each of the same layer.","metadata":{"papermill":{"duration":0.189839,"end_time":"2024-12-09T03:40:14.964184","exception":false,"start_time":"2024-12-09T03:40:14.774345","status":"completed"},"tags":[]}},{"id":"0e304a25","cell_type":"code","source":"fig = plt.figure(figsize=(10,10))\nax = plt.subplot(2, 2, 1)\nplt.xticks([])\nplt.yticks([])\nplt.title('Denoised')\nplt.imshow(z_ts_6_4[0][62], cmap='gray')\nax = plt.subplot(2, 2, 2)\nplt.xticks([])\nplt.yticks([])\nplt.title('IsoNet Corrected')\nplt.imshow(z_ts_6_4_iso[0][62], cmap='gray')\nax = plt.subplot(2, 2, 3)\nplt.xticks([])\nplt.yticks([])\nplt.title('CTF Deconvolved')\nplt.imshow(z_ts_6_4_dcon[0][62], cmap='gray')\nax = plt.subplot(2, 2, 4)\nplt.xticks([])\nplt.yticks([])\nplt.title('Weighted Back Projection')\n_ = plt.imshow(z_ts_6_4_wbp[0][62], cmap='gray')\n","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:51.196072Z","iopub.execute_input":"2024-12-09T22:26:51.196672Z","iopub.status.idle":"2024-12-09T22:26:54.061870Z","shell.execute_reply.started":"2024-12-09T22:26:51.196573Z","shell.execute_reply":"2024-12-09T22:26:54.060527Z"},"papermill":{"duration":8.519309,"end_time":"2024-12-09T03:40:23.673505","exception":false,"start_time":"2024-12-09T03:40:15.154196","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"d3e02991","cell_type":"markdown","source":"### Ribosome Identification\n\nNow that we can plot the images the next step is to try to identify structures of interest.  Lists of those structures for TS_6_4 are in the train/overlay directory.  We'll start with ribosomes.\n\nFind all of the ribosomes between 600 and 650 in the z-axis, and plot them on slide 62 to see if we get something reasonable.  If we do that suggests the origin is in the upper left in the x and y directions, and in the first image in the z direction.","metadata":{"papermill":{"duration":0.193046,"end_time":"2024-12-09T03:40:24.084644","exception":false,"start_time":"2024-12-09T03:40:23.891598","status":"completed"},"tags":[]}},{"id":"e9362cc2","cell_type":"code","source":"ribosomes_x = []\nribosomes_y = []\nf = open(paths.LABELS['TS_6_4']['ribosome'])\nfor p in json.loads(f.read())['points']:\n    z = float(p['location']['z'])\n    if z >= 600 and z < 650:\n        ribosomes_x.append(float(p['location']['x'])/10)\n        ribosomes_y.append(float(p['location']['y'])/10)\n        print(p['location'])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:54.063569Z","iopub.execute_input":"2024-12-09T22:26:54.064208Z","iopub.status.idle":"2024-12-09T22:26:54.077487Z","shell.execute_reply.started":"2024-12-09T22:26:54.064154Z","shell.execute_reply":"2024-12-09T22:26:54.075955Z"},"papermill":{"duration":0.394495,"end_time":"2024-12-09T03:40:24.670792","exception":false,"start_time":"2024-12-09T03:40:24.276297","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"2acc978f","cell_type":"markdown","source":"Looking at the plotted images, we seem to have compelling matches.","metadata":{"papermill":{"duration":0.192288,"end_time":"2024-12-09T03:40:25.056478","exception":false,"start_time":"2024-12-09T03:40:24.864190","status":"completed"},"tags":[]}},{"id":"8b422269","cell_type":"code","source":"fig = plt.figure(figsize=(10,5))\nax = plt.subplot(1, 2, 1)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][62], cmap='gray', vmin=-0.00005, vmax=0.00005)\nax = plt.subplot(1, 2, 2)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][62], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter(ribosomes_x, ribosomes_y, edgecolor='red', facecolor='none')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:54.078804Z","iopub.execute_input":"2024-12-09T22:26:54.079130Z","iopub.status.idle":"2024-12-09T22:26:55.450485Z","shell.execute_reply.started":"2024-12-09T22:26:54.079098Z","shell.execute_reply":"2024-12-09T22:26:55.449352Z"},"papermill":{"duration":1.496749,"end_time":"2024-12-09T03:40:26.745787","exception":false,"start_time":"2024-12-09T03:40:25.249038","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"8bcc0b62","cell_type":"markdown","source":"### Virus Identification\n\nRepeat the same process for viruses except with a different z-value.","metadata":{"papermill":{"duration":0.200176,"end_time":"2024-12-09T03:40:27.163879","exception":false,"start_time":"2024-12-09T03:40:26.963703","status":"completed"},"tags":[]}},{"id":"4e6fd3b2","cell_type":"code","source":"virus_x = []\nvirus_y = []\nf = open(paths.LABELS['TS_6_4']['virus-like-particle'])\nfor p in json.loads(f.read())['points']:\n    z = float(p['location']['z'])\n    if z >= 670 and z < 700:\n        virus_x.append(float(p['location']['x'])/10)\n        virus_y.append(float(p['location']['y'])/10)\n        print(p['location'])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:55.451926Z","iopub.execute_input":"2024-12-09T22:26:55.452262Z","iopub.status.idle":"2024-12-09T22:26:55.460307Z","shell.execute_reply.started":"2024-12-09T22:26:55.452227Z","shell.execute_reply":"2024-12-09T22:26:55.459110Z"},"papermill":{"duration":0.209126,"end_time":"2024-12-09T03:40:27.568022","exception":false,"start_time":"2024-12-09T03:40:27.358896","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"36e1f61d","cell_type":"markdown","source":"Good matches again.","metadata":{"papermill":{"duration":0.20695,"end_time":"2024-12-09T03:40:27.970217","exception":false,"start_time":"2024-12-09T03:40:27.763267","status":"completed"},"tags":[]}},{"id":"a02d2085","cell_type":"code","source":"fig = plt.figure(figsize=(10,5))\nax = plt.subplot(1, 2, 1)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][68], cmap='gray', vmin=-0.00005, vmax=0.00005)\nax = plt.subplot(1, 2, 2)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][68], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter(virus_x, virus_y, edgecolor='red', facecolor='none')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:55.461942Z","iopub.execute_input":"2024-12-09T22:26:55.462267Z","iopub.status.idle":"2024-12-09T22:26:56.786842Z","shell.execute_reply.started":"2024-12-09T22:26:55.462236Z","shell.execute_reply":"2024-12-09T22:26:56.785586Z"},"papermill":{"duration":1.804731,"end_time":"2024-12-09T03:40:29.995728","exception":false,"start_time":"2024-12-09T03:40:28.190997","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"b7b70380","cell_type":"markdown","source":"### Apo-Ferritin Identification","metadata":{"papermill":{"duration":0.2365,"end_time":"2024-12-09T03:40:30.467476","exception":false,"start_time":"2024-12-09T03:40:30.230976","status":"completed"},"tags":[]}},{"id":"2f93bd91","cell_type":"code","source":"apo_ferritin_x = []\napo_ferritin_y = []\nf = open(paths.LABELS['TS_6_4']['apo-ferritin'])\nfor p in json.loads(f.read())['points']:\n    z = float(p['location']['z'])\n    if z >= 400 and z < 450:\n        apo_ferritin_x.append(float(p['location']['x'])/10)\n        apo_ferritin_y.append(float(p['location']['y'])/10)\n        print(p['location'])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:56.788268Z","iopub.execute_input":"2024-12-09T22:26:56.788640Z","iopub.status.idle":"2024-12-09T22:26:56.797609Z","shell.execute_reply.started":"2024-12-09T22:26:56.788585Z","shell.execute_reply":"2024-12-09T22:26:56.796212Z"},"papermill":{"duration":0.222284,"end_time":"2024-12-09T03:40:30.890614","exception":false,"start_time":"2024-12-09T03:40:30.668330","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"5d1f3e2e","cell_type":"code","source":"fig = plt.figure(figsize=(10,5))\nax = plt.subplot(1, 2, 1)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][42], cmap='gray', vmin=-0.00005, vmax=0.00005)\nax = plt.subplot(1, 2, 2)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][42], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter(apo_ferritin_x, apo_ferritin_y, edgecolor='red', facecolor='none')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:56.799158Z","iopub.execute_input":"2024-12-09T22:26:56.799520Z","iopub.status.idle":"2024-12-09T22:26:58.114692Z","shell.execute_reply.started":"2024-12-09T22:26:56.799475Z","shell.execute_reply":"2024-12-09T22:26:58.113567Z"},"papermill":{"duration":1.640186,"end_time":"2024-12-09T03:40:32.731155","exception":false,"start_time":"2024-12-09T03:40:31.090969","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"a2ac30f0","cell_type":"markdown","source":"### Beta-Galactosidase Identification","metadata":{"papermill":{"duration":0.205565,"end_time":"2024-12-09T03:40:33.169376","exception":false,"start_time":"2024-12-09T03:40:32.963811","status":"completed"},"tags":[]}},{"id":"16830a3f","cell_type":"code","source":"beta_galactosidase_x = []\nbeta_galactosidase_y = []\nf = open(paths.LABELS['TS_6_4']['beta-galactosidase'])\nfor p in json.loads(f.read())['points']:\n    z = float(p['location']['z'])\n    if z >= 450 and z < 500:\n        beta_galactosidase_x.append(float(p['location']['x'])/10)\n        beta_galactosidase_y.append(float(p['location']['y'])/10)\n        print(p['location'])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:58.115721Z","iopub.execute_input":"2024-12-09T22:26:58.116008Z","iopub.status.idle":"2024-12-09T22:26:58.124474Z","shell.execute_reply.started":"2024-12-09T22:26:58.115978Z","shell.execute_reply":"2024-12-09T22:26:58.123358Z"},"papermill":{"duration":0.217784,"end_time":"2024-12-09T03:40:33.597413","exception":false,"start_time":"2024-12-09T03:40:33.379629","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"809a0b65","cell_type":"code","source":"fig = plt.figure(figsize=(10,5))\nax = plt.subplot(1, 2, 1)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][47], cmap='gray', vmin=-0.00005, vmax=0.00005)\nax = plt.subplot(1, 2, 2)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][47], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter(beta_galactosidase_x, beta_galactosidase_y, edgecolor='red', facecolor='none')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:58.126067Z","iopub.execute_input":"2024-12-09T22:26:58.126532Z","iopub.status.idle":"2024-12-09T22:26:59.491576Z","shell.execute_reply.started":"2024-12-09T22:26:58.126472Z","shell.execute_reply":"2024-12-09T22:26:59.490352Z"},"papermill":{"duration":1.581989,"end_time":"2024-12-09T03:40:35.381961","exception":false,"start_time":"2024-12-09T03:40:33.799972","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"373939fb","cell_type":"markdown","source":"### Thyroglobulin Identification","metadata":{"papermill":{"duration":0.222799,"end_time":"2024-12-09T03:40:35.848905","exception":false,"start_time":"2024-12-09T03:40:35.626106","status":"completed"},"tags":[]}},{"id":"26c6113e","cell_type":"code","source":"thyroglobulin_x = []\nthyroglobulin_y = []\nf = open(paths.LABELS['TS_6_4']['thyroglobulin'])\nfor p in json.loads(f.read())['points']:\n    z = float(p['location']['z'])\n    if z >= 550 and z < 600:\n        thyroglobulin_x.append(float(p['location']['x'])/10)\n        thyroglobulin_y.append(float(p['location']['y'])/10)\n        print(p['location'])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:59.499500Z","iopub.execute_input":"2024-12-09T22:26:59.500040Z","iopub.status.idle":"2024-12-09T22:26:59.509227Z","shell.execute_reply.started":"2024-12-09T22:26:59.499989Z","shell.execute_reply":"2024-12-09T22:26:59.507927Z"},"papermill":{"duration":0.234161,"end_time":"2024-12-09T03:40:36.295416","exception":false,"start_time":"2024-12-09T03:40:36.061255","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"6da7d2af","cell_type":"code","source":"fig = plt.figure(figsize=(10,5))\nax = plt.subplot(1, 2, 1)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][57], cmap='gray', vmin=-0.00005, vmax=0.00005)\nax = plt.subplot(1, 2, 2)\nplt.xticks([])\nplt.yticks([])\nplt.imshow(z_ts_6_4[0][57], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter(thyroglobulin_x, thyroglobulin_y, edgecolor='red', facecolor='none')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:26:59.510548Z","iopub.execute_input":"2024-12-09T22:26:59.511092Z","iopub.status.idle":"2024-12-09T22:27:00.893268Z","shell.execute_reply.started":"2024-12-09T22:26:59.511052Z","shell.execute_reply":"2024-12-09T22:27:00.892170Z"},"papermill":{"duration":1.567355,"end_time":"2024-12-09T03:40:38.070954","exception":false,"start_time":"2024-12-09T03:40:36.503599","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"f9918e71","cell_type":"markdown","source":"### Ribosome Close-Up\n\nThe following are zoomed in images of a ribosome from three perspectives, straight on, from the right side (front is to the left) and from the top (front is to the bottom.)  Somewhat unexpected is the difference in image quality from the sides and top.","metadata":{"papermill":{"duration":0.210076,"end_time":"2024-12-09T03:40:38.516208","exception":false,"start_time":"2024-12-09T03:40:38.306132","status":"completed"},"tags":[]}},{"id":"2e683726","cell_type":"code","source":"# {'x': 5106.838, 'y': 4835.263, 'z': 619.225}\nfig = plt.figure(figsize=(10,2.5))\nax = plt.subplot(1, 4, 1)\nplt.xticks([])\nplt.yticks([])\nplt.title('Original')\nplt.imshow(z_ts_6_4[0][61], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter([5106.838/10], [4835.263/10], edgecolor='red', facecolor='none')\nax = plt.subplot(1, 4, 2)\nplt.xticks([])\nplt.yticks([])\nplt.title('Straight On')\nplt.imshow(z_ts_6_4[0][61, 461:505, 488:532], cmap='gray')\nax = plt.subplot(1, 4, 3)\nplt.xticks([])\nplt.yticks([])\nplt.title('Side View')\nplt.imshow(np.transpose(z_ts_6_4[0], axes=(2,1,0))[510, 461:505, 39:83], cmap='gray')\nax = plt.subplot(1, 4, 4)\nplt.xticks([])\nplt.yticks([])\nplt.title('Top View')\n_ = plt.imshow(np.transpose(z_ts_6_4[0], axes=(1,0,2))[483, 39:83, 488:532], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:00.894806Z","iopub.execute_input":"2024-12-09T22:27:00.895235Z","iopub.status.idle":"2024-12-09T22:27:03.713883Z","shell.execute_reply.started":"2024-12-09T22:27:00.895191Z","shell.execute_reply":"2024-12-09T22:27:03.711717Z"},"papermill":{"duration":2.744086,"end_time":"2024-12-09T03:40:41.468288","exception":false,"start_time":"2024-12-09T03:40:38.724202","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"206f6123","cell_type":"markdown","source":"### Virus Close-Up\n\nSame for virus, although I don't believe this captures the full virus.  In the images above, there is an elongated structure protruding down an to the left.","metadata":{"papermill":{"duration":0.2109,"end_time":"2024-12-09T03:40:41.926399","exception":false,"start_time":"2024-12-09T03:40:41.715499","status":"completed"},"tags":[]}},{"id":"3e11e6b5","cell_type":"code","source":"# {'x': 5580.108, 'y': 1240.86, 'z': 692.222}\nfig = plt.figure(figsize=(10,2.5))\nax = plt.subplot(1, 4, 1)\nplt.xticks([])\nplt.yticks([])\nplt.title('Original')\nplt.imshow(z_ts_6_4[0][69], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter([5580.108/10], [1240.86/10], edgecolor='red', facecolor='none')\nax = plt.subplot(1, 4, 2)\nplt.xticks([])\nplt.yticks([])\nplt.title('Straight On')\nplt.imshow(z_ts_6_4[0][69, 102:146, 536:580], cmap='gray')\nax = plt.subplot(1, 4, 3)\nplt.xticks([])\nplt.yticks([])\nplt.title('Side View')\nplt.imshow(np.transpose(z_ts_6_4[0], axes=(2,1,0))[558, 102:146, 47:91], cmap='gray')\nax = plt.subplot(1, 4, 4)\nplt.xticks([])\nplt.yticks([])\nplt.title('Top View')\n_ = plt.imshow(np.transpose(z_ts_6_4[0], axes=(1,0,2))[124, 47:91, 536:580], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:03.715780Z","iopub.execute_input":"2024-12-09T22:27:03.717056Z","iopub.status.idle":"2024-12-09T22:27:06.425457Z","shell.execute_reply.started":"2024-12-09T22:27:03.716973Z","shell.execute_reply":"2024-12-09T22:27:06.424328Z"},"papermill":{"duration":2.600554,"end_time":"2024-12-09T03:40:44.737476","exception":false,"start_time":"2024-12-09T03:40:42.136922","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"2f62d795","cell_type":"markdown","source":"### Apo-Ferritin Close-Up\n\nHere the particle is difficult to discerne from the side and top.","metadata":{"papermill":{"duration":0.210477,"end_time":"2024-12-09T03:40:45.190615","exception":false,"start_time":"2024-12-09T03:40:44.980138","status":"completed"},"tags":[]}},{"id":"aa7bcf17","cell_type":"code","source":"# {'x': 1019.831, 'y': 1859.831, 'z': 400.424}\nfig = plt.figure(figsize=(10,2.5))\nax = plt.subplot(1, 4, 1)\nplt.xticks([])\nplt.yticks([])\nplt.title('Original')\nplt.imshow(z_ts_6_4[0][40], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter([1019.831/10], [1859.831/10], edgecolor='red', facecolor='none')\nax = plt.subplot(1, 4, 2)\nplt.xticks([])\nplt.yticks([])\nplt.title('Straight On')\nplt.imshow(z_ts_6_4[0][40, 163:207, 79:123], cmap='gray')\nax = plt.subplot(1, 4, 3)\nplt.xticks([])\nplt.yticks([])\nplt.title('Side View')\nplt.imshow(np.transpose(z_ts_6_4[0], axes=(2,1,0))[101, 163:207, 18:62], cmap='gray')\nax = plt.subplot(1, 4, 4)\nplt.xticks([])\nplt.yticks([])\nplt.title('Top View')\n_ = plt.imshow(np.transpose(z_ts_6_4[0], axes=(1,0,2))[185, 18:62, 79:123], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:06.426790Z","iopub.execute_input":"2024-12-09T22:27:06.427229Z","iopub.status.idle":"2024-12-09T22:27:08.833648Z","shell.execute_reply.started":"2024-12-09T22:27:06.427181Z","shell.execute_reply":"2024-12-09T22:27:08.832499Z"},"papermill":{"duration":2.636232,"end_time":"2024-12-09T03:40:48.040235","exception":false,"start_time":"2024-12-09T03:40:45.404003","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"db25fb34","cell_type":"markdown","source":"### Beta-Galactosidase Close-Up\n\nSame for beta-galactosidase.","metadata":{"papermill":{"duration":0.213989,"end_time":"2024-12-09T03:40:48.497661","exception":false,"start_time":"2024-12-09T03:40:48.283672","status":"completed"},"tags":[]}},{"id":"fc8977e4","cell_type":"code","source":"# {'x': 804.615, 'y': 1977.846, 'z': 489.385}\nfig = plt.figure(figsize=(10,2.5))\nax = plt.subplot(1, 4, 1)\nplt.xticks([])\nplt.yticks([])\nplt.title('Original')\nplt.imshow(z_ts_6_4[0][48], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter([804.615/10], [1977.846/10], edgecolor='red', facecolor='none')\nax = plt.subplot(1, 4, 2)\nplt.xticks([])\nplt.yticks([])\nplt.title('Straight On')\nplt.imshow(z_ts_6_4[0][48, 175:219, 58:102], cmap='gray')\nax = plt.subplot(1, 4, 3)\nplt.xticks([])\nplt.yticks([])\nplt.title('Side View')\nplt.imshow(np.transpose(z_ts_6_4[0], axes=(2,1,0))[80, 175:219, 26:70], cmap='gray')\nax = plt.subplot(1, 4, 4)\nplt.xticks([])\nplt.yticks([])\nplt.title('Top View')\n_ = plt.imshow(np.transpose(z_ts_6_4[0], axes=(1,0,2))[197, 26:70, 58:102], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:08.834945Z","iopub.execute_input":"2024-12-09T22:27:08.835382Z","iopub.status.idle":"2024-12-09T22:27:11.426443Z","shell.execute_reply.started":"2024-12-09T22:27:08.835333Z","shell.execute_reply":"2024-12-09T22:27:11.425257Z"},"papermill":{"duration":2.570091,"end_time":"2024-12-09T03:40:51.280439","exception":false,"start_time":"2024-12-09T03:40:48.710348","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"22b0b2ca","cell_type":"markdown","source":"### Thyroglobulin Close-Up\n\nSame for thyroglobulin.","metadata":{"papermill":{"duration":0.21397,"end_time":"2024-12-09T03:40:51.743118","exception":false,"start_time":"2024-12-09T03:40:51.529148","status":"completed"},"tags":[]}},{"id":"715ffa38","cell_type":"code","source":"# {'x': 1242.919, 'y': 1464.644, 'z': 581.353}\nfig = plt.figure(figsize=(10,2.5))\nax = plt.subplot(1, 4, 1)\nplt.xticks([])\nplt.yticks([])\nplt.title('Original')\nplt.imshow(z_ts_6_4[0][58], cmap='gray', vmin=-0.00005, vmax=0.00005)\n_ = plt.scatter([1242.919/10], [1464.644/10], edgecolor='red', facecolor='none')\nax = plt.subplot(1, 4, 2)\nplt.xticks([])\nplt.yticks([])\nplt.title('Straight On')\n_ = plt.scatter([1242.919/10], [1464.644/10], edgecolor='red', facecolor='none')\nplt.imshow(z_ts_6_4[0][58, 124:168, 102:146], cmap='gray')\nax = plt.subplot(1, 4, 3)\nplt.xticks([])\nplt.yticks([])\nplt.title('Side View')\nplt.imshow(np.transpose(z_ts_6_4[0], axes=(2,1,0))[124, 175:219, 36:80], cmap='gray')\nax = plt.subplot(1, 4, 4)\nplt.xticks([])\nplt.yticks([])\nplt.title('Top View')\n_ = plt.imshow(np.transpose(z_ts_6_4[0], axes=(1,0,2))[146, 36:80, 102:146], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:11.428001Z","iopub.execute_input":"2024-12-09T22:27:11.428332Z","iopub.status.idle":"2024-12-09T22:27:13.981564Z","shell.execute_reply.started":"2024-12-09T22:27:11.428300Z","shell.execute_reply":"2024-12-09T22:27:13.980224Z"},"papermill":{"duration":2.56778,"end_time":"2024-12-09T03:40:54.523354","exception":false,"start_time":"2024-12-09T03:40:51.955574","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"89c3b396","cell_type":"markdown","source":"### Low Res from the Side\n\nHere is the low resolution version plotted from the rigth side moving from the far side to the near side.  The point of doing this is to get a look at the overall image quality from the side.","metadata":{"papermill":{"duration":0.215722,"end_time":"2024-12-09T03:40:54.989046","exception":false,"start_time":"2024-12-09T03:40:54.773324","status":"completed"},"tags":[]}},{"id":"22342cd6","cell_type":"code","source":"fig = plt.figure(figsize=(10,64))\nfor i in range(158):\n    ax = plt.subplot(18, 9, i + 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(np.transpose(z_ts_6_4[2], axes=(2,1,0))[i])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:13.983300Z","iopub.execute_input":"2024-12-09T22:27:13.983808Z","iopub.status.idle":"2024-12-09T22:27:29.401291Z","shell.execute_reply.started":"2024-12-09T22:27:13.983756Z","shell.execute_reply":"2024-12-09T22:27:29.399902Z"},"papermill":{"duration":15.588554,"end_time":"2024-12-09T03:41:10.793161","exception":false,"start_time":"2024-12-09T03:40:55.204607","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"9ad1e592","cell_type":"markdown","source":"### Low Res from the Top\nSame idea from the top.  Images proceed from top to bottom of the volume.","metadata":{"papermill":{"duration":0.340017,"end_time":"2024-12-09T03:41:11.472216","exception":false,"start_time":"2024-12-09T03:41:11.132199","status":"completed"},"tags":[]}},{"id":"5886005e","cell_type":"code","source":"fig = plt.figure(figsize=(10,64))\nfor i in range(158):\n    ax = plt.subplot(53, 3, i + 1)\n    plt.xticks([])\n    plt.yticks([])\n    plt.imshow(np.transpose(z_ts_6_4[2], axes=(1,0,2))[i])","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:29.403023Z","iopub.execute_input":"2024-12-09T22:27:29.403448Z","iopub.status.idle":"2024-12-09T22:27:45.188554Z","shell.execute_reply.started":"2024-12-09T22:27:29.403404Z","shell.execute_reply":"2024-12-09T22:27:45.186606Z"},"papermill":{"duration":15.423886,"end_time":"2024-12-09T03:41:27.221715","exception":false,"start_time":"2024-12-09T03:41:11.797829","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"cc437f15","cell_type":"markdown","source":"### Deformation along the Z-axis\n\nReturning to the ribosome, the same views are displayed with the side and top views elongated along the z-axis.  A red circle is displayed to indicate the 150 unit radius around the central point.  The images pretty clearly show that the ribosome does not stay within the radius.\n\n### Straight On","metadata":{"papermill":{"duration":0.421222,"end_time":"2024-12-09T03:41:28.059717","exception":false,"start_time":"2024-12-09T03:41:27.638495","status":"completed"},"tags":[]}},{"id":"b818dda4","cell_type":"code","source":"# {'x': 5106.838, 'y': 4835.263, 'z': 619.225}\nplt.xticks([])\nplt.yticks([])\ncircle = plt.Circle((22,22), radius=15, facecolor='none', edgecolor='r')\nplt.gca().add_patch(circle)\n_ = plt.imshow(z_ts_6_4[0][61, 461:505, 488:532], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:45.190118Z","iopub.execute_input":"2024-12-09T22:27:45.190465Z","iopub.status.idle":"2024-12-09T22:27:45.430431Z","shell.execute_reply.started":"2024-12-09T22:27:45.190429Z","shell.execute_reply":"2024-12-09T22:27:45.429021Z"},"papermill":{"duration":0.633752,"end_time":"2024-12-09T03:41:29.100743","exception":false,"start_time":"2024-12-09T03:41:28.466991","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"8f2cb857","cell_type":"markdown","source":"### Side View","metadata":{"papermill":{"duration":0.414523,"end_time":"2024-12-09T03:41:29.922630","exception":false,"start_time":"2024-12-09T03:41:29.508107","status":"completed"},"tags":[]}},{"id":"26ba934a","cell_type":"code","source":"from matplotlib.patches import Circle\nplt.xticks([])\nplt.yticks([])\ncircle = plt.Circle((37,22), radius=15, facecolor='none', edgecolor='r')\nplt.gca().add_patch(circle)\n_ = plt.imshow(np.transpose(z_ts_6_4[0], axes=(2,1,0))[510, 461:505, 24:98], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:45.432112Z","iopub.execute_input":"2024-12-09T22:27:45.432706Z","iopub.status.idle":"2024-12-09T22:27:46.357361Z","shell.execute_reply.started":"2024-12-09T22:27:45.432640Z","shell.execute_reply":"2024-12-09T22:27:46.355987Z"},"papermill":{"duration":1.301651,"end_time":"2024-12-09T03:41:31.635600","exception":false,"start_time":"2024-12-09T03:41:30.333949","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"3652d1be","cell_type":"markdown","source":"### Top View","metadata":{"papermill":{"duration":0.461746,"end_time":"2024-12-09T03:41:32.585004","exception":false,"start_time":"2024-12-09T03:41:32.123258","status":"completed"},"tags":[]}},{"id":"cd7a6817","cell_type":"code","source":"fig = plt.figure(figsize=(5,6))\nplt.xticks([])\nplt.yticks([])\ncircle = plt.Circle((22,37), radius=15, facecolor='none', edgecolor='r')\nplt.gca().add_patch(circle)\n_ = plt.imshow(np.transpose(z_ts_6_4[0], axes=(1,0,2))[483, 24:98, 488:532], cmap='gray')","metadata":{"execution":{"iopub.status.busy":"2024-12-09T22:27:46.359027Z","iopub.execute_input":"2024-12-09T22:27:46.359573Z","iopub.status.idle":"2024-12-09T22:27:47.259130Z","shell.execute_reply.started":"2024-12-09T22:27:46.359511Z","shell.execute_reply":"2024-12-09T22:27:47.257693Z"},"papermill":{"duration":1.299696,"end_time":"2024-12-09T03:41:34.313056","exception":false,"start_time":"2024-12-09T03:41:33.013360","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"17c5fc41","cell_type":"markdown","source":"## Make Training Crops\n\nFor the training crops, we can use the centroids, except where they are too close to the edge.  For that situation we might as well shift them across a bit first. And while we're at it, let's set aside a sensible number of crops of empty space from around our regions of interest, and call those 'empty'.","metadata":{}},{"id":"c7f19f57","cell_type":"code","source":"HALF = cfg.CROP_SIZE//2\ndf['x_v'] = round(df['x'] / cfg.ZARR_SCALE).astype(int).clip(lower=HALF, upper=630-HALF) # 8 - 622\ndf['y_v'] = round(df['y'] / cfg.ZARR_SCALE).astype(int).clip(lower=HALF, upper=630-HALF) # 8 - 622\ndf['z_v'] = round(df['z'] / cfg.ZARR_SCALE).astype(int).clip(lower=HALF, upper=184-HALF) # 8 - 176\ndf['x_start'], df['x_end'] = df['x_v'] - HALF, df['x_v'] + HALF\ndf['y_start'], df['y_end'] = df['y_v'] - HALF, df['y_v'] + HALF\ndf['z_start'], df['z_end'] = df['z_v'] - HALF, df['z_v'] + HALF\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:27:47.260798Z","iopub.execute_input":"2024-12-09T22:27:47.261864Z","iopub.status.idle":"2024-12-09T22:27:47.326550Z","shell.execute_reply.started":"2024-12-09T22:27:47.261793Z","shell.execute_reply":"2024-12-09T22:27:47.325185Z"}},"outputs":[],"execution_count":null},{"id":"3d8e0caf","cell_type":"code","source":"def check_for_overlap(df, \n                      sample_id,\n                      size,\n                      proposal, \n                      overlap, \n                      scale):\n    poi = df[['x_v', 'y_v', 'z_v']].to_numpy()   #existing points of interest\n    difference = np.abs(poi -proposal)    #  - proposal   where proposal is a 3x1 array\n    if np.any(np.all(difference < overlap, axis=1)):\n        return None\n    else:\n        empty = {'sample_id': sample_id,\n                 'object_type': 'empty',\n                 'x': proposal[0] * scale,\n                 'y': proposal[1] * scale,\n                 'z': proposal[2] * scale,\n                 'Size (A)': 100,\n                 'Size (V)': 10,\n                 'Vol (V3)': 100,\n                 'x_v': proposal[0],\n                 'y_v': proposal[1],\n                 'z_v': proposal[2],\n                 'x_start': proposal[0] - size // 2,  #eg 8 -> 0, with a block size of 16\n                 'x_end': proposal[0] + size // 2,    #eg 8 -> 16,  with a block size of 16\n                 'y_start': proposal[1] - size // 2,  \n                 'y_end': proposal[1] + size // 2,\n                 'z_start': proposal[2]  - size // 2,\n                 'z_end': proposal[2]  + size // 2}\n        return empty\n\ndef generate_proposal(x_lim, y_lim, z_lim, buffer, samples):\n    x_p = np.random.randint(buffer, x_lim - buffer)\n    y_p = np.random.randint(buffer, y_lim - buffer)\n    z_p = np.random.randint(buffer, z_lim - buffer)\n    sample = random.choice(samples)\n    return np.array([x_p, y_p, z_p]), sample\n\nempties=[]\nwhile len(empties) < cfg.NUM_EMPTY:\n    proposal, sample = generate_proposal(630, 630, 184, cfg.CROP_SIZE // 2, paths.TRAIN_NMS)\n    empty = check_for_overlap(df, sample, 16, proposal, 10, cfg.ZARR_SCALE)\n    if empty is not None:\n        empties.append(empty)\n\nempty_df = pd.DataFrame(empties)\nempty_df.head(3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:27:47.328525Z","iopub.execute_input":"2024-12-09T22:27:47.329108Z","iopub.status.idle":"2024-12-09T22:27:47.705155Z","shell.execute_reply.started":"2024-12-09T22:27:47.329043Z","shell.execute_reply":"2024-12-09T22:27:47.704032Z"}},"outputs":[],"execution_count":null},{"id":"30389340","cell_type":"code","source":"df = pd.concat([df, empty_df], ignore_index=True)\n\ndf['x_dif'] = df['x_end'] - df['x_start']\ndf['y_dif'] = df['y_end'] - df['y_start']\ndf['z_dif'] = df['z_end'] - df['z_start']\n\ndf.head(3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:27:47.706578Z","iopub.execute_input":"2024-12-09T22:27:47.706929Z","iopub.status.idle":"2024-12-09T22:27:47.729440Z","shell.execute_reply.started":"2024-12-09T22:27:47.706896Z","shell.execute_reply":"2024-12-09T22:27:47.728336Z"}},"outputs":[],"execution_count":null},{"id":"c5b05d4d","cell_type":"code","source":"df['x_dif'].unique()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:27:47.730908Z","iopub.execute_input":"2024-12-09T22:27:47.731234Z","iopub.status.idle":"2024-12-09T22:27:47.748181Z","shell.execute_reply.started":"2024-12-09T22:27:47.731203Z","shell.execute_reply":"2024-12-09T22:27:47.747085Z"}},"outputs":[],"execution_count":null},{"id":"75de0cff","cell_type":"code","source":"def process_tomo(sample, group, paths):\n    '''Open the zarr file, access the highest resolution scan, and save the crop as Unsigned 8-bit integer'''\n    tomo = zarr.open(str(paths.TRAIN_DN_ZARS[sample]), mode='r')\n    slicing_cols = ['object_type','x_start', 'x_end', 'y_start', 'y_end', 'z_start', 'z_end']\n    records = group[slicing_cols].to_dict(orient='records')\n    print(f'{len(group)} record were found in sample {sample}')\n    \n    for idx, row in enumerate(records):\n        crop = tomo[0][row['z_start']:row['z_end'],\n                       row['y_start']:row['y_end'],\n                       row['x_start']:row['x_end']]\n        type=row['object_type']\n\n        lower, upper = np.percentile(crop, (0.5, 99.5))\n        clipped = np.clip(crop, lower, upper)\n        scaled = ((clipped - lower) / (upper - lower + 1e-12) * 255).astype(np.uint8)\n        np.save(paths.DESTN_FLDRS[type] / f'{sample}_{idx}.npy', scaled)\n        \n    \nfor sample_id, group in df.groupby('sample_id'):\n    process_tomo(sample_id, group, paths)\n\nnpy_files = list(paths.RESULTS_FLDR.rglob('*.npy'))\nprint(f'{len(npy_files)} files were saved as numpy arrays')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:27:47.749520Z","iopub.execute_input":"2024-12-09T22:27:47.749963Z","iopub.status.idle":"2024-12-09T22:30:05.226639Z","shell.execute_reply.started":"2024-12-09T22:27:47.749931Z","shell.execute_reply":"2024-12-09T22:30:05.225332Z"}},"outputs":[],"execution_count":null},{"id":"91e82c4d","cell_type":"markdown","source":"### Varify the crops\n\nNow let's take a quick look at the result, just by examining some planes through the centre of the crop to get an idea if this is something the could looks like it could be classified.  I'll look seperately at each class.  The cell can be re-run to generate a new random example.","metadata":{}},{"id":"bd1ff746-667e-4528-9798-846091751ea2","cell_type":"code","source":"def plot_random_cube(path, size):\n    crop = np.load(path)\n    cube_type = Path(path).parent.name  # Assuming `path` is a Path object\n    slices = [\n        (crop[0, :, :], 'Slice 0 along z axis'),\n        (crop[1, :, :], 'Slice 1 along z axis'),\n        (crop[2, :, :], 'Slice 2 along z axis'),\n        (crop[3, :, :], 'Slice 3 along z axis'),\n        (crop[4, :, :], 'Slice 4 along z axis'),\n        (crop[5, :, :], 'Slice 5 along z axis'),\n        (crop[6, :, :], 'Slice 6 along z axis'),\n        (crop[7, :, :], 'Slice 7 along z axis'),\n        (crop[8, :, :], 'Slice 8 along z axis'),\n        (crop[9, :, :], 'Slice 9 along z axis'),\n        (crop[:, 3, :], 'Slice 3 along y axis'),\n        (crop[:, :, 3], 'Slice 3 along x axis')\n    ]\n    \n    fig, axes = plt.subplots(3, 4, figsize=(10, 10))\n    axes = axes.flat\n    \n    for ax, (slice_data, title) in zip(axes, slices):\n        ax.imshow(slice_data, cmap='gray')\n        ax.set_title(title)\n        ax.axis('off')\n    \n    plt.tight_layout()\n    text = f'Plotting a sample of {cube_type}, with shape {crop.shape}'\n    fig.suptitle(text, fontsize=14)\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:30:05.228176Z","iopub.execute_input":"2024-12-09T22:30:05.228575Z","iopub.status.idle":"2024-12-09T22:30:05.239069Z","shell.execute_reply.started":"2024-12-09T22:30:05.228539Z","shell.execute_reply":"2024-12-09T22:30:05.237745Z"}},"outputs":[],"execution_count":null},{"id":"d6f8455b-22fb-4db1-a3f7-5c15b3b9f7ef","cell_type":"code","source":"paths.DESTN_FLDRS['apo-ferritin']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:30:05.240539Z","iopub.execute_input":"2024-12-09T22:30:05.240960Z","iopub.status.idle":"2024-12-09T22:30:05.265215Z","shell.execute_reply.started":"2024-12-09T22:30:05.240924Z","shell.execute_reply":"2024-12-09T22:30:05.263853Z"}},"outputs":[],"execution_count":null},{"id":"d60909bb-5db1-4073-bbea-5500d4212c09","cell_type":"code","source":"apo_ferritins = list(paths.DESTN_FLDRS['apo-ferritin'].rglob('*.npy'))\nrandom_apo = random.choice(apo_ferritins)\nplot_random_cube(random_apo, 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:30:05.267235Z","iopub.execute_input":"2024-12-09T22:30:05.267587Z","iopub.status.idle":"2024-12-09T22:30:06.321927Z","shell.execute_reply.started":"2024-12-09T22:30:05.267552Z","shell.execute_reply":"2024-12-09T22:30:06.320817Z"}},"outputs":[],"execution_count":null},{"id":"8bba3065-e5ac-43b9-9d37-88caed23dea2","cell_type":"code","source":"betas = list(paths.DESTN_FLDRS['beta-amylase'].rglob('*.npy'))\nrandom_file = random.choice(betas)\nplot_random_cube(random_file, 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:30:06.323108Z","iopub.execute_input":"2024-12-09T22:30:06.323392Z","iopub.status.idle":"2024-12-09T22:30:07.277328Z","shell.execute_reply.started":"2024-12-09T22:30:06.323363Z","shell.execute_reply":"2024-12-09T22:30:07.276167Z"}},"outputs":[],"execution_count":null},{"id":"b2a5805d-4307-431e-9b2b-faeadcebd373","cell_type":"code","source":"beta_gs = list(paths.DESTN_FLDRS['beta-galactosidase'].rglob('*.npy'))\nrandom_file = random.choice(beta_gs)\nplot_random_cube(random_file, 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:30:07.279002Z","iopub.execute_input":"2024-12-09T22:30:07.279455Z","iopub.status.idle":"2024-12-09T22:30:08.328667Z","shell.execute_reply.started":"2024-12-09T22:30:07.279398Z","shell.execute_reply":"2024-12-09T22:30:08.327302Z"}},"outputs":[],"execution_count":null},{"id":"ac649f90-c7d0-4b08-9c38-26ba86c6c945","cell_type":"code","source":"empties = list(paths.DESTN_FLDRS['empty'].rglob('*.npy'))\nrandom_file = random.choice(empties)\nplot_random_cube(random_file, 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:31:46.492155Z","iopub.execute_input":"2024-12-09T22:31:46.492702Z","iopub.status.idle":"2024-12-09T22:31:47.457056Z","shell.execute_reply.started":"2024-12-09T22:31:46.492652Z","shell.execute_reply":"2024-12-09T22:31:47.455729Z"}},"outputs":[],"execution_count":null},{"id":"ff40feb6-bbfa-45c1-97d3-fef5edfff0d7","cell_type":"code","source":"ribosome = list(paths.DESTN_FLDRS['ribosome'].rglob('*.npy'))\nrandom_file = random.choice(ribosome)\nplot_random_cube(random_file, 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:30:09.837188Z","iopub.execute_input":"2024-12-09T22:30:09.837652Z","iopub.status.idle":"2024-12-09T22:30:10.780065Z","shell.execute_reply.started":"2024-12-09T22:30:09.837583Z","shell.execute_reply":"2024-12-09T22:30:10.778881Z"}},"outputs":[],"execution_count":null},{"id":"5d27fc8e-43cb-46e8-b78f-dc96873a19d3","cell_type":"code","source":"thyros = list(paths.DESTN_FLDRS['thyroglobulin'].rglob('*.npy'))\nrandom_file = random.choice(thyros)\nplot_random_cube(random_file, 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:30:10.781462Z","iopub.execute_input":"2024-12-09T22:30:10.781806Z","iopub.status.idle":"2024-12-09T22:30:11.742085Z","shell.execute_reply.started":"2024-12-09T22:30:10.781774Z","shell.execute_reply":"2024-12-09T22:30:11.740883Z"}},"outputs":[],"execution_count":null},{"id":"b457e7ff-2f2a-4154-9c30-25e023585150","cell_type":"code","source":"virus = list(paths.DESTN_FLDRS['beta-galactosidase'].rglob('*.npy'))\nrandom_file = random.choice(virus)\nplot_random_cube(random_file, 16)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-09T22:30:11.743473Z","iopub.execute_input":"2024-12-09T22:30:11.743860Z","iopub.status.idle":"2024-12-09T22:30:12.688773Z","shell.execute_reply.started":"2024-12-09T22:30:11.743824Z","shell.execute_reply":"2024-12-09T22:30:12.687590Z"}},"outputs":[],"execution_count":null},{"id":"bc0f33f3","cell_type":"markdown","source":"## Conclusion\n\n- It remains to be seen whether single-stage classification, like U-Net or YOLO,  will out-perform a two stage concepts like I'm working on here.  But there is potentially a huge efficiency advantage to building very small models just on proposed regions of interest, rather than uniformly classifying the whole volume.\n- Looking through the above cells a few times, it looks like most, but often not quite all the particles are covered by 16x16x16 crops.  But it would be a good idea to re-visit larger crop sizes too.\n- It isn't all that clear just from inspecting like this how best to make best use of the 3d nature of these scans.  I will leave that for experimentation.\n- The dataset is reasonably well balanced, but smaller than I'm familiar with from past projects.  Augmentation will likely be very important for this competition.\n- As was noted in [David's original notebook](https://www.kaggle.com/code/davidlist/experiment-ts-6-4-visualization), there is elongation in the z axis.  See discussion here: [https://www.kaggle.com/competitions/czii-cryo-et-object-identification/discussion/545742](https://www.kaggle.com/competitions/czii-cryo-et-object-identification/discussion/545742)\n\nThanks to David, and others for their great visualisations so far.   This is my first foray into medical physics.  It seems to be quite a difficult to get startarted, but a fascinating competition to understand properly.  Good luck to all.","metadata":{"papermill":{"duration":0.408338,"end_time":"2024-12-09T03:41:35.184372","exception":false,"start_time":"2024-12-09T03:41:34.776034","status":"completed"},"tags":[]}}]}