If u suggest me an X ray must know for the MBBS exam respiratory exam ,find that X rays, and include that X ray in pdf and make a good shirt notes on it as pdf
MBBS respiratory radiology must know chest X-ray findings exam pneumothorax pleural effusion pneumonia TB
You need to download real chest X-ray images for a medical study PDF. Download the following open-access chest X-ray images from Wikimedia Commons or PMC/NIH open access sources into /tmp/workspace/xray_images/ directory. Create the directory first. For each image, use wget or curl to download it. Save them with these specific filenames: 1. Pneumothorax X-ray: Try: https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Pneumothorax_on_chest_xray.jpg/800px-Pneumothorax_on_chest_xray.jpg Save as: /tmp/workspace/xray_images/01_pneumothorax.jpg 2. Pleural effusion X-ray: Try: https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Pleural_effusion.jpg/800px-Pleural_effusion.jpg Save as: /tmp/workspace/xray_images/02_pleural_effusion.jpg 3. Lobar Pneumonia X-ray: Try: https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Lobar_pneumonia_with_abscess.jpg/800px-Lobar_pneumonia_with_abscess.jpg Save as: /tmp/workspace/xray_images/03_pneumonia.jpg 4. Pulmonary TB X-ray: Try: https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Tuberculosis-x-ray-1.jpg/800px-Tuberculosis-x-ray-1.jpg Save as: /tmp/workspace/xray_images/04_tb.jpg 5. Pulmonary edema / cardiomegaly: Try: https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Pulmonary_oedema.jpg/800px-Pulmonary_oedema.jpg Save as: /tmp/workspace/xray_images/05_pulmonary_edema.jpg 6. Lung abscess (cavity): Try: https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Lung_abscess_-_posteroanterior_chest_radiograph.jpg/800px-Lung_abscess_-_posteroanterior_chest_radiograph.jpg Save as: /tmp/workspace/xray_images/06_lung_abscess.jpg 7. COPD / Hyperinflation: Try: https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/COPD_X-Ray.jpg/800px-COPD_X-Ray.jpg Save as: /tmp/workspace/xray_images/07_copd.jpg 8. Normal chest X-ray (for comparison): Try: https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Chest_X-ray_PA_3-8-2010.png/800px-Chest_X-ray_PA_3-8-2010.png Save as: /tmp/workspace/xray_images/00_normal.jpg For any URL that fails (404 or non-image), try alternative Wikimedia Commons URLs by searching for the actual file. The key is to get real chest X-ray JPEG/PNG files that are at least 100KB in size (to confirm they're real images, not error pages). After downloading, run `ls -lh /tmp/workspace/xray_images/` to show which files were successfully downloaded and their sizes. Only report files that are >50KB (those are real images; smaller ones are likely error pages). Return a JSON list of successfully downloaded files like: {"downloaded": [{"filename": "00_normal.jpg", "path": "/tmp/workspace/xray_images/00_normal.jpg", "size_kb": 245}, ...]}
mkdir -p /tmp/workspace/xray_images && echo "Directory created"
cd /tmp/workspace/xray_images && \ wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Pneumothorax_on_chest_xray.jpg/800px-Pneumothorax_on_chest_xray.jpg" \ -O 01_pneumothorax.jpg 2>&1; echo "Exit: $?" wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Pleural_effusion.jpg/800px-Pleural_effusion.jpg" \ -O 02_pleural_effusion.jpg 2>&1; echo "Exit: $?" wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Lobar_pneumonia_with_abscess.jpg/800px-Lobar_pneumonia_with_abscess.jpg" \ -O 03_pneumonia.jpg 2>&1; echo "Exit: $?" wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Tuberculosis-x-ray-1.jpg/800px-Tuberculosis-x-ray-1.jpg" \ -O 04_tb.jpg 2>&1; echo "Exit: $?" wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Pulmonary_oedema.jpg/800px-Pulmonary_oedema.jpg" \ -O 05_pulmonary_edema.jpg 2>&1; echo "Exit: $?" wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Lung_abscess_-_posteroanterior_chest_radiograph.jpg/800px-Lung_abscess_-_posteroanterior_chest_radiograph.jpg" \ -O 06_lung_abscess.jpg 2>&1; echo "Exit: $?" wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/COPD_X-Ray.jpg/800px-COPD_X-Ray.jpg" \ -O 07_copd.jpg 2>&1; echo "Exit: $?" wget -q --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Chest_X-ray_PA_3-8-2010.png/800px-Chest_X-ray_PA_3-8-2010.png" \ -O 00_normal.jpg 2>&1; echo "Exit: $?" ls -lh /tmp/workspace/xray_images/
cd /tmp/workspace/xray_images && \ curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Pneumothorax_on_chest_xray.jpg/800px-Pneumothorax_on_chest_xray.jpg" \ -o 01_pneumothorax.jpg -s -w "pneumothorax: %{http_code} %{size_download} bytes\n" && \ curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d6/Pleural_effusion.jpg/800px-Pleural_effusion.jpg" \ -o 02_pleural_effusion.jpg -s -w "pleural_effusion: %{http_code} %{size_download} bytes\n" && \ curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b3/Lobar_pneumonia_with_abscess.jpg/800px-Lobar_pneumonia_with_abscess.jpg" \ -o 03_pneumonia.jpg -s -w "pneumonia: %{http_code} %{size_download} bytes\n" && \ curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5c/Tuberculosis-x-ray-1.jpg/800px-Tuberculosis-x-ray-1.jpg" \ -o 04_tb.jpg -s -w "tb: %{http_code} %{size_download} bytes\n" && \ curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/3/31/Pulmonary_oedema.jpg/800px-Pulmonary_oedema.jpg" \ -o 05_pulmonary_edema.jpg -s -w "pulmonary_edema: %{http_code} %{size_download} bytes\n" && \ curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Lung_abscess_-_posteroanterior_chest_radiograph.jpg/800px-Lung_abscess_-_posteroanterior_chest_radiograph.jpg" \ -o 06_lung_abscess.jpg -s -w "lung_abscess: %{http_code} %{size_download} bytes\n" && \ curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/COPD_X-Ray.jpg/800px-COPD_X-Ray.jpg" \ -o 07_copd.jpg -s -w "copd: %{http_code} %{size_download} bytes\n" && \ curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Chest_X-ray_PA_3-8-2010.png/800px-Chest_X-ray_PA_3-8-2010.png" \ -o 00_normal.jpg -s -w "normal: %{http_code} %{size_download} bytes\n" echo "--- File listing ---" ls -lh /tmp/workspace/xray_images/
# Try full-resolution (non-thumb) Wikimedia URLs and check response cd /tmp/workspace/xray_images # Test one direct file URL first curl -L -A "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://en.wikipedia.org/" \ "https://upload.wikimedia.org/wikipedia/commons/1/1b/Pneumothorax_on_chest_xray.jpg" \ -o test_pnx.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" ls -lh test_pnx.jpg
# Try with different Wikimedia URLs - search for correct filenames # Let's try some well-known X-ray images from Wikimedia Commons cd /tmp/workspace/xray_images # Test pneumothorax - trying exact known filename curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Accept: image/webp,image/apng,image/*,*/*;q=0.8" \ -H "Referer: https://commons.wikimedia.org/" \ "https://upload.wikimedia.org/wikipedia/commons/b/b5/Pneumothorax_CXR.jpg" \ -o test1.jpg -s -w "test1: %{http_code} %{size_download}\n" curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Accept: image/webp,image/apng,image/*,*/*;q=0.8" \ -H "Referer: https://commons.wikimedia.org/" \ "https://upload.wikimedia.org/wikipedia/commons/5/5c/Tuberculosis-x-ray-1.jpg" \ -o test2.jpg -s -w "test2: %{http_code} %{size_download}\n" ls -lh test*.jpg
wikimedia commons chest xray pneumothorax direct image URL upload.wikimedia.org
wikimedia commons tuberculosis pleural effusion pulmonary edema chest xray direct image file URL
# Use Wikimedia Commons API to get direct image URLs # API endpoint: https://commons.wikimedia.org/w/api.php?action=query&titles=File:NAME&prop=imageinfo&iiprop=url&format=json FILES=( "Pneumothorax_CXR.jpg" "Pleural_effusion.jpg" "Pneumonia_x-ray.jpg" "Tuberculosis-x-ray-1.jpg" "Pulmonary_oedema.jpg" "Lung_abscess_-_posteroanterior_chest_radiograph.jpg" "COPD_X-Ray.jpg" "Chest_Xray_PA_3-8-2010.png" "Chest_X-ray_of_pneumothorax.png" "X-ray_subtle_pneumothorax_in_inspiration.jpg" ) for f in "${FILES[@]}"; do echo "=== $f ===" curl -s "https://commons.wikimedia.org/w/api.php?action=query&titles=File:${f}&prop=imageinfo&iiprop=url&format=json" | python3 -c "import sys,json; d=json.load(sys.stdin); pages=d['query']['pages']; [print('URL:', v['imageinfo'][0]['url']) for k,v in pages.items() if 'imageinfo' in v]" 2>/dev/null || echo "No URL found" done
# Get additional missing URLs via API FILES2=( "Lung_abscess_posteroanterior_chest_radiograph.jpg" "Lung_abscess.jpg" "COPD_radiograph.jpg" "Pulmonary_emphysema_COPD.jpg" "Chest_radiograph_in_influenza_and_Haemophilus_influenzae.jpg" "Chest_radiograph_showing_fibrous_tumor_of_the_pleura.jpg" "Emphysema_022.jpg" ) for f in "${FILES2[@]}"; do echo "=== $f ===" curl -s "https://commons.wikimedia.org/w/api.php?action=query&titles=File:${f}&prop=imageinfo&iiprop=url&format=json" | python3 -c "import sys,json; d=json.load(sys.stdin); pages=d['query']['pages']; [print('URL:', v['imageinfo'][0]['url']) for k,v in pages.items() if 'imageinfo' in v]" 2>/dev/null || echo "No URL found" done
wikimedia commons "lung abscess" chest radiograph X-ray file commons.wikimedia.org
wikimedia commons COPD chest X-ray hyperinflation file commons.wikimedia.org
# Get API URLs for lung abscess, COPD, lobar pneumonia alternatives FILES3=( "COPD.JPG" "X-ray_of_lobar_pneumonia.jpg" "Lung_abscess_CXR_annotated.JPG" "Cavitary_lesion_right_lung.jpg" "Lung_cavity.jpg" "Abscess_lung.jpg" ) for f in "${FILES3[@]}"; do echo "=== $f ===" curl -s "https://commons.wikimedia.org/w/api.php?action=query&titles=File:${f}&prop=imageinfo&iiprop=url&format=json" | python3 -c "import sys,json; d=json.load(sys.stdin); pages=d['query']['pages']; [print('URL:', v['imageinfo'][0]['url']) for k,v in pages.items() if 'imageinfo' in v]" 2>/dev/null || echo "No URL found" done
# Search Commons API directly for these files curl -s "https://commons.wikimedia.org/w/api.php?action=query&list=search&srsearch=lung+abscess+chest+xray&srnamespace=6&format=json&srlimit=5" | python3 -c " import sys,json d=json.load(sys.stdin) for r in d['query']['search']: print(r['title']) " echo "---" curl -s "https://commons.wikimedia.org/w/api.php?action=query&list=search&srsearch=COPD+chest+xray&srnamespace=6&format=json&srlimit=5" | python3 -c " import sys,json d=json.load(sys.stdin) for r in d['query']['search']: print(r['title']) "
# Try with user agent for API requests curl -s -A "Mozilla/5.0" "https://commons.wikimedia.org/w/api.php?action=query&list=search&srsearch=lung+abscess+chest+xray&srnamespace=6&format=json&srlimit=5" | python3 -c " import sys,json d=json.load(sys.stdin) for r in d['query']['search']: print(r['title']) " echo "---COPD---" curl -s -A "Mozilla/5.0" "https://commons.wikimedia.org/w/api.php?action=query&list=search&srsearch=COPD+chest+xray&srnamespace=6&format=json&srlimit=5" | python3 -c " import sys,json d=json.load(sys.stdin) for r in d['query']['search']: print(r['title']) "
# Test if we can reach wikimedia API at all curl -v -s -A "Mozilla/5.0" "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Pneumothorax_CXR.jpg&prop=imageinfo&iiprop=url&format=json" 2>&1 | head -40
# Check full response from the previously working API call RESULT=$(curl -s -A "Mozilla/5.0" "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Pneumothorax_CXR.jpg&prop=imageinfo&iiprop=url&format=json") echo "Response length: ${#RESULT}" echo "First 200 chars: ${RESULT:0:200}"
# Rate limited - wait a bit and try again, and use batch API calls to be efficient sleep 5 # Batch request for all files at once RESULT=$(curl -s -A "Mozilla/5.0 (compatible; MediaBot/1.0; +mailto:bot@example.com)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:COPD.JPG|File:X-ray_of_lobar_pneumonia.jpg|File:Lung_abscess_CXR.jpg|File:Lung_abscess_chest_X-ray.jpg&prop=imageinfo&iiprop=url&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): print(v['title'], '->', v.get('imageinfo', [{}])[0].get('url', 'MISSING')) " 2>/dev/null || echo "RAW: $RESULT"
sleep 3 # Get URL for lung abscess alternatives RESULT=$(curl -s -A "Mozilla/5.0 (compatible; MediaBot/1.0; +mailto:bot@example.com)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Lung_abscess_CXR_annotated.JPG|File:Klebsiella_pneumoniae_lung_abscess.jpg|File:Pneumonia_lung_abscess.jpg|File:Right_lung_abscess.jpg|File:Cavitating_lung_lesion.jpg&prop=imageinfo&iiprop=url&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] url=v.get('imageinfo', [{}])[0].get('url', 'MISSING') print(title, '->', url) " 2>/dev/null
site:commons.wikimedia.org "lung abscess" chest radiograph X-ray file JPG
sleep 5 # Batch API request for remaining files RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:XR_chest_-_pneumonia_with_abscess_and_caverns_-_d0.jpg|File:Chest_radiograph_of_a_lung_with_Kerley_B_lines.jpg&prop=imageinfo&iiprop=url&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] url=v.get('imageinfo', [{}])[0].get('url', 'MISSING') print(title, '->', url) " 2>/dev/null || echo "RATE LIMITED: $RESULT"
cd /tmp/workspace/xray_images && rm -f test*.jpg # Download all 8 images with correct URLs (found via API) # Use --max-time 30 per file and add brief delays between requests echo "Downloading 01_pneumothorax.jpg..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/2/2f/Pneumothorax_CXR.jpg" \ -o 01_pneumothorax.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" sleep 2 echo "Downloading 02_pleural_effusion.jpg..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/e/e7/Pleural_effusion.jpg" \ -o 02_pleural_effusion.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" sleep 2 echo "Downloading 03_pneumonia.jpg..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/5/51/X-ray_of_lobar_pneumonia.jpg" \ -o 03_pneumonia.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" sleep 2 echo "Downloading 04_tb.jpg..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/9/9c/Tuberculosis-x-ray-1.jpg" \ -o 04_tb.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" sleep 2 echo "Downloading 05_pulmonary_edema.jpg..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/7/75/Pulmonary_oedema.jpg" \ -o 05_pulmonary_edema.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n"
cd /tmp/workspace/xray_images sleep 2 echo "Downloading 06_lung_abscess.jpg..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/4/4d/XR_chest_-_pneumonia_with_abscess_and_caverns_-_d0.jpg" \ -o 06_lung_abscess.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" sleep 2 echo "Downloading 07_copd.jpg..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/0/0b/COPD.JPG" \ -o 07_copd.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" sleep 2 echo "Downloading 00_normal.jpg..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/c/c8/Chest_Xray_PA_3-8-2010.png" \ -o 00_normal.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" echo "" echo "=== FINAL FILE LISTING ===" ls -lh /tmp/workspace/xray_images/
cd /tmp/workspace/xray_images # Compute sizes in KB and output JSON python3 -c " import os, json files = sorted(os.listdir('/tmp/workspace/xray_images/')) results = [] for f in files: path = f'/tmp/workspace/xray_images/{f}' size_bytes = os.path.getsize(path) size_kb = round(size_bytes / 1024, 1) if size_kb > 50: results.append({'filename': f, 'path': path, 'size_kb': size_kb}) print(f'{f}: {size_kb} KB - PASS') else: print(f'{f}: {size_kb} KB - FAIL (too small)') print() print(json.dumps({'downloaded': results}, indent=2)) "
sleep 3 # Get better URLs for pleural effusion and TB - look for higher-res alternatives RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Pleural_effusion_CXR_annotated.jpg|File:Pleural_effusion_CXR.jpg|File:Large_right_sided_pleural_effusion.jpg|File:Tuberculous_lesions_in_lungs.jpg|File:TB_Chest_Xray.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null || echo "Error: $RESULT"
sleep 3 # Try more TB and pleural effusion options RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Tuberculosis_chest_xray.jpg|File:Tuberculosis_nodule_xray.jpg|File:Military_TB.jpg|File:Pleural_effusion_PA.jpg|File:Right_pleural_effusion.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null || echo "Error: $RESULT"
site:commons.wikimedia.org tuberculosis chest xray large file JPG PNG 2048 pixels
site:commons.wikimedia.org pleural effusion chest xray large file
sleep 3 # Get the URLs for the better alternatives: Unilateral Pleural Effusion, Effusionhalf.PNG # Also search for TB xrays RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Unilateral_Pleural_Effusion.jpg|File:Effusionhalf.PNG|File:Tuberculosis-x-ray-1.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null || echo "Error: $RESULT"
sleep 2 # Better TB alternative - search for it RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Tuberculosis_Chest_X-ray.jpg|File:Pulmonary_tuberculosis.jpg|File:Tuberculosis_X_ray.jpg|File:TB_xray.jpg|File:Tuberculosis.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null || echo "Error: $RESULT"
wikimedia commons "pulmonary tuberculosis" chest xray file "upload.wikimedia.org"
sleep 3 # Get URL for TB_CXR.jpg and Tuberculosis-x-ray.jpg which might be larger RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:TB_CXR.jpg|File:Tuberculosis-x-ray.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null || echo "Error: $RESULT"
sleep 3 # Look for a bigger TB xray - try NIH/NLM open access or other larger TB images RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Tuberculosis_xray_lungs.jpg|File:Chest_X-ray_tuberculosis.jpg|File:TB_chest.jpg|File:Tuberculosis_infiltration.jpg|File:Miliary_tuberculosis.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null || echo "Error: $RESULT"
sleep 3 # Try PMC/NIH open access TB xray # Also try a direct download of a higher quality version of TB from Wikimedia # The original Tuberculosis-x-ray-1.jpg is 590x542 = 47KB - that's the actual file # For pleural effusion, let's use the larger Unilateral_Pleural_Effusion.jpg (1MB) # For TB, let's try to find a larger one via Wikimedia search RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&list=search&srsearch=tuberculosis+chest+xray&srnamespace=6&format=json&srlimit=10") echo "$RESULT" | python3 -c " import sys,json try: d=json.load(sys.stdin) for r in d['query']['search']: print(r['title']) except Exception as e: print('Error:', e) sys.stdin.seek(0) print(sys.stdin.read()[:500]) " 2>/dev/null || echo "Could not parse"
sleep 3 # The TB image at 47KB IS a real image (just small original file), same for pleural effusion at 40KB # Let's replace them with larger alternatives that we found: # - Pleural effusion: Use Unilateral_Pleural_Effusion.jpg (1013246 bytes = 989KB) ✓ # - TB: The original TB-xray is 47KB (real image, just small). Let's see if there's a better one. # Try the Medical X-Ray imaging nevit series which are known to be large RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Medical_X-Ray_imaging_AKO02_nevit.jpg|File:Chest_radiograph_in_influensa_and_H_influenzae,_posteroanterior.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null || echo "Error: $RESULT"
cd /tmp/workspace/xray_images sleep 2 # Replace 02_pleural_effusion.jpg with the larger Unilateral_Pleural_Effusion.jpg echo "Downloading better 02_pleural_effusion.jpg (Unilateral Pleural Effusion - 1MB)..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 60 \ "https://upload.wikimedia.org/wikipedia/commons/d/df/Unilateral_Pleural_Effusion.jpg" \ -o 02_pleural_effusion.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" sleep 2 # For TB, use the chest radiograph in influenza which is 444KB - it shows pneumonia features # Actually let's use the Tuberculosis-x-ray-1.jpg (47KB) - it IS a real image (590x542 original file) # But the threshold is 50KB... let's get a better TB image # Try to get a TB image from a PMC source echo "Checking NLM/NIH open-access TB image..." curl -L -A "Mozilla/5.0" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/9/9c/Tuberculosis-x-ray-1.jpg" \ -o 04_tb_check.jpg -s -w "TB original: %{http_code}, Size: %{size_download} bytes\n" ls -lh *.jpg
cd /tmp/workspace/xray_images rm 04_tb_check.jpg sleep 2 # Find a larger TB xray image # Try CDC/NIH open-access TB images RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Tuberculosis_lobe_collapse.jpg|File:CXR_TB.jpg|File:Chest-xray-in-tuberculosis.jpg|File:Tuberculosis_chest_radiograph_CDC_Phil_5745_lores.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null || echo "Error"
sleep 3 # Let's verify file is a real JPEG (not an error page) by checking the magic bytes python3 -c " with open('/tmp/workspace/xray_images/04_tb.jpg', 'rb') as f: magic = f.read(4) print('Magic bytes:', magic.hex()) print('JPEG starts with FF D8:', magic[:2] == bytes([0xFF, 0xD8])) "
sleep 3 # The TB file IS a real JPEG image (47.4KB at 590x542 original) - it's the actual file, just small # Let's find a higher-res version of the TB xray from NIH's image library or PMC # Try NIH NLM/CDC gallery curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \ --max-time 30 \ "https://phil.cdc.gov/PHIL_Images/5745/5745.jpg" \ -o /tmp/test_tb_cdc.jpg -s -w "CDC TB: %{http_code}, Size: %{size_download} bytes\n" # Also try another known wikimedia TB file RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:Tb_rl.jpg|File:Infiltrate_tb.jpg|File:Tb_upper_lobe.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null
sleep 3 # Let's search Commons for TB files using the API text search RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&list=search&srsearch=filetype:bitmap+tuberculosis+xray&srnamespace=6&format=json&srlimit=10") echo "$RESULT" | python3 -c " import sys,json try: d=json.load(sys.stdin) for r in d['query']['search']: print(r['title']) except Exception as e: print(sys.stdin.read()[:200]) " 2>&1 | head -20
sleep 3 # Try to get the OSC Microbio xray which may show TB RESULT=$(curl -s -A "Mozilla/5.0 (compatible; ResearchBot/1.0)" \ "https://commons.wikimedia.org/w/api.php?action=query&titles=File:OSC_Microbio_04_02_Xray.jpg|File:Tuberculosis_Xray_2.jpg|File:TB_xray_2.jpg&prop=imageinfo&iiprop=url|size&format=json") echo "$RESULT" | python3 -c " import sys,json d=json.load(sys.stdin) pages=d['query']['pages'] for k,v in pages.items(): title=v['title'] info=v.get('imageinfo', [{}])[0] url=info.get('url', 'MISSING') size=info.get('size', 0) print(f'{title} -> {url} ({size} bytes)') " 2>/dev/null
cd /tmp/workspace/xray_images sleep 2 # Download the OSC Microbio TB xray (115KB) - replace the small 47KB one echo "Downloading better TB xray (OSC Microbio 04 02 Xray.jpg - 115KB)..." curl -L -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \ -H "Referer: https://commons.wikimedia.org/" \ --max-time 30 \ "https://upload.wikimedia.org/wikipedia/commons/b/b8/OSC_Microbio_04_02_Xray.jpg" \ -o 04_tb.jpg -s -w "Status: %{http_code}, Size: %{size_download} bytes\n" echo "" echo "=== FINAL FILE LISTING ===" ls -lh /tmp/workspace/xray_images/
python3 -c " import os, json files = sorted(os.listdir('/tmp/workspace/xray_images/')) results = [] for f in files: path = f'/tmp/workspace/xray_images/{f}' size_bytes = os.path.getsize(path) size_kb = round(size_bytes / 1024, 1) if size_kb > 50: results.append({'filename': f, 'path': path, 'size_kb': size_kb}) print(json.dumps({'downloaded': results}, indent=2)) "
mkdir -p /tmp/workspace/respiratory_xray_notes cat > /tmp/workspace/respiratory_xray_notes/build_pdf.py << 'PYEOF' from reportlab.lib.pagesizes import A4 from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.units import cm, mm from reportlab.lib import colors from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle, PageBreak, HRFlowable, KeepTogether ) from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY from PIL import Image as PILImage import os # ── Output path ────────────────────────────────────────────────────────────── OUTPUT = "/tmp/workspace/respiratory_xray_notes/MBBS_Respiratory_Xrays.pdf" IMG_DIR = "/tmp/workspace/xray_images" # ── Colour palette ──────────────────────────────────────────────────────────── NAVY = colors.HexColor("#1a3a5c") TEAL = colors.HexColor("#0d7a8a") GOLD = colors.HexColor("#e8a000") LIGHT_BG = colors.HexColor("#eef4f8") WHITE = colors.white LIGHT_GREY= colors.HexColor("#f5f5f5") RED = colors.HexColor("#c0392b") GREEN = colors.HexColor("#1a7a4a") # ── Styles ──────────────────────────────────────────────────────────────────── styles = getSampleStyleSheet() TITLE_STYLE = ParagraphStyle( "Title", fontSize=26, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=34, spaceAfter=4 ) SUBTITLE_STYLE = ParagraphStyle( "Subtitle", fontSize=13, textColor=colors.HexColor("#d0e8f5"), fontName="Helvetica", alignment=TA_CENTER, spaceAfter=2 ) SECTION_TITLE = ParagraphStyle( "SectionTitle", fontSize=17, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=22 ) CASE_LABEL = ParagraphStyle( "CaseLabel", fontSize=11, textColor=TEAL, fontName="Helvetica-Bold", spaceAfter=2, leading=15 ) BODY = ParagraphStyle( "Body", fontSize=10, textColor=colors.HexColor("#222222"), fontName="Helvetica", leading=15, spaceAfter=4, alignment=TA_JUSTIFY ) BULLET = ParagraphStyle( "Bullet", fontSize=10, textColor=colors.HexColor("#222222"), fontName="Helvetica", leading=15, leftIndent=14, bulletIndent=4, spaceAfter=2, alignment=TA_JUSTIFY ) KEY_SIGN = ParagraphStyle( "KeySign", fontSize=10, textColor=RED, fontName="Helvetica-Bold", leading=15, leftIndent=14, bulletIndent=4, spaceAfter=2 ) REMEMBER = ParagraphStyle( "Remember", fontSize=9.5, textColor=colors.HexColor("#1a4a1a"), fontName="Helvetica-BoldOblique", leading=14, spaceAfter=0 ) FOOTER_STYLE = ParagraphStyle( "Footer", fontSize=8, textColor=colors.HexColor("#888888"), fontName="Helvetica", alignment=TA_CENTER ) # ── Helpers ─────────────────────────────────────────────────────────────────── def section_header(text, bg=NAVY): table = Table([[Paragraph(text, SECTION_TITLE)]], colWidths=[17.5*cm]) table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), bg), ("TOPPADDING", (0,0), (-1,-1), 10), ("BOTTOMPADDING", (0,0), (-1,-1), 10), ("LEFTPADDING", (0,0), (-1,-1), 12), ("RIGHTPADDING", (0,0), (-1,-1), 12), ("ROUNDEDCORNERS", [6]), ])) return table def labelled_box(label, items, key_signs=None, remember=None, bg=LIGHT_BG): """Builds a shaded box with a bold label, bullet items, optional key signs and a remember note.""" content = [] content.append(Paragraph(label, CASE_LABEL)) for item in items: content.append(Paragraph(f"• {item}", BULLET)) if key_signs: content.append(Spacer(1, 4)) for ks in key_signs: content.append(Paragraph(f"★ {ks}", KEY_SIGN)) if remember: content.append(Spacer(1, 4)) content.append(Paragraph(f"Exam Tip: {remember}", REMEMBER)) inner = Table([[content]], colWidths=[16.5*cm]) inner.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), bg), ("TOPPADDING", (0,0), (-1,-1), 8), ("BOTTOMPADDING", (0,0), (-1,-1), 8), ("LEFTPADDING", (0,0), (-1,-1), 10), ("RIGHTPADDING", (0,0), (-1,-1), 10), ("BOX", (0,0), (-1,-1), 0.75, TEAL), ("ROUNDEDCORNERS",[4]), ])) return inner def fit_image(path, max_w, max_h): """Returns a ReportLab Image scaled to fit within max_w × max_h, maintaining aspect ratio.""" pil = PILImage.open(path) iw, ih = pil.size ratio = min(max_w/iw, max_h/ih) return Image(path, width=iw*ratio, height=ih*ratio) # ── X-ray data ───────────────────────────────────────────────────────────────── xrays = [ { "num": "00", "title": "Normal Chest X-Ray (PA View)", "file": "00_normal.jpg", "bg": colors.HexColor("#e8f4e8"), "header_bg": GREEN, "findings": [ "Trachea: Midline, bifurcates at angle of Louis (T4/T5) — carina angle <70°", "Lungs: Clear lung fields with visible bronchovascular markings up to periphery", "Heart: Cardiothoracic (CT) ratio < 0.5 on PA view", "Hila: Left hilum slightly higher than right; hilar angle 100–120°", "Diaphragm: Right hemidiaphragm higher (liver) — level of 5th–6th rib anteriorly", "Costophrenic angles: Sharp, acute — fluid > 200 mL blunts them", "Mediastinum: Superior width < 8 cm (check for widening in aortic dissection / lymphoma)" ], "key_signs": [ "Silhouette sign: Loss of a normally visible border = adjacent pathology", "Air bronchogram: Air-filled bronchi visible within opacified lung = alveolar filling" ], "remember": "Always describe CXR systematically: ABCDE — Airway, Breathing, Cardiac, Diaphragm, Everything else (bones/soft tissue)." }, { "num": "01", "title": "1. Pneumothorax", "file": "01_pneumothorax.jpg", "bg": LIGHT_BG, "header_bg": NAVY, "findings": [ "Visceral pleural line visible — thin white line parallel to chest wall", "Absence of lung markings peripheral to the pleural line", "Lung collapsed toward hilum", "Trachea midline (no tension) or deviated AWAY from pneumothorax (tension)", "Increased translucency on affected side" ], "key_signs": [ "Deep sulcus sign: On supine AP film — abnormally deep, lucent costophrenic angle", "Tension pneumothorax: Trachea + mediastinum deviate to OPPOSITE side — treat BEFORE X-ray!" ], "remember": "Spontaneous pneumothorax: tall, thin young males. Secondary: COPD, TB, Marfan syndrome. Treatment: observation (<2 cm), aspiration or chest drain (>2 cm)." }, { "num": "02", "title": "2. Pleural Effusion", "file": "02_pleural_effusion.jpg", "bg": LIGHT_BG, "header_bg": NAVY, "findings": [ "Blunting of costophrenic (CP) angle — requires > 200–300 mL fluid", "Meniscus sign: Concave upper border of opacity, highest laterally", "Homogeneous opacity in lower zone; obliterates diaphragm shadow", "Trachea/mediastinum pushed AWAY (massive effusion, >1 liter)", "On supine film: Diffuse haziness on affected side (fluid layers posteriorly)", "Fluid in fissures: Lenticular opacity (encysted/loculated effusion)" ], "key_signs": [ "Meniscus sign — differentiates effusion from consolidation", "Spine sign on lateral view: Increasing opacity over lower thoracic vertebrae" ], "remember": "Exudate vs Transudate: Light's criteria (protein, LDH). Causes — transudate: CCF, cirrhosis, nephrotic syndrome; exudate: pneumonia, TB, malignancy, PE." }, { "num": "03", "title": "3. Lobar Pneumonia", "file": "03_pneumonia.jpg", "bg": LIGHT_BG, "header_bg": NAVY, "findings": [ "Homogeneous opacification conforming to a lobe (no volume loss)", "Air bronchogram sign (pathognomonic): Air-filled bronchi visible in opacified lobe", "RLL: Opacity behind heart, obliterates right hemidiaphragm", "LLL: Retrocardiac opacity, obscures left hemidiaphragm (left lower lobe sign)", "RML: Obliterates right heart border (silhouette sign)", "RUL: Opacity in upper zone with preserved diaphragm" ], "key_signs": [ "Air bronchogram sign — air in bronchi surrounded by fluid-filled alveoli", "Silhouette sign: RML pneumonia obliterates RIGHT heart border" ], "remember": "Most common cause: Streptococcus pneumoniae. Radiological lag — X-ray lags behind clinical improvement by 2–4 weeks. Aspiration pneumonia — right lower lobe (supine) or right middle lobe (upright)." }, { "num": "04", "title": "4. Pulmonary Tuberculosis (TB)", "file": "04_tb.jpg", "bg": LIGHT_BG, "header_bg": NAVY, "findings": [ "Primary TB: Ghon focus (peripheral opacity) + hilar lymphadenopathy = Ghon complex (Ranke complex if calcified)", "Post-primary (reactivation) TB: Upper lobe / apical infiltrates (posterior segment of upper lobe most common)", "Cavity formation: Thick-walled cavity ± air-fluid level within upper lobes", "Miliary TB: Diffuse 1–3 mm nodules ('millet seed' pattern) throughout both lungs", "Fibrosis, calcification, scarring with volume loss in upper lobes", "Bilateral, asymmetric — upper zone predominance" ], "key_signs": [ "Ghon focus + hilar adenopathy = Primary TB complex", "Miliary pattern = haematogenous dissemination (uniform tiny nodules)" ], "remember": "Simon foci: Calcified upper lobe apical nodules from old healed TB. Post-primary TB reactivates in apices (high O2 tension). Sputum AFB stain (Ziehl-Neelsen) is the key diagnostic test." }, { "num": "05", "title": "5. Pulmonary Edema (Cardiogenic)", "file": "05_pulmonary_edema.jpg", "bg": LIGHT_BG, "header_bg": NAVY, "findings": [ "Cardiomegaly: CT ratio > 0.5 on PA view", "Upper lobe blood diversion (vascular redistribution) — earliest sign", "Kerley B lines: Short horizontal lines at lung bases, perpendicular to pleura (interstitial edema)", "Perihilar ('bat-wing') pattern: Bilateral perihilar alveolar opacification", "Bilateral pleural effusions (more often right-sided or bilateral)", "Septal lines: Kerley A lines (long diagonal lines from hila); Kerley C lines (fine network)" ], "key_signs": [ "Kerley B lines — short, peripheral horizontal lines = interstitial edema", "Bat-wing / butterfly pattern — bilateral perihilar alveolar edema", "Upper lobe diversion — pulmonary venous hypertension" ], "remember": "Sequence: Upper lobe diversion → Kerley B lines → perihilar haziness → bat-wing opacity → pleural effusions. PCWP > 18 mmHg = pulmonary edema. Treat: diuretics, O2, treat underlying cause." }, { "num": "06", "title": "6. Lung Abscess", "file": "06_lung_abscess.jpg", "bg": LIGHT_BG, "header_bg": NAVY, "findings": [ "Round or oval cavitary lesion with thick irregular wall", "Air-fluid level within the cavity (pathognomonic feature)", "Surrounding consolidation / pneumonia", "Commonly in right lower lobe (aspiration-related), upper lobes (TB-related)", "Rim of surrounding inflammation / infiltrate", "Single large cavity vs. multiple (differentiates from cavitating metastases)" ], "key_signs": [ "Air-fluid level in a thick-walled cavity = LUNG ABSCESS until proven otherwise", "Differential: TB cavity (usually no fluid level), hydatid cyst, cavitating carcinoma" ], "remember": "Common organisms: Klebsiella (upper lobe), anaerobes (aspiration, lower lobe). Aspiration risk: alcoholics, epileptics, altered consciousness. Treatment: prolonged antibiotics (6–8 weeks) ± postural drainage." }, { "num": "07", "title": "7. COPD / Hyperinflated Lungs (Emphysema)", "file": "07_copd.jpg", "bg": LIGHT_BG, "header_bg": NAVY, "findings": [ "Hyperinflation: More than 6 anterior ribs visible above the diaphragm (>10 posterior ribs)", "Flattened hemidiaphragms (seen on PA and lateral) — key sign", "Increased AP diameter (barrel chest on lateral view)", "Decreased peripheral lung markings / hyperlucency", "Bullae: Large avascular areas demarcated by thin walls", "Narrow vertical heart (hanging or pendulous heart)", "Wide intercostal spaces; horizontal ribs" ], "key_signs": [ "Flat diaphragm — most reliable sign of hyperinflation", "Barrel chest (AP:lateral ratio approaching 1:1) on lateral view", "Bullae — localized areas of emphysema with absent lung markings" ], "remember": "Emphysema: panacinar (Alpha-1 AT deficiency, lower lobes) vs. centrilobular (smoking, upper lobes). Cor pulmonale in chronic COPD: right heart enlargement + pulmonary artery enlargement." }, ] # ── Build flowable story ─────────────────────────────────────────────────────── story = [] W, H = A4 # 595.28 × 841.89 pt # ─── COVER PAGE ────────────────────────────────────────────────────────────── cover_bg = Table( [[Paragraph("MBBS RESPIRATORY RADIOLOGY", TITLE_STYLE)], [Spacer(1, 6)], [Paragraph("Must-Know Chest X-Rays for Final MBBS / Clinical Exams", SUBTITLE_STYLE)], [Spacer(1, 4)], [Paragraph("8 Classic Patterns | Key Signs | Exam Tips", SUBTITLE_STYLE)], ], colWidths=[17.5*cm] ) cover_bg.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), NAVY), ("TOPPADDING", (0,0), (-1,-1), 28), ("BOTTOMPADDING", (0,0), (-1,-1), 28), ("LEFTPADDING", (0,0), (-1,-1), 16), ("RIGHTPADDING", (0,0), (-1,-1), 16), ("ROUNDEDCORNERS",[8]), ])) story.append(cover_bg) story.append(Spacer(1, 18)) # Intro box intro_box = labelled_box( "How to Use These Notes", [ "Each X-ray is presented with: (i) key radiological findings to identify on the film, " "(ii) classic signs tested in MCQs and clinical OSCEs, and (iii) a high-yield exam tip.", "Red starred (★) items are the most frequently tested signs — memorize these first.", "Green Exam Tip boxes summarize the clinical context and common exam traps.", "Start with the Normal X-ray (Page 1) to build your baseline before studying pathology.", ], bg=colors.HexColor("#e8f4fd") ) story.append(intro_box) story.append(Spacer(1, 10)) # Quick-reference table toc_data = [ [Paragraph("<b>#</b>", BODY), Paragraph("<b>Condition</b>", BODY), Paragraph("<b>Classic Sign</b>", BODY)], ["0", "Normal Chest X-Ray", "CT ratio < 0.5, carina angle < 70°"], ["1", "Pneumothorax", "Pleural line, absent lung markings"], ["2", "Pleural Effusion", "Meniscus sign, blunted CP angle"], ["3", "Lobar Pneumonia", "Air bronchogram + silhouette sign"], ["4", "Pulmonary TB", "Ghon complex; upper lobe cavities"], ["5", "Pulmonary Edema", "Kerley B lines; bat-wing pattern"], ["6", "Lung Abscess", "Air-fluid level in thick-walled cavity"], ["7", "COPD / Emphysema", "Flat diaphragm; bullae; barrel chest"], ] toc = Table(toc_data, colWidths=[1.2*cm, 6.5*cm, 9.5*cm]) toc.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,0), TEAL), ("TEXTCOLOR", (0,0), (-1,0), WHITE), ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,-1), 9.5), ("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHT_GREY, WHITE]), ("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#aaaaaa")), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 7), ("RIGHTPADDING", (0,0), (-1,-1), 7), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ])) story.append(Paragraph("Quick Reference Table", ParagraphStyle("QRef", fontSize=12, fontName="Helvetica-Bold", textColor=NAVY, spaceAfter=6))) story.append(toc) story.append(PageBreak()) # ─── X-RAY PAGES ────────────────────────────────────────────────────────────── MAX_IMG_W = 14.5 * cm MAX_IMG_H = 10.5 * cm for xr in xrays: img_path = os.path.join(IMG_DIR, xr["file"]) # Section header story.append(section_header(xr["title"], bg=xr["header_bg"])) story.append(Spacer(1, 10)) # X-ray image (centred) if os.path.exists(img_path): img = fit_image(img_path, MAX_IMG_W, MAX_IMG_H) img.hAlign = "CENTER" story.append(img) else: story.append(Paragraph(f"[Image not found: {xr['file']}]", BODY)) story.append(Spacer(1, 10)) # Findings box story.append(labelled_box( "Radiological Findings", xr["findings"], key_signs=xr.get("key_signs"), remember=xr.get("remember"), bg=xr["bg"] )) story.append(Spacer(1, 8)) story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#cccccc"))) story.append(PageBreak()) # ─── FINAL SUMMARY PAGE ─────────────────────────────────────────────────────── story.append(section_header("HIGH-YIELD SUMMARY: Key Signs at a Glance", bg=TEAL)) story.append(Spacer(1, 12)) summary_rows = [ [Paragraph("<b>Sign</b>", BODY), Paragraph("<b>What It Is</b>", BODY), Paragraph("<b>Disease</b>", BODY)], ["Meniscus sign", "Concave upper border of pleural opacity", "Pleural effusion"], ["Air bronchogram", "Air in bronchi surrounded by opacified alveoli","Pneumonia / pulmonary edema"], ["Silhouette sign", "Loss of border of cardiac/diaphragm shadow", "Adjacent consolidation"], ["Kerley B lines", "Short horizontal peripheral lines at bases", "Pulmonary edema (interstitial)"], ["Deep sulcus sign", "Deep costophrenic angle on supine film", "Pneumothorax (supine)"], ["Bat-wing pattern", "Bilateral perihilar alveolar opacification", "Pulmonary edema"], ["Air-fluid level", "Horizontal fluid level in cavity", "Lung abscess (/ hydatid)"], ["Ghon complex", "Peripheral focus + hilar adenopathy", "Primary TB"], ["Miliary pattern", "Diffuse 1–3 mm nodules both lungs", "Miliary TB / haematogenous spread"], ["Flat diaphragm", "Loss of diaphragm dome on PA/lateral", "COPD / emphysema"], ["Pleural line", "Thin white line with absent markings lateral", "Pneumothorax"], ] summary_table = Table( summary_rows, colWidths=[4.5*cm, 7.5*cm, 5.5*cm] ) summary_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,0), NAVY), ("TEXTCOLOR", (0,0), (-1,0), WHITE), ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,-1), 9), ("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHT_GREY, WHITE]), ("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#aaaaaa")), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 7), ("RIGHTPADDING", (0,0), (-1,-1), 7), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ])) story.append(summary_table) story.append(Spacer(1, 18)) # Closing exam tips story.append(labelled_box( "Final MBBS Exam Strategy", [ "Describe systematically: Airway (trachea) → Bones → Cardiac → Diaphragm → Everything else (ABCDE).", "Always state whether the trachea is central or deviated and which direction.", "Name the sign explicitly: 'There is a meniscus sign consistent with pleural effusion'.", "For consolidation, use the silhouette sign to localize the lobe.", "Mention what is ABSENT (e.g., 'lung markings are absent peripherally') — examiners reward negative findings.", "Correlate with history: Pyrexia → pneumonia; Trauma → pneumothorax; Night sweats + weight loss → TB.", ], key_signs=[ "Never say 'opacity' without localising it — always say which zone and lobe", "Tension pneumothorax: A CLINICAL diagnosis — needle decompression BEFORE X-ray" ], bg=colors.HexColor("#fffae6") )) # ─── Build PDF ───────────────────────────────────────────────────────────────── def on_page(canvas, doc): canvas.saveState() canvas.setFont("Helvetica", 8) canvas.setFillColor(colors.HexColor("#888888")) canvas.drawCentredString(W/2, 1.5*cm, f"MBBS Respiratory Radiology Notes | Page {doc.page} | For Educational Use Only") canvas.restoreState() doc = SimpleDocTemplate( OUTPUT, pagesize=A4, topMargin=1.8*cm, bottomMargin=2.2*cm, leftMargin=1.8*cm, rightMargin=1.8*cm, title="MBBS Respiratory Radiology - Must-Know Chest X-Rays", author="MBBS Study Notes", subject="Respiratory Radiology" ) doc.build(story, onFirstPage=on_page, onLaterPages=on_page) print(f"PDF created: {OUTPUT}") PYEOF python3 /tmp/workspace/respiratory_xray_notes/build_pdf.py