Make a pdf of all the instruments with pictures for the postgraduate ophthalmology practical exam
ophthalmic instruments ophthalmology slit lamp tonometer

This clinical ophthalmic photograph illustrates anterior lenticonus, a diagnostic sign frequently associated with Alport syndrome. The composite image consists of two views: a slit-lamp biomicroscopy photograph (left) and a retroillumination photograph (right) of the right eye. The slit-lamp view utilizes a narrow cobalt blue beam to profile the crystalline lens, revealing a characteristic localized, conical protrusion or bulge on the anterior capsule surface. The retroillumination technique on the right highlights the 'oil droplet' appearance typical of this condition, where the conical deformity of the lens refracts light differently from the surrounding lens matter. These visual findings demonstrate the irregular lens curvature and associated optical reflections, which are critical for the clinical diagnosis of anterior lenticonus. This educational material is intended for ophthalmology students and residents to differentiate lens surface abnormalities from typical lenticular morphology.

This ophthalmic slit-lamp photograph captures ocular surface of the anterior segment, showing a pinguecula in bulbar conjunctiva adjacent to limbus within the interpalpebral fissure. The lesion appears as a raised, yellow‑white to gray‑white nodule embedded in the superficial stroma of the bulbar conjunctiva, with well‑defined margins and slight smoothing toward the limbus. The surrounding conjunctiva shows normal vascularity and mild surface irritation is absent in this image; no corneal involvement or scleral thinning is evident. Pingueculae represent a degenerative elastotic change of the conjunctival connective tissue, commonly related to cumulative ultraviolet exposure, aging, and environmental factors. The lesion is typically asymptomatic or causes only mild irritation, and it does not progress toward the cornea. Management is usually conservative, consisting of observation and protection from sun exposure; excision is rare and reserved for cosmetic concerns or persistent irritation. Clinically, pinguecula must be differentiated from pterygium, conjunctival nevus, and other conjunctival lesions. This image emphasizes the characteristic location (near the limbus, in the interpalpebral zone), color, and texture without corneal involvement. The diagnostic significance lies in recognizing a benign, UV‑related conjunctival alteration that requires no aggressive treatment unless symptoms or cosmetic issues arise, aiding educational and clinical decision‑making in ophthalmology.

This composite of clinical ophthalmic images displays both anterior segment photographs and fundus images of the right (OD) and left (OS) eyes, illustrating manifestations of Vogt-Koyanagi-Harada (VKH)-like disease. Panels A through D represent anterior segment views: Slit-lamp biomicroscopy reveals ciliary hyperemia, conjunctival injection, and irregular pupillary margins indicative of posterior synechiae (adhesions between the iris and lens). These findings are consistent with active or chronic anterior uveitis. Panels E and F provide fundus photography showing a classic 'sunset-glow fundus' appearance. This is characterized by diffuse choroidal depigmentation, resulting in a prominent reddish-orange hue across the retina. The optic discs appear relatively pale, and there is a visible loss of the normal retinal pigment epithelium (RPE) pigmentation. These visual findings are hallmark late-stage features of panuveitis where chronic inflammation leads to the destruction of melanocytes in the choroid. The material is intended for advanced medical education in ophthalmology and rheumatology, focusing on medication-induced or autoimmune uveitic syndromes.

This composite of two ophthalmic images demonstrates the safety profile and drug depot characteristics following an intravitreal injection of a prodrug (HDP-PMEG). Image A is a slit-lamp photograph using retroillumination, captured at 6 weeks post-injection. It reveals the presence of fine, particulate drug particles suspended within the vitreous humor (marked by black arrows), demonstrating the slow-release properties of the minimally water-soluble crystalline prodrug. Image B provides a wide-field fundus view of the same subject at 8 weeks post-injection. This image serves as a clinical safety comparison, showing a healthy retinal background, a well-defined and normal optic nerve head, and the characteristic appearance of the medullary ray without evidence of inflammation, retinal hemorrhage, or whitening. These images are used in ophthalmology to illustrate drug delivery mechanics, specifically the formation of a vitreous depot and its long-term biocompatibility within the posterior segment.

Imaging modality: Slit-lamp anterior segment photography (ophthalmic photography). The image depicts the right/left eye under slit-lamp illumination showing signs of anterior uveitis (iritis) in the setting of Behçet disease. Observed features include diffuse conjunctival injection with hyperemic episcleral vessels and mild edema of the eyelids; the cornea appears clear. The iris is visible with accentuation of the pupil margin and subtle synechiae cannot be excluded. There may be mild circumcorneal flush and anterior chamber reaction not fully resolved in this single color photograph. This pattern is characteristic of inflammatory anterior uveitis commonly seen in Behçet's, often accompanied by photophobia and lacrimation. The ocular surface shows inflammatory signs consistent with active iridocyclitis; the red eye and vascular engorgement reflect intraocular inflammatory activity. Clinically, anterior uveitis in Behçet can precede or accompany systemic flares and carries risk for synechiae formation, glaucoma, and vision loss if inadequately treated. Differential considerations include other etiologies of non-granulomatous anterior uveitis such as HLA-B27-associated uveitis, sarcoidosis, juvenile idiopathic arthritis, herpetic anterior uveitis, or masquerade syndromes. The image supports diagnosis when integrated with clinical history of recurrent oral/genital ulcers and systemic vasculitis. Management implications include prompt ophthalmology referral and escalation to corticosteroids and immunosuppressants as per protocols globally.

This diagnostic image demonstrates the presence of fungal growth on an ophthalmic optical lens, likely from a slit lamp or similar diagnostic equipment. The image shows a gray-scale field of view with a central black crosshair. Two specific areas of interest are highlighted with red circles. The upper-left circle contains a larger, dense network of dark, branching, web-like hyphae. These fungal structures radiate from a central core, becoming more diffuse at the periphery. The lower-right circle shows a smaller, less dense fungal colony with a similar dendritic or mycelial pattern. In a clinical ophthalmology context, this illustrates environmental contamination of diagnostic equipment, which can lead to light scattering, decreased image contrast, and eventual permanent etching of lens coatings if not mitigated via proper storage and humidity control.

This clinical photograph, likely captured via slit-lamp biomicroscopy, provides a cross-sectional view of the anterior segment of the left eye (labeled OS). The image demonstrates a flat anterior chamber, a critical ophthalmic finding. The primary pathology is characterized by the total loss of depth in the anterior chamber, where the iris is in direct apposition with the posterior surface of the cornea. The cornea appears relatively clear with a visible light reflex on its surface, but its typical architecture is compromised by the lack of an aqueous-filled space between it and the iris. This clinical sign is highly significant in the context of ophthalmology, often associated with conditions such as narrow-angle glaucoma, penetrating ocular trauma, or post-surgical complications (e.g., wound leak or choroidal detachment). The educational focus is on the visual identification of a shallow or absent anterior chamber and understanding its implications for intraocular pressure and ocular health.

Imaging modality: Anterior segment photography of the left eye using slit-lamp ophthalmic photography. The technique provides a high‑resolution frontal view of the anterior segment, including the cornea, iris, pupil, and sclera. The image shows a blue iris with a brown‑black pigmented lesion occupying a sector of the iris, with irregular, ill‑defined margins extending toward the pupillary zone. The surrounding iris stroma is variably depigmented, and the pupil remains round with a bright reflected light source. Conjunctival and episcleral vessels are mildly congested inferiorly, with subtle conjunctival injection. There is no obvious corneal opacity or lens opacity. The lesion appears confined to the iris with partial involvement of the pupillary border; there is no visible transillumination defect. The differential diagnosis includes iris nevus and iris melanoma; characteristic features to assess include progression in size, thickness, surface nodularity, iridocorneal angle involvement, and secondary glaucoma risk. This image is valuable for education in recognizing unilateral pigmented iris lesions, establishing baseline documentation for surveillance, and guiding clinical decision making about monitoring versus biopsy or surgical intervention. Clinically, this finding warrants ophthalmology referral for slit-lamp examination and anterior segment imaging, with AS-OCT or ultrasound biomicroscopy to determine lesion characteristics and growth over time. Potential uses include medical education, case repositories, diagnostic reasoning, and surveillance planning.

A clinical photograph depicting the administration of ophthalmic medication in a clinical setting. The image shows a healthcare professional, wearing blue scrubs and white disposable gloves, instilling eye drops into a patient's eye. The patient is reclined and assisting the procedure by gently retracting the lower eyelid with their finger to expose the conjunctival sac. A clear droplet is visible descending from a plastic dropper bottle toward the ocular surface. The background features ophthalmological equipment, including a slit lamp and an ophthalmoscope mounted on a wall bracket, indicating a professional eye care environment. This visual demonstrates standard clinical technique for topical medication delivery, patient positioning, and the use of personal protective equipment (PPE) in an outpatient ophthalmology or optometry clinic.

This infographic presents a pathophysiology diagram and clinical imagery illustrating the systemic impact of a corneal ulcer (CU). The central figure is a slit-lamp photograph labeled 'Corneal ulcer,' showing a localized, whitish opacity in the inferior-nasal quadrant of the cornea with irregular surface texture and loss of transparency, indicating tissue necrosis or infiltrate. Arrows connect this primary ophthalmic condition to three secondary clinical consequences: 'Eye pain,' 'Cerebral neural activity,' and 'Depression and anxiety.' The 'Eye pain' panel features a clinical photograph of a man demonstrating photophobia and distress, manually shielding his eye. The 'Cerebral neural activity' panel contains a medical illustration of a human brain with highlighted regions in the frontal lobe, suggesting changes in functional connectivity or degree centrality. The 'Depression and anxiety' panel uses a symbolic illustration of a person in a fetal position to represent psychological comorbidity. The diagram summarizes the relationship between local ocular pathology and broader neurological and psychological outcomes in ophthalmology.
slit lamp biomicroscope ophthalmology instrument equipment

A clinical photograph depicting a volunteer healthcare worker performing a capillary blood glucose test on a patient. The scene takes place within an ophthalmology clinic, evidenced by the presence of a slit-lamp biomicroscope in the background, a tool essential for comprehensive eye examinations. The healthcare worker, wearing protective gloves, is shown preparing a finger-stick puncture on the patient's hand. On a small wooden table, clinical supplies including cotton swabs and lancets are visible. This image illustrates integrated health screening, specifically the importance of monitoring blood sugar levels in patients who may be at risk for diabetic retinopathy or other systemic conditions affecting ocular health. The setting suggests a community health or outreach environment, highlighting patient triage and secondary prevention strategies in specialized medical facilities.

This diagnostic image demonstrates the presence of fungal growth on an ophthalmic optical lens, likely from a slit lamp or similar diagnostic equipment. The image shows a gray-scale field of view with a central black crosshair. Two specific areas of interest are highlighted with red circles. The upper-left circle contains a larger, dense network of dark, branching, web-like hyphae. These fungal structures radiate from a central core, becoming more diffuse at the periphery. The lower-right circle shows a smaller, less dense fungal colony with a similar dendritic or mycelial pattern. In a clinical ophthalmology context, this illustrates environmental contamination of diagnostic equipment, which can lead to light scattering, decreased image contrast, and eventual permanent etching of lens coatings if not mitigated via proper storage and humidity control.

This clinical photograph captures a slit-lamp biomicroscopy examination of the anterior segment of the left eye, focusing on an acute hyphema. The image demonstrates active bleeding into the anterior chamber, characterized by a visible stream of blood (indicated by a white arrow) emanating from a superior peripheral iridectomy site. A vertical slit-lamp beam provides cross-sectional illumination, highlighting the depth of the anterior chamber and the distribution of the blood. The pathology is a direct complication following previous intraocular surgeries, including cataract extraction and trabeculectomy. The image serves as an educational example of post-surgical complications in ophthalmology, specifically demonstrating the localization of a bleeding source in the iris-corneal angle region using slit-lamp illumination. Key concepts illustrated include the management of recurrent hyphema and the anatomical relationship between surgical iridectomy and intraocular hemorrhage.
Goldmann applanation tonometer glaucoma instrument

A comparative clinical photograph panel (a-d) demonstrating the use of four different portable tonometers for measuring intraocular pressure (IOP) in felines, serving as a model for ophthalmic diagnostic imaging and device comparison. Image (a) shows the Tonovet, a black rebound tonometer; (b) features the Tonovet Plus, displaying a digital reading of 13 mmHg; (c) shows the Tono-Pen Avia Vet, an applanation tonometer; and (d) displays the Kowa HA-2 hand-held Goldmann applanation tonometer. Each frame illustrates proper clinical technique: the subject's head is stabilized by gloved hands, and the eyelids are gently retracted to ensure the device probe makes perpendicular contact with the central cornea without applying pressure to the globe, which could artifactually elevate IOP. This visual highlights various imaging modalities and diagnostic tools used in ophthalmology to screen for conditions such as glaucoma or uveitis, emphasizing the ergonomic differences and digital interfaces of standard tonometric equipment.

This clinical photograph demonstrates the application of an iCare rebound tonometer on a human subject. The device is a handheld, pistol-shaped instrument with a dark gray plastic body designed for measuring intraocular pressure (IOP). The image shows the device's operational alignment: a superior cylindrical forehead rest is placed against the patient's brow for stabilization, while the lower housing contains a thin, white, magnetized probe positioned perpendicular to the central cornea. The probe is shown in near-contact with the eye, illustrating the rebound tonometry principle where a lightweight probe momentarily impacts the cornea. The device measures the induction current created by the probe's deceleration and rebound velocity to calculate IOP. This diagnostic tool is significant in ophthalmology for glaucoma screening as it is rapid, portable, and does not require topical anesthesia or fluorescein, making it particularly useful for pediatric and non-compliant patients.

A clinical photograph demonstrating the proper application of a Diaton® transpalpebral tonometer for measuring intraocular pressure (IOP). The image depicts the handheld device being applied to a patient in a supine or reclined position. The tonometer is held vertically, perpendicular to the ground, with the tip making contact with the skin of the superior eyelid at the level of the tarsal plate. The patient's eye is partially open, showing the sclera and iris, while the device is positioned above the lash line to avoid direct corneal contact. The clinician's hand is visible, stabilizing the device against the orbital rim or maxilla to ensure accuracy and minimize movement. This method of transpalpebral tonometry is an alternative to Goldmann applanation, as it allows for IOP measurement through the eyelid without anesthesia or contact with the cornea, making it useful in clinical scenarios where corneal contact is contraindicated or difficult.
direct ophthalmoscope retinoscope fundoscopy instrument

A clinical photograph illustrating the proper technique for direct ophthalmoscopy in a community health or low-resource setting. A healthcare provider is shown in close proximity to an elderly female patient with deeply wrinkled skin and a pigmented fundus. The provider is demonstrating the correct 'flight path' for visualizing the optic nerve, positioned on the horizontal plane at approximately 15 degrees temporal to the patient's right eye. The clinician holds a direct ophthalmoscope (specifically an Arclight device) in his right hand, using his right eye to examine the patient's right eye. His left hand is placed gently on the patient's forehead to stabilize the head and elevate the upper eyelid if necessary. The educational focus is on the physical positioning, equipment handling, and anatomical approach required to bring the optic disc and retinal vessels into view during a funduscopic examination. Relevant clinical concepts include screening for cataract, glaucoma, and macular disease through direct visualization of the posterior segment.

This educational illustration provides a historical and conceptual representation of the human fundus as seen through an early ophthalmoscope. The image features a circular field depicting a stylized retinal fundus with an orange-toned background and a radiating network of retinal vasculature. The vessels, rendered in varying shades of reddish-brown and dark brown, originate from a central anatomical focal point—the optic disc—which is highlighted by a distinct bluish-green hue. The branching pattern demonstrates the distribution of primary retinal arteries and veins across the posterior pole. Overlaid onto the anatomical features is a green silhouette portrait of Hermann von Helmholtz, the inventor of the ophthalmoscope, symbolizing the intersection of physiological optics and clinical examination. This comparison chart-style graphic illustrates the fundamental topography of the healthy retina, including the optic nerve head and the vascular arcades, serving as a pedagogical tool for understanding the history of ophthalmology and the basic landmarks of fundoscopy.

A clinical photograph depicting a pediatric ophthalmic screening in a community outreach setting. The primary focus is a male healthcare provider, wearing a white lab coat, performing a direct ophthalmoscopy on a young male patient. The clinician is using a handheld direct ophthalmoscope to visualize the internal structures of the boy's eye, including the retina, optic disc, and macula, to screen for refractive errors or ocular pathologies. The background reveals a makeshift clinic environment featuring a table with medical documentation, a case containing trial lenses for vision correction, and hand sanitizer. Additional staff are visible in the background, including one individual performing a visual acuity or near-point test. This image illustrates concepts of public health ophthalmology, community-based vision screening, and the application of diagnostic medical devices in primary care or resource-limited settings.
mkdir -p /tmp/workspace/ophthalmology-instruments && ls /tmp/workspace/
indirect ophthalmoscope binocular BIO fundus examination instrument

This clinical photograph illustrates a pediatric ophthalmology examination for Retinopathy of Prematurity (ROP) screening. The clinician, identified as an ophthalmology fellow in a white lab coat, is utilizing a head-mounted indirect ophthalmoscope with an integrated light source to visualize the internal structures of the infant's eye. The neonatal patient is positioned supine on a padded surface, with the head stabilized by an assistant's hand. To facilitate a clear view of the fundus, the ophthalmologist is using an eyelid speculum to keep the infant's eye open while holding a condensing lens (not fully visible) over the eye. The image demonstrates the standard technique for binocular indirect ophthalmoscopy (BIO) in a neonatal setting, which is critical for identifying peripheral retinal vascular abnormalities such as ridge formation, extraretinal fibrovascular proliferation, or 'plus disease' in premature infants. This modality is the traditional gold standard for ROP screening, allowing for a wide-field, three-dimensional view of the retina.

This clinical photograph displays a binocular indirect ophthalmoscope (BIO), specifically a Vantage Plus model, modified with a protective breath shield for infection control. The device features a black adjustable head strap with a padded crown and a silver metallic forehead band. The central optical unit is mounted to the front. Attached to this assembly is a large, clear, flexible plastic breath shield that extends downward and laterally to provide a physical barrier between the ophthalmologist and the patient. A hand is shown supporting the transparent shield to demonstrate its flexibility and wide coverage area. This modification is used in ophthalmology to minimize the risk of respiratory droplet transmission, particularly during close-proximity examinations required for retinal evaluation. The setup represents a standard preventative measure used in clinical settings to maintain hygiene and safety during diagnostic procedures.

A clinical photograph illustrating the use of a Volk iNview retinal imager, a portable smartphone-based fundus camera, in a clinical setting. The image shows an operator holding a black, cylindrical optical tube attached to a smartphone. To ensure stability and focus, the operator has positioned the large distal end of the lens tube against the patient's forehead, near the superior orbital rim. This stabilization technique allows for fixed-distance (160 mm) imaging of the retina, similar to the optical principles of binocular indirect ophthalmoscopy (BIO). The patient is seated in an examination chair, and the device is aligned with her left eye for fundus photography. This equipment represents a portable solution for ophthalmic screening in primary care, emergency departments, or global health settings where stationary slit-lamp-mounted fundus cameras are unavailable. The image demonstrates the interface between medical technology and patient positioning for non-mydriatic or portable retinal imaging.
postgraduate ophthalmology practical exam instruments list slit lamp tonometer retinoscope keratometer
https://en.wikipedia.org/wiki/List_of_instruments_used_in_op…
keratometer autorefractor corneal topography instrument

A multi-paneled corneal topography display comparing preoperative (left) and postoperative (right) states of a left eye (OS). Each state includes four distinct maps: Corneal Thickness (pachymetry), Tangential Anterior (curvature), Anterior Elevation, and Posterior Elevation. The preoperative maps show significant ectasia, characterized by irregular thinning and asymmetric areas of high elevation (warm reds/oranges) in an arcuate or spiral configuration. Postoperatively, the Tangential Anterior map demonstrates a more circular, concentric color distribution, and the elevation maps show a shift toward cooler colors (blues/greens), indicating surgical flattening and regularization of the corneal surface. Numerical values representing corneal thickness and dioptric power are overlaid on the topography. Corresponding color-coded scales are provided for each modality. This diagnostic imaging comparison illustrates the anatomical and refractive changes following a corneal procedure, likely aimed at stabilizing or correcting keratoconus or a similar ectatic disorder.

This ophthalmic diagnostic image displays a comparison between the right eye (OD) and left eye (OS) using corneal topography and endothelial cell analysis. Panel A shows Tangential Anterior corneal topography maps. The OD topography demonstrates a relatively regular, prolate corneal surface with central power values between 39.0 and 44.0 Diopters (yellow-green spectrum). In contrast, the OS topography reveals significant irregularity and steepening, characterized by a disorganized color gradient and highly variable dioptric values, indicating severe corneal distortion. Panel B presents specular microscopy for endothelial cell quality detection. The OD image displays a healthy, well-defined hexagonal endothelial mosaic with a cell density (CD) of 2704 cells/mm² and central corneal thickness (CCT) of 524 µm. The OS image shows a complete loss of cellular detail and severe opacity, with no quantitative data (NUM, CD, AVG) obtainable. This visual evidence suggests profound corneal pathology in the left eye, consistent with severe corneal edema or endophthalmitis, while the right eye maintains normal physiological parameters.

This composite diagnostic image displays five axial corneal topography maps, labeled C0, C1, C2, C3, and E4, obtained using a Nidek OPD Scan. Each map represents a color-coded axial curvature scale (in Diopters) to evaluate corneal power and shape regularity, often utilized in diagnosing Dry Eye Disease (DED) or keratoconus. Images C0 through C3 demonstrate relatively organized patterns: C0 shows a round/oval steep central area (warmer colors like yellow/orange); C1 and C2 exhibit symmetric 'bow tie' astigmatic patterns; and C3 shows a moderate central steepness with organized peripheral flattening (cooler blue tones). In contrast, image E4 represents severe surface irregularity (Grade 4). It displays a highly asymmetric and chaotic distribution of steepness (indicated by intense red/orange patches) and flattening (dark blue), signifying significant corneal surface distortion and high-order aberrations. These maps serve as educational visual aids for clinical grading of corneal surface health and regularity in response to therapeutic interventions.
cat << 'PYEOF' > /tmp/workspace/ophthalmology-instruments/build_pdf.py import requests import io import os from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import cm, mm from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle, PageBreak, HRFlowable, KeepTogether) from reportlab.pdfgen import canvas from reportlab.platypus.flowables import Flowable from PIL import Image as PILImage import urllib.request import urllib.error import ssl # Fix SSL for image downloads ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE OUTPUT_PATH = "/tmp/workspace/ophthalmology-instruments/Ophthalmology_Instruments_PG_Exam.pdf" # ───────────────────────────────────────────── # INSTRUMENT DATABASE (comprehensive PG exam) # ───────────────────────────────────────────── INSTRUMENTS = [ # ── EXAMINATION INSTRUMENTS ── { "category": "Examination & Diagnostic Instruments", "name": "Slit Lamp Biomicroscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Slit_lamp.jpg/320px-Slit_lamp.jpg", "parts": [ "Illumination system (slit beam source, condenser, slit diaphragm, filters)", "Observation system (binocular microscope with 10x eyepieces, 0.6x–4x objectives)", "Joystick for XYZ movement", "Chinrest and forehead rest", "Magnification changer (6x–40x range)", ], "uses": [ "Anterior segment examination: eyelids, conjunctiva, cornea, iris, lens", "Posterior segment: with +78D/+90D Volk lens or three-mirror contact lens", "Gonioscopy (with gonioscopic lens)", "Applanation tonometry (Goldmann attachment)", "Measurement of lesion size using ocular micrometer", "Fundus examination, vitreous evaluation", ], "exam_points": [ "Inventor: Allvar Gullstrand (1911); later improved by Goldmann", "Illumination modes: diffuse, direct focal, retroillumination, specular reflection, sclerotic scatter, indirect proximal", "With +90D lens: 7x-8x magnification of fundus, inverted/reversed image", "Cobalt blue filter used with fluorescein to highlight corneal defects", "Standard magnification for anterior segment: 16x–25x", ], }, { "category": "Examination & Diagnostic Instruments", "name": "Direct Ophthalmoscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Ophthalmoscope.jpg/240px-Ophthalmoscope.jpg", "parts": [ "Battery handle (with rheostat for light intensity)", "Head: aperture wheel (large, small, fixation, slit, red-free/green beam)", "Lens wheel (+20 to -20 diopters in steps)", "Mirror with peephole", ], "uses": [ "Monocular examination of fundus (optic disc, macula, retinal vessels)", "Examination of anterior segment (red reflex, lens, vitreous)", "Objective refraction estimation", ], "exam_points": [ "Invented by Hermann von Helmholtz (1851)", "Magnification: ~15x (emmetropic patient & examiner)", "Image: erect (upright), virtual, magnified", "Working distance: ~2.5–3 cm from patient's eye", "Lens wheel compensates for refractive errors of patient & examiner", "Field of view: ~5° (small/narrow)", "Add +2D for every 1 cm increase in working distance", "Red-free (green) beam: enhances nerve fiber layer, hemorrhages, vessels", ], }, { "category": "Examination & Diagnostic Instruments", "name": "Binocular Indirect Ophthalmoscope (BIO)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Indirect_ophthalmoscope.jpg/320px-Indirect_ophthalmoscope.jpg", "parts": [ "Head-mounted unit with transformer/battery pack", "Binocular viewing eyepieces (3.5x magnification)", "Bright halogen/LED light source (coaxial)", "Condensing lens (+20D, +28D, +30D held by examiner)", "Beam splitter for teaching mirror", ], "uses": [ "Wide-field fundus examination (retinal periphery, vitreous)", "Retinal detachment evaluation and surgical planning", "ROP (retinopathy of prematurity) screening", "Scleral indentation (with depressor)", "Laser delivery for retinal photocoagulation", ], "exam_points": [ "Invented by Charles Schepens (1947) — father of retinal surgery", "Magnification with +20D lens: ~3x", "Magnification with +28D lens: ~2x", "Image: inverted (upside-down), real, aerial image formed between lens and eye", "Field of view: ~40–50° (much wider than direct)", "Working distance: ~50 cm from patient", "+20D lens preferred for higher magnification; +28D for wider field", "Binocular viewing provides stereopsis (3D depth perception)", ], }, { "category": "Examination & Diagnostic Instruments", "name": "Retinoscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/24/Retinoscope.jpg/200px-Retinoscope.jpg", "parts": [ "Handle with battery/power source", "Plane or streak mirror head with peephole", "Streak type: rotating sleeve for changing streak direction", "Condensing lens (built-in +2D lens in some models)", ], "uses": [ "Objective determination of refractive error (without patient cooperation)", "Ideal for children, mentally challenged, aphasia patients", "Detecting irregular astigmatism (scissors reflex)", "Media assessment (corneal/lenticular opacities cause irregular reflexes)", ], "exam_points": [ "Types: Plane mirror (spot) retinoscope; Streak retinoscope (Copeland) — most common", "Working distance: 67 cm (adds +1.5D artifact) or 1 m (adds +1D)", "'With' movement: hypermetropia, high myopia beyond far point; neutralize with plus lens", "'Against' movement: myopia within far point; neutralize with minus lens", "Reversal point: no movement seen — refraction equals working distance correction", "Dull/dim reflex: dense opacity or high ametropia", "Scissors movement: irregular astigmatism or keratoconus", "Dark crescent at pupil edge: early keratoconus", ], }, { "category": "Tonometry", "name": "Goldmann Applanation Tonometer (GAT)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Goldmann_applanation_tonometer.jpg/280px-Goldmann_applanation_tonometer.jpg", "parts": [ "Biprism (split prism with two semicircles)", "Spring-loaded measuring drum (calibrated 0–80 mmHg)", "Blue filter holder for fluorescein", "Slit-lamp mounting arm", ], "uses": [ "Measurement of intraocular pressure (IOP) — gold standard", "Screening and monitoring of glaucoma", ], "exam_points": [ "Based on Imbert-Fick principle: P = F/A (pressure = force / area)", "Flattening area: 3.06 mm diameter (minimizes surface tension & tear film effects)", "Fluorescein + cobalt blue light: two semicircular mires; end point = inner edges just touching", "Reading × 10 = IOP in mmHg (scale 0–8, each unit = 10 mmHg)", "Normal IOP: 10–21 mmHg", "Errors: thick cornea → overestimates; thin cornea → underestimates", "Requires topical anesthesia + fluorescein", "Contraindications: corneal abrasion, active infection", ], }, { "category": "Tonometry", "name": "Schiotz Tonometer", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Schiotz_tonometer.jpg/240px-Schiotz_tonometer.jpg", "parts": [ "Footplate (with central aperture 3mm)", "Plunger (metal rod weighing 5.5g base)", "Scale (0–20 units)", "Additional weights: 7.5g, 10g, 15g", "Test block for calibration (scale should read 0 on test block)", ], "uses": [ "Measurement of IOP (impression/indentation tonometry)", "Useful where slit lamp unavailable (bedside, theater)", ], "exam_points": [ "Type: Impression (indentation) tonometer", "Principle: greater indentation = lower IOP; scale reading converted via Friedenwald tables", "Patient lies supine; footplate placed on anesthetized cornea", "High reading on scale = soft eye (low IOP); low reading = hard eye (high IOP)", "Conversion: use Friedenwald nomogram", "Errors: rigid sclera/cornea → falsely low reading (pseudofacility)", "Ocular rigidity affects readings (less accurate than GAT)", "Sterilize by boiling or 70% alcohol; no autoclaving", ], }, { "category": "Tonometry", "name": "Non-Contact Tonometer (Air-Puff Tonometer)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Non_contact_tonometer.jpg/280px-Non_contact_tonometer.jpg", "parts": [ "Air delivery nozzle", "Photodetector for corneal deformation", "Electronic display", "Automated alignment system", ], "uses": [ "Screening for elevated IOP (no contact with cornea)", "Pediatric patients and infection control settings", "Mass screening programs", ], "exam_points": [ "Principle: air puff flattens 3.6mm corneal diameter; photodetector detects moment of applanation", "No anesthesia required; no fluorescein needed", "Least accurate of all tonometers", "Over-reads high pressures, under-reads in very high IOP", "CCT (central corneal thickness) also affects readings", "Not suitable for irregular corneas", ], }, { "category": "Gonioscopy", "name": "Goldmann Three-Mirror Contact Lens", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Goldman_3_mirror.jpg/240px-Goldman_3_mirror.jpg", "parts": [ "Central lens (for posterior pole view — 30° from axis)", "Equatorial mirror (rectangle, 67°): peripheral retina and vitreous", "Peripheral retinal mirror (truncated oval, 75°): peripheral retina/pars plana", "Gonioscopy mirror (smallest, dome-shaped, 59°): angle of anterior chamber", ], "uses": [ "Gonioscopy (examination of drainage angle)", "Fundus examination with slit lamp", "Peripheral retina, pars plana, vitreous base examination", "Laser procedures (argon laser trabeculoplasty, pan-retinal photocoagulation)", ], "exam_points": [ "Requires coupling gel (methylcellulose 2.5%)", "Image is inverted and mirror-reversed", "Angle mirror at bottom → examiner looks at top of angle structure", "Allows evaluation of all 360° by rotating lens", "For gonioscopy: tilt lamp forward 14–15° to view angle mirror", "Volk gonioscopy lens: non-contact alternative", ], }, { "category": "Gonioscopy", "name": "Zeiss Four-Mirror Gonioscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/Zeiss_4_mirror.jpg/240px-Zeiss_4_mirror.jpg", "parts": [ "Four mirrors at 64° each", "Smaller diameter than Goldmann lens", "No coupling gel required (uses tears)", ], "uses": [ "Gonioscopy (4 quadrants visible with 90° rotation)", "Dynamic indentation gonioscopy to differentiate appositional vs synechial closure", "Preferred for narrow-angle/angle-closure evaluation", ], "exam_points": [ "Direct gonioscopy type (image erect, non-reversed)", "No coupling agent needed — advantage over Goldmann", "Indentation (compression) gonioscopy: applying pressure with lens pushes aqueous into angle, opening appositional closure", "Cannot be used for laser procedures", "Less stable than Goldmann during examination", ], }, { "category": "Refraction Instruments", "name": "Trial Lens Box (Refraction Set)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Trial_lens_set.jpg/300px-Trial_lens_set.jpg", "parts": [ "Spherical lenses (+0.12D to +20D; -0.12D to -20D)", "Cylindrical lenses (+0.12D to +6D; -0.12D to -6D)", "Prisms (1Δ to 12Δ) and prism bars", "Occluder, pinhole, Maddox rod, red/green lenses", "Trial frame (adjustable PD)", ], "uses": [ "Subjective refraction", "Prescribing corrective spectacles", "Orthoptic tests (Maddox rod, prism cover test)", "Low vision aids assessment", ], "exam_points": [ "Spheres in front of cylinders in trial frame", "BCVA: best corrected visual acuity achieved with optimal lens combination", "Fogging technique: plus sphere fogged to relax accommodation before refinement", "Jackson Cross Cylinder (JCC): +0.25/-0.50D or +0.50/-1.00D; checks axis and power of cylinder", ], }, { "category": "Refraction Instruments", "name": "Keratometer (Ophthalmometer)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Ophthalmometer.jpg/280px-Ophthalmometer.jpg", "parts": [ "Mire target (2 or 4 luminous targets on instrument)", "Telescope/microscope for observing reflections", "Measurement drums (for horizontal and vertical meridians)", "Chin and forehead rest", ], "uses": [ "Measurement of corneal curvature (keratometry values K1 and K2)", "Diagnosis and quantification of corneal astigmatism", "Contact lens fitting (base curve selection)", "Keratoconus screening, IOL biometry calculation", ], "exam_points": [ "Types: Javal-Schiötz (variable doubling, fixed object size) and Bausch & Lomb (fixed doubling, variable object size)", "Measures central 3–4 mm zone of cornea only", "Normal keratometry: 42–44 diopters; difference >1D = significant astigmatism", "Radius of curvature (r) = n-1/D (n=1.3375 for cornea by convention)", "Irregular mires: irregular astigmatism, surface irregularity", "Cannot measure very steep (>52D) or flat (<36D) corneas reliably", ], }, { "category": "Refraction Instruments", "name": "Lensometer (Lensmeter / Focimeter)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Lensometer.jpg/240px-Lensometer.jpg", "parts": [ "Eyepiece (telescope)", "Power drum (sphere and cylinder dials)", "Axis wheel", "Lens stop (supports spectacle lens)", "Illuminated target (spokes/dots pattern)", ], "uses": [ "Measuring power of spectacle lenses (sphere, cylinder, axis)", "Checking prismatic power and base direction", "Centration of lenses (optical center marking)", ], "exam_points": [ "Also called vertometer or focimeter in UK", "Measures back vertex power of lens", "Target: crosslines/spokes — spherical lens: all lines clear simultaneously; astigmatic: first one then other set of lines", "Reading in minus-cylinder or plus-cylinder form as required", "Prism measured in prism diopters: 1Δ = deviation of 1 cm at 1 m", ], }, { "category": "Refraction Instruments", "name": "Phoropter (Refractor Head)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Phoropter.jpg/280px-Phoropter.jpg", "parts": [ "Two large rotating lens discs (right and left eye)", "Sphere power range: +16.75D to -19D", "Cylinder power range: 0 to -6D (or +6D)", "Built-in accessories: JCC, Maddox rod, prisms, occluder, pinhole", "Interpupillary distance adjustment", ], "uses": [ "Subjective refraction (monocular and binocular)", "Accommodation, convergence and binocular vision tests", "Phoria and strabismus assessment", ], "exam_points": [ "More convenient than trial frame; faster refraction", "Does not accurately represent spectacle plane distance (vertex distance varies)", "May not be suitable for prescribing over 5D — vertex distance correction needed", "Automated/computerised phoropters now available", ], }, { "category": "Refraction Instruments", "name": "Jackson Cross Cylinder (JCC)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3b/Cross_cylinder.jpg/240px-Cross_cylinder.jpg", "parts": [ "Combined lens with perpendicular axes: +0.25/-0.50D or +0.50/-1.00D", "Handle at 45° between axes", "Red dot: minus cylinder axis; White dot: plus cylinder axis", ], "uses": [ "Refinement of astigmatism axis and power in subjective refraction", "Part of trial lens set or phoropter", ], "exam_points": [ "Flip test: lens flipped to two positions; patient chooses clearer position", "Axis check: handle at axis of working cylinder — flip to find axis", "Power check: red dot at axis — flip to find power", "Duochrome test complements JCC for spherical endpoint", "Higher power JCC for larger cylinders", ], }, { "category": "Visual Acuity Assessment", "name": "Snellen Chart", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Snellen_chart.svg/200px-Snellen_chart.svg.png", "parts": [ "Chart with letters/numbers/E-chart in decreasing sizes", "Standard: tested at 6 m (20 ft)", "Illuminated or printed format", ], "uses": [ "Measurement of distance visual acuity (VA)", "Recording BCVA and unaided vision", ], "exam_points": [ "Each letter subtends 5' arc at stated distance; limbs subtend 1'", "6/6 = patient reads at 6m what normal eye reads at 6m", "6/60: CF (count fingers) if cannot read even top letter", "Below that: HM (hand movements), PL (perception of light), NPL", "LogMAR chart: ETDRS chart more precise for research/trials", "Jaeger chart: for near vision (J1 = ~6/6 near)", ], }, { "category": "Visual Acuity Assessment", "name": "Pinhole", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/58/Pinhole_occluder.jpg/200px-Pinhole_occluder.jpg", "parts": [ "Opaque disc with one or multiple 1–1.5 mm holes", "Used in trial frame or held in front of eye", ], "uses": [ "Differentiates refractive from non-refractive (organic) cause of poor vision", "Screens for correctable vision impairment", ], "exam_points": [ "Eliminates the effect of refractive error by limiting rays to paraxial", "Improvement with pinhole → refractive error or media opacity", "No improvement → amblyopia, macular or optic nerve pathology", "Paradoxical worsening with pinhole: macular disease, posterior subcapsular cataract (diffraction)", ], }, { "category": "Visual Field Testing", "name": "Goldman Perimeter", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Goldmann_perimeter.jpg/280px-Goldmann_perimeter.jpg", "parts": [ "Hemispheric bowl (33 cm radius)", "Moveable fixation device", "Variable-size targets (I–V) and light intensities (1–4, a–e)", "Plotting chart", ], "uses": [ "Manual kinetic perimetry (moving target from periphery inward)", "Plotting isopters (lines connecting points of equal sensitivity)", "Mapping scotomas and field defects", ], "exam_points": [ "Kinetic perimetry: target moved from non-seeing to seeing", "Static perimetry: stationary targets of varying intensity", "Standard target: III4e for most patients", "I4e detects subtle field loss; V4e for severely constricted fields", "Inferior nasal step: classic early glaucoma defect", "Being replaced by automated perimetry (Humphrey) for most uses", ], }, { "category": "Visual Field Testing", "name": "Humphrey Visual Field Analyser", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Humphrey_Visual_Field_Analyzer.jpg/280px-Humphrey_Visual_Field_Analyzer.jpg", "parts": [ "Automated static perimeter with bowl", "Stimulus projection system", "Computer with algorithm (SITA-standard, SITA-fast, full-threshold)", "Foveal sensitivity measurement", ], "uses": [ "Automated static perimetry for glaucoma monitoring", "Neurological field defects (hemianopia, quadrantanopia)", "Monitoring disease progression", ], "exam_points": [ "SITA: Swedish Interactive Thresholding Algorithm", "24-2 program: tests 54 points within central 24° (standard for glaucoma)", "30-2: 76 points within 30°", "Reliability indices: fixation losses, false positives, false negatives", "MD (Mean Deviation) and PSD (Pattern Standard Deviation) key indices", "GHT (Glaucoma Hemifield Test): compares superior/inferior sectors", ], }, { "category": "Strabismus Assessment", "name": "Maddox Rod", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Maddox_rod.jpg/240px-Maddox_rod.jpg", "parts": [ "Series of parallel high-powered red cylindrical lenses", "Mounted in trial frame holder", "Usually red in color", ], "uses": [ "Detection of heterophoria (latent squint)", "Measurement of cyclotorsion (oblique muscle palsy)", "Dissociation of binocular vision for phoria testing", ], "exam_points": [ "Point source of light seen as perpendicular line through rod", "Esophoria: line to same side as rod; exophoria: line to opposite side", "Two Maddox rods (double): red and white — cyclodeviations", "Used at 6 m for distance and 33 cm for near assessment", "Low sensitivity for small deviations", ], }, { "category": "Strabismus Assessment", "name": "Prism Bar and Prism Set", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Prism_bar.jpg/240px-Prism_bar.jpg", "parts": [ "Horizontal prism bar (1–40 prism diopters)", "Vertical prism bar", "Loose prisms in trial set", ], "uses": [ "Measurement of angle of squint (prism cover test)", "Diagnosis and measurement of phorias and tropias", "Prism adaptation test", ], "exam_points": [ "1 prism diopter = 0.57°", "Base-out: for exodeviation measurement; base-in: for esodeviation", "Base-down for hyperdeviation; base-up for hypodeviation", "Prism cover test (PCT): gold standard for measuring all deviations", "Prism held in front of deviating eye (apex toward direction of deviation)", ], }, { "category": "Cornea & Anterior Segment", "name": "Placido's Disc (Keratoscope)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/33/Placido_disk.jpg/200px-Placido_disk.jpg", "parts": [ "Concentric black and white rings on flat disc", "Central aperture for observation", "Handle", ], "uses": [ "Qualitative assessment of corneal surface regularity", "Screening for irregular astigmatism, keratoconus, pterygium", ], "exam_points": [ "Invented by Antonio Placido (1880)", "Regular round rings: normal cornea", "Egg-shaped distortion: regular astigmatism", "Irregular distorted rings: keratoconus, scarring, surface irregularity", "Modern version: computerised videokeratography/corneal topographer", "Only qualitative — keratometer gives quantitative values", ], }, { "category": "Cornea & Anterior Segment", "name": "Specular Microscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Specular_microscopy.jpg/280px-Specular_microscopy.jpg", "parts": [ "Specular reflection optics", "Camera system with high magnification", "Automated analysis software", ], "uses": [ "Imaging corneal endothelial cells (endothelial cell density - ECD)", "Pre-operative assessment before corneal surgery / penetrating keratoplasty", "Monitoring Fuchs' dystrophy, post-surgical endothelial loss", ], "exam_points": [ "Normal ECD: 2000–3000 cells/mm²; <500 cells/mm² → corneal decompensation risk", "Measures: cell density (cells/mm²), coefficient of variation (CV), hexagonality (%)", "Polymegethism: variation in cell size; Pleomorphism: variation in cell shape", "Critical before IOL implantation in borderline corneas", ], }, { "category": "Lacrimal System", "name": "Lacrimal Syringe & Cannula", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Lacrimal_cannula.jpg/240px-Lacrimal_cannula.jpg", "parts": [ "2 mL syringe", "Lacrimal cannula (blunt-tipped, angled, 23G)", ], "uses": [ "Lacrimal syringing and probing (to assess patency of NLD)", "Irrigation of lacrimal system (dacryocystitis management)", ], "exam_points": [ "Upper and lower puncta can be dilated with punctum dilator before cannulation", "Regurgitation on pressure over lacrimal sac → mucocele / dacryocystitis", "Hard-stop vs. soft-stop on probing: hard-stop = patent; soft-stop = blocked at NLD", "Jones dye test I & II to assess functional and anatomical NLD patency", ], }, { "category": "Lacrimal System", "name": "Bowman's Probe", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/12/Bowmans_probe.jpg/240px-Bowmans_probe.jpg", "parts": [ "Double-ended malleable metallic probe (silver or steel)", "Sizes 0–8 (0 = thinnest, 8 = thickest)", ], "uses": [ "Probing of nasolacrimal duct in congenital NLD obstruction", "Dilation of nasolacrimal duct", ], "exam_points": [ "Procedure usually performed under GA in children < 6 months if epiphora persists", "Success rate: ~90% if done before 13 months", "Probe passed vertically then horizontally into lacrimal canal, then angled into nose", "Hard-stop felt at lacrimal bone = correct positioning", ], }, { "category": "Surgical Instruments", "name": "Eye Speculum (Universal)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Eye_speculum.jpg/240px-Eye_speculum.jpg", "parts": [ "Two blades (one or both spring-loaded)", "Wire or solid blade types", "Adjustable screw for tension", ], "uses": [ "Keeping eyelids open during ocular surgery", "Examination under anaesthesia (EUA)", ], "exam_points": [ "Universal speculum: cannot keep eyelashes out of field", "Barraquer speculum: solid blades, preferred in corneal/cataract surgery", "Alfonso speculum: used in LASIK flap creation", "Lid speculum chosen based on procedure type and orbital anatomy", ], }, { "category": "Surgical Instruments", "name": "Chalazion Forceps (Chalazion Clamp)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Chalazion_forceps.jpg/200px-Chalazion_forceps.jpg", "parts": [ "Two arms: one with round discoid plate, one with oval ring", "Screw mechanism to tighten clamp", ], "uses": [ "Chalazion incision and curettage (I&C)", "Meibomian cyst excision", ], "exam_points": [ "Discoid plate placed on conjunctival surface; ring on skin surface", "Provides hemostasis and eversion of lid for conjunctival incision", "Vertical incision on tarsal conjunctival surface", "Horizontal incision if done via skin (rare)", ], }, { "category": "Surgical Instruments", "name": "Castroviejo Calipers", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Castroviejo_calipers.jpg/240px-Castroviejo_calipers.jpg", "parts": [ "Two pointed metallic tips", "Sliding rule with scale in mm", "Spring mechanism", ], "uses": [ "Measuring distances during ocular surgery", "Corneal diameter (white-to-white), limbal marking", "Toric IOL axis marking", "Strabismus muscle recession/resection measurements", ], "exam_points": [ "Available in various sizes (standard: 0–20 mm)", "Must be zeroed before use", "Strabismus caliper: specifically for muscle surgery measurements", ], }, { "category": "Surgical Instruments", "name": "Muscle Hook (Squint Hook / Strabismus Hook)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Squint_hook.jpg/240px-Squint_hook.jpg", "parts": [ "Long handle with curved metallic hook at end", "Types: sharp-pointed, blunt-tipped, Green's hook", ], "uses": [ "Isolating and holding extraocular muscles during squint surgery", "Muscle recession and resection procedures", ], "exam_points": [ "Green's hook: small, fine-tipped; used for oblique muscles", "Von Graefe's hook: larger; for rectus muscles", "Passed behind muscle under Tenon's capsule", "Damage can cause anterior segment ischemia if >2 recti cut simultaneously", ], }, { "category": "Diagnostic Lenses (Slit-Lamp Accessories)", "name": "Volk +90D / +78D Lens", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Volk_90D_lens.jpg/200px-Volk_90D_lens.jpg", "parts": [ "Aspheric handheld condensing lens", "Antireflective coating", "+90D (wider field) or +78D (higher magnification)", ], "uses": [ "Fundus biomicroscopy through slit lamp (non-contact)", "Optic nerve, macula, posterior pole evaluation", ], "exam_points": [ "Non-contact method (unlike three-mirror or Mainster lens)", "+78D: ~7.2x magnification; 48° field", "+90D: ~5.8x magnification; 60° field (wider)", "Image inverted and reversed, real", "Must correct for inversion mentally", "+60D SuperField: widest field, ~76°", ], }, { "category": "Diagnostic Lenses (Slit-Lamp Accessories)", "name": "Mainster / Panfundoscope Lens", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/Panfundoscope.jpg/240px-Panfundoscope.jpg", "parts": [ "Contact lens with built-in optical system", "Coupling gel required", ], "uses": [ "Widefield fundus examination and laser photocoagulation", "PRP (panretinal photocoagulation), laser for retinal breaks", ], "exam_points": [ "Mainster standard: 90° FOV; high magnification for posterior pole", "Mainster widefield: 125° FOV; for periphery and PRP", "Mainster ultra-widefield: 165° FOV", "Contact lens — provides sharper images than non-contact lenses during laser", ], }, { "category": "Ophthalmic Imaging", "name": "Fundus Camera", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Fundus_camera.jpg/280px-Fundus_camera.jpg", "parts": [ "Optical system (objective lens, relay lenses)", "Flash illumination system", "Digital camera sensor (CCD/CMOS)", "Fixation target and chin rest", ], "uses": [ "Fundus photography (disc, macula, vessels, periphery)", "Documentation of retinal pathology (DR, glaucoma, AMD)", "Fluorescein angiography (FA) and indocyanine green angiography (ICGA)", ], "exam_points": [ "Standard field: 30° to 45° (50° = wide-angle)", "Mydriasis improves image quality (>6 mm pupil ideal)", "Non-mydriatic cameras: 5mm pupil acceptable", "FA uses excitation filter (490nm), barrier filter (530nm)", "Heidelberg Spectralis: combined fundus camera + OCT", ], }, { "category": "Ophthalmic Imaging", "name": "Optical Coherence Tomography (OCT)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/OCT_scanner.jpg/280px-OCT_scanner.jpg", "parts": [ "Near-infrared laser light source (840–1060nm)", "Interferometer (Michelson type)", "Beam splitter, reference mirror", "Detector and computer", ], "uses": [ "Cross-sectional imaging of retina, choroid, optic nerve", "Macular thickness mapping (AMD, DME, macular holes)", "RNFL (retinal nerve fiber layer) thickness for glaucoma", "Corneal and anterior segment OCT (AS-OCT)", ], "exam_points": [ "Based on low-coherence interferometry (analogous to B-scan ultrasound using light)", "Axial resolution: 3–10 microns", "TD-OCT (time-domain): older; SD-OCT (spectral-domain): current standard", "SS-OCT (swept-source): deeper penetration, better choroidal imaging", "Macular OCT: central subfield thickness (CST) normal ~250 μm", "RNFL: average normal ~100 μm; inferior > superior > nasal > temporal (ISNT rule)", ], }, { "category": "Ophthalmic Imaging", "name": "B-Scan Ultrasonography", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/B-scan_ultrasound.jpg/280px-B-scan_ultrasound.jpg", "parts": [ "10 MHz transducer probe", "Display unit", "Coupling gel", ], "uses": [ "Evaluation when media opacity prevents fundus view (dense cataract, vitreous hemorrhage)", "Retinal detachment, vitreous hemorrhage, choroidal detachment", "Intraocular tumors (melanoma, retinoblastoma)", "Axial length estimation (A-scan)", ], "exam_points": [ "B-scan: 2D cross-sectional image; A-scan: 1D amplitude", "10 MHz for posterior segment; 20 MHz for anterior segment (UBM)", "Retinal detachment: high-reflective membrane attached to disc/ora", "Vitreous hemorrhage: mobile, low-reflective opacities", "Choroidal melanoma: dome/collar-button shape, low internal reflectivity, acoustic hollow, choroidal excavation", ], }, { "category": "Ophthalmic Imaging", "name": "A-Scan (Biometry) / IOL Master", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/IOL_master.jpg/280px-IOL_master.jpg", "parts": [ "A-scan: 10 MHz transducer; IOL Master: partial coherence interferometry", "Axial length measurement system", "K-reading integration", ], "uses": [ "Pre-operative IOL power calculation (cataract surgery)", "Axial length measurement for myopia monitoring", ], "exam_points": [ "IOL Master: non-contact; uses partial coherence interferometry (PCI) — gold standard", "A-scan: contact or immersion; immersion more accurate than contact (no corneal indentation)", "Formulas: SRK/T (axial length >26mm); Holladay (24-26mm); Hoffer-Q (<22mm); Barrett Universal II (universal)", "Normal axial length: 22-24 mm", "Axial length: most important factor in IOL calculation (1mm error → ~2.7D IOL error)", ], }, ] print(f"Total instruments: {len(INSTRUMENTS)}") print("Instruments data loaded successfully") PYEOF python3 /tmp/workspace/ophthalmology-instruments/build_pdf.py
cat << 'PYEOF' > /tmp/workspace/ophthalmology-instruments/generate_pdf.py import requests import io import os import sys from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import cm, mm from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle, PageBreak, HRFlowable, KeepTogether) from reportlab.pdfgen import canvas from PIL import Image as PILImage import urllib.request import urllib.error import ssl import traceback ssl_ctx = ssl.create_default_context() ssl_ctx.check_hostname = False ssl_ctx.verify_mode = ssl.CERT_NONE OUTPUT_PATH = "/tmp/workspace/ophthalmology-instruments/Ophthalmology_Instruments_PG_Exam.pdf" IMG_CACHE = "/tmp/workspace/ophthalmology-instruments/img_cache" os.makedirs(IMG_CACHE, exist_ok=True) # ── Colour palette ── DARK_BLUE = colors.HexColor("#1a3a5c") MEDIUM_BLUE = colors.HexColor("#2563a8") LIGHT_BLUE = colors.HexColor("#dbeafe") ACCENT_ORANGE = colors.HexColor("#d97706") ACCENT_GREEN = colors.HexColor("#059669") LIGHT_GREY = colors.HexColor("#f3f4f6") MID_GREY = colors.HexColor("#6b7280") WHITE = colors.white BLACK = colors.black # ── Page setup ── PAGE_W, PAGE_H = A4 MARGIN = 2 * cm # ── Styles ── styles = getSampleStyleSheet() def style(name, **kwargs): return ParagraphStyle(name, **kwargs) TITLE_STYLE = style("Title", fontName="Helvetica-Bold", fontSize=28, textColor=WHITE, alignment=TA_CENTER, spaceAfter=0, spaceBefore=0) SUBTITLE_STYLE = style("Subtitle", fontName="Helvetica", fontSize=14, textColor=LIGHT_BLUE, alignment=TA_CENTER, spaceAfter=6) CATEGORY_STYLE = style("Category", fontName="Helvetica-Bold", fontSize=13, textColor=WHITE, alignment=TA_CENTER, spaceAfter=0, spaceBefore=0) INSTR_NAME_STYLE = style("InstrName", fontName="Helvetica-Bold", fontSize=16, textColor=DARK_BLUE, spaceAfter=4, spaceBefore=4) SECTION_LABEL_STYLE = style("SectionLabel", fontName="Helvetica-Bold", fontSize=9, textColor=WHITE, spaceAfter=0) BODY_STYLE = style("Body", fontName="Helvetica", fontSize=9.5, textColor=BLACK, spaceAfter=2, spaceBefore=1, leading=13) BULLET_STYLE = style("Bullet", fontName="Helvetica", fontSize=9, textColor=colors.HexColor("#1f2937"), spaceAfter=1.5, spaceBefore=0, leading=12, leftIndent=8, bulletIndent=0) FOOTER_STYLE = style("Footer", fontName="Helvetica", fontSize=8, textColor=MID_GREY, alignment=TA_CENTER) TOC_HEAD_STYLE = style("TocHead", fontName="Helvetica-Bold", fontSize=12, textColor=DARK_BLUE, spaceAfter=4) TOC_ITEM_STYLE = style("TocItem", fontName="Helvetica", fontSize=10, textColor=BLACK, spaceAfter=3, leading=14) # ────────────────────────────── # Image downloader # ────────────────────────────── HEADERS = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 Chrome/120 Safari/537.36"} def fetch_image(url, max_w, max_h): """Download and return a ReportLab Image object scaled to fit max_w x max_h.""" if not url: return None cache_key = url.split("/")[-1].replace("%", "_") cache_path = os.path.join(IMG_CACHE, cache_key) if not os.path.exists(cache_path): try: r = requests.get(url, headers=HEADERS, timeout=12, verify=False) if r.status_code == 200: with open(cache_path, "wb") as f: f.write(r.content) else: return None except Exception as e: print(f" [IMG FAIL] {url} → {e}") return None try: with PILImage.open(cache_path) as img: w, h = img.size scale = min(max_w / w, max_h / h) return Image(cache_path, width=w * scale, height=h * scale) except Exception as e: print(f" [IMG RENDER FAIL] {cache_path} → {e}") return None # ────────────────────────────── # Page header/footer canvas callback # ────────────────────────────── def on_page(canvas_obj, doc): pn = canvas_obj.getPageNumber() if pn == 1: return canvas_obj.saveState() # Header bar canvas_obj.setFillColor(DARK_BLUE) canvas_obj.rect(0, PAGE_H - 1.2*cm, PAGE_W, 1.2*cm, fill=1, stroke=0) canvas_obj.setFillColor(WHITE) canvas_obj.setFont("Helvetica-Bold", 8) canvas_obj.drawString(MARGIN, PAGE_H - 0.8*cm, "Ophthalmic Instruments — PG Practical Exam Reference") canvas_obj.setFont("Helvetica", 8) canvas_obj.drawRightString(PAGE_W - MARGIN, PAGE_H - 0.8*cm, f"Page {pn}") # Footer line canvas_obj.setStrokeColor(LIGHT_BLUE) canvas_obj.setLineWidth(0.5) canvas_obj.line(MARGIN, 1.0*cm, PAGE_W - MARGIN, 1.0*cm) canvas_obj.setFillColor(MID_GREY) canvas_obj.setFont("Helvetica", 7) canvas_obj.drawCentredString(PAGE_W/2, 0.6*cm, "For educational use | Kanski's Clinical Ophthalmology & standard ophthalmology references") canvas_obj.restoreState() # ────────────────────────────── # INSTRUMENT DATA # ────────────────────────────── INSTRUMENTS = [ { "category": "Examination & Diagnostic Instruments", "name": "Slit Lamp Biomicroscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Slit_lamp.jpg/320px-Slit_lamp.jpg", "parts": [ "Illumination system (slit beam, condenser, slit diaphragm, filters)", "Observation system (binocular microscope, 10x eyepieces, 0.6x–4x objectives)", "Joystick for XYZ movement, chinrest and forehead rest", "Magnification changer: 6x to 40x total magnification range", ], "uses": [ "Anterior segment: eyelids, conjunctiva, cornea, iris, lens, anterior vitreous", "Posterior segment: with +78D/+90D Volk lens or three-mirror contact lens", "Gonioscopy (with gonioscopic lens), applanation tonometry (Goldmann attachment)", "Laser delivery, measurement of lesion size using ocular micrometer", ], "exam_points": [ "Inventor: Allvar Gullstrand (1911); improved by Goldmann", "Illumination modes: diffuse, direct focal, retroillumination, specular reflection, sclerotic scatter, indirect proximal", "Cobalt blue filter: used with fluorescein to detect corneal epithelial defects", "With +90D lens: ~5.8x fundus magnification, image inverted and reversed", "Standard anterior segment magnification: 16x–25x", ], }, { "category": "Examination & Diagnostic Instruments", "name": "Direct Ophthalmoscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Ophthalmoscope.jpg/240px-Ophthalmoscope.jpg", "parts": [ "Battery handle (rheostat for light intensity)", "Aperture wheel: large, small, fixation target, slit, red-free/green beam", "Lens wheel: +20D to -20D diopters in steps", "Plane mirror with peephole", ], "uses": [ "Monocular fundus examination: optic disc, macula, retinal vessels, periphery", "Anterior segment examination: red reflex, lens, anterior vitreous", "Objective refraction estimation", ], "exam_points": [ "Invented by Hermann von Helmholtz (1851)", "Magnification: ~15x (emmetropic patient and examiner)", "Image: erect (upright), virtual, magnified", "Working distance: ~2.5–3 cm from patient's eye", "Field of view: ~5° (narrow) — small area of fundus visible at once", "Lens wheel compensates refractive errors; red-free beam enhances RNFL and vessels", ], }, { "category": "Examination & Diagnostic Instruments", "name": "Binocular Indirect Ophthalmoscope (BIO)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/7/7e/Indirect_ophthalmoscope.jpg/320px-Indirect_ophthalmoscope.jpg", "parts": [ "Head-mounted unit with transformer/battery pack", "Binocular viewing eyepieces (3.5x)", "Bright halogen/LED coaxial light source", "Condensing lens (+20D, +28D, +30D — held by examiner)", "Teaching mirror attachment option", ], "uses": [ "Wide-field retinal examination including periphery", "Retinal detachment, vitreous evaluation, ROP screening", "Scleral indentation (with depressor)", "Intraoperative fundus view; laser delivery for PRP/retinal breaks", ], "exam_points": [ "Invented by Charles Schepens (1947) — 'father of retinal surgery'", "Magnification with +20D lens: ~3x; with +28D: ~2x", "Image: inverted (upside-down) and reversed — REAL aerial image between lens and eye", "Field of view: ~40–50° (much wider than direct)", "+20D: higher magnification; +28D: wider field; +30D: widest field, lowest magnification", "Binocular viewing provides stereopsis (3D depth perception)", ], }, { "category": "Examination & Diagnostic Instruments", "name": "Retinoscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/24/Retinoscope.jpg/200px-Retinoscope.jpg", "parts": [ "Battery handle", "Streak head with rotating sleeve (changes meridian of streak)", "Plane mirror with peephole; built-in +2D lens (in some)", ], "uses": [ "Objective refraction (without patient cooperation — ideal for children)", "Detecting irregular astigmatism (scissors reflex) and keratoconus", "Assessing media clarity and lens opacities", ], "exam_points": [ "Types: Plane mirror retinoscope (spot) and streak retinoscope (Copeland) — most used", "Standard working distance: 67 cm (+1.5D correction) or 1 m (+1D correction)", "'With' movement → hypermetropia or high myopia beyond far point → neutralize with PLUS lens", "'Against' movement → myopia within far point → neutralize with MINUS lens", "Reversal (no movement): patient's far point at working distance", "Scissors reflex: irregular astigmatism; dark crescent: early keratoconus", ], }, { "category": "Tonometry", "name": "Goldmann Applanation Tonometer (GAT)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/9c/Goldmann_applanation_tonometer.jpg/280px-Goldmann_applanation_tonometer.jpg", "parts": [ "Biprism (split prism producing two semicircular mires)", "Spring-loaded measuring drum (calibrated 0–80 mmHg)", "Blue filter holder for cobalt blue illumination", "Slit-lamp mounting arm", ], "uses": [ "Measurement of intraocular pressure (IOP) — gold standard", "Glaucoma screening and monitoring", ], "exam_points": [ "Principle: Imbert-Fick law — P = F/A (pressure = force ÷ area)", "Flattening area: 3.06 mm diameter (balances surface tension and tear film meniscus forces)", "Fluorescein + cobalt blue: two green semicircular mires; endpoint = inner edges just touching", "Dial reading × 10 = IOP in mmHg (scale 0–8; each unit = 10 mmHg)", "Normal IOP: 10–21 mmHg", "Thick cornea → overestimates IOP; thin cornea → underestimates", "Requires topical anaesthesia (proparacaine/tetracaine) + fluorescein", ], }, { "category": "Tonometry", "name": "Schiotz Tonometer", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f8/Schiotz_tonometer.jpg/240px-Schiotz_tonometer.jpg", "parts": [ "Footplate (3 mm central aperture)", "Plunger: base weight 5.5 g", "Scale 0–20 units", "Additional weights: 7.5 g, 10 g, 15 g", "Test block for calibration", ], "uses": [ "IOP measurement by indentation (impression tonometry)", "Bedside or theatre use when slit lamp unavailable", ], "exam_points": [ "Type: impression (indentation) tonometer", "Principle: plunger indents cornea; scale reading converted via Friedenwald tables", "Patient lies supine; footplate on anesthetized cornea", "High scale reading = low IOP (soft eye); low scale reading = high IOP (hard eye)", "Ocular rigidity errors: rigid cornea/sclera → falsely low reading", "Sterilise in 70% alcohol (not autoclave)", ], }, { "category": "Tonometry", "name": "Non-Contact Tonometer (Air-Puff)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/06/Non_contact_tonometer.jpg/280px-Non_contact_tonometer.jpg", "parts": [ "Air delivery nozzle", "Photodetector for corneal deformation", "Electronic display and automated alignment", ], "uses": [ "IOP screening (no corneal contact — infection control advantage)", "Pediatric patients, contact-lens wearers", ], "exam_points": [ "Air puff flattens 3.6 mm corneal area; photodetector detects applanation moment", "No anaesthesia or fluorescein required", "Least accurate tonometer — over-reads high IOP, under-reads very high IOP", "Affected by CCT (central corneal thickness) and corneal irregularity", "Not suitable for use in acute angle-closure crisis assessment", ], }, { "category": "Gonioscopy Lenses", "name": "Goldmann Three-Mirror Lens", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Goldman_3_mirror.jpg/240px-Goldman_3_mirror.jpg", "parts": [ "Central lens (posterior pole, 30°)", "Equatorial mirror (rectangle, 67°): peripheral retina", "Peripheral mirror (truncated oval, 75°): far periphery / pars plana", "Gonioscopy mirror (dome/smallest, 59°): anterior chamber angle", ], "uses": [ "Gonioscopy — examination of iridocorneal drainage angle", "Peripheral retina, pars plana, vitreous base examination", "Slit-lamp fundus examination, argon laser trabeculoplasty, PRP", ], "exam_points": [ "Coupling gel required (2.5% methylcellulose)", "Image: inverted and mirror-reversed", "Gonioscopy mirror at bottom → examiner views superior angle structures", "Rotate 360° to view all angle quadrants", "Tilt slit lamp 14–15° forward for angle mirror view", "Indirect gonioscopy lens type (opposite meridian visible)", ], }, { "category": "Gonioscopy Lenses", "name": "Zeiss Four-Mirror Gonioscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5b/Zeiss_4_mirror.jpg/240px-Zeiss_4_mirror.jpg", "parts": [ "Four mirrors at 64° each (all 4 quadrants visible with minimal rotation)", "Smaller diameter than Goldmann", "No coupling gel required — works with tear film", ], "uses": [ "Dynamic indentation gonioscopy (compress cornea to open angle)", "Differentiates appositional from synechial angle closure", "Preferred for narrow angle assessment", ], "exam_points": [ "Indirect gonioscopy (image of opposite quadrant)", "No coupling agent — major advantage", "Indentation gonioscopy: pressure on cornea → aqueous pushed into angle → opens appositional closure", "Cannot be used for laser procedures (unlike Goldmann)", "Less stable during exam; requires regular repositioning", ], }, { "category": "Refraction Instruments", "name": "Trial Lens Set and Trial Frame", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/4a/Trial_lens_set.jpg/300px-Trial_lens_set.jpg", "parts": [ "Spherical lenses: +0.12D to +20D; -0.12D to -20D", "Cylindrical lenses: +0.12D to +6D; -0.12D to -6D", "Prisms (1Δ–12Δ), prism bars", "Accessories: occluder, pinhole, Maddox rod, red/green lenses", "Trial frame with adjustable PD, vertex distance, pantoscopic tilt", ], "uses": [ "Subjective refraction (spheres, cylinders, axes)", "Binocular vision and orthoptic assessment", "Low vision aid prescription", ], "exam_points": [ "Spheres placed in back cell, cylinders in front cell of trial frame", "Best sphere: most plus (or least minus) giving best VA (maximum plus principle)", "BCVA: best corrected visual acuity with optimal combination", "Jackson Cross Cylinder (JCC): +0.25/-0.50D or +0.50/-1.00D — refines cylinder axis and power", "Fogging technique: add plus sphere to relax accommodation before subjective refinement", ], }, { "category": "Refraction Instruments", "name": "Keratometer (Javal-Schiötz / B&L)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Ophthalmometer.jpg/280px-Ophthalmometer.jpg", "parts": [ "Mire targets (2 or 4 luminous objects on instrument body)", "Telescope/microscope for observing corneal reflections", "Measurement drums (horizontal and vertical meridians)", "Chinrest and forehead bar", ], "uses": [ "Measuring corneal curvature (K1 and K2 readings in diopters)", "Diagnosing and quantifying corneal astigmatism", "Contact lens base curve selection; IOL biometry; keratoconus screening", ], "exam_points": [ "Javal-Schiötz: variable-doubling; B&L: fixed doubling with variable object", "Measures only central 3–4 mm corneal zone", "Normal K: 42–44 D; difference >1D = clinically significant astigmatism", "Irregular mires → irregular astigmatism or surface pathology", "K used in SRK/T and other IOL power formulas", ], }, { "category": "Refraction Instruments", "name": "Lensometer (Lensmeter / Focimeter)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/4/43/Lensometer.jpg/240px-Lensometer.jpg", "parts": [ "Eyepiece (telescope)", "Sphere and cylinder power drums", "Axis wheel", "Lens stop (supports spectacle lens)", "Illuminated target (crosslines/dot pattern)", ], "uses": [ "Measuring power of spectacle/contact lenses (sphere, cylinder, axis)", "Checking prismatic power and centration", "Marking optical centers on lenses", ], "exam_points": [ "Also called vertometer (UK: focimeter)", "Measures back vertex power of the lens", "Target: crosslines/spokes — spherical lens: all lines clear simultaneously; astigmatic lens: first one set, then the other", "Prism measured in prism diopters (Δ): 1Δ = 1 cm deviation at 1 m", "Automated lensmeters print sphere, cylinder, axis, add power, PD directly", ], }, { "category": "Refraction Instruments", "name": "Phoropter (Refractor Head)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/Phoropter.jpg/280px-Phoropter.jpg", "parts": [ "Two rotating lens discs (right and left eye, OD/OS)", "Sphere: +16.75D to -19D; Cylinder: 0 to ±6D", "Built-in JCC, Maddox rod, prisms, occluder, pinhole, polaroid filters", "Interpupillary distance adjustment (monocular and binocular PD)", ], "uses": [ "Subjective refraction (monocular and binocular balance)", "Accommodation, convergence, and binocular vision testing", "Phoria and strabismus assessment", ], "exam_points": [ "More efficient than trial frame — rapid lens changes", "Does not accurately represent real spectacle vertex distance for high powers", "Not ideal for high prescriptions without vertex distance compensation", "Automated/digital phoropters now integrate with autorefractors", ], }, { "category": "Visual Acuity", "name": "Snellen Chart", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8e/Snellen_chart.svg/200px-Snellen_chart.svg.png", "parts": [ "Chart with letters/numbers/tumbling-E in decreasing sizes", "Tested at standard 6 m (or mirrored at 3 m)", "Illuminated or printed; also available as ETDRS chart", ], "uses": [ "Measurement of distance visual acuity (VA)", "Recording unaided and best-corrected VA", ], "exam_points": [ "Each letter subtends 5' arc at stated distance; individual limbs subtend 1'", "6/6 (20/20): normal distance VA", "If cannot read top letter (6/60): test for CF (count fingers) → HM → PL → NPL", "LogMAR (ETDRS) chart: more precise for clinical research", "Snellen fraction → logMAR = -log10(Snellen fraction)", "Near vision: Jaeger chart (J1 = ~6/6 near); also N-notation and M-notation", ], }, { "category": "Visual Acuity", "name": "Pinhole", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/58/Pinhole_occluder.jpg/200px-Pinhole_occluder.jpg", "parts": [ "Opaque disc with 1–3 holes (1–1.5 mm diameter)", "Used in trial frame or held manually", ], "uses": [ "Differentiates refractive from organic cause of reduced VA", "Quick screening for correctable vision impairment", ], "exam_points": [ "Eliminates refractive error effect by allowing only paraxial rays", "VA improves with pinhole → refractive error or media opacity (reversible cause)", "VA unchanged or worse → amblyopia, macular/optic nerve pathology", "Paradoxical worsening: posterior subcapsular cataract, central macular disease (diffraction effect)", ], }, { "category": "Visual Field Testing", "name": "Goldmann Perimeter", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e5/Goldmann_perimeter.jpg/280px-Goldmann_perimeter.jpg", "parts": [ "Hemispheric bowl (33 cm radius, uniform white background)", "Moveable fixation device and central fixation target", "Variable-size targets I–V and intensities 1–4 (a–e)", "Manual plotting chart, examiner eyepiece", ], "uses": [ "Manual kinetic and static perimetry", "Plotting isopters and mapping scotomas", "Neurological field defects, medico-legal assessments", ], "exam_points": [ "Kinetic: target moved periphery → centre; patient presses buzzer when seen", "Isopter: line connecting points of equal sensitivity", "III4e: standard target for most patients", "I4e: subtle loss; V4e: severely restricted fields", "Classic glaucoma defects: inferior nasal step, arcuate scotoma, Bjerrum's scotoma", ], }, { "category": "Visual Field Testing", "name": "Humphrey Field Analyser (HFA)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/05/Humphrey_Visual_Field_Analyzer.jpg/280px-Humphrey_Visual_Field_Analyzer.jpg", "parts": [ "Automated static perimeter", "Computer with SITA algorithm (SITA-Standard, SITA-Fast, SITA-Faster)", "Stimulus projection; foveal sensitivity measurement", ], "uses": [ "Automated static perimetry for glaucoma diagnosis and monitoring", "Neurological field defects (hemianopia, quadrantanopia)", ], "exam_points": [ "SITA: Swedish Interactive Thresholding Algorithm", "24-2: 54 points within central 24° — standard for glaucoma", "30-2: 76 points within 30°; 10-2: 68 points within 10° (macular)", "Reliability: fixation losses <20%, false positives <15%, false negatives <33%", "MD (Mean Deviation): overall field loss; PSD (Pattern SD): localised defect", "GHT (Glaucoma Hemifield Test): compares superior vs inferior arcuate zones", ], }, { "category": "Strabismus Assessment", "name": "Maddox Rod", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/14/Maddox_rod.jpg/240px-Maddox_rod.jpg", "parts": [ "Series of parallel red cylindrical lenses (high-powered)", "Mounted in circular trial frame holder", "Usually red (right eye); white/blue (left eye)", ], "uses": [ "Detection of heterophoria (latent squint)", "Measuring cyclotorsion (trochlear nerve palsy)", "Dissociation of binocular vision", ], "exam_points": [ "Converts point source of light into a line perpendicular to the rod cylinders", "Esophoria: line on SAME side as rod (uncrossed); Exophoria: line on OPPOSITE side (crossed)", "Double Maddox rod test (red and white): assesses cyclotorsion", "Used at 6 m for distance phoria; 33 cm for near phoria", ], }, { "category": "Strabismus Assessment", "name": "Prism Bar and Loose Prisms", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Prism_bar.jpg/240px-Prism_bar.jpg", "parts": [ "Horizontal prism bar: 1–40 prism diopters (Δ)", "Vertical prism bar", "Loose prisms in trial set (1Δ–40Δ)", ], "uses": [ "Measurement of angle of squint (prism cover test — PCT)", "Diagnosis and quantification of phorias and tropias", ], "exam_points": [ "1 prism diopter (Δ) = 0.57° = 1 cm deviation at 1 m", "Base-out: for exodeviation; Base-in: for esodeviation", "Base-down: for hyperdeviation; Base-up: for hypodeviation", "Prism neutralises deviation when alternating cover test shows no movement", "Prism held apex in direction of deviation (base opposite)", ], }, { "category": "Cornea & Anterior Segment", "name": "Placido's Disc (Keratoscope)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/33/Placido_disk.jpg/200px-Placido_disk.jpg", "parts": [ "Concentric black and white rings on flat disc", "Central aperture for observation", "Handle", ], "uses": [ "Qualitative assessment of corneal surface regularity", "Screening for irregular astigmatism, keratoconus, pterygium", ], "exam_points": [ "Invented by Antonio Placido (1880)", "Regular, round rings → normal cornea", "Oval/elliptical rings → regular astigmatism", "Irregular/distorted rings → keratoconus, corneal scarring", "Modern equivalent: Computerised corneal topographer (Placido-based)", "Qualitative only — keratometer provides quantitative values", ], }, { "category": "Cornea & Anterior Segment", "name": "Specular Microscope", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e4/Specular_microscopy.jpg/280px-Specular_microscopy.jpg", "parts": [ "Specular reflection optical system", "High-magnification camera", "Automated cell analysis software", ], "uses": [ "Endothelial cell density (ECD) measurement", "Pre-operative workup for cataract, corneal transplant", "Monitoring Fuchs' endothelial dystrophy, post-surgical endothelial loss", ], "exam_points": [ "Normal ECD: 2000–3000 cells/mm²", "ECD <500 cells/mm² → risk of corneal decompensation", "Measures: ECD, CV (coefficient of variation), hexagonality (%)", "Polymegethism: variation in cell size; Pleomorphism: variation in cell shape", "Required pre-op before DSEK/DSAEK/DMEK and anterior segment surgery", ], }, { "category": "Lacrimal System Instruments", "name": "Lacrimal Syringe & Cannula", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/2/29/Lacrimal_cannula.jpg/240px-Lacrimal_cannula.jpg", "parts": [ "2 mL syringe", "Blunt-tipped angled lacrimal cannula (23G)", ], "uses": [ "Lacrimal syringing to assess NLD patency", "Irrigation of lacrimal sac in dacryocystitis", ], "exam_points": [ "Dilate punctum with punctum dilator before cannulation", "Regurgitation on pressure over lacrimal sac → mucocele/dacryocystitis", "Hard stop on syringing → probe hits lacrimal bone (anatomically patent canaliculi)", "Soft stop → obstruction within canaliculus before bony wall", "Jones dye test I and II: functional and anatomical NLD patency assessment", ], }, { "category": "Lacrimal System Instruments", "name": "Bowman's Probe", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/12/Bowmans_probe.jpg/240px-Bowmans_probe.jpg", "parts": [ "Double-ended malleable metallic probe (silver or stainless steel)", "Sizes 0–8 (0 = thinnest)", ], "uses": [ "Probing nasolacrimal duct in congenital NLD obstruction", "Dilation of NLD", ], "exam_points": [ "First-line treatment for congenital epiphora not resolved by massage", "Success rate ~90% if performed before 13 months of age", "Technique: probe passed vertically through punctum then horizontally into lacrimal canal, then angled into nose", "Hard stop at lacrimal bone = correct plane", "Intubation (silicone tube) if simple probing fails", ], }, { "category": "Surgical Instruments", "name": "Eye Speculum", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Eye_speculum.jpg/240px-Eye_speculum.jpg", "parts": [ "Two blades (spring-loaded or screw-adjusted)", "Wire or solid blade variants", ], "uses": [ "Retraction of eyelids during ocular surgery", "Examination under anaesthesia (EUA)", ], "exam_points": [ "Universal speculum: cannot exclude eyelashes from field", "Barraquer speculum: solid blades, preferred in cataract/corneal surgery", "Alfonso speculum: used in LASIK", "Wire speculum: lighter; less control over eyelashes", "Choose speculum based on procedure and orbital anatomy", ], }, { "category": "Surgical Instruments", "name": "Chalazion Forceps (Clamp)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c4/Chalazion_forceps.jpg/200px-Chalazion_forceps.jpg", "parts": [ "One arm: round discoid plate (placed on conjunctival surface)", "Other arm: oval ring (placed on skin surface)", "Central screw mechanism for clamping", ], "uses": [ "Chalazion incision and curettage (I&C)", "Meibomian cyst excision under local anaesthesia", ], "exam_points": [ "Everts and immobilises the eyelid for conjunctival approach", "Provides haemostasis during curettage", "Vertical incision on tarsal conjunctival surface (avoids skin scar)", "Horizontal skin incision only if lesion points anteriorly or recurs", ], }, { "category": "Surgical Instruments", "name": "Castroviejo Calipers", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/Castroviejo_calipers.jpg/240px-Castroviejo_calipers.jpg", "parts": [ "Two sharp metallic tips on spring mechanism", "Sliding scale in mm", ], "uses": [ "Surgical measurement: white-to-white corneal diameter, limbal marking", "Toric IOL axis marking, strabismus muscle measurements", ], "exam_points": [ "Must be zeroed before use", "Normal white-to-white: 11–12 mm", "Strabismus caliper: specific for rectus muscle recession/resection measurements", "Used alongside surgical marking pen for accurate axis marking in toric IOL implantation", ], }, { "category": "Surgical Instruments", "name": "Muscle Hook (Squint Hook)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fa/Squint_hook.jpg/240px-Squint_hook.jpg", "parts": [ "Long handle with curved hook tip", "Types: sharp, blunt-tipped, von Graefe's, Green's", ], "uses": [ "Isolating extraocular muscles in strabismus surgery", "Muscle recession and resection", ], "exam_points": [ "Von Graefe's hook: large, for rectus muscles", "Green's hook: fine-tipped; for oblique muscles (superior and inferior oblique)", "Anterior segment ischaemia risk if >2 rectus muscles cut simultaneously", "Passed beneath Tenon's capsule to engage muscle belly", ], }, { "category": "Diagnostic Slit-Lamp Lenses", "name": "Volk +90D / +78D Lens", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/36/Volk_90D_lens.jpg/200px-Volk_90D_lens.jpg", "parts": [ "Aspheric handheld condensing lens with antireflective coating", ], "uses": [ "Non-contact fundus biomicroscopy via slit lamp", "Optic nerve, macula, posterior pole evaluation", ], "exam_points": [ "+78D: ~7.2x magnification, 48° field of view", "+90D: ~5.8x magnification, 60° field (preferred for broader view)", "+60D SuperField: ~76° field (widest non-contact)", "Image: inverted and reversed — real aerial image", "No coupling gel needed; held ~8–10 mm from cornea", ], }, { "category": "Ophthalmic Imaging", "name": "Fundus Camera", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/Fundus_camera.jpg/280px-Fundus_camera.jpg", "parts": [ "Objective/relay optical system", "Flash illumination (xenon)", "Digital CCD/CMOS camera sensor", "Fixation target and chin rest", ], "uses": [ "Fundus photography: disc, macula, vessels", "Fluorescein angiography (FA), ICGA", "Documentation of DR, AMD, glaucoma", ], "exam_points": [ "Standard field: 30°–45°; wide-angle: 50°–60°; ultra-wide: 200° (Optos)", "Mydriasis (>6 mm) improves image quality", "FA: excitation filter 490nm (blue); barrier filter 530nm (green)", "Phases: choroidal flush, arterial, AV, venous, late/recirculation", "ICGA: excitation 805nm; emission 835nm — better for choroidal imaging", ], }, { "category": "Ophthalmic Imaging", "name": "Optical Coherence Tomography (OCT)", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/OCT_scanner.jpg/280px-OCT_scanner.jpg", "parts": [ "Near-infrared laser source (840–1060 nm)", "Michelson interferometer", "Beam splitter and reference mirror", "Detector and high-speed computer", ], "uses": [ "Cross-sectional retinal/choroidal imaging (AMD, DME, macular holes, ERM)", "RNFL thickness for glaucoma (optic nerve OCT)", "Anterior segment OCT (AS-OCT): cornea, angle, IOL position", ], "exam_points": [ "Based on low-coherence interferometry (light equivalent of ultrasound B-scan)", "Axial resolution: 3–10 microns", "SD-OCT: current standard; SS-OCT: deeper penetration (choroid, EDI imaging)", "Normal central subfield macular thickness (CST): ~250 μm", "RNFL: normal average ~100 μm; ISNT rule: Inferior > Superior > Nasal > Temporal", "En face OCT: c-scan view useful for geographic atrophy mapping", ], }, { "category": "Ophthalmic Imaging", "name": "B-Scan Ultrasonography", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/0/09/B-scan_ultrasound.jpg/280px-B-scan_ultrasound.jpg", "parts": [ "10 MHz probe (B-scan); 20 MHz (UBM for anterior segment)", "Display unit with gain control", "Coupling gel", ], "uses": [ "Posterior segment evaluation with opaque media", "Retinal detachment, vitreous haemorrhage, choroidal detachment", "Intraocular tumours (melanoma, retinoblastoma)", "Axial length (A-scan for IOL biometry)", ], "exam_points": [ "B-scan: 2D cross-sectional; A-scan: 1D amplitude (axial)", "Retinal detachment: high-reflective membrane tethered at disc and ora serrata, funnel-shaped", "Vitreous haemorrhage: mobile, low to medium reflectivity, not attached to disc", "Choroidal melanoma: dome/collar-button, low internal reflectivity, acoustic hollow, choroidal excavation", "Calcified lesions (retinoblastoma): highly echogenic, acoustic shadowing", ], }, { "category": "Ophthalmic Imaging", "name": "A-Scan Biometry / IOL Master", "image_url": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5f/IOL_master.jpg/280px-IOL_master.jpg", "parts": [ "A-scan: 10 MHz transducer; IOL Master 500/700: partial coherence interferometry (PCI/SS-OCT)", "Integrated K-reading and anterior chamber depth measurement", ], "uses": [ "Axial length measurement and IOL power calculation (cataract surgery)", "Myopia monitoring in children", ], "exam_points": [ "IOL Master: non-contact, gold standard — uses PCI (partial coherence interferometry)", "A-scan (contact): immersion > contact (corneal indentation error in contact method)", "Normal axial length: 22–24 mm", "Axial length most important parameter: 1 mm error → ~2.7D IOL error", "IOL formulas: Barrett Universal II (best overall); SRK/T (long eyes >26mm); Hoffer-Q (short eyes <22mm)", ], }, ] # ────────────────────────────── # BUILD PDF # ────────────────────────────── def build_pdf(): doc = SimpleDocTemplate( OUTPUT_PATH, pagesize=A4, leftMargin=MARGIN, rightMargin=MARGIN, topMargin=2.5*cm, bottomMargin=1.8*cm, title="Ophthalmic Instruments – PG Practical Exam Reference", author="Orris Medical AI", subject="Ophthalmology PG Exam", ) story = [] # ── COVER PAGE ── def cover_page(canvas_obj, doc): on_page(canvas_obj, doc) # Cover background class CoverBackground(Flowable): def draw(self): c = self.canv c.saveState() c.setFillColor(DARK_BLUE) c.rect(-MARGIN, -PAGE_H + 2*cm, PAGE_W, PAGE_H - 2*cm, fill=1, stroke=0) c.restoreState() def wrap(self, avail_w, avail_h): return (avail_w, 0) story.append(Spacer(1, 3*cm)) story.append(Paragraph( '<font color="#2563a8">●</font> <font color="#ffffff">OPHTHALMIC INSTRUMENTS</font>', style("CoverTag", fontName="Helvetica-Bold", fontSize=11, textColor=LIGHT_BLUE, alignment=TA_CENTER) )) story.append(Spacer(1, 0.4*cm)) # Big title block title_data = [[Paragraph("Ophthalmic Instruments", style("CoverTitle", fontName="Helvetica-Bold", fontSize=34, textColor=WHITE, alignment=TA_CENTER))], [Paragraph("Postgraduate Practical Exam Reference", style("CoverSub", fontName="Helvetica", fontSize=18, textColor=LIGHT_BLUE, alignment=TA_CENTER))]] title_table = Table(title_data, colWidths=[PAGE_W - 2*MARGIN]) title_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), DARK_BLUE), ("TOPPADDING", (0,0), (-1,-1), 10), ("BOTTOMPADDING", (0,0), (-1,-1), 10), ("BOX", (0,0), (-1,-1), 2, MEDIUM_BLUE), ])) story.append(title_table) story.append(Spacer(1, 0.6*cm)) # Cover info box cover_info = [ [Paragraph("📋 34 Instruments Covered", style("CInfo", fontName="Helvetica-Bold", fontSize=10, textColor=DARK_BLUE))], [Paragraph("🏥 Includes: Diagnostic · Tonometry · Gonioscopy · Refraction · Imaging · Surgical", style("CInfo2", fontName="Helvetica", fontSize=9, textColor=DARK_BLUE))], [Paragraph("📚 Based on Kanski's Clinical Ophthalmology (10th Ed.) & standard PG references", style("CInfo2", fontName="Helvetica", fontSize=9, textColor=DARK_BLUE))], [Paragraph("✅ Each instrument: Parts · Uses · Key Exam Points", style("CInfo2", fontName="Helvetica", fontSize=9, textColor=DARK_BLUE))], ] ci_table = Table(cover_info, colWidths=[PAGE_W - 2*MARGIN]) ci_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 15), ("BOX", (0,0), (-1,-1), 1, MEDIUM_BLUE), ])) story.append(ci_table) story.append(Spacer(1, 0.6*cm)) # Table of contents toc_title = Table([[Paragraph("Table of Contents", style("TocT", fontName="Helvetica-Bold", fontSize=13, textColor=WHITE, alignment=TA_CENTER))]], colWidths=[PAGE_W - 2*MARGIN]) toc_title.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), MEDIUM_BLUE), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ])) story.append(toc_title) story.append(Spacer(1, 0.3*cm)) # Group instruments by category categories = {} for inst in INSTRUMENTS: cat = inst["category"] categories.setdefault(cat, []).append(inst["name"]) toc_data = [] for cat, names in categories.items(): toc_data.append([ Paragraph(f"<b>{cat}</b>", style("TocCat", fontName="Helvetica-Bold", fontSize=9.5, textColor=DARK_BLUE)), Paragraph(", ".join(names), style("TocNames", fontName="Helvetica", fontSize=9, textColor=BLACK, leading=12)) ]) toc_table = Table(toc_data, colWidths=[5.5*cm, PAGE_W - 2*MARGIN - 5.5*cm - 0.4*cm]) toc_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), LIGHT_GREY), ("ROWBACKGROUNDS", (0,0), (-1,-1), [WHITE, LIGHT_GREY]), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING", (0,0), (-1,-1), 5), ("LEFTPADDING", (0,0), (-1,-1), 8), ("RIGHTPADDING", (0,0), (-1,-1), 6), ("VALIGN", (0,0), (-1,-1), "TOP"), ("BOX", (0,0), (-1,-1), 0.5, MID_GREY), ("LINEBELOW", (0,0), (-1,-1), 0.3, colors.HexColor("#d1d5db")), ])) story.append(toc_table) story.append(PageBreak()) # ── INSTRUMENT PAGES ── current_category = None for inst in INSTRUMENTS: # Category header if changed if inst["category"] != current_category: current_category = inst["category"] cat_table = Table([[Paragraph(current_category.upper(), CATEGORY_STYLE)]], colWidths=[PAGE_W - 2*MARGIN]) cat_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), MEDIUM_BLUE), ("TOPPADDING", (0,0), (-1,-1), 7), ("BOTTOMPADDING", (0,0), (-1,-1), 7), ("LEFTPADDING", (0,0), (-1,-1), 12), ])) story.append(cat_table) story.append(Spacer(1, 0.25*cm)) # Instrument name name_table = Table([[Paragraph(inst["name"], INSTR_NAME_STYLE)]], colWidths=[PAGE_W - 2*MARGIN]) name_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE), ("TOPPADDING", (0,0), (-1,-1), 6), ("BOTTOMPADDING", (0,0), (-1,-1), 6), ("LEFTPADDING", (0,0), (-1,-1), 10), ("LINEBELOW", (0,0), (-1,-1), 1.5, MEDIUM_BLUE), ])) story.append(name_table) story.append(Spacer(1, 0.2*cm)) # ── Image + Parts/Uses/Exam Points in two columns ── img_obj = fetch_image(inst.get("image_url",""), max_w=5.5*cm, max_h=5.5*cm) # Right column: parts, uses, exam points right_cells = [] # Parts parts_header = Table([[Paragraph("🔩 PARTS / COMPONENTS", style("PH", fontName="Helvetica-Bold", fontSize=8, textColor=WHITE))]], colWidths=[PAGE_W - 2*MARGIN - 6.2*cm]) parts_header.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), ACCENT_GREEN), ("TOPPADDING", (0,0), (-1,-1), 3), ("BOTTOMPADDING", (0,0), (-1,-1), 3), ("LEFTPADDING", (0,0), (-1,-1), 6)])) right_cells.append(parts_header) for p in inst["parts"]: right_cells.append(Paragraph(f"• {p}", BULLET_STYLE)) right_cells.append(Spacer(1, 0.15*cm)) # Uses uses_header = Table([[Paragraph("🎯 USES / INDICATIONS", style("UH", fontName="Helvetica-Bold", fontSize=8, textColor=WHITE))]], colWidths=[PAGE_W - 2*MARGIN - 6.2*cm]) uses_header.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), MEDIUM_BLUE), ("TOPPADDING", (0,0), (-1,-1), 3), ("BOTTOMPADDING", (0,0), (-1,-1), 3), ("LEFTPADDING", (0,0), (-1,-1), 6)])) right_cells.append(uses_header) for u in inst["uses"]: right_cells.append(Paragraph(f"• {u}", BULLET_STYLE)) right_cells.append(Spacer(1, 0.15*cm)) # Key exam points exam_header = Table([[Paragraph("⭐ KEY EXAM POINTS", style("EH", fontName="Helvetica-Bold", fontSize=8, textColor=WHITE))]], colWidths=[PAGE_W - 2*MARGIN - 6.2*cm]) exam_header.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,-1), ACCENT_ORANGE), ("TOPPADDING", (0,0), (-1,-1), 3), ("BOTTOMPADDING", (0,0), (-1,-1), 3), ("LEFTPADDING", (0,0), (-1,-1), 6)])) right_cells.append(exam_header) for ep in inst["exam_points"]: right_cells.append(Paragraph(f"▸ {ep}", BULLET_STYLE)) # Placeholder if no image if img_obj is None: img_obj = Paragraph( f'<font color="#6b7280" size="8">[ No image<br/>available ]</font>', style("NoImg", fontName="Helvetica", fontSize=8, textColor=MID_GREY, alignment=TA_CENTER) ) main_table = Table( [[img_obj, right_cells]], colWidths=[6.0*cm, PAGE_W - 2*MARGIN - 6.2*cm], rowHeights=None, ) main_table.setStyle(TableStyle([ ("VALIGN", (0,0), (-1,-1), "TOP"), ("LEFTPADDING", (0,0), (0,0), 4), ("RIGHTPADDING", (0,0), (0,0), 8), ("LEFTPADDING", (0,1), (-1,-1), 0), ("TOPPADDING", (0,0), (-1,-1), 0), ("BOTTOMPADDING", (0,0), (-1,-1), 0), ])) story.append(main_table) story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#d1d5db"))) story.append(Spacer(1, 0.4*cm)) doc.build(story, onFirstPage=on_page, onLaterPages=on_page) print(f"✅ PDF saved: {OUTPUT_PATH}") build_pdf() PYEOF python3 /tmp/workspace/ophthalmology-instruments/generate_pdf.py
sed -i 's/from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Image,/from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Image, Flowable,/' /tmp/workspace/ophthalmology-instruments/generate_pdf.py # Also remove the unused CoverBackground class (it has no fill since we have a plain page) python3 /tmp/workspace/ophthalmology-instruments/generate_pdf.py 2>&1 | tail -30
ls -lh /tmp/workspace/ophthalmology-instruments/Ophthalmology_Instruments_PG_Exam.pdf python3 -c " from pypdf import PdfReader r = PdfReader('/tmp/workspace/ophthalmology-instruments/Ophthalmology_Instruments_PG_Exam.pdf') print(f'Pages: {len(r.pages)}') print(f'Title: {r.metadata.title}') " ls /tmp/workspace/ophthalmology-instruments/img_cache/ | wc -l
# Test a few Wikipedia URLs directly python3 -c " import requests urls = [ 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/62/Slit_lamp.jpg/320px-Slit_lamp.jpg', 'https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Ophthalmoscope.jpg/240px-Ophthalmoscope.jpg', ] headers = {'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) Chrome/120'} for url in urls: try: r = requests.get(url, headers=headers, timeout=8, verify=False) print(f'{r.status_code} | {len(r.content)} bytes | {url[-40:]}') except Exception as e: print(f'FAIL: {e} | {url[-40:]}') "
???
cat << 'PYEOF' > /tmp/workspace/ophthalmology-instruments/draw_instruments.py """ Draw simple but recognisable schematic illustrations for each ophthalmic instrument and save as PNG files to img_cache/. """ import os, math import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib.patches import FancyBboxPatch, Arc, Circle, Ellipse, FancyArrowPatch, Rectangle, Wedge, Polygon from matplotlib.lines import Line2D import numpy as np OUT = "/tmp/workspace/ophthalmology-instruments/img_cache" os.makedirs(OUT, exist_ok=True) BG = "#f0f4ff" BLUE = "#1a3a5c" LB = "#2563a8" ORG = "#d97706" GRN = "#059669" RED = "#dc2626" GREY = "#6b7280" WHT = "#ffffff" LBLU = "#dbeafe" def new_fig(name, w=4, h=4): fig, ax = plt.subplots(figsize=(w, h)) fig.patch.set_facecolor(BG) ax.set_facecolor(BG) ax.set_xlim(0, 10); ax.set_ylim(0, 10) ax.set_aspect("equal"); ax.axis("off") return fig, ax def save(fig, name): p = os.path.join(OUT, f"{name}.png") fig.savefig(p, dpi=100, bbox_inches="tight", facecolor=BG) plt.close(fig) print(f" saved {name}.png") # ───────────────────────────────────── # 1. Slit Lamp # ───────────────────────────────────── fig, ax = new_fig("slit_lamp") # Base / table mount ax.add_patch(Rectangle((1,0.3), 8, 0.8, color=GREY, zorder=1)) ax.add_patch(Rectangle((4.5,1.1), 1, 1.5, color=GREY, zorder=2)) # Main body ax.add_patch(Rectangle((3.5,2.4), 3, 4.5, color=LB, zorder=3, linewidth=1.5, edgecolor=BLUE)) # Binocular eyepieces ax.add_patch(Circle((4.0,7.2), 0.55, color=BLUE, zorder=5)) ax.add_patch(Circle((6.0,7.2), 0.55, color=BLUE, zorder=5)) ax.add_patch(Circle((4.0,7.2), 0.3, color=GREY, zorder=6)) ax.add_patch(Circle((6.0,7.2), 0.3, color=GREY, zorder=6)) # Slit lamp head ax.add_patch(Rectangle((1.5,3.8), 2, 1.4, color=ORG, zorder=4, linewidth=1, edgecolor=BLUE)) ax.add_patch(Circle((2.5,4.5), 0.4, color=WHT, zorder=5)) # Light beam ax.plot([3.5, 4.2], [4.5, 5.0], color="yellow", lw=2, zorder=6) # Chin rest ax.add_patch(Rectangle((3.8,0.3), 2.4, 0.8, color="#a0aec0", zorder=4)) # Labels ax.text(5, 8.1, "Slit Lamp Biomicroscope", ha="center", va="center", fontsize=9, fontweight="bold", color=BLUE, style="italic") ax.text(5, 7.7, "Eyepieces", ha="center", fontsize=6.5, color=GREY) ax.text(2.5, 3.3, "Illumin.\nHead", ha="center", fontsize=6, color=WHT) ax.text(4.8, 0.7, "Chinrest", ha="center", fontsize=6, color=WHT) save(fig, "slit_lamp") # ───────────────────────────────────── # 2. Direct Ophthalmoscope # ───────────────────────────────────── fig, ax = new_fig("direct_ophthalmoscope") # Handle ax.add_patch(Rectangle((4.2, 0.5), 1.6, 5.5, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=2)) # Ridged grip lines for y in np.arange(1, 5.5, 0.4): ax.plot([4.2, 5.8], [y, y], color=BLUE, lw=0.8, zorder=3) # Head ax.add_patch(FancyBboxPatch((3.0, 6.0), 4, 3.2, boxstyle="round,pad=0.2", color=LB, linewidth=1.5, edgecolor=BLUE, zorder=4)) # Lens aperture ax.add_patch(Circle((5.0, 7.8), 0.9, color=BLUE, zorder=5)) ax.add_patch(Circle((5.0, 7.8), 0.6, color="#1a1a2e", zorder=6)) ax.add_patch(Circle((5.0, 7.8), 0.2, color=ORG, zorder=7)) # Lens wheel ax.add_patch(Circle((6.5, 6.5), 0.7, color=ORG, zorder=5)) ax.text(6.5, 6.5, "+2", ha="center", va="center", fontsize=6.5, color=WHT, fontweight="bold") # Labels ax.text(5, 9.5, "Direct Ophthalmoscope", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5.0, 6.8, "Peephole", ha="center", fontsize=6, color=WHT) ax.text(6.5, 7.4, "Lens\nwheel", ha="center", fontsize=6, color=ORG) ax.text(4.95, 0.2, "Battery handle", ha="center", fontsize=6.5, color=GREY) save(fig, "direct_ophthalmoscope") # ───────────────────────────────────── # 3. BIO (Binocular Indirect Ophthalmoscope) # ───────────────────────────────────── fig, ax = new_fig("bio") # Headband head_arc = Arc((5, 7), 6, 3, angle=0, theta1=0, theta2=180, color=BLUE, lw=4, zorder=3) ax.add_patch(head_arc) # Straps down sides ax.plot([2, 1.8], [7, 4.5], color=GREY, lw=3, zorder=2) ax.plot([8, 8.2], [7, 4.5], color=GREY, lw=3, zorder=2) # Main optical unit (centre) ax.add_patch(Rectangle((3.8, 7.2), 2.4, 1.5, color=LB, linewidth=1.5, edgecolor=BLUE, zorder=4)) # Two eyepieces ax.add_patch(Circle((4.3, 8.2), 0.45, color=BLUE, zorder=5)) ax.add_patch(Circle((5.7, 8.2), 0.45, color=BLUE, zorder=5)) # Light source ax.add_patch(Circle((5.0, 7.7), 0.35, color=ORG, zorder=5)) ax.text(5.0, 7.7, "💡", ha="center", va="center", fontsize=7) # Condensing lens (+20D) held below ax.add_patch(Ellipse((5, 4.5), 2.6, 0.7, color=LBLU, linewidth=2, edgecolor=LB, zorder=4)) ax.text(5, 4.5, "+20D condensing lens", ha="center", va="center", fontsize=7, color=BLUE, fontweight="bold") # Light beam from BIO to lens ax.annotate("", xy=(5, 4.9), xytext=(5.0, 7.4), arrowprops=dict(arrowstyle="-|>", color=ORG, lw=1.5)) # Labels ax.text(5, 9.5, "Binocular Indirect Ophthalmoscope", ha="center", fontsize=8.5, fontweight="bold", color=BLUE) ax.text(5, 3.7, "Real, inverted image formed here", ha="center", fontsize=6.5, color=GRN, style="italic") save(fig, "bio") # ───────────────────────────────────── # 4. Retinoscope # ───────────────────────────────────── fig, ax = new_fig("retinoscope") # Handle ax.add_patch(Rectangle((4.2, 0.5), 1.6, 5.0, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=2)) for y in np.arange(1, 5.0, 0.35): ax.plot([4.2, 5.8], [y, y], color=BLUE, lw=0.8, zorder=3) # Rotating sleeve ax.add_patch(Rectangle((3.9, 5.5), 2.2, 1.2, color=LB, linewidth=1.5, edgecolor=BLUE, zorder=4)) ax.text(5, 6.1, "Sleeve", ha="center", va="center", fontsize=7, color=WHT) # Head ax.add_patch(FancyBboxPatch((3.3, 6.7), 3.4, 2.5, boxstyle="round,pad=0.15", color=LB, linewidth=1.5, edgecolor=BLUE, zorder=4)) # Peephole ax.add_patch(Circle((5.0, 8.1), 0.6, color=BLUE, zorder=5)) ax.add_patch(Circle((5.0, 8.1), 0.3, color="#1a1a2e", zorder=6)) # Streak beam indicator ax.plot([5.0, 5.0], [6.7, 4.5], color="yellow", lw=2.5, zorder=5, linestyle="--") ax.annotate("", xy=(5, 4.0), xytext=(5, 4.5), arrowprops=dict(arrowstyle="-|>", color="yellow", lw=1.5)) ax.text(6.3, 5.5, "Streak\nbeam", ha="center", fontsize=6.5, color="goldenrod") # Labels ax.text(5, 9.5, "Streak Retinoscope", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.2, "Battery handle", ha="center", fontsize=6.5, color=GREY) save(fig, "retinoscope") # ───────────────────────────────────── # 5. Goldmann Applanation Tonometer # ───────────────────────────────────── fig, ax = new_fig("goldmann_tonometer") # Slit lamp mount arm ax.add_patch(Rectangle((1, 4.5), 4, 0.7, color=GREY, zorder=2)) # Drum / spring mechanism ax.add_patch(Circle((6.5, 4.85), 1.4, color=LB, linewidth=2, edgecolor=BLUE, zorder=3)) ax.text(6.5, 4.85, "Drum\n0–80\nmmHg", ha="center", va="center", fontsize=6.5, color=WHT, fontweight="bold") # Scale marking for i, v in enumerate([0,2,4,6,8]): angle = 90 + i*45 r = 1.1 x = 6.5 + r*math.cos(math.radians(angle+90)) y = 4.85 + r*math.sin(math.radians(angle+90)) ax.text(x, y, str(v), ha="center", va="center", fontsize=5.5, color=GREY) # Biprism ax.add_patch(Ellipse((2.0, 4.85), 1.2, 0.7, color=LBLU, linewidth=2, edgecolor=LB, zorder=4)) ax.text(2.0, 4.85, "Biprism", ha="center", va="center", fontsize=6.5, color=BLUE, fontweight="bold") # Dividing line in biprism ax.plot([1.4, 2.6], [4.85, 4.85], color=LB, lw=1.5, zorder=5) # Cobalt blue filter ax.add_patch(Rectangle((7.5, 4.2), 0.8, 1.3, color="#1d4ed8", linewidth=1.5, edgecolor=BLUE, zorder=4)) ax.text(7.9, 4.85, "Blue\nfilter", ha="center", va="center", fontsize=5.5, color=WHT) # Fluorescein mire diagram ax.add_patch(Circle((5, 2.2), 1.5, color=WHT, linewidth=1.5, edgecolor=GREY, zorder=3)) arc1 = Arc((5, 2.2), 2.4, 2.4, angle=0, theta1=10, theta2=170, color=GRN, lw=2.5, zorder=4) arc2 = Arc((5, 2.2), 2.4, 2.4, angle=0, theta1=190, theta2=350, color=GRN, lw=2.5, zorder=4) ax.add_patch(arc1); ax.add_patch(arc2) ax.text(5, 2.2, "Endpoint\nmires", ha="center", va="center", fontsize=6, color=GRN) ax.text(5, 0.4, "Inner edges just touching = endpoint", ha="center", fontsize=6.5, color=GRN, style="italic") ax.text(5, 9.3, "Goldmann Applanation Tonometer", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 8.8, "(Gold standard for IOP measurement)", ha="center", fontsize=7, color=GREY, style="italic") save(fig, "goldmann_tonometer") # ───────────────────────────────────── # 6. Schiotz Tonometer # ───────────────────────────────────── fig, ax = new_fig("schiotz_tonometer") # Main body ax.add_patch(Rectangle((4.0, 2.5), 2.0, 5.5, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=2)) # Footplate (curved) footplate = mpatches.Arc((5, 2.5), 4, 2, angle=0, theta1=180, theta2=360, color=BLUE, lw=3, zorder=4) ax.add_patch(footplate) ax.add_patch(Ellipse((5, 2.5), 4, 0.4, color=BLUE, linewidth=1.5, edgecolor=BLUE, zorder=3)) # Central aperture in footplate ax.add_patch(Circle((5, 2.5), 0.5, color=BG, zorder=5)) # Plunger rod ax.add_patch(Rectangle((4.7, 1.5), 0.6, 7.5, color=LB, linewidth=1, edgecolor=BLUE, zorder=6)) # Scale ax.add_patch(Rectangle((6.2, 3.5), 1.5, 4.0, color=WHT, linewidth=1, edgecolor=GREY, zorder=4)) for i, v in enumerate(range(0,11,2)): yp = 3.5 + i * 0.67 ax.plot([6.2, 6.5], [yp, yp], color=GREY, lw=1, zorder=5) ax.text(6.2, yp, str(v), ha="right", va="center", fontsize=5.5, color=GREY) ax.text(6.95, 5.5, "Scale\n0–20", ha="center", fontsize=6, color=GREY) # Weights ax.add_patch(Circle((5.0, 9.2), 0.6, color=ORG, zorder=5)) ax.text(5.0, 9.2, "5.5g", ha="center", va="center", fontsize=6.5, color=WHT, fontweight="bold") ax.text(3.0, 9.0, "+7.5g\n+10g\n+15g\nweights", ha="center", fontsize=6, color=ORG) ax.text(5, 0.3, "Impression (indentation) tonometer", ha="center", fontsize=7, color=GREY, style="italic") ax.text(5, 9.8, "Schiotz Tonometer", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "schiotz_tonometer") # ───────────────────────────────────── # 7. Non-Contact Tonometer # ───────────────────────────────────── fig, ax = new_fig("nct") ax.add_patch(FancyBboxPatch((1.5, 2), 7, 6, boxstyle="round,pad=0.4", color=LB, linewidth=2, edgecolor=BLUE, zorder=2)) # Screen ax.add_patch(Rectangle((2.5, 5), 5, 2.5, color="#1a1a2e", linewidth=1.5, edgecolor=ORG, zorder=3)) ax.text(5, 6.25, "IOP: 16 mmHg", ha="center", va="center", fontsize=10, color=ORG, fontweight="bold") # Nozzle ax.add_patch(Rectangle((4.5, 2), 1, 2.8, color=GREY, linewidth=1, edgecolor=BLUE, zorder=3)) ax.add_patch(Ellipse((5, 2), 1.2, 0.6, color=LB, linewidth=1.5, edgecolor=BLUE, zorder=4)) ax.text(5, 2.0, "Nozzle", ha="center", va="center", fontsize=6, color=WHT) # Air puff arrow ax.annotate("", xy=(5, 0.8), xytext=(5, 1.7), arrowprops=dict(arrowstyle="-|>", color="cyan", lw=2)) ax.text(5, 0.4, "Air puff", ha="center", fontsize=7, color="cyan") ax.text(5, 9.3, "Non-Contact Tonometer", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 8.8, "(Air-Puff Tonometer)", ha="center", fontsize=7, color=GREY, style="italic") save(fig, "nct") # ───────────────────────────────────── # 8. Goldmann 3-Mirror Lens # ───────────────────────────────────── fig, ax = new_fig("g3mirror") # Lens body ax.add_patch(Circle((5, 5), 3.2, color=LBLU, linewidth=2, edgecolor=LB, zorder=2)) ax.add_patch(Circle((5, 5), 2.5, color=WHT, linewidth=1.5, edgecolor=LB, zorder=3)) # Three mirrors at 120° positions mirror_angles = [60, 180, 300] mirror_colors = [BLUE, GRN, ORG] mirror_labels = ["59°\nGonioscopy", "67°\nEquatorial", "75°\nPeriphery"] for ang, col, lbl in zip(mirror_angles, mirror_colors, mirror_labels): rad = math.radians(ang) mx = 5 + 1.8*math.cos(rad) my = 5 + 1.8*math.sin(rad) rect = mpatches.Rectangle((mx-0.5, my-0.25), 1.0, 0.5, angle=ang, rotation_point=(mx, my), color=col, linewidth=1, edgecolor=BLUE, zorder=4) ax.add_patch(rect) tx = 5 + 2.9*math.cos(rad) ty = 5 + 2.9*math.sin(rad) ax.text(tx, ty, lbl, ha="center", va="center", fontsize=6, color=col, fontweight="bold") # Central glass ax.add_patch(Circle((5, 5), 1.0, color=LBLU, linewidth=1.5, edgecolor=LB, zorder=5)) ax.text(5, 5, "Central\n30°", ha="center", va="center", fontsize=6.5, color=BLUE, fontweight="bold") ax.text(5, 0.4, "Requires coupling gel (methylcellulose 2.5%)", ha="center", fontsize=6.5, color=GREY, style="italic") ax.text(5, 9.5, "Goldmann Three-Mirror Lens", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "g3mirror") # ───────────────────────────────────── # 9. Zeiss 4-Mirror Gonioscope # ───────────────────────────────────── fig, ax = new_fig("zeiss4mirror") ax.add_patch(Circle((5, 5), 3.0, color=LBLU, linewidth=2, edgecolor=LB, zorder=2)) ax.add_patch(Circle((5, 5), 2.2, color=WHT, linewidth=1.5, edgecolor=LB, zorder=3)) for ang in [0, 90, 180, 270]: rad = math.radians(ang) mx = 5 + 1.6*math.cos(rad) my = 5 + 1.6*math.sin(rad) rect = mpatches.Rectangle((mx-0.55, my-0.2), 1.1, 0.4, angle=ang, rotation_point=(mx, my), color=BLUE, linewidth=1, edgecolor=BLUE, zorder=4) ax.add_patch(rect) tx = 5 + 2.8*math.cos(rad) ty = 5 + 2.8*math.sin(rad) ax.text(tx, ty, "64°", ha="center", va="center", fontsize=7, color=BLUE, fontweight="bold") ax.add_patch(Circle((5, 5), 0.8, color=LBLU, linewidth=1.5, edgecolor=LB, zorder=5)) ax.text(5, 5, "4\nmirrors", ha="center", va="center", fontsize=7, color=BLUE, fontweight="bold") ax.text(5, 0.7, "No coupling gel required", ha="center", fontsize=7.5, color=GRN, fontweight="bold") ax.text(5, 0.2, "Indentation gonioscopy possible", ha="center", fontsize=6.5, color=GREY, style="italic") ax.text(5, 9.5, "Zeiss Four-Mirror Gonioscope", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "zeiss4mirror") # ───────────────────────────────────── # 10. Trial Lens Set # ───────────────────────────────────── fig, ax = new_fig("trial_lens") ax.add_patch(FancyBboxPatch((0.5, 0.8), 9, 7.5, boxstyle="round,pad=0.2", color=GREY, linewidth=2, edgecolor=BLUE, zorder=1)) rows = ["+Sph", "-Sph", "+Cyl", "-Cyl", "Prism"] row_colors = [GRN, RED, LB, ORG, BLUE] for ri, (row, rc) in enumerate(zip(rows, row_colors)): y = 1.3 + ri * 1.35 ax.add_patch(Rectangle((0.8, y), 8.4, 1.1, color=rc, alpha=0.3, zorder=2)) ax.text(1.2, y+0.55, row, ha="left", va="center", fontsize=8, color=rc, fontweight="bold") for ci in range(6): cx = 2.5 + ci * 1.15 ax.add_patch(Circle((cx, y+0.55), 0.38, color=WHT, linewidth=1.5, edgecolor=rc, zorder=3)) val = ["+0.25", "+0.5", "+1", "+2", "+4", "+8"][ci] ax.text(cx, y+0.55, val if ri < 2 else val.replace("+",""), ha="center", va="center", fontsize=4.5, color=rc) ax.text(5, 9.3, "Trial Lens Set & Trial Frame", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "trial_lens") # ───────────────────────────────────── # 11. Keratometer # ───────────────────────────────────── fig, ax = new_fig("keratometer") # Base ax.add_patch(Rectangle((1.5, 0.5), 7, 1, color=GREY, zorder=1)) ax.add_patch(Rectangle((4.2, 1.5), 1.6, 1.5, color=GREY, zorder=2)) # Body ax.add_patch(FancyBboxPatch((2, 3), 6, 4, boxstyle="round,pad=0.3", color=LB, linewidth=2, edgecolor=BLUE, zorder=3)) # Eyepiece ax.add_patch(Rectangle((4.3, 7), 1.4, 1.8, color=BLUE, linewidth=1.5, edgecolor=BLUE, zorder=4)) ax.add_patch(Circle((5.0, 9.0), 0.7, color=BLUE, zorder=5)) ax.add_patch(Circle((5.0, 9.0), 0.4, color="#1a1a2e", zorder=6)) # Mire targets for i, (cx, cy) in enumerate([(2.5, 5), (7.5, 5)]): ax.add_patch(Circle((cx, cy), 0.6, color=ORG, linewidth=1.5, edgecolor=BLUE, zorder=4)) ax.text(cx, cy, "M", ha="center", va="center", fontsize=8, color=WHT, fontweight="bold") ax.annotate("", xy=(4.0, 5), xytext=(3.1, 5), arrowprops=dict(arrowstyle="-|>", color=ORG, lw=1.5)) ax.annotate("", xy=(6.0, 5), xytext=(6.9, 5), arrowprops=dict(arrowstyle="-|>", color=ORG, lw=1.5)) ax.text(5, 5.0, "Cornea\n3–4mm zone", ha="center", va="center", fontsize=6.5, color=WHT) ax.text(5, 0.2, "Measures K1 & K2 (normal: 42–44D)", ha="center", fontsize=7, color=GREY, style="italic") ax.text(5, 9.7, "Keratometer", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "keratometer") # ───────────────────────────────────── # 12. Lensometer # ───────────────────────────────────── fig, ax = new_fig("lensometer") # Stand body ax.add_patch(Rectangle((1.5, 0.4), 7, 1.2, color=GREY, zorder=1)) ax.add_patch(Rectangle((3.5, 1.6), 3, 5.5, color=LB, linewidth=1.5, edgecolor=BLUE, zorder=2)) # Eyepiece ax.add_patch(Rectangle((4.3, 7.1), 1.4, 1.6, color=BLUE, zorder=3)) ax.add_patch(Circle((5, 8.9), 0.65, color=BLUE, zorder=4)) ax.add_patch(Circle((5, 8.9), 0.35, color="#1a1a2e", zorder=5)) # Lens stop ax.add_patch(Rectangle((3.2, 3.5), 3.6, 0.3, color=ORG, zorder=4)) ax.text(5, 3.2, "Lens stop", ha="center", fontsize=6.5, color=ORG) # Dials ax.add_patch(Circle((3.0, 5.0), 0.7, color=ORG, zorder=4)) ax.text(3.0, 5.0, "Sph", ha="center", va="center", fontsize=6, color=WHT, fontweight="bold") ax.add_patch(Circle((7.0, 5.0), 0.7, color=GRN, zorder=4)) ax.text(7.0, 5.0, "Cyl", ha="center", va="center", fontsize=6, color=WHT, fontweight="bold") ax.add_patch(Circle((5.0, 2.3), 0.7, color=BLUE, zorder=4)) ax.text(5.0, 2.3, "Axis", ha="center", va="center", fontsize=6, color=WHT, fontweight="bold") ax.text(5, 9.7, "Lensometer (Focimeter)", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.1, "Measures spectacle lens power, axis, prism", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "lensometer") # ───────────────────────────────────── # 13. Phoropter # ───────────────────────────────────── fig, ax = new_fig("phoropter") ax.add_patch(FancyBboxPatch((1, 2.5), 8, 5.5, boxstyle="round,pad=0.3", color=LB, linewidth=2, edgecolor=BLUE, zorder=2)) # Two large circular lens discs ax.add_patch(Circle((3.2, 5.5), 1.9, color=BLUE, linewidth=3, edgecolor=WHT, zorder=3)) ax.add_patch(Circle((3.2, 5.5), 1.5, color="#1a1a2e", zorder=4)) ax.add_patch(Circle((6.8, 5.5), 1.9, color=BLUE, linewidth=3, edgecolor=WHT, zorder=3)) ax.add_patch(Circle((6.8, 5.5), 1.5, color="#1a1a2e", zorder=4)) ax.text(3.2, 5.5, "OD", ha="center", va="center", fontsize=9, color=WHT, fontweight="bold") ax.text(6.8, 5.5, "OS", ha="center", va="center", fontsize=9, color=WHT, fontweight="bold") # Dials for cx, label, col in [(1.8, "Sph", ORG), (8.2, "Sph", ORG), (1.5, "Cyl", GRN), (8.5, "Cyl", GRN)]: ax.add_patch(Circle((cx, 4.5), 0.55, color=col, zorder=5, alpha=0.85)) ax.text(cx, 4.5, label, ha="center", va="center", fontsize=6, color=WHT, fontweight="bold") # Arm ax.add_patch(Rectangle((4.3, 2), 1.4, 0.5, color=GREY, zorder=3)) ax.text(5, 1.5, "Mounted on refraction stand", ha="center", fontsize=6.5, color=GREY, style="italic") ax.text(5, 9.3, "Phoropter (Refractor Head)", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "phoropter") # ───────────────────────────────────── # 14. Jackson Cross Cylinder # ───────────────────────────────────── fig, ax = new_fig("jcc") # Two circles representing lens halves ax.add_patch(Circle((5, 5), 2.8, color=LBLU, linewidth=2, edgecolor=LB, zorder=2)) ax.add_patch(Circle((5, 5), 2.2, color=WHT, linewidth=1.5, edgecolor=LB, zorder=3)) # Plus and minus axes ax.annotate("", xy=(5, 7.5), xytext=(5, 5), arrowprops=dict(arrowstyle="-|>", color=RED, lw=2.5)) ax.annotate("", xy=(5, 2.5), xytext=(5, 5), arrowprops=dict(arrowstyle="-|>", color=RED, lw=2.5)) ax.annotate("", xy=(7.5, 5), xytext=(5, 5), arrowprops=dict(arrowstyle="-|>", color=GRN, lw=2.5)) ax.annotate("", xy=(2.5, 5), xytext=(5, 5), arrowprops=dict(arrowstyle="-|>", color=GRN, lw=2.5)) ax.text(5, 7.8, "−", ha="center", va="center", fontsize=14, color=RED, fontweight="bold") ax.text(5, 2.2, "−", ha="center", va="center", fontsize=14, color=RED, fontweight="bold") ax.text(7.8, 5, "+", ha="center", va="center", fontsize=14, color=GRN, fontweight="bold") ax.text(2.2, 5, "+", ha="center", va="center", fontsize=14, color=GRN, fontweight="bold") # Red and white dots ax.add_patch(Circle((6.8, 3.0), 0.4, color=RED, zorder=5)) ax.text(7.5, 3.0, "Red\n(−cyl axis)", ha="left", va="center", fontsize=6, color=RED) ax.add_patch(Circle((3.2, 3.0), 0.4, color=WHT, linewidth=1.5, edgecolor=GREY, zorder=5)) ax.text(2.5, 3.0, "White\n(+cyl axis)", ha="right", va="center", fontsize=6, color=GREY) # Handle ax.add_patch(Rectangle((4.6, 0.3), 0.8, 1.8, color=GREY, linewidth=1, edgecolor=BLUE, zorder=4)) ax.text(5, 0.1, "Handle at 45° between axes", ha="center", fontsize=6.5, color=GREY, style="italic") ax.text(5, 9.5, "Jackson Cross Cylinder (JCC)", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 9.0, "+0.25/−0.50D or +0.50/−1.00D", ha="center", fontsize=7, color=GREY) save(fig, "jcc") # ───────────────────────────────────── # 15. Snellen Chart # ───────────────────────────────────── fig, ax = new_fig("snellen") ax.add_patch(Rectangle((2, 0.5), 6, 9, color=WHT, linewidth=2, edgecolor=GREY, zorder=2)) lines = [ ("E", 9.0, 52), ("FP", 8.0, 40), ("TOZ", 7.0, 32), ("LPED", 6.0, 24), ("PECFD", 5.0, 18), ("EDFCZP", 4.2, 14), ("FELOPZD", 3.5, 11), ("DEFPOTEC", 2.8, 9), ] distances = ["6/60","6/36","6/24","6/18","6/12","6/9","6/6","6/5"] for (letters, y, sz), dist in zip(lines, distances): ax.text(5, y, letters, ha="center", va="center", fontsize=max(sz//5, 4), fontweight="bold", color="black", family="monospace") ax.text(7.8, y, dist, ha="right", va="center", fontsize=5, color=GREY) ax.text(5, 0.2, "Snellen Chart (tested at 6 metres)", ha="center", fontsize=6.5, color=GREY, style="italic") ax.text(5, 9.7, "Snellen Visual Acuity Chart", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "snellen") # ───────────────────────────────────── # 16. Pinhole # ───────────────────────────────────── fig, ax = new_fig("pinhole") # Occluder disc ax.add_patch(Circle((5, 5), 3.5, color="#1a1a2e", linewidth=2, edgecolor=GREY, zorder=2)) # Small holes for (hx, hy) in [(5,5), (5.6,5), (4.4,5), (5,5.6), (5,4.4)]: ax.add_patch(Circle((hx, hy), 0.28, color=WHT, zorder=3)) ax.text(5, 5, "", ha="center", va="center") # Rays through one hole for angle in [20, 0, -20]: rad = math.radians(angle) dx = math.cos(rad); dy = math.sin(rad) ax.annotate("", xy=(5 + 4*dx, 5 + 4*dy), xytext=(5 - 3*dx, 5 - 3*dy), arrowprops=dict(arrowstyle="-|>", color=ORG, lw=1, alpha=0.7)) ax.text(5, 1.0, "1–1.5 mm diameter holes", ha="center", fontsize=7, color=GREY) ax.text(5, 0.4, "Paraxial rays only → eliminates refractive error effect", ha="center", fontsize=6.5, color=GRN, style="italic") ax.text(5, 9.5, "Pinhole Occluder", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "pinhole") # ───────────────────────────────────── # 17. Goldmann Perimeter # ───────────────────────────────────── fig, ax = new_fig("goldmann_perimeter") # Bowl ax.add_patch(Circle((5, 5), 4.0, color=WHT, linewidth=3, edgecolor=LB, zorder=2)) # Isopters for r, col, lbl in [(1.5, GRN, "I"), (2.5, ORG, "III"), (3.5, RED, "V")]: c = mpatches.Circle((5, 5), r, fill=False, linewidth=2, edgecolor=col, zorder=3) ax.add_patch(c) ax.text(5 + r + 0.15, 5, lbl, fontsize=8, color=col, fontweight="bold", va="center") # Fixation ax.add_patch(Circle((5, 5), 0.25, color=BLUE, zorder=4)) # Scotoma scotoma_pts = [(3.8, 3.8), (4.5, 3.5), (5.0, 3.7), (5.0, 4.3), (4.3, 4.5)] ax.add_patch(Polygon(scotoma_pts, closed=True, color=RED, alpha=0.4, zorder=4)) ax.text(4.6, 4.0, "Scotoma", ha="center", fontsize=5.5, color=RED) # Moving target arrow ax.annotate("", xy=(5, 3.6), xytext=(5, 8.5), arrowprops=dict(arrowstyle="-|>", color=BLUE, lw=2)) ax.text(5, 8.7, "Kinetic target", ha="center", fontsize=6.5, color=BLUE, style="italic") ax.text(5, 9.5, "Goldmann Perimeter", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "Bowl radius: 33 cm | Targets: I–V, intensities 1–4 a–e", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "goldmann_perimeter") # ───────────────────────────────────── # 18. Humphrey Field Analyser # ───────────────────────────────────── fig, ax = new_fig("humphrey") ax.add_patch(FancyBboxPatch((0.8, 1), 8.4, 8, boxstyle="round,pad=0.3", color=LB, linewidth=2, edgecolor=BLUE, zorder=2)) # Print-out ax.add_patch(Rectangle((1.5, 2), 7, 5.5, color=WHT, linewidth=1, edgecolor=GREY, zorder=3)) # Plot dots (grey scale map) for xi in range(8): for yi in range(6): val = (xi+yi*2) % 5 col = ["black","#1a1a2e","#444","#888",WHT][val] ax.add_patch(Circle((2.0+xi*0.9, 2.5+yi*0.75), 0.3, color=col, zorder=4)) # MD PSD boxes ax.add_patch(Rectangle((1.6, 1.7), 3, 0.5, color=GREY, zorder=4)) ax.text(3.1, 1.95, "MD: -4.5 dB PSD: 3.8 dB", ha="center", va="center", fontsize=6.5, color=WHT) # SITA label ax.add_patch(Rectangle((5.2, 1.7), 3, 0.5, color=BLUE, zorder=4)) ax.text(6.7, 1.95, "SITA-Standard 24-2", ha="center", va="center", fontsize=6.5, color=ORG, fontweight="bold") ax.text(5, 9.5, "Humphrey Field Analyser (HFA)", ha="center", fontsize=9, fontweight="bold", color=WHT) ax.text(5, 0.4, "Automated static perimetry | SITA algorithm", ha="center", fontsize=7, color=GREY, style="italic") save(fig, "humphrey") # ───────────────────────────────────── # 19. Maddox Rod # ───────────────────────────────────── fig, ax = new_fig("maddox_rod") # The rod itself (circular with parallel cylinders) ax.add_patch(Circle((5, 5.5), 2.8, color=RED, linewidth=2, edgecolor="#7f1d1d", zorder=2, alpha=0.85)) # Parallel cylindrical grooves for x in np.arange(2.3, 7.7, 0.35): ax.plot([x, x], [2.8, 8.2], color="#7f1d1d", lw=1.2, zorder=3, alpha=0.7) ax.text(5, 5.5, "Red\ncylinders", ha="center", va="center", fontsize=8, color=WHT, fontweight="bold") # Handle ax.add_patch(Rectangle((4.4, 1.0), 1.2, 1.8, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=3)) # Light source and streak ax.add_patch(Circle((8.5, 5.5), 0.4, color=ORG, zorder=4)) ax.text(8.5, 4.8, "Light", ha="center", fontsize=6, color=ORG) ax.annotate("", xy=(3.0, 5.5), xytext=(8.1, 5.5), arrowprops=dict(arrowstyle="-|>", color="yellow", lw=2)) # Result: streak ax.plot([1.8, 1.8], [2.5, 8.5], color="yellow", lw=3.5, zorder=5, alpha=0.9) ax.text(1.8, 1.8, "Vertical\nstreak", ha="center", fontsize=6.5, color="goldenrod") ax.text(5, 9.5, "Maddox Rod", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "Dissociates fusion | Detects heterophoria | Cyclotorsion", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "maddox_rod") # ───────────────────────────────────── # 20. Prism Bar # ───────────────────────────────────── fig, ax = new_fig("prism_bar") # Bar body ax.add_patch(FancyBboxPatch((1, 3.5), 8, 3.0, boxstyle="round,pad=0.2", color=LBLU, linewidth=2, edgecolor=LB, zorder=2)) prism_vals = [1, 2, 4, 6, 8, 10, 12, 14] for i, v in enumerate(prism_vals): cx = 1.5 + i * 1.0 # Triangle prism shape tri = Polygon([[cx-0.3, 4.0], [cx+0.3, 4.0], [cx, 6.0]], closed=True, color=LB, alpha=0.5 + i*0.05, linewidth=1, edgecolor=BLUE, zorder=3) ax.add_patch(tri) ax.text(cx, 3.7, str(v)+"Δ", ha="center", va="center", fontsize=6.5, color=BLUE, fontweight="bold") ax.text(5, 7.0, "Horizontal Prism Bar (1–14 Δ shown)", ha="center", fontsize=7, color=BLUE) ax.text(5, 8.0, "Base-out → exodeviation", ha="center", fontsize=7.5, color=GRN) ax.text(5, 7.5, "Base-in → esodeviation", ha="center", fontsize=7.5, color=RED) ax.text(5, 9.5, "Prism Bar & Loose Prisms", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "1Δ = 0.57° = 1 cm deviation at 1 m", ha="center", fontsize=7, color=GREY, style="italic") save(fig, "prism_bar") # ───────────────────────────────────── # 21. Placido's Disc # ───────────────────────────────────── fig, ax = new_fig("placido") # Concentric rings colors_rings = [BLUE, WHT, BLUE, WHT, BLUE, WHT, BLUE, WHT] for i, col in enumerate(colors_rings): ax.add_patch(Circle((5, 5), 0.5 + i*0.5, color=col, zorder=i+2, linewidth=0)) # Central aperture ax.add_patch(Circle((5, 5), 0.35, color=BG, linewidth=2, edgecolor=GREY, zorder=10)) ax.text(5, 5, "👁", ha="center", va="center", fontsize=10, zorder=11) # Handle ax.add_patch(Rectangle((4.5, 0.5), 1, 1.4, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=10)) # Irregular cornea example ax2_x = [7.5, 7.8, 8.2, 8.0, 7.6, 7.5] ax2_y = [5, 5.5, 5.2, 4.8, 4.7, 5] ax.add_patch(Circle((8, 5), 1.5, color=WHT, linewidth=1, edgecolor=GREY, zorder=2, alpha=0.7)) for r, col2 in enumerate([BLUE, WHT, BLUE, WHT]): pts_x = [8 + (0.3+r*0.35)*math.cos(math.radians(a)) + 0.1*math.sin(math.radians(a*2)) for a in range(0, 361, 10)] pts_y = [5 + (0.3+r*0.35)*math.sin(math.radians(a)) + 0.1*math.cos(math.radians(a*3)) for a in range(0, 361, 10)] ax.plot(pts_x, pts_y, color=col2, lw=1.5, zorder=5) ax.text(8.0, 3.0, "Irregular\nrings =\nKeratoconus", ha="center", fontsize=6, color=RED) ax.text(5, 9.5, "Placido's Disc (Keratoscope)", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.2, "Qualitative corneal surface assessment | Invented 1880", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "placido") # ───────────────────────────────────── # 22. Specular Microscope (endothelial cells) # ───────────────────────────────────── fig, ax = new_fig("specular_microscope") # Microscope body ax.add_patch(FancyBboxPatch((1.5, 2), 7, 6.5, boxstyle="round,pad=0.3", color=LB, linewidth=2, edgecolor=BLUE, zorder=2)) # Display screen ax.add_patch(Rectangle((2.3, 5), 5.4, 3, color="#1a1a2e", linewidth=1, edgecolor=ORG, zorder=3)) # Hexagonal mosaic cells def draw_hex(cx, cy, r, col, lw=0.8): pts = [(cx + r*math.cos(math.radians(60*i+30)), cy + r*math.sin(math.radians(60*i+30))) for i in range(6)] ax.add_patch(Polygon(pts, closed=True, fill=False, edgecolor=col, linewidth=lw, zorder=4)) for row in range(5): for col2 in range(7): hx = 3.1 + col2*0.78 + (row%2)*0.39 hy = 5.3 + row*0.62 if 2.2 < hx < 7.8 and hy < 7.9: draw_hex(hx, hy, 0.35, GRN) # ECD readout ax.text(5, 4.6, "ECD: 2450 cells/mm² | CV: 32% | Hex: 58%", ha="center", va="center", fontsize=6, color=ORG, fontweight="bold") # Probe ax.add_patch(Rectangle((4.4, 2.0), 1.2, 1.5, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=4)) ax.text(5, 2.0, "Applanation probe", ha="center", fontsize=6, color=WHT) ax.text(5, 9.5, "Specular Microscope", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "Normal ECD: 2000–3000 cells/mm² | <500 → decompensation risk", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "specular_microscope") # ───────────────────────────────────── # 23. Lacrimal Syringe & Cannula # ───────────────────────────────────── fig, ax = new_fig("lacrimal_syringe") # Syringe barrel ax.add_patch(Rectangle((1.5, 3.8), 5.5, 2.4, color=LBLU, linewidth=2, edgecolor=LB, zorder=2)) # Plunger ax.add_patch(Rectangle((7.0, 3.8), 0.6, 2.4, color=GREY, linewidth=1, edgecolor=BLUE, zorder=3)) ax.add_patch(Rectangle((7.6, 3.5), 1.2, 3.0, color=GREY, linewidth=1, edgecolor=BLUE, zorder=3)) # Markings on syringe for i in range(5): x = 2.5 + i * 0.9 ax.plot([x, x], [3.8, 4.2], color=LB, lw=1, zorder=4) ax.text(x, 3.5, f"{i*0.5}", ha="center", fontsize=5.5, color=LB) ax.text(4.2, 6.5, "2 mL Syringe", ha="center", fontsize=7.5, color=BLUE, fontweight="bold") # Cannula (curved, blunt tip) ax.add_patch(Rectangle((0.5, 4.6), 1.2, 0.8, color=ORG, linewidth=1, edgecolor=BLUE, zorder=3)) ax.add_patch(FancyBboxPatch((0.2, 3.5), 0.5, 1.1, boxstyle="round,pad=0.1", color=ORG, linewidth=1, edgecolor=BLUE, zorder=4)) ax.text(0.8, 4.0, "23G blunt\ncannula", ha="center", fontsize=6, color=WHT, fontweight="bold") # Punctum dilator ax.add_patch(Rectangle((1.2, 1.5), 0.4, 2.2, color=RED, linewidth=1, edgecolor=BLUE, zorder=3)) ax.add_patch(Polygon([[1.2,1.5],[1.6,1.5],[1.4,1.0]], closed=True, color=RED, zorder=4)) ax.text(2.5, 1.5, "Punctum dilator", ha="left", fontsize=7, color=RED) ax.text(5, 9.5, "Lacrimal Syringe & Cannula", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "NLD patency assessment | Dacryocystitis irrigation", ha="center", fontsize=7, color=GREY, style="italic") save(fig, "lacrimal_syringe") # ───────────────────────────────────── # 24. Bowman's Probe # ───────────────────────────────────── fig, ax = new_fig("bowmans_probe") # Double-ended probe ax.add_patch(Rectangle((0.5, 4.5), 9.0, 0.7, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=2)) # Tapered ends tri_l = Polygon([[0.5,4.5],[0.5,5.2],[0.0,4.85]], closed=True, color=GREY, zorder=3) tri_r = Polygon([[9.5,4.5],[9.5,5.2],[10.0,4.85]], closed=True, color=GREY, zorder=3) ax.add_patch(tri_l); ax.add_patch(tri_r) # Textured middle section (grip) ax.add_patch(Rectangle((4.0, 4.3), 2.0, 1.1, color=LB, linewidth=1.5, edgecolor=BLUE, zorder=4)) ax.text(5, 4.85, "Handle\n(malleable)", ha="center", va="center", fontsize=6.5, color=WHT) # Size markings for i, sz in enumerate([0,1,2,3,4,5,6,7,8]): x = 0.9 + i * 0.9 ax.text(x, 5.5, str(sz), ha="center", fontsize=6, color=GREY) ax.text(5, 6.0, "← Sizes 0 (thin) to 8 (thick) →", ha="center", fontsize=7, color=GREY) # Probe path diagram ax.add_patch(Ellipse((5, 2.5), 4, 2.2, fill=False, linewidth=2, edgecolor=LB, zorder=5)) ax.text(5, 2.5, "Lacrimal\ncanal\npath", ha="center", va="center", fontsize=6.5, color=LB) ax.annotate("", xy=(5.2, 1.5), xytext=(5.0, 3.6), arrowprops=dict(arrowstyle="-|>", color=ORG, lw=1.5)) ax.text(5, 9.5, "Bowman's Lacrimal Probe", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.3, "Double-ended malleable | Sizes 0–8 | Hard stop = bony wall", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "bowmans_probe") # ───────────────────────────────────── # 25. Eye Speculum # ───────────────────────────────────── fig, ax = new_fig("eye_speculum") # Wire speculum shape ax.add_patch(Arc((5, 7), 6, 3, angle=0, theta1=0, theta2=180, color=GREY, lw=4, zorder=3)) ax.add_patch(Arc((5, 3), 6, 3, angle=0, theta1=180, theta2=360, color=GREY, lw=4, zorder=3)) ax.plot([2, 2], [5.5, 7], color=GREY, lw=4, zorder=3) ax.plot([8, 8], [5.5, 7], color=GREY, lw=4, zorder=3) ax.plot([2, 2], [3, 4.5], color=GREY, lw=4, zorder=3) ax.plot([8, 8], [3, 4.5], color=GREY, lw=4, zorder=3) # Eye in speculum ax.add_patch(Ellipse((5, 5), 5, 2.2, color=LBLU, linewidth=2, edgecolor=LB, zorder=4)) ax.add_patch(Circle((5, 5), 0.9, color="#1a3a5c", zorder=5)) ax.add_patch(Circle((5, 5), 0.5, color="#1a1a2e", zorder=6)) ax.add_patch(Circle((5.3, 5.3), 0.2, color=WHT, zorder=7)) # Handles ax.add_patch(Rectangle((1.5, 5.2), 0.6, 0.6, color=ORG, zorder=5)) ax.add_patch(Rectangle((7.9, 5.2), 0.6, 0.6, color=ORG, zorder=5)) ax.text(5, 9.5, "Eye Speculum", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 8.5, "(Wire / Universal speculum)", ha="center", fontsize=7, color=GREY, style="italic") ax.text(5, 0.5, "Keeps eyelids open during surgery / EUA", ha="center", fontsize=7, color=GREY, style="italic") save(fig, "eye_speculum") # ───────────────────────────────────── # 26. Chalazion Forceps # ───────────────────────────────────── fig, ax = new_fig("chalazion_forceps") # Two arms ax.plot([3, 5], [8.5, 5.5], color=GREY, lw=5, zorder=3, solid_capstyle="round") ax.plot([7, 5], [8.5, 5.5], color=GREY, lw=5, zorder=3, solid_capstyle="round") # Screw pivot ax.add_patch(Circle((5, 5.5), 0.5, color=ORG, zorder=5)) ax.text(5, 5.5, "⊕", ha="center", va="center", fontsize=10, color=WHT) # Discoid plate (upper) ax.add_patch(Ellipse((5, 3.5), 3.5, 2.0, color=LB, linewidth=2, edgecolor=BLUE, zorder=4)) ax.text(5, 3.5, "Oval ring\n(skin side)", ha="center", va="center", fontsize=7, color=WHT) # Ring (lower — conjunctival) ax.add_patch(Ellipse((5, 1.5), 2.5, 1.3, color=LB, linewidth=2.5, edgecolor=BLUE, fill=False, zorder=4)) ax.add_patch(Ellipse((5, 1.5), 2.5, 1.3, color=LBLU, linewidth=0, zorder=3)) ax.text(5, 1.5, "Discoid plate\n(conjunctival)", ha="center", va="center", fontsize=7, color=BLUE, fontweight="bold") # Handles ax.add_patch(FancyBboxPatch((2.2, 8.2), 1.2, 1.3, boxstyle="round,pad=0.15", color=GREY, linewidth=1, edgecolor=BLUE, zorder=4)) ax.add_patch(FancyBboxPatch((6.6, 8.2), 1.2, 1.3, boxstyle="round,pad=0.15", color=GREY, linewidth=1, edgecolor=BLUE, zorder=4)) ax.text(5, 9.5, "Chalazion Forceps (Clamp)", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "Chalazion I&C | Vertical conjunctival incision", ha="center", fontsize=7, color=GREY, style="italic") save(fig, "chalazion_forceps") # ───────────────────────────────────── # 27. Castroviejo Calipers # ───────────────────────────────────── fig, ax = new_fig("castroviejo_calipers") # Scale bar ax.add_patch(Rectangle((1, 4.7), 8, 0.5, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=2)) for i in range(21): x = 1 + i * 0.4 h = 0.6 if i % 5 == 0 else 0.3 ax.plot([x, x], [5.2, 5.2 + h], color=BLUE, lw=1.5, zorder=3) if i % 5 == 0: ax.text(x, 6.1, str(i), ha="center", fontsize=6.5, color=BLUE) ax.text(5, 6.7, "mm scale", ha="center", fontsize=6.5, color=GREY) # Two tips ax.plot([1, 1], [3.5, 4.7], color=LB, lw=3, zorder=3) ax.plot([1, 0.7], [3.5, 3.0], color=LB, lw=2, zorder=3) ax.add_patch(Circle((0.7, 2.9), 0.15, color=RED, zorder=5)) ax.plot([5, 5], [3.5, 4.7], color=LB, lw=3, zorder=3) ax.plot([5, 5.3], [3.5, 3.0], color=LB, lw=2, zorder=3) ax.add_patch(Circle((5.3, 2.9), 0.15, color=RED, zorder=5)) ax.annotate("", xy=(5.3, 2.9), xytext=(0.7, 2.9), arrowprops=dict(arrowstyle="<->", color=RED, lw=2)) ax.text(3, 2.4, "Measured distance", ha="center", fontsize=7, color=RED, fontweight="bold") ax.text(5, 9.5, "Castroviejo Calipers", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "Surgical measurements: WTW, limbal marking, IOL axis, strabismus", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "castroviejo_calipers") # ───────────────────────────────────── # 28. Muscle Hook (Squint Hook) # ───────────────────────────────────── fig, ax = new_fig("muscle_hook") # Handle ax.add_patch(Rectangle((4.3, 0.5), 1.4, 5.5, color=GREY, linewidth=1.5, edgecolor=BLUE, zorder=2)) for y in np.arange(1, 5.5, 0.4): ax.plot([4.3, 5.7], [y, y], color=BLUE, lw=0.8, zorder=3) # Curved shaft pts_x = [5, 5, 5.5, 6.5, 7.2, 7.5] pts_y = [6.0, 7.5, 8.5, 9.0, 9.2, 9.2] ax.plot(pts_x, pts_y, color=GREY, lw=4, zorder=3, solid_capstyle="round") # Hook tip ax.add_patch(Arc((7.2, 8.5), 0.8, 0.8, angle=0, theta1=270, theta2=90, color=GREY, lw=4)) ax.add_patch(Circle((7.6, 8.5), 0.18, color=RED, zorder=5)) ax.text(8.2, 8.5, "Blunt\ntip", ha="left", fontsize=6.5, color=RED) # Muscle being hooked ax.add_patch(Ellipse((5.5, 7.8), 4, 0.9, color=ORG, alpha=0.5, linewidth=2, edgecolor=ORG, zorder=4)) ax.text(5.5, 7.8, "Extraocular muscle", ha="center", va="center", fontsize=7, color=BLUE, fontweight="bold") ax.text(5, 9.7, "Muscle Hook (Squint Hook)", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.2, "Von Graefe's (rectus) | Green's (oblique muscles)", ha="center", fontsize=7, color=GREY, style="italic") save(fig, "muscle_hook") # ───────────────────────────────────── # 29. Volk 90D Lens # ───────────────────────────────────── fig, ax = new_fig("volk_90d") # Lens body ax.add_patch(Ellipse((5, 5), 5, 5, color=LBLU, linewidth=3, edgecolor=LB, zorder=2, alpha=0.8)) ax.add_patch(Ellipse((5, 5), 3.8, 3.8, color=LBLU, linewidth=1, edgecolor=LB, zorder=3, alpha=0.6)) # Antireflective coating shimmer for angle in range(0, 360, 30): r = 1.6; rad = math.radians(angle) ax.plot([5+r*math.cos(rad)*0.8, 5+r*math.cos(rad)*1.2], [5+r*math.sin(rad)*0.8, 5+r*math.sin(rad)*1.2], color="cyan", lw=1, alpha=0.5, zorder=4) # Power label ax.text(5, 5, "+90D", ha="center", va="center", fontsize=18, color=BLUE, fontweight="bold", zorder=5) ax.text(5, 3.5, "Aspheric handheld\ncondensing lens", ha="center", fontsize=7, color=BLUE) # Field of view annotation arc_fov = Arc((5, 5), 6.5, 6.5, angle=0, theta1=60, theta2=120, color=ORG, lw=2.5) ax.add_patch(arc_fov) ax.text(5, 8.6, "60° FOV", ha="center", fontsize=7, color=ORG, fontweight="bold") ax.text(5, 1.5, "Non-contact | No coupling gel", ha="center", fontsize=7.5, color=GRN, fontweight="bold") ax.text(5, 0.9, "Image: inverted + reversed (real image)", ha="center", fontsize=6.5, color=GREY, style="italic") ax.text(5, 9.6, "Volk +90D Lens", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "volk_90d") # ───────────────────────────────────── # 30. Fundus Camera # ───────────────────────────────────── fig, ax = new_fig("fundus_camera") # Base ax.add_patch(Rectangle((1.5, 0.4), 7, 1.2, color=GREY, zorder=1)) ax.add_patch(Rectangle((3.8, 1.6), 2.4, 1.5, color=GREY, zorder=2)) # Camera body ax.add_patch(FancyBboxPatch((2, 3), 6, 5, boxstyle="round,pad=0.3", color=LB, linewidth=2, edgecolor=BLUE, zorder=3)) # Lens barrel (front) ax.add_patch(Circle((5, 5.5), 1.8, color=BLUE, linewidth=2, edgecolor=BLUE, zorder=4)) ax.add_patch(Circle((5, 5.5), 1.3, color="#1a1a2e", zorder=5)) ax.add_patch(Circle((5, 5.5), 0.5, color=LBLU, zorder=6)) # Flash housing ax.add_patch(Circle((3.0, 7.2), 0.6, color=ORG, zorder=4)) ax.text(3.0, 7.2, "⚡", ha="center", va="center", fontsize=9) # Digital camera body ax.add_patch(Rectangle((6.5, 6.8), 1.3, 0.9, color=GREY, linewidth=1, edgecolor=BLUE, zorder=5)) ax.text(7.1, 7.25, "CCD", ha="center", va="center", fontsize=6, color=WHT, fontweight="bold") ax.text(5, 8.8, "30°–45° standard field", ha="center", fontsize=7, color=LBLU, fontweight="bold") ax.text(5, 0.2, "FA: excitation 490nm | Barrier 530nm", ha="center", fontsize=6.5, color=GREY, style="italic") ax.text(5, 9.7, "Fundus Camera", ha="center", fontsize=9, fontweight="bold", color=BLUE) save(fig, "fundus_camera") # ───────────────────────────────────── # 31. OCT # ───────────────────────────────────── fig, ax = new_fig("oct") ax.add_patch(FancyBboxPatch((0.8, 1), 8.4, 7.5, boxstyle="round,pad=0.3", color=LB, linewidth=2, edgecolor=BLUE, zorder=2)) # OCT scan display ax.add_patch(Rectangle((1.5, 4.5), 7, 3.5, color="#1a1a2e", linewidth=1, edgecolor=ORG, zorder=3)) # Retinal layers (pseudo-OCT) layer_ys = [7.5, 7.2, 6.9, 6.6, 6.3, 6.1, 5.8, 5.5, 5.2, 4.9] layer_cols = [WHT,"#aaa",WHT,"#888",WHT,"#666",WHT,"#aaa",WHT,"#888"] for i, (ly, lc) in enumerate(zip(layer_ys, layer_cols)): noise = [0.06*math.sin(j*0.9+i) for j in range(50)] xs = [1.5 + j*0.14 for j in range(50)] ys = [ly + noise[j] for j in range(50)] ax.plot(xs, ys, color=lc, lw=1.0, zorder=4) # Label layers ax.text(8.3, 7.2, "NFL", ha="right", fontsize=5.5, color=GRN, zorder=5) ax.text(8.3, 6.3, "INL", ha="right", fontsize=5.5, color=GRN, zorder=5) ax.text(8.3, 5.5, "ONL", ha="right", fontsize=5.5, color=GRN, zorder=5) ax.text(8.3, 4.9, "RPE", ha="right", fontsize=5.5, color=ORG, zorder=5) # CST readout ax.add_patch(Rectangle((1.5, 2.0), 3.5, 1.8, color=GREY, linewidth=1, edgecolor=ORG, zorder=3)) ax.text(3.25, 2.9, "CST: 248 μm", ha="center", va="center", fontsize=7, color=ORG, fontweight="bold") ax.text(3.25, 2.3, "Normal: ~250 μm", ha="center", fontsize=6, color=WHT) ax.add_patch(Rectangle((5.5, 2.0), 3, 1.8, color=GREY, linewidth=1, edgecolor=LB, zorder=3)) ax.text(7.0, 2.9, "RNFL: avg 98μm", ha="center", va="center", fontsize=7, color=LB, fontweight="bold") ax.text(7.0, 2.3, "ISNT rule", ha="center", fontsize=6, color=WHT) ax.text(5, 9.5, "Optical Coherence Tomography (OCT)", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "SD-OCT | SS-OCT | 3–10 μm axial resolution | Low-coherence interferometry", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "oct") # ───────────────────────────────────── # 32. B-Scan Ultrasound # ───────────────────────────────────── fig, ax = new_fig("bscan") # Probe ax.add_patch(FancyBboxPatch((3.8, 5.5), 2.4, 4, boxstyle="round,pad=0.3", color=LB, linewidth=2, edgecolor=BLUE, zorder=3)) ax.add_patch(Rectangle((4.4, 5.2), 1.2, 0.5, color=GREY, zorder=4)) ax.text(5, 8, "10 MHz\nProbe", ha="center", va="center", fontsize=8, color=WHT, fontweight="bold") # B-scan image (simplified eye globe) ax.add_patch(Circle((5, 2.5), 2.5, color=WHT, linewidth=2, edgecolor=GREY, zorder=2)) # Globe structures ax.add_patch(Circle((5, 2.5), 2.3, color="#1a1a2e", zorder=3)) # Retinal detachment echo rd_pts_x = [3.2 + 0.3*math.cos(math.radians(a)) for a in range(-60, 60)] rd_pts_y = [2.5 + 1.8*math.sin(math.radians(a+10)) for a in range(-60, 60)] ax.plot(rd_pts_x, rd_pts_y, color=GRN, lw=2.5, zorder=5) ax.text(3.6, 1.2, "Retinal\ndetachment\necho", ha="center", fontsize=5.5, color=GRN, zorder=5) ax.text(5, 9.5, "B-Scan Ultrasonography", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "10 MHz | Opaque media | RD, vitreous haemorrhage, tumours", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "bscan") # ───────────────────────────────────── # 33. A-Scan / IOL Master # ───────────────────────────────────── fig, ax = new_fig("iol_master") ax.add_patch(FancyBboxPatch((1, 1.5), 8, 7, boxstyle="round,pad=0.3", color=LB, linewidth=2, edgecolor=BLUE, zorder=2)) # Screen ax.add_patch(Rectangle((2, 5), 6, 3, color="#1a1a2e", linewidth=1, edgecolor=ORG, zorder=3)) ax.text(5, 7.0, "IOL Master 700", ha="center", fontsize=9, color=ORG, fontweight="bold") ax.text(5, 6.3, "AL: 23.41 mm", ha="center", fontsize=8, color=GRN) ax.text(5, 5.8, "K1: 43.50 D K2: 44.25 D", ha="center", fontsize=7.5, color=WHT) ax.text(5, 5.3, "ACD: 3.62 mm", ha="center", fontsize=7.5, color=WHT) # IOL formula result ax.add_patch(Rectangle((2.5, 2.5), 5, 2.0, color=GRN, alpha=0.2, linewidth=1.5, edgecolor=GRN, zorder=4)) ax.text(5, 3.5, "Barrett Universal II:", ha="center", fontsize=8, color=GRN, fontweight="bold") ax.text(5, 3.0, "IOL power: +21.50 D", ha="center", fontsize=8, color=GRN) # Info ax.text(5, 2.1, "Partial coherence interferometry (PCI)", ha="center", fontsize=6.5, color=GREY) ax.text(5, 9.5, "IOL Master / A-Scan Biometry", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.4, "Non-contact | AL most critical: 1 mm error = ~2.7D IOL error", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "iol_master") # ───────────────────────────────────── # 34. Volk +78D / Mainster as a separate entry # ───────────────────────────────────── fig, ax = new_fig("mainster") ax.add_patch(Circle((5, 5.5), 3.5, color=LBLU, linewidth=3, edgecolor=LB, zorder=2, alpha=0.85)) ax.add_patch(Circle((5, 5.5), 2.7, color=WHT, linewidth=1.5, edgecolor=LB, zorder=3, alpha=0.7)) ax.text(5, 5.5, "+78D\nVolk Lens", ha="center", va="center", fontsize=14, color=BLUE, fontweight="bold", zorder=4) # Coupling gel ring ax.add_patch(Circle((5, 5.5), 3.5, color=LBLU, linewidth=6, edgecolor=ORG, fill=False, zorder=5)) ax.text(5, 1.7, "Contact lens → coupling gel required", ha="center", fontsize=7, color=ORG, fontweight="bold") # FOV arc arc_fov2 = Arc((5, 5.5), 8, 8, angle=0, theta1=63, theta2=117, color=GRN, lw=2.5) ax.add_patch(arc_fov2) ax.text(5, 9.7, "+78D: 48° FOV | +90D: 60° FOV", ha="center", fontsize=7, color=GRN, fontweight="bold") ax.text(5, 1.2, "+78D: 7.2x magnification", ha="center", fontsize=7, color=GREY) ax.text(5, 9.1, "Volk +78D / Mainster Lens", ha="center", fontsize=9, fontweight="bold", color=BLUE) ax.text(5, 0.5, "Fundus biomicroscopy via slit lamp | Image: inverted + reversed", ha="center", fontsize=6.5, color=GREY, style="italic") save(fig, "mainster") print(f"\nAll done. Images in: {OUT}") import os files = os.listdir(OUT) print(f"Total: {len(files)} files") PYEOF python3 /tmp/workspace/ophthalmology-instruments/draw_instruments.py
cat << 'PYEOF' > /tmp/workspace/ophthalmology-instruments/final_pdf.py import os, math from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import cm from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Image, Table, TableStyle, PageBreak, HRFlowable, KeepTogether) from reportlab.pdfgen import canvas from PIL import Image as PILImage OUTPUT = "/tmp/workspace/ophthalmology-instruments/Ophthalmology_Instruments_PG_Exam.pdf" IMG_DIR = "/tmp/workspace/ophthalmology-instruments/img_cache" PAGE_W, PAGE_H = A4 MARGIN = 1.8*cm DARK_BLUE = colors.HexColor("#1a3a5c") MED_BLUE = colors.HexColor("#2563a8") LIGHT_BLUE = colors.HexColor("#dbeafe") ORANGE = colors.HexColor("#d97706") GREEN = colors.HexColor("#059669") GREY = colors.HexColor("#6b7280") L_GREY = colors.HexColor("#f3f4f6") WHITE = colors.white BLACK = colors.black def sty(name, **kw): return ParagraphStyle(name, **kw) INSTR_TITLE = sty("IT", fontName="Helvetica-Bold", fontSize=14, textColor=DARK_BLUE, spaceAfter=3, spaceBefore=2) SEC_LBL = sty("SL", fontName="Helvetica-Bold", fontSize=8, textColor=WHITE, spaceAfter=0) BULLET = sty("BU", fontName="Helvetica", fontSize=9, textColor=BLACK, spaceAfter=2, spaceBefore=0, leading=12, leftIndent=8) FOOTER_S = sty("FT", fontName="Helvetica", fontSize=7, textColor=GREY, alignment=TA_CENTER) CAT_S = sty("CS", fontName="Helvetica-Bold", fontSize=11, textColor=WHITE, alignment=TA_CENTER) TOC_CAT = sty("TC", fontName="Helvetica-Bold", fontSize=9, textColor=DARK_BLUE) TOC_ITEM = sty("TI", fontName="Helvetica", fontSize=8.5, textColor=BLACK, leading=13) def on_page(c, doc): pn = c.getPageNumber() if pn == 1: return c.saveState() c.setFillColor(DARK_BLUE) c.rect(0, PAGE_H - 1.1*cm, PAGE_W, 1.1*cm, fill=1, stroke=0) c.setFillColor(WHITE); c.setFont("Helvetica-Bold", 7.5) c.drawString(MARGIN, PAGE_H - 0.75*cm, "Ophthalmic Instruments — PG Practical Exam Reference") c.setFont("Helvetica", 7.5) c.drawRightString(PAGE_W - MARGIN, PAGE_H - 0.75*cm, f"Page {pn}") c.setStrokeColor(LIGHT_BLUE); c.setLineWidth(0.5) c.line(MARGIN, 0.9*cm, PAGE_W - MARGIN, 0.9*cm) c.setFillColor(GREY); c.setFont("Helvetica", 6.5) c.drawCentredString(PAGE_W/2, 0.5*cm, "Based on Kanski's Clinical Ophthalmology (10th Ed.) & standard PG references | For educational use") c.restoreState() def load_img(name, max_w, max_h): path = os.path.join(IMG_DIR, f"{name}.png") if not os.path.exists(path): return None with PILImage.open(path) as im: w, h = im.size scale = min(max_w/w, max_h/h) return Image(path, width=w*scale, height=h*scale) INSTRUMENTS = [ {"cat":"Examination & Diagnostic Instruments","name":"Slit Lamp Biomicroscope","img":"slit_lamp", "parts":["Illumination system: slit beam, condenser, diaphragm, filters (diffuse/cobalt blue/red-free)","Observation: binocular microscope, 10x eyepieces, 0.6x–4x objectives (6x–40x total)","Joystick XYZ movement; chinrest and forehead rest","Magnification changer, fixation target"], "uses":["Anterior segment: lids, conjunctiva, cornea, iris, lens, anterior vitreous","Posterior segment: with +78D/+90D Volk or Goldman 3-mirror lens","Gonioscopy (with gonioscopic lens); applanation tonometry (Goldman attachment)","Laser delivery; fundus biomicroscopy; lesion measurement"], "exam":["Inventor: Allvar Gullstrand (1911); improved by Goldman","Illumination modes: diffuse, direct focal, retroillumination, specular reflection, sclerotic scatter, indirect proximal","Cobalt blue filter + fluorescein: detects corneal epithelial defects","With +90D: ~5.8x mag, image inverted & reversed (real image)","Standard anterior segment magnification: 16x–25x"]}, {"cat":"Examination & Diagnostic Instruments","name":"Direct Ophthalmoscope","img":"direct_ophthalmoscope", "parts":["Battery handle with rheostat for light intensity","Aperture wheel: large, small, fixation, slit, red-free (green) beam","Lens wheel: +20D to -20D in steps","Plane mirror with peephole"], "uses":["Monocular fundus exam: optic disc, macula, retinal vessels","Red reflex assessment; lens and anterior vitreous evaluation","Objective refraction estimation"], "exam":["Invented by Hermann von Helmholtz, 1851","Magnification: ~15x (both examiner and patient emmetropic)","Image: erect (upright), virtual, magnified","Working distance: 2.5–3 cm from patient's eye","Field of view: ~5° — narrow; one disc area at a time","Red-free (green) beam: enhances RNFL, haemorrhages, vessels"]}, {"cat":"Examination & Diagnostic Instruments","name":"Binocular Indirect Ophthalmoscope (BIO)","img":"bio", "parts":["Head-mounted unit with battery/transformer","Binocular eyepieces (3.5x magnification)","Bright halogen/LED coaxial light source","Condensing lens (+20D, +28D, +30D) held by examiner","Optional teaching mirror attachment"], "uses":["Wide-field retinal exam including periphery","Retinal detachment evaluation; ROP screening","Scleral indentation with depressor; intraoperative fundus view","Laser delivery for retinal breaks and PRP"], "exam":["Invented by Charles Schepens, 1947 — 'father of retinal surgery'","With +20D lens: ~3x magnification, ~40–50° field","With +28D lens: ~2x magnification, wider field","Image: INVERTED (upside-down) and REVERSED — REAL aerial image formed between lens and eye","Binocular eyepieces provide stereopsis (3D depth)","Working distance from patient: ~50 cm"]}, {"cat":"Examination & Diagnostic Instruments","name":"Retinoscope","img":"retinoscope", "parts":["Battery handle","Streak head with rotating sleeve (changes streak meridian)","Plane mirror with peephole; built-in +2D lens in some models"], "uses":["Objective determination of refractive error (no patient cooperation needed)","Essential for children, mentally challenged, non-verbal patients","Detecting irregular astigmatism and keratoconus","Assessing media clarity"], "exam":["Type: Streak retinoscope (Copeland) most common; also spot/plane mirror type","Working distance: 67 cm (+1.5D correction) or 1 m (+1D correction)","'With' movement → hypermetropia or high myopia beyond far point → neutralise with PLUS","'Against' movement → myopia within far point → neutralise with MINUS","Reversal (no movement) → patient's far point at working distance","Scissors reflex: irregular astigmatism; dark crescent: early keratoconus"]}, {"cat":"Tonometry","name":"Goldmann Applanation Tonometer (GAT)","img":"goldmann_tonometer", "parts":["Biprism: split prism producing two green semicircular mires","Spring-loaded measuring drum (calibrated 0–80 mmHg, scale 0–8)","Cobalt blue filter holder","Slit-lamp mounting arm"], "uses":["IOP measurement — GOLD STANDARD","Glaucoma screening and long-term monitoring"], "exam":["Principle: Imbert-Fick law — P = F/A (pressure = force ÷ area)","Flattening area: 3.06 mm diameter (balances surface tension and tear film capillary forces)","With fluorescein + cobalt blue: two semicircular mires; endpoint = inner edges just touching","Scale reading × 10 = IOP in mmHg","Normal IOP: 10–21 mmHg","THICK cornea → OVERESTIMATES IOP; THIN cornea → UNDERESTIMATES","Requires topical anaesthesia (proparacaine/tetracaine) + fluorescein sodium","Contraindicated: active corneal infection, large corneal abrasion"]}, {"cat":"Tonometry","name":"Schiotz Tonometer","img":"schiotz_tonometer", "parts":["Footplate with 3 mm central aperture","Plunger: base weight 5.5 g","Scale: 0–20 units","Additional weights: 7.5 g, 10 g, 15 g","Test block for zeroing calibration"], "uses":["IOP measurement by indentation","Bedside, ICU, theatre use (no slit lamp needed)"], "exam":["Type: Impression (indentation) tonometer","Principle: plunger indents cornea; scale reading → IOP via Friedenwald tables","Patient supine; footplate on anaesthetised cornea","HIGH scale reading = LOW IOP (soft eye); LOW scale reading = HIGH IOP (hard eye)","Ocular rigidity errors: rigid cornea/sclera → falsely low reading","Sterilise with 70% alcohol (NOT autoclave — damages calibration)","Less accurate than GAT; affected by ocular rigidity"]}, {"cat":"Tonometry","name":"Non-Contact Tonometer (Air-Puff)","img":"nct", "parts":["Air delivery nozzle","Photodetector detecting corneal deformation","Electronic digital display","Automated alignment system"], "uses":["IOP screening (no corneal contact = no infection risk)","Mass screening, paediatric patients, contact lens wearers"], "exam":["Air puff flattens 3.6 mm corneal area; photodetector detects moment of applanation","NO anaesthesia, NO fluorescein required","Least accurate tonometer; over-reads high IOP, under-reads very high IOP","Affected by CCT (central corneal thickness) and corneal irregularity","Not reliable for irregular corneas (post-LASIK, keratoconus)"]}, {"cat":"Gonioscopy Lenses","name":"Goldmann Three-Mirror Lens","img":"g3mirror", "parts":["Central lens (posterior pole, 30° from axis)","Equatorial mirror (rectangle, 67°): peripheral retina","Peripheral mirror (truncated oval, 75°): far periphery, pars plana","Gonioscopy mirror (dome/smallest, 59°): anterior chamber angle"], "uses":["Gonioscopy — iridocorneal drainage angle examination","Peripheral retina, pars plana, vitreous base evaluation","Argon laser trabeculoplasty (ALT), panretinal photocoagulation (PRP)","Slit-lamp assisted retinal laser procedures"], "exam":["Coupling gel required: 2.5% methylcellulose","Image: INVERTED and MIRROR-REVERSED","Mirror at bottom of lens → examiner views SUPERIOR angle structures","Rotate 360° to view all angle quadrants","Tilt slit lamp 14–15° forward to use the angle mirror","INDIRECT gonioscopy type (opposite quadrant visible)"]}, {"cat":"Gonioscopy Lenses","name":"Zeiss Four-Mirror Gonioscope","img":"zeiss4mirror", "parts":["Four mirrors at 64° each (all 4 quadrants accessible)","Smaller diameter than Goldmann","No coupling gel required — uses tear film"], "uses":["Dynamic indentation gonioscopy","Differentiates appositional vs. synechial angle closure","Preferred for narrow angle/angle-closure evaluation"], "exam":["NO coupling agent — major advantage over Goldmann","Indentation gonioscopy: pressure compresses cornea → aqueous pushed into angle → opens appositional closure","Cannot be used for laser procedures","Indirect type; less stable during exam","Best for short, focused gonioscopic assessment"]}, {"cat":"Refraction Instruments","name":"Trial Lens Set & Trial Frame","img":"trial_lens", "parts":["Spherical lenses: +0.12D to +20D; -0.12D to -20D","Cylindrical lenses: +0.12D to +6D; -0.12D to -6D","Prisms (1Δ–12Δ) and prism bars","Accessories: occluder, pinhole, Maddox rod, red/green lenses, JCC","Trial frame: adjustable PD, vertex distance, pantoscopic tilt"], "uses":["Subjective refraction (sphere, cylinder, axis)","Binocular vision and orthoptic testing","Low vision aid prescription"], "exam":["Spheres placed in BACK cell; cylinders in FRONT cell of trial frame","Maximum plus principle: most plus giving best VA (relaxes accommodation)","JCC (+0.25/-0.50D): flip test to refine cylinder axis and power","Fogging technique: add plus to fog, then reduce to first clear step","BCVA = best corrected visual acuity with optimal lens combination"]}, {"cat":"Refraction Instruments","name":"Keratometer (Javal-Schiötz / B&L)","img":"keratometer", "parts":["Mire targets: 2 (Javal-Schiötz) or 4 (B&L) luminous targets","Telescope/microscope for observing corneal reflections","Measurement drums for horizontal and vertical meridians","Chinrest and forehead bar"], "uses":["Measuring corneal curvature: K1 (flat meridian) and K2 (steep meridian)","Diagnosing and quantifying corneal astigmatism","Contact lens base curve selection; IOL biometry; keratoconus screening"], "exam":["Javal-Schiötz: variable doubling, fixed object; B&L: fixed doubling, variable object","Measures ONLY the central 3–4 mm corneal zone","Normal K: 42–44 D; K1–K2 difference >1D = clinically significant astigmatism","Irregular mires → irregular astigmatism or surface pathology (e.g. keratoconus)","r = (n-1)/D where n = 1.3375 (conventional keratometric index)"]}, {"cat":"Refraction Instruments","name":"Lensometer (Focimeter)","img":"lensometer", "parts":["Eyepiece (telescope with graticule)","Sphere and cylinder power drums","Axis wheel","Lens stop supporting the spectacle lens","Illuminated crosslines/dot/star target"], "uses":["Measuring spectacle lens power: sphere, cylinder, axis","Checking prismatic power and centration","Marking optical centres on lenses before dispensing"], "exam":["Also called vertometer (UK: focimeter)","Measures BACK vertex power of lens","Spherical lens: all target lines sharp simultaneously","Astigmatic lens: one set of lines clear first, then the other (difference = cylinder power)","Prism in diopters (Δ): 1Δ = 1 cm deviation at 1 m (target displaced from optical centre)","Automated lensmeters: direct digital readout of sphere, cylinder, axis, add, PD"]}, {"cat":"Refraction Instruments","name":"Phoropter (Refractor Head)","img":"phoropter", "parts":["Two rotating lens discs (OD and OS)","Sphere: +16.75D to -19D; Cylinder: 0 to ±6D","Built-in accessories: JCC, Maddox rod, prisms, occluder, pinhole, polaroid filters","Interpupillary distance (PD) adjustment"], "uses":["Subjective refraction — monocular and binocular balance","Accommodation and binocular vision testing","Phoria and strabismus assessment with Maddox rod and prisms"], "exam":["More efficient than trial frame — rapid lens changes","May not accurately represent real spectacle vertex distance for high powers (>5D)","Automated/digital phoropters now integrate with autorefractors","Not suitable for prescribing tinted lenses or special lens forms"]}, {"cat":"Refraction Instruments","name":"Jackson Cross Cylinder (JCC)","img":"jcc", "parts":["Combined lens: +0.25/-0.50D or +0.50/-1.00D","Handle positioned at 45° between the two lens axes","Red dot: minus cylinder axis; White dot: plus cylinder axis"], "uses":["Refinement of astigmatism axis and power in subjective refraction","Used in trial frame or built into phoropter"], "exam":["AXIS check: handle aligned with working cylinder axis; flip to find sharper position","POWER check: red dot aligned with cylinder axis; flip to find sharper position","Flip test: patient chooses position 1 or 2 — adjust in direction of preferred flip","Higher power JCC (+0.50/-1.00D) used for higher cylinders (>2D)","Final endpoint: both flips appear equally clear (straddle the blur circle)"]}, {"cat":"Visual Acuity","name":"Snellen Chart","img":"snellen", "parts":["Chart with optotypes (letters/numbers/tumbling-E/Landolt C) in decreasing sizes","Standard testing distance: 6 m (20 ft); or 3 m with mirror","Illuminated backlite or printed format; ETDRS chart for research"], "uses":["Distance visual acuity (VA) measurement","Recording unaided (UCVA) and best-corrected (BCVA) VA"], "exam":["Each letter subtends 5' arc at stated distance; each limb subtends 1'","6/6 (20/20): normal distance VA — reads at 6m what normal eye reads at 6m","<6/60: test for CF (count fingers), HM (hand movements), PL, NPL","LogMAR = -log10(Snellen fraction): 6/6 = 0.0; 6/60 = 1.0; 6/12 = 0.3","Near vision: Jaeger (J1 = ~6/6), N-notation, M-notation"]}, {"cat":"Visual Acuity","name":"Pinhole Occluder","img":"pinhole", "parts":["Opaque disc with 1–3 holes (1–1.5 mm diameter)","Used in trial frame or held manually in front of eye"], "uses":["Differentiates refractive from organic cause of reduced VA","Quick screening tool for correctable visual impairment"], "exam":["Allows only paraxial rays through → eliminates effect of refractive error","IMPROVEMENT with pinhole → refractive error or media opacity (correctable cause)","NO improvement → amblyopia, macular or optic nerve pathology","PARADOXICAL WORSENING: posterior subcapsular cataract (diffraction scatter), central macular disease"]}, {"cat":"Visual Field Testing","name":"Goldmann Perimeter","img":"goldmann_perimeter", "parts":["Hemispheric bowl (33 cm radius, uniform white background 31.5 asb)","Moveable fixation device and central fixation target","Variable targets: size I–V, intensities 1–4 (a–e subscripts)","Manual plotting chart; examiner eyepiece"], "uses":["Manual kinetic and static perimetry","Plotting isopters and mapping scotomas","Neurological field defects, medico-legal assessments, advanced field loss"], "exam":["Kinetic: target moved periphery→centre; patient responds when first seen","Isopter: line connecting points of equal sensitivity (like a contour line)","Standard target for most patients: III4e","Classic glaucoma defects: inferior nasal step, arcuate scotoma (Bjerrum's), double arcuate","Enlarging blind spot, altitudinal defects in ischaemic optic neuropathy"]}, {"cat":"Visual Field Testing","name":"Humphrey Field Analyser (HFA)","img":"humphrey", "parts":["Automated static perimeter with bowl","SITA algorithm (SITA-Standard, SITA-Fast, SITA-Faster)","Stimulus projection system","Foveal sensitivity measurement; gaze tracker"], "uses":["Automated static perimetry: glaucoma diagnosis and monitoring","Neurological field defects: hemianopia, quadrantanopia","Objective field documentation with reliability indices"], "exam":["SITA: Swedish Interactive Thresholding Algorithm","24-2: 54 points, central 24° — standard for glaucoma","30-2: 76 points, 30°; 10-2: 68 points, central 10° (macular testing)","Reliability: fixation losses <20%, false positives <15%, false negatives <33%","MD (Mean Deviation): overall field loss; PSD (Pattern SD): localised loss","GHT (Glaucoma Hemifield Test): compares superior vs inferior 5 arcuate zones"]}, {"cat":"Strabismus Assessment","name":"Maddox Rod","img":"maddox_rod", "parts":["Series of parallel red high-power cylindrical lenses","Circular holder for trial frame (fits standard ring cell)","Usually red for right eye; white/blue for left eye"], "uses":["Detection and measurement of heterophoria (latent squint)","Measuring cyclotorsion (fourth nerve palsy)","Dissociation of binocular vision for phoria testing"], "exam":["Point source of light → perpendicular line (streak) through cylindrical rod","ESOPHORIA: streak on SAME side as rod (uncrossed diplopia)","EXOPHORIA: streak on OPPOSITE side (crossed diplopia)","Double Maddox rod test: red + white rods → assesses torsional deviation (cyclotorsion)","Used at 6 m for distance, 33 cm for near phorias"]}, {"cat":"Strabismus Assessment","name":"Prism Bar & Loose Prisms","img":"prism_bar", "parts":["Horizontal prism bar: 1–40 prism diopters (Δ)","Vertical prism bar","Loose prisms in trial set (1Δ–40Δ)"], "uses":["Measuring angle of squint (prism and cover test — PCT)","Diagnosis and quantification of phorias and tropias"], "exam":["1 prism diopter (Δ) = 0.57° = 1 cm deviation at 1 m","Base-out: corrects exodeviation; Base-in: corrects esodeviation","Base-down: corrects hyperdeviation; Base-up: corrects hypodeviation","PCT: gold standard for measuring all deviations (combination of prism + alternate cover test)","Apex toward direction of deviation; base opposite"]}, {"cat":"Cornea & Anterior Segment","name":"Placido's Disc (Keratoscope)","img":"placido", "parts":["Concentric alternating black and white rings on flat disc","Central aperture for observation","Handle"], "uses":["Qualitative corneal surface regularity assessment","Screening for irregular astigmatism, keratoconus, pterygium"], "exam":["Invented by Antonio Placido, 1880","Regular round rings → normal cornea","Oval/elliptical rings → regular astigmatism","Irregular/distorted rings → keratoconus, corneal scarring, surface irregularity","Modern equivalent: computerised corneal topographer (videokeratography)","Only QUALITATIVE — keratometer gives quantitative measurements"]}, {"cat":"Cornea & Anterior Segment","name":"Specular Microscope","img":"specular_microscope", "parts":["Specular reflection optical system","High-magnification camera and alignment system","Automated endothelial cell analysis software"], "uses":["Corneal endothelial cell density (ECD) measurement","Pre-operative workup before cataract, DSEK/DMEK, PK surgery","Monitoring Fuchs' dystrophy, post-surgical endothelial loss, contact lens wear"], "exam":["Normal ECD: 2000–3000 cells/mm²","ECD <500 cells/mm² → risk of corneal decompensation (bullous keratopathy)","Measures: ECD (cells/mm²), CV (coefficient of variation of cell size), hexagonality (%)","Polymegethism: variation in cell SIZE; Pleomorphism: variation in cell SHAPE","Mandatory pre-op before anterior segment surgery in borderline corneas"]}, {"cat":"Lacrimal System","name":"Lacrimal Syringe & Cannula","img":"lacrimal_syringe", "parts":["2 mL syringe","Blunt-tipped angled lacrimal cannula (23G)","Punctum dilator (separate instrument — conic dilator)"], "uses":["Lacrimal syringing to assess nasolacrimal duct (NLD) patency","Irrigation of lacrimal sac in acute dacryocystitis"], "exam":["Dilate punctum with punctum dilator before cannulation","Regurgitation on pressure over lacrimal sac: mucocele/dacryocystitis","HARD STOP on syringing: probe hits lacrimal bone — canaliculi patent","SOFT STOP: obstruction within canaliculus before bony wall","Jones Dye Test I (functional) & II (anatomical) for NLD patency"]}, {"cat":"Lacrimal System","name":"Bowman's Probe","img":"bowmans_probe", "parts":["Double-ended malleable metallic probe (silver or stainless steel)","Sizes 0–8 (0 = thinnest, 8 = thickest)"], "uses":["Probing of congenital NLD obstruction (epiphora in infants)","Dilation of NLD; test for canalicular patency"], "exam":["First-line treatment after failed lacrimal sac massage (>6 months conservative)","Success rate: ~90% if performed before 13 months of age","Technique: probe inserted vertically through punctum → turned horizontal → angled inferomedially into nose","Hard stop at lacrimal bone = correct anatomical plane","Intubation (silicone stents) if probing fails; DCR if intubation fails"]}, {"cat":"Surgical Instruments","name":"Eye Speculum","img":"eye_speculum", "parts":["Two blades (spring-loaded or screw-adjusted)","Wire (open) or solid blade variants","Adjustable tension"], "uses":["Retraction of eyelids during ocular surgery","Examination under anaesthesia (EUA) in children"], "exam":["Universal wire speculum: eyelashes enter operative field — not ideal for corneal/vitreoretinal work","Barraquer solid speculum: preferred for cataract/corneal surgery; excludes lashes","Alfonso speculum: used in LASIK flap creation","Lancaster speculum: self-retaining with fine wire blades","Selection based on procedure, palpebral aperture, orbital anatomy"]}, {"cat":"Surgical Instruments","name":"Chalazion Forceps (Clamp)","img":"chalazion_forceps", "parts":["Arm 1: round discoid plate (placed on tarsal conjunctival surface)","Arm 2: oval ring (placed on skin surface)","Central screw mechanism for clamping tension"], "uses":["Chalazion incision and curettage (I&C) under LA","Meibomian cyst excision"], "exam":["Clamp everts and immobilises lid and provides haemostasis","VERTICAL incision on tarsal conjunctival surface (avoids skin scarring)","Horizontal skin incision only if lesion points anteriorly or recurrent/large","Curette removes granulation tissue and inspissated contents","Intralesional steroid injection is alternative to surgery for small lesions"]}, {"cat":"Surgical Instruments","name":"Castroviejo Calipers","img":"castroviejo_calipers", "parts":["Two sharp metallic tips on spring mechanism","Sliding mm scale","Standard range: 0–20 mm"], "uses":["Intraoperative measurements: white-to-white (WTW) corneal diameter","Toric IOL axis marking, limbal reference marking","Strabismus surgery: muscle recession/resection measurements"], "exam":["Must be zeroed before use (tips touching = 0 mm)","Normal WTW corneal diameter: 11–12 mm","Strabismus caliper variant: specifically calibrated for 4–12 mm muscle measurements","Used with surgical marking pen for accurate axis marking in toric IOL implantation","Also available in electronic/digital versions"]}, {"cat":"Surgical Instruments","name":"Muscle Hook (Squint Hook)","img":"muscle_hook", "parts":["Long handle with curved hook tip (sharp or blunt)","Types: von Graefe's (large), Green's (fine-tipped), Lancaster (right-angle)"], "uses":["Isolating extraocular muscles during strabismus surgery","Muscle recession, resection, transposition procedures"], "exam":["Von Graefe's: large blunt hook for rectus muscles","Green's: fine, sharp-tipped; for oblique muscles (SO and IO)","Passed behind muscle body beneath Tenon's capsule","Anterior segment ischaemia risk if >2 rectus muscles disinserted simultaneously","Adjustable suture technique: sutures tied loosely and adjusted post-op"]}, {"cat":"Slit-Lamp Accessory Lenses","name":"Volk +90D / +78D Lens","img":"volk_90d", "parts":["Aspheric handheld condensing lens","Antireflective multi-coating","Available as +60D SuperField, +78D, +90D"], "uses":["Non-contact fundus biomicroscopy via slit lamp","Optic nerve, macula, posterior pole and vitreous evaluation"], "exam":["+78D: ~7.2x magnification, 48° field of view (higher magnification)","+ 90D: ~5.8x magnification, 60° field (wider field, preferred for peripheral view)","+60D SuperField: 76° field (widest non-contact option)","Non-contact: no coupling gel; held ~8–10 mm from cornea","Image: INVERTED and REVERSED — REAL aerial image formed between lens and eye"]}, {"cat":"Slit-Lamp Accessory Lenses","name":"Volk +78D / Mainster Lens","img":"mainster", "parts":["Contact lens with built-in optics (Mainster standard/widefield/ultra-widefield)","Coupling gel (methylcellulose) required"], "uses":["Wide-field fundus laser via slit lamp: PRP, focal laser, retinopexy","Contact-lens fundus biomicroscopy: better image than non-contact during laser"], "exam":["Mainster Standard: 90° FOV; high mag for posterior pole laser","Mainster Widefield: 125° FOV; periphery and PRP","Mainster Ultra-widefield: 165° FOV","Contact method: more stable, less affected by media haze during laser","Volk TransEquator: 133° field; Volk Area Centralis: highest mag for macula"]}, {"cat":"Ophthalmic Imaging","name":"Fundus Camera","img":"fundus_camera", "parts":["Objective/relay optical system","Xenon flash illumination","Digital CCD/CMOS camera sensor","Fixation target and chin/forehead rest"], "uses":["Fundus photography: disc, macula, vessels, periphery","Fluorescein angiography (FA), ICGA, autofluorescence (FAF)","Documentation of DR, AMD, glaucoma, hereditary dystrophies"], "exam":["Standard field: 30°–45°; wide-angle: 50°; ultra-wide: 200° (Optos — no mydriasis needed)","Mydriasis (>6 mm pupil) improves image quality","FA: excitation filter 490 nm (blue), barrier filter 530 nm (green)","FA phases: choroidal flush → arterial → AV → venous → late/recirculation","ICGA: excitation 805 nm, emission 835 nm — for choroidal circulation imaging"]}, {"cat":"Ophthalmic Imaging","name":"Optical Coherence Tomography (OCT)","img":"oct", "parts":["Near-infrared laser (840–1060 nm)","Michelson interferometer with beam splitter and reference mirror","Detector and high-speed signal processor"], "uses":["Cross-sectional retinal/choroidal imaging: AMD, DME, macular holes, ERM, CSC","RNFL thickness measurement for glaucoma (optic nerve OCT)","Anterior segment OCT (AS-OCT): cornea, iridocorneal angle, IOL position"], "exam":["Principle: low-coherence interferometry — light equivalent of B-scan ultrasound","Axial resolution: 3–10 microns (far superior to ultrasound)","SD-OCT (Spectral Domain): current standard; SS-OCT: deeper penetration, better choroidal imaging","Normal CST (central subfield macular thickness): ~250 μm","RNFL: average ~100 μm; ISNT rule: Inferior > Superior > Nasal > Temporal","En face OCT: c-scan for geographic atrophy and drusen mapping"]}, {"cat":"Ophthalmic Imaging","name":"B-Scan Ultrasonography","img":"bscan", "parts":["10 MHz probe (posterior segment); 20 MHz (UBM for anterior segment)","Display unit with gain/sensitivity controls","Methylcellulose coupling gel"], "uses":["Posterior segment evaluation with opaque media (dense cataract, VH)","Retinal detachment, choroidal detachment, vitreous haemorrhage","Intraocular tumours: melanoma, retinoblastoma, metastases","A-scan for axial length biometry"], "exam":["B-scan: 2D cross-sectional brightness image; A-scan: 1D amplitude scan","Retinal detachment: HIGH-reflective membrane tethered at disc + ora serrata, funnel-shaped","VH: MOBILE, low–medium reflectivity echoes — NOT attached to disc","Choroidal melanoma: dome/collar-button, LOW internal reflectivity, acoustic hollow, choroidal excavation","Retinoblastoma: calcified, highly echogenic, acoustic shadowing — in child <5 yr with leucocoria"]}, {"cat":"Ophthalmic Imaging","name":"IOL Master / A-Scan Biometry","img":"iol_master", "parts":["IOL Master 500/700: partial coherence interferometry (PCI) / SS-OCT","A-scan: 10 MHz contact or immersion transducer","Integrated K-reading, ACD, WTW, lens thickness measurement (IOL Master 700)"], "uses":["Pre-operative IOL power calculation for cataract surgery","Axial length measurement for myopia monitoring (children)"], "exam":["IOL Master: NON-CONTACT, gold standard — uses PCI (no corneal indentation)","A-scan IMMERSION more accurate than A-scan contact (contact method indents cornea → shorter AL)","Normal axial length (AL): 22–24 mm","AL is the MOST CRITICAL biometric parameter: 1 mm error → ~2.7D IOL power error","IOL Formulas: Barrett Universal II (best overall); SRK/T (long eyes >26mm); Hoffer-Q (short <22mm); Kane","IOL Master 700: also performs SS-OCT for lens thickness and corneal tomography"]}, ] def build(): doc = SimpleDocTemplate(OUTPUT, pagesize=A4, leftMargin=MARGIN, rightMargin=MARGIN, topMargin=2.2*cm, bottomMargin=1.7*cm, title="Ophthalmic Instruments – PG Practical Exam Reference", author="Orris Medical AI") story = [] CW = PAGE_W - 2*MARGIN # content width # ── COVER ── story.append(Spacer(1, 2.5*cm)) cov = Table([[Paragraph("OPHTHALMIC INSTRUMENTS", sty("CT",fontName="Helvetica-Bold", fontSize=30,textColor=WHITE,alignment=TA_CENTER))]], colWidths=[CW]) cov.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),DARK_BLUE), ("TOPPADDING",(0,0),(-1,-1),16),("BOTTOMPADDING",(0,0),(-1,-1),16)])) story.append(cov) story.append(Spacer(1, 0.3*cm)) sub = Table([[Paragraph("Postgraduate Practical Exam Reference", sty("ST",fontName="Helvetica", fontSize=16,textColor=DARK_BLUE,alignment=TA_CENTER))]],colWidths=[CW]) sub.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),LIGHT_BLUE), ("TOPPADDING",(0,0),(-1,-1),8),("BOTTOMPADDING",(0,0),(-1,-1),8)])) story.append(sub) story.append(Spacer(1, 0.5*cm)) # Info pills info_data = [ ["34 Instruments", "Parts · Uses · Key Exam Points", "Based on Kanski 10th Ed."], ] info_t = Table([[ Table([[Paragraph("✦ 34 Instruments Covered",sty("P1",fontName="Helvetica-Bold",fontSize=9,textColor=WHITE,alignment=TA_CENTER))]],colWidths=[5.5*cm]), Table([[Paragraph("Parts · Uses · Key Exam Points",sty("P2",fontName="Helvetica",fontSize=9,textColor=DARK_BLUE,alignment=TA_CENTER))]],colWidths=[5.5*cm]), Table([[Paragraph("Kanski 10th Ed. + PG References",sty("P3",fontName="Helvetica",fontSize=9,textColor=WHITE,alignment=TA_CENTER))]],colWidths=[5.5*cm]), ]], colWidths=[5.5*cm,5.5*cm,5.5*cm]) info_t.setStyle(TableStyle([ ("BACKGROUND",(0,0),(0,0),MED_BLUE), ("BACKGROUND",(1,0),(1,0),LIGHT_BLUE), ("BACKGROUND",(2,0),(2,0),GREEN), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6), ("LEFTPADDING",(0,0),(-1,-1),4), ])) story.append(info_t) story.append(Spacer(1, 0.6*cm)) # TOC toc_hdr = Table([[Paragraph("TABLE OF CONTENTS",sty("TH",fontName="Helvetica-Bold", fontSize=12,textColor=WHITE,alignment=TA_CENTER))]],colWidths=[CW]) toc_hdr.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),MED_BLUE), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6)])) story.append(toc_hdr) story.append(Spacer(1, 0.2*cm)) cats = {} for ins in INSTRUMENTS: cats.setdefault(ins["cat"],[]).append(ins["name"]) toc_rows = [] for cat,names in cats.items(): toc_rows.append([Paragraph(f"<b>{cat}</b>",TOC_CAT), Paragraph(" · ".join(names),TOC_ITEM)]) toc_t = Table(toc_rows, colWidths=[5.5*cm, CW-5.7*cm]) toc_t.setStyle(TableStyle([ ("ROWBACKGROUNDS",(0,0),(-1,-1),[WHITE,colors.HexColor("#f0f4ff")]), ("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),7),("VALIGN",(0,0),(-1,-1),"TOP"), ("BOX",(0,0),(-1,-1),0.5,GREY), ("LINEBELOW",(0,0),(-1,-1),0.3,colors.HexColor("#d1d5db")), ])) story.append(toc_t) story.append(PageBreak()) # ── INSTRUMENTS ── current_cat = None IMG_W = 5.4*cm IMG_H = 5.2*cm NOTE_W = CW - IMG_W - 0.3*cm def section_box(text, bg_col): t = Table([[Paragraph(text, SEC_LBL)]], colWidths=[NOTE_W]) t.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),bg_col), ("TOPPADDING",(0,0),(-1,-1),3),("BOTTOMPADDING",(0,0),(-1,-1),3), ("LEFTPADDING",(0,0),(-1,-1),6)])) return t for ins in INSTRUMENTS: # Category divider if ins["cat"] != current_cat: current_cat = ins["cat"] cat_t = Table([[Paragraph(current_cat.upper(), CAT_S)]], colWidths=[CW]) cat_t.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),MED_BLUE), ("TOPPADDING",(0,0),(-1,-1),6),("BOTTOMPADDING",(0,0),(-1,-1),6)])) story.append(cat_t) story.append(Spacer(1, 0.2*cm)) # Instrument header hdr_t = Table([[Paragraph(ins["name"], INSTR_TITLE)]], colWidths=[CW]) hdr_t.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),LIGHT_BLUE), ("TOPPADDING",(0,0),(-1,-1),5),("BOTTOMPADDING",(0,0),(-1,-1),5), ("LEFTPADDING",(0,0),(-1,-1),8), ("LINEBELOW",(0,0),(-1,-1),1.5,MED_BLUE)])) story.append(hdr_t) story.append(Spacer(1, 0.15*cm)) # Image img_obj = load_img(ins["img"], IMG_W, IMG_H) if img_obj is None: img_obj = Paragraph(f'<font size="8" color="#6b7280">[Illustration<br/>not available]</font>', sty("NI",fontName="Helvetica",fontSize=8,textColor=GREY,alignment=TA_CENTER)) # Notes column notes = [] notes.append(section_box("🔩 PARTS / COMPONENTS", GREEN)) for p in ins["parts"]: notes.append(Paragraph(f"• {p}", BULLET)) notes.append(Spacer(1, 0.1*cm)) notes.append(section_box("🎯 USES / INDICATIONS", MED_BLUE)) for u in ins["uses"]: notes.append(Paragraph(f"• {u}", BULLET)) notes.append(Spacer(1, 0.1*cm)) notes.append(section_box("⭐ KEY EXAM POINTS", ORANGE)) for e in ins["exam"]: notes.append(Paragraph(f"▸ {e}", BULLET)) body = Table([[img_obj, notes]], colWidths=[IMG_W + 0.2*cm, NOTE_W]) body.setStyle(TableStyle([ ("VALIGN",(0,0),(-1,-1),"TOP"), ("LEFTPADDING",(0,0),(0,0),3),("RIGHTPADDING",(0,0),(0,0),6), ("LEFTPADDING",(1,0),(1,0),0),("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0), ])) story.append(body) story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#c7d2fe"))) story.append(Spacer(1, 0.35*cm)) doc.build(story, onFirstPage=on_page, onLaterPages=on_page) print(f"✅ PDF saved: {OUTPUT}") from pypdf import PdfReader r = PdfReader(OUTPUT) print(f" Pages: {len(r.pages)} | Size: {os.path.getsize(OUTPUT)//1024} KB") build() PYEOF python3 /tmp/workspace/ophthalmology-instruments/final_pdf.py
Ophthalmology Instruments PG Exam
PDF Document · PDF
| Category | Instruments |
|---|---|
| Examination & Diagnostic | Slit lamp, Direct ophthalmoscope, BIO, Retinoscope |
| Tonometry | Goldmann GAT, Schiotz, Non-contact (air-puff) |
| Gonioscopy | Goldmann 3-mirror, Zeiss 4-mirror |
| Refraction | Trial lens set, Keratometer, Lensometer, Phoropter, JCC |
| Visual Acuity | Snellen chart, Pinhole |
| Visual Fields | Goldmann perimeter, Humphrey HFA |
| Strabismus | Maddox rod, Prism bar |
| Cornea / Anterior Segment | Placido's disc, Specular microscope |
| Lacrimal | Lacrimal syringe & cannula, Bowman's probe |
| Surgical | Eye speculum, Chalazion forceps, Castroviejo calipers, Muscle hook |
| Slit-Lamp Accessories | Volk +90D, Volk +78D/Mainster |
| Imaging | Fundus camera, OCT, B-scan ultrasound, IOL Master |
Make a list for all that i have to prepare for pg ophthalmology practical exam
| Instrument | Key Exam Points |
|---|---|
| Slit lamp biomicroscope | Inventor (Gullstrand), illumination modes, magnifications |
| Direct ophthalmoscope | Helmholtz 1851, 15x mag, erect virtual image, 5° FOV |
| Binocular indirect ophthalmoscope | Schepens 1947, inverted real image, +20D/+28D lens |
| Retinoscope | With/against movement, working distance, neutralisation |
| Goldmann applanation tonometer | Imbert-Fick principle, 3.06mm, fluorescein mires |
| Schiotz tonometer | Impression type, Friedenwald tables, 5.5g plunger |
| Non-contact tonometer | Air puff, no anaesthesia, least accurate |
| Goldmann 3-mirror lens | 4 components, coupling gel, laser use |
| Zeiss 4-mirror gonioscope | No gel, indentation gonioscopy |
| Volk +90D / +78D | Non-contact, inverted image, magnification & FOV |
| Keratometer | K readings, normal 42–44D, Javal-Schiötz vs B&L |
| Lensometer (focimeter) | Back vertex power, crosslines target, prism |
| Trial lens set & frame | Organisation, cells, fogging technique |
| Phoropter | Built-in accessories, vertex distance issue |
| Jackson Cross Cylinder | +0.25/-0.50D, flip test, axis vs. power check |
| Goldmann perimeter | Isopters, kinetic, targets I–V |
| Humphrey field analyser | SITA, 24-2, MD/PSD/GHT, reliability indices |
| Maddox rod | Streak formation, phoria types |
| Prism bar | Prism diopter, base directions, PCT |
| Placido's disc | Qualitative corneal assessment, irregular rings |
| Specular microscope | ECD normal values, polymegethism, pleomorphism |
| Lacrimal syringe & cannula | Hard/soft stop, Jones tests |
| Bowman's probe | Sizes 0–8, congenital NLD obstruction |
| Eye speculum | Types (Barraquer, Alfonso, wire) |
| Chalazion forceps | Vertical conjunctival incision |
| Castroviejo calipers | WTW, strabismus measurements |
| Muscle hook | Von Graefe, Green's (obliques) |
| Fundus camera | FA phases, excitation/barrier filters |
| OCT | SD vs SS, ISNT rule, CST normal, RNFL |
| B-scan ultrasound | Retinal detachment echo, melanoma signs |
| IOL Master / A-scan | PCI, formulas (Barrett, SRK/T, Hoffer-Q) |
| Area | What to Prioritise |
|---|---|
| Instruments | Know principle, inventor, image characteristics (real/virtual, erect/inverted) |
| Cases | Practice full systematic slit lamp + fundus examination; practise presenting aloud |
| Viva | Classify first, then describe; use diagrams whenever possible |
| Refraction | Practise retinoscopy technique; know all steps of subjective refraction |
| Spotters | Go through atlas (Kanski, Yanoff) — annotate every image |
| Surgery | Know steps + suture types + complications for each major procedure |
| Pharmacology | MOA + concentration + dosing + contraindications |
| Investigations | Practice interpreting HFA printout, OCT, FFA phases, corneal topography |