comparison OrthancStone/Sources/Toolbox/DicomStructureSet.cpp @ 1751:946eb7200b82

FastParseVector usage + timing instrumentation guarded by STONE_TIME_BLOCKING_OPS
author Benjamin Golinvaux <bgo@osimis.io>
date Mon, 22 Feb 2021 14:57:01 +0100
parents 9ac2a65d4172
children 34ab7f643327
comparison
equal deleted inserted replaced
1750:5f74ebe2516b 1751:946eb7200b82
21 21
22 22
23 #include "DicomStructureSet.h" 23 #include "DicomStructureSet.h"
24 #include "DicomStructureSetUtils.h" 24 #include "DicomStructureSetUtils.h"
25 25
26 #include "../Toolbox/GeometryToolbox.h" 26 #include "GeometryToolbox.h"
27 #include "GenericToolbox.h"
28
27 #include "OrthancDatasets/DicomDatasetReader.h" 29 #include "OrthancDatasets/DicomDatasetReader.h"
28 30
29 #include <Logging.h> 31 #include <Logging.h>
30 #include <OrthancException.h> 32 #include <OrthancException.h>
31 #include <Toolbox.h> 33 #include <Toolbox.h>
32 34
33 #if defined(_MSC_VER) 35 #if defined(_MSC_VER)
34 # pragma warning(push) 36 # pragma warning(push)
35 # pragma warning(disable:4244) 37 # pragma warning(disable:4244)
38 #endif
39
40 #if STONE_TIME_BLOCKING_OPS
41 # include <boost/date_time/posix_time/posix_time.hpp>
36 #endif 42 #endif
37 43
38 #include <limits> 44 #include <limits>
39 #include <stdio.h> 45 #include <stdio.h>
40 #include <boost/geometry.hpp> 46 #include <boost/geometry.hpp>
161 return static_cast<uint8_t>(v); 167 return static_cast<uint8_t>(v);
162 } 168 }
163 } 169 }
164 170
165 171
166 static bool ParseVector(Vector& target, 172 static bool FastParseVector(Vector& target,
167 const IDicomDataset& dataset, 173 const IDicomDataset& dataset,
168 const DicomPath& tag) 174 const DicomPath& tag)
169 { 175 {
170 std::string value; 176 std::string value;
171 return (dataset.GetStringValue(value, tag) && 177 return (dataset.GetStringValue(value, tag) &&
172 LinearAlgebra::ParseVector(target, value)); 178 GenericToolbox::FastParseVector(target, value));
173 } 179 }
174 180
175 void DicomStructureSet::Polygon::CheckPointIsOnSlice(const Vector& v) const 181 void DicomStructureSet::Polygon::CheckPointIsOnSlice(const Vector& v) const
176 { 182 {
177 if (hasSlice_) 183 if (hasSlice_)
466 return structures_[index]; 472 return structures_[index];
467 } 473 }
468 474
469 void DicomStructureSet::Setup(const IDicomDataset& tags) 475 void DicomStructureSet::Setup(const IDicomDataset& tags)
470 { 476 {
477 #if STONE_TIME_BLOCKING_OPS
478 boost::posix_time::ptime timerStart = boost::posix_time::microsec_clock::universal_time();
479 #endif
480
471 DicomDatasetReader reader(tags); 481 DicomDatasetReader reader(tags);
472 482
473 size_t count, tmp; 483 size_t count, tmp;
474 if (!tags.GetSequenceSize(count, DicomPath(DICOM_TAG_RT_ROI_OBSERVATIONS_SEQUENCE)) || 484 if (!tags.GetSequenceSize(count, DicomPath(DICOM_TAG_RT_ROI_OBSERVATIONS_SEQUENCE)) ||
475 !tags.GetSequenceSize(tmp, DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE)) || 485 !tags.GetSequenceSize(tmp, DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE)) ||
479 { 489 {
480 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); 490 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
481 } 491 }
482 492
483 structures_.resize(count); 493 structures_.resize(count);
494 #if STONE_TIME_BLOCKING_OPS
495 LOG(WARNING) << "DicomStructureSet::Setup(...) structures_.size() = " << structures_.size();
496 #endif
484 for (size_t i = 0; i < count; i++) 497 for (size_t i = 0; i < count; i++)
485 { 498 {
486 structures_[i].interpretation_ = reader.GetStringValue 499 structures_[i].interpretation_ = reader.GetStringValue
487 (DicomPath(DICOM_TAG_RT_ROI_OBSERVATIONS_SEQUENCE, i, 500 (DicomPath(DICOM_TAG_RT_ROI_OBSERVATIONS_SEQUENCE, i,
488 DICOM_TAG_RT_ROI_INTERPRETED_TYPE), 501 DICOM_TAG_RT_ROI_INTERPRETED_TYPE),
492 (DicomPath(DICOM_TAG_STRUCTURE_SET_ROI_SEQUENCE, i, 505 (DicomPath(DICOM_TAG_STRUCTURE_SET_ROI_SEQUENCE, i,
493 DICOM_TAG_ROI_NAME), 506 DICOM_TAG_ROI_NAME),
494 "No name"); 507 "No name");
495 508
496 Vector color; 509 Vector color;
497 if (ParseVector(color, tags, DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, 510 if (FastParseVector(color, tags, DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
498 DICOM_TAG_ROI_DISPLAY_COLOR)) && 511 DICOM_TAG_ROI_DISPLAY_COLOR)) &&
499 color.size() == 3) 512 color.size() == 3)
500 { 513 {
501 structures_[i].red_ = ConvertColor(color[0]); 514 structures_[i].red_ = ConvertColor(color[0]);
502 structures_[i].green_ = ConvertColor(color[1]); 515 structures_[i].green_ = ConvertColor(color[1]);
513 if (!tags.GetSequenceSize(countSlices, DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i, 526 if (!tags.GetSequenceSize(countSlices, DicomPath(DICOM_TAG_ROI_CONTOUR_SEQUENCE, i,
514 DICOM_TAG_CONTOUR_SEQUENCE))) 527 DICOM_TAG_CONTOUR_SEQUENCE)))
515 { 528 {
516 countSlices = 0; 529 countSlices = 0;
517 } 530 }
531
532 #if STONE_TIME_BLOCKING_OPS
533 LOG(WARNING) << "DicomStructureSet::Setup(...) structure # " << i << " : countSlices = " << countSlices;
534 #endif
518 535
519 LOG(INFO) << "New RT structure: \"" << structures_[i].name_ 536 LOG(INFO) << "New RT structure: \"" << structures_[i].name_
520 << "\" with interpretation \"" << structures_[i].interpretation_ 537 << "\" with interpretation \"" << structures_[i].interpretation_
521 << "\" containing " << countSlices << " slices (color: " 538 << "\" containing " << countSlices << " slices (color: "
522 << static_cast<int>(structures_[i].red_) << "," 539 << static_cast<int>(structures_[i].red_) << ","
580 597
581 contourDataPath.SetPrefixIndex(1, j); 598 contourDataPath.SetPrefixIndex(1, j);
582 std::string slicesData = reader.GetMandatoryStringValue(contourDataPath); 599 std::string slicesData = reader.GetMandatoryStringValue(contourDataPath);
583 600
584 Vector points; 601 Vector points;
585 if (!LinearAlgebra::ParseVector(points, slicesData) || 602
603 if (!GenericToolbox::FastParseVector(points, slicesData) ||
586 points.size() != 3 * countPoints) 604 points.size() != 3 * countPoints)
587 { 605 {
588 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); 606 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
589 } 607 }
590 608
607 } 625 }
608 626
609 structures_[i].polygons_.push_back(polygon); 627 structures_[i].polygons_.push_back(polygon);
610 } 628 }
611 } 629 }
630 #if STONE_TIME_BLOCKING_OPS
631 boost::posix_time::ptime timerEnd = boost::posix_time::microsec_clock::universal_time();
632 boost::posix_time::time_duration duration = timerEnd - timerStart;
633 int64_t durationMs = duration.total_milliseconds();
634 LOG(WARNING) << "DicomStructureSet::Setup took " << durationMs << " ms";
635 #endif
612 } 636 }
613 637
614 638
615 #if ORTHANC_ENABLE_DCMTK == 1 639 #if ORTHANC_ENABLE_DCMTK == 1
616 DicomStructureSet::DicomStructureSet(Orthanc::ParsedDicomFile& instance) 640 DicomStructureSet::DicomStructureSet(Orthanc::ParsedDicomFile& instance)