Skip to content

Commit

Permalink
Updating documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
meyertst-aws committed Jan 3, 2024
1 parent 0b6e9c7 commit 521fedb
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 91 deletions.
10 changes: 5 additions & 5 deletions cpp/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# To build the docker image, run the following command from the shell. This command must be run in
# the "aws-doc-sdk-examples" directory, the parent directory of "cpp", in order to access the resources folder.
# To build the docker image, run the following command from the shell. This Dockerfile
# is configured to be run from with the cpp directory of aws-doc-sdk-examples.
#
# 'docker build -f cpp/Dockerfile -t <container_tag> .'
# 'docker build -t <container_tag> .'
#
# The following command will run the docker image, copying your AWS credentials.
# 'docker run -it --volume ~/.aws/credentials:/home/tests/.aws/credentials <container_tag>'
Expand All @@ -15,7 +15,7 @@ RUN \

# Build only the services needed for example code.
ENV SERVICES="acm;autoscaling;cloudtrail;codebuild;codecommit;cognito-idp;dynamodb;ec2;elasticache;elasticbeanstalk"
ENV SERVICES=${SERVICES}";elasticfilesystem;email;events;glacier;glue;guardduty;iam;kinesis;lambda;logs;mediaconvert;monitoring"
ENV SERVICES=${SERVICES}";elasticfilesystem;email;events;glacier;glue;guardduty;iam;kinesis;lambda;logs;mediaconvert;medical-imaging;monitoring"
ENV SERVICES=${SERVICES}";monitoring;neptune;rds;rds-data;redshift;rekognition;s3;s3-crt;s3-encryption;secretsmanager;sesv2;sns;sqs"
ENV SERVICES=${SERVICES}";storagegateway;sts;transfer;transcribe;transcribestreaming"

Expand Down Expand Up @@ -58,4 +58,4 @@ RUN useradd -ms /bin/bash tests && \

USER tests

CMD ["python3", "/src/cpp/run_automated_tests.py "]
CMD ["python3", "/src/cpp/run_automated_tests.py", "-23"]
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,13 @@ bool AwsDoc::Medical_Imaging::downloadDecodeAndCheckImageFrames(
Aws::MedicalImaging::Model::GetImageFrameOutcome outcome,
const std::shared_ptr<const Aws::Client::AsyncCallerContext> &context) {

result = handleGetImageFrameResult(outcome, outDirectory, imageFrame);
if (!handleGetImageFrameResult(outcome, outDirectory, imageFrame))
{
std::cerr << "Failed to download and convert image frame: "
<< imageFrame.mImageFrameId << " from image set: "
<< imageFrame.mImageSetId << std::endl;
result = false;
}

count--;
if (count <= 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
\param clientConfig: Aws client configuration.
\return bool: Function succeeded.
*/

bool AwsDoc::Medical_Imaging::startDICOMImportJob(
const Aws::String &dataStoreID, const Aws::String &inputBucketName,
const Aws::String &inputDirectory, const Aws::String &outputBucketName,
Expand Down
48 changes: 24 additions & 24 deletions cpp/example_code/medical-imaging/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ cmake_minimum_required(VERSION 3.14)

set(EXAMPLE_SERVICE_NAME "medical-imaging")
set(CURRENT_TARGET "${EXAMPLE_SERVICE_NAME}_gtest")
set(CURRENT_TARGET_AWS_DEPENDENCIES medical-imaging)
set(CURRENT_TARGET_AWS_DEPENDENCIES medical-imaging)

# Set this project's name.
project("${EXAMPLE_SERVICE_NAME}-examples-gtests" )
project("${EXAMPLE_SERVICE_NAME}-examples-gtests")

# Set the C++ standard to use to build this target.
set(CMAKE_CXX_STANDARD 14)
Expand All @@ -21,7 +21,7 @@ enable_testing()

find_package(GTest)

if(NOT GTest_FOUND)
if (NOT GTest_FOUND)
include(FetchContent)
FetchContent_Declare(
googletest
Expand All @@ -32,16 +32,16 @@ if(NOT GTest_FOUND)
# For Windows: Prevent overriding the parent project's compiler/linker settings.
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
endif()
endif ()

# Use the MSVC variable to determine if this is a Windows build.
set(WINDOWS_BUILD ${MSVC})

# Set the location for Windows to find the installed libraries of the SDK.
if(WINDOWS_BUILD)
if (WINDOWS_BUILD)
string(REPLACE ";" "/aws-cpp-sdk-all;" SYSTEM_MODULE_PATH "${CMAKE_SYSTEM_PREFIX_PATH}/aws-cpp-sdk-all")
list(APPEND CMAKE_PREFIX_PATH ${SYSTEM_MODULE_PATH})
endif()
endif ()

# Find the AWS SDK for C++ package.
find_package(AWSSDK REQUIRED COMPONENTS ${CURRENT_TARGET_AWS_DEPENDENCIES})
Expand All @@ -50,26 +50,26 @@ add_executable(
${CURRENT_TARGET}
)

if(WINDOWS_BUILD)
# set(BIN_SUB_DIR "/Debug") # If you are building from the command line, you may need to uncomment this
# and set the proper subdirectory to the executables' location.
if (WINDOWS_BUILD)
# set(BIN_SUB_DIR "/Debug") # If you are building from the command line, you may need to uncomment this
# and set the proper subdirectory to the executables' location.

# Copy relevant AWS SDK for C++ libraries into the current binary directory for running and debugging.
AWSSDK_CPY_DYN_LIBS(
CURRENT_TARGET_AWS_DEPENDENCIES
""
${CMAKE_CURRENT_BINARY_DIR}${BIN_SUB_DIR}
""
${CMAKE_CURRENT_BINARY_DIR} ${BIN_SUB_DIR}
)

add_custom_command(
TARGET
${CURRENT_TARGET}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}${BIN_SUB_DIR}/gtest.dll
${CMAKE_CURRENT_BINARY_DIR}${BIN_SUB_DIR}
TARGET
${CURRENT_TARGET}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} ${BIN_SUB_DIR}/gtest.dll
${CMAKE_CURRENT_BINARY_DIR} ${BIN_SUB_DIR}
)
endif()
endif ()

# GTEST_SOURCE_FILES can be defined in the command line to limit the files in a build, for example to one action.
if (NOT DEFINED GTEST_SOURCE_FILES)
Expand All @@ -78,16 +78,16 @@ if (NOT DEFINED GTEST_SOURCE_FILES)
GTEST_SOURCE_FILES
"gtest_*.cpp"
)
endif()
endif ()

foreach(TEST_FILE ${GTEST_SOURCE_FILES})
foreach (TEST_FILE ${GTEST_SOURCE_FILES})
string(REPLACE "gtest_" "../" SOURCE_FILE ${TEST_FILE})
if (EXISTS ${SOURCE_FILE})
if (EXISTS ${SOURCE_FILE})
list(APPEND GTEST_SOURCE ${SOURCE_FILE} ${TEST_FILE})
else()
else ()
message("Error: no associated source file found for ${TEST_FILE}")
endif()
endforeach()
endif ()
endforeach ()

target_sources(
${CURRENT_TARGET}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ namespace AwsDocTest {
bool result = mockHttp.addResponseWithBody("mock_input/deleteImageSet.json");
ASSERT_TRUE(result) << preconditionError() << std::endl;

result = AwsDoc::Medical_Imaging::deleteImageSet("12345678901234567890123456789012",
"12345678901234567890123456789012",
*s_clientConfig);
result = AwsDoc::Medical_Imaging::deleteImageSet(
"12345678901234567890123456789012",
"12345678901234567890123456789012",
*s_clientConfig);
ASSERT_TRUE(result);
}
} // namespace AwsDocTest
21 changes: 11 additions & 10 deletions cpp/example_code/medical-imaging/tests/gtest_get_image_frame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,23 @@
#include <cstdio>

namespace AwsDocTest {
// NOLINTNEXTLINE(readability-named-parameter)
TEST_F(MedicalImaging_GTests, get_image_frame_3_ ) {
// NOLINTNEXTLINE(readability-named-parameter)
TEST_F(MedicalImaging_GTests, get_image_frame_3_) {
MockHTTP mockHttp;
bool result = mockHttp.addResponseWithBody(
"mock_input/test.jph");
ASSERT_TRUE(result) << preconditionError() << std::endl;
Aws::String outputFileName = "test_output.jph";
result = AwsDoc::Medical_Imaging::getImageFrame("12345678901234567890123456789012",
"12345678901234567890123456789012",
"12345678901234567890123456789012",
outputFileName,
*s_clientConfig);
ASSERT_TRUE(result);
Aws::String outputFileName = "test_output.jph";
result = AwsDoc::Medical_Imaging::getImageFrame(
"12345678901234567890123456789012",
"12345678901234567890123456789012",
"12345678901234567890123456789012",
outputFileName,
*s_clientConfig);
ASSERT_TRUE(result);
std::ifstream ifs(outputFileName);
ASSERT_TRUE(ifs);
std::remove(outputFileName.c_str());
}
}

} // namespace AwsDocTest
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,44 @@
#include <cstdio>

namespace AwsDocTest {
// NOLINTNEXTLINE(readability-named-parameter)
TEST_F(MedicalImaging_GTests, get_image_set_metadata_3_ ) {
// NOLINTNEXTLINE(readability-named-parameter)
TEST_F(MedicalImaging_GTests, get_image_set_metadata_without_version_3_) {
MockHTTP mockHttp;
bool result = mockHttp.addResponseWithBody(
"mock_input/deleteImageSet.json.gz");
ASSERT_TRUE(result) << preconditionError() << std::endl;

Aws::String outFileName = "test.json.gzip";
result = AwsDoc::Medical_Imaging::getImageSetMetadata("12345678901234567890123456789012",
"12345678901234567890123456789012",
outFileName, *s_clientConfig);
ASSERT_TRUE(result);

std::ifstream ifs(outFileName);
ASSERT_TRUE(ifs);
std::remove(outFileName.c_str());
}
result = AwsDoc::Medical_Imaging::getImageSetMetadata(
"12345678901234567890123456789012",
"12345678901234567890123456789012",
"",
outFileName, *s_clientConfig);
ASSERT_TRUE(result);

std::ifstream ifs(outFileName);
ASSERT_TRUE(ifs);
std::remove(outFileName.c_str());
}

// NOLINTNEXTLINE(readability-named-parameter)
TEST_F(MedicalImaging_GTests, get_image_set_metadata_with_version_3_) {
MockHTTP mockHttp;
bool result = mockHttp.addResponseWithBody(
"mock_input/deleteImageSet.json.gz");
ASSERT_TRUE(result) << preconditionError() << std::endl;

Aws::String outFileName = "test.json.gzip";
result = AwsDoc::Medical_Imaging::getImageSetMetadata(
"12345678901234567890123456789012",
"12345678901234567890123456789012",
"1",
outFileName, *s_clientConfig);
ASSERT_TRUE(result);

std::ifstream ifs(outFileName);
ASSERT_TRUE(ifs);
std::remove(outFileName.c_str());
}

} // namespace AwsDocTest
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ namespace AwsDocTest {

const Aws::MedicalImaging::Model::SearchCriteria searchCriteria;
Aws::Vector<Aws::String> imageSetResults;
result = AwsDoc::Medical_Imaging::searchImageSets("12345678901234567890123456789012",
searchCriteria,
imageSetResults,
*s_clientConfig);
result = AwsDoc::Medical_Imaging::searchImageSets(
"12345678901234567890123456789012",
searchCriteria,
imageSetResults,
*s_clientConfig);
ASSERT_TRUE(result);
ASSERT_EQ(2, imageSetResults.size());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace AwsDocTest {
"destination_bucket",
"destination_folder",
"arn:aws:iam::123456789012:role/dicom_import",
jobID,
jobID,
*s_clientConfig);

ASSERT_TRUE(result);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ void AwsDocTest::MedicalImaging_GTests::SetUpTestSuite() {
}

void AwsDocTest::MedicalImaging_GTests::TearDownTestSuite() {
ShutdownAPI(s_options);
ShutdownAPI(s_options);

}

Expand Down Expand Up @@ -80,6 +80,7 @@ int AwsDocTest::MyStringBuffer::underflow() {

return result;
}

AwsDocTest::MockHTTP::MockHTTP() {
mockHttpClient = Aws::MakeShared<MockHttpClient>(ALLOCATION_TAG);
mockHttpClientFactory = Aws::MakeShared<MockHttpClientFactory>(ALLOCATION_TAG);
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 17 additions & 30 deletions workflows/healthimaging_image_sets/SPECIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ This document explains the following:
- Flow of the demo, importing DICOM files, and downloading and decoding image frames.
- Destroying the AWS resources at the end of the example.

For an introduction to *HealthImaging image sets and frames*, see the [TODO README.md](README.md).
For an introduction to *HealthImaging image sets and frames*, see the [README.md](README.md).

Note: HealthImaging is often referenced as MedicalImaging or medical-imaging in the APIs.

Expand All @@ -30,7 +30,7 @@ Note: HealthImaging is often referenced as MedicalImaging or medical-imaging in
A CloudFormation template is used to create and destroy the following resources.

1. A HealthImaging data store.
2. An S3 bucket.
2. Two S3 buckets.
3. An IAM role with permissions for a DICOM import job.

The template is stored at [resources/cfn_template.yaml](resources/cfn_template.yaml).
Expand Down Expand Up @@ -77,7 +77,7 @@ the particular DICOM files to import:
3. Select the DICOM files to import.
4. Choose whether to delete the stack.

For more detail on how this is implemented, see [TODO Demo](#demo).
For more detail on how this is implemented, see [Demo](#demo).

---

Expand Down Expand Up @@ -195,33 +195,22 @@ The application uses GetImageSetMetadata to retrieve the metadata as gzipped JSO
retrieve the image frame IDs.
Other values which are or could be used for image display are also retrieved, as an aid to customers.

TODO - document jmesPATH for these values.

- DICOM.RescaleSlope
- DICOM.RescaleIntercept
- MinPixelValue
- MaxPixelValue

In the code, the following comments were added about transforming the image data.

/*
* Sometimes in DICOM, the max pixel value is small enough that all pixels will appear black
* without applying a transform.
* For example, if the max pixel value is 4000 and the precision is 16,
* then the max pixel will be (4000 / 65535 = 0.06) of the max for the precision.
*
* The following code scales the image data to make it visible when saved as a jpeg image.
* This is done simply for validation purposes, so that you can see if the downloaded
* image was correctly decoded.
*
* This code is not meant to demonstrate a rigorous transform of DICOM image data for
* viewing or other purposes.
* For example, it does not use the rescale slope or the rescale slope intercept values obtained from
* the DICOM metadata.
*
*/
- An image set can have one or more image instances.
- An image instance can have one or more image frames.


- JMESPath query for array of image instances. "Study.Series.*.Instances[].*[]"
- JMESPath query on image instance for the rescale slope. "DICOM.RescaleSlope"
- JMESPath query on image instance for the rescale intercept. "DICOM.RescaleIntercept"
- JMESPath query on image instance for array of image frames. "ImageFrames[][]"
- JMESPath query on image frame for max pixel value. "MaxPixelValue"
- JMESPath query on image frame for min pixel value. "MinPixelValue"
- JMESPath query on image frame for checksum of max resolution image. "max_by(PixelDataChecksumFromBaseToFullResolution, &Width).Checksum"


The image frames are decoded to a bitmap format and then the checksum is calculated and compared with the checksum
retrieved from the metadata.

```
***************************************************************************************
Expand Down Expand Up @@ -310,8 +299,6 @@ TODO
* medical-imaging_DeleteImageSet


TODO - Should CloudFormation metadata be added.

---

# Other material
Expand Down

0 comments on commit 521fedb

Please sign in to comment.