def save_as_csv(agg_metric, fname_out, fname_in=None, append=False): """ Write metric structure as csv. If field 'error' exists, it will add a specific column. :param agg_metric: output of aggregate_per_slice_or_level() :param fname_out: output filename. Extention (.csv) will be added if it does not exist. :param fname_in: input file to be listed in the csv file (e.g., segmentation file which produced the results). :param append: Bool: Append results at the end of file (if exists) instead of overwrite. :return: """ # Item sorted in order for display in csv output # list_item = ['VertLevel', 'Label', 'MEAN', 'WA', 'BIN', 'ML', 'MAP', 'STD', 'MAX'] # TODO: The thing below is ugly and needs to be fixed, but this is the only solution I found to order the columns # without refactoring the code with OrderedDict. list_item = ['Label', 'Size [vox]', 'MEAN(area)', 'STD(area)', 'MEAN(angle_AP)', 'STD(angle_AP)', 'MEAN(angle_RL)', 'STD(angle_RL)', 'MEAN(diameter_AP)', 'STD(diameter_AP)', 'MEAN(diameter_RL)', 'STD(diameter_RL)', 'MEAN(eccentricity)', 'STD(eccentricity)', 'MEAN(orientation)', 'STD(orientation)', 'MEAN(solidity)', 'STD(solidity)', 'SUM(length)', 'WA()', 'BIN()', 'ML()', 'MAP()', 'STD()', 'MAX()'] # TODO: if append=True but file does not exist yet, raise warning and set append=False # write header (only if append=False) if not append or not os.path.isfile(fname_out): with open(fname_out, 'w') as csvfile: # spamwriter = csv.writer(csvfile, delimiter=',') header = ['Timestamp', 'SCT Version', 'Filename', 'Slice (I->S)', 'VertLevel'] agg_metric_key = [v for i, (k, v) in enumerate(agg_metric.items())][0] for item in list_item: for key in agg_metric_key: if item in key: header.append(key) break writer = csv.DictWriter(csvfile, fieldnames=header) writer.writeheader() # populate data with open(fname_out, 'a') as csvfile: spamwriter = csv.writer(csvfile, delimiter=',') for slicegroup in sorted(agg_metric.keys()): line = list() line.append(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) # Timestamp line.append(__version__) # SCT Version line.append(fname_in) # file name associated with the results line.append(parse_num_list_inv(slicegroup)) # list all slices in slicegroup line.append(parse_num_list_inv(agg_metric[slicegroup]['VertLevel'])) # list vertebral levels agg_metric_key = [v for i, (k, v) in enumerate(agg_metric.items())][0] for item in list_item: for key in agg_metric_key: if item in key: line.append(str(agg_metric[slicegroup][key])) break spamwriter.writerow(line)
def save_as_csv(agg_metric, fname_out, fname_in=None, append=False): """ Write metric structure as csv. If field 'error' exists, it will add a specific column. :param agg_metric: output of aggregate_per_slice_or_level() :param fname_out: output filename. Extention (.csv) will be added if it does not exist. :param fname_in: input file to be listed in the csv file (e.g., segmentation file which produced the results). :param append: Bool: Append results at the end of file (if exists) instead of overwrite. :return: """ # Item sorted in order for display in csv output # list_item = ['VertLevel', 'Label', 'MEAN', 'WA', 'BIN', 'ML', 'MAP', 'STD', 'MAX'] # TODO: The thing below is ugly and needs to be fixed, but this is the only solution I found to order the columns # without refactoring the code with OrderedDict. list_item = ['Label', 'Size [vox]', 'MEAN(area)', 'STD(area)', 'MEAN(angle_AP)', 'STD(angle_AP)', 'MEAN(angle_RL)', 'STD(angle_RL)', 'MEAN(diameter_AP)', 'STD(diameter_AP)', 'MEAN(diameter_RL)', 'STD(diameter_RL)', 'MEAN(eccentricity)', 'STD(eccentricity)', 'MEAN(orientation)', 'STD(orientation)', 'MEAN(solidity)', 'STD(solidity)', 'WA()', 'BIN()', 'ML()', 'MAP()', 'STD()', 'MAX()'] # TODO: if append=True but file does not exist yet, raise warning and set append=False # write header (only if append=False) if not append or not os.path.isfile(fname_out): with open(fname_out, 'w') as csvfile: # spamwriter = csv.writer(csvfile, delimiter=',') header = ['Timestamp', 'SCT Version', 'Filename', 'Slice (I->S)', 'VertLevel'] agg_metric_key = [v for i, (k, v) in enumerate(agg_metric.items())][0] for item in list_item: for key in agg_metric_key: if item in key: header.append(key) break writer = csv.DictWriter(csvfile, fieldnames=header) writer.writeheader() # populate data with open(fname_out, 'a') as csvfile: spamwriter = csv.writer(csvfile, delimiter=',') for slicegroup in sorted(agg_metric.keys()): line = list() line.append(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")) # Timestamp line.append(__version__) # SCT Version line.append(fname_in) # file name associated with the results line.append(parse_num_list_inv(slicegroup)) # list all slices in slicegroup line.append(parse_num_list_inv(agg_metric[slicegroup]['VertLevel'])) # list vertebral levels agg_metric_key = [v for i, (k, v) in enumerate(agg_metric.items())][0] for item in list_item: for key in agg_metric_key: if item in key: line.append(str(agg_metric[slicegroup][key])) break spamwriter.writerow(line)
def test_parse_num_list_inv(): assert utils.parse_num_list_inv([1, 2, 3, 5, 6, 9]) == '1:3;5:6;9' assert utils.parse_num_list_inv([3, 2, 1, 5]) == '1:3;5' assert utils.parse_num_list_inv([]) == ''
def test_parse_num_list_inv(): assert utils.parse_num_list_inv([1, 2, 3, 5, 6, 9]) == '1:3;5:6;9' assert utils.parse_num_list_inv([3, 2, 1, 5]) == '1:3;5' assert utils.parse_num_list_inv([]) == ''