Skip to content

Commit c78f80f

Browse files
authored
Merge pull request #2170 from SCIInstitute/exclude_mode
Add exclude capability
2 parents 9721a15 + d33fa76 commit c78f80f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1316
-290
lines changed

Libs/Analyze/Particles.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,9 @@ void Particles::save_particles_file(std::string filename, const Eigen::VectorXd&
248248
out.close();
249249
}
250250

251+
//---------------------------------------------------------------------------
252+
int Particles::get_number_of_domains() { return local_particles_.size(); }
253+
251254
//---------------------------------------------------------------------------
252255
void Particles::set_alignment_type(int alignment) { alignment_type_ = alignment; }
253256

Libs/Analyze/Particles.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class Particles {
5454

5555
static void save_particles_file(std::string filename, const Eigen::VectorXd& points);
5656

57+
int get_number_of_domains();
5758

5859
private:
5960
void transform_global_particles();

Libs/Analyze/Shape.cpp

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,7 @@ void Shape::set_subject(std::shared_ptr<Subject> subject) {
7171
groomed_meshes_.set_number_of_meshes(subject->get_number_of_domains());
7272
reconstructed_meshes_.set_number_of_meshes(subject->get_number_of_domains());
7373

74-
if (!subject_->get_original_filenames().empty()) {
75-
/// TODO: Show multiple lines of filenames for multiple domains?
76-
std::string filename = subject_->get_original_filenames()[0];
77-
corner_annotations_[0] = StringUtils::getFilename(filename);
78-
}
79-
80-
if (subject->get_display_name() != "") {
81-
corner_annotations_[0] = subject->get_display_name();
82-
}
74+
update_annotations();
8375
}
8476

8577
//---------------------------------------------------------------------------
@@ -88,6 +80,12 @@ bool Shape::is_subject() { return subject_ != nullptr; }
8880
//---------------------------------------------------------------------------
8981
std::shared_ptr<Subject> Shape::get_subject() { return subject_; }
9082

83+
//---------------------------------------------------------------------------
84+
bool Shape::is_fixed() { return is_subject() && subject_->is_fixed(); }
85+
86+
//---------------------------------------------------------------------------
87+
bool Shape::is_excluded() { return is_subject() && subject_->is_excluded(); }
88+
9189
//---------------------------------------------------------------------------
9290
void Shape::import_original_file(const std::string& filename) {
9391
subject_->set_original_filenames({filename});
@@ -320,10 +318,26 @@ int Shape::get_id() { return id_; }
320318
void Shape::set_id(int id) { id_ = id; }
321319

322320
//---------------------------------------------------------------------------
323-
void Shape::update_name() {
321+
void Shape::update_annotations() {
322+
if (!subject_->get_original_filenames().empty()) {
323+
/// TODO: Show multiple lines of filenames for multiple domains?
324+
std::string filename = subject_->get_original_filenames()[0];
325+
corner_annotations_[0] = StringUtils::getFilename(filename);
326+
}
327+
324328
if (subject_->get_display_name() != "") {
325329
corner_annotations_[0] = subject_->get_display_name();
326330
}
331+
332+
std::vector<std::string> corner2_items;
333+
if (subject_->is_fixed()) {
334+
corner2_items.push_back("Fixed");
335+
}
336+
if (subject_->is_excluded()) {
337+
corner2_items.push_back("Excluded");
338+
}
339+
340+
corner_annotations_[2] = StringUtils::join(corner2_items, ", ");
327341
}
328342

329343
//---------------------------------------------------------------------------

Libs/Analyze/Shape.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ class Shape {
5656
//! Return the pointer to the subject object
5757
std::shared_ptr<shapeworks::Subject> get_subject();
5858

59+
//! Helper to ask if this shape is fixed or not
60+
bool is_fixed();
61+
62+
/// Helper to ask if this shape is excluded
63+
bool is_excluded();
64+
5965
//! Import the original raw mesh or image file
6066
void import_original_file(const std::string& filename);
6167

@@ -119,7 +125,7 @@ class Shape {
119125
void set_id(int id);
120126

121127
//! Update the name of this shape
122-
void update_name();
128+
void update_annotations();
123129

124130
std::vector<std::string> get_original_filenames();
125131
std::vector<std::string> get_original_filenames_with_path();
@@ -201,7 +207,7 @@ class Shape {
201207
std::map<std::string, Eigen::VectorXd> point_features_;
202208
Particles particles_;
203209

204-
std::shared_ptr<shapeworks::Subject> subject_;
210+
std::shared_ptr<Subject> subject_;
205211

206212
vtkSmartPointer<vtkTransform> transform_ = vtkSmartPointer<vtkTransform>::New();
207213

Libs/Common/Logging.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ namespace spd = spdlog;
1010
namespace shapeworks {
1111

1212
//-----------------------------------------------------------------------------
13-
static std::string create_header(const int line, const char* filename) {
13+
static std::string create_header(const int line, const char* filename, const char* function = "") {
1414
const char* name = (strrchr(filename, '/') ? strrchr(filename, '/') + 1 : filename);
1515
const char* name2 = (strrchr(name, '\\') ? strrchr(name, '\\') + 1 : name);
16-
std::string header = "[" + std::string(name2) + "|" + std::to_string(line) + "]";
17-
return header;
16+
const char* function_name = (strrchr(function, ':') ? strrchr(function, ':') + 1 : function);
17+
if (!function) {
18+
std::string header = "[" + std::string(name2) + "|" + std::to_string(line) + "]";
19+
return header;
20+
} else {
21+
std::string header = "[" + std::string(name2) + "|" + std::string(function_name) + "|" + std::to_string(line) + "]";
22+
return header;
23+
}
1824
}
1925

2026
//-----------------------------------------------------------------------------
@@ -98,8 +104,8 @@ void Logging::show_status(const std::string& message, const int line, const char
98104
}
99105

100106
//-----------------------------------------------------------------------------
101-
void Logging::log_debug(const std::string& message, const int line, const char* file) const {
102-
std::string str = create_header(line, file) + " " + message;
107+
void Logging::log_debug(const std::string& message, const int line, const char* file, const char* function) const {
108+
std::string str = create_header(line, file, function) + " " + message;
103109
spd::debug(str);
104110
if (log_open_) {
105111
spd::get("file")->debug(str);
@@ -155,6 +161,8 @@ void Logging::set_debug_callback(const std::function<void(std::string)>& callbac
155161
void Logging::set_status_callback(const std::function<void(std::string)>& callback) { status_callback_ = callback; }
156162

157163
//-----------------------------------------------------------------------------
158-
void Logging::set_progress_callback(const std::function<void(double, std::string)>& callback) { progress_callback_ = callback; }
164+
void Logging::set_progress_callback(const std::function<void(double, std::string)>& callback) {
165+
progress_callback_ = callback;
166+
}
159167

160168
} // namespace shapeworks

Libs/Common/Logging.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class Logging {
105105
void show_progress(double value, const std::string& message);
106106

107107
//! Log a debug message, use SW_DEBUG macro
108-
void log_debug(const std::string& message, const int line, const char* file) const;
108+
void log_debug(const std::string& message, const int line, const char* file, const char *function) const;
109109

110110
//! Log a warning message, use SW_WARN macro
111111
void log_warning(const std::string& message, const int line, const char* file) const;
@@ -168,7 +168,7 @@ class Logging {
168168

169169
//! Log debug macro
170170
#define SW_DEBUG(message, ...) \
171-
shapeworks::Logging::Instance().log_debug(fmt::format(message, ##__VA_ARGS__), __LINE__, __FILE__)
171+
shapeworks::Logging::Instance().log_debug(fmt::format(message, ##__VA_ARGS__), __LINE__, __FILE__, __FUNCTION__)
172172

173173
//! Variable trace macro (e.g. output variable name = <variable value>)
174174
#define SW_TRACE(x) SW_DEBUG(#x " = {}", x);

Libs/Groom/Groom.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ bool Groom::run() {
5252
continue;
5353
}
5454

55+
if (subjects[i]->is_excluded()) {
56+
// clear groomed filenames
57+
subjects[i]->set_groomed_filenames(std::vector<std::string>());
58+
return;
59+
}
60+
5561
bool is_image = project_->get_original_domain_types()[domain] == DomainType::Image;
5662
bool is_mesh = project_->get_original_domain_types()[domain] == DomainType::Mesh;
5763
bool is_contour = project_->get_original_domain_types()[domain] == DomainType::Contour;
@@ -511,9 +517,11 @@ bool Groom::run_alignment() {
511517
vtkSmartPointer<vtkTransform> transform = ProjectUtils::convert_transform(list);
512518
mesh.applyTransform(transform);
513519

520+
// if fixed subjects are present, only add the fixed subjects
514521
if (subjects[i]->is_fixed() || !project_->get_fixed_subjects_present()) {
515-
// if fixed subjects are present, only add the fixed subjects
516-
reference_meshes.push_back(mesh);
522+
if (!subjects[i]->is_excluded()) {
523+
reference_meshes.push_back(mesh);
524+
}
517525
}
518526
meshes.push_back(mesh);
519527
}
@@ -550,8 +558,11 @@ bool Groom::run_alignment() {
550558
auto list = subjects[i]->get_groomed_transforms()[0];
551559
vtkSmartPointer<vtkTransform> transform = ProjectUtils::convert_transform(list);
552560
mesh.applyTransform(transform);
561+
// if fixed subjects are present, only add the fixed subjects
553562
if (subjects[i]->is_fixed() || !project_->get_fixed_subjects_present()) {
554-
meshes.push_back(mesh);
563+
if (!subjects[i]->is_excluded()) {
564+
meshes.push_back(mesh);
565+
}
555566
}
556567
}
557568

@@ -590,6 +601,9 @@ void Groom::assign_transforms(std::vector<std::vector<double>> transforms, int d
590601
auto subjects = project_->get_subjects();
591602

592603
for (size_t i = 0; i < subjects.size(); i++) {
604+
if (subjects[i]->is_excluded()) {
605+
continue;
606+
}
593607
auto subject = subjects[i];
594608

595609
int base_domain = domain;

Libs/Optimize/Domain/ImageDomain.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class ImageDomain : public ParticleRegionDomain {
137137
} else {
138138
std::ostringstream message;
139139
message << "Domain " << m_DomainID << ": " << m_DomainName << " : Distance transform queried for a Point, " << p
140-
<< ", outside the given image domain. Consider increasing the narrow band";
140+
<< ", outside the given image domain. Consider increasing the padding in grooming or the narrow band optimization parameter";
141141
throw std::runtime_error(message.str());
142142
}
143143
}

Libs/Optimize/Matrix/LegacyShapeMatrix.h

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ class LegacyShapeMatrix : public vnl_matrix<double>, public Observer {
3232
/** Method for creation through the object factory. */
3333
itkNewMacro(Self)
3434

35-
/** Run-time type information (and related methods). */
36-
itkTypeMacro(LegacyShapeMatrix, Observer)
37-
38-
/** Callbacks that may be defined by a subclass. If a subclass defines one
39-
of these callback methods, the corresponding flag in m_DefinedCallbacks
40-
should be set to true so that the ParticleSystem will know to register
41-
the appropriate event with this method. */
42-
virtual void DomainAddEventCallback(Object*, const itk::EventObject& e) {
35+
/** Run-time type information (and related methods). */
36+
itkTypeMacro(LegacyShapeMatrix, Observer)
37+
38+
/** Callbacks that may be defined by a subclass. If a subclass defines one
39+
of these callback methods, the corresponding flag in m_DefinedCallbacks
40+
should be set to true so that the ParticleSystem will know to register
41+
the appropriate event with this method. */
42+
virtual void DomainAddEventCallback(Object*, const itk::EventObject& e) {
4343
const ParticleDomainAddEvent& event = dynamic_cast<const ParticleDomainAddEvent&>(e);
4444
unsigned int d = event.GetDomainIndex();
4545

@@ -67,16 +67,28 @@ class LegacyShapeMatrix : public vnl_matrix<double>, public Observer {
6767
const typename ParticleSystem::PointType pos = ps->GetTransformedPosition(idx, d);
6868

6969
int numRows = 0;
70-
for (int i = 0; i < m_DomainsPerShape; i++) numRows += VDimension * ps->GetNumberOfParticles(i);
70+
for (int i = 0; i < m_DomainsPerShape; i++) {
71+
numRows += VDimension * ps->GetNumberOfParticles(i);
72+
}
7173

72-
if (numRows > this->rows()) this->ResizeMatrix(numRows, this->cols());
74+
if (numRows > this->rows()) {
75+
this->ResizeMatrix(numRows, this->cols());
76+
}
7377

7478
unsigned int k = 0;
7579
int dom = d % m_DomainsPerShape;
76-
for (int i = 0; i < dom; i++) k += VDimension * ps->GetNumberOfParticles(i);
80+
for (int i = 0; i < dom; i++) {
81+
k += VDimension * ps->GetNumberOfParticles(i);
82+
}
7783
k += idx * VDimension;
7884

79-
for (unsigned int i = 0; i < VDimension; i++) this->operator()(i + k, d / m_DomainsPerShape) = pos[i];
85+
for (unsigned int i = 0; i < VDimension; i++) {
86+
if (i + k >= this->rows()) {
87+
throw std::runtime_error(
88+
"PositionSetEventCallback: index out of bounds! Different number of particles per shape?");
89+
}
90+
this->operator()(i + k, d / m_DomainsPerShape) = pos[i];
91+
}
8092
}
8193

8294
virtual void PositionSetEventCallback(Object* o, const itk::EventObject& e) {
@@ -89,10 +101,18 @@ class LegacyShapeMatrix : public vnl_matrix<double>, public Observer {
89101

90102
unsigned int k = 0;
91103
int dom = d % m_DomainsPerShape;
92-
for (int i = 0; i < dom; i++) k += VDimension * ps->GetNumberOfParticles(i);
104+
for (int i = 0; i < dom; i++) {
105+
k += VDimension * ps->GetNumberOfParticles(i);
106+
}
93107
k += idx * VDimension;
94108

95-
for (unsigned int i = 0; i < VDimension; i++) this->operator()(i + k, d / m_DomainsPerShape) = pos[i];
109+
for (unsigned int i = 0; i < VDimension; i++) {
110+
if (i + k >= this->rows()) {
111+
throw std::runtime_error(
112+
"PositionSetEventCallback: index out of bounds! Different number of particles per shape?");
113+
}
114+
this->operator()(i + k, d / m_DomainsPerShape) = pos[i];
115+
}
96116
}
97117

98118
virtual void PositionRemoveEventCallback(Object*, const itk::EventObject&) {

Libs/Optimize/OptimizeParameters.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ std::vector<std::vector<itk::Point<double>>> OptimizeParameters::get_initial_poi
297297
for (auto s : subjects) {
298298
if (s->is_fixed()) {
299299
count++;
300-
// read the local points
301-
auto filename = s->get_local_particle_filenames()[d];
300+
// read the world points that are in the shared coordinate space
301+
auto filename = s->get_world_particle_filenames()[d];
302302
auto particles = read_particles_as_vector(filename);
303303
if (domain_sum.size() == 0) {
304304
domain_sum = particles;
@@ -531,13 +531,19 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) {
531531
}
532532

533533
optimize->SetFixedDomains(fixed_domains);
534-
optimize->SetInitialPoints(get_initial_points());
534+
if (!get_use_landmarks()) { // can't use both initial points and landmarks
535+
SW_DEBUG("Setting Initial Points");
536+
optimize->SetInitialPoints(get_initial_points());
537+
}
535538
}
536539

537540
for (auto s : subjects) {
538541
if (abort_load_) {
539542
return false;
540543
}
544+
if (s->is_excluded()) {
545+
continue;
546+
}
541547
auto files = s->get_groomed_filenames();
542548
if (files.empty()) {
543549
throw std::invalid_argument("No groomed inputs for optimization");
@@ -552,6 +558,7 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) {
552558
point_files.insert(std::end(point_files), std::begin(landmarks), std::end(landmarks));
553559
}
554560
if (!point_files.empty()) {
561+
SW_DEBUG("Setting Initial Points as landmarks");
555562
optimize->SetPointFiles(point_files);
556563
}
557564
}
@@ -619,6 +626,11 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) {
619626
if (abort_load_) {
620627
return false;
621628
}
629+
630+
if (s->is_excluded()) {
631+
continue;
632+
}
633+
622634
auto files = s->get_groomed_filenames();
623635
if (files.empty()) {
624636
throw std::invalid_argument("No groomed inputs for optimization");
@@ -681,9 +693,9 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) {
681693
} else {
682694
Image image(filename);
683695
if (s->is_fixed()) {
684-
optimize->AddImage(nullptr);
696+
optimize->AddImage(nullptr, filename);
685697
} else {
686-
optimize->AddImage(image);
698+
optimize->AddImage(image, filename);
687699
}
688700
}
689701

0 commit comments

Comments
 (0)