3
// Copyright (c) 2010 by The VoxBo Development Team
5
// This file is part of VoxBo
7
// VoxBo is free software: you can redistribute it and/or modify it
8
// under the terms of the GNU General Public License as published by
9
// the Free Software Foundation, either version 3 of the License, or
10
// (at your option) any later version.
12
// VoxBo is distributed in the hope that it will be useful, but
13
// WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
// General Public License for more details.
17
// You should have received a copy of the GNU General Public License
18
// along with VoxBo. If not, see <http://www.gnu.org/licenses/>.
20
// For general information on VoxBo, including the latest complete
21
// source code and binary distributions, manual, and associated files,
22
// see the VoxBo home page at: http://www.voxbo.org/
24
// original version written by Tom King?
26
#include "covariates.h"
27
#include <qmessagebox.h>
33
/*---------------------------------------------------------------------------*/
37
Covariate::Covariate(QObject * parent, const char * name)
38
: QObject(parent, name)
42
Covariate::Covariate(const Covariate& aCov)
43
: mName(aCov.mName), mInterest(aCov.mInterest)
47
Covariate::InterestType Covariate::str2type(const std::string& str)
49
// Looks at the first character in str and returns the appropriate type.
51
char interest = str[0];
54
case 'I': return Covariate::INTEREST_I;
55
case 'N': return Covariate::INTEREST_N;
56
case 'K': return Covariate::INTEREST_K;
57
case 'U': return Covariate::INTEREST_U;
58
case 'D': return Covariate::INTEREST_D;
59
default: return Covariate::INTEREST_ERR;
63
std::string Covariate::type2str(Covariate::InterestType inter)
65
// Looks at the first character in str and returns the appropriate type.
69
case Covariate::INTEREST_I: return "I";
70
case Covariate::INTEREST_N: return "N";
71
case Covariate::INTEREST_K: return "K";
72
case Covariate::INTEREST_U: return "U";
73
case Covariate::INTEREST_D: return "D";
74
default: return "error";
78
void Covariate::setName(const std::string& aName)
81
emit nameChanged(aName);
84
void Covariate::setType(Covariate::InterestType aType)
87
emit typeChanged(aType);
90
const std::string& Covariate::getName() const
95
const Covariate::InterestType& Covariate::getType() const
100
Covariate& Covariate::operator=(const Covariate& aCov)
103
mInterest = aCov.mInterest;
107
/*---------------------------------------------------------------------------*/
111
Contrast::Contrast(std::vector<Covariate>& aCovList,
112
QObject * parent, const char * name)
113
: QObject(parent, name), Covariates(aCovList)
117
Contrast::Parameter& Contrast::operator[](int aIndex)
119
return Weights[aIndex];
122
Contrast::Parameter& Contrast::operator[](std::string aCovName)
125
for (vector<Covariate>::iterator iter = Covariates.begin();
126
iter != Covariates.end();
129
if (iter->getName() == aCovName) break;
133
// i'm not doing bounds checking. maybe VoxBo should start throwing around
134
// exceptions. i've always liked the idea of exceptions.
135
return Weights[index];
138
/********************************************************************************
139
* VB::CovatiatesView class
140
********************************************************************************/
142
const char* CovariatesView::NAME_COL = "Name";
143
const char* CovariatesView::ID_COL = "ID";
144
const char* CovariatesView::TYPE_COL = "Type";
146
CovariatesView::CovariatesView(QWidget *parent, const char *name)
147
: Q3ListView(parent,name)
149
setSelectionMode(Q3ListView::Extended);
150
setRootIsDecorated(true);
153
connect( this, SIGNAL( selectionChanged( ) ),
154
this, SLOT( onSelectionChanged( ) ) );
157
void CovariatesView::setupColumns()
161
setColumnAlignment(1, Qt::AlignHCenter);
163
setColumnAlignment(2, Qt::AlignHCenter);
167
void CovariatesView::buildTree(GLMInfo* aGLMInfo, bool aShowAll)
169
std::vector<std::string> names;
170
std::vector<std::string> types;
172
// Prepare and build the parameter tree
173
std::vector<std::string>::iterator name_iter;
174
for (name_iter = aGLMInfo->cnames.begin();
175
name_iter != aGLMInfo->cnames.end();
178
names.push_back(name_iter->substr(1));
179
types.push_back(name_iter->substr(0,1));
181
buildTree(names, types, aShowAll);
184
void CovariatesView::buildTree(std::vector<VB::Covariate>& aCovList, bool aShowAll)
186
vector<string> name_list;
187
vector<string> type_list;
192
// Copy the covariate information into the name and interest type lists.
193
vector<Covariate>::iterator cov_iter;
194
for (cov_iter = aCovList.begin();
195
cov_iter != aCovList.end();
198
name = cov_iter->getName();
199
interest = Covariate::type2str(cov_iter->getType());
201
name_list.push_back(name);
202
type_list.push_back(interest);
204
buildTree(name_list, type_list, aShowAll);
207
void CovariatesView::buildTree(vector<string>& aNameList,
208
vector<string>& aTypeList, bool aShowAll)
212
QString nameStr, sectionStr, typeStr;
214
for (unsigned i = 0; i < aNameList.size(); i++) {
216
// Get the root of this ListView.
217
// cerr << "finding the root of the listview...\n";
218
Q3ListViewItem *parent = firstChild();
219
// cerr << "first child is at "<< parent << ".\n";
221
// Get the name for the item...
222
nameStr = QString(aNameList[i].c_str());
223
// cerr << "name for this item: " << nameStr << endl;
224
// And get it's type.
225
typeStr = QString(aTypeList[i].c_str());
226
// cerr << "type for this item: " << typeStr << endl;
227
// Parse the hierarchy for this item from the name.
228
QStringList qList = QStringList::split("->", nameStr);
229
// cerr << "...parsed the hierarchy for this file.\n";
231
// Iterate through the hierarchy list...
232
// cerr << "iterating through the hierarchy...\n";
233
for (int32 j = 0; j < qList.size(); j++) {
234
sectionStr = *qList.at(j);
235
// Covariate is a direct child of the root
236
if (qList.size() == 1) {
237
(void) new Q3ListViewItem(this, lastChild(), sectionStr, typeStr, QString::number(i));
240
// Covariate belongs to a certain group
241
else if (j == qList.size() - 1) {
242
(void) new Q3ListViewItem(parent, lastChild(parent), sectionStr, typeStr, QString::number(i));
245
// Create the covariate's first layer group item (if not available)
247
parent = findGroup(sectionStr);
249
parent = new Q3ListViewItem(this, lastChild(), sectionStr);
250
parent->setOpen(true);
253
// Create group items after the first layer
255
// ::FIXED:: have to make a copy of the parent in this case so that,
256
// in case the subgroup does not yet exist, we still know
257
// the address of the parent and we can create it.
259
Q3ListViewItem* sub_parent = findGroup(parent, sectionStr);
261
sub_parent = new Q3ListViewItem(parent, lastChild(parent), sectionStr);
262
sub_parent->setOpen(true);
272
// cerr << "done!\n";
275
/* cpView() copies input QListView and add it on the main interface */
276
void CovariatesView::copyTree(const CovariatesView* aCovView, bool aShowAll)
280
// Copy the input tree, select 1st selectable covariate and set baseIndex
281
Q3ListViewItemIterator it(const_cast<CovariatesView*> (aCovView));
282
while (it.current()) {
284
// Copy the current item
285
Q3ListViewItem *newItem;
286
Q3ListViewItem *inputItem = it.current();
288
if (inputItem->text(2).isEmpty()) {
289
if (!inputItem->childCount())
291
if (inputItem->depth() == 0)
292
newItem = new Q3ListViewItem(this, lastChild(), inputItem->text(0));
294
newItem = new Q3ListViewItem(findParent(inputItem), lastChild(findParent(inputItem)),
296
newItem->setOpen(true);
297
newItem->setEnabled(false);
301
if (inputItem->depth() == 0)
302
newItem = new Q3ListViewItem(this, lastChild(), inputItem->text(0),
303
inputItem->text(1), inputItem->text(2));
305
newItem = new Q3ListViewItem(findParent(inputItem), lastChild(findParent(inputItem)),
306
inputItem->text(0), inputItem->text(1), inputItem->text(2));
307
// By default, only enable type I covariates
308
if (newItem->text(1) != "I")
309
newItem->setEnabled(false);
314
Q3ListViewItemIterator all(this, Q3ListViewItemIterator::Selectable);
320
/* lastChild(...) gets the last 1st-gen child of parent, or of the View if
322
Q3ListViewItem* CovariatesView::lastChild(const Q3ListViewItem* parent) const
324
Q3ListViewItem *last_child, *temp_child;
327
temp_child = firstChild(parent);
329
temp_child = firstChild();
333
temp_child = temp_child->nextSibling())
334
last_child = temp_child;
336
// cerr << "done looking at the last child" << endl;
340
/* firstChild(...) gets the first 1st-gen child of parent, or of the View if
342
Q3ListViewItem* CovariatesView::firstChild(const Q3ListViewItem* parent) const
344
Q3ListViewItem* first_child;
346
// cerr << " parent is at " << parent << ".\n";
348
first_child = parent->firstChild();
350
first_child = Q3ListView::firstChild();
352
// cerr << "done looking at the first child" << endl;
356
/* findChild(...) finds the first item in column that matches text and is a
357
* direct descendant of parent (or is at depth 0 if parent is NULL). */
358
Q3ListViewItem* CovariatesView::findChild(const Q3ListViewItem* parent,
359
const QString& text, int column) const
361
Q3ListViewItem* found_item;
363
for (found_item = firstChild(parent);
365
found_item = found_item->nextSibling())
367
if (found_item->text(column) == text)
374
Q3ListViewItem* CovariatesView::findChild(const QString& text, int column) const
376
return findChild(0, text, column);
379
/* findGroup(...) finds the first item in column that matches text and is a
380
* direct descendant of parent (or is at depth 0 if parent is NULL). */
381
Q3ListViewItem* CovariatesView::findGroup(const Q3ListViewItem* parent,
382
const QString& text) const
384
Q3ListViewItem* found_item;
386
for (found_item = firstChild(parent);
388
found_item = found_item->nextSibling())
390
if (found_item->text(0) == text && found_item->text(2).isEmpty())
397
/* findGroup(...) finds the first item in column that matches text and is a
398
* direct descendant of parent (or is at depth 0 if parent is NULL). */
399
Q3ListViewItem* CovariatesView::findGroup(const QString& text) const
401
return findGroup(0, text);
404
/* Modified based on gdw's same function */
405
Q3ListViewItem * CovariatesView::findParent(Q3ListViewItem *inputItem) const
407
int lastDepth = lastItem()->depth();
408
int inputDepth = inputItem->depth();
409
if (lastDepth < inputDepth)
412
Q3ListViewItem *newParent = lastItem()->parent();
413
while (newParent->depth() > inputDepth - 1)
414
newParent = newParent->parent();
418
void CovariatesView::showInterestOnly(bool aInterestOnly)
420
Q3ListViewItemIterator it(this);
423
Q3ListViewItem* item = it.current();
424
if (item->text(columnNumber(ID_COL)) != "")
426
if (aInterestOnly && item->text(columnNumber(TYPE_COL)) != "I")
427
item->setVisible(false);
429
item->setVisible(true);
435
int CovariatesView::columnNumber(const QString& text)
437
for (int i = 0; i < columns(); ++i)
438
if (text == columnText(i)) return i;
443
void CovariatesView::setColumnText(int column, const QStringList& textList)
445
int id_col = columnNumber(ID_COL);
447
Q3ListViewItemIterator it( this );
448
QStringList::ConstIterator string_it = textList.begin();
449
while ( it.current() && string_it != textList.end() )
451
Q3ListViewItem *item = it.current();
452
if (!item->text(id_col).isEmpty())
454
item->setText(column, *string_it);
461
void CovariatesView::setColumnText(int column, const QString& text)
463
int id_col = columnNumber(ID_COL);
465
Q3ListViewItemIterator it(this);
468
Q3ListViewItem *item = it.current();
469
if (!item->text(id_col).isEmpty())
470
item->setText(column, text);
475
void CovariatesView::setColumnText(const QString& column, const QStringList& textList)
477
setColumnText(columnNumber(column), textList);
480
void CovariatesView::setColumnText(const QString& column, const QString& text)
482
setColumnText(columnNumber(column), text);
485
void CovariatesView::setSelectedColumnText(int column, const QString& text)
487
int id_col = columnNumber(ID_COL);
488
list<Q3ListViewItem*>::iterator iter;
490
for (iter = mSelection.begin();
491
iter != mSelection.end();
494
if (!(*iter)->text(id_col).isEmpty())
495
(*iter)->setText(column, text);
499
void CovariatesView::setSelectedColumnText(const QString& column, const QString& text)
501
setSelectedColumnText(columnNumber(column), text);
504
int CovariatesView::itemIndex(const Q3ListViewItem* item)
508
Q3ListViewItemIterator it(this);
511
if (it.current() == item)
519
list<Q3ListViewItem*>& CovariatesView::selectedItems()
524
list<int>& CovariatesView::selectedItemIDs()
526
return mSelectionIDs;
529
void CovariatesView::onSelectionChanged()
532
mSelectionIDs.clear();
534
int id_col = columnNumber(ID_COL);
536
Q3ListViewItemIterator it(this);
539
Q3ListViewItem* item = it.current();
540
if (isSelected(item))
542
mSelection.push_back(item);
543
if (!item->text(id_col).isEmpty())
544
mSelectionIDs.push_back(item->text(id_col).toInt());
550
void CovariatesView::clear()
554
mSelectionIDs.clear();
555
return Q3ListView::clear();
558
/********************************************************************************
559
* VB::ContrastsView class
560
********************************************************************************/
562
ContrastsView::ContrastsView(QWidget *parent, const char *name)
563
: Q3ListView(parent, name)
565
setSelectionMode(Q3ListView::Single);
566
setRootIsDecorated(false);
568
addColumn("Scale Type");
572
connect( this, SIGNAL( selectionChanged() ),
573
this, SLOT( onSelectionChanged() ) );
575
connect( this, SIGNAL( itemRenamed(Q3ListViewItem *,int,const QString &) ),
576
this, SLOT( onContrastRenamed(Q3ListViewItem *,int,const QString &) ) );
579
void ContrastsView::buildList(GLMInfo* aGLMInfo)
581
vector<VBContrast*> contrast_list;
584
vector<VBContrast>::iterator cont_iter;
585
for (cont_iter = aGLMInfo->contrasts.begin();
586
cont_iter != aGLMInfo->contrasts.end();
589
contrast_list.push_back(new VBContrast(*cont_iter));
591
buildList(contrast_list);
594
void ContrastsView::buildList(std::vector<Contrast>& aContList)
596
vector<VBContrast*> contrast_list;
599
// Copy the contrast information into the name, scale, and weight lists.
600
vector<Contrast>::iterator cont_iter;
601
for (cont_iter = aContList.begin();
602
cont_iter != aContList.end();
605
contrast.name = cont_iter->Name;
606
//contrast.scale = Contrast::scale2str(cont_iter->Scale);
607
contrast.contrast = Vec(cont_iter->Weights);
609
contrast_list.push_back(new VBContrast(contrast));
611
buildList(contrast_list);
614
void ContrastsView::buildList(vector<string> aNameList,
615
vector<string> aScaleList,
616
vector<VB_Vector> aWeightList)
618
vector<VBContrast*> contrast_list;
621
int len = aNameList.size(); // should i check that they're all the same size?
622
for (int i = 0; i < len; ++i)
624
contrast.name = aNameList[i];
625
contrast.scale = aScaleList[i];
626
contrast.contrast = Vec(aWeightList[i]);
628
contrast_list.push_back(new VBContrast(contrast));
630
buildList(contrast_list);
633
void ContrastsView::buildList(vector<VBContrast*>& aContrastList)
635
mContrasts = aContrastList;
640
vector<VBContrast*>::iterator cont_iter;
641
for (cont_iter = aContrastList.begin();
642
cont_iter != aContrastList.end();
645
Q3ListViewItem* temp_item = new Q3ListViewItem(this, lastItem(), QString((*cont_iter)->name.c_str()), QString((*cont_iter)->scale.c_str()));
646
temp_item->setRenameEnabled(0,true);
647
// cerr << "Contrast: " << (*cont_iter)->name.c_str() << endl;
649
// cerr << "Contrast list has been populated." << endl;
652
void ContrastsView::insertContrast(VBContrast* aContrast)
654
mContrasts.push_back(aContrast);
655
Q3ListViewItem* temp_item = new Q3ListViewItem(this, lastItem(), aContrast->name.c_str(), aContrast->scale.c_str());
656
temp_item->setRenameEnabled(0,true);
659
void ContrastsView::takeContrast(VBContrast* aContrast)
661
Q3ListViewItemIterator list_iter(this);
662
vector<VBContrast*>::iterator iter;
664
for (iter = mContrasts.begin(); iter != mContrasts.end(); ++iter)
666
if (*iter == aContrast) break;
669
mContrasts.erase(iter);
670
takeItem(*list_iter);
673
int ContrastsView::itemIndex(const Q3ListViewItem* item)
677
Q3ListViewItemIterator it(this);
680
if (it.current() == item)
688
VBContrast* ContrastsView::selectedContrast() const
690
return mCurrentContrast;
693
void ContrastsView::onSelectionChanged()
695
Q3ListViewItem* item = selectedItem();
696
mCurrentContrast = contrastAt(item);
699
VBContrast* ContrastsView::contrastAt(const Q3ListViewItem* item, bool diag)
701
VBContrast* contrast;
705
if (diag) cerr << "No contrast is selected." << endl;
709
int index = itemIndex(item);
710
contrast = mContrasts[index];
711
if (diag) cerr << "Contrast selected: " << contrast->name << endl <<
712
" " << contrast->contrast << endl;
718
void ContrastsView::onContrastRenamed(Q3ListViewItem * item, int /* col */, const QString & text)
720
VBContrast* contrast = contrastAt(item);
721
contrast->name = text.ascii();
724
/********************************************************************************
725
* VB::ContParamsView class
726
********************************************************************************/
728
const char* ContParamsView::WEIGHT_COL = "Weight";
730
ContParamsView::ContParamsView(QWidget *parent, const char *name)
731
: CovariatesView(parent, name)
733
addColumn(WEIGHT_COL);
734
setColumnWidthMode(columnNumber(ID_COL), Q3ListView::Manual);
735
header()->setResizeEnabled(FALSE, columnNumber(ID_COL));
736
hideColumn(columnNumber(ID_COL));
739
void ContParamsView::buildTree(GLMInfo* aGLMInfo, bool aShowAll)
743
CovariatesView::buildTree(aGLMInfo, aShowAll);
745
void ContParamsView::buildTree(std::vector<Covariate>& aCovList, bool aShowAll)
749
CovariatesView::buildTree(aCovList, aShowAll);
752
void ContParamsView::buildTree(std::vector<std::string>& aNameList,
753
std::vector<std::string>& aTypeList, bool aShowAll)
757
CovariatesView::buildTree(aNameList, aTypeList, aShowAll);
760
void ContParamsView::setContrast(const VBContrast& aContrast)
763
setContrast(aContrast.contrast);
766
void ContParamsView::setContrast(const VB_Vector& aContrast)
768
QStringList str_list;
769
for (int i = 0; i < aContrast.size(); ++i)
770
str_list += QString::number(double(aContrast[i]), 'f', 2);
772
setColumnText(WEIGHT_COL, str_list);
775
void ContParamsView::clearContrast()
777
setColumnText(WEIGHT_COL, QString(""));