-
Notifications
You must be signed in to change notification settings - Fork 52
Improve subject configuration structure #1150
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
Improve subject configuration structure #1150
Conversation
@maximemulder for phantoms, the PSCID is always |
@maximemulder can you give an example on how that would work with changes made to the template so I can get a better idea of how that would work. Link to the database_config.py template: https://github.com/aces/Loris-MRI/blob/main/dicom-archive/database_config_template.py |
@cmadjar The idea would be to return objects of the def get_subject_ids(db, dicom_value=None, scanner_id=None):
subject_id_dict = {}
imaging = Imaging(db, False)
phantom_match = re.search('(pha)|(test)', dicom_value, re.IGNORECASE)
candidate_match = re.search('([^_]+)_(\d+)_([^_]+)', dicom_value, re.IGNORECASE)
if phantom_match:
subject_id_dict['isPhantom'] = True
subject_id_dict['CandID'] = imaging.get_scanner_candid(scanner_id)
subject_id_dict['visitLabel'] = dicom_value.strip()
subject_id_dict['createVisitLabel'] = 1
subject_id_dict['ProjectID'] = 1
subject_id_dict['CohortID'] = 1
elif candidate_match:
subject_id_dict['isPhantom'] = False
subject_id_dict['PSCID'] = candidate_match.group(1)
subject_id_dict['CandID'] = candidate_match.group(2)
subject_id_dict['visitLabel'] = candidate_match.group(3)
subject_id_dict['createVisitLabel'] = 0
return subject_id_dict We would would have this: from lib.dataclass.config import SubjectConfig, CreateVisitConfig
def get_subject_ids(db: Database, subject_name: str, scanner_id: int | None = None) -> SubjectConfig | None:
imaging = Imaging(db, False)
phantom_match = re.search('(pha)|(test)', subject_name, re.IGNORECASE)
candidate_match = re.search('([^_]+)_(\d+)_([^_]+)', subject_name, re.IGNORECASE)
if phantom_match:
return SubjectConfig(
name = subject_name,
is_phantom = True,
psc_id = 'scanner',
cand_id = imaging.get_scanner_candid(scanner_id),
visit_label = subject_name.strip()
create_visit = CreateVisitConfig(
project_id = 1,
cohort_id = 1,
)
)
elif candidate_match:
return SubjectConfig(
name = subject_name,
is_phantom = False,
psc_id = candidate_match.group(1),
cand_id = int(candidate_match.group(2)),
visit_label = candidate_match.group(3),
create_visit = None,
)
return None I note that the current function has a parameter This change can also be done with other currently non-implemented |
4bb6c5b
to
4a4e23f
Compare
74e7698
to
f77d9a7
Compare
508d6f8
to
c3d8a19
Compare
b2130a8
to
4cd7f09
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like your opinion on these two conditions @cmadjar . I am very confident on the issues of these conditions, but would just like to know whether this may be an indicator of a larger problem.
I edited the PR description with up-to-date information. Manually tested with Ready for review or merge @cmadjar (or re-assign someone else to review if you don't have time). EDIT: Just fixed a typo in a comment but still ready to merge. |
cf0c600
to
72a546f
Compare
9f144dd
to
23bc589
Compare
Naming changes:
The config file change is to not conflict with the config from the database. |
23bc589
to
9b003d5
Compare
@maximemulder As discussed, if you could add a note in the description for existing project on how to migrate their configuration file. I will work on upgrading my HBCD sandbox to 26 and should be able to test the PR next week 🤞 |
Done ! |
9b003d5
to
7394197
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maximemulder I am not able to connect to MySQL with the new way of connecting. I get the following error:
$ run_dicom_archive_validation.py -p database_config_27.py -u 140 -t /data/loris/data/tarchive/DCM_2023-11-28_DICOM_DIR_2024-10-09_18h28m05s_d8kht8nu.tar
Traceback (most recent call last):
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/network.py", line 482, in open_connection
addrinfos = socket.getaddrinfo(self.server_host,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/socket.py", line 962, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -2] Name or service not known
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 146, in __init__
self._dbapi_connection = engine.raw_connection()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 3302, in raw_connection
return self.pool.connect()
^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 449, in connect
return _ConnectionFairy._checkout(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 1263, in _checkout
fairy = _ConnectionRecord.checkout(pool)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 712, in checkout
rec = pool._do_get()
^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/impl.py", line 179, in _do_get
with util.safe_reraise():
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
raise exc_value.with_traceback(exc_tb)
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/impl.py", line 177, in _do_get
return self._create_connection()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 390, in _create_connection
return _ConnectionRecord(self)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 674, in __init__
self.__connect()
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 900, in __connect
with util.safe_reraise():
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
raise exc_value.with_traceback(exc_tb)
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 896, in __connect
self.dbapi_connection = connection = pool._invoke_creator(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/create.py", line 643, in connect
return dialect.connect(*cargs, **cparams)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/default.py", line 621, in connect
return self.loaded_dbapi.connect(*cargs, **cparams)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/__init__.py", line 179, in connect
return MySQLConnection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/connection.py", line 95, in __init__
self.connect(**kwargs)
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/abstracts.py", line 716, in connect
self._open_connection()
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/connection.py", line 206, in _open_connection
self._socket.open_connection()
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/network.py", line 500, in open_connection
raise errors.InterfaceError(
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on 'd@localhost:3306' (-2 Name or service not known)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/opt/loris/bin/mri/python/scripts/run_dicom_archive_validation.py", line 75, in <module>
main()
File "/opt/loris/bin/mri/python/scripts/run_dicom_archive_validation.py", line 71, in main
DicomValidationPipeline(loris_getopt_obj, os.path.basename(__file__[:-3]))
File "/opt/loris/bin/mri/python/lib/dcm2bids_imaging_pipeline_lib/dicom_validation_pipeline.py", line 30, in __init__
self.validate_subject_info()
File "/opt/loris/bin/mri/python/lib/dcm2bids_imaging_pipeline_lib/base_pipeline.py", line 241, in validate_subject_info
validate_subject_info(self.db_orm, self.subject_info)
File "/opt/loris/bin/mri/python/lib/validate_subject_info.py", line 17, in validate_subject_info
candidate = try_get_candidate_with_cand_id(db, subject_info.cand_id)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/loris/bin/mri/python/lib/db/query/candidate.py", line 14, in try_get_candidate_with_cand_id
return db.execute(query).scalar_one_or_none()
^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2362, in execute
return self._execute_internal(
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2237, in _execute_internal
conn = self._connection_for_bind(bind)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 2106, in _connection_for_bind
return trans._connection_for_bind(engine, execution_options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<string>", line 2, in _connection_for_bind
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/orm/state_changes.py", line 139, in _go
ret_value = fn(self, *arg, **kw)
^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/orm/session.py", line 1189, in _connection_for_bind
conn = bind.connect()
^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 3278, in connect
return self._connection_cls(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 148, in __init__
Connection._handle_dbapi_exception_noconnection(
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 2442, in _handle_dbapi_exception_noconnection
raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 146, in __init__
self._dbapi_connection = engine.raw_connection()
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/base.py", line 3302, in raw_connection
return self.pool.connect()
^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 449, in connect
return _ConnectionFairy._checkout(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 1263, in _checkout
fairy = _ConnectionRecord.checkout(pool)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 712, in checkout
rec = pool._do_get()
^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/impl.py", line 179, in _do_get
with util.safe_reraise():
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
raise exc_value.with_traceback(exc_tb)
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/impl.py", line 177, in _do_get
return self._create_connection()
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 390, in _create_connection
return _ConnectionRecord(self)
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 674, in __init__
self.__connect()
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 900, in __connect
with util.safe_reraise():
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/util/langhelpers.py", line 146, in __exit__
raise exc_value.with_traceback(exc_tb)
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/pool/base.py", line 896, in __connect
self.dbapi_connection = connection = pool._invoke_creator(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/create.py", line 643, in connect
return dialect.connect(*cargs, **cparams)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/sqlalchemy/engine/default.py", line 621, in connect
return self.loaded_dbapi.connect(*cargs, **cparams)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/__init__.py", line 179, in connect
return MySQLConnection(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/connection.py", line 95, in __init__
self.connect(**kwargs)
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/abstracts.py", line 716, in connect
self._open_connection()
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/connection.py", line 206, in _open_connection
self._socket.open_connection()
File "/home/lorisadmin/miniconda3/envs/loris-mri-py311/lib/python3.11/site-packages/mysql/connector/network.py", line 500, in open_connection
raise errors.InterfaceError(
sqlalchemy.exc.InterfaceError: (mysql.connector.errors.InterfaceError) 2003: Can't connect to MySQL server on 'd@localhost:3306' (-2 Name or service not known)
(Background on this error at: https://sqlalche.me/e/20/rvf5)
I tried connecting manually to mysql with mysql -P 3306 -u lorisuser -h localhost -p
and the correct password. It worked so this is not due to an incorrect setup.
mysql: DatabaseConfig = DatabaseConfig (
host='localhost',
username='lorisuser',
password='################',
database='prod_26',
port=3306
)
Any idea what might be going on?
@cmadjar Hhhhm, no idea what's happening here since it is working well on my end. The last line seems to be implying that it is using a wrong username ( |
7394197
to
ad87522
Compare
ad87522
to
50ff869
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maximemulder see one tiny bug on the push to s3 script
python/lib/dcm2bids_imaging_pipeline_lib/push_imaging_files_to_s3_pipeline.py
Outdated
Show resolved
Hide resolved
Co-authored-by: Cécile Madjar <cecile.madjar@mcin.ca>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good now! Thanks!
* remove trailing whitespaces (#1149) Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * SQLAlchemy proof-of-concept (#1152) * add sqlalchemy * fix lints * add comment --------- Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * fix (#1168) Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * integration test (#1138) * test * main Loris here * ignore Loris python * clone Loris * rm loris * override test * override test * override RB data * fix folder * test php files * test * try * test * try install loris mri * os * test * rm modules * Update flake8_python_linter.yml * Small linting improvements (#1167) * better linting * remove tab in comment --------- Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * Improve Python subject determination and validation error handling (#1146) * improve subjects determination and validation * use tuple for database query arguments * query on single line --------- Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * Add literal regex leading r (#1176) Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * fix (#1178) Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * LORIS-MRI tooling configuration (#1170) * add pyproject.toml * keep flake8 (for now) * double type checking * Use Pyright as main type checker * remove comment * test * test * change configuration * add python environment variables * try factorization * test * test * test * test * remove temporary things * test ruff error * ruff output github * further test errors * test pyright output github * test * test * test * change comment * remove test errors * test --------- Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * update docker install (#1171) Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> * add RB override tables for the MRI side (#1173) * Remove php 8.1 and 8.2 from the LORIS tests to keep only test on PHP 8.3 (#1175) * remove php 8.1 and 8.2 testing * update to 8.3 in Dockerfile.test.php8 * ADD minc tools install in gitactions (#1179) * todo install loris mri * test * run pytest in gitaction (#1172) * test * ttt * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * test * Delete test_example.py * rename * done * Delete test/Dockerfile.test.py * test (#1187) * unit tests poc (#1188) * add more pytest global rules (#1194) * Stricter linter configuration (#1193) * stricter ruff config * do not ignore N818 * lint for sorted imports * add python scripts directory (#1196) * Bunch of SQLAlchemy definitions (#1192) * bunch of sqlalchemy definitions * add project orm definition * fix candidate to site query function * optimize docker image (#1195) * fix pytest config (#1197) * fix python scripts (#1199) * remove mysql-connector (#1200) * Improve subject configuration structure (#1150) * refacor subject config * remove suspicious phantom code * change naming * fix rebase lints * cleaner database url * Cecile CandID path join bug fix Co-authored-by: Cécile Madjar <cecile.madjar@mcin.ca> --------- Co-authored-by: Cécile Madjar <cecile.madjar@mcin.ca> * Integration test to check that the ORM definitions match the LORIS SQL database (#1198) * orm sync integration test * add docker health check * use integration config file * test error * Revert "test error" This reverts commit d1a70e6. * Clean up Docker database scripts (#1202) * clean docker database * remove docker warning * remove unused attribute (#1201) * try fix perl ci * Add file, file_parameter and scanner SQLAlchemy models (#1207) * add tables * rename file model * rename parameter_file * fix lints (#1210) * Unify LORIS-MRI logging (#1191) * new env * change print order in database log * create notification type if needed * fix typing pyright update * Integration test for `run_dicom_archive_loader.py` (#1203) add integration test put keys in github repo debugging add database check add comments and debugging remove s3 keys change converter in test check file tree fix doc fix docs 2 rename variable go back to using s3 keys fix path try fix * rename database sub-namepaces (#1214) * fix warnings (#1215) * Factorize get subject session (#1190) * factorize subject session * re-add site log * Migrate "get all sites from the database" to the SQLAlchemy abstraction (#1216) * Fix new PEP585 Ruff lint (#1218) * Clean-up database scan type (#1139) Complementary PR of LORIS #9304 * Migrate DICOM archive files to new database abstraction (#1217) * wip * use self.dicom_archive.id instead of self.tarchive_id * fix todo * Fix SQLAlchemy file model (#1221) * Improve Python requirements order (#1222) * add python documentation (#1223) * Update SQLAlchemy bindings to match LORIS#9556 (#1229) * trigger_tests * try update * fix old queries for integration tests * Migrate `ImagingUpload` and `MriUploadDB` to the new database abstraction (#1224) * migrate mri upload to sqlalchemy * fix concurrency bug * fix clean up * display mri upload ids use dicom archive id instead of tarchiveid because it is prettier ruff check * migrate scanner to new abstraction (#1232) * Fix install script (#1234) * fix install script and move files related to install into the install directory * fix install script and move files related to install into the install directory * fix install script and move files related to install into the install directory * fix paths in imaging_install_test.sh * fix paths in imaging_install_test.sh * fix SQL error in install script * fix tests * fix tests * fix github action * add cpanfile * copy cpanfile in MRI dockerfile * add new dependency in order to be able to source the Digest::BLAKE2 in the cpanfile * fix Digest::BLAKE2 installation though cpanfile * move config templates to a templates directory and requirements files into a requirements directory * remove copy * fix test * fix test * fix test * fix test * Maxime's feedback * specify python version (#1237) * fix large file hash memory (#1236) * add lib.util module (#1238) * New DICOM study import script (#1117) * rewrite dicom archive * update * remove --year and --target options * get session from config file * remove unused upload argument * fix little oopsie for --session * handle large files hash * fix unhandled modalities * use new lib.util module * Add support to be able to read headers from enhanced DICOMs (#7) * print * print * print * print * add support for enhanced DICOMs * add support for enhanced DICOMs * rework associate files with series * sort dicom series and files before inserting in the database * handle null scanner --------- Co-authored-by: Cécile Madjar <cecile.madjar@mcin.ca> * refactoring of CandID on the non-ORM python side * tests * fix insertion in mri_protocol_violation_scans * alphabetical order is hard sometimes * FIx `get_candidate_id` documentation --------- Co-authored-by: Maxime Mulder <maxime-mulder@outlook.com> Co-authored-by: Maxime Mulder <maxime.mulder@mcgill.ca> Co-authored-by: Shen <kongtiaowangshen@gmail.com>
This PR makes the Python configuration file (database, S3, and subject IDs) more explicit by wrapping it in typed dataclasses instead of dicts, and adds a few comments.
I discussed some suspicious phantom-related code with @cmadjar, and it appears that phantom scans are not deeply tested in LORIS-MRI Python so there are likely a few bugs in our code. Therefore, I removed the suspicious lines as we probably want the scanner/scanner candidate to be created as early as possible so that the rest of the code does not have to worry about it.
Phantom configuration is still possible provided that the scanner and candidate exist in the database, which the user can add themselves since there is access to the database in the configuration function. More work is probably needed on that front (small quality-of-life improvements or the infamous phantom refactor) but that is a subject for other PRs.
NOTE FOR EXISTING PROJECTS: To update your project, change your configuration file (usually
dicom-archive/.loris_mri/database_config.py
) from the dict-shaped template to the typed one by imitatingdicom_archive/database_config_template.py
.