Switch to unified view

a b/CLI/IntervertebralAnalysis/IntervertebralAnalysis.py
1
#!/usr/bin/env python-real
2
3
import sys
4
import os
5
from datetime import date
6
7
import numpy as np
8
9
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
10
from MusculoskeletalAnalysisCLITools import (
11
   crop,
12
   readImg,
13
   readMask,
14
   width,
15
   writeReport,
16
)
17
18
19
OUTPUT_FIELDS = [
20
    ("Date Analysis Performed", "The current date"),
21
    ("Input Volume", "Name of the input volume"),
22
    ("Disc Volume (mm^3)", "The volume of the disc"),
23
    ("Nucleus Pulposus Volume (mm^3)", "The volume of the NP"),
24
    ("Volume Ratio", "The ratio of whole disc volume to NP volume"),
25
    ("Annulus Fibrosus Width (mm)", "The width of the AF, calculated by using rotating calipers algorithm on each slice and finding the maximum width"),
26
    ("Nucleus Pulposus Width (mm)", "The width of the NP, calculated using the same method as AF width"),
27
    ("Disc Height (mm)", "The height of the disc at its center"),
28
    ("Disc Height Ratio", "The ratio of disc height to disc width"),
29
    ("Voxel Dimension (mm)", "The side length of one voxel, measured in milimeters"),
30
]
31
32
33
def main(inputImg, inputMask1, inputMask2, voxSize, name, output):
34
    imgData = readImg(inputImg)
35
    (_, maskData1) = readMask(inputMask1)
36
    (_, maskData2) = readMask(inputMask2)
37
    # Set the np mask to the smaller one
38
    if np.count_nonzero(maskData1) > np.count_nonzero(maskData2):
39
        (maskData, npData, imgData) = crop(maskData1, maskData2, imgData)
40
    else:
41
        (maskData, npData, imgData) = crop(maskData2, maskData1, imgData)
42
    (maskData, npData, imgData) = crop(maskData, npData, imgData)
43
    if np.count_nonzero(maskData) == 0 or np.count_nonzero(npData) == 0:
44
         raise Exception("Segmentation mask is empty.")
45
46
    volume = np.count_nonzero(maskData) * voxSize**3
47
    npVolume = np.count_nonzero(npData) * voxSize**3
48
    vr = npVolume/volume
49
50
    print("""<filter-progress>{}</filter-progress>""".format(.33))
51
    sys.stdout.flush()
52
53
    afWidth= width(maskData) * voxSize
54
    npWidth = width(npData) * voxSize
55
56
    # Find the center
57
    xcent = int(np.rint(np.mean(np.nonzero(maskData)[0])))
58
    ycent = int(np.rint(np.mean(np.nonzero(maskData[1]))))
59
    center = np.nonzero(maskData[xcent,ycent,:])
60
    height = (np.max(center)-np.min(center)) * voxSize
61
62
    hw = height/afWidth
63
64
    print("""<filter-progress>{}</filter-progress>""".format(.66))
65
    sys.stdout.flush()
66
67
    fPath = os.path.join(output, "intervertebral.txt")
68
    header = [field[0] for field in OUTPUT_FIELDS]
69
    data = [
70
        date.today(),
71
        name,
72
        volume,
73
        npVolume,
74
        vr,
75
        afWidth,
76
        npWidth,
77
        height,
78
        hw,
79
        voxSize
80
    ]
81
82
    writeReport(fPath, header, data)
83
84
85
86
if __name__ == "__main__":
87
    if len(sys.argv) < 7:
88
        print(sys.argv)
89
        print("Usage: Intervertebral Analysis <input> <mask1> <mask2> <voxelSize> <name> <output>")
90
        sys.exit(1)
91
    main(sys.argv[1], sys.argv[2], sys.argv[3], float(sys.argv[4]), str(sys.argv[5]), str(sys.argv[6]))
92