Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev #176

Merged
merged 27 commits into from
May 8, 2023
Merged

Dev #176

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bdcef96
Merge pull request #169 from NIEHS/stable
JoQCcoz Apr 11, 2023
c15b443
fixed issue with missing method in fakescope
JoQCcoz Apr 13, 2023
44ece4f
Merge pull request #170 from JoQCcoz/0.9-debug
JoQCcoz Apr 13, 2023
b0d7797
Added plotly and yamlCLI as requirements
JoQCcoz Apr 20, 2023
87936ba
Merge pull request #171 from JoQCcoz/cli_plot
JoQCcoz Apr 20, 2023
8f7ff9a
Added plotly and yamlCLI as requirements
JoQCcoz Apr 20, 2023
8c2a949
updated base image to cuda 12
JoQCcoz Apr 20, 2023
90db928
Merge branch 'dev' of github.com:NIEHS/SmartScope into dev
JoQCcoz Apr 20, 2023
78c9c2c
Timezone and DB options
JoQCcoz Apr 27, 2023
9633797
removed fast atlas from main repo
JoQCcoz Apr 27, 2023
4affb24
ability to interact with preprocessing pipeline
JoQCcoz May 1, 2023
4439c60
added download buttons to the highmag maps
JoQCcoz May 1, 2023
65fd7a6
initial ability to dl svg as png
JoQCcoz May 2, 2023
556444b
removed canvag from cnd list
JoQCcoz May 2, 2023
11c564e
enabled coma vs image-shift BIS
JoQCcoz May 2, 2023
a058b54
fix issue with crash on zero targets found
JoQCcoz May 2, 2023
735fe1b
change version
JoQCcoz May 2, 2023
76d6f48
Merge branch 'dev' into cli_plot
JoQCcoz May 2, 2023
fba22cd
Merge pull request #172 from JoQCcoz/cli_plot
JoQCcoz May 2, 2023
5208427
preprocessing sidebar fixes
JoQCcoz May 3, 2023
42c2c9e
debug new preprocessing actions
JoQCcoz May 4, 2023
785dbcd
Merge pull request #173 from JoQCcoz/cli_plot
JoQCcoz May 4, 2023
2dcd5ce
finalize preprocessing sidebar
JoQCcoz May 5, 2023
53f5598
Merge pull request #174 from JoQCcoz/cli_plot
JoQCcoz May 5, 2023
d321fbb
Fix issue with new version of chrome
JoQCcoz May 6, 2023
e751d6b
Merge pull request #175 from JoQCcoz/cli_plot
JoQCcoz May 6, 2023
bf1faeb
fixed issue in dockerfile
JoQCcoz May 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@ docker-compose.yml.bak
.config
.python_history
MyDocker/*

.ipython
.mysql_history
.gitignore
.ipython/profile_default/history.sqlite
11 changes: 11 additions & 0 deletions .ipython/profile_default/startup/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
This is the IPython startup directory

.py and .ipy files in this directory will be run *prior* to any code or files specified
via the exec_lines or exec_files configurables whenever you load this profile.

Files will be run in lexicographical order, so you can control the execution order of files
with a prefix, e.g.::

00-first.py
50-middle.py
99-last.ipy
30 changes: 7 additions & 23 deletions Docker/Dockerfile-base
Original file line number Diff line number Diff line change
@@ -1,50 +1,34 @@
FROM nvidia/cuda:10.1-base-ubuntu18.04

FROM nvidia/cuda:12.1.0-base-ubuntu18.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
python3-dev default-libmysqlclient-dev build-essential wget libglib2.0-0 ffmpeg libsm6 libxext6 curl mariadb-server && \
apt-get clean && rm -rf /var/cache/apt/lists

# RUN service mariadb stop && service mariadb disable

RUN wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh && \
bash Miniconda3-latest-Linux-x86_64.sh -b -p /opt/miniconda3 && \
rm Miniconda3-latest-Linux-x86_64.sh

RUN wget https://bio3d.colorado.edu/imod/AMD64-RHEL5/imod_4.11.15_RHEL7-64_CUDA10.1.sh && \
yes | bash imod_4.11.15_RHEL7-64_CUDA10.1.sh -name IMOD && \
rm imod_4.11.15_RHEL7-64_CUDA10.1.sh
RUN wget https://bio3d.colorado.edu/imod/AMD64-RHEL5/imod_4.11.24_RHEL7-64_CUDA10.1.sh && ls && \
yes | bash imod_4.11.24_RHEL7-64_CUDA10.1.sh -name IMOD && \
rm imod_4.11.24_RHEL7-64_CUDA10.1.sh

ADD config/singularity/ctffind /usr/local/

ADD config/docker/requirements.txt .

# RUN mkdir /opt/logs/ /mnt/fake_scope/ /mnt/fake_scope/raw/ /opt/nginx-mount/



ENV PATH=$PATH:/opt/smartscope/Smartscope/bin:/opt/miniconda3/bin:$IMOD_DIR/bin
ENV PATH=$PATH:/opt/miniconda3/bin

RUN conda update -y conda && \
yes | conda install python=3.9 cudatoolkit=10.2 cudnn=7.6 && \
yes | conda install python=3.9 cudatoolkit=10.2 cudnn=7.6 git && \
yes | pip install numpy==1.21.0 && \
yes | pip install torch==1.8.2 torchvision==0.9.2 torchaudio==0.8.2 --extra-index-url https://download.pytorch.org/whl/lts/1.8/cu102 && \
yes | pip install -r requirements.txt && \
yes | pip install ipython && \
yes | pip install sphinx-multiversion && \
conda clean --all

# RUN wget docs.smartscope.org/downloads/Smartscope0.6.tar.gz --no-check-certificate &&\
# tar -xvf Smartscope0.6.tar.gz -C /opt/ &&\
# rm Smartscope0.6.tar.gz

# create a non-root user
ARG USER_ID=9999

RUN useradd -m --no-log-init --system --uid $USER_ID smartscope_user

# RUN chmod 777 -R /mnt/ && \
# chmod 777 /opt/logs/ && \
# chmod 777 /opt/nginx-mount/
RUN useradd -m --no-log-init --system --uid $USER_ID smartscope_user
4 changes: 3 additions & 1 deletion Docker/Dockerfile-smartscope
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@ ENV ALLOWED_HOSTS=localhost \
MYSQL_HOST=db \
MYSQL_PORT=3306 \
MYSQL_USERNAME=root \
MYSQL_ROOT_PASSWORD=pass \
MYSQL_PASSWORD=pass \
DB_NAME=smartscope \
REDIS_HOST=cache \
REDIS_PORT=6379 \
USE_AWS=False \
FORCE_CPU=False

ENV PATH=$PATH:/opt/smartscope/Smartscope/bin:/usr/local/IMOD/bin

ADD . /opt/smartscope/

RUN wget docs.smartscope.org/downloads/Smartscope0.6.tar.gz --no-check-certificate && \
Expand Down
7 changes: 5 additions & 2 deletions Docker/SmartScope/database.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
MYSQL_USER=root
MYSQL_ROOT_PASSWORD=pass
MYSQL_DATABASE=smartscope
MYSQL_PASSWORD=pass
MYSQL_DATABASE=smartscope
MYSQL_HOST=db
MYSQL_PORT=3306
MYSQL_SSL=False
4 changes: 1 addition & 3 deletions Docker/SmartScope/smartscope.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@ ALLOWED_HOSTS=localhost
AUTO_MIGRATION=true
USE_SSL=false
USE_LONGTERMSTORAGE=False
TIMEZONE=America/New_York

### EXPERT SETTINGS ###
### EVERYTHING BELOW SHOULD NOT NEED TO BE CHANGED###
#Other database settings
# MYSQL_HOST=db
# MYSQL_PORT=3306

# #Executables
# IMOD_DIR=/usr/local/IMOD
Expand Down
1 change: 1 addition & 0 deletions Smartscope/bin/smartscope.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import logging
from Smartscope.core.main_commands import main


logger = logging.getLogger(__name__)


Expand Down
3 changes: 3 additions & 0 deletions Smartscope/bin/smartscope.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

smartscope.py $@ &
25 changes: 15 additions & 10 deletions Smartscope/core/autoscreen.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os
import sys
import time
import shlex
from Smartscope.core.microscope_interfaces import FakeScopeInterface, TFSSerialemInterface, JEOLSerialemInterface
from Smartscope.core.selectors import selector_wrapper
from Smartscope.core.models import ScreeningSession, HoleModel, SquareModel, Process, HighMagModel
Expand All @@ -13,6 +12,7 @@
from Smartscope.core.protocols import get_or_set_protocol
from Smartscope.lib.Datatypes.microscope import Microscope,Detector,AtlasSettings
from Smartscope.lib.preprocessing_methods import processing_worker_wrapper
from Smartscope.core.preprocessing_pipelines import load_preprocessing_pipeline
from Smartscope.lib.file_manipulations import get_file_and_process, create_grid_directories
from Smartscope.lib.transformations import register_to_other_montage, register_targets_by_proximity
from Smartscope.core.db_manipulations import update, select_n_areas, queue_atlas, add_targets, group_holes_for_BIS
Expand All @@ -23,7 +23,6 @@
from django.utils import timezone
import multiprocessing
import logging
import subprocess
import numpy as np
from pathlib import Path

Expand Down Expand Up @@ -104,18 +103,20 @@ def run_grid(grid, session, processing_queue, scope):
session (ScreeningSession): ScreeningSession object from Smartscope.server.models
"""

if grid.status == 'complete':
logger.info(f'{grid.name} already complete')
return
if grid.status == 'aborting':
logger.info(f'Aborting {grid.name}')
return


session_id = session.pk
microscope = session.microscope_id

# Set the Websocket_update_decorator grid property
update.grid = grid
if grid.status == 'complete':
logger.info(f'{grid.name} already complete')
return
if grid.status == 'aborting':
logger.info(f'Aborting {grid.name}')
update(grid, status='complete')
return

logger.info(f'Starting {grid.name}')

Expand All @@ -131,7 +132,8 @@ def run_grid(grid, session, processing_queue, scope):
# ADD the new protocol loader
protocol = get_or_set_protocol(grid)
resume_incomplete_processes(processing_queue, grid, session.microscope_id)
subprocess.Popen(shlex.split(f'smartscope.py highmag_processing smartscopePipeline {grid.grid_id} 1'))
preprocessing = load_preprocessing_pipeline(Path('preprocessing.json'))
preprocessing.start(grid)
is_stop_file(session_id)
atlas = queue_atlas(grid)
scope.loadGrid(grid.position)
Expand All @@ -141,7 +143,6 @@ def run_grid(grid, session, processing_queue, scope):
grid_type = grid.holeType
grid_mesh = grid.meshMaterial
if atlas.status == 'queued' or atlas.status == 'started':

atlas = update(atlas, status='started')
logger.info('Waiting on atlas file')
runAcquisition(scope,protocol.atlas.acquisition,params,atlas)
Expand All @@ -168,6 +169,7 @@ def run_grid(grid, session, processing_queue, scope):
grid = update(grid, refresh_from_db=True, last_update=None)
params = grid.params_id
if grid.status == 'aborting':
preprocessing.stop(grid)
break
else:
squares, holes = get_queue(grid)
Expand Down Expand Up @@ -370,6 +372,9 @@ def autoscreen(session_id):
except Exception as e:
logger.exception(e)
status = 'error'
if grid in locals():
update.grid = grid
update(grid, status='error')
except KeyboardInterrupt:
logger.info('Stopping Smartscope.py autoscreen')
status = 'killed'
Expand Down
12 changes: 5 additions & 7 deletions Smartscope/core/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

logger = logging.getLogger(__name__)


def save_multishot_from_cache(multishot_id, directory):
multishot = cache.get(multishot_id)
logger.debug(f'Getting multishot from cache at id {multishot_id}:\n{multishot}')
with open(Path(directory,'multishot.json'),'w') as f:
f.write(multishot)

def save_json_from_cache(item_id, directory, file_root_name):
cached_item = cache.get(item_id)
logger.debug(f'Getting {file_root_name} from cache at id {item_id}:\n{cached_item}')
with open(Path(directory,f'{file_root_name}.json'),'w') as f:
f.write(cached_item)
2 changes: 2 additions & 0 deletions Smartscope/core/finders.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ def find_targets(montage: Montage, methods: list):
logger.debug(f"{method} was successful: {success}, Is Classifier: {method.target_class is TargetClass.CLASSIFIER}")

return targets, method.name, method.name if method.target_class is TargetClass.CLASSIFIER else None, additional_outputs

return [], '', None, dict()
5 changes: 4 additions & 1 deletion Smartscope/core/microscope_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def reset_image_shift(self):
return sem.ResetImageShift()

def image_shift_by_microns(self,isX,isY,tiltAngle):
sem.ImageShiftByMicrons(isX - self.state.imageShiftX, isY - self.state.imageShiftY, 0)
sem.ImageShiftByMicrons(isX - self.state.imageShiftX, isY - self.state.imageShiftY, 0, 1)
self.state.imageShiftX = isX
self.state.imageShiftY = isY
sem.SetDefocus(self.state.currentDefocus - isY * math.sin(math.radians(tiltAngle)))
Expand Down Expand Up @@ -390,6 +390,9 @@ def medium_mag_hole(self, file=''):
def focusDrift(self, def1, def2, step, drifTarget):
pass

def tiltTo(self,tiltAngle):
pass

def highmag(self, file='', frames=True, earlyReturn=False):
if not frames:
generate_fake_file(file, 'highmag', sleeptime=7, destination_dir=self.microscope.scopePath)
Expand Down
5 changes: 4 additions & 1 deletion Smartscope/core/models/models_actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ def targets_methods(instance):
if (output:=cache.get(cache_key)) is not None:
logger.debug(f'Loading targets_method for {instance} from cache.')
return output
default_output = dict(finders=[], classifiers=[], selectors=[])
if not hasattr(instance,'targets'):
return default_output
targets = instance.targets.values_list('pk', flat=True)
if len(targets) == 0:
return dict(finders=[], classifiers=[], selectors=[])
return default_output
contenttype = ContentType.objects.get_for_model(instance.targets.first())

finders = list(Finder.objects.filter(content_type=contenttype, object_id__in=targets).values_list('method_name', flat=True).distinct())
Expand Down
11 changes: 5 additions & 6 deletions Smartscope/core/models/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ def targets(self):
return self.squaremodel_set.all()

# @cached_model_property(key_prefix='svg', extra_suffix_from_function=['method'], timeout=3600)
def toSVG(self, display_type, method):
def svg(self, display_type, method):
targets = list(SquareModel.display.filter(atlas_id=self.atlas_id))
return drawAtlas(self,targets , display_type, method)

Expand Down Expand Up @@ -782,7 +782,7 @@ def targets(self):


# @cached_model_property(key_prefix='svg', extra_suffix_from_function=['method'], timeout=3600)
def toSVG(self, display_type, method):
def svg(self, display_type, method):
holes = list(HoleModel.display.filter(square_id=self.square_id))
sq = drawSquare(self, holes, display_type, method)

Expand Down Expand Up @@ -883,7 +883,7 @@ def id(self):
return self.hole_id

# @cached_model_property(key_prefix='svg', extra_suffix_from_function=['method'], timeout=3600)
def toSVG(self, display_type, method):
def svg(self, display_type, method):
holes = list(self.targets)
if self.shape_x is None: # There was an error in previous version where shape wasn't set.
set_shape_values(self)
Expand Down Expand Up @@ -981,9 +981,8 @@ def parent(self):
def set_parent(self, parent):
self.hole_id = parent
# endaliases

@property
def SVG(self):

def svg(self, *args, **kwargs):
return drawHighMag(self)

@property
Expand Down
Loading