-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDataDisplayWindow.cpp
More file actions
379 lines (313 loc) · 13.7 KB
/
Copy pathDataDisplayWindow.cpp
File metadata and controls
379 lines (313 loc) · 13.7 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
#include "DataDisplayWindow.h"
DataDisplayWindow::DataDisplayWindow(QWidget* parent, int field, int span, int complexity, int totaldbSeq, int totalSmallSeq, int totalYielding, int totalNonYielding)
: BaseClass(parent), field(field), span(span), complexity(complexity), totaldbSeq(totaldbSeq), totalSmallSeq(totalSmallSeq), totalYielding(totalYielding), totalNonYielding(totalNonYielding)
{
// top label
std::string str = "de-Bruijn Sequences\n Over Field F" + std::to_string(field)
+ " Span " + std::to_string(span)
+ " Complexity " + std::to_string(complexity);
const char* label = str.c_str();
topLabel->setText(tr(label));
QFont labelFont = topLabel->font();
labelFont.setPointSize(15);
labelFont.setBold(true);
topLabel->setFont(labelFont);
topLabel->setAlignment(Qt::AlignCenter);
// results group box
createResultsGroupBox();
// filter checkboxes
createFiltersGroupBox();
// small seq inspection groupbox
createSmallSeqInspectGroupBox();
connect(smallSequenceInput, &QTextEdit::textChanged, this, &DataDisplayWindow::validateText);
connect(inspectButton, &QPushButton::clicked, this, &DataDisplayWindow::onInspectButtonClicked);
// button box
leftButton->setText(tr("Load Files"));
connect(leftButton, &QPushButton::clicked, this, &DataDisplayWindow::onOpenFileClicked);
rightButton->setText(tr("Close"));
connect(rightButton, &QPushButton::clicked, this, &DataDisplayWindow::reject);
buttonBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
// main layout
mainLayout->addWidget(topLabel);
mainLayout->addSpacing(20);
mainLayout->addWidget(resultsGroupBox);
mainLayout->addSpacing(5);
mainLayout->addWidget(filtersGroupBox);
mainLayout->addSpacing(5);
mainLayout->addWidget(smallSeqInspectGroupBox);
mainLayout->addSpacing(20);
mainLayout->addWidget(buttonBox);
// main widget
QWidget* mainWidget = new QWidget(this);
mainWidget->setLayout(mainLayout);
setLayout(mainLayout);
}
void DataDisplayWindow::createResultsGroupBox()
{
QFormLayout* resultsLayout = new QFormLayout;
resultsGroupBox = new QGroupBox(tr("Results Overview"));
// LABELS
QLabel* labelTotalDbSeq = new QLabel(tr("Total number of de Bruijn sequences is: %1").arg(totaldbSeq));
QLabel* labelTotalSmallSeq = new QLabel(tr("Total number of sequences of small complexity is: %1").arg(totalSmallSeq));
QLabel* labelTotalYielding = new QLabel(tr("Total number of sequences of small complexity which yielded de Bruijn sequences is : %1").arg(totalYielding));
QLabel* labelTotalNonYielding = new QLabel(tr("Total number of sequences of small complexity which DIDN'T yield de Bruijn sequences is : %1").arg(totalNonYielding));
// LABEL FONT
QFont groupBoxFont = resultsGroupBox->font();
groupBoxFont.setPointSize(11);
resultsGroupBox->setFont(groupBoxFont); // group box title
labelTotalDbSeq->setFont(groupBoxFont);
labelTotalSmallSeq->setFont(groupBoxFont);
labelTotalYielding->setFont(groupBoxFont);
labelTotalNonYielding->setFont(groupBoxFont);
// LAYOUT
resultsLayout->addRow(labelTotalDbSeq);
resultsLayout->addRow(labelTotalSmallSeq);
resultsLayout->addRow(labelTotalYielding);
resultsLayout->addRow(labelTotalNonYielding);
resultsGroupBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
resultsGroupBox->setLayout(resultsLayout);
}
void DataDisplayWindow::createFiltersGroupBox()
{
QFormLayout* filtersLayout = new QFormLayout;
filtersGroupBox = new QGroupBox(tr("Select Files To Open"));
QLabel* label = new QLabel(tr("Small sequences file options:"));
label->setStyleSheet("QLabel { font-weight : bold; }");
QWidget* verticalSpacerWidget = new QWidget();
verticalSpacerWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
verticalSpacerWidget->setFixedHeight(3);
// CHECK BOXES
noFilterCheckbox = new QCheckBox(tr("Original File"), this);
noFilterCheckbox->setToolTip(tr("Select to open the original file"));
yieldingCheckbox = new QCheckBox(tr("Yielding Sequences Only"), this);
yieldingCheckbox->setToolTip(tr("Select to show the small sequences & their yeilded de-Bruijn sequences"));
yieldingSmallCheckbox = new QCheckBox(tr("Yielding Small Sequences Only"), this);
yieldingSmallCheckbox->setToolTip(tr("Select to show sequences of small complexity which yield any de-Bruijn sequences"));
NonYieldingCheckbox = new QCheckBox(tr("Non-Yielding Small Sequences Only"), this);
NonYieldingCheckbox->setToolTip(tr("Select to show sequences of small complexity which do not yield de-Bruijn sequences"));
filterSmallSeqCheckbox = new QCheckBox(tr("Sequences Of Small Complexity Only"), this);
filterSmallSeqCheckbox->setToolTip(tr("Select to open the file containing the sequences of small complexity of which we generate the de-Bruijn sequences"));
// LABEL FONT
QFont groupBoxFont = filtersGroupBox->font();
groupBoxFont.setPointSize(11);
label->setFont(groupBoxFont);
filtersGroupBox->setFont(groupBoxFont); // group box title
noFilterCheckbox->setFont(groupBoxFont);
yieldingCheckbox->setFont(groupBoxFont);
yieldingSmallCheckbox->setFont(groupBoxFont);
NonYieldingCheckbox->setFont(groupBoxFont);
filterSmallSeqCheckbox->setFont(groupBoxFont);
// LAYOUT
filtersLayout->addRow(noFilterCheckbox);
filtersLayout->addRow(yieldingCheckbox); //add spacing inbetween
filtersLayout->addRow(tr(""), verticalSpacerWidget);
filtersLayout->addRow(label);
filtersLayout->addRow(yieldingSmallCheckbox);
filtersLayout->addRow(NonYieldingCheckbox);
filtersLayout->addRow(filterSmallSeqCheckbox);
filtersGroupBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
filtersGroupBox->setLayout(filtersLayout);
}
void DataDisplayWindow::createSmallSeqInspectGroupBox()
{
QVBoxLayout* groupBoxLayout = new QVBoxLayout;
QLabel* label = new QLabel(tr("Enter the sequences of small complexity which you would like to inspect, separated by a new line: "));
smallSeqInspectGroupBox = new QGroupBox(tr("Sequence Inspection"));
// TEXT EDIT
smallSequenceInput = new QTextEdit(this);
smallSequenceInput->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// CHECKBOX
inspectSeparatelyCheckbox = new QCheckBox(tr("Extract to separate files"), this);
inspectSeparatelyCheckbox->setToolTip(tr("Check to save each small sequence result in a separate file"));
// LABEL FONT
QFont groupBoxFont = smallSeqInspectGroupBox->font();
groupBoxFont.setPointSize(11);
smallSeqInspectGroupBox->setFont(groupBoxFont); // group box title
label->setFont(groupBoxFont);
inspectSeparatelyCheckbox->setFont(groupBoxFont);
smallSequenceInput->setFont(groupBoxFont);
// BUTTON
inspectButton = new QPushButton(tr("Inspect"), this);
inspectButton->setStyleSheet(
"QPushButton { "
" background-color: #2196F3; " // Vibrant blue
" color: white; " // text color
" border-radius: 4px; " // Rounded corners
" font-weight: bold; "
" border: none; "
" padding: 5px 15px; "
"} "
"QPushButton:hover { "
" background-color: #1E88E5; " // dark blue
"} "
"QPushButton:pressed { "
" background-color: #1565C0; " // dark blue
"} "
"QDialogButtonBox > QPushButton { "
" min-width: 50px; " // Minimum width for both buttons
"}"
);
QHBoxLayout* buttonLayout = new QHBoxLayout;
buttonLayout->addWidget(inspectButton);
buttonLayout->addStretch(); // align button to the left
// LAYOUT
groupBoxLayout->addWidget(label);
groupBoxLayout->addWidget(smallSequenceInput);
groupBoxLayout->addWidget(inspectSeparatelyCheckbox);
groupBoxLayout->addLayout(buttonLayout); // Add the horizontal layout containing the button & checkbox
smallSeqInspectGroupBox->setLayout(groupBoxLayout);
}
void DataDisplayWindow::onOpenFileClicked()
{
bool isNoFilterChecked = noFilterCheckbox->isChecked();
bool NonYieldingChecked = NonYieldingCheckbox->isChecked();
bool yieldingChecked = yieldingCheckbox->isChecked();
bool yieldingSmallChecked = yieldingSmallCheckbox->isChecked();
bool smallSeqChecked = filterSmallSeqCheckbox->isChecked();
QString fileName = "";
if (isNoFilterChecked) {
fileName = QString("/data/F_%1/span_%2/%3/field_%1_span_%2_complexity_%3.txt").arg(field).arg(span).arg(complexity);
openFileForUser(fileName);
noFilterCheckbox->setCheckState(Qt::Unchecked);
}
if (yieldingChecked) {
fileName = QString("/data/F_%1/span_%2/%3/%3_yielding_sequences.txt").arg(field).arg(span).arg(complexity);
openFileForUser(fileName);
yieldingSmallCheckbox->setCheckState(Qt::Unchecked);
}
if (NonYieldingChecked) {
fileName = QString("/data/F_%1/span_%2/%3/%3_non_yielding_small_sequences.txt").arg(field).arg(span).arg(complexity);
openFileForUser(fileName);
NonYieldingCheckbox->setCheckState(Qt::Unchecked);
}
if (yieldingSmallChecked) {
fileName = QString("/data/F_%1/span_%2/%3/%3_yielding_small_sequences.txt").arg(field).arg(span).arg(complexity);
openFileForUser(fileName);
yieldingCheckbox->setCheckState(Qt::Unchecked);
}
if (smallSeqChecked) {
int offset;
if (field == 2)
offset = complexity - qPow(field, span - 1);
else
offset = complexity % field;
//open file
fileName = QString("/data/F_%1/smallSequences/sequences_of_complexity_%2.txt").arg(field).arg(offset);
openFileForUser(fileName);
filterSmallSeqCheckbox->setCheckState(Qt::Unchecked);
}
}
void DataDisplayWindow::openFileForUser(const QString& filePath)
{
QString appDir = QCoreApplication::applicationDirPath();
#ifdef _DEBUG // go up two directories from the Release/Debug folder
appDir = QDir(appDir).absoluteFilePath("../../");
#endif
QString localFilePath = appDir + filePath;
QUrl fileUrl = QUrl::fromLocalFile(localFilePath);
if (!QDesktopServices::openUrl(fileUrl)) {
QMessageBox::warning(this, tr("File Open Error"), tr("Unable to open file: ") + localFilePath);
}
}
void DataDisplayWindow::validateText()
{
QRegularExpression re("^(\\d+\n)*\\d+$");
QString text = smallSequenceInput->toPlainText();
QRegularExpressionMatch match = re.match(text);
if (!match.hasMatch()) {
QMessageBox::warning(this, tr("Invalid Text Detected"), tr("Only digits and new lines are allowed. Each line must contain only digits."));
}
}
void DataDisplayWindow::onInspectButtonClicked()
{
bool inspectSeparatelyChecked = inspectSeparatelyCheckbox->isChecked();
QString userInput = smallSequenceInput->toPlainText();
if (userInput.isEmpty()) {
QMessageBox::warning(this, tr("Error"), tr("Sequence inspection requires at least one sequence to be inserted in the box before proceeding."));
return;
}
QStringList smallSequences = userInput.split('\n', Qt::SkipEmptyParts);
QString saveFilePath;
QFile fileOut;
QTextStream out;
QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
QString folderName = "inspection_result"; // output folder
QDir desktopDir(desktopPath);
//inspect separely
if (inspectSeparatelyChecked && !desktopDir.exists(folderName)) {
desktopDir.mkdir(folderName); // Create the folder if it does not exist
}
else if (!inspectSeparatelyChecked) {
saveFilePath = QFileDialog::getSaveFileName(this, tr("Save File"), QStandardPaths::writableLocation(QStandardPaths::DesktopLocation),tr("Text Files (*.txt)"));
if (saveFilePath.isEmpty()) {
QMessageBox::information(this, tr("Cancelled"), tr("File save cancelled."));
return;
}
fileOut.setFileName(saveFilePath);
if (!fileOut.open(QIODevice::ReadWrite | QIODevice::Truncate | QIODevice::Text )) {
QMessageBox::warning(this, tr("Error"), tr("Cannot create or open file for writing."));
return;
}
out.setDevice(&fileOut);
}
QString ReadFilePath = QString(":/results/data/F_%1/span_%2/%3/field_%1_span_%2_complexity_%3.txt").arg(field).arg(span).arg(complexity);
QFile ReadFile(ReadFilePath);
if (!ReadFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Error"), tr("Cannot open file for reading."));
return;
}
QTextStream in(&ReadFile);
QString line;
bool isSequenceOfInterest = false; // Flag to track if we're within a section of interest
static QRegularExpression smallSeqRegex(R"(Debruijn Sequences generated by the sequence (\d+) : )");
while (in.readLineInto(&line)) {
QRegularExpressionMatch smallSeqMatch = smallSeqRegex.match(line);
if (smallSeqMatch.hasMatch()) { //sequence of interest
QString currentSeq = smallSeqMatch.captured(1);
if (smallSequences.contains(currentSeq)) {
isSequenceOfInterest = true;
//inspect separelty
if (inspectSeparatelyChecked) {
QString individualFileName = QString("%1/%2_F%3_complexity_%4.txt").arg(folderName).arg(currentSeq).arg(field).arg(complexity);
fileOut.setFileName(desktopPath + "/" + individualFileName);
if (!fileOut.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::warning(this, tr("Error"), tr("Cannot create or open file for writing."));
return;
}
out.setDevice(&fileOut);
}
out << line << "\n";
}
else {
isSequenceOfInterest = false;
if (inspectSeparatelyChecked && fileOut.isOpen()) {
fileOut.close();
}
}
}
else if (isSequenceOfInterest) {
if (!line.trimmed().isEmpty()) {
out << line << "\n";
}
else {
out << "\n";
isSequenceOfInterest = false;
if (inspectSeparatelyChecked && fileOut.isOpen()) {
fileOut.close(); // Close the individual file
}
}
}
}
if (inspectSeparatelyChecked && fileOut.isOpen()) {
fileOut.close();
}
// inform the user that the inspection is complete
if (!inspectSeparatelyChecked) {
QMessageBox::information(this, tr("Success"), tr("Inspection complete.\n\nClick OK to open the inspection result file."));
QDesktopServices::openUrl(QUrl::fromLocalFile(fileOut.fileName()));
}
else {
QMessageBox::information(this, tr("Success"), tr("All separate inspections completed.\nThe results were saved under a new folder <inspection_result> in your desktop.\n\nClick OK to open the inspection result directory."));
QDesktopServices::openUrl(QUrl::fromLocalFile(desktopPath + "/" + folderName));
}
}