-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgenerate_graph_csa_pmj.py
97 lines (80 loc) · 3.33 KB
/
generate_graph_csa_pmj.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env python
# -*- coding: utf-8
# Functions to plot CSA perslice and vertebral levels
# Need sct_process_segmentation -vert 1:10 -vertfile -perslice 1 -pmj
# Author: Sandrine Bédard
import matplotlib.pyplot as plt
import pandas as pd
import argparse
import numpy as np
def get_parser():
parser = argparse.ArgumentParser(
description="Generate graph of CSA perslice ")
parser.add_argument('-filename', required=True, type=str,
help="Input .csv file with CSA computed perslice.")
parser.add_argument('-o', required=False, type=str,
default='csa.png',
help="Ouput graph filename.")
return parser
def csv2dataFrame(filename):
"""
Loads a .csv file and builds a pandas dataFrame of the data
Args:
filename (str): filename of the .csv file
Returns:
data (pd.dataFrame): pandas dataframe of the .csv file's data
"""
data = pd.read_csv(filename)
return data
def get_csa(csa_filename):
"""
From .csv output file of process_data.sh (sct_process_segmentation),
returns a panda dataFrame with CSA values sorted by subject eid.
Args:
csa_filename (str): filename of the .csv file that contains de CSA values
Returns:
csa (pd.Series): column of CSA values
"""
sc_data = csv2dataFrame(csa_filename)
csa = pd.DataFrame(sc_data[['Filename', 'Slice (I->S)', 'VertLevel','DistancePMJ', 'MEAN(area)']]).rename(columns={'Filename': 'Subject'})
# Add a columns with subjects eid from Filename column
csa.loc[:, 'Subject'] = csa['Subject'].str.slice(-43, -32)
#TODO change CSA to float!!!
# Set index to subject eid
csa = csa.set_index('Subject')
return csa
def smooth(y, box_pts):
box = np.ones(box_pts)/box_pts
y_smooth = np.convolve(y, box, mode='same')
return y_smooth
def main():
parser = get_parser()
args = parser.parse_args()
df = get_csa(args.filename)
#df[df.rebounds != 'None']
df = df.replace('None', np.NaN)
df = df.dropna(0, how='any').reset_index(drop=True)
df = df.iloc[::-1].reset_index()
plt.figure()
fig, ax = plt.subplots(figsize=(5,6))
plt.tick_params(axis='y', which='both', labelleft=False, labelright=True)
# Get slices where array changes value
vert = df['VertLevel'].to_numpy()
ind_vert = np.where(vert[:-1] != vert[1:])[0]
for x in ind_vert:
new_x = (185-40) - x
plt.axhline(df.loc[x,'DistancePMJ'], color='darkblue', linestyle='--')
#ax.text(0.05 , new_x/(230), 'C'+str(vert[x]), transform=ax.transAxes, horizontalalignment='right', verticalalignment='center',color='darkblue')
ax.text(33 , df.loc[x,'DistancePMJ']-2, 'C'+str(vert[x]), horizontalalignment='right', verticalalignment='center',color='darkblue')
plt.plot(smooth(pd.to_numeric(df['MEAN(area)']).to_numpy(), 5)[6:-6],df['DistancePMJ'].to_numpy()[6:-6], 'r', aa=True)
plt.grid(color='lightgrey')
plt.title('Spinal Cord Cross-sectional area', fontsize=16)
#plt.ylim(max(df['DistancePMJ'].to_numpy()[6:-6]), min(df['DistancePMJ'].to_numpy()[6:-6]))
plt.ylim(190, 35)
plt.xlim(30,90)
plt.xlabel('CSA ($mm^2$)', fontsize=14)
plt.ylabel('Distance from PMJ (S->I)', fontsize=14)
#ax2.set_xlabel('VertLevel')
plt.savefig(args.o)
if __name__ == '__main__':
main()