-
Notifications
You must be signed in to change notification settings - Fork 1
/
files.go
134 lines (108 loc) · 3.27 KB
/
files.go
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main
import (
_ "embed"
"errors"
"fmt"
"log"
"os"
"reflect"
"github.com/gocarina/gocsv"
"github.com/xuri/excelize/v2"
)
//go:embed resources/prefix-data_clinical_patient.tsv
var prefixDataClinicalPatient string
//go:embed resources/prefix-data_clinical_sample.tsv
var prefixDataClinicalSample string
// Liest eine bestehende Datei ein
func ReadFile[D PatientData | SampleData](filename string, data []D) ([]D, error) {
file, err := os.Open(filename)
defer func(file *os.File) {
err := file.Close()
if err != nil {
log.Println("Cannot close file")
}
}(file)
if err != nil {
return nil, errors.New("file: Datei kann nicht geöffnet werden")
}
if gocsv.UnmarshalFile(file, &data) != nil {
return nil, errors.New("file: Datei kann nicht gelesen werden")
}
return data, nil
}
// Schreibt Daten in CSV/TSV Datei
func WriteFile[D PatientData | SampleData](filename string, data []D) error {
file, err := os.Create(filename)
if err != nil {
return errors.New("file: Datei kann nicht geöffnet werden")
}
if output, err := gocsv.MarshalString(data); err == nil {
// Prepend CSV comments bc cBioportal will result in errors without them
if reflect.TypeOf(data) == reflect.TypeOf([]PatientData{}) {
output = prefixDataClinicalPatient + output
} else if reflect.TypeOf(data) == reflect.TypeOf([]SampleData{}) {
output = prefixDataClinicalSample + output
}
if _, err := file.Write([]byte(output)); err != nil {
return errors.New("file: In die Datei kann nicht geschrieben werden")
}
} else {
return errors.New("file: Fehler beim Erstellen der Ausgabedaten")
}
return nil
}
// Schreibt Daten in Xlsx Datei
func WriteXlsxFile(filename string, patientData []PatientData, sampleData []SampleData) error {
file := excelize.NewFile()
defer func() {
if err := file.Close(); err != nil {
return
}
}()
patientsIndex, _ := file.NewSheet("Patients Data")
samplesIndex, _ := file.NewSheet("Samples Data")
_ = addPatientData(file, patientsIndex, patientData)
_ = addSampleData(file, samplesIndex, sampleData)
_ = file.DeleteSheet("Sheet1")
if err := file.SaveAs(filename); err != nil {
fmt.Println(err)
}
return nil
}
func addPatientData(file *excelize.File, index int, patientData []PatientData) error {
file.SetActiveSheet(index)
for idx, columnHeader := range PatientDataHeaders() {
cell := getColumn(idx) + "1"
_ = file.SetCellValue("Patients Data", cell, columnHeader)
}
for row, data := range patientData {
for idx, value := range data.AsStringArray() {
cell := getColumn(idx) + fmt.Sprint(row+2)
_ = file.SetCellValue("Patients Data", cell, value)
}
}
return nil
}
func addSampleData(file *excelize.File, index int, sampleData []SampleData) error {
file.SetActiveSheet(index)
for idx, columnHeader := range SampleDataHeaders() {
cell := getColumn(idx) + "1"
_ = file.SetCellValue("Samples Data", cell, columnHeader)
}
for row, data := range sampleData {
for idx, value := range data.AsStringArray() {
cell := getColumn(idx) + fmt.Sprint(row+2)
_ = file.SetCellValue("Samples Data", cell, value)
}
}
return nil
}
func getColumn(idx int) string {
z := int('Z' - 'A' + 1)
m := idx % z
if idx <= m {
return string(rune(idx + 'A'))
}
r := ((idx - m) / z) - 1
return string(rune(r+'A')) + string(rune(m+'A'))
}