Skip to content

Commit

Permalink
parrt1
Browse files Browse the repository at this point in the history
  • Loading branch information
OleksandrZhynzher committed Sep 28, 2023
1 parent ce6c00e commit 89e07ba
Show file tree
Hide file tree
Showing 51 changed files with 4,882 additions and 4,299 deletions.
16 changes: 10 additions & 6 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
"es6": true
},
"root": true,
"parser": "babel-eslint",
"plugins": ["react", "prettier"],
"extends": ["eslint:recommended", "plugin:react/recommended", "prettier"],
"parser": "@typescript-eslint/parser",
"plugins": ["react", "prettier", "@typescript-eslint"],
"extends": ["eslint:recommended", "plugin:react/recommended", "prettier", "plugin:@typescript-eslint/recommended"],
"settings": {
"react": {
"createClass": "createReactClass",
Expand All @@ -28,6 +28,7 @@
"react/no-string-refs": "off",
"react/jsx-no-undef": "off",
"react/jsx-key": "off",
"react/react-in-jsx-scope": "off",
"no-case-declarations": "off",
"react/no-unescaped-entities": "off",
"linebreak-style": "off",
Expand All @@ -53,7 +54,7 @@
"no-multi-spaces": "off",
"no-prototype-builtins": "off",
"wrap-iife": ["error", "any"],
"no-use-before-define": ["error", "nofunc"],
"no-use-before-define": "off",
"object-property-newline": "off",
"no-restricted-syntax": "off",
"no-else-return": "off",
Expand All @@ -66,8 +67,11 @@
"no-plusplus": "off",
"no-multi-assign": "off",
"react/no-unknown-property": "off",
"lines-between-class-members": ["error", "always"],
"lines-between-class-members": ["off"],
"no-debugger": "warn",
"prettier/prettier": ["error"]
"prettier/prettier": ["error"],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/explicit-module-boundary-types": "off"
}
}
5,759 changes: 3,609 additions & 2,150 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 10 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"build": "react-scripts build",
"test": "react-scripts test --detectOpenHandles",
"debugtest": "DEBUG=true react-scripts test",
"lint": "eslint src/**/*.js",
"lint": "eslint \"src/**/*.{js,jsx,ts,tsx}\"",
"format": "prettier --write \"src/**/*.{js,jsx,html,css}\"",
"docker": "npm run build && docker run --name mri-viewer -v ./build:/usr/share/nginx/html:ro -d -p 8080:80 nginx",
"prepare": "husky install"
Expand All @@ -36,8 +36,7 @@
"@tensorflow/tfjs": "^3.6.0",
"classnames": "^2.3.1",
"daikon": "^1.2.42",
"eslint": "^7.27.0",
"filereader-stream": "^2.0.0",
"jszip": "^3.10.1",
"react": "^17.0.2",
"react-dnd": "^14.0.2",
"react-dnd-html5-backend": "^14.0.0",
Expand All @@ -48,21 +47,26 @@
"react-scripts": "4.0.3",
"redux": "4.1.0",
"seedrandom": "^2.4.4",
"three": "0.101.1",
"zlib": "1.x.x"
"three": "0.101.1"
},
"devDependencies": {
"@babel/core": "7.14.3",
"@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^12.1.0",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/user-event": "^13.2.1",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@typescript-eslint/eslint-plugin": "^6.7.2",
"@typescript-eslint/parser": "^6.7.2",
"eslint": "^7.27.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "7.x.x",
"husky": "^7.0.0",
"lint-staged": "^11.0.0",
"prettier": "^2.4.1"
"prettier": "^2.4.1",
"typescript": "^4.9.5"
},
"jest": {
"resetMocks": false,
Expand Down
11 changes: 10 additions & 1 deletion src/config/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@
const config = {
// special demo dialog file locations

demoUrls: [],
demoUrls: [
'https://daentjnvnffrh.cloudfront.net/demo/01_lungs/20101108.ktx',
'https://daentjnvnffrh.cloudfront.net/demo/02_brain_set/brain256.ktx',
'https://daentjnvnffrh.cloudfront.net/demo/03_grandmother_gm3/gm3_512_512_165.nii',
'https://daentjnvnffrh.cloudfront.net/demo/04_woman_pelvis/file_list.txt',
'https://daentjnvnffrh.cloudfront.net/demo/05_lungs_00cba/file_list.txt',
'https://daentjnvnffrh.cloudfront.net/demo/06_ct_256/ct_256_256_256.ktx',
'https://daentjnvnffrh.cloudfront.net/demo/07_lungs_256/lungs_256_256_256.ktx',
'https://daentjnvnffrh.cloudfront.net/demo/08_brain_with_roi/set_intn.hdr',
],

googleCloudDemoActivce: false,
arrMenuGoogle: [
Expand Down
2 changes: 1 addition & 1 deletion src/engine/Volume.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class Volume extends React.Component {

// do nothing. But we need to implement render() to run Volume tests
render() {
return <p>></p>;
return <p></p>;
}
} // end class Volume

Expand Down
12 changes: 6 additions & 6 deletions src/engine/VolumeSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ import LoaderHdr from './loaders/LoaderHdr';
* See Volume class as an element of volume set
*/
class VolumeSet extends React.Component {
/**
* @param {object} props - props from up level object
*/
constructor(props) {
super(props);
constructor() {
super();
/** nuber of volumes in set */
this.m_numVolumes = 0;
/** volumes array. see more details in class Volume */
Expand Down Expand Up @@ -101,7 +98,7 @@ class VolumeSet extends React.Component {

// do nothing. But we need to implement render() to run Volume tests
render() {
return <p>></p>;
return <p></p>;
}

// ********************************************
Expand Down Expand Up @@ -150,9 +147,12 @@ class VolumeSet extends React.Component {
}

readFromNifti(arrBuf, callbackProgress, callbackComplete) {
console.log('I HERE IN READ!');
const loader = new LoaderNifti();
const vol = this.getVolume(0);
console.log('vol = ', vol);
const ret = loader.readFromBuffer(vol, arrBuf, callbackProgress, callbackComplete);
console.log('ret = ', ret);
return ret;
}

Expand Down
25 changes: 25 additions & 0 deletions src/engine/lib/MRIViewer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { MRIFileReader, mriFileReader } from './core/readers';
import { MRIEventsService } from './services';
import mriEventsService from './services/EventsService';

export class MRIViwer {
public fileReader: MRIFileReader;
public events: MRIEventsService;

constructor() {
this.events = mriEventsService;
this.fileReader = mriFileReader;
}

read(data: File[] | string): void {
console.log('data = ', data);

this.fileReader.read(data);
}
}

// Create the singleton instance and freeze it
const w3MriViwer = new MRIViwer();
Object.freeze(w3MriViwer);

export default w3MriViwer;
3 changes: 3 additions & 0 deletions src/engine/lib/config/volume.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const volumeConfig: any = {
setTextureSize4X: true,
};
28 changes: 28 additions & 0 deletions src/engine/lib/core/readers/MRIFileReader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { MRIUrlReader } from './url/MRIUrlReader';
import { MRIFileReaderFactory } from './local/MRIFileReaderFactory';

export class MRIFileReader {
private localFileReader: MRIFileReaderFactory;
private urlFileReader: MRIUrlReader;

constructor() {
this.localFileReader = new MRIFileReaderFactory();
this.urlFileReader = new MRIUrlReader();
}

read(data: File[] | string): void {
if (data && data.length && data[0] instanceof File) {
this.localFileReader.read(data as File[]);
} else if (typeof data === 'string') {
this.urlFileReader.read(data as string);
} else {
throw new Error('Invalid input. Expected a File or URL string.');
}
}
}

// Create the singleton instance and freeze it
const mriFileReader = new MRIFileReader();
Object.freeze(mriFileReader);

export default mriFileReader;
83 changes: 83 additions & 0 deletions src/engine/lib/core/readers/abstract/AbstractMRIReader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import LoadResult from '../../../../LoadResult';
import VolumeSet from '../../../../VolumeSet';
import LoaderDicom from '../../../../loaders/LoaderDicom';
import LoaderHdr from '../../../../loaders/LoaderHdr';
import { volumeConfig } from '../../../config/volume.config';
import { MriEvents } from '../../../enums';
import mriEventsService, { MRIEventsService } from '../../../services/EventsService';
import mriLocalStorageService, { MRILocalStorageService } from '../../../services/LocalStorageService';
import mriStoreService, { MRIStoreService } from '../../../services/StoreService';

export abstract class AbstractMRIReader {
// VolumeData
volumeSet: VolumeSet;
volumeIndex: number = 0;
// FileData
fileName: string;
fileExtension: string;
// File Handlers
loader: LoaderDicom | LoaderHdr | null;
fileReader: FileReader;
// Services
store: MRIStoreService;
events: MRIEventsService;
localStorage: MRILocalStorageService;

constructor() {
this.loader = null;
this.volumeSet = new VolumeSet();
this.fileReader = new FileReader();

this.fileName = '';
this.fileExtension = '';

this.store = mriStoreService;
this.events = mriEventsService;
this.localStorage = mriLocalStorageService;

this.callbackReadProgress = this.callbackReadProgress.bind(this);
this.callbackReadComplete = this.callbackReadComplete.bind(this);
}

public handleVolumeLoadSuccess() {
const volume = this.volumeSet.getVolume(this.volumeIndex);

if (!volume.m_dataArray) return;

if (volumeConfig.setTextureSize4X) {
volume.makeDimensions4x();
}

this.callbackReadProgress(1);
this.localStorage.saveRecentFiles(this.fileName);
this.store.setVolume(this.volumeSet, this.volumeIndex, this.fileName);

if (this.store.getState().graphics2d) {
this.store.getState().graphics2d.forceUpdate();
}
}

public handleVolumeLoadFailed(error: string) {
this.events.emit(MriEvents.FILE_READ_ERROR, { error });
this.store.setVolumeLoadFailed(this.fileName, [error]);
}

public callbackReadProgress(progress: number) {
const progressPercentage: number = Math.floor(progress * 100);

if (progressPercentage >= 99) {
this.store.setLoadingProgress(0);
} else {
this.store.setLoadingProgress(progressPercentage);
}
}

public callbackReadComplete(status: number) {
if (status === LoadResult.SUCCESS) {
this.handleVolumeLoadSuccess();
} else {
const error = LoadResult.getResultString(status);
this.handleVolumeLoadFailed(error);
}
}
}
3 changes: 3 additions & 0 deletions src/engine/lib/core/readers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import mriFileReader, { MRIFileReader } from './MRIFileReader';

export { mriFileReader, MRIFileReader };
56 changes: 56 additions & 0 deletions src/engine/lib/core/readers/local/ArchiveReader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import JSZip from 'jszip';

const IGNORED_FILE_PREFIXES = ['__MACOSX/', '._'];

export class ArchiveReader {
/**
* Reads the provided ZIP file and returns the list of extracted files.
* @param file - The ZIP file to be read.
* @returns A promise that resolves to an array of files extracted from the ZIP.
*/
async readZipFile(file: File): Promise<File[]> {
const zip = new JSZip();
const unzippedFiles: File[] = [];

const arrayBuffer = await this.readFileAsArrayBuffer(file);

// Load the ZIP file
await zip.loadAsync(arrayBuffer);

// Use the original order in the ZIP file
for (const fileName in zip.files) {
// Skip OS specific files and folders
if (this.shouldSkipFile(fileName)) {
continue;
}

const zipObject = zip.files[fileName];

if (!zipObject.dir) {
const blob = await zipObject.async('blob');
unzippedFiles.push(new File([blob], fileName, { type: blob.type }));
}
}

return unzippedFiles.sort((a, b) => a.name.localeCompare(b.name));
}

/**
* Determines if a file from the ZIP should be skipped based on its name.
* @param fileName - The name of the file to check.
* @returns True if the file should be skipped, false otherwise.
*/
private shouldSkipFile(fileName: string): boolean {
return IGNORED_FILE_PREFIXES.some((prefix) => fileName.startsWith(prefix));
}

// Function to read a file as ArrayBuffer
readFileAsArrayBuffer(file: File): Promise<ArrayBuffer> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result as ArrayBuffer);
reader.onerror = reject;
reader.readAsArrayBuffer(file);
});
}
}
Loading

0 comments on commit 89e07ba

Please sign in to comment.