Radiation Safety and Protection in Medical Imaging Make a downloadable ppt for the topic max 10-15 slides with good relatable images with clarity with good slides templates
radiation protection lead apron shielding radiography
time distance shielding radiation protection
CT scanner computed tomography patient

A comparison chart consisting of two clinical photographs demonstrating a radiation safety experimental setup for Computed Tomography (CT). The left panel displays an unshielded dose chamber (spherical ionization chamber) positioned adjacent to the CT scanner bore, mounted in front of an orange anatomical torso 'physician phantom' used to simulate backscatter radiation. The right panel illustrates the same setup with a lead apron draped over the phantom to evaluate its effectiveness in reducing physician scatter dose. In both panels, a white cylindrical 'patient phantom' is positioned on the CT table extending into the scanner bore to act as the primary radiation target. Labels identify the dose chamber, physician phantom, patient phantom, and lead apron. This content serves to teach principles of occupational radiation protection, dosimetry, and the clinical efficacy of personal protective equipment (PPE) during radiologic procedures.

A clinical photograph of a modern hybrid trauma suite featuring a dual-room sliding gantry computed tomography (CT) scanner. The scanner is mounted on floor rails, allowing the gantry to move between two identical, adjacent trauma rooms separated by a radiation protection door. In the foreground, a radiolucent trauma table is equipped with multicolored patient immobilization straps. High-intensity surgical LED lights are mounted on articulating ceiling booms. The environment is heavily equipped for emergency care, including a portable ultrasound machine, life-support monitors, medical gas outlets, and specialized equipment carts for resuscitation. A digital wall clock and radiation-shielded viewing window are visible. This configuration is designed for rapid diagnostic imaging (CT) of polytrauma patients immediately upon arrival in the emergency department, minimizing the need for hazardous patient transfers between clinical areas.

A clinical photograph of a SIEMENS SOMATOM Emotion 16-slice computed tomography (CT) scanner, illustrating the primary hardware components and patient positioning. The image features a large, light-blue circular gantry with a central bore, equipped with digital displays, control buttons, and yellow safety labels. The scanner's white exterior casing includes horizontal gray stripes and branding. A patient table is aligned horizontally with the gantry's aperture, supporting a cadaver in the supine position for anatomical research. The cadaver is partially covered with blue surgical drapes, demonstrating a standard setup for whole-body, head, chest, or abdominal imaging protocols. The image serves as an educational reference for radiological equipment configuration and clinical imaging preparation in a research or forensic setting.

This composite educational figure illustrates the workflow and technology behind 3D camera-guided patient positioning for Computed Tomography (CT) scanning. Panel (a) presents a scalar depth image in grayscale, where pixel intensity represents the distance from the infrared camera to the patient's surface (brighter shades indicate greater distance). Panel (b) shows the resulting 3D point cloud after perspective correction. Panel (c) displays the CT scanner's touch panel user interface, featuring tools for table adjustment (1), body region selection (2), and scan range definition (3). Panel (d) demonstrates a virtual patient avatar—a statistical shape model—overlaid in green on the depth data to estimate anatomical landmarks. Finally, panel (e) shows a sagittal scout image used to calculate positioning accuracy, comparing the scanner isocenter (blue line) with the patient isocenter estimated by the camera (green line) and the actual average isocenter (red line). The system is designed to automate and standardize table height and scan range to reduce radiation dose and improve imaging efficiency.

This composite educational graphic illustrates the application of 3D camera technology for pediatric patient positioning in computed tomography (CT). Figure (a) is a top-down color photograph of a 12-year-old child in a supine position on a CT table with arms raised. Figure (b) shows a diagnostic axial CT cross-section of the abdomen, displaying the liver, stomach, and vertebral column. It is overlaid with a yellow line representing depth measurements from a 3D camera and a green line representing the algorithm-estimated body contour (Avatar model). Figure (c) provides a sagittal localizer radiograph (scout view) of the thorax and upper abdomen, showing the ribs and spine. Multiple colored horizontal and dotted lines are used to compare positioning metrics: a blue line for the radiographer's estimated isocenter, green lines for the camera's average isocenter and curve, and red lines representing the ideal table height (scanner isocenter). This visualization demonstrates the high accuracy of automated 3D surface mapping in aligning a patient's anatomical center with the scanner's isocenter to optimize dose efficiency and image quality.

This clinical photograph displays a specialized experimental setup within a Computed Tomography (CT) gantry designed for dose profile measurements. The image depicts an Area Detector CT (ADCT) scanner with a Cartesian coordinate system (x, y, z axes) overlaid at the isocenter. A RTI CT Dose Profiler (CTDP) probe is suspended free-in-air, guided by a plastic tube aligned along the longitudinal z-axis. A dashed arrow indicates the direction of probe movement during measurements. External to the gantry, the setup includes an RTI Mover positioned on the patient table, which controls the translation of the probe at a constant velocity (83 mm/s). The RTI CTDP probe is connected via a thin wire to an RTI Piranha dosimeter resting on the scanner base. This configuration is used to assess the dose distribution and longitudinal beam characteristics, such as heel effect and beam width (160 mm), in high-row count ADCT systems (256-row or 320-row scanners). The educational focus is on medical physics, radiology quality assurance, and CT dosimetry protocols.
fluoroscopy interventional radiology staff lead shield radiation dose
lead apron thyroid shield radiation protection
X-ray radiography room radiation dose reduction
fluoroscopy C-arm operating room radiation
ionizing radiation electromagnetic spectrum X-ray production tube
"radiation protection"[MeSH Terms] AND "diagnostic imaging"[MeSH Terms]
mkdir -p /tmp/workspace/radsafety/assets && cd /tmp/workspace/radsafety && cat > urls.txt <<'EOF' ct_apron|https://cdn.orris.care/cdss_images/pmc_clinical_VQA_6a926c980e459fe789b1eeef2ffb8913d2b81710df0534430fd8c017921154c5.jpg trauma_ct|https://cdn.orris.care/cdss_images/pmc_clinical_VQA_6affc65983d8ef27a0c915bb4b6dd46134b45f25f447b78f73623b6b48e42d91.jpg siemens_ct|https://cdn.orris.care/cdss_images/pmc_clinical_VQA_458ef0e7860396013a2ce89f9b726fde8fecca9cadd51f7421f55b996f8e3df2.jpg booth|https://cdn.orris.care/cdss_images/27bb254a4dfeac8cd4a8b80cf5a552b275417b4bb8013980ed002a73440eb9d7.png xray_door|https://cdn.orris.care/cdss_images/901e14f3195d21abfd1243ce80d7cba7ec9efa2ef40e14fda823f7a9080d75e4.png apron_gloves|https://cdn.orris.care/cdss_images/1827ae6e145f1b26e87e3e91002e79d137391e48c1fda5444e7589cb70b472ec.png fluoro_setup|https://cdn.orris.care/cdss_images/37ea7094efaa3676f93ee70cf79486f512f78d85dbcca95d6b811ee387e5e60c.png apron_or|https://cdn.orris.care/cdss_images/GLGCA_349880_1766510528084_030c0d6c-b02b-42a0-ae08-025d995946c3_d11e8d51-9638-4d32-a0f9-cfa00853a2b8.png axillary|https://cdn.orris.care/cdss_images/GLGCA_4589021_1766494540010_3da1c849-f3d7-46de-984d-f2c33dbbc578_55404358-4d99-4ea6-9098-31e5a99504f5.png tld|https://cdn.orris.care/cdss_images/pmc_clinical_VQA_25ac4ce22f874e7da6cd42e5425920ddcbc0af3d904e01597ce2319492b279a5.jpg carm|https://cdn.orris.care/cdss_images/GLGCA_349880_1766510527699_a79c1586-932f-4d76-8467-e94821d7d75a_a071d08d-08d7-40e5-a98d-1a38b9ea1436.png dosimeters|https://cdn.orris.care/cdss_images/pmc_clinical_VQA_5f0cb2cb0f22327a142fe238aecc70d8d8d009fbab27e9990ac9ff6e9905d472.jpg training|https://cdn.orris.care/cdss_images/GLGCA_4589021_1766494483446_880b3ea4-cdac-4a2b-b874-62783959c669_989ad794-dce5-4316-9a47-6524fa5564ab.png EOF python - <<'EOF' import json,subprocess,base64 lines=[l.strip().split('|') for l in open('urls.txt') if l.strip()] res=json.loads(subprocess.check_output(["python","/tmp/skills/shared/scripts/fetch_images.py"]+[u for _,u in lines])) from PIL import Image from io import BytesIO for (n,u),r in zip(lines,res): if r['base64']: raw=base64.b64decode(r['base64'].split('base64,')[1]) im=Image.open(BytesIO(raw)).convert('RGB'); im.save(f'assets/{n}.jpg',quality=92) print(n,im.size) else: print(n,'ERR',r['error']) EOF
cd /tmp/workspace/radsafety && python - <<'EOF' from PIL import Image, ImageDraw import glob,os fs=sorted(glob.glob('assets/*.jpg')) W=300;H=260 sheet=Image.new('RGB',(W*5,H*3),'white') d=ImageDraw.Draw(sheet) for i,f in enumerate(fs): im=Image.open(f); im.thumbnail((W-10,H-30)) x,y=(i%5)*W,(i//5)*H sheet.paste(im,(x+5,y+25)); d.text((x+5,y+5),os.path.basename(f),fill='black') sheet.save('sheet.jpg') EOF
ls -la /tmp/workspace/radsafety/ /tmp/workspace/radsafety/assets | head -30
mkdir -p /tmp/workspace/radsafety/output && cd /tmp/workspace/radsafety && cat > build.py <<'EOF' from pptx import Presentation from pptx.util import Inches, Pt from pptx.dml.color import RGBColor from pptx.enum.text import PP_ALIGN, MSO_ANCHOR from pptx.enum.shapes import MSO_SHAPE from PIL import Image NAVY=RGBColor(0x0B,0x1F,0x3A); TEAL=RGBColor(0x0E,0x9F,0x9A); AMBER=RGBColor(0xF5,0xA6,0x23) RED=RGBColor(0xD6,0x45,0x45); LIGHT=RGBColor(0xF3,0xF6,0xF9); WHITE=RGBColor(255,255,255) GREY=RGBColor(0x5B,0x67,0x78); DARK=RGBColor(0x1F,0x29,0x37); GREEN=RGBColor(0x3C,0xA5,0x5C); MID=RGBColor(0x1D,0x4E,0x89) A='assets/' prs=Presentation(); prs.slide_width=Inches(13.333); prs.slide_height=Inches(7.5) blank=prs.slide_layouts[6] total=14 def rect(s,x,y,w,h,fill,shape=MSO_SHAPE.RECTANGLE,line=None): sh=s.shapes.add_shape(shape,Inches(x),Inches(y),Inches(w),Inches(h)) sh.fill.solid(); sh.fill.fore_color.rgb=fill if line: sh.line.color.rgb=line; sh.line.width=Pt(1) else: sh.line.fill.background() sh.shadow.inherit=False return sh def text(s,x,y,w,h,t,size=16,color=DARK,bold=False,align=PP_ALIGN.LEFT,font='Calibri',anchor=MSO_ANCHOR.TOP): tb=s.shapes.add_textbox(Inches(x),Inches(y),Inches(w),Inches(h)); tf=tb.text_frame; tf.word_wrap=True tf.margin_left=tf.margin_right=Inches(0.05); tf.margin_top=tf.margin_bottom=Inches(0.03); tf.vertical_anchor=anchor lines=t if isinstance(t,list) else [t] for i,l in enumerate(lines): p=tf.paragraphs[0] if i==0 else tf.add_paragraph() p.alignment=align; r=p.add_run(); r.text=l r.font.size=Pt(size); r.font.color.rgb=color; r.font.bold=bold; r.font.name=font return tb def bullets(s,x,y,w,h,items,size=16,color=DARK,gap=8,dot=TEAL): tb=s.shapes.add_textbox(Inches(x),Inches(y),Inches(w),Inches(h)); tf=tb.text_frame; tf.word_wrap=True for i,it in enumerate(items): p=tf.paragraphs[0] if i==0 else tf.add_paragraph() p.space_after=Pt(gap) r0=p.add_run(); r0.text='\u25A0 '; r0.font.size=Pt(size-5); r0.font.color.rgb=dot; r0.font.name='Calibri' if isinstance(it,tuple): r=p.add_run(); r.text=it[0]+' '; r.font.bold=True; r.font.size=Pt(size); r.font.color.rgb=NAVY; r.font.name='Calibri' r2=p.add_run(); r2.text=it[1]; r2.font.size=Pt(size); r2.font.color.rgb=color; r2.font.name='Calibri' else: r=p.add_run(); r.text=it; r.font.size=Pt(size); r.font.color.rgb=color; r.font.name='Calibri' return tb def pic(s,name,x,y,w,h,caption=None,frame=True): im=Image.open(A+name+'.jpg'); iw,ih=im.size cap_h=0.35 if caption else 0 if frame: rect(s,x,y,w,h,WHITE,line=RGBColor(0xD5,0xDC,0xE4)) bw,bh=w-0.2,h-0.2-cap_h sc=min(bw/iw,bh/ih); pw,ph=iw*sc,ih*sc s.shapes.add_picture(A+name+'.jpg',Inches(x+(w-pw)/2),Inches(y+0.1+(bh-ph)/2),Inches(pw),Inches(ph)) if caption: text(s,x,y+h-cap_h-0.02,w,cap_h,caption,size=11,color=GREY,align=PP_ALIGN.CENTER) def base(title,n,kicker=None,src=None): s=prs.slides.add_slide(blank) rect(s,0,0,13.333,7.5,LIGHT) rect(s,0,0,13.333,1.15,NAVY); rect(s,0,1.15,13.333,0.06,TEAL) if kicker: text(s,0.6,0.12,10,0.3,kicker.upper(),size=12,color=AMBER,bold=True) text(s,0.6,0.38,12,0.7,title,size=30,color=WHITE,bold=True,font='Georgia') text(s,0.6,7.08,10.5,0.3,src or '',size=10,color=GREY) text(s,11.8,7.08,1.0,0.3,f'{n} / {total}',size=11,color=GREY,align=PP_ALIGN.RIGHT) return s def card(s,x,y,w,h,head,body,col=TEAL,size=14,hsize=17): rect(s,x,y,w,h,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,x,y,0.09,h,col) text(s,x+0.25,y+0.12,w-0.4,0.45,head,size=hsize,color=NAVY,bold=True) text(s,x+0.25,y+0.62,w-0.4,h-0.7,body,size=size,color=DARK) # 1 TITLE s=prs.slides.add_slide(blank) rect(s,0,0,13.333,7.5,NAVY); rect(s,0,0,0.35,7.5,TEAL) rect(s,7.4,0,5.933,7.5,MID) pic(s,'trauma_ct',7.9,1.7,4.9,3.9,'Hybrid trauma suite with sliding-gantry CT') text(s,0.9,1.3,6.3,0.4,'MEDICAL IMAGING | RADIOLOGICAL SAFETY',size=13,color=AMBER,bold=True) text(s,0.9,1.9,6.4,2.6,['Radiation Safety','and Protection in','Medical Imaging'],size=42,color=WHITE,bold=True,font='Georgia') rect(s,0.95,4.65,1.4,0.06,AMBER) text(s,0.9,4.85,6.2,1.0,'Principles, dose limits, and practical protection for patients and staff in radiography, fluoroscopy and CT',size=17,color=RGBColor(0xC9,0xD6,0xE6)) text(s,0.9,6.7,6,0.4,'Prepared with Orris | Medical textbook library and PubMed',size=12,color=RGBColor(0x8F,0xA3,0xBC)) # 2 WHY IT MATTERS s=base('Why Radiation Safety Matters',2,'Overview','Source: Campbell-Walsh-Wein Urology (NCRP 2012; Geise & Morin 2000); NRC 2006') stats=[('6.2 mSv','average annual dose per person in the US; medical procedures are 36% of it',TEAL), ('1 min','of fluoroscopy gives a skin dose about 10x that of a single radiograph of the same area',AMBER), ('10 mSv','effective dose may cause a malignancy in about 1 of 1000 people exposed (LNT model)',RED), ('50 mSv','recommended annual occupational limit for medical personnel (NCRP 2012)',MID)] for i,(big,small,c) in enumerate(stats): x=0.6+i*3.1 rect(s,x,1.7,2.9,2.7,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,x,1.7,2.9,0.12,c) text(s,x,2.0,2.9,0.9,big,size=40,color=c,bold=True,align=PP_ALIGN.CENTER,font='Georgia') text(s,x+0.2,3.0,2.5,1.4,small,size=14,color=DARK,align=PP_ALIGN.CENTER) rect(s,0.6,4.8,12.1,1.95,NAVY) text(s,0.9,4.95,11.5,0.4,'KEY MESSAGE',size=12,color=AMBER,bold=True) text(s,0.9,5.35,11.5,1.3,'Imaging saves lives, but ionizing radiation carries cumulative risk. Every exposure should be justified, kept as low as reasonably achievable (ALARA), and monitored for both patients and staff.',size=19,color=WHITE) # 3 QUANTITIES s=base('Radiation Quantities and Units',3,'Fundamentals','Source: Campbell-Walsh-Wein Urology, Table 3.1 (modified from Geise & Morin)') rows=[('Quantity','Traditional unit','SI unit','Conversion','What it tells you'), ('Exposure','roentgen (R)','coulomb/kg','1 C/kg = 3876 R','Charge per unit mass of air'), ('Absorbed dose','rad','gray (Gy)','1 Gy = 100 rad','Energy absorbed by tissue'), ('Equivalent dose','rem','sievert (Sv)','1 Sv = 100 rem','Absorbed energy weighted by radiation type'), ('Effective dose','rem','sievert (Sv)','-','Biologic risk to the whole body from a study')] tbl=s.shapes.add_table(5,5,Inches(0.6),Inches(1.7),Inches(12.1),Inches(3.2)).table for c,w in enumerate([2.2,2.1,2.0,2.3,3.5]): tbl.columns[c].width=Inches(w) for r,row in enumerate(rows): tbl.rows[r].height=Inches(0.62) for c,v in enumerate(row): cell=tbl.cell(r,c); cell.text=v; cell.vertical_anchor=MSO_ANCHOR.MIDDLE cell.fill.solid(); cell.fill.fore_color.rgb = NAVY if r==0 else (WHITE if r%2 else RGBColor(0xE8,0xEF,0xF5)) f=cell.text_frame.paragraphs[0].runs[0].font; f.size=Pt(15); f.name='Calibri' f.bold=(r==0 or c==0); f.color.rgb= WHITE if r==0 else DARK card(s,0.6,5.2,5.9,1.65,'For diagnostic X-rays','Radiation weighting factor is 1, so absorbed dose (Gy) numerically equals equivalent dose (Sv).',TEAL,14) card(s,6.8,5.2,5.9,1.65,'Which unit where?','Gray is used for therapy. Sievert is used for patient and staff exposure from diagnostic imaging.',AMBER,14) # 4 BIOLOGICAL EFFECTS s=base('Biological Effects of Ionizing Radiation',4,'Risk','Source: Campbell-Walsh-Wein Urology; standard radiobiology (ICRP)') card(s,0.6,1.6,5.9,3.0,'Deterministic (tissue reactions)',['Threshold dose, severity rises with dose','Examples: skin erythema, epilation, cataract, radiation burns','Seen mainly after prolonged or repeated fluoroscopy or interventional procedures','Prevented by keeping dose below thresholds'],RED,15) card(s,6.8,1.6,5.9,3.0,'Stochastic (random effects)',['No threshold assumed; probability rises with dose, severity does not','Examples: radiation-induced cancer, hereditary effects','Basis for the linear no-threshold (LNT) model','Prevented by ALARA: reduce dose wherever possible'],AMBER,15) rect(s,0.6,4.9,12.1,1.95,WHITE,line=RGBColor(0xD5,0xDC,0xE4)) text(s,0.85,5.0,11.6,0.4,'Who is more vulnerable?',size=17,color=NAVY,bold=True) bullets(s,0.85,5.45,11.6,1.4,[('Children and the fetus:','longer life expectancy and more radiosensitive tissue.'),('Eyes and gonads:','greater biologic impact than extremities, so limits differ by body part.'),('Repeat imaging patients:','e.g. recurrent stone disease or cancer follow-up accumulate dose quickly.')],size=14,gap=4) # 5 DOSE BY MODALITY s=base('Typical Effective Doses: Know the Relative Radiation Level',5,'Patient dose','Source: Campbell-Walsh-Wein Urology, Table 3.2 (ACR RRL); Grainger & Allison; Harrison 22e') levels=[('NONE','0 mSv','Ultrasound, MRI',GREEN,1.4),('MINIMAL','< 0.1 mSv','Chest radiograph',TEAL,2.4),('LOW','0.1 - 1 mSv','Lumbar spine and pelvic radiographs',RGBColor(0x8B,0xB8,0x3A),3.6), ('MEDIUM','1 - 10 mSv','Non-contrast abdominal CT, nuclear bone scan, IVP, contrast chest CT',AMBER,5.6),('HIGH','10 - 100 mSv','Multiphase abdomen-pelvis CT (25-40 mSv), whole-body PET',RED,7.6)] for i,(lv,rng,ex,c,bw) in enumerate(levels): y=1.55+i*0.98 rect(s,0.6,y,1.7,0.8,c); text(s,0.6,y,1.7,0.8,lv,size=16,color=WHITE,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) rect(s,2.3,y,bw*0.9+0.4,0.8,WHITE,line=c) text(s,2.45,y,2.0,0.8,rng,size=16,color=NAVY,bold=True,anchor=MSO_ANCHOR.MIDDLE) text(s,4.5,y,8.2,0.8,ex,size=15,color=DARK,anchor=MSO_ANCHOR.MIDDLE) text(s,0.6,6.5,12.1,0.5,'Coronary CTA typically delivers 3-15 mSv, and as low as 1 mSv with dose-reduction techniques. Always prefer non-ionizing options (ultrasound, MRI) when they answer the clinical question.',size=13,color=GREY) # 6 FRAMEWORK s=base('The Three Pillars of Radiation Protection',6,'ICRP framework','Source: ICRP system of radiological protection; ALARA per Rheumatology (Elsevier 2022), Fuster & Hurst\'s The Heart') pill=[('1 JUSTIFICATION','Benefit must outweigh risk. Use clinical decision rules and appropriateness criteria (e.g. ACR). Avoid duplicate or low-yield studies.',TEAL), ('2 OPTIMIZATION (ALARA)','Keep dose As Low As Reasonably Achievable while maintaining diagnostic image quality: right kVp and mA, collimation, limited scan range.',AMBER), ('3 DOSE LIMITS','Apply to workers and the public, not to patients (patients are governed by justification and optimization).',MID)] for i,(h,b,c) in enumerate(pill): x=0.6+i*4.1 rect(s,x,1.6,3.9,3.1,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,x,1.6,3.9,0.75,c) text(s,x+0.1,1.6,3.7,0.75,h,size=18,color=WHITE,bold=True,anchor=MSO_ANCHOR.MIDDLE) text(s,x+0.2,2.5,3.5,2.2,b,size=15,color=DARK) rect(s,0.6,4.95,12.1,1.9,NAVY) text(s,0.85,5.05,11.6,0.4,'COMMONLY QUOTED LIMITS (ICRP; confirm local regulation)',size=12,color=AMBER,bold=True) lim=[('20 mSv/yr','Worker effective dose, averaged over 5 years (max 50 in any one year)'),('20 mSv/yr','Worker eye lens equivalent dose'),('1 mSv/yr','Member of the public'),('1 mSv','Fetus for the remainder of pregnancy once declared')] for i,(a,b) in enumerate(lim): x=0.85+i*3.0 text(s,x,5.45,2.8,0.5,a,size=22,color=WHITE,bold=True,font='Georgia') text(s,x,5.95,2.8,0.9,b,size=12,color=RGBColor(0xC9,0xD6,0xE6)) # 7 TIME DISTANCE SHIELDING s=base('Time, Distance and Shielding',7,'Core protection tools for staff','Source: Campbell-Walsh-Wein Urology; Brogdon\'s Forensic Radiology (Ch. 34)') cols=[('TIME','Shortest exposure possible',['Use pulsed, low frame-rate fluoroscopy','Use last-image hold instead of re-exposing','Limit time in the exposure area','Plan the procedure before the beam is on'],TEAL), ('DISTANCE','Step back from the source',['Dose falls with the square of distance (inverse square law)','Use the full length of the exposure cord','Stand at least 2 m from the tube when possible','Keep hands out of the primary beam'],AMBER), ('SHIELDING','Put attenuating material in the way',['Lead apron, thyroid collar, glasses, gloves','Control booth with lead glass window','Mobile and ceiling-suspended shields','Lead-lined walls, doors and warning lights'],MID)] for i,(h,sub,items,c) in enumerate(cols): x=0.6+i*4.1 rect(s,x,1.6,3.9,5.25,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,x,1.6,3.9,1.2,c) text(s,x,1.65,3.9,0.65,h,size=28,color=WHITE,bold=True,align=PP_ALIGN.CENTER,font='Georgia') text(s,x,2.25,3.9,0.45,sub,size=14,color=WHITE,align=PP_ALIGN.CENTER) bullets(s,x+0.25,3.05,3.45,3.7,items,size=15,gap=10,dot=c) # 8 FACILITY s=base('Room Design: Barriers, Booths and Warning Signs',8,'Facility protection','Source: Brogdon\'s Forensic Radiology, Figs 34.19-34.20; images from textbook library') pic(s,'booth',0.6,1.55,6.0,3.2,'Control booth with lead protective screen') pic(s,'xray_door',6.9,1.55,2.4,3.2,'Warning lights above door') card(s,9.5,1.55,3.2,3.2,'Barriers','Primary barrier: thick lead, faces the central beam. Secondary barrier: thinner, stops scatter and tube leakage.',TEAL,13,16) bullets(s,0.6,5.0,12.1,1.9,[('Control booth:','lead glass window; staff enter behind the screen during exposures.'),('Warning lights:','show when the room is in use and when the X-ray beam is on.'),('Never','direct the primary beam toward a secondary barrier.'),('Design:','involve a radiation physicist when planning or modifying an X-ray room.')],size=15,gap=5) # 9 PPE s=base('Personal Protective Equipment',9,'Shielding in practice','Source: Brogdon\'s Forensic Radiology Fig 34.21; photos from library (GLGCA guideline figures)') pic(s,'apron_or',0.6,1.5,2.9,4.25,'Wrap-around lead apron') pic(s,'axillary',3.65,1.5,2.9,4.25,'Extra axillary lead protection') pic(s,'apron_gloves',6.7,1.5,2.0,4.25,'Apron and gloves') card(s,9.0,1.5,3.7,4.25,'Wear and check',['Lead apron: typically 0.25-0.5 mm lead equivalent','Thyroid collar and leaded glasses for fluoroscopy','Leaded gloves only when hands must be near the beam','Hang aprons, never fold them','Check for cracks with X-ray or fluoroscopy yearly'],MID,13,16) rect(s,0.6,5.95,12.1,0.9,NAVY) text(s,0.85,5.95,11.6,0.9,'PPE reduces scatter exposure but does not make the primary beam safe. It supports, never replaces, time and distance.',size=16,color=WHITE,anchor=MSO_ANCHOR.MIDDLE) # 10 FLUORO s=base('Fluoroscopy and C-arm Safety',10,'Highest staff exposure','Source: Campbell-Walsh-Wein Urology, Fig 3.1 and text; Miller\'s Anesthesia 10e') pic(s,'fluoro_setup',0.6,1.5,3.9,4.0,'Tube under table, intensifier close to patient') pic(s,'carm',4.7,1.5,3.1,4.0,'Mobile C-arm unit') text(s,8.1,1.45,4.6,0.4,'Practical rules',size=20,color=NAVY,bold=True,font='Georgia') bullets(s,8.1,1.95,4.6,4.0,[('Tube below table:','scatter is highest near the beam entry, so keep the source under the patient.'),('Intensifier close:','minimizes scatter and patient dose.'),('Collimate','to the area of interest.'),('Magnification','raises dose; use only when needed.'),('Train operators:','poor technique and inexperience prolong exposure.')],size=14,gap=7) rect(s,0.6,5.8,12.1,1.05,AMBER) text(s,0.85,5.8,11.6,1.05,'Fluoroscopy for 1 minute gives a skin dose about 10 times that of a single radiograph. Cumulative staff dose rises quickly during long procedures.',size=17,color=NAVY,bold=True,anchor=MSO_ANCHOR.MIDDLE) # 11 CT s=base('CT: Optimizing Dose Without Losing Diagnostic Quality',11,'CT protection','Source: Grainger & Allison; Rockwood & Green 10e; Fuster & Hurst\'s The Heart') pic(s,'siemens_ct',0.6,1.5,4.0,3.15,'Multislice CT scanner') pic(s,'ct_apron',0.6,4.8,4.0,2.0,'Lead apron lowers physician scatter dose') card(s,4.9,1.5,3.8,5.3,'Protocol levers',['Limit scan range to the area of interest','Tailor kVp and mA to body size and age','Use iterative reconstruction','Avoid unnecessary multiphase scans','Use split-bolus techniques','Center the patient at the isocenter'],TEAL,14,17) card(s,8.95,1.5,3.75,5.3,'Evidence and cautions',['Low-dose multidetector CT cut dose 61-71% versus standard CT in cervical spine trauma','Four-phase CT urography can reach 25-35 mSv','Three-phase abdomen-pelvis CT may reach 25-40 mSv','Use ultrasound or MRI when equivalent'],AMBER,14,17) # 12 MONITORING s=base('Occupational Monitoring and Dosimetry',12,'Staff safety','Source: Library guideline figures (dosimetry, TLD use); ICRP') pic(s,'dosimeters',0.6,1.5,6.2,3.0,'Dosimeter positions: eye lens, body, wrist, ring') pic(s,'tld',7.0,1.5,5.7,3.0,'TLD monitoring during vertebroplasty') card(s,0.6,4.75,3.9,2.1,'Whole-body badge','Worn at the collar outside the apron. A second badge under the apron estimates effective dose.',TEAL,13,16) card(s,4.7,4.75,3.9,2.1,'Extremity and eye','Ring or wrist TLDs for hands, lens dosimeter near the eye for interventional staff.',AMBER,13,16) card(s,8.8,4.75,3.9,2.1,'Review and act','Read doses regularly, investigate high readings, and keep records. Pregnant staff declare early.',MID,13,16) # 13 PATIENT & SPECIAL s=base('Protecting Patients and Special Populations',13,'Patient-centred safety','Source: Campbell-Walsh-Wein Urology; ACR appropriateness criteria; Image Gently/Wisely principles') card(s,0.6,1.6,3.9,3.3,'Before the scan',['Confirm clinical indication','Check prior imaging','Consider non-ionizing alternatives','Screen for pregnancy where relevant'],TEAL,15,18) card(s,4.7,1.6,3.9,3.3,'During the scan',['Use protocols matched to size and age','Collimate and limit repeats','Shield only when it does not interfere with exposure control','Keep necessary staff only in room'],AMBER,15,18) card(s,8.8,1.6,3.9,3.3,'After the scan',['Record dose indices (DLP, CTDIvol, DAP)','Audit against diagnostic reference levels','Follow up high skin doses','Track repeat-imaging patients'],MID,15,18) rect(s,0.6,5.15,12.1,1.7,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,0.6,5.15,0.09,1.7,RED) text(s,0.9,5.2,11.6,0.4,'Special populations',size=18,color=NAVY,bold=True) bullets(s,0.9,5.65,11.6,1.2,[('Children:','use pediatric protocols and the lowest dose that answers the question.'),('Pregnancy:','avoid abdominal-pelvic ionizing studies unless essential; prefer ultrasound or MRI.'),('Chronic disease:','cumulative dose from repeated CT or fluoroscopy needs planning.')],size=14,gap=3) # 14 TAKEAWAYS s=prs.slides.add_slide(blank) rect(s,0,0,13.333,7.5,NAVY); rect(s,0,0,0.35,7.5,TEAL) text(s,0.9,0.5,8,0.4,'KEY TAKEAWAYS',size=13,color=AMBER,bold=True) text(s,0.9,0.9,8,0.8,'Safe imaging is a shared habit',size=34,color=WHITE,bold=True,font='Georgia') bullets(s,0.9,1.9,7.0,3.8,[('Justify','every exposure and prefer non-ionizing options.'),('Optimize','dose with ALARA: protocol, collimation, scan range.'),('Time, distance, shielding','protect staff every day.'),('Monitor','badges, doses and equipment integrity.'),('Protect','children, pregnant patients and repeat-imaging patients.')],size=18,color=WHITE,gap=12,dot=AMBER) for p in s.shapes: pass rect(s,8.4,0.7,4.4,6.1,MID) text(s,8.65,0.85,4,0.4,'References',size=16,color=AMBER,bold=True) text(s,8.65,1.3,3.95,5.4,['Campbell-Walsh-Wein Urology: Radiation management in uroradiology, p. 52-53.','Brogdon\'s Forensic Radiology: Radiation protection, Ch. 34.','Grainger & Allison\'s Diagnostic Radiology: CT.','Fuster & Hurst\'s The Heart, 15e: Minimizing radiation dosimetry.','Recent reviews: Videira 2026 (PMID 42372711); Elsaeidy 2025 (PMID 40540234); Ramos-Avasola 2024 (PMID 38959875).','Dose limits: ICRP Publications 103 and 118; verify against local regulations.'],size=12,color=RGBColor(0xDD,0xE6,0xF2)) prs.save('output/Radiation_Safety_and_Protection_in_Medical_Imaging.pptx') EOF python build.py && echo ok
cd /tmp/workspace/radsafety && which soffice libreoffice 2>&1 | head -2; python - <<'EOF' from pptx import Presentation from pptx.util import Emu prs=Presentation('output/Radiation_Safety_and_Protection_in_Medical_Imaging.pptx') for i,s in enumerate(prs.slides,1): for sh in s.shapes: if sh.has_text_frame and sh.text_frame.text.strip(): w=sh.width/914400-0.1; h=sh.height/914400 tot=0 for p in sh.text_frame.paragraphs: if not p.runs: continue sz=max(r.font.size.pt for r in p.runs) chars=sum(len(r.text) for r in p.runs) cpl=max(1,w*72/(sz*0.5)) import math lines=math.ceil(chars/cpl) sa=(p.space_after.pt if p.space_after else 0) tot+=lines*sz*1.2/72+sa/72 if tot>h+0.05: print(i,round(tot,2),'>',round(h,2),sh.text_frame.text[:50].replace('\n',' | ')) EOF
cd /tmp/workspace/radsafety && python - <<'EOF' s=open('build.py').read() s=s.replace("'Typical Effective Doses: Know the Relative Radiation Level'","'Typical Effective Doses by Examination'") s=s.replace(" text(s,x+0.25,y+0.62,w-0.4,h-0.7,body,size=size,color=DARK)", """ if isinstance(body,list): tb=text(s,x+0.25,y+0.62,w-0.4,h-0.7,['\\u2022 '+b for b in body],size=size,color=DARK) for p in tb.text_frame.paragraphs: p.space_after=Pt(6) else: text(s,x+0.25,y+0.62,w-0.4,h-0.7,body,size=size,color=DARK)""") open('build.py','w').write(s) EOF python build.py && ls -la output
cd /tmp/workspace/radsafety && python - <<'EOF' from pptx import Presentation import math prs=Presentation('output/Radiation_Safety_and_Protection_in_Medical_Imaging.pptx') print(len(prs.slides)) for i,s in enumerate(prs.slides,1): for sh in s.shapes: if sh.has_text_frame and sh.text_frame.text.strip(): w=sh.width/914400-0.1; h=sh.height/914400; tot=0 for p in sh.text_frame.paragraphs: if not p.runs: continue sz=max(r.font.size.pt for r in p.runs); chars=sum(len(r.text) for r in p.runs) lines=math.ceil(chars/max(1,w*72/(sz*0.5))) tot+=lines*sz*1.2/72+(p.space_after.pt if p.space_after else 0)/72 if tot>h+0.05: print(i,round(tot,2),'>',round(h,2),sh.text_frame.text[:50].replace('\n',' | ')) EOF
Radiation Safety and Protection in Medical Imaging
Presentation · PPTX
MBBS level with good information and easy to explain
inverse square law radiation distance diagram
radiation sources background medical exposure pie chart
radiation-induced cataract posterior subcapsular lens opacity
cd /tmp/workspace/radsafety && cat > urls2.txt <<'EOF' skin_injury|https://cdn.orris.care/cdss_images/pmc_clinical_VQA_5705d77902aae6ebd0ea2e7adc1ee336dce15cd80b6f7951100453fd0105b943.jpg em_spectrum|https://cdn.orris.care/cdss_images/905aec6300b541143ddb516efdcb8fce544fb94816c46e3d855a9dc8633588d5.png carm_suite|https://cdn.orris.care/cdss_images/35745772da0eb8bbac90bbc872e5bda1a99ed0b0f3491589dfe428f6a28790bd.png dose_table|https://cdn.orris.care/cdss_images/GLGCA_3472859_1763905001260_6c839816-0e0d-4f85-be5e-b908aa68eaa9.png EOF python - <<'EOF' import json,subprocess,base64 from PIL import Image from io import BytesIO lines=[l.strip().split('|') for l in open('urls2.txt') if l.strip()] res=json.loads(subprocess.check_output(["python","/tmp/skills/shared/scripts/fetch_images.py"]+[u for _,u in lines])) for (n,u),r in zip(lines,res): if r['base64']: raw=base64.b64decode(r['base64'].split('base64,')[1]) im=Image.open(BytesIO(raw)).convert('RGB'); im.save(f'assets/{n}.jpg',quality=92); print(n,im.size) else: print(n,'ERR',r['error']) EOF
cd /tmp/workspace/radsafety && cat > build2.py <<'EOF' import re src=open('build.py').read() head=src.split('# 1 TITLE')[0] head=head.replace("total=14","total=15") # add notes + simply helpers head+=''' from pptx.chart.data import CategoryChartData from pptx.enum.chart import XL_CHART_TYPE, XL_LEGEND_POSITION, XL_LABEL_POSITION def notes(s,t): s.notes_slide.notes_text_frame.text=t def simply(s,t,y=6.28,h=0.72): rect(s,0.6,y,12.1,h,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,0.6,y,1.75,h,AMBER) text(s,0.6,y,1.75,h,'IN SIMPLE WORDS',size=12,color=NAVY,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) text(s,2.5,y,10.1,h,t,size=14,color=DARK,anchor=MSO_ANCHOR.MIDDLE) ''' exec(head) # 1 TITLE s=prs.slides.add_slide(blank) rect(s,0,0,13.333,7.5,NAVY); rect(s,0,0,0.35,7.5,TEAL); rect(s,7.4,0,5.933,7.5,MID) pic(s,'trauma_ct',7.9,1.7,4.9,3.9,'Hybrid trauma suite with sliding-gantry CT') text(s,0.9,1.2,6.3,0.4,'MBBS | RADIOLOGY AND COMMUNITY MEDICINE',size=13,color=AMBER,bold=True) text(s,0.9,1.8,6.4,2.6,['Radiation Safety','and Protection in','Medical Imaging'],size=42,color=WHITE,bold=True,font='Georgia') rect(s,0.95,4.6,1.4,0.06,AMBER) text(s,0.9,4.8,6.2,1.2,'How radiation harms, how much we use, and how to protect patients, staff and the public',size=18,color=RGBColor(0xC9,0xD6,0xE6)) text(s,0.9,6.7,6.4,0.4,'Built from standard medical textbooks and PubMed reviews',size=12,color=RGBColor(0x8F,0xA3,0xBC)) notes(s,'Open by asking: which investigations in your last ward round used radiation? This talk gives you a simple framework to answer: is it needed, how much dose, and how do we protect everyone in the room.') # 2 IONIZING VS NON IONIZING s=base('Start Here: Ionizing vs Non-ionizing Radiation',2,'Basics','Source: Rosen\'s Emergency Medicine (EM spectrum figure); Barash Clinical Anesthesia') pic(s,'em_spectrum',0.6,1.45,7.6,2.75,'Electromagnetic spectrum: shorter wavelength means higher energy') card(s,8.45,1.45,4.25,2.75,'By the end you can',['Explain how radiation injures cells','Define Gy, Sv and effective dose','Separate deterministic and stochastic effects','Apply time, distance, shielding and ALARA','Counsel pregnant and paediatric patients'],TEAL,13,16) card(s,0.6,4.4,5.95,1.75,'Ionizing: can remove electrons from atoms','X-ray, CT, fluoroscopy, nuclear medicine (gamma). Energy is high enough to break DNA bonds, so dose must be controlled.',RED,14,16) card(s,6.75,4.4,5.95,1.75,'Non-ionizing: cannot ionize tissue','Ultrasound, MRI, visible light, radio waves. No ionizing dose, so prefer them when they answer the clinical question.',GREEN,14,16) simply(s,'X-rays and gamma rays carry enough energy to knock electrons out of atoms and damage DNA. Ultrasound and MRI do not.') notes(s,'Use the spectrum: move left and energy rises. X-ray and gamma are on the high-energy side. MRI uses radio waves and magnets, ultrasound uses sound, so neither ionizes.') # 3 SOURCES s=base('Where Does Our Radiation Dose Come From?',3,'Exposure sources','Source: Rosen\'s Emergency Medicine, Ch. 134 (US average 6.2 mSv per person per year)') cd=CategoryChartData() cats=['Radon and thoron','Cosmic','Internal isotopes (K-40)','Terrestrial','CT','Nuclear medicine','Interventional fluoroscopy','Conventional radiography and fluoroscopy','Occupational and consumer'] vals=[37,5,5,3,24,12,7,5,2] cd.categories=cats; cd.add_series('Share of annual dose (%)',vals) gf=s.shapes.add_chart(XL_CHART_TYPE.DOUGHNUT,Inches(0.5),Inches(1.4),Inches(7.2),Inches(4.8),cd); ch=gf.chart ch.has_legend=True; ch.legend.position=XL_LEGEND_POSITION.RIGHT; ch.legend.include_in_layout=False; ch.legend.font.size=Pt(11) cols=[RGBColor(0x5B,0x8D,0xB8),RGBColor(0x7F,0xB3,0xD5),RGBColor(0xA9,0xCC,0xE3),RGBColor(0xC9,0xDD,0xEC),RED,AMBER,RGBColor(0xE0,0x7B,0x39),RGBColor(0xF2,0xC1,0x4E),RGBColor(0xB0,0xB8,0xC2)] pl=ch.plots[0]; pl.has_data_labels=True; dl=pl.data_labels; dl.font.size=Pt(11); dl.font.bold=True; dl.font.color.rgb=WHITE; dl.number_format='0"%"'; dl.number_format_is_linked=False for i,c in enumerate(cols): pt=pl.series[0].points[i]; pt.format.fill.solid(); pt.format.fill.fore_color.rgb=c card(s,8.0,1.45,4.7,1.45,'50% natural background','Radon is the largest single source (37%) and the second leading cause of lung cancer after smoking.',MID,13,16) card(s,8.0,3.05,4.7,1.45,'48% medical imaging','CT alone gives 24%, the biggest medical share; nuclear medicine 12%.',RED,13,16) card(s,8.0,4.65,4.7,1.5,'Why this matters to you','Medical exposure is the one source doctors directly control, by choosing the test.',AMBER,13,16) simply(s,'Nature gives us about half our yearly dose. Almost all the rest comes from the scans we order.') notes(s,'Figures are US averages from the NCRP 2012 report quoted in Rosen. Indian background varies by region (for example monazite sands in Kerala) but the medical share trend is the same: CT dominates.') # 4 MECHANISM s=base('How Radiation Injures a Cell',4,'Radiobiology','Source: Goldman-Cecil Medicine (radiation biology); Barash Clinical Anesthesia; Bergonie-Tribondeau law (general radiobiology)') steps=[('X-ray or gamma photon','Deposits energy in tissue',NAVY),('DIRECT hit','Breaks DNA bonds, including double-strand breaks',RED),('INDIRECT hit','Splits water into hydroxyl free radicals which damage DNA',AMBER)] rect(s,0.6,1.5,2.7,1.5,NAVY); text(s,0.6,1.5,2.7,1.5,['X-ray or gamma photon','Energy absorbed in tissue'],size=15,color=WHITE,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) rect(s,3.9,1.5,3.1,0.68,RED); text(s,3.9,1.5,3.1,0.68,'DIRECT: breaks DNA strands',size=14,color=WHITE,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) rect(s,3.9,2.32,3.1,0.68,AMBER); text(s,3.9,2.32,3.1,0.68,'INDIRECT: water to free radicals',size=14,color=NAVY,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) for yy in (1.84,2.66): a=s.shapes.add_shape(MSO_SHAPE.RIGHT_ARROW,Inches(3.35),Inches(yy-0.15),Inches(0.5),Inches(0.3)); a.fill.solid(); a.fill.fore_color.rgb=GREY; a.line.fill.background() a2=s.shapes.add_shape(MSO_SHAPE.RIGHT_ARROW,Inches(7.05),Inches(yy-0.15),Inches(0.5),Inches(0.3)); a2.fill.solid(); a2.fill.fore_color.rgb=GREY; a2.line.fill.background() rect(s,7.6,1.5,2.5,1.5,WHITE,line=GREY); text(s,7.6,1.5,2.5,1.5,['DNA damage','double-strand break','is the key lesion'],size=14,color=NAVY,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) a=s.shapes.add_shape(MSO_SHAPE.RIGHT_ARROW,Inches(10.15),Inches(2.1),Inches(0.5),Inches(0.3)); a.fill.solid(); a.fill.fore_color.rgb=GREY; a.line.fill.background() outs=[('Repaired',GREEN),('Misrepaired: chromosome aberrations, mutation, cancer',AMBER),('Cell death: mitotic death or apoptosis',RED)] for i,(t,c) in enumerate(outs): rect(s,10.7,1.5+i*0.52,2.0,0.48,c); text(s,10.7,1.5+i*0.52,2.0,0.48,t,size=10,color=WHITE if c!=AMBER else NAVY,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) card(s,0.6,3.3,5.95,2.85,'Which cells are most sensitive?',['Rapidly dividing and undifferentiated cells (Bergonie-Tribondeau law)','High: lymphocytes, bone marrow, gut crypt cells, gonads','Medium: skin, lens of eye','Low: muscle, nerve, bone'],TEAL,14,17) card(s,6.75,3.3,5.95,2.85,'Why acute syndromes follow this pattern',['Dividing precursor cells die first','Symptoms appear only when old cells need replacing, hence a latent period','Haematopoietic syndrome: 3 to 9 Gy, illness at 4 to 8 weeks','GI syndrome: about 8 Gy and above, crypt stem cells lost'],RED,14,17) simply(s,'Radiation breaks DNA, directly or through free radicals. Cells that divide a lot suffer most, which is why marrow and gut fail first.') notes(s,'Prodromal nausea and vomiting, then a latent period, then manifest illness, then recovery or death are the four stages of acute radiation syndrome. Diagnostic imaging doses are far below these levels; this explains the biology behind the safety rules.') # 5 UNITS s=base('Units Made Easy: Becquerel, Gray and Sievert',5,'Fundamentals','Source: Campbell-Walsh-Wein Urology Table 3.1; Rosen\'s Emergency Medicine Table 134.1') rows=[('Question it answers','Quantity','SI unit','Old unit'), ('How radioactive is the source?','Activity','becquerel (Bq)','curie (Ci)'), ('How much radiation is in the air?','Exposure','coulomb/kg','roentgen (R)'), ('How much energy did tissue absorb?','Absorbed dose','gray (Gy)','rad (1 Gy = 100 rad)'), ('How harmful is that for the tissue type?','Equivalent dose','sievert (Sv)','rem (1 Sv = 100 rem)'), ('What is the whole-body risk?','Effective dose','sievert (Sv)','rem')] tbl=s.shapes.add_table(6,4,Inches(0.6),Inches(1.5),Inches(12.1),Inches(3.2)).table for c,w in enumerate([4.6,2.5,2.4,2.6]): tbl.columns[c].width=Inches(w) for r,row in enumerate(rows): tbl.rows[r].height=Inches(0.52) for c,v in enumerate(row): cell=tbl.cell(r,c); cell.text=v; cell.vertical_anchor=MSO_ANCHOR.MIDDLE cell.fill.solid(); cell.fill.fore_color.rgb = NAVY if r==0 else (WHITE if r%2 else RGBColor(0xE8,0xEF,0xF5)) f=cell.text_frame.paragraphs[0].runs[0].font; f.size=Pt(14); f.name='Calibri'; f.bold=(r==0 or c==1); f.color.rgb= WHITE if r==0 else DARK card(s,0.6,4.9,5.95,1.25,'For diagnostic X-rays','Weighting factor = 1, so 1 Gy = 1 Sv. Use gray for therapy, sievert for staff and patient protection.',TEAL,13,16) card(s,6.75,4.9,5.95,1.25,'Handy prefixes','1 Sv = 1000 mSv = 1,000,000 uSv. Most imaging doses are in mSv.',AMBER,13,16) simply(s,'Gray = energy absorbed. Sievert = biological harm. Effective dose lets us compare a chest X-ray with a CT on one scale.') notes(s,'Analogy: gray is how hard you were hit, sievert is how much it hurts given where you were hit. Effective dose sums the weighted organ doses into one whole-body risk number.') # 6 DETERMINISTIC VS STOCHASTIC s=base('Deterministic vs Stochastic Effects',6,'Radiobiology','Sources: Goldman-Cecil, Barash, Rosen, Mulholland (definitions); thresholds marked * are standard ICRP/radiobiology values') rows=[('','Deterministic (tissue reaction)','Stochastic (chance effect)'), ('Threshold','Yes, below it no effect','No threshold assumed (LNT model)'), ('Severity','Rises with dose','Same at any dose'), ('What rises with dose','Severity','Probability'), ('Examples','Skin burn, epilation, cataract, marrow failure, sterility','Cancer, hereditary effects'), ('Typical setting','Prolonged fluoroscopy, radiotherapy, accidents','Any exposure, including routine CT'), ('Prevention aim','Stay below threshold','ALARA: keep dose as low as possible')] tbl=s.shapes.add_table(7,3,Inches(0.6),Inches(1.45),Inches(8.1),Inches(4.7)).table for c,w in enumerate([1.9,3.2,3.0]): tbl.columns[c].width=Inches(w) for r,row in enumerate(rows): tbl.rows[r].height=Inches(0.66) for c,v in enumerate(row): cell=tbl.cell(r,c); cell.text=v; cell.vertical_anchor=MSO_ANCHOR.MIDDLE cell.fill.solid(); cell.fill.fore_color.rgb = NAVY if r==0 else (WHITE if r%2 else RGBColor(0xE8,0xEF,0xF5)) if cell.text_frame.paragraphs[0].runs: f=cell.text_frame.paragraphs[0].runs[0].font; f.size=Pt(13); f.name='Calibri'; f.bold=(r==0 or c==0); f.color.rgb= WHITE if r==0 else DARK card(s,8.95,1.45,3.75,4.7,'Approximate thresholds*',['Lens opacity (cataract): about 0.5 Gy','Transient skin erythema: about 2 Gy','Temporary epilation: about 3 Gy','Haematopoietic syndrome: 3 to 9 Gy','GI syndrome: about 8 Gy and above','Diagnostic exams: far below these, except long fluoroscopy'],RED,13,17) simply(s,'Deterministic = burns with a dose limit you can stay under. Stochastic = a lottery where more dose means more tickets.') notes(s,'LNT stands for linear no-threshold: cancer risk is assumed to rise in proportion to dose with no safe level. Campbell quotes about 1 in 1000 extra malignancies for 10 mSv (National Research Council 2006). Thresholds marked with an asterisk are standard values and should be checked against your exam textbook.') # 7 SKIN INJURY CASE s=base('Case: Fluoroscopy-Induced Skin Injury',7,'Deterministic effect in real life','Source: Library figure on fluoroscopy-induced radiation dermatitis (cardiac procedure)') pic(s,'skin_injury',0.6,1.45,4.1,4.7,'(a) beam field, (b) 3 weeks, (c) 5 months, (d) 8 months, (e) 10 months') text(s,5.0,1.45,7.7,0.45,'What happened',size=20,color=NAVY,bold=True,font='Georgia') tl=[('3 weeks','Well-demarcated circular erythema on the arm that was in the primary beam',AMBER),('5 months','Deep necrotic ulcer with eschar and inflamed rim',RED),('8 months','Open ulcer with slough after debridement',RED),('10 months','Reconstruction with a skin flap',MID)] for i,(t,d,c) in enumerate(tl): y=2.0+i*0.82 rect(s,5.0,y,1.5,0.7,c); text(s,5.0,y,1.5,0.7,t,size=15,color=WHITE,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) rect(s,6.5,y,6.2,0.7,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); text(s,6.65,y,6.0,0.7,d,size=14,color=DARK,anchor=MSO_ANCHOR.MIDDLE) card(s,5.0,5.3,7.7,0.85,'Lessons','Injury appears weeks later and may not be linked to the procedure. Keep the beam moving and dose low.',TEAL,13,14) simply(s,'A long fluoroscopy run can burn the skin where the beam enters, and the burn may only show up weeks later.') notes(s,'Ask students: why did the patient not notice anything on the day? Because skin injury needs time to evolve. Prevention: change beam angles, collimate, use pulsed low frame-rate fluoroscopy, and record the dose.') # 8 DOSES s=base('How Much Is One Scan? Relating Dose to Everyday Life',8,'Patient dose','Sources: Library dose table (ICRP 103, NCRP 177; background 3.1 mSv/yr); Barash (chest X-ray 0.02 mSv); Campbell-Walsh Table 3.2') cd=CategoryChartData(); cd.categories=['Abdomen + pelvis CT','Natural background (1 year)','Head CT (brain)','Chest X-ray']; cd.add_series('Effective dose (mSv)',[7.7,3.1,1.6,0.02]) gf=s.shapes.add_chart(XL_CHART_TYPE.BAR_CLUSTERED,Inches(0.6),Inches(1.45),Inches(7.2),Inches(4.7),cd); ch=gf.chart ch.has_legend=False; ch.has_title=True; ch.chart_title.text_frame.text='Effective dose (mSv)'; ch.chart_title.text_frame.paragraphs[0].runs[0].font.size=Pt(14) ch.category_axis.tick_labels.font.size=Pt(13); ch.category_axis.reverse_order=True ch.value_axis.visible=False; ch.value_axis.has_major_gridlines=False pl=ch.plots[0]; pl.gap_width=60; pl.has_data_labels=True; pl.data_labels.font.size=Pt(14); pl.data_labels.font.bold=True; pl.data_labels.position=XL_LABEL_POSITION.OUTSIDE_END for i,c in enumerate([RED,GREY,AMBER,GREEN]): p=pl.series[0].points[i]; p.format.fill.solid(); p.format.fill.fore_color.rgb=c text(s,8.1,1.45,4.6,0.4,'Same dose as how many days of natural background?',size=15,color=NAVY,bold=True) eq=[('Chest X-ray','about 2 days',GREEN),('Head CT','about 188 days',AMBER),('Abdomen + pelvis CT','about 905 days (2.5 years)',RED)] for i,(a,b,c) in enumerate(eq): y=2.2+i*1.0 rect(s,8.1,y,4.6,0.88,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,8.1,y,0.1,0.88,c) text(s,8.3,y+0.04,4.3,0.4,a,size=14,color=NAVY,bold=True); text(s,8.3,y+0.42,4.3,0.4,b,size=15,color=DARK) text(s,8.1,5.25,4.6,0.9,'Multiphase abdominal CT can reach 25 to 40 mSv; whole-body PET and coronary CTA (3 to 15 mSv) are also high.',size=12,color=GREY) simply(s,'One abdominal CT equals about 2.5 years of natural background radiation. A chest X-ray equals about 2 days.') notes(s,'Days of background are from the library table: head CT 860-1500 uSv equals 101-177 days; brain CT 1.6 mSv equals 188 days; abdomen-pelvis CT 7.7 mSv equals 905 days; chest X-ray 0.02 mSv is about 2 days by simple arithmetic (0.02 / 3.1 x 365). Values vary by machine, protocol and patient size.') # 9 PRINCIPLES + LIMITS s=base('The Framework: Justify, Optimize, Limit',9,'ICRP system of protection','Sources: ICRP 103 (limits, from general knowledge); Campbell-Walsh (NCRP 50 mSv); Rockwood & Green; Rheumatology (Elsevier) for ALARA') pill=[('1 JUSTIFICATION','Does the benefit outweigh the risk? Is there a non-ionizing alternative? Is the result going to change management?',TEAL), ('2 OPTIMIZATION (ALARA)','As Low As Reasonably Achievable: right kVp and mA, collimate, shortest scan range, no unnecessary repeats.',AMBER), ('3 DOSE LIMITS','Apply to workers and the public. Patients have no dose limit; they are protected by justification and optimization.',MID)] for i,(h,b,c) in enumerate(pill): x=0.6+i*4.1 rect(s,x,1.45,3.9,2.45,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,x,1.45,3.9,0.65,c) text(s,x+0.1,1.45,3.7,0.65,h,size=17,color=WHITE if c!=AMBER else NAVY,bold=True,anchor=MSO_ANCHOR.MIDDLE) text(s,x+0.2,2.2,3.5,1.7,b,size=14,color=DARK) rows=[('Group','Annual limit (ICRP 103 / 118)'),('Radiation worker, effective dose','20 mSv/year averaged over 5 years; max 50 mSv in any one year'),('Lens of the eye','20 mSv/year averaged over 5 years'),('Skin and hands','500 mSv/year'),('Member of the public','1 mSv/year'),('Pregnant worker (fetus)','About 1 mSv for the rest of pregnancy after declaration')] tbl=s.shapes.add_table(6,2,Inches(0.6),Inches(4.05),Inches(12.1),Inches(2.1)).table tbl.columns[0].width=Inches(4.3); tbl.columns[1].width=Inches(7.8) for r,row in enumerate(rows): tbl.rows[r].height=Inches(0.35) for c,v in enumerate(row): cell=tbl.cell(r,c); cell.text=v; cell.vertical_anchor=MSO_ANCHOR.MIDDLE; cell.margin_top=cell.margin_bottom=Inches(0.02) cell.fill.solid(); cell.fill.fore_color.rgb = NAVY if r==0 else (WHITE if r%2 else RGBColor(0xE8,0xEF,0xF5)) f=cell.text_frame.paragraphs[0].runs[0].font; f.size=Pt(12); f.name='Calibri'; f.bold=(r==0 or c==0); f.color.rgb= WHITE if r==0 else DARK simply(s,'Ask first if the test is needed, then do it with the least dose that answers the question, and keep staff below their limits.') notes(s,'Campbell quotes 50 mSv per year as the NCRP occupational limit; ICRP recommends 20 mSv per year averaged over 5 years with a 50 mSv cap in a single year. In India AERB follows the ICRP-based values. Always confirm with local regulation.') # 10 TIME DISTANCE SHIELDING s=base('Protecting Staff: Time, Distance, Shielding',10,'Core rules','Sources: Rosen Ch. 134; Barash Clinical Anesthesia; Morgan & Mikhail; Campbell-Walsh-Wein') cols=[('TIME','Less time, less dose',['Pulsed, low frame-rate fluoroscopy','Short bursts, last-image hold','Plan before the beam goes on'],TEAL), ('DISTANCE','Step back from the source',['Dose falls with the square of distance','Use the full exposure cord','Stay out of the primary beam'],AMBER), ('SHIELDING','Put lead in the way',['Lead apron, thyroid collar, glasses','Lead glass booth and mobile screens','Barash: staff dose at 1 m is about 1/1000 of entrance skin dose'],MID)] for i,(h,sub,items,c) in enumerate(cols): x=0.6+i*4.1 rect(s,x,1.45,3.9,2.45,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,x,1.45,3.9,0.75,c) text(s,x,1.45,3.9,0.75,[h],size=22,color=WHITE if c!=AMBER else NAVY,bold=True,align=PP_ALIGN.CENTER,font='Georgia',anchor=MSO_ANCHOR.MIDDLE) text(s,x+0.2,2.22,3.5,0.35,sub,size=13,color=GREY,bold=True) bullets(s,x+0.2,2.58,3.55,1.4,items,size=13,gap=3,dot=c) text(s,0.6,4.02,6,0.4,'Inverse square law: intensity = 1 / distance squared',size=16,color=NAVY,bold=True) src=rect(s,0.6,4.5,1.5,1.65,RED,shape=MSO_SHAPE.OVAL); text(s,0.6,4.5,1.5,1.65,['X-ray','source'],size=14,color=WHITE,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) dd=[('1 m','100%',RED),('2 m','25%',RGBColor(0xE0,0x7B,0x39)),('3 m','11%',AMBER),('4 m','6%',GREEN)] for i,(d,p,c) in enumerate(dd): x=2.4+i*2.1; hgt=1.65-i*0.2 rect(s,x,4.5+(1.65-hgt)/2,1.9,hgt,c,shape=MSO_SHAPE.ROUNDED_RECTANGLE) text(s,x,4.5+(1.65-hgt)/2,1.9,hgt,[d,p],size=18,color=WHITE if c!=AMBER else NAVY,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) rect(s,10.85,4.5,1.85,1.65,NAVY); text(s,10.85,4.5,1.85,1.65,['Double the distance, one quarter of the dose'],size=13,color=WHITE,bold=True,align=PP_ALIGN.CENTER,anchor=MSO_ANCHOR.MIDDLE) simply(s,'Be quick, stand far, and put lead between you and the patient. Barash reports anaesthetists getting 15 times a scrub nurse\'s dose when they skipped the shields.') notes(s,'Rosen also adds a fourth factor: quantity (limit the amount of radioactive material in the work area). Shielding depends on radiation type: alpha stopped by paper or skin, beta by plastic or aluminium, gamma and X-rays need dense material such as lead or concrete.') # 11 PPE AND ROOM s=base('Shielding in Practice: PPE and Room Design',11,'Equipment','Sources: Brogdon\'s Forensic Radiology Ch. 34 (Figs 34.19-34.20); library figures; lead equivalence is general practice') pic(s,'apron_or',0.6,1.45,2.55,3.1,'Wrap-around lead apron') pic(s,'axillary',3.3,1.45,2.55,3.1,'Extra axillary protection') pic(s,'booth',6.0,1.45,4.1,3.1,'Control booth with lead glass') pic(s,'xray_door',10.25,1.45,2.45,3.1,'Warning light above door') card(s,0.6,4.7,5.95,1.45,'Personal protective equipment',['Apron 0.25 to 0.5 mm lead equivalent, thyroid collar, leaded glasses','Hang aprons, never fold; check for cracks regularly'],MID,12,15) card(s,6.75,4.7,5.95,1.45,'Room design',['Primary barrier (thick lead) faces the beam; secondary barrier stops scatter','Warning lights show when the room is in use and when the beam is on'],TEAL,12,15) simply(s,'Lead aprons stop scattered X-rays, not the direct beam. Walls, booths and lights protect everyone else.') notes(s,'Brogdon: the control booth is usually a secondary barrier; the primary beam must never be directed at it. Involve a radiation physicist during construction. Lead equivalence of 0.25-0.5 mm is common practice; confirm local rules.') # 12 FLUOROSCOPY s=base('Fluoroscopy and C-arm: The High-Exposure Setting',12,'Highest staff exposure','Sources: Campbell-Walsh-Wein Urology Fig 3.1; Barash Clinical Anesthesia Fig 33-2; Miller\'s Anesthesia 10e') pic(s,'fluoro_setup',0.6,1.45,3.9,4.7,'Tube under table, intensifier close to patient') pic(s,'carm_suite',4.7,1.45,4.2,4.7,'C-arm suite: crowded equipment around the patient') text(s,9.15,1.45,3.55,0.4,'Rules for the operator',size=18,color=NAVY,bold=True,font='Georgia') bullets(s,9.15,1.95,3.55,4.2,[('Tube under table:','scatter rises on the beam-entry side.'),('Intensifier close:','less scatter, less patient dose.'),('Collimate','to the area needed.'),('Avoid magnification','unless essential.'),('1 minute of fluoroscopy','gives roughly 10 times a radiograph\'s skin dose.'),('Wear your shields','even when busy.')],size=13,gap=4) simply(s,'In fluoroscopy the beam stays on, so doses add up fast. Keep the tube under the table and your lead on.') notes(s,'Patients are exposed to the direct beam at the skin entry point, staff to scatter. Scatter comes from the patient, so the area close to the patient is where staff dose is highest. Fix protection habits early in training.') # 13 PREGNANCY CHILDREN s=base('Special Groups: Pregnancy and Children',13,'Counselling','Sources: Rosen\'s Emergency Medicine; Rockwood & Green 10e; Mulholland & Greenfield (Table 104.1); Campbell-Walsh-Wein; Sabiston') card(s,0.6,1.45,6.0,2.5,'Pregnancy',['Fetal harm is unlikely below 50 mGy','Pelvic or abdomen-pelvis CT gives about 25 to 30 mGy to the fetus','Chest radiograph: 0.08 to 0.5 mGy (scatter only)','Abdominal plain film: about 2.5 to 3 mGy'],RED,13,17) card(s,6.8,1.45,5.9,2.5,'Children',['More radiosensitive, with more years to develop cancer','Dose-response seen between CT dose and brain cancer','Use ultrasound or MRI first when possible','Use paediatric-size protocols'],AMBER,13,17) card(s,0.6,4.1,6.0,2.05,'Practical steps in pregnancy',['Ask about LMP before any abdominal or pelvic exam','Choose ultrasound or MRI first','If CT is needed, limit the scan range and document consent'],TEAL,13,16) card(s,6.8,4.1,5.9,2.05,'Do not withhold a needed scan',['Mulholland: fear of radiation can cause misdiagnosis, which endangers mother and fetus more than the dose','Explain numbers in plain language: compare with background'],MID,13,16) simply(s,'A necessary scan is almost always safer than a missed diagnosis. Use ultrasound or MRI first, and explain the numbers calmly.') notes(s,'Effects depend on gestational age and dose. The first three categories of fetal harm (lethal, teratogenic, growth retardation) are deterministic with a threshold; cancer risk is stochastic. Organs outside the abdomen and pelvis receive only scatter to the fetus.') # 14 MONITORING s=base('Monitoring Staff Doses',14,'Dosimetry','Sources: Library figures on dosimeter placement and TLD monitoring; ICRP') pic(s,'dosimeters',0.6,1.45,6.2,2.95,'Where dosimeters are worn: eye, body, wrist, ring') pic(s,'tld',7.0,1.45,5.7,2.95,'TLDs used during a fluoroscopy-guided procedure') card(s,0.6,4.55,3.9,1.6,'Whole-body badge','Worn at collar level outside the apron; add a second badge under it to estimate effective dose.',TEAL,12,15) card(s,4.7,4.55,3.9,1.6,'Extremity and eye','Ring or wrist TLD for hands, small lens dosimeter near the eye for interventional staff.',AMBER,12,15) card(s,8.8,4.55,3.9,1.6,'Act on results','Review every period, investigate high readings and keep records. Pregnant staff should declare early.',MID,12,15) simply(s,'A badge is a report card for your protection habits. Read it, learn from it, and keep it with your own records.') notes(s,'TLD stands for thermoluminescent dosimeter; OSL and electronic dosimeters are alternatives. The lens of the eye has a lower limit now because cataract risk appears at lower doses than once thought; Rockwood quotes cataract risk above 0.5 Sv lifetime ocular exposure.') # 15 REVISION s=prs.slides.add_slide(blank) rect(s,0,0,13.333,7.5,NAVY); rect(s,0,0,0.35,7.5,TEAL) text(s,0.9,0.4,8,0.4,'QUICK REVISION',size=13,color=AMBER,bold=True) text(s,0.9,0.75,8,0.8,'Five viva questions',size=32,color=WHITE,bold=True,font='Georgia') qa=[('What does ALARA mean?','As Low As Reasonably Achievable: keep dose minimal while keeping image quality.'), ('Deterministic vs stochastic?','Threshold and severity rise with dose, versus no threshold and probability rises with dose.'), ('Which unit measures biological risk?','Sievert (effective dose); gray measures absorbed energy.'), ('If distance doubles?','Dose falls to one quarter (inverse square law).'), ('Fetal dose considered safe?','Below 50 mGy; do not withhold a needed scan.')] for i,(q,a) in enumerate(qa): y=1.75+i*1.03 rect(s,0.9,y,7.4,0.92,RGBColor(0x14,0x30,0x55)); rect(s,0.9,y,0.09,0.92,AMBER) text(s,1.1,y+0.04,7.1,0.38,q,size=15,color=AMBER,bold=True); text(s,1.1,y+0.4,7.1,0.52,a,size=12.5,color=WHITE) rect(s,8.6,0.7,4.2,6.1,MID) text(s,8.85,0.85,3.8,0.4,'References',size=16,color=AMBER,bold=True) text(s,8.85,1.3,3.75,5.4,['Rosen\'s Emergency Medicine: Radiation protection and sources (Ch. 134).','Goldman-Cecil Medicine: Radiation biology and acute radiation syndromes.','Barash Clinical Anesthesia 9e: Hazards of ionizing radiation.','Campbell-Walsh-Wein Urology: Radiation management in uroradiology.','Mulholland & Greenfield Surgery 7e: Imaging the pregnant patient.','Brogdon\'s Forensic Radiology: Methods of protection.','Recent reviews: Videira 2026 (PMID 42372711); Elsaeidy 2025 (PMID 40540234); Ramos-Avasola 2024 (PMID 38959875).','ICRP Publications 103 and 118 for limits. Verify with local regulation.'],size=11.5,color=RGBColor(0xDD,0xE6,0xF2)) notes(s,'Use these as a closing active-recall exercise: cover the right-hand answers and ask the audience to respond.') prs.save('output/Radiation_Safety_MBBS.pptx') print('saved') EOF python build2.py
cd /tmp/workspace/radsafety && python - <<'EOF' from pptx import Presentation import math prs=Presentation('output/Radiation_Safety_MBBS.pptx') print(len(prs.slides)) for i,s in enumerate(prs.slides,1): for sh in s.shapes: if sh.has_text_frame and sh.text_frame.text.strip(): w=sh.width/914400-0.1; h=sh.height/914400; tot=0 for p in sh.text_frame.paragraphs: if not p.runs: continue sz=max(r.font.size.pt for r in p.runs); chars=sum(len(r.text) for r in p.runs) lines=math.ceil(chars/max(1,w*72/(sz*0.5))) tot+=lines*sz*1.2/72+(p.space_after.pt if p.space_after else 0)/72 if tot>h+0.02: print(i,round(tot,2),'>',round(h,2),sh.text_frame.text[:60].replace('\n',' | ')) EOF
cd /tmp/workspace/radsafety && python - <<'EOF' s=open('build2.py').read() s=s.replace("'Apply time, distance, shielding and ALARA','Counsel pregnant and paediatric patients'],TEAL,13,16)","'Apply time, distance, shielding and ALARA','Counsel pregnant and paediatric patients'],TEAL,12,16)") s=s.replace("card(s,5.0,5.3,7.7,0.85,'Lessons','Injury appears weeks later and may not be linked to the procedure. Keep the beam moving and dose low.',TEAL,13,14)", "rect(s,5.0,5.3,7.7,0.85,WHITE,line=RGBColor(0xD5,0xDC,0xE4)); rect(s,5.0,5.3,0.09,0.85,TEAL)\ntext(s,5.2,5.3,7.4,0.85,'Lesson: injury appears weeks later and may not be linked to the procedure. Keep the beam moving and the dose low.',size=13,color=DARK,anchor=MSO_ANCHOR.MIDDLE)") s=s.replace("text(s,8.1,1.45,4.6,0.4,'Same dose as how many days of natural background?',size=15","text(s,8.1,1.45,4.6,0.7,'Same dose as how many days of natural background?',size=14") for a,b in [("pic(s,'apron_or',0.6,1.45,2.55,3.1","pic(s,'apron_or',0.6,1.45,2.55,2.9"),("pic(s,'axillary',3.3,1.45,2.55,3.1","pic(s,'axillary',3.3,1.45,2.55,2.9"),("pic(s,'booth',6.0,1.45,4.1,3.1","pic(s,'booth',6.0,1.45,4.1,2.9"),("pic(s,'xray_door',10.25,1.45,2.45,3.1","pic(s,'xray_door',10.25,1.45,2.45,2.9"), ("card(s,0.6,4.7,5.95,1.45,'Personal protective equipment'","card(s,0.6,4.45,5.95,1.75,'Personal protective equipment'"),("card(s,6.75,4.7,5.95,1.45,'Room design'","card(s,6.75,4.45,5.95,1.75,'Room design'")]: assert a in s; s=s.replace(a,b) open('build2.py','w').write(s) EOF python build2.py && python - <<'EOF' from pptx import Presentation import math prs=Presentation('/tmp/workspace/radsafety/output/Radiation_Safety_MBBS.pptx') for i,s in enumerate(prs.slides,1): for sh in s.shapes: if sh.has_text_frame and sh.text_frame.text.strip(): w=sh.width/914400-0.1; h=sh.height/914400; tot=0 for p in sh.text_frame.paragraphs: if not p.runs: continue sz=max(r.font.size.pt for r in p.runs); chars=sum(len(r.text) for r in p.runs) tot+=math.ceil(chars/max(1,w*72/(sz*0.5)))*sz*1.2/72+(p.space_after.pt if p.space_after else 0)/72 if tot>h+0.02: print(i,round(tot,2),'>',round(h,2),sh.text_frame.text[:60]) print('checked') EOF
Radiation Safety MBBS
Presentation · PPTX