{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Hey There, Welcome!\n\nPlease familiarize yourself with the table of contents for easy navigation. <br>\n\n### Table of contents\n* [Understanding Pulmonary Emolism](#upe)\n* [About The Competition](#atc)\n* [Data](#data)\n* [EDA](#eda)\n* [DICOM Data Handling](#dicom)\n* [Image Data Handling](#image)\n* [TODO And Future Improvements](#todo)"},{"metadata":{},"cell_type":"markdown","source":"# Understanding Pulmonary Embolism <a class=\"anchor\" id=\"upe\"></a>\n\n**Pulmonary embolism (PE)** is a blockage of an artery in the lungs by a substance that has moved from elsewhere in the body through the bloodstream (embolism). It is a condition in which one or more arteries in the lungs become blocked by a blood clot. Most times, a pulmonary embolism is caused by blood clots that travel from the legs, or rarely, other parts of the body (deep vein thrombosis or DVT).\n\n<center> \n    <table><tr><td><img src=\"https://i.imgur.com/wmFMDEe.png\"></td><td><img src=\"https://i.imgur.com/TvZLM2v.png\"></td></tr></table>\n    </center>\n<br>\n<br>\n\n***SYMPTOPMS:*** <br>\n**Pain circumstances:** can occur in the chest while breathing <br>\n**Whole body:** light-headedness or low oxygen in the body <br>\n**Heart:** fast heart rate or palpitations <br>\n**Respiratory:** fast breathing or shortness of breath <br>\n**Also common:** dry cough <br>\n\n***TREATMENT:*** <br>\n*Treatment consists of blood thinners:* Prompt treatment to break up the clot greatly reduces the risk of death. This can be done with blood thinners and drugs or procedures. Compression stockings and physical activity can help prevent clots from forming in the first place.\n\n<center> \n    <table><tr><td><img src=\"https://i.imgur.com/E3UR0Mt.png\" ></td><td><img src=\"https://i.imgur.com/aV5WMyj.png\"></td></tr></table>\n    </center>\n<br>\n<br>\n\n***How It Occurs:*** <br>\nPulmonary embolism is caused by a blocked artery in the lungs. The most common cause of such a blockage is a blood clot that forms in a deep vein in the leg and travels to the lungs, where it gets lodged in a smaller lung artery. Almost all blood clots that cause pulmonary embolism are formed in the deep leg veins. <br>\n\n***How It Kills:*** <br>\nWithout treatment, VTE can restrict or block blood flow and oxygen, which can damage the body's tissue or organs. This can be especially serious in the case of a pulmonary embolism, which blocks blood flow to the lungs. If a blood clot is large or there are many clots, a pulmonary embolism can cause death. <br>\n\n**Mortality Rate:** 1 in 10 Patients <br>\n**Recurrence Rate:** 1 in 5 Recoveries <br>\n\nWatch this short video to get a better idea about this disease:"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"_kg_hide-output":false,"_kg_hide-input":true},"cell_type":"code","source":"from IPython.display import HTML\n\nHTML('<center><iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/1IBvrOBQ268\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe></center>')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## About The Competition <a class=\"anchor\" id=\"atc\"></a>\nCurrently, CT pulmonary angiography (CTPA), is the most common type of medical imaging to evaluate patients with suspected PE. These CT scans consist of hundreds of images that require detailed review to identify clots within the pulmonary arteries. As the use of imaging continues to grow, constraints of radiologists’ time may contribute to delayed diagnosis. <br>\n<br>\nThe Radiological Society of North America (RSNA®) has teamed up with the Society of Thoracic Radiology (STR) to help improve the use of machine learning in the diagnosis of PE. <br>\n<br>\nIn this competition, you’ll detect and classify PE cases. In particular, you'll use chest CTPA images (grouped together as studies) and your data science skills to enable more accurate identification of PE. If successful, you'll help reduce human delays and errors in detection and treatment. <br>\n<br>\nWith 60,000-100,000 PE deaths annually in the United States, it is among the most fatal cardiovascular diseases. Timely and accurate diagnosis will help these patients receive better care and may also improve outcomes."},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true,"_kg_hide-input":true,"_kg_hide-output":true},"cell_type":"code","source":"!conda install -c conda-forge gdcm -y\n!pip install pandas-profiling -y","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":false,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"# Setup\nimport numpy as np \nimport pandas as pd \nimport matplotlib.pyplot as plt\nfrom matplotlib import animation, rc\nimport seaborn as sns\n\nsns.set_style('darkgrid')\nimport pydicom as dcm\nimport scipy.ndimage\nimport gdcm\nimport glob\nimport imageio\nfrom IPython import display\n\nfrom skimage import measure \nfrom mpl_toolkits.mplot3d.art3d import Poly3DCollection\nfrom skimage.morphology import disk, opening, closing\nfrom tqdm import tqdm\n\nfrom IPython.display import HTML\nfrom PIL import Image","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\", category=DeprecationWarning)\nwarnings.filterwarnings(\"ignore\", category=UserWarning)\nwarnings.filterwarnings(\"ignore\", category=FutureWarning)\n\nfrom os import listdir, mkdir\n\npath = \"../input/rsna-str-pulmonary-embolism-detection/\"\nfiles = glob.glob(path+'/train/*/*/*.dcm')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Let's See How Our Data Looks <a class=\"anchor\" id=\"data\"></a>\n\n* *StudyInstanceUID* - unique ID for each study (exam) in the data. <br>\n* *SeriesInstanceUID* - unique ID for each series within the study. <br>\n* *SOPInstanceUID* - unique ID for each image within the study (and data). <br>\n* *pe_present_on_image* - image-level, notes whether any form of PE is present on the image. <br>\n* *negative_exam_for_pe* - exam-level, whether there are any images in the study that have PE present. <br>\n* *qa_motion* - informational, indicates whether radiologists noted an issue with motion in the study. <br>\n* *qa_contrast* - informational, indicates whether radiologists noted an issue with contrast in the study. <br>\n* *flow_artifact* - informational <br>\n* *rv_lv_ratio_gte_1* - exam-level, indicates whether the RV/LV ratio present in the study is >= 1 <br>\n* *rv_lv_ratio_lt_1*- exam-level, indicates whether the RV/LV ratio present in the study is < 1 <br>\n* *leftsided_pe* - exam-level, indicates that there is PE present on the left side of the images in the study <br>\n* *chronic_pe* - exam-level, indicates that the PE in the study is chronic <br>\n* *true_filling_defect_not_pe* - informational, indicates a defect that is NOT PE <br>\n* *rightsided_pe* - exam-level, indicates that there is PE present on the right side of the images in the study <br>\n* *acute_and_chronic_pe* - exam-level, indicates that the PE present in the study is both acute AND chronic <br>\n* *central_pe* - exam-level, indicates that there is PE present in the center of the images in the study <br>\n* *indeterminate* -exam-level, indicates that while the study is not negative for PE, an ultimate set of exam-level labels could not be created, due to QA issues <br>\n"},{"metadata":{"_kg_hide-input":false,"trusted":true},"cell_type":"code","source":"# Reading Data\ntrain = pd.read_csv(path + \"train.csv\")\ntest = pd.read_csv(path + \"test.csv\")\nprint(\"Train Data Shape:\",train.shape)\nprint(\"Test Data Shape:\",test.shape)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.head(5).T","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test.describe()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('Missing values in train data:',train.isnull().sum().sum())\nprint('Missing values in test data:',test.isnull().sum().sum())","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"from pandas_profiling import ProfileReport\nprofile = ProfileReport(train, title='Training Data Report')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## EDA <a class=\"anchor\" id=\"eda\"></a>"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"profile.to_notebook_iframe()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"cols = train.copy()\ncols.drop(['StudyInstanceUID','SeriesInstanceUID','SOPInstanceUID'],axis=1,inplace=True)\ncolumns = cols.columns\n\ncorr = cols.corr()\nmask = np.zeros_like(corr)\nmask[np.triu_indices_from(mask)] = True\nwith sns.axes_style(\"white\"):\n    f, ax = plt.subplots(figsize=(12, 12))\n    ax = sns.heatmap(corr,mask=mask,square=True,linewidths=.8,cmap=\"gnuplot\",annot=True)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(7,2,figsize=(16,28))\nfor i,col in enumerate(columns): \n    plt.subplot(7,2,i+1)\n    sns.countplot(cols[col],palette=\"gnuplot\")   ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## What is a DICOM? <a class=\"anchor\" id=\"dicom\"></a>\n\n**D**igital **I**maging and **Co**mmunications in **M**edicine (DICOM) - an international standard related to the exchange, storage and communication of digital medical images. Prior to this format, there was no standardized way to transfer medical scans. So loading up a single patient's study outside the hospital, in older formats took about 10-30 minutes for a single scan! \n\nWhile DICOM 16-bit images (with values ranging from -32768..32767), other 8-bit greyscale images store values 0 - 255. These value ranges in DICOM are useful, as they correlate with the [Hounsfield Scale](https://en.wikipedia.org/wiki/Hounsfield_scale). Each voxel can store a large amount of information.\n\nRead more about it here: https://www.dicomstandard.org/\n\n![ct](https://media.giphy.com/media/2kWaWmhoFfFkI/giphy.gif)\n\nNow, we will see dicom data of a random sample from our data."},{"metadata":{"trusted":true},"cell_type":"code","source":"from random import randint\n# This function reads dicom images from the given path\ndef load_dicom(path):\n    files = listdir(path)\n    f = [dcm.dcmread(path + \"/\" + str(file)) for file in files]\n    return f\n\nrandom_integer = randint(0,len(train))\nexample = path + \"train/\" + train.StudyInstanceUID.values[random_integer] +'/'+ train.SeriesInstanceUID.values[random_integer]\nscans = load_dicom(example)\nscans[randint(0,len(scans))]","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Looking at the Image Data <a class=\"anchor\" id=\"image\"></a>"},{"metadata":{"trusted":true},"cell_type":"code","source":"f, plots = plt.subplots(3, 3, sharex='col', sharey='row', figsize=(15, 15))\nfor i in range(9):\n    plots[i // 3, i % 3].axis('off')\n    plots[i // 3, i % 3].imshow(dcm.dcmread(np.random.choice(files[:3000])).pixel_array,cmap='gist_earth_r')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### A closer look..."},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(10, 10))\nax.imshow(dcm.dcmread(np.random.choice(files[:3000])).pixel_array, cmap=\"gist_earth_r\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## For a Single Person...\n\ncredit: https://www.kaggle.com/nitindatta/pulmonary-embolism-dicom-preprocessing-eda"},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"def load_slice(path):\n    slices = [dcm.read_file(path + '/' + s) for s in listdir(path)]\n    slices.sort(key = lambda x: float(x.ImagePositionPatient[2]))\n    try:\n        slice_thickness = np.abs(slices[0].ImagePositionPatient[2] - slices[1].ImagePositionPatient[2])\n    except:\n        slice_thickness = np.abs(slices[0].SliceLocation - slices[1].SliceLocation)\n        \n    for s in slices:\n        s.SliceThickness = slice_thickness\n        \n    return slices\n\ndef transform_to_hu(slices):\n    images = np.stack([file.pixel_array for file in slices])\n    images = images.astype(np.int16)\n\n    # convert ouside pixel-values to air:\n    # I'm using <= -1000 to be sure that other defaults are captured as well\n    images[images <= -1000] = 0\n    \n    # convert to HU\n    for n in range(len(slices)):\n        \n        intercept = slices[n].RescaleIntercept\n        slope = slices[n].RescaleSlope\n        \n        if slope != 1:\n            images[n] = slope * images[n].astype(np.float64)\n            images[n] = images[n].astype(np.int16)\n            \n        images[n] += np.int16(intercept)\n    \n    return np.array(images, dtype=np.int16)","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"first_patient = load_slice(path+'/train/0003b3d648eb/d2b2960c2bbf')\nfirst_patient_pixels = transform_to_hu(first_patient)\n\nfig, plots = plt.subplots(8, 10, sharex='col', sharey='row', figsize=(20, 16))\nfor i in range(80):\n    plots[i // 10, i % 10].axis('off')\n    plots[i // 10, i % 10].imshow(first_patient_pixels[i], cmap=\"gray\") ","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"imageio.mimsave(\"/tmp/gif.gif\", first_patient_pixels, duration=0.08)\ndisplay.Image(filename=\"/tmp/gif.gif\", format='png')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## What is CT(Computed Tomography) and How it Works?\n<center>\n    <img src = \"https://i.imgur.com/0wZOIKt.jpg\" width = \"80%\">\n</center>\n<br>\n**Computed tomography (CT)** scanning, also known as, especially in the older literature and textbooks, computerized axial tomography (CAT) scanning, is a diagnostic imaging procedure that uses x-rays to build cross-sectional images (\"slices\") of the body. Cross-sections are reconstructed from measurements of attenuation coefficients of x-ray beams in the volume of the object studied.\n\nCT is based on the fundamental principle that the density of the tissue passed by the x-ray beam can be measured from the calculation of the attenuation coefficient. Using this principle, CT allows the reconstruction of the density of the body, by two-dimensional section perpendicular to the axis of the acquisition system.\n\nThe CT x-ray tube (typically with energy levels between 20 and 150 keV), emits N photons (monochromatic) per unit of time. The emitted x-rays form a beam which passes through the layer of biological material of thickness Δx. A detector placed at the exit of the sample, measures N + ΔN photons, ΔN smaller than 0. Attenuation values of the x-ray beam are recorded and data used to build a 3D representation of the scanned object/tissue.\n\nThere are basically two processes of the absorption: **the photoelectric effect and the Compton effect**. This phenomenon is represented by a single coefficient, mju.\n\nIn the particular case of the CT, the emitter of x-rays rotates around the patient and the detector, placed in diametrically opposite side, picks up the image of a body section (beam and detector move in synchrony).\n\nUnlike x-ray radiography, the detectors of the CT scanner do not produce an image. They measure the transmission of a thin beam (1-10 mm) of x-rays through a full scan of the body. The image of that section is taken from different angles, and this allows to retrieve the information on the depth (in the third dimension).\n\nIn order to obtain tomographic images of the patient from the data in \"raw\" scan, the computer uses complex mathematical algorithms for image reconstruction.\n\nIf the x-ray at the exit of the tube is made monochromatic or quasi-monochromatic with the proper filter, one can calculate the attenuation coefficient corresponding to the volume of irradiated tissue by the application of the general formula of absorption of the x-rays in the field (see Figure 1).\n\nThe outgoing intensity I(x) of the beam of photons measured will depend on the location. In fact, I(x) is smaller where the body is more radiopaque.\n\n**Hounsfield** chose a scale that affects the four basic densities, with the following values:\n\n    air = -1000\n    fat = -60 to -120\n    water = 0\n    compact bone = +1000\n\nThe image of the section of the object irradiated by the x-ray is reconstructed from a large number of measurements of attenuation coefficient. It gathers together all the data coming from the elementary volumes of material through the detectors. Using the computer, it presents the elementary surfaces of the reconstructed image from a projection of the data matrix reconstruction, the tone depending on the attenuation coefficients.\n\nThe image by the CT scanner is a digital image and consists of a square matrix of elements (pixel), each of which represents a voxel (volume element) of the tissue of the patient.\n\nIn conclusion, a measurement made by a detector CT is proportional to the sum of the attenuation coefficients.\n\nThe typical CT image is composed of **512 rows, each of 512 pixels**, i.e., a square matrix of **512 x 512 = 262,144 pixels** (one for each voxel). In the process of the image, the value of the attenuated coefficient for each voxel corresponding to these pixel needs to be calculated.\n\nEach image point is surrounded by a halo-shaped star that degrades the contrast and blurs the boundary of the object. To avoid this, the method of filtered back projection is used. The action of the filter function is such that the negative value created is the filtered projection, when projected backwards, is removed, and an image is produced, which is the accurate representation of the original object.\n\nThe CT scan deals with the attenuation of the x-rays during the passage through the body segment. However, several features distinguish it from conventional radiology: the image is reconstructed from a large number of measurements of attenuation coefficient.\n\nBefore the data are presented on the screen, the conventional rescaling was made into CT numbers, expressed in Hounsfield Units (HU), as mentioned before. CT numbers based on measurements with the EMI scanner invented by Sir Godfrey Hounsfield 6, a Nobel prize winner for his work in 1979, related the linear attenuation coefficient of a localized region with the attenuation coefficient of water, the multiplication factor of 1000 is used for CT number integers. \n\nSo, the signal transmitted by the detector is processed by the PC in the form of the digital information, the CT image reconstruction.\n"},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"HTML('<center><iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/SdYUniRMtz4\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe></center>')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# ⚠️Work In Progress⚠️ <a class=\"anchor\" id=\"todo\"></a>\n\n## TODO:\n1. <del> What are CT scans and how they work?\n2. Understanding competition evaluation metric.\n3. Potential ways to approach this competition.\n4. Models and Techniques that can be used.\n\nAll this and more is on the way so stay tuned! Happy Kaggling!\n\n[NOTE] I will be releasing a starter notebook with pytorch code soon."}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}