Make 20 weeks standard anomaly scan ultrasound report draft, follow ICRI and ISUOG guidelines
ISUOG 20 week anomaly scan ultrasound report guidelines 2024 parameters
https://www.isuog.org/static/4e2ed89e-fa8a-42c2-9c0929cd89cb…
ICRI India anomaly scan report format 20 weeks second trimester guidelines
| Field | Details |
|---|---|
| Patient Name | _________________________________ |
| Age | _______ years |
| Reg. / MRD No. | _________________________________ |
| Referred By | Dr. ______________________________ |
| Date of Scan | _________________________________ |
| LMP | _________________________________ |
| Previous USG Dating | _________________________________ |
| GA by Dates | _______ weeks _______ days |
| GA by Biometry | _______ weeks _______ days |
| Gravida / Para / Abortion | G ___ P ___ A ___ |
| Indication | Routine anomaly scan / ____________ |
| Parameter | Measurement | Gestational Age | Percentile / Z-score |
|---|---|---|---|
| Biparietal Diameter (BPD) | _______ mm | _______ wks _______ d | _______ %ile |
| Head Circumference (HC) | _______ mm | _______ wks _______ d | _______ %ile |
| Abdominal Circumference (AC) | _______ mm | _______ wks _______ d | _______ %ile |
| Femur Length (FL) | _______ mm | _______ wks _______ d | _______ %ile |
| Estimated Fetal Weight (EFW) | _______ g | - | _______ %ile |
| Structure | Finding |
|---|---|
| Shape of skull / Calvarium | Normal ovoid / Abnormal: _________ |
| Falx cerebri (midline echo) | Present / Absent |
| Cavum Septi Pellucidi (CSP) | Visualized / Not visualized |
| Cerebral ventricles (atrial width) | Right: _______ mm Left: _______ mm (Normal: <10 mm) |
| Choroid plexus | Bilateral, symmetrical / Abnormal: _______ |
| Cerebellum | Present, normal size / Transverse diameter: _______ mm |
| Cisterna magna | _______ mm (Normal: 2-10 mm) |
| Posterior fossa | Normal / Abnormal: _____________ |
| Brain parenchyma | Normal echogenicity / ____________ |
| Nuchal fold thickness | _______ mm (Normal: <6 mm at 18-22 wks) |
| Structure | Finding |
|---|---|
| Orbits / Eyes | Bilateral, symmetrical / _________ |
| Profile (mid-sagittal) | Normal / Abnormal: _____________ |
| Upper lip (coronal view) | Intact / Cleft: ________________ |
| Nasal bone | Present / Absent / Not assessed |
| Neck / Nuchal region | Normal / Cystic hygroma / _______ |
| Structure | Finding |
|---|---|
| Cervical spine | Normal alignment and ossification / _______ |
| Thoracic spine | Normal / _______________________ |
| Lumbar spine | Normal / _______________________ |
| Sacral spine | Normal / _______________________ |
| Skin covering (posterior) | Intact / Defect seen at: _________ |
| Neural tube defect | Not seen / Suspected: ___________ |
| Structure | Finding |
|---|---|
| Thorax shape | Normal / Abnormal: _____________ |
| Lung echogenicity | Normal / Echogenic: ____________ |
| Heart position / Situs | Levocardia / Dextrocardia / ______ |
| Cardiac axis | Normal (~45°, leftward) / Abnormal |
| Heart size (approx. 1/3 thorax) | Normal / Enlarged / Small |
| 4-chamber view | Normal / Abnormal: _____________ |
| - LV / RV symmetry | Symmetrical / Asymmetrical |
| - AV valves | Normal / _______________________ |
| - Foramen ovale flap | Seen in LA / __________________ |
| - Interventricular septum | Intact / VSD suspected |
| Left ventricular outflow tract (LVOT) | Normal / Abnormal: _____________ |
| Right ventricular outflow tract (RVOT) | Normal / Abnormal: _____________ |
| Crossing of great vessels | Normal / Parallel / Not seen |
| 3-vessel trachea view (3VT) | Normal / Abnormal: _____________ |
| Cardiac rhythm (M-mode / Doppler) | Regular / Irregular |
| Structure | Finding |
|---|---|
| Abdominal wall / Umbilical insertion | Intact / Defect: ________________ |
| Stomach | Visible, left side / Not seen / Situs inversus |
| Liver | Normal / _______________________ |
| Bowel | Non-dilated / Echogenic bowel / Dilated |
| Kidneys (bilateral) | Present, normal echogenicity |
| - Right kidney | _______ mm x _______ mm |
| - Left kidney | _______ mm x _______ mm |
| Renal pelvis AP diameter | Right: _______ mm Left: _______ mm (Alert: >7 mm) |
| Adrenal glands | Normal / _______________________ |
| Urinary bladder | Visible / Not seen |
| Intra-abdominal cysts | None / _______________________ |
Note: In India, sex determination and disclosure are prohibited under the PC-PNDT Act, 1994. The sex of the fetus will NOT be disclosed.
| Structure | Finding |
|---|---|
| Upper limbs (bilateral) | Both present, normal appearance / __ |
| - Humerus (both) | Visualized / __________________ |
| - Radius / Ulna (both) | Visualized / __________________ |
| - Hands (both) | Visualized / ___________________ |
| Lower limbs (bilateral) | Both present, normal appearance / __ |
| - Femur (both) | Visualized / __________________ |
| - Tibia / Fibula (both) | Visualized / __________________ |
| - Feet (both) | Visualized / Clubfoot suspected / __ |
| Bone echogenicity | Normal / Reduced mineralization |
| Limb movements | Active / Reduced |
| Parameter | Finding |
|---|---|
| Placental location | Anterior / Posterior / Fundal / Lateral / Low-lying |
| Placental grade (Grannum) | Grade 0 / I / II / III |
| Placental thickness | _______ mm |
| Placental echogenicity | Homogeneous / Heterogeneous |
| Distance from internal os | _______ mm (Normal: >20 mm acceptable; refer if <20 mm) |
| Placenta praevia | Not seen / Suspected / Present |
| Retroplacental clear zone | Present / Absent |
| Subchorionic hemorrhage | Not seen / Present: _____________ |
| Cord insertion | Central / Eccentric / Marginal / Velamentous |
| Parameter | Finding |
|---|---|
| Number of cord vessels | 3-vessel cord (2 arteries + 1 vein) / 2-vessel cord |
| Cord presentation / position | Normal / _______________________ |
| Umbilical artery Doppler (if indicated) | S/D ratio: _______ PI: _______ RI: _______ |
| Single umbilical artery (SUA) | Not detected / Detected |
| Parameter | Finding |
|---|---|
| Amniotic fluid volume (subjective) | Normal / Increased (Polyhydramnios) / Reduced (Oligohydramnios) |
| Amniotic Fluid Index (AFI) | _______ cm (Normal: 8-24 cm) |
| Single Deepest Pocket (SDP) | _______ cm (Normal: 2-8 cm) |
| Echogenic particles | Not seen / Present |
| Parameter | Finding |
|---|---|
| Uterine wall | Normal / Fibroids: ______________ |
| Lower uterine segment | Normal / _______________________ |
| Cervical length (if indicated) | _______ mm (Normal: >25 mm) |
| Cervical os | Closed / Dilated / Funneling |
| Right adnexa | Normal / Cyst: _________________ |
| Left adnexa | Normal / Cyst: _________________ |
| Periuterine masses | Not seen / _____________________ |
| Marker | Present | Absent | Measurement |
|---|---|---|---|
| Nuchal fold thickness (≥6 mm = significant) | ✓ | _______ mm | |
| Echogenic cardiac focus (ECF) | ✓ | ||
| Choroid plexus cyst (CPC) | ✓ | ||
| Mild ventriculomegaly (10-15 mm) | ✓ | ||
| Echogenic bowel | ✓ | ||
| Renal pelvis dilatation (>7 mm) | ✓ | ||
| Short femur / humerus | ✓ | ||
| Two-vessel cord | ✓ | ||
| Absent / hypoplastic nasal bone | ✓ |
| Vessel | Parameter | Value | Interpretation |
|---|---|---|---|
| Umbilical artery | S/D ratio | ||
| Umbilical artery | PI | ||
| Umbilical artery | RI | ||
| Middle cerebral artery (MCA) | Peak systolic velocity (PSV) | ||
| Uterine artery (if indicated) | PI bilateral |
SINGLE LIVE INTRAUTERINE FETUS IN _____ PRESENTATION GESTATIONAL AGE: _______ WEEKS _______ DAYS (by composite biometry) ESTIMATED DATE OF DELIVERY (EDD): _______________________
Make final draft considering pcpndt law in mind
PC-PNDT Act 2024 Form F ultrasound report mandatory fields requirements India
https://nhmmeghalaya.nic.in/programmes/pcpndt/form-f.pdf
| Indication | |
|---|---|
| ☐ | Estimation of gestational age / dating |
| ☐ | Detection of chromosomal abnormalities, fetal structural defects and other abnormalities (ANOMALY SCAN) |
| ☐ | Evaluation of fetal growth parameters, fetal weight and fetal wellbeing |
| ☐ | Evaluation of placental position, thickness, grading and abnormalities |
| ☐ | Evaluation of umbilical cord - insertion, number of vessels |
| ☐ | Assessment of liquor amnii |
| ☐ | Evaluation of fetal presentation and position |
| ☐ | Color flow mapping and duplex Doppler studies |
| ☐ | Any suspected adnexal or uterine pathology |
| ☐ | Other: __________________________________________________ |
| Date of scan | |
| Time of scan | |
| LMP (Last Menstrual Period) | |
| GA by LMP | _______ weeks _______ days |
| GA by previous USG (if done) | _______ weeks _______ days (USG date: ________) |
| EDD by dates | |
| Mode of scan | Transabdominal (TA) / Transvaginal (TV) |
| Machine & Model | |
| Probe |
| Parameter | Finding |
|---|---|
| Number of fetuses | Singleton / Multiple |
| Fetal cardiac activity | Present - Regular / Rate: _______ bpm |
| Fetal lie | Longitudinal / Transverse / Oblique |
| Presentation | Cephalic / Breech / Transverse |
| Parameter | Measurement | GA Equivalent | Percentile |
|---|---|---|---|
| Biparietal Diameter (BPD) | _______ mm | _______ wks _______ d | _______ %ile |
| Head Circumference (HC) | _______ mm | _______ wks _______ d | _______ %ile |
| Abdominal Circumference (AC) | _______ mm | _______ wks _______ d | _______ %ile |
| Femur Length (FL) | _______ mm | _______ wks _______ d | _______ %ile |
| Estimated Fetal Weight (EFW) | _______ grams | _______ %ile |
| Structure | Normal | Abnormal / Comment |
|---|---|---|
| Skull shape & integrity (ovoid) | ☐ | |
| Midline falx cerebri | ☐ | |
| Cavum septi pellucidi (CSP) | ☐ | |
| Lateral ventricles - atrial width | ☐ | R: _____ mm L: _____ mm (normal <10 mm) |
| Choroid plexus (bilateral) | ☐ | |
| Cerebellum | ☐ | Transverse diameter: _______ mm |
| Cisterna magna | ☐ | _______ mm (normal 2-10 mm) |
| Brain parenchyma echogenicity | ☐ | |
| Nuchal fold thickness | ☐ | _______ mm (alert if ≥6 mm) |
| Structure | Normal | Abnormal / Comment |
|---|---|---|
| Orbits / eyes (bilateral) | ☐ | |
| Mid-sagittal facial profile | ☐ | |
| Upper lip - coronal view | ☐ | Intact / Cleft: ______________ |
| Nasal bone | ☐ | Present / Absent / Not assessed |
| Neck / Nuchal region | ☐ |
| Structure | Normal | Abnormal / Comment |
|---|---|---|
| Cervical spine | ☐ | |
| Thoracic spine | ☐ | |
| Lumbar spine | ☐ | |
| Sacral spine | ☐ | |
| Posterior skin covering | ☐ | Intact / Defect at: ___________ |
| Neural tube defect | ☐ not seen | Suspected: _________________ |
| Structure | Normal | Abnormal / Comment |
|---|---|---|
| Thorax shape | ☐ | |
| Lung echogenicity (bilateral) | ☐ | |
| Cardiac situs / position | ☐ Levocardia | Dextrocardia / ______________ |
| Cardiac axis (~45° leftward) | ☐ | |
| Heart size (~1/3 thorax) | ☐ | |
| 4-chamber view | ☐ | |
| - LV / RV symmetry | ☐ | |
| - Atrioventricular valves | ☐ | |
| - Foramen ovale flap in LA | ☐ | |
| - Interventricular septum (IVS) | ☐ intact | VSD suspected / ____________ |
| - Interatrial septum | ☐ | |
| LVOT (Left ventricular outflow tract) | ☐ | |
| RVOT (Right ventricular outflow tract) | ☐ | |
| Crossing of great vessels | ☐ | Parallel / Not seen |
| 3-vessel trachea view (3VT) | ☐ | |
| Cardiac rhythm | ☐ Regular | Irregular / Rate: _______ bpm |
| Structure | Normal | Abnormal / Comment |
|---|---|---|
| Anterior abdominal wall | ☐ intact | Defect: __________________ |
| Umbilical cord insertion into abdomen | ☐ normal | |
| Stomach (visible, left side) | ☐ | Not seen / Double bubble / _____ |
| Liver | ☐ | |
| Bowel | ☐ non-dilated | Echogenic bowel / Dilated |
| Right kidney | ☐ | Size: _______ mm x _______ mm |
| Left kidney | ☐ | Size: _______ mm x _______ mm |
| Renal pelvis AP diameter | ☐ normal | R: _____ mm L: _____ mm (alert >7 mm) |
| Urinary bladder | ☐ visible | Not seen |
| Adrenal glands | ☐ | |
| Intra-abdominal masses / cysts | ☐ none | Present: __________________ |
| Structure | Normal | Abnormal / Comment |
|---|---|---|
| Right upper limb (humerus, radius/ulna, hand) | ☐ | |
| Left upper limb (humerus, radius/ulna, hand) | ☐ | |
| Right lower limb (femur, tibia/fibula, foot) | ☐ | |
| Left lower limb (femur, tibia/fibula, foot) | ☐ | |
| Bone echogenicity / mineralization | ☐ normal | Reduced / _________________ |
| Fetal movements observed | ☐ active | Reduced |
| Parameter | Finding |
|---|---|
| Location | Anterior / Posterior / Fundal / Lateral / Low-lying |
| Placental thickness | _______ mm |
| Grading (Grannum) | Grade 0 / I / II / III |
| Echogenicity | Homogeneous / Heterogeneous |
| Distance of lower edge from internal os | _______ mm |
| Placenta praevia | Not seen / Suspected - repeat scan at 32 wks |
| Retroplacental clear zone | Present / Absent |
| Subchorionic haemorrhage | Not seen / Present: ____________ |
| Placental cord insertion | Central / Eccentric / Marginal / Velamentous |
| Parameter | Finding |
|---|---|
| Number of vessels | 3-vessel cord (2 arteries + 1 vein) / 2-vessel cord (SUA) |
| Cord presentation | Normal / Nuchal cord / __________ |
| Umbilical artery Doppler (if indicated) | S/D: _______ PI: _______ RI: _______ |
| Parameter | Finding |
|---|---|
| Subjective assessment | Normal / Polyhydramnios / Oligohydramnios |
| Amniotic Fluid Index (AFI) | _______ cm (normal 8-24 cm) |
| Single Deepest Pocket (SDP) | _______ cm (normal 2-8 cm) |
| Parameter | Finding |
|---|---|
| Uterine wall | Normal / Fibroid(s): size _________ location _________ |
| Lower uterine segment | Normal / Scar: ________________ |
| Cervical length (if indicated) | _______ mm (normal >25 mm) |
| Cervical internal os | Closed / Dilated / Funneling seen |
| Adnexa - Right | Normal / Cyst: ________________ |
| Adnexa - Left | Normal / Cyst: ________________ |
| Soft Marker | Absent | Present | Value |
|---|---|---|---|
| Nuchal fold ≥6 mm | ☐ | ☐ | _______ mm |
| Echogenic intracardiac focus (EIF) | ☐ | ☐ | |
| Choroid plexus cysts (CPC) | ☐ | ☐ | |
| Mild ventriculomegaly (10-15 mm) | ☐ | ☐ | _______ mm |
| Echogenic bowel | ☐ | ☐ | |
| Renal pelvis dilatation >7 mm | ☐ | ☐ | _______ mm |
| Short femur (<5th centile) | ☐ | ☐ | |
| Short humerus (<5th centile) | ☐ | ☐ | |
| Absent / hypoplastic nasal bone | ☐ | ☐ | |
| Two-vessel cord (SUA) | ☐ | ☐ |
| Vessel | S/D | PI | RI | Interpretation |
|---|---|---|---|---|
| Umbilical artery (UA) | ||||
| Middle cerebral artery (MCA) - PSV | ||||
| Uterine artery (bilateral, if indicated) |
| Finding | Detail |
|---|---|
| Composite GA by biometry | _______ weeks _______ days |
| EDD (by biometry) | |
| Fetal heart rate | _______ bpm, regular |
| Anatomy survey | Complete / Incomplete |
| Gross structural anomaly | Not detected / Detected (see below) |
| Placenta | Location: _______ |
| Amniotic fluid | Normal / Abnormal (AFI: _______ cm) |
| Umbilical cord | 3-vessel / 2-vessel cord |
| Soft markers | None / Present (as listed in B9) |
| Cervix | Normal (_______ mm) / Short cervix |
| Form F Serial No. | |
| Date of scan | |
| Copy 1 | Submitted to Appropriate Authority by: _______ (date) |
| Copy 2 | Retained at centre (to be preserved for 2 years) |
| Online submission done | Yes / No |
| Printout preserved with patient signature | Yes / No |
| Report signed by: | Doctor performing USG (not centre owner) |
"Disclosure of sex of fetus is prohibited under law. Sex determination is not done at this centre." (To be displayed in English and local language)
| Area | What was added / changed |
|---|---|
| Form F structure | Report is now built inside the official PC-PNDT Form F framework (Section A = mandatory patient fields per the Act) |
| Patient declaration | Mandatory pre-procedure declaration by patient that she does not want to know the sex |
| Doctor declaration | Mandatory 3-signature doctor declaration (at procedure, on report, on record copy) that sex was neither detected nor disclosed |
| Living children | Form F mandatory field - number of living sons and daughters with ages |
| PC-PNDT Reg. No. | Prominently placed at the top, next to centre name |
| Genitalia section removed | Completely removed - PC-PNDT prohibits any documentation that could imply sex determination |
| Fetal sex field removed | Removed entirely - no "male/female/not disclosed" option - the field does not exist in this report |
| Two-copy record keeping | Administrative section documents copy 1 (Appropriate Authority) and copy 2 (clinic, 2 years) |
| Online Form F compliance | Provision for portal reference number and printout with patient signature |
| Penalty clause | Specific criminal penalties noted in the disclaimer |
Make b/l lower limb varicose veins doppler report
bilateral lower limb varicose veins venous duplex doppler ultrasound report format SVS AVF guidelines 2024
venous duplex ultrasound varicose veins report template deep superficial perforator reflux CEAP GSV SSV
| Patient Name | |
| Age / Sex | / Female / Male |
| Reg. / MRD No. | |
| Date of Scan | |
| Referred By | Dr. |
| Clinical Indication | Bilateral lower limb varicose veins / leg swelling / leg pain / venous ulcer / pre-treatment mapping |
| Previous vein treatment | None / Sclerotherapy / EVLA / Surgery (specify: ___________) |
| Machine | |
| Transducer | Linear / 7.5-15 MHz |
| Patient position | Standing / Reverse Trendelenburg (preferred for reflux testing) |
| Compression used | Manual calf squeeze / Pneumatic cuff deflation |
| Valsalva used | Yes (for SFJ / CFV) / No |
| Modes used | B-mode (greyscale) + Color Doppler + Spectral Doppler (Duplex) |
| Scan performed by | |
| Interpreted by |
Reflux threshold used (per SVS/AVF/AVLS 2023 Guidelines):
- Superficial veins (GSV, SSV, AAGV, perforators): >500 ms retrograde flow = significant reflux
- Deep veins (CFV, FV, Popliteal vein): >1000 ms retrograde flow = significant reflux
| Vein Segment | Compressible | Flow | Augmentation | Reflux Duration | Interpretation |
|---|---|---|---|---|---|
| Common Femoral Vein (CFV) | ☐ Yes ☐ No | Phasic / Non-phasic | Present / Absent | _______ ms | Normal / Reflux |
| Femoral Vein (FV) - proximal | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Femoral Vein (FV) - mid | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Femoral Vein (FV) - distal | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Deep Femoral Vein (Profunda) | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Popliteal Vein (POPV) | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Posterior Tibial Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Peroneal Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Anterior Tibial Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Gastrocnemius Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Soleal Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux |
| Parameter | Finding |
|---|---|
| SFJ location | _______ cm below inguinal ligament |
| SFJ competence | Competent / Incompetent |
| Reflux at SFJ (Valsalva) | No reflux / Reflux: _______ ms |
| Tributaries at SFJ | Normal / Accessory saphenous vein entering / __________ |
| Segment | Diameter (mm) | In Saphenous Canal | Reflux Duration | Reflux Present |
|---|---|---|---|---|
| GSV - groin / proximal thigh | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - mid thigh | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - distal thigh | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - above knee | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - below knee | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - ankle level | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| Parameter | Finding |
|---|---|
| AAGSV visible | Yes / No |
| Diameter | _______ mm |
| Reflux | No / Yes: _______ ms |
| Parameter | Finding |
|---|---|
| Visible | Yes / No |
| Reflux | No / Yes: _______ ms |
| Parameter | Finding |
|---|---|
| SPJ present / identifiable | Yes / No (absent in ~10-30% cases) |
| SPJ level | _______ cm above popliteal crease |
| SPJ competence | Competent / Incompetent |
| Reflux at SPJ | No reflux / Reflux: _______ ms |
| SSV cranial extension (Giacomini) | Present / Absent |
| SSV Segment | Diameter (mm) | Reflux Duration | Reflux Present |
|---|---|---|---|
| SSV - upper calf | _______ mm | _______ ms | ☐ Yes ☐ No |
| SSV - mid calf | _______ mm | _______ ms | ☐ Yes ☐ No |
| SSV - lower calf | _______ mm | _______ ms | ☐ Yes ☐ No |
| Location | Level | Diameter (mm) | Outward Flow Duration (ms) | Connecting to | Significant |
|---|---|---|---|---|---|
| Medial thigh | _______ cm from groin | _______ mm | _______ ms | GSV / Tributary | ☐ Yes ☐ No |
| Hunterian perforator | Mid thigh | _______ mm | _______ ms | GSV / FV | ☐ Yes ☐ No |
| Dodd's perforator | Distal thigh | _______ mm | _______ ms | GSV / FV | ☐ Yes ☐ No |
| Boyd's perforator | Below knee | _______ mm | _______ ms | GSV / PT | ☐ Yes ☐ No |
| Cockett I (medial ankle) | _______ cm from medial malleolus | _______ mm | _______ ms | Posterior arch / GSV | ☐ Yes ☐ No |
| Cockett II | _______ cm from medial malleolus | _______ mm | _______ ms | ☐ Yes ☐ No | |
| Cockett III | _______ cm from medial malleolus | _______ mm | _______ ms | ☐ Yes ☐ No | |
| Posterior tibial perforator | _______ mm | _______ ms | ☐ Yes ☐ No | ||
| Paratibial | _______ mm | _______ ms | ☐ Yes ☐ No | ||
| Lateral leg | _______ mm | _______ ms | SSV / tributary | ☐ Yes ☐ No |
| Location | Distribution | Approx. Diameter | Source of Filling |
|---|---|---|---|
| Medial thigh | Present / Absent | _______ mm | GSV trunk / AAGSV / perforator |
| Medial leg | Present / Absent | _______ mm | GSV / Cockett perforator |
| Lateral thigh | Present / Absent | _______ mm | SSV / LAGSV |
| Posterior calf | Present / Absent | _______ mm | SSV / perforator |
| Anterior leg | Present / Absent | _______ mm | |
| Ankle / gaiter zone | Present / Absent | _______ mm | Cockett perforator |
| Finding | Present / Absent | Details |
|---|---|---|
| Pitting oedema | ||
| Haemosiderin / pigmentation | Site: __________ | |
| Lipodermatosclerosis | Site: __________ | |
| Corona phlebectatica | At ankle | |
| Healed ulcer | Site: __________ | |
| Active venous ulcer | Site / size: _____ | |
| Telangiectasias | Distribution: ____ |
| Vein Segment | Compressible | Flow | Augmentation | Reflux Duration | Interpretation |
|---|---|---|---|---|---|
| Common Femoral Vein (CFV) | ☐ Yes ☐ No | Phasic / Non-phasic | Present / Absent | _______ ms | Normal / Reflux |
| Femoral Vein (FV) - proximal | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Femoral Vein (FV) - mid | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Femoral Vein (FV) - distal | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Deep Femoral Vein (Profunda) | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Popliteal Vein (POPV) | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Posterior Tibial Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Peroneal Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Anterior Tibial Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Gastrocnemius Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux | ||
| Soleal Veins | ☐ Yes ☐ No | _______ ms | Normal / Reflux |
| Parameter | Finding |
|---|---|
| SFJ competence | Competent / Incompetent |
| Reflux at SFJ (Valsalva) | No reflux / Reflux: _______ ms |
| Tributaries at SFJ | Normal / ________________________________ |
| Segment | Diameter (mm) | In Saphenous Canal | Reflux Duration | Reflux Present |
|---|---|---|---|---|
| GSV - groin / proximal thigh | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - mid thigh | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - distal thigh | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - above knee | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - below knee | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| GSV - ankle level | _______ mm | ☐ Yes ☐ No | _______ ms | ☐ Yes ☐ No |
| Parameter | Finding |
|---|---|
| AAGSV visible | Yes / No |
| Parameter | Finding |
|---|---|
| SPJ identifiable | Yes / No |
| SPJ level | _______ cm above popliteal crease |
| SPJ competence | Competent / Incompetent |
| Reflux at SPJ | No reflux / Reflux: _______ ms |
| SSV Segment | Diameter (mm) | Reflux Duration | Reflux Present |
|---|---|---|---|
| SSV - upper calf | _______ mm | _______ ms | ☐ Yes ☐ No |
| SSV - mid calf | _______ mm | _______ ms | ☐ Yes ☐ No |
| SSV - lower calf | _______ mm | _______ ms | ☐ Yes ☐ No |
| Location | Diameter (mm) | Outward Flow (ms) | Significant |
|---|---|---|---|
| Medial thigh | ☐ Yes ☐ No | ||
| Hunterian | ☐ Yes ☐ No | ||
| Dodd's | ☐ Yes ☐ No | ||
| Boyd's | ☐ Yes ☐ No | ||
| Cockett I / II / III | ☐ Yes ☐ No | ||
| Paratibial | ☐ Yes ☐ No | ||
| Lateral leg | ☐ Yes ☐ No |
| Location | Distribution | Source of Filling |
|---|---|---|
| Medial thigh | Present / Absent | |
| Medial leg | Present / Absent | |
| Lateral thigh | Present / Absent | |
| Posterior calf | Present / Absent | |
| Ankle / gaiter zone | Present / Absent |
| Reflux Pattern | Right | Left |
|---|---|---|
| Axial reflux (uninterrupted, groin to calf) | ☐ Present ☐ Absent | ☐ Present ☐ Absent |
| Junctional reflux only (SFJ or SPJ isolated) | ☐ Present ☐ Absent | ☐ Present ☐ Absent |
| Segmental reflux (portion of truncal vein only) | ☐ Present ☐ Absent | ☐ Present ☐ Absent |
| Deep vein reflux | ☐ Present ☐ Absent | ☐ Present ☐ Absent |
| Perforator-sourced reflux | ☐ Present ☐ Absent | ☐ Present ☐ Absent |
| Pelvic source suspected | ☐ Present ☐ Absent | ☐ Present ☐ Absent |
| Component | Right | Left |
|---|---|---|
| C - Clinical class | C__ (see below) | C__ |
| E - Etiology | Ep (primary) / Es (secondary/post-thrombotic) / Ec (congenital) | |
| A - Anatomy | As (superficial) / Ad (deep) / Ap (perforator) | |
| P - Pathophysiology | Pr (reflux) / Po (obstruction) / Pr,o (both) |
| Class | Description |
|---|---|
| C0 | No visible or palpable signs of venous disease |
| C1 | Telangiectasias or reticular veins |
| C2 | Varicose veins |
| C2r | Recurrent varicose veins |
| C3 | Oedema |
| C4a | Pigmentation or eczema |
| C4b | Lipodermatosclerosis or atrophie blanche |
| C4c | Corona phlebectatica |
| C5 | Healed venous ulcer |
| C6 | Active venous ulcer |
| C6r | Recurrent active venous ulcer |
Chronic venous insufficiency, right lower limb. [GSV axial reflux / SFJ junctional reflux / SSV reflux / isolated perforator reflux] from ___________________ to ___________________. Deep venous system patent. [No DVT / DVT at ___________________.]
Chronic venous insufficiency, left lower limb. [GSV axial reflux / SFJ junctional reflux / SSV reflux / isolated perforator reflux] from ___________________ to ___________________. Deep venous system patent. [No DVT / DVT at ___________________.]
| Report prepared by | |
| Qualification | MD Radiology / DNB Radiology / DMRD / MS Vascular Surgery |
| Registration No. | |
| Date & Time | |
| Signature & Stamp | |
| Centre Name & Address |
| Feature | Rationale |
|---|---|
| Reflux thresholds stated explicitly | >500 ms superficial/perforators; >1000 ms deep veins - per SVS/AVF 2023 (Grade 1B) |
| Pathological perforator criteria | ≥3.5 mm diameter AND ≥500 ms outward flow - per SVS/AVF 2023 |
| Named perforators | Cockett I/II/III, Dodd, Hunterian, Boyd - standard anatomical landmarks for surgical planning |
| CEAP 2020 | Updated classification including C2r, C4c (corona phlebectatica), C6r |
| Reflux pattern subtypes | Axial / junctional / segmental - required for treatment planning (ablation vs. sclerotherapy) |
| Standing position noted | Reflux is gravity-dependent; position must be documented as it affects interpretation |
| GSV segment-by-segment diameter | Required for EVLA/RFA suitability (typically GSV >3 mm needed for thermal ablation) |
| Bilateral symmetrical layout | Mirrors standard clinical workflow - deep first, then GSV, SSV, perforators, skin |
Make a pdf of above mentioned report
mkdir -p /home/daytona/workspace/varicose-doppler && ls /home/daytona/workspace/…
~/varicose-doppler/generate_report.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import PageBreak
OUTPUT = "/home/daytona/workspace/varicose-doppler/Varicose_Veins_Doppler_Report.pdf"
# ── Colours ──────────────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1a3a5c")
MID_BLUE = colors.HexColor("#2563a8")
LIGHT_BLUE = colors.HexColor("#dbeafe")
HEADER_BG = colors.HexColor("#0f2d52")
ROW_ALT = colors.HexColor("#f0f5fb")
BORDER = colors.HexColor("#93c5fd")
TEXT_DARK = colors.HexColor("#1e293b")
ORANGE = colors.HexColor("#d97706")
WHITE = colors.white
W, H = A4
ML = MR = 14*mm
MT = MB = 12*mm
styles = getSampleStyleSheet()
def S(name, **kw):
base = styles[name]
return ParagraphStyle(name + str(id(kw)), parent=base, **kw)
# ── Style helpers ─────────────────────────────────────────────────────────────
TITLE = S("Title", fontSize=15, textColor=WHITE, alignment=TA_CENTER, spaceAfter=2)
SUB = S("Normal", fontSize=9, textColor=LIGHT_BLUE, alignment=TA_CENTER, spaceAfter=1)
SEC = S("Normal", fontSize=10, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_LEFT, leftIndent=4, spaceAfter=0, spaceBefore=0)
BODY = S("Normal", fontSize=8, textColor=TEXT_DARK, leading=11)
BOLD = S("Normal", fontSize=8, textColor=TEXT_DARK, fontName="Helvetica-Bold", leading=11)
ITALIC = S("Normal", fontSize=7.5,textColor=colors.HexColor("#475569"), leading=10)
CELL = S("Normal", fontSize=7.5,textColor=TEXT_DARK, leading=10)
CELL_B = S("Normal", fontSize=7.5,textColor=TEXT_DARK, fontName="Helvetica-Bold", leading=10)
CELL_H = S("Normal", fontSize=7.5,textColor=WHITE, fontName="Helvetica-Bold",
leading=10, alignment=TA_CENTER)
NOTE = S("Normal", fontSize=7, textColor=colors.HexColor("#64748b"), leading=9)
IMPRS = S("Normal", fontSize=8, textColor=DARK_BLUE, fontName="Helvetica-Bold",
leading=11, leftIndent=4)
def section_bar(title):
tbl = Table([[Paragraph(title, SEC)]], colWidths=[W - ML - MR])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
]))
return tbl
def header_row(*cols):
return [Paragraph(c, CELL_H) for c in cols]
def trow(*cols, bold=False):
st = CELL_B if bold else CELL
return [Paragraph(str(c), st) for c in cols]
def blank_field(label, width=55*mm):
return f"{label}: {'_'*30}"
DOTTED = "_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _"
def field_table(pairs, col1=65*mm, col2=None):
col2 = col2 or (W - ML - MR - col1)
rows = [[Paragraph(f"<b>{k}</b>", CELL), Paragraph(v, CELL)] for k, v in pairs]
tbl = Table(rows, colWidths=[col1, col2])
tbl.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.3, BORDER),
("BACKGROUND", (0,0), (0,-1), ROW_ALT),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
]))
return tbl
def vein_table(rows_data, col_widths, header):
rows = [header_row(*header)]
for i, r in enumerate(rows_data):
row = trow(*r)
rows.append(row)
tbl = Table(rows, colWidths=col_widths)
style = [
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.3, BORDER),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 3),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, ROW_ALT]),
]
tbl.setStyle(TableStyle(style))
return tbl
# ─────────────────────────────────────────────────────────────────────────────
# PAGE TEMPLATE – header/footer
# ─────────────────────────────────────────────────────────────────────────────
def on_page(canvas, doc):
canvas.saveState()
# Header band
canvas.setFillColor(HEADER_BG)
canvas.rect(0, H - 28*mm, W, 28*mm, fill=1, stroke=0)
canvas.setFillColor(WHITE)
canvas.setFont("Helvetica-Bold", 13)
canvas.drawCentredString(W/2, H - 12*mm,
"VENOUS DUPLEX DOPPLER ULTRASOUND REPORT")
canvas.setFont("Helvetica", 8)
canvas.setFillColor(LIGHT_BLUE)
canvas.drawCentredString(W/2, H - 19*mm,
"Bilateral Lower Limb Varicose Veins / Chronic Venous Disease Assessment")
canvas.drawCentredString(W/2, H - 24*mm,
"SVS/AVF/AVLS 2023 Guidelines | 2020 CEAP Classification | UIP Consensus")
# Footer
canvas.setFillColor(HEADER_BG)
canvas.rect(0, 0, W, 10*mm, fill=1, stroke=0)
canvas.setFillColor(LIGHT_BLUE)
canvas.setFont("Helvetica", 7)
canvas.drawString(ML, 3.5*mm,
"Reflux thresholds: Superficial/Perforators >500 ms | Deep veins (CFV/FV/POPV) >1000 ms | Pathological perforator: ≥3.5 mm & ≥500 ms outward flow")
canvas.drawRightString(W - MR, 3.5*mm, f"Page {doc.page}")
canvas.restoreState()
# ─────────────────────────────────────────────────────────────────────────────
# BUILD STORY
# ─────────────────────────────────────────────────────────────────────────────
story = []
SP = lambda n=4: Spacer(1, n*mm)
# ══ SECTION 1: Patient & Referral ════════════════════════════════════════════
story += [SP(2), section_bar("SECTION 1 — PATIENT & REFERRAL DETAILS"), SP(2)]
story += [field_table([
("Patient Name", DOTTED),
("Age / Sex", DOTTED),
("Reg. / MRD No.", DOTTED),
("Date of Scan", DOTTED),
("Referred By", "Dr. " + DOTTED),
("Clinical Indication", "Bilateral lower limb varicose veins / leg swelling / leg pain / venous ulcer / pre-treatment mapping"),
("Previous Treatment", "None ☐ | Sclerotherapy ☐ | EVLA ☐ | Surgery ☐ Specify: " + DOTTED),
], col1=68*mm), SP(3)]
# ══ SECTION 2: Technique ═════════════════════════════════════════════════════
story += [section_bar("SECTION 2 — TECHNIQUE & EQUIPMENT"), SP(2)]
story += [field_table([
("Machine / Model", DOTTED),
("Transducer", "Linear high-frequency 7.5 – 15 MHz"),
("Patient Position", "Standing / Reverse Trendelenburg ☐ Supine ☐"),
("Compression Method", "Manual calf squeeze ☐ Pneumatic cuff deflation ☐"),
("Valsalva Manoeuvre", "Yes ☐ No ☐ (used for SFJ / CFV assessment)"),
("Modes Used", "B-mode (greyscale) + Colour Doppler + Spectral Doppler (Duplex)"),
("Scan Performed By", DOTTED),
("Interpreted By", DOTTED),
], col1=68*mm)]
story += [SP(2), Paragraph(
"<b>Reflux Threshold (SVS/AVF/AVLS 2023):</b> Superficial veins & perforators: <b>>500 ms</b> retrograde flow. "
"Deep veins (CFV, FV, POPV): <b>>1000 ms</b> retrograde flow. "
"Pathological perforator: diameter <b>≥3.5 mm</b> AND outward flow <b>≥500 ms</b>.", ITALIC), SP(3)]
# ══ Helper: deep vein table ═══════════════════════════════════════════════════
deep_veins = [
("Common Femoral Vein (CFV)", "Yes ☐ No ☐", "Phasic / Non-phasic", "Present / Absent", "_______ ms", "Normal / Reflux"),
("Femoral Vein – proximal", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Femoral Vein – mid", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Femoral Vein – distal", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Deep Femoral V. (Profunda)", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Popliteal Vein (POPV)", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Posterior Tibial Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Peroneal Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Anterior Tibial Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Gastrocnemius Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
("Soleal Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"),
]
deep_hdr = ["Vein Segment", "Compressible", "Flow", "Augmentation", "Reflux Duration", "Interpretation"]
deep_cols = [52*mm, 22*mm, 28*mm, 26*mm, 26*mm, 28*mm]
gsv_rows = [
("GSV – groin / proximal thigh", "_______ mm", "Yes ☐ No ☐", "_______ ms", "Yes ☐ No ☐"),
("GSV – mid thigh", "_______ mm", "Yes ☐ No ☐", "_______ ms", "Yes ☐ No ☐"),
("GSV – distal thigh", "_______ mm", "Yes ☐ No ☐", "_______ ms", "Yes ☐ No ☐"),
("GSV – above knee", "_______ mm", "Yes ☐ No ☐", "_______ ms", "Yes ☐ No ☐"),
("GSV – below knee", "_______ mm", "Yes ☐ No ☐", "_______ ms", "Yes ☐ No ☐"),
("GSV – ankle level", "_______ mm", "Yes ☐ No ☐", "_______ ms", "Yes ☐ No ☐"),
]
gsv_hdr = ["GSV Segment", "Diameter (mm)", "In Saphenous Canal", "Reflux Duration", "Reflux Present"]
gsv_cols = [52*mm, 28*mm, 34*mm, 30*mm, 28*mm]
ssv_rows = [
("SSV – upper calf", "_______ mm", "_______ ms", "Yes ☐ No ☐"),
("SSV – mid calf", "_______ mm", "_______ ms", "Yes ☐ No ☐"),
("SSV – lower calf", "_______ mm", "_______ ms", "Yes ☐ No ☐"),
]
ssv_hdr = ["SSV Segment", "Diameter (mm)", "Reflux Duration", "Reflux Present"]
ssv_cols = [55*mm, 35*mm, 40*mm, 42*mm]
perforator_rows = [
("Medial thigh", "_______ cm from groin", "_______ mm", "_______ ms", "GSV / Tributary", "Yes ☐ No ☐"),
("Hunterian perforator", "Mid thigh", "_______ mm", "_______ ms", "GSV / FV", "Yes ☐ No ☐"),
("Dodd's perforator", "Distal thigh", "_______ mm", "_______ ms", "GSV / FV", "Yes ☐ No ☐"),
("Boyd's perforator", "Below knee", "_______ mm", "_______ ms", "GSV / PT", "Yes ☐ No ☐"),
("Cockett I", "Medial ankle – lower", "_______ mm", "_______ ms", "Post. arch / GSV", "Yes ☐ No ☐"),
("Cockett II", "Medial ankle – mid", "_______ mm", "_______ ms", "Post. arch / GSV", "Yes ☐ No ☐"),
("Cockett III", "Medial ankle – upper", "_______ mm", "_______ ms", "Post. arch / GSV", "Yes ☐ No ☐"),
("Posterior tibial", "Medial leg", "_______ mm", "_______ ms", "", "Yes ☐ No ☐"),
("Paratibial", "Medial leg", "_______ mm", "_______ ms", "", "Yes ☐ No ☐"),
("Lateral leg", "Lateral calf", "_______ mm", "_______ ms", "SSV / Tributary", "Yes ☐ No ☐"),
]
perf_hdr = ["Perforator", "Location", "Diameter", "Outward Flow", "Connecting to", "Significant"]
perf_cols = [32*mm, 36*mm, 22*mm, 22*mm, 30*mm, 22*mm+2*mm] # tight but fits
varic_rows = [
("Medial thigh", "Present ☐ Absent ☐", "_______ mm", "GSV trunk / AAGSV / perforator"),
("Medial leg", "Present ☐ Absent ☐", "_______ mm", "GSV / Cockett perforator"),
("Lateral thigh", "Present ☐ Absent ☐", "_______ mm", "SSV / LAGSV"),
("Posterior calf", "Present ☐ Absent ☐", "_______ mm", "SSV / perforator"),
("Anterior leg", "Present ☐ Absent ☐", "_______ mm", "_________________"),
("Ankle / gaiter zone","Present ☐ Absent ☐", "_______ mm", "Cockett perforator"),
]
varic_hdr = ["Location", "Distribution", "Approx. Diameter", "Source of Filling"]
varic_cols = [40*mm, 38*mm, 35*mm, 55*mm+14*mm] # proportional
skin_rows = [
("Pitting oedema", "Present ☐ Absent ☐", ""),
("Haemosiderin / pigmentation","Present ☐ Absent ☐","Site: _________________"),
("Lipodermatosclerosis", "Present ☐ Absent ☐", "Site: _________________"),
("Corona phlebectatica", "Present ☐ Absent ☐", "At ankle region"),
("Healed ulcer", "Present ☐ Absent ☐", "Site: _________________"),
("Active venous ulcer", "Present ☐ Absent ☐", "Site / size: ___________"),
("Telangiectasias", "Present ☐ Absent ☐", "Distribution: __________"),
]
skin_hdr = ["Finding", "Present / Absent", "Details"]
skin_cols = [55*mm, 42*mm, 75*mm]
def build_limb_section(side):
s = []
s += [section_bar(f"SECTION {'3' if side=='RIGHT' else '4'} — {side} LOWER LIMB"), SP(2)]
# Deep
s += [Paragraph(f"<b>{'3' if side=='RIGHT' else '4'}A. Deep Venous System – {side}</b>", BOLD), SP(1)]
s += [vein_table(deep_veins, deep_cols, deep_hdr), SP(1)]
s += [Paragraph(f"<b>DVT ({side}):</b> None ☐ Acute DVT at: __________________ Chronic changes at: __________________", CELL), SP(3)]
# SFJ
s += [Paragraph(f"<b>{'3' if side=='RIGHT' else '4'}B. Superficial Venous System – {side}</b>", BOLD), SP(1)]
s += [Paragraph("<i>Saphenofemoral Junction (SFJ)</i>", ITALIC), SP(1)]
s += [field_table([
("SFJ location", "_______ cm below inguinal ligament"),
("SFJ competence", "Competent ☐ Incompetent ☐"),
("Reflux at SFJ", "No reflux ☐ Reflux: _______ ms (Valsalva-provoked)"),
("Tributaries at SFJ","Normal ☐ Accessory saphenous entering ☐ Other: _______________"),
], col1=62*mm), SP(2)]
# GSV
s += [Paragraph("<i>Great Saphenous Vein (GSV)</i>", ITALIC), SP(1)]
s += [vein_table(gsv_rows, gsv_cols, gsv_hdr), SP(1)]
s += [Paragraph(
"GSV total refluxing length: _______ cm | "
"GSV wall: Normal ☐ Thickened ☐ Intraluminal echoes ☐ Post-thrombotic ☐", CELL), SP(2)]
# AAGSV / Giacomini
s += [field_table([
("AAGSV (Anterior Accessory GSV)", "Visible: Yes ☐ No ☐ Diameter: _______ mm Reflux: _______ ms"),
("Giacomini / Posterior Accessory","Visible: Yes ☐ No ☐ Diameter: _______ mm Reflux: _______ ms"),
], col1=68*mm), SP(2)]
# SPJ / SSV
s += [Paragraph(f"<b>{'3' if side=='RIGHT' else '4'}C. Small Saphenous Vein (SSV) & Saphenopopliteal Junction (SPJ) – {side}</b>", BOLD), SP(1)]
s += [field_table([
("SPJ identifiable", "Yes ☐ No ☐ (absent in ~10-30% cases)"),
("SPJ level", "_______ cm above popliteal crease"),
("SPJ competence", "Competent ☐ Incompetent ☐"),
("Reflux at SPJ", "No reflux ☐ Reflux: _______ ms"),
("SSV cranial extension (Giacomini)", "Present ☐ Absent ☐"),
], col1=68*mm), SP(1)]
s += [vein_table(ssv_rows, ssv_cols, ssv_hdr), SP(1)]
s += [Paragraph("SSV total refluxing length: _______ cm", CELL), SP(2)]
# Perforators
s += [Paragraph(f"<b>{'3' if side=='RIGHT' else '4'}D. Incompetent Perforating Veins (IPVs) – {side}</b>", BOLD), SP(0.5)]
s += [Paragraph("<i>Pathological criterion: outward flow ≥500 ms AND diameter ≥3.5 mm (SVS/AVF/AVLS 2023)</i>", ITALIC), SP(1)]
s += [vein_table(perforator_rows, perf_cols, perf_hdr), SP(1)]
s += [Paragraph(f"Total pathological perforators identified ({side}): _______", CELL), SP(2)]
# Varicosities
s += [Paragraph(f"<b>{'3' if side=='RIGHT' else '4'}E. Varicosities – {side}</b>", BOLD), SP(1)]
s += [vein_table(varic_rows, varic_cols, varic_hdr), SP(2)]
# Skin
s += [Paragraph(f"<b>{'3' if side=='RIGHT' else '4'}F. Skin & Soft Tissue Changes – {side}</b>", BOLD), SP(1)]
s += [vein_table(skin_rows, skin_cols, skin_hdr), SP(3)]
return s
story += build_limb_section("RIGHT")
story += [PageBreak()]
story += build_limb_section("LEFT")
# ══ SECTION 5: Reflux Pattern ═════════════════════════════════════════════════
story += [SP(2), section_bar("SECTION 5 — REFLUX PATTERN CLASSIFICATION (BILATERAL SUMMARY)"), SP(2)]
reflux_rows = [
("Axial reflux (groin → calf, uninterrupted)", "Present ☐ Absent ☐", "Present ☐ Absent ☐"),
("Junctional reflux only (SFJ or SPJ isolated)","Present ☐ Absent ☐", "Present ☐ Absent ☐"),
("Segmental reflux (portion of truncal vein)", "Present ☐ Absent ☐", "Present ☐ Absent ☐"),
("Deep vein reflux", "Present ☐ Absent ☐", "Present ☐ Absent ☐"),
("Perforator-sourced reflux", "Present ☐ Absent ☐", "Present ☐ Absent ☐"),
("Pelvic source suspected", "Present ☐ Absent ☐", "Present ☐ Absent ☐"),
]
story += [vein_table(reflux_rows, [100*mm, 47*mm, 35*mm],
["Reflux Pattern", "Right", "Left"]), SP(3)]
# ══ SECTION 6: CEAP ══════════════════════════════════════════════════════════
story += [section_bar("SECTION 6 — CEAP CLASSIFICATION (2020 Updated CEAP – American Venous Forum)"), SP(2)]
ceap_comp = [
("C – Clinical class", "C___ (see table below)", "C___"),
("E – Etiology", "Ep (primary) ☐ Es (secondary/post-thrombotic) ☐ Ec (congenital) ☐",
"Ep ☐ Es ☐ Ec ☐"),
("A – Anatomy", "As (superficial) ☐ Ad (deep) ☐ Ap (perforator) ☐",
"As ☐ Ad ☐ Ap ☐"),
("P – Pathophysiology", "Pr (reflux) ☐ Po (obstruction) ☐ Pr,o (both) ☐",
"Pr ☐ Po ☐ Pr,o ☐"),
]
comp_rows = [[Paragraph(f"<b>{r[0]}</b>", CELL), Paragraph(r[1], CELL), Paragraph(r[2], CELL)] for r in ceap_comp]
comp_tbl = Table([header_row("Component", "Right", "Left")] + comp_rows,
colWidths=[35*mm, 105*mm, 42*mm])
comp_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.3, BORDER),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, ROW_ALT]),
]))
story += [comp_tbl, SP(2)]
ceap_class = [
("C0","No visible or palpable signs of venous disease"),
("C1","Telangiectasias or reticular veins"),
("C2","Varicose veins"),
("C2r","Recurrent varicose veins"),
("C3","Oedema"),
("C4a","Pigmentation or eczema"),
("C4b","Lipodermatosclerosis or atrophie blanche"),
("C4c","Corona phlebectatica"),
("C5","Healed venous ulcer"),
("C6","Active venous ulcer"),
("C6r","Recurrent active venous ulcer"),
]
cc_rows = [[Paragraph(f"<b>{c[0]}</b>", CELL_B), Paragraph(c[1], CELL)] for c in ceap_class]
# 2-column layout side by side
half = len(cc_rows)//2 + len(cc_rows)%2
left_col = cc_rows[:half]
right_col = cc_rows[half:]
while len(right_col) < len(left_col):
right_col.append([Paragraph("", CELL), Paragraph("", CELL)])
merged_rows = [[Paragraph("<b>Class</b>", CELL_H), Paragraph("<b>Description</b>", CELL_H),
Paragraph("<b>Class</b>", CELL_H), Paragraph("<b>Description</b>", CELL_H)]]
for l, r in zip(left_col, right_col):
merged_rows.append(l + r)
cc_tbl = Table(merged_rows, colWidths=[14*mm, 80*mm, 14*mm, 74*mm])
cc_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.3, BORDER),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 2),
("LEFTPADDING", (0,0), (-1,-1), 3),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, ROW_ALT]),
]))
story += [cc_tbl, SP(2)]
story += [Paragraph("<b>Suffix:</b> s = symptomatic (pain, heaviness, swelling, achiness, itching – HASTI) | a = asymptomatic", CELL)]
story += [Paragraph("<b>Right CEAP:</b> C___ E___ A___ P___ ( s / a ) "
"<b>Left CEAP:</b> C___ E___ A___ P___ ( s / a )", BOLD), SP(3)]
# ══ SECTION 7: Summary ═══════════════════════════════════════════════════════
story += [PageBreak(), section_bar("SECTION 7 — SUMMARY OF FINDINGS"), SP(2)]
for side in ["RIGHT", "LEFT"]:
story += [Paragraph(f"<b>{side} LOWER LIMB</b>", BOLD), SP(1)]
rows = [
("Deep system", f"Patent ☐ No DVT ☐ Deep venous reflux: Present ☐ Absent ☐ at: _______________________"),
("SFJ", "Competent ☐ Incompetent ☐ Reflux: _______ ms"),
("GSV", "Reflux from __________________ to __________________ Total: _______ cm Diameter SFJ: _______ mm BK: _______ mm"),
("SSV / SPJ", "Competent ☐ Incompetent ☐ Reflux: _______ ms SSV refluxing length: _______ cm"),
("Reflux pattern", "Axial ☐ Junctional ☐ Segmental ☐"),
("Pathological IPVs", "_______ perforator(s) at: _____________________________________________"),
("Varicosities", "Distribution: ______________________ Source: ________________________"),
("Skin changes", "None ☐ Pigmentation ☐ LDS ☐ Corona phlebectatica ☐ Ulcer at: ______________"),
]
tbl = Table([[Paragraph(f"<b>{r[0]}</b>", CELL), Paragraph(r[1], CELL)] for r in rows],
colWidths=[48*mm, W-ML-MR-48*mm])
tbl.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.3, BORDER),
("BACKGROUND", (0,0), (0,-1), ROW_ALT),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
]))
story += [tbl, SP(3)]
# ══ SECTION 8: Impression ════════════════════════════════════════════════════
story += [section_bar("SECTION 8 — IMPRESSION"), SP(2)]
for side, n in [("RIGHT","8.1"), ("LEFT","8.2")]:
box_rows = [
[Paragraph(f"<b>{n} {side} LOWER LIMB</b>", IMPRS)],
[Paragraph(
f"CEAP: C___ E___ A___ P___ (s/a)<br/>"
f"Chronic venous insufficiency, {side.lower()} lower limb.<br/>"
f"[GSV axial reflux ☐ | SFJ junctional reflux ☐ | SSV reflux ☐ | Isolated perforator reflux ☐]<br/>"
f"Reflux from ____________________ to ____________________. Truncal length: _______ cm<br/>"
f"Deep venous system: Patent ☐ DVT at: ____________________ Chronic changes: ____________________",
BODY)],
]
imp_tbl = Table(box_rows, colWidths=[W-ML-MR])
imp_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), LIGHT_BLUE),
("BACKGROUND", (0,1), (0,1), WHITE),
("BOX", (0,0), (-1,-1), 0.8, MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
]))
story += [imp_tbl, SP(3)]
# ══ SECTION 9: Recommendations ═══════════════════════════════════════════════
story += [section_bar("SECTION 9 — CLINICAL CORRELATION & RECOMMENDATIONS"), SP(2)]
recs = [
"☐ Findings support conservative management (compression stockings, lifestyle modification) for C2/C3 disease",
"☐ Patient suitable for endovenous thermal ablation (EVLA / RFA) of GSV – Right ☐ Left ☐ Bilateral ☐",
"☐ Patient suitable for ultrasound-guided foam sclerotherapy (UGFS) of: ___________________________",
"☐ Phlebectomy / stab avulsions of varicosities advised",
"☐ Perforator ablation (MOCA / UGFS) advised for IPVs at: ___________________________________",
"☐ DVT found – anticoagulation and haematology referral recommended",
"☐ Deep venous reflux present – refer to vascular surgery for further evaluation",
"☐ Pelvic source suspected – pelvic venous duplex / CT venography recommended",
"☐ Pre-treatment anatomical mapping complete for planned intervention",
"☐ Post-treatment follow-up – occlusion confirmed ☐ Re-canalisation noted ☐",
]
for r in recs:
story += [Paragraph(r, BODY)]
story += [SP(3)]
# ══ SECTION 10: Technical Quality ════════════════════════════════════════════
story += [section_bar("SECTION 10 — TECHNICAL QUALITY"), SP(2)]
techs = [
"☐ Technically satisfactory – all segments adequately assessed",
"☐ Suboptimal assessment of: ____________________ due to: oedema / pain / obesity / wound dressing",
"☐ Standing position not tolerated; scan performed supine – may underestimate reflux",
"☐ Images archived to PACS / printed and filed",
]
for t in techs:
story += [Paragraph(t, BODY)]
story += [SP(3)]
# ══ Authorisation ═════════════════════════════════════════════════════════════
story += [section_bar("AUTHORISATION"), SP(2)]
story += [field_table([
("Report Prepared By", DOTTED),
("Qualification", "MD Radiology / DNB Radiology / DMRD / MS Vascular Surgery"),
("MCI / NMC Reg. No.", DOTTED),
("Date & Time of Report", DOTTED),
("Signature & Stamp", ""),
("Centre Name & Address", DOTTED),
], col1=65*mm), SP(3)]
# ══ Disclaimer ════════════════════════════════════════════════════════════════
story += [HRFlowable(width="100%", thickness=0.5, color=MID_BLUE), SP(2)]
story += [Paragraph(
"<b>DISCLAIMER:</b> This report constitutes a screening/diagnostic duplex ultrasound examination. "
"A normal study does not exclude all venous pathology. Results are position- and technique-dependent; "
"reflux may be underestimated in the supine position. All findings must be correlated with clinical history, "
"physical examination, and symptom severity (HASTI). Surveillance imaging is recommended for progressive disease. "
"References: SVS/AVF/AVLS 2023 Varicose Vein Guidelines (PMID 37652254) | 2020 CEAP Update (AVF) | "
"UIP Duplex Consensus Document | ACR Duplex Ultrasound Standards.",
ITALIC), SP(2)]
# ─────────────────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=ML, rightMargin=MR,
topMargin=34*mm, bottomMargin=16*mm,
title="Bilateral Lower Limb Varicose Veins Doppler Report",
author="Orris Medical Reports",
subject="Venous Duplex Doppler Ultrasound",
)
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print("PDF created:", OUTPUT)
cd /home/daytona/workspace/varicose-doppler && python generate_report.py 2>&1
ls -lh /home/daytona/workspace/varicose-doppler/Varicose_Veins_Doppler_Report.pd…
Varicose Veins Doppler Report
PDF Document · PDF
| Section | Content |
|---|---|
| 1 | Patient & Referral Details |
| 2 | Technique & Equipment (with reflux threshold box) |
| 3 | Right Lower Limb - Deep system, SFJ, GSV, SSV, IPVs, Varicosities, Skin changes |
| 4 | Left Lower Limb - Same structure as Section 3 |
| 5 | Bilateral Reflux Pattern Classification (axial / junctional / segmental / deep / perforator / pelvic) |
| 6 | CEAP Classification table (2020 updated, C0-C6r) with bilateral entry fields |
| 7 | Summary of Findings - bilateral side-by-side |
| 8 | Impression boxes for Right and Left limbs with CEAP codes |
| 9 | Recommendations checklist (conservative / EVLA / RFA / UGFS / phlebectomy / DVT referral) |
| 10 | Technical Quality + Authorisation + Disclaimer |
Create a Word version of this varicose veins report for easy editing
node -e "require('docx'); console.log('docx ok')" 2>&1 | head -3
~/varicose-doppler/generate_report.js
"use strict";
const fs = require("fs");
const {
Document, Packer, Paragraph, TextRun, Table, TableRow, TableCell,
Header, Footer, AlignmentType, HeadingLevel, BorderStyle, WidthType,
ShadingType, VerticalAlign, PageNumber, NumberFormat,
convertInchesToTwip, convertMillimetersToTwip, PageBreak,
} = require("docx");
// ── Colours ────────────────────────────────────────────────────────────────
const C = {
darkBlue: "1a3a5c",
midBlue: "2563a8",
lightBlue: "dbeafe",
headerBg: "0f2d52",
rowAlt: "f0f5fb",
white: "FFFFFF",
textDark: "1e293b",
orange: "d97706",
grey: "64748b",
};
// ── Helpers ────────────────────────────────────────────────────────────────
const mm = convertMillimetersToTwip;
const twp = convertInchesToTwip;
function shading(hex) {
return { type: ShadingType.SOLID, color: hex, fill: hex };
}
function borders(color = C.midBlue, sz = 4) {
const b = { style: BorderStyle.SINGLE, size: sz, color };
return { top: b, bottom: b, left: b, right: b };
}
function noBorders() {
const b = { style: BorderStyle.NONE, size: 0, color: "FFFFFF" };
return { top: b, bottom: b, left: b, right: b };
}
// ── Text helpers ───────────────────────────────────────────────────────────
function run(text, opts = {}) {
return new TextRun({ text, font: "Calibri", size: opts.size || 18,
bold: opts.bold || false, italics: opts.italic || false,
color: opts.color || C.textDark, ...opts });
}
function para(children, opts = {}) {
const c = typeof children === "string" ? [run(children, opts)] : children;
return new Paragraph({
children: c,
alignment: opts.align || AlignmentType.LEFT,
spacing: { before: opts.spaceBefore || 40, after: opts.spaceAfter || 40 },
indent: opts.indent ? { left: mm(opts.indent) } : undefined,
});
}
function emptyPara(space = 60) {
return new Paragraph({ children: [], spacing: { before: 0, after: space } });
}
// ── Section bar (shaded heading row) ──────────────────────────────────────
function sectionBar(title) {
return new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
rows: [new TableRow({
children: [new TableCell({
children: [new Paragraph({
children: [run(title, { bold: true, color: C.white, size: 20 })],
spacing: { before: 60, after: 60 },
indent: { left: mm(3) },
})],
shading: shading(C.midBlue),
borders: noBorders(),
margins: { left: mm(2), right: mm(2) },
})],
})],
borders: { top: noBorders().top, bottom: noBorders().bottom,
left: noBorders().left, right: noBorders().right,
insideH: noBorders().top, insideV: noBorders().left },
});
}
// ── 2-column field table (label | value) ──────────────────────────────────
function fieldTable(pairs, labelWidthPct = 30) {
const rows = pairs.map(([label, value], i) => new TableRow({
children: [
new TableCell({
children: [para([run(label, { bold: true, size: 17, color: C.darkBlue })], { spaceBefore: 30, spaceAfter: 30 })],
width: { size: labelWidthPct, type: WidthType.PERCENTAGE },
shading: shading(i % 2 === 0 ? C.rowAlt : C.white),
borders: borders(C.midBlue, 3),
margins: { left: mm(2), right: mm(2) },
verticalAlign: VerticalAlign.CENTER,
}),
new TableCell({
children: [para(value || "________________________________", { spaceBefore: 30, spaceAfter: 30 })],
width: { size: 100 - labelWidthPct, type: WidthType.PERCENTAGE },
shading: shading(i % 2 === 0 ? C.white : C.rowAlt),
borders: borders(C.midBlue, 3),
margins: { left: mm(2), right: mm(2) },
verticalAlign: VerticalAlign.CENTER,
}),
],
}));
return new Table({ width: { size: 100, type: WidthType.PERCENTAGE }, rows });
}
// ── Generic data table ─────────────────────────────────────────────────────
function dataTable(headers, rows, colPcts) {
const headerRow = new TableRow({
tableHeader: true,
children: headers.map((h, i) => new TableCell({
children: [new Paragraph({
children: [run(h, { bold: true, color: C.white, size: 16 })],
alignment: AlignmentType.CENTER,
spacing: { before: 40, after: 40 },
})],
shading: shading(C.darkBlue),
borders: borders(C.white, 4),
width: { size: colPcts[i], type: WidthType.PERCENTAGE },
margins: { left: mm(1.5), right: mm(1.5) },
verticalAlign: VerticalAlign.CENTER,
})),
});
const dataRows = rows.map((row, ri) => new TableRow({
children: row.map((cell, ci) => new TableCell({
children: [new Paragraph({
children: [run(String(cell), { size: 16, color: C.textDark })],
spacing: { before: 30, after: 30 },
})],
shading: shading(ri % 2 === 0 ? C.white : C.rowAlt),
borders: borders(C.midBlue, 3),
width: { size: colPcts[ci], type: WidthType.PERCENTAGE },
margins: { left: mm(1.5), right: mm(1.5) },
verticalAlign: VerticalAlign.CENTER,
})),
}));
return new Table({
width: { size: 100, type: WidthType.PERCENTAGE },
rows: [headerRow, ...dataRows],
});
}
// ── Sub-heading paragraph ──────────────────────────────────────────────────
function subHead(text) {
return new Paragraph({
children: [run(text, { bold: true, size: 18, color: C.darkBlue })],
spacing: { before: 120, after: 40 },
});
}
function subHeadItalic(text) {
return new Paragraph({
children: [run(text, { italic: true, size: 17, color: C.midBlue })],
spacing: { before: 80, after: 30 },
});
}
function note(text) {
return new Paragraph({
children: [run(text, { italic: true, size: 15, color: C.grey })],
spacing: { before: 20, after: 60 },
});
}
function bullet(text) {
return new Paragraph({
children: [run(text, { size: 17 })],
spacing: { before: 20, after: 20 },
indent: { left: mm(6) },
});
}
// ─────────────────────────────────────────────────────────────────────────────
// DATA DEFINITIONS
// ─────────────────────────────────────────────────────────────────────────────
const DOTTED = "________________________________";
const deepVeins = [
["Common Femoral Vein (CFV)", "Yes ☐ No ☐", "Phasic / Non-phasic", "Present / Absent", "_______ ms", "Normal / Reflux"],
["Femoral Vein – proximal", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Femoral Vein – mid", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Femoral Vein – distal", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Deep Femoral V. (Profunda)", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Popliteal Vein (POPV)", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Posterior Tibial Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Peroneal Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Anterior Tibial Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Gastrocnemius Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
["Soleal Veins", "Yes ☐ No ☐", "", "", "_______ ms", "Normal / Reflux"],
];
const deepHdr = ["Vein Segment","Compressible","Flow","Augmentation","Reflux Duration","Interpretation"];
const deepCols = [24, 13, 15, 16, 16, 16];
const gsvRows = [
["GSV – groin / proximal thigh","_______ mm","Yes ☐ No ☐","_______ ms","Yes ☐ No ☐"],
["GSV – mid thigh", "_______ mm","Yes ☐ No ☐","_______ ms","Yes ☐ No ☐"],
["GSV – distal thigh", "_______ mm","Yes ☐ No ☐","_______ ms","Yes ☐ No ☐"],
["GSV – above knee", "_______ mm","Yes ☐ No ☐","_______ ms","Yes ☐ No ☐"],
["GSV – below knee", "_______ mm","Yes ☐ No ☐","_______ ms","Yes ☐ No ☐"],
["GSV – ankle level", "_______ mm","Yes ☐ No ☐","_______ ms","Yes ☐ No ☐"],
];
const gsvHdr = ["GSV Segment","Diameter (mm)","In Saphenous Canal","Reflux Duration","Reflux Present"];
const gsvCols = [28, 18, 22, 18, 14];
const ssvRows = [
["SSV – upper calf","_______ mm","_______ ms","Yes ☐ No ☐"],
["SSV – mid calf", "_______ mm","_______ ms","Yes ☐ No ☐"],
["SSV – lower calf","_______ mm","_______ ms","Yes ☐ No ☐"],
];
const ssvHdr = ["SSV Segment","Diameter (mm)","Reflux Duration","Reflux Present"];
const ssvCols = [30, 24, 26, 20];
const perfRows = [
["Medial thigh", "_______ cm from groin", "_______ mm","_______ ms","GSV / Tributary", "Yes ☐ No ☐"],
["Hunterian perforator", "Mid thigh", "_______ mm","_______ ms","GSV / FV", "Yes ☐ No ☐"],
["Dodd's perforator", "Distal thigh", "_______ mm","_______ ms","GSV / FV", "Yes ☐ No ☐"],
["Boyd's perforator", "Below knee", "_______ mm","_______ ms","GSV / PT", "Yes ☐ No ☐"],
["Cockett I", "Medial ankle – lower", "_______ mm","_______ ms","Post. arch / GSV", "Yes ☐ No ☐"],
["Cockett II", "Medial ankle – mid", "_______ mm","_______ ms","Post. arch / GSV", "Yes ☐ No ☐"],
["Cockett III", "Medial ankle – upper", "_______ mm","_______ ms","Post. arch / GSV", "Yes ☐ No ☐"],
["Posterior tibial", "Medial leg", "_______ mm","_______ ms","", "Yes ☐ No ☐"],
["Paratibial", "Medial leg", "_______ mm","_______ ms","", "Yes ☐ No ☐"],
["Lateral leg", "Lateral calf", "_______ mm","_______ ms","SSV / Tributary", "Yes ☐ No ☐"],
];
const perfHdr = ["Perforator","Location","Diameter","Outward Flow","Connecting to","Significant"];
const perfCols = [18, 22, 12, 14, 19, 15];
const varicRows = [
["Medial thigh", "Present ☐ Absent ☐","_______ mm","GSV trunk / AAGSV / perforator"],
["Medial leg", "Present ☐ Absent ☐","_______ mm","GSV / Cockett perforator"],
["Lateral thigh", "Present ☐ Absent ☐","_______ mm","SSV / LAGSV"],
["Posterior calf", "Present ☐ Absent ☐","_______ mm","SSV / perforator"],
["Anterior leg", "Present ☐ Absent ☐","_______ mm","_________________"],
["Ankle / gaiter zone", "Present ☐ Absent ☐","_______ mm","Cockett perforator"],
];
const varicHdr = ["Location","Distribution","Approx. Diameter","Source of Filling"];
const varicCols = [22, 26, 22, 30];
const skinRows = [
["Pitting oedema", "Present ☐ Absent ☐",""],
["Haemosiderin / pigmentation","Present ☐ Absent ☐","Site: _________________"],
["Lipodermatosclerosis", "Present ☐ Absent ☐","Site: _________________"],
["Corona phlebectatica", "Present ☐ Absent ☐","At ankle region"],
["Healed ulcer", "Present ☐ Absent ☐","Site: _________________"],
["Active venous ulcer", "Present ☐ Absent ☐","Site / size: ___________"],
["Telangiectasias", "Present ☐ Absent ☐","Distribution: __________"],
];
const skinHdr = ["Finding","Present / Absent","Details"];
const skinCols = [30, 30, 40];
// ─────────────────────────────────────────────────────────────────────────────
// PER-LIMB CONTENT BUILDER
// ─────────────────────────────────────────────────────────────────────────────
function buildLimb(side, secNum) {
const items = [];
items.push(sectionBar(`SECTION ${secNum} — ${side} LOWER LIMB`));
// Deep
items.push(subHead(`${secNum}A. Deep Venous System – ${side}`));
items.push(dataTable(deepHdr, deepVeins, deepCols));
items.push(para(`DVT (${side}): None ☐ Acute DVT at: __________________ Chronic changes at: __________________`));
// SFJ
items.push(subHead(`${secNum}B. Superficial Venous System – ${side}`));
items.push(subHeadItalic("Saphenofemoral Junction (SFJ)"));
items.push(fieldTable([
["SFJ location", "_______ cm below inguinal ligament"],
["SFJ competence", "Competent ☐ Incompetent ☐"],
["Reflux at SFJ", "No reflux ☐ Reflux: _______ ms (Valsalva-provoked)"],
["Tributaries at SFJ", "Normal ☐ Accessory saphenous entering ☐ Other: _______________"],
], 32));
// GSV
items.push(subHeadItalic("Great Saphenous Vein (GSV)"));
items.push(dataTable(gsvHdr, gsvRows, gsvCols));
items.push(para("GSV total refluxing length: _______ cm GSV wall: Normal ☐ Thickened ☐ Intraluminal echoes ☐ Post-thrombotic ☐"));
items.push(fieldTable([
["AAGSV (Anterior Accessory GSV)","Visible: Yes ☐ No ☐ Diameter: _______ mm Reflux: _______ ms"],
["Giacomini / Posterior Accessory","Visible: Yes ☐ No ☐ Diameter: _______ mm Reflux: _______ ms"],
], 38));
// SSV / SPJ
items.push(subHead(`${secNum}C. Small Saphenous Vein (SSV) & Saphenopopliteal Junction (SPJ) – ${side}`));
items.push(fieldTable([
["SPJ identifiable", "Yes ☐ No ☐ (absent in ~10-30% of cases)"],
["SPJ level", "_______ cm above popliteal crease"],
["SPJ competence", "Competent ☐ Incompetent ☐"],
["Reflux at SPJ", "No reflux ☐ Reflux: _______ ms"],
["SSV cranial extension (Giacomini)","Present ☐ Absent ☐"],
], 38));
items.push(dataTable(ssvHdr, ssvRows, ssvCols));
items.push(para("SSV total refluxing length: _______ cm"));
// Perforators
items.push(subHead(`${secNum}D. Incompetent Perforating Veins (IPVs) – ${side}`));
items.push(note("Pathological criterion: outward flow ≥500 ms AND diameter ≥3.5 mm (SVS/AVF/AVLS 2023 Guidelines)"));
items.push(dataTable(perfHdr, perfRows, perfCols));
items.push(para(`Total pathological perforators identified (${side}): _______`));
// Varicosities
items.push(subHead(`${secNum}E. Varicosities – ${side}`));
items.push(dataTable(varicHdr, varicRows, varicCols));
// Skin
items.push(subHead(`${secNum}F. Skin & Soft Tissue Changes – ${side}`));
items.push(dataTable(skinHdr, skinRows, skinCols));
return items;
}
// ─────────────────────────────────────────────────────────────────────────────
// DOCUMENT BUILD
// ─────────────────────────────────────────────────────────────────────────────
const docChildren = [];
// ── TITLE BLOCK ──────────────────────────────────────────────────────────────
docChildren.push(new Paragraph({
children: [run("VENOUS DUPLEX DOPPLER ULTRASOUND REPORT", { bold: true, size: 28, color: C.white })],
alignment: AlignmentType.CENTER,
spacing: { before: 60, after: 20 },
shading: shading(C.headerBg),
}));
docChildren.push(new Paragraph({
children: [run("Bilateral Lower Limb Varicose Veins / Chronic Venous Disease Assessment", { size: 18, color: C.lightBlue })],
alignment: AlignmentType.CENTER,
spacing: { before: 0, after: 10 },
shading: shading(C.headerBg),
}));
docChildren.push(new Paragraph({
children: [run("SVS/AVF/AVLS 2023 Guidelines | 2020 CEAP Classification | UIP Consensus Document", { italic: true, size: 15, color: C.lightBlue })],
alignment: AlignmentType.CENTER,
spacing: { before: 0, after: 80 },
shading: shading(C.headerBg),
}));
// ── SECTION 1: Patient ────────────────────────────────────────────────────────
docChildren.push(sectionBar("SECTION 1 — PATIENT & REFERRAL DETAILS"));
docChildren.push(fieldTable([
["Patient Name", DOTTED],
["Age / Sex", DOTTED],
["Reg. / MRD No.", DOTTED],
["Date of Scan", DOTTED],
["Referred By", "Dr. " + DOTTED],
["Clinical Indication", "Bilateral lower limb varicose veins / leg swelling / leg pain / venous ulcer / pre-treatment mapping"],
["Previous Treatment", "None ☐ Sclerotherapy ☐ EVLA ☐ Surgery ☐ Specify: " + DOTTED],
], 28));
docChildren.push(emptyPara());
// ── SECTION 2: Technique ──────────────────────────────────────────────────────
docChildren.push(sectionBar("SECTION 2 — TECHNIQUE & EQUIPMENT"));
docChildren.push(fieldTable([
["Machine / Model", DOTTED],
["Transducer", "Linear high-frequency 7.5 – 15 MHz"],
["Patient Position", "Standing / Reverse Trendelenburg ☐ Supine ☐"],
["Compression Method", "Manual calf squeeze ☐ Pneumatic cuff deflation ☐"],
["Valsalva Manoeuvre", "Yes ☐ No ☐ (used for SFJ / CFV assessment)"],
["Modes Used", "B-mode (greyscale) + Colour Doppler + Spectral Doppler (Duplex)"],
["Scan Performed By", DOTTED],
["Interpreted By", DOTTED],
], 28));
docChildren.push(emptyPara(40));
docChildren.push(new Paragraph({
children: [
run("Reflux Threshold (SVS/AVF/AVLS 2023): ", { bold: true, size: 17, color: C.darkBlue }),
run("Superficial veins & perforators: ", { size: 17 }),
run(">500 ms", { bold: true, size: 17, color: C.midBlue }),
run(" retrograde flow. Deep veins (CFV, FV, POPV): ", { size: 17 }),
run(">1000 ms", { bold: true, size: 17, color: C.midBlue }),
run(" retrograde flow. Pathological perforator: diameter ", { size: 17 }),
run("≥3.5 mm", { bold: true, size: 17, color: C.midBlue }),
run(" AND outward flow ", { size: 17 }),
run("≥500 ms", { bold: true, size: 17, color: C.midBlue }),
],
spacing: { before: 40, after: 120 },
shading: shading(C.rowAlt),
}));
// ── SECTIONS 3 & 4: Right & Left Limbs ────────────────────────────────────────
buildLimb("RIGHT", "3").forEach(el => docChildren.push(el));
docChildren.push(new Paragraph({ children: [new PageBreak()] }));
buildLimb("LEFT", "4").forEach(el => docChildren.push(el));
// ── SECTION 5: Reflux Pattern ─────────────────────────────────────────────────
docChildren.push(emptyPara());
docChildren.push(sectionBar("SECTION 5 — REFLUX PATTERN CLASSIFICATION (BILATERAL SUMMARY)"));
docChildren.push(dataTable(
["Reflux Pattern", "Right", "Left"],
[
["Axial reflux (groin to calf, uninterrupted)", "Present ☐ Absent ☐","Present ☐ Absent ☐"],
["Junctional reflux only (SFJ or SPJ isolated)", "Present ☐ Absent ☐","Present ☐ Absent ☐"],
["Segmental reflux (portion of truncal vein)", "Present ☐ Absent ☐","Present ☐ Absent ☐"],
["Deep vein reflux", "Present ☐ Absent ☐","Present ☐ Absent ☐"],
["Perforator-sourced reflux", "Present ☐ Absent ☐","Present ☐ Absent ☐"],
["Pelvic source suspected", "Present ☐ Absent ☐","Present ☐ Absent ☐"],
],
[55, 22, 23]
));
docChildren.push(emptyPara());
// ── SECTION 6: CEAP ───────────────────────────────────────────────────────────
docChildren.push(sectionBar("SECTION 6 — CEAP CLASSIFICATION (2020 Updated CEAP – American Venous Forum)"));
docChildren.push(dataTable(
["Component","Right","Left"],
[
["C – Clinical class", "C___", "C___"],
["E – Etiology", "Ep (primary) ☐ Es (secondary/post-thrombotic) ☐ Ec (congenital) ☐", "Ep ☐ Es ☐ Ec ☐"],
["A – Anatomy", "As (superficial) ☐ Ad (deep) ☐ Ap (perforator) ☐", "As ☐ Ad ☐ Ap ☐"],
["P – Pathophysiology", "Pr (reflux) ☐ Po (obstruction) ☐ Pr,o (both) ☐", "Pr ☐ Po ☐ Pr,o ☐"],
],
[20, 55, 25]
));
docChildren.push(emptyPara(40));
docChildren.push(subHead("CEAP Clinical Classes"));
docChildren.push(dataTable(
["Class","Description"],
[
["C0","No visible or palpable signs of venous disease"],
["C1","Telangiectasias or reticular veins"],
["C2","Varicose veins"],
["C2r","Recurrent varicose veins"],
["C3","Oedema"],
["C4a","Pigmentation or eczema"],
["C4b","Lipodermatosclerosis or atrophie blanche"],
["C4c","Corona phlebectatica"],
["C5","Healed venous ulcer"],
["C6","Active venous ulcer"],
["C6r","Recurrent active venous ulcer"],
],
[15, 85]
));
docChildren.push(emptyPara(40));
docChildren.push(para([
run("Suffix: ", { bold: true, size: 17, color: C.darkBlue }),
run("s = symptomatic (pain, heaviness, swelling, achiness, itching – HASTI symptoms) | a = asymptomatic", { size: 17 }),
]));
docChildren.push(para([
run("Right CEAP: ", { bold: true, size: 18, color: C.darkBlue }),
run("C___ E___ A___ P___ ( s / a ) ", { size: 18 }),
run("Left CEAP: ", { bold: true, size: 18, color: C.darkBlue }),
run("C___ E___ A___ P___ ( s / a )", { size: 18 }),
]));
// ── SECTION 7: Summary ────────────────────────────────────────────────────────
docChildren.push(new Paragraph({ children: [new PageBreak()] }));
docChildren.push(sectionBar("SECTION 7 — SUMMARY OF FINDINGS"));
for (const side of ["RIGHT", "LEFT"]) {
docChildren.push(subHead(`${side} LOWER LIMB`));
docChildren.push(fieldTable([
["Deep system", "Patent ☐ No DVT ☐ Deep venous reflux: Present ☐ Absent ☐ at: _______________________"],
["SFJ", "Competent ☐ Incompetent ☐ Reflux: _______ ms"],
["GSV", "Reflux from __________________ to __________________ Total: _______ cm Diameter SFJ: _______ mm BK: _______ mm"],
["SSV / SPJ", "Competent ☐ Incompetent ☐ Reflux: _______ ms SSV length: _______ cm"],
["Reflux pattern", "Axial ☐ Junctional ☐ Segmental ☐"],
["Pathological IPVs", "_______ perforator(s) at: ________________________________________________"],
["Varicosities", "Distribution: ______________________ Source: ________________________"],
["Skin changes", "None ☐ Pigmentation ☐ LDS ☐ Corona phlebectatica ☐ Ulcer at: ______________"],
], 28));
docChildren.push(emptyPara());
}
// ── SECTION 8: Impression ─────────────────────────────────────────────────────
docChildren.push(sectionBar("SECTION 8 — IMPRESSION"));
for (const [side, n] of [["RIGHT","8.1"],["LEFT","8.2"]]) {
docChildren.push(new Paragraph({
children: [run(`${n} ${side} LOWER LIMB`, { bold: true, size: 18, color: C.darkBlue })],
spacing: { before: 80, after: 20 },
shading: shading(C.lightBlue),
}));
docChildren.push(new Paragraph({
children: [
run(`CEAP: C___ E___ A___ P___ (s/a)\n`, { bold: true, size: 17 }),
run(`Chronic venous insufficiency, ${side.toLowerCase()} lower limb.\n`, { size: 17 }),
run("Reflux type: GSV axial ☐ SFJ junctional ☐ SSV reflux ☐ Isolated perforator ☐\n", { size: 17 }),
run("Reflux from ____________________ to ____________________ Truncal length: _______ cm\n", { size: 17 }),
run("Deep venous system: Patent ☐ DVT at: ____________________ Chronic changes: ____________________", { size: 17 }),
],
spacing: { before: 40, after: 80 },
shading: shading(C.white),
border: { top: { style: BorderStyle.SINGLE, size: 6, color: C.midBlue },
bottom: { style: BorderStyle.SINGLE, size: 6, color: C.midBlue },
left: { style: BorderStyle.SINGLE, size: 6, color: C.midBlue },
right: { style: BorderStyle.SINGLE, size: 6, color: C.midBlue } },
}));
}
// ── SECTION 9: Recommendations ───────────────────────────────────────────────
docChildren.push(emptyPara(40));
docChildren.push(sectionBar("SECTION 9 — CLINICAL CORRELATION & RECOMMENDATIONS"));
const recs = [
"☐ Findings support conservative management (compression stockings, lifestyle) for C2/C3 disease",
"☐ Patient suitable for endovenous thermal ablation (EVLA / RFA) of GSV – Right ☐ Left ☐ Bilateral ☐",
"☐ Patient suitable for ultrasound-guided foam sclerotherapy (UGFS) of: ___________________________",
"☐ Phlebectomy / stab avulsions of varicosities advised",
"☐ Perforator ablation (MOCA / UGFS) advised for IPVs at: _____________________________________",
"☐ DVT found – anticoagulation and haematology referral recommended",
"☐ Deep venous reflux present – refer to vascular surgery for further evaluation",
"☐ Pelvic source suspected – pelvic venous duplex / CT venography recommended",
"☐ Pre-treatment anatomical mapping complete for planned intervention",
"☐ Post-treatment follow-up – occlusion confirmed ☐ Re-canalisation noted ☐",
];
recs.forEach(r => docChildren.push(bullet(r)));
docChildren.push(emptyPara());
// ── SECTION 10: Technical Quality ────────────────────────────────────────────
docChildren.push(sectionBar("SECTION 10 — TECHNICAL QUALITY"));
[
"☐ Technically satisfactory – all segments adequately assessed",
"☐ Suboptimal assessment of: ____________________ due to: oedema / pain / obesity / wound",
"☐ Standing position not tolerated; examination performed supine – may underestimate reflux",
"☐ Images archived to PACS / printed and filed",
].forEach(t => docChildren.push(bullet(t)));
docChildren.push(emptyPara());
// ── Authorisation ─────────────────────────────────────────────────────────────
docChildren.push(sectionBar("AUTHORISATION"));
docChildren.push(fieldTable([
["Report Prepared By", DOTTED],
["Qualification", "MD Radiology / DNB Radiology / DMRD / MS Vascular Surgery"],
["MCI / NMC Reg. No.", DOTTED],
["Date & Time", DOTTED],
["Signature & Stamp", ""],
["Centre Name & Address",DOTTED],
], 28));
docChildren.push(emptyPara(60));
// ── Disclaimer ────────────────────────────────────────────────────────────────
docChildren.push(new Paragraph({
children: [
run("DISCLAIMER: ", { bold: true, size: 15, color: C.darkBlue }),
run(
"This report constitutes a screening/diagnostic duplex ultrasound examination. A normal study does not exclude all venous pathology. " +
"Results are position- and technique-dependent; reflux may be underestimated in the supine position. " +
"All findings must be correlated with clinical history, physical examination, and symptom severity (HASTI). " +
"References: SVS/AVF/AVLS 2023 Varicose Vein Guidelines (PMID 37652254) | 2020 CEAP Update (AVF) | " +
"UIP Duplex Consensus Document | ACR Duplex Ultrasound Standards.",
{ italic: true, size: 15, color: C.grey }
),
],
spacing: { before: 60, after: 60 },
shading: shading(C.rowAlt),
}));
// ─────────────────────────────────────────────────────────────────────────────
// HEADER & FOOTER
// ─────────────────────────────────────────────────────────────────────────────
const pageHeader = new Header({
children: [
new Paragraph({
children: [run("VENOUS DUPLEX DOPPLER – Bilateral Lower Limb Varicose Veins", { bold: true, size: 17, color: C.darkBlue })],
alignment: AlignmentType.CENTER,
border: { bottom: { style: BorderStyle.SINGLE, size: 6, color: C.midBlue } },
spacing: { before: 0, after: 60 },
}),
],
});
const pageFooter = new Footer({
children: [
new Paragraph({
children: [
run("Reflux thresholds: Superficial/Perforators >500 ms | Deep veins (CFV/FV/POPV) >1000 ms | Pathological perforator: ≥3.5 mm & ≥500 ms | Page ", { size: 14, color: C.grey }),
new TextRun({ children: [PageNumber.CURRENT], font: "Calibri", size: 14, color: C.grey }),
],
alignment: AlignmentType.CENTER,
border: { top: { style: BorderStyle.SINGLE, size: 4, color: C.midBlue } },
spacing: { before: 60, after: 0 },
}),
],
});
// ─────────────────────────────────────────────────────────────────────────────
// ASSEMBLE & WRITE
// ─────────────────────────────────────────────────────────────────────────────
const doc = new Document({
creator: "Orris Medical Reports",
title: "Bilateral Lower Limb Varicose Veins Doppler Report",
subject: "Venous Duplex Doppler Ultrasound",
sections: [{
headers: { default: pageHeader },
footers: { default: pageFooter },
properties: {
page: {
margin: { top: mm(20), bottom: mm(18), left: mm(18), right: mm(15) },
},
},
children: docChildren,
}],
});
const OUT = "/home/daytona/workspace/varicose-doppler/Varicose_Veins_Doppler_Report.docx";
Packer.toBuffer(doc).then(buf => {
fs.writeFileSync(OUT, buf);
console.log("DOCX created:", OUT);
});
cd /home/daytona/workspace/varicose-doppler && node generate_report.js 2>&1
ls -lh /home/daytona/workspace/varicose-doppler/ && python /home/daytona/skills/…
cd /home/daytona/workspace/varicose-doppler && python3 -c " import zipfile, sys …
Varicose Veins Doppler Report
Word Document · DOCX
| File | Format | Use for |
|---|---|---|
Varicose Veins Doppler Report Word Document · DOCX | Word (.docx) | Editing, customising centre name, filling patient data |
Varicose Veins Doppler Report PDF Document · PDF | Printing, archiving, sharing read-only |