Mercurial > hg > orthanc-python
comparison Sources/DicomScpCallbacks.cpp @ 151:566df919b286 cmove2
new more detailed C-Move SCP callbacks
author | Alain Mazy <am@osimis.io> |
---|---|
date | Tue, 27 Feb 2024 16:13:08 +0100 |
parents | c55b0583084b |
children | a6b4e0abe532 |
comparison
equal
deleted
inserted
replaced
150:3c98306828de | 151:566df919b286 |
---|---|
28 | 28 |
29 static PyObject* findScpCallback_ = NULL; | 29 static PyObject* findScpCallback_ = NULL; |
30 static PyObject* moveScpCallback_ = NULL; | 30 static PyObject* moveScpCallback_ = NULL; |
31 static PyObject* worklistScpCallback_ = NULL; | 31 static PyObject* worklistScpCallback_ = NULL; |
32 | 32 |
33 // version 2 of Move callbacks | |
34 static PyObject* createMoveScpDriverCallback_ = NULL; | |
35 static PyObject* getMoveSizeCallback_ = NULL; | |
36 static PyObject* applyMoveCallback_ = NULL; | |
37 static PyObject* freeMoveCallback_ = NULL; | |
38 | |
33 | 39 |
34 static PyObject *GetFindQueryTag(sdk_OrthancPluginFindQuery_Object* self, | 40 static PyObject *GetFindQueryTag(sdk_OrthancPluginFindQuery_Object* self, |
35 PyObject *args, | 41 PyObject *args, |
36 bool isGroup) | 42 bool isGroup) |
37 { | 43 { |
397 assert(moveDriver != NULL); | 403 assert(moveDriver != NULL); |
398 delete reinterpret_cast<IMoveDriver*>(moveDriver); | 404 delete reinterpret_cast<IMoveDriver*>(moveDriver); |
399 } | 405 } |
400 | 406 |
401 | 407 |
408 static void* CreateMoveCallback2(OrthancPluginResourceType resourceType, | |
409 const char *patientId, | |
410 const char *accessionNumber, | |
411 const char *studyInstanceUid, | |
412 const char *seriesInstanceUid, | |
413 const char *sopInstanceUid, | |
414 const char *originatorAet, | |
415 const char *sourceAet, | |
416 const char *targetAet, | |
417 uint16_t originatorId) | |
418 { | |
419 assert(createMoveScpDriverCallback_ != NULL); | |
420 | |
421 try | |
422 { | |
423 std::string _patientId, _accessionNumber, _studyInstanceUid, _seriesInstanceUid, _sopInstanceUid, _originatorAet, _sourceAet, _targetAet; | |
424 if (patientId != NULL) | |
425 { | |
426 _patientId.assign(patientId); | |
427 } | |
428 | |
429 if (accessionNumber != NULL) | |
430 { | |
431 _accessionNumber.assign(accessionNumber); | |
432 } | |
433 | |
434 if (studyInstanceUid != NULL) | |
435 { | |
436 _studyInstanceUid.assign(studyInstanceUid); | |
437 } | |
438 | |
439 if (seriesInstanceUid != NULL) | |
440 { | |
441 _seriesInstanceUid.assign(seriesInstanceUid); | |
442 } | |
443 | |
444 if (sopInstanceUid != NULL) | |
445 { | |
446 _sopInstanceUid.assign(sopInstanceUid); | |
447 } | |
448 | |
449 if (originatorAet != NULL) | |
450 { | |
451 _originatorAet.assign(originatorAet); | |
452 } | |
453 | |
454 if (sourceAet != NULL) | |
455 { | |
456 _sourceAet.assign(sourceAet); | |
457 } | |
458 | |
459 if (targetAet != NULL) | |
460 { | |
461 _targetAet.assign(targetAet); | |
462 } | |
463 | |
464 PythonLock lock; | |
465 | |
466 PythonObject kw(lock, PyDict_New()); | |
467 | |
468 std::string level; | |
469 switch (resourceType) | |
470 { | |
471 case OrthancPluginResourceType_Patient: | |
472 level = "PATIENT"; | |
473 break; | |
474 | |
475 case OrthancPluginResourceType_Study: | |
476 level = "STUDY"; | |
477 break; | |
478 | |
479 case OrthancPluginResourceType_Series: | |
480 level = "SERIES"; | |
481 break; | |
482 | |
483 case OrthancPluginResourceType_Instance: | |
484 level = "INSTANCE"; | |
485 break; | |
486 | |
487 default: | |
488 throw OrthancPlugins::PluginException(OrthancPluginErrorCode_ParameterOutOfRange); | |
489 } | |
490 | |
491 { | |
492 PythonString tmp(lock, level); | |
493 PyDict_SetItemString(kw.GetPyObject(), "Level", tmp.GetPyObject()); | |
494 } | |
495 | |
496 { | |
497 PythonString tmp(lock, _patientId); | |
498 PyDict_SetItemString(kw.GetPyObject(), "PatientID", tmp.GetPyObject()); | |
499 } | |
500 | |
501 { | |
502 PythonString tmp(lock, _accessionNumber); | |
503 PyDict_SetItemString(kw.GetPyObject(), "AccessionNumber", tmp.GetPyObject()); | |
504 } | |
505 | |
506 { | |
507 PythonString tmp(lock, _studyInstanceUid); | |
508 PyDict_SetItemString(kw.GetPyObject(), "StudyInstanceUID", tmp.GetPyObject()); | |
509 } | |
510 | |
511 { | |
512 PythonString tmp(lock, _seriesInstanceUid); | |
513 PyDict_SetItemString(kw.GetPyObject(), "SeriesInstanceUID", tmp.GetPyObject()); | |
514 } | |
515 | |
516 { | |
517 PythonString tmp(lock, _sopInstanceUid); | |
518 PyDict_SetItemString(kw.GetPyObject(), "SOPInstanceUID", tmp.GetPyObject()); | |
519 } | |
520 | |
521 { | |
522 PythonString tmp(lock, _originatorAet); | |
523 PyDict_SetItemString(kw.GetPyObject(), "OriginatorAET", tmp.GetPyObject()); | |
524 } | |
525 | |
526 { | |
527 PythonString tmp(lock, _sourceAet); | |
528 PyDict_SetItemString(kw.GetPyObject(), "SourceAET", tmp.GetPyObject()); | |
529 } | |
530 | |
531 { | |
532 PythonString tmp(lock, _targetAet); | |
533 PyDict_SetItemString(kw.GetPyObject(), "TargetAET", tmp.GetPyObject()); | |
534 } | |
535 | |
536 { | |
537 PythonObject tmp(lock, PyLong_FromUnsignedLong(originatorId)); | |
538 PyDict_SetItemString(kw.GetPyObject(), "OriginatorID", tmp.GetPyObject()); | |
539 } | |
540 | |
541 PythonObject args(lock, PyTuple_New(0)); | |
542 | |
543 // Note: the result is not attached to the PythonLock because we want it to survive after this call since | |
544 // the result is the python move driver that will be passed as first argument to GetMoveSize, Apply and Free | |
545 std::unique_ptr<PyObject> result(PyObject_Call(createMoveScpDriverCallback_, args.GetPyObject(), kw.GetPyObject())); | |
546 | |
547 OrthancPluginErrorCode code = lock.CheckCallbackSuccess("Python C-MOVE SCP callback (Create)"); | |
548 if (code != OrthancPluginErrorCode_Success) | |
549 { | |
550 throw OrthancPlugins::PluginException(code); | |
551 } | |
552 | |
553 // make sure it survives after this call | |
554 Py_INCREF(result.get()); | |
555 | |
556 return result.release(); | |
557 } | |
558 catch (OrthancPlugins::PluginException& e) | |
559 { | |
560 return NULL; | |
561 } | |
562 } | |
563 | |
564 | |
565 static uint32_t GetMoveSize2(void *moveDriver) | |
566 { | |
567 assert(moveDriver != NULL); | |
568 assert(getMoveSizeCallback_ != NULL); | |
569 | |
570 PythonLock lock; | |
571 | |
572 PythonObject args(lock, PyTuple_New(1)); | |
573 PyTuple_SetItem(args.GetPyObject(), 0, reinterpret_cast<PyObject*>(moveDriver)); | |
574 Py_INCREF(moveDriver); // because PyTuple_SetItem steals a reference and we need to keep the object alive | |
575 | |
576 PythonObject result(lock, PyObject_CallObject(getMoveSizeCallback_, args.GetPyObject())); | |
577 | |
578 OrthancPluginErrorCode code = lock.CheckCallbackSuccess("Python C-MOVE SCP callback (GetMoveSize)"); | |
579 if (code != OrthancPluginErrorCode_Success) | |
580 { | |
581 throw OrthancPlugins::PluginException(code); | |
582 } | |
583 | |
584 if (!PyLong_Check(result.GetPyObject())) | |
585 { | |
586 throw OrthancPlugins::PluginException(OrthancPluginErrorCode_BadParameterType); | |
587 } | |
588 | |
589 return static_cast<uint32_t>(PyLong_AsLong(result.GetPyObject())); | |
590 } | |
591 | |
592 | |
593 OrthancPluginErrorCode ApplyMove2(void *moveDriver) | |
594 { | |
595 assert(moveDriver != NULL); | |
596 assert(applyMoveCallback_ != NULL); | |
597 | |
598 PythonLock lock; | |
599 | |
600 PythonObject args(lock, PyTuple_New(1)); | |
601 PyTuple_SetItem(args.GetPyObject(), 0, reinterpret_cast<PyObject*>(moveDriver)); | |
602 Py_INCREF(moveDriver); // because PyTuple_SetItem steals a reference and we need to keep the object alive | |
603 | |
604 PythonObject result(lock, PyObject_CallObject(applyMoveCallback_, args.GetPyObject())); | |
605 | |
606 OrthancPluginErrorCode code = lock.CheckCallbackSuccess("Python C-MOVE SCP callback (Apply)"); | |
607 return code; | |
608 } | |
609 | |
610 | |
611 void FreeMove2(void *moveDriver) | |
612 { | |
613 assert(moveDriver != NULL); | |
614 | |
615 PythonLock lock; | |
616 | |
617 PythonObject args(lock, PyTuple_New(1)); | |
618 PyTuple_SetItem(args.GetPyObject(), 0, reinterpret_cast<PyObject*>(moveDriver)); | |
619 Py_INCREF(moveDriver); // because PyTuple_SetItem steals a reference and we need to keep the object alive | |
620 | |
621 assert(freeMoveCallback_ != NULL); | |
622 PythonObject result(lock, PyObject_CallObject(freeMoveCallback_, args.GetPyObject())); | |
623 | |
624 lock.CheckCallbackSuccess("Python C-MOVE SCP callback (Free)"); | |
625 | |
626 Py_DECREF(moveDriver); | |
627 } | |
628 | |
402 | 629 |
403 OrthancPluginErrorCode WorklistCallback(OrthancPluginWorklistAnswers *answers, | 630 OrthancPluginErrorCode WorklistCallback(OrthancPluginWorklistAnswers *answers, |
404 const OrthancPluginWorklistQuery *query, | 631 const OrthancPluginWorklistQuery *query, |
405 const char *issuerAet, | 632 const char *issuerAet, |
406 const char *calledAet) | 633 const char *calledAet) |
485 return ICallbackRegistration::Apply( | 712 return ICallbackRegistration::Apply( |
486 registration, args, moveScpCallback_, "Python C-MOVE SCP callback"); | 713 registration, args, moveScpCallback_, "Python C-MOVE SCP callback"); |
487 } | 714 } |
488 | 715 |
489 | 716 |
717 PyObject* RegisterMoveCallback2(PyObject* module, PyObject* args) | |
718 { | |
719 // The GIL is locked at this point (no need to create "PythonLock") | |
720 | |
721 class Registration : public ICallbackRegistration | |
722 { | |
723 public: | |
724 virtual void Register() ORTHANC_OVERRIDE | |
725 { | |
726 OrthancPluginRegisterMoveCallback( | |
727 OrthancPlugins::GetGlobalContext(), CreateMoveCallback2, GetMoveSize2, ApplyMove2, FreeMove2); | |
728 } | |
729 }; | |
730 | |
731 Registration registration; | |
732 return ICallbackRegistration::Apply4( | |
733 registration, args, createMoveScpDriverCallback_, getMoveSizeCallback_, applyMoveCallback_, freeMoveCallback_, "Python C-MOVE SCP callback (2)"); | |
734 } | |
735 | |
490 PyObject* RegisterWorklistCallback(PyObject* module, PyObject* args) | 736 PyObject* RegisterWorklistCallback(PyObject* module, PyObject* args) |
491 { | 737 { |
492 // The GIL is locked at this point (no need to create "PythonLock") | 738 // The GIL is locked at this point (no need to create "PythonLock") |
493 | 739 |
494 class Registration : public ICallbackRegistration | 740 class Registration : public ICallbackRegistration |
509 void FinalizeDicomScpCallbacks() | 755 void FinalizeDicomScpCallbacks() |
510 { | 756 { |
511 ICallbackRegistration::Unregister(findScpCallback_); | 757 ICallbackRegistration::Unregister(findScpCallback_); |
512 ICallbackRegistration::Unregister(moveScpCallback_); | 758 ICallbackRegistration::Unregister(moveScpCallback_); |
513 ICallbackRegistration::Unregister(worklistScpCallback_); | 759 ICallbackRegistration::Unregister(worklistScpCallback_); |
514 } | 760 |
761 ICallbackRegistration::Unregister(createMoveScpDriverCallback_); | |
762 ICallbackRegistration::Unregister(getMoveSizeCallback_); | |
763 ICallbackRegistration::Unregister(applyMoveCallback_); | |
764 ICallbackRegistration::Unregister(freeMoveCallback_); | |
765 } |