pythoncourse

Assignments (Py02)

Problem 1: Patient Monitoring and Alert System

Hard

Scenario:
A hospital has a patient monitoring system that tracks the vital signs of patients in the intensive care unit (ICU). Each patient’s heart rate is recorded every minute and stored in an array. The array for each patient contains the heart rate data for the last 24 hours (1440 minutes). The hospital wants to implement an alert system that detects potential issues based on abnormal heart rate patterns.

Problem Statement:
Write a program that takes in the heart rate data for a patient as an array of 1440 integers and checks for the following: 1. Tachycardia Alert: If the heart rate exceeds 100 bpm for 15 consecutive minutes or more, raise a Tachycardia alert. 2. Bradycardia Alert: If the heart rate drops below 60 bpm for 10 consecutive minutes or more, raise a Bradycardia alert.

The program should output a list of times (in minutes from the start of the 24-hour period) where alerts were triggered.

Array Usage:

# Example usage (dummy data)
# read in the heart rate data csv file as array of integers 
heart_rate_data = np.genfromtxt('Data/heart_rate_data.csv', delimiter=',')
# Run the function
alerts = check_heart_rate(heart_rate_data)
print(alerts)  # Print the detected alerts
# {'Tachycardia': [(47, 65, 19), (234, 248, 15), (315, 329, 15), (404, 439, 36)], 'Bradycardia': [(990, 1001, 12), (1090, 1100, 11), (1166, 1179, 14), (1374, 1388, 15)]}

If you stop here, and code this function, by yourself, you will learn a lot. (HARD)




Medium

To solve the problem more efficiently using array functions and reduce the number of iterations, follow these steps:

1. Identify Consecutive Segments

2. Find Runs of 1s

3. Filter Based on Length

4. Extract Start and End Times

5. Output the Alerts

Efficiency Considerations

Summary of Steps Using Array Functions

  1. Create binary masks for abnormal heart rates.
  2. Identify consecutive runs of abnormal values using array operations.
  3. Filter these runs by duration to determine valid alerts.
  4. Calculate and store the times of these alerts.
  5. Return the results in a structured format.

If you stop here, and code this function, with the help of the instructions above, you still learn a lot. (MEDIUM)




Easy

Fill the TODOs in the code below to complete the function.

Here’s the dummy Python code that outlines the process using array functions to minimize iterations:

import numpy as np

def check_heart_rate(heart_rate_data):
    # Step 1: Create binary masks
    tachy_mask = #TODO # Mask for Tachycardia
    brady_mask = #TODO # Mask for Bradycardia
    
    # Step 2: Identify consecutive runs of abnormal values
    # Calculate differences to find the start and end of runs
    tachy_diff = #TODO  # Calculate diff for Tachycardia
    brady_diff = #TODO  # Calculate diff for Bradycardia

    # Find the indices where runs start and end
    tachy_start_indices = np.where(tachy_diff == 1)[0]
    tachy_end_indices = np.where(tachy_diff == -1)[0] - 1

    brady_start_indices = #TODO
    brady_end_indices = #TODO

    # Step 3: Filter by length of runs
    tachy_alerts = []
    brady_alerts = []

    for start, end in zip(tachy_start_indices, tachy_end_indices):
        lenght = end - start + 1
        if lenght >= 15:  # Check if the run is 15 minutes or more
            tachy_alerts.append((start, end, lenght))

    #TODO same for brady_alerts loop

    # Step 4: Combine the alerts
    alerts = {
        "Tachycardia": tachy_alerts,
        "Bradycardia": brady_alerts
    }

    return alerts

Breakdown of the Python Code

  1. Binary Masks:
    • tachy_mask and brady_mask are arrays where each element is True if the corresponding heart rate meets the criteria for Tachycardia or Bradycardia, respectively.
  2. Identifying Consecutive Runs:
    • np.diff is used to find where the binary mask switches from False to True (indicating the start of a run) and from True to False (indicating the end of a run).
    • Concatenating with [0] ensures that changes at the boundaries (beginning or end) are detected.
  3. Filtering Runs:
    • The code checks each run to see if it meets the minimum duration required for an alert.
    • Only runs that are long enough are stored in the tachy_alerts or brady_alerts lists.
  4. Combining Alerts:
    • The alerts are stored in a dictionary and returned.

You finished this problem, if you complete the code above, and test it with the example usage. (EASY)




Problem 2: Medical Imaging Pixel Intensity Analysis

Hard

Scenario:
A radiologist is analyzing a grayscale MRI image represented as a 2D array, where each element in the array represents the intensity of a pixel (ranging from 0 to 255). The radiologist wants to identify regions of interest (ROI) where the pixel intensity exceeds a certain threshold, indicating possible abnormalities. !wget https://raw.githubusercontent.com/stawiskm/pythoncourse/student/Assignments/Data/mri_image.png

Problem Statement:
Write a program that takes a 2D array representing an MRI scan and a threshold value as input. The program should:

  1. Should create a segmentation mask where each pixel above the threshold is marked as 1 and others as 0.
  2. Calculate the following from Mask:
    • The total number of pixels above the threshold.
    • The average intensity of the pixels above the threshold.
    • The maximum intensity value among the pixels above the threshold.
  3. Apply the Mask to the Image and window the remaining pixel values between 10 and 255.
  4. Return the segmentation mask, the calculated values, and the windowed image.

Array Usage:

These problems can be solved efficiently using arrays and basic array operations in coding.

# Example usage
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image

# Example usage (mri_image.png is a dummy image)
mri_image = Image.open('Data/mri_image.png')
# Convert the image to grayscale
mri_image = np.mean(mri_image, axis=2, dtype=int)
mri_image = np.array(mri_image)
threshold = 250

# Analyze the image
results = analyze_mri_image(mri_image, threshold)

# Plot the results
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
axes[0].imshow(mri_image, cmap='gray', vmin=0, vmax=255)
axes[0].set_title('Original Image')
axes[0].axis('off')

axes[1].imshow(results['segmentation_mask'], cmap='gray', vmin=0, vmax=1)
axes[1].set_title('Segmentation Mask')
axes[1].axis('off')

axes[2].imshow(results['windowed_image'], cmap='gray', vmin=0, vmax=255)
axes[2].set_title('Windowed Segmented Image')
axes[2].axis('off')

plt.show()

If you stop here, and code this function, by yourself, you will learn a lot. (HARD)




Medium

Here’s how to solve the problem efficiently using array functions and numpy:

  1. Create a Segmentation Mask:
    • Create a new 2D array (mask) where each pixel is set to 1 if its intensity exceeds the threshold, and 0 otherwise.
  2. Calculate Statistics from the Mask:
    • Extract the pixels from the original image where the mask value is 1 (i.e., pixels above the threshold).
    • Count the total number of these pixels.
    • Compute the average intensity of these pixels by summing their intensities and dividing by the total number of pixels.
    • Determine the maximum intensity value among these pixels.
  3. Apply Mask and do the windowing of the values:
    • Use numpy.where to apply the mask. Pixels above the threshold get new values within the range of 10 to 255.
      • Windowing with Full 0-255 Range:
        • After identifying the pixels above the threshold, we find the minimum and maximum intensity values among them.
        • We then linearly rescale these pixel values so that the minimum value maps to 10 and the maximum value maps to 255. This is done using the formula: alt text
        • We use numpy.clip to ensure the rescaled values remain within the 10-255 range.
      • Handling Edge Cases:
        • If all pixels above the threshold have the same intensity (i.e., max_intensity == min_intensity), the scale is set to 1, preventing division by zero.
  4. Return Results:
    • Provide the segmentation mask.
    • Return the total count of pixels above the threshold.
    • Return the average and maximum intensity values of the pixels above the threshold.
    • Provide the modified image where non-ROI pixels are set to 0 and intensity values are clipped to the valid range.

If you stop here, and code this function, with the help of the instructions above, you still learn a lot. (MEDIUM)




Easy

Here’s some dummy code in Python to achieve this. We’ll use basic array operations and numpy for efficiency.

import numpy as np

def analyze_mri_image(mri_image, threshold):
    max_intensity = 0
    min_intensity = 0
    
    # Convert the input image to a numpy array (if not already in that format)
    mri_image = #TODO
        
    # Step 1: Create a segmentation mask
    segmentation_mask = #TODO
    
    # Step 2: Calculate statistics
    # Get pixels above the threshold
    above_threshold_pixels = #TODO
    
    # Calculate the total number of pixels above the threshold
    total_above_threshold = #TODO
    
    # Calculate the average intensity of the pixels above the threshold
    if total_above_threshold > 0:
        average_intensity = above_threshold_pixels.mean()
        max_intensity = above_threshold_pixels.max()
        min_intensity = above_threshold_pixels.min()

        # Step 3: Apply the mask and window the pixel values
        # segment the image by applying the mask
        segmented_image = #TODO  
        # Rescale the pixel values to the 10-255 range
        windowed_image = #TODO

    else:
        average_intensity = 0  # Avoid division by zero if no pixels exceed the threshold
        max_intensity = 0
        min_intensity = 0
        windowed_image = mri_image
    
    # Return results
    return {
        'segmentation_mask': segmentation_mask,
        'total_above_threshold': total_above_threshold,
        'average_intensity': average_intensity,
        'max_intensity': max_intensity,
        'windowed_image': windowed_image
    }

This code provides a comprehensive analysis of the MRI image and efficiently processes the data using numpy’s capabilities.