diff --git a/Dockerfile b/Dockerfile index fb0ce0b..3f510ea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,21 +1,37 @@ FROM rockylinux:8 -# install some base necessities -RUN dnf install -y git vim python39 python39-devel && \ - alternatives --set python /usr/bin/python3 +# Install necessary packages +RUN dnf install -y git vim tcsh libpng15 motif make curl clang zlib-devel \ + libXt-devel libXext-devel expat-devel motif-devel f2c unzip cmake gcc-c++ \ + epel-release && \ + dnf --enablerepo=powertools install -y libstdc++-static -# create a home directory +# Install Mambaforge +WORKDIR /tmp +RUN curl -L https://github.com/conda-forge/miniforge/releases/download/24.9.2-0/Mambaforge-24.9.2-0-Linux-x86_64.sh -o Mambaforge-24.9.2-0.sh && \ + chmod 755 Mambaforge-24.9.2-0.sh && \ + ./Mambaforge-24.9.2-0.sh -b -p /opt/conda && \ + rm Mambaforge-24.9.2-0.sh +ENV PATH=/opt/conda/bin:$PATH + +# Create a Conda environment with Python 3.13 +RUN conda create -n py313 python=3.13 python-freethreading -c conda-forge/label/python_rc -c conda-forge && \ + echo "conda activate py313" >> ~/.bashrc +ENV CONDA_DEFAULT_ENV=py313 +ENV PATH /opt/conda/envs/py313/bin:$PATH + +# Verify Python version +RUN python --version + +# Create a home directory RUN mkdir -p /home/scanbuddy ENV HOME=/home/scanbuddy -# compile and install 3dvolreg from AFNI (linux/amd64 and linux/arm64/v8) +# Compile and install 3dvolreg from AFNI (linux/amd64 and linux/arm64/v8) ARG AFNI_PREFIX="/sw/apps/afni" ARG AFNI_URI="https://github.com/afni/afni" WORKDIR /tmp -RUN dnf install -y epel-release && \ - dnf install -y curl tcsh python2-devel libpng15 motif && \ - dnf install -y make clang zlib-devel libXt-devel libXext-devel expat-devel motif-devel f2c && \ - git clone "${AFNI_URI}" +RUN git clone "${AFNI_URI}" WORKDIR afni/src RUN cp other_builds/Makefile.linux_ubuntu_22_64 Makefile && \ make libmri.a 3dvolreg && \ @@ -23,14 +39,12 @@ RUN cp other_builds/Makefile.linux_ubuntu_22_64 Makefile && \ mv 3dvolreg "${AFNI_PREFIX}" && \ rm -r /tmp/afni -# compile and install dcm2niix (linux/amd64 and linux/arm64/v8) +# Compile and install dcm2niix (linux/amd64 and linux/arm64/v8) ARG D2N_PREFIX="/sw/apps/dcm2niix" ARG D2N_VERSION="1.0.20220720" ARG D2N_URI="https://github.com/rordenlab/dcm2niix/archive/refs/tags/v${D2N_VERSION}.zip" -WORKDIR "/tmp" -RUN dnf install -y unzip cmake gcc-c++ && \ - dnf --enablerepo=powertools install -y libstdc++-static && \ - curl -sL "${D2N_URI}" -o "dcm2niix_src.zip" && \ +WORKDIR /tmp +RUN curl -sL "${D2N_URI}" -o "dcm2niix_src.zip" && \ unzip "dcm2niix_src.zip" && \ rm "dcm2niix_src.zip" && \ mkdir "dcm2niix-${D2N_VERSION}/build" @@ -41,23 +55,23 @@ RUN cmake .. && \ cp bin/dcm2niix "${D2N_PREFIX}" && \ rm -r "/tmp/dcm2niix-${D2N_VERSION}" -# install scanbuddy +# Install scanbuddy ARG SB_PREFIX="/sw/apps/scanbuddy" ARG SB_VERSION="v0.1.7" -RUN python3 -m venv "${SB_PREFIX}" && \ +RUN python -m venv "${SB_PREFIX}" && \ dnf install -y gcc zlib-devel libjpeg-devel python39-tkinter && \ "${SB_PREFIX}/bin/pip" install "git+https://github.com/harvard-nrg/scanbuddy.git@${SB_VERSION}" -# set up afni environment +# Set up AFNI environment ENV PATH="${AFNI_PREFIX}:${PATH}" -# set up dcm2niix environment +# Set up dcm2niix environment ENV PATH="${D2N_PREFIX}:${PATH}" -# set up scanbuddy +# Set up scanbuddy ENV TERM="xterm-256color" -# expose port +# Expose port EXPOSE 11112 -ENTRYPOINT ["/sw/apps/scanbuddy/bin/start.py"] +ENTRYPOINT ["/sw/apps/scanbuddy/bin/start.py"] \ No newline at end of file diff --git a/scanbuddy/proc/__init__.py b/scanbuddy/proc/__init__.py index 0e8fdc3..3577374 100644 --- a/scanbuddy/proc/__init__.py +++ b/scanbuddy/proc/__init__.py @@ -85,7 +85,7 @@ def listener(self, ds, path): insert_position = key - 5 self._fdata_array[:, :, :, insert_position] = self._slice_means[key]['slice_means'].squeeze() - if key > 53 and (key % 3 == 0) and key < self._num_vols: + if key > 53 and (key % 4 == 0) and key < self._num_vols: logger.info('launching calculate and publish snr thread') snr_thread = threading.Thread(target=self.calculate_and_publish_snr, args=(key,)) @@ -190,10 +190,12 @@ def get_mean_slice_intensitites(self, key): dim_t = key - 4 + ''' if key > 55: start = time.time() differing_slices = self.find_mask_differences(key) logger.info(f'finding mask differences took {time.time() - start}') + ''' slice_voxel_counts = np.zeros( (dim_z), dtype='uint32' ) @@ -221,31 +223,48 @@ def get_mean_slice_intensitites(self, key): slice_vol_mean = slice_data.mean() self._slice_intensity_means[slice_idx,volume_idx] = slice_vol_mean - logger.info(f'recalculating slice means at the following slices: {differing_slices}') - logger.info(f'total of {len(differing_slices)} new slices being computed') - - if differing_slices: - - if key == self._num_vols: - for volume_idx in range(dim_t): - for slice_idx in differing_slices: - slice_data = data[:,:,slice_idx,volume_idx] - slice_vol_mean = slice_data.mean() - self._slice_intensity_means[slice_idx,volume_idx] = slice_vol_mean - - elif key % 4 == 0: - for volume_idx in range(0, dim_t, 6): - for slice_idx in differing_slices: - slice_data = data[:,:,slice_idx,volume_idx] - slice_vol_mean = slice_data.mean() - self._slice_intensity_means[slice_idx,volume_idx] = slice_vol_mean - - elif key % 3 == 0: - for volume_idx in range(3, dim_t, 6): - for slice_idx in differing_slices: - slice_data = data[:,:,slice_idx,volume_idx] - slice_vol_mean = slice_data.mean() - self._slice_intensity_means[slice_idx,volume_idx] = slice_vol_mean + #logger.info(f'recalculating slice means at the following slices: {differing_slices}') + #logger.info(f'total of {len(differing_slices)} new slices being computed') + + #if differing_slices: + + if key == self._num_vols: + start = time.time() + differing_slices = self.find_mask_differences(key) + logger.info(f'finding mask differences took {time.time() - start}') + logger.info(f'recalculating slice means at the following slices: {differing_slices}') + logger.info(f'total of {len(differing_slices)} new slices being computed') + for volume_idx in range(dim_t): + for slice_idx in differing_slices: + slice_data = data[:,:,slice_idx,volume_idx] + slice_vol_mean = slice_data.mean() + self._slice_intensity_means[slice_idx,volume_idx] = slice_vol_mean + + elif key % 6 == 0: + logger.info(f'inside the even calculation') + start = time.time() + differing_slices = self.find_mask_differences(key) + logger.info(f'finding mask differences took {time.time() - start}') + logger.info(f'recalculating slice means at the following slices: {differing_slices}') + logger.info(f'total of {len(differing_slices)} new slices being computed') + for volume_idx in range(0, dim_t, 8): + for slice_idx in differing_slices: + slice_data = data[:,:,slice_idx,volume_idx] + slice_vol_mean = slice_data.mean() + self._slice_intensity_means[slice_idx,volume_idx] = slice_vol_mean + + elif key % 5 == 0: + logger.info(f'inside the odd calculation') + start = time.time() + differing_slices = self.find_mask_differences(key) + logger.info(f'finding mask differences took {time.time() - start}') + logger.info(f'recalculating slice means at the following slices: {differing_slices}') + logger.info(f'total of {len(differing_slices)} new slices being computed') + for volume_idx in range(5, dim_t, 8): + for slice_idx in differing_slices: + slice_data = data[:,:,slice_idx,volume_idx] + slice_vol_mean = slice_data.mean() + self._slice_intensity_means[slice_idx,volume_idx] = slice_vol_mean return self._slice_intensity_means[:, :dim_t], slice_voxel_counts, data @@ -276,17 +295,16 @@ def generate_mask(self, key): return masked_data def find_mask_differences(self, key): - num_old_vols = key - 7 - prev_mask = self._slice_means[key-3]['mask'] + num_old_vols = key - 8 + last_50 = num_old_vols - 50 + prev_mask = self._slice_means[key-4]['mask'] current_mask = self._slice_means[key]['mask'] - differences = prev_mask != current_mask[:,:,:,:num_old_vols] + differences = prev_mask[:,:,:,-50:] != current_mask[:,:,:,last_50:num_old_vols] diff_indices = np.where(differences) differing_slices = [] for index in zip(*diff_indices): if int(index[2]) not in differing_slices: differing_slices.append(int(index[2])) - #slices_to_update = differing_slices.sort() - #pdb.set_trace() return differing_slices