Esempio n. 1
0
//
// Determine if 2 sets contain the same elements.
//
bool DataFlowUtil::setEquals(const Assignments& a, const Assignments& b) {
  // make sure sets are the same length
  if (a.size() != b.size()) {
    return false;
  }

  // ensure they contain the same elements
  for (Assignments::const_iterator i = a.begin(); i != a.end(); ++i) {
    const Assignment& test = *i;
    if (b.count(test) < 1) {
      return false;
    }
  }
  return true;
}
Esempio n. 2
0
Assignments get_state_clusters(const Subset &subset, const Assignments &states,
                               ParticleStatesTable *pst, double resolution) {
  Vector<Ints> rotated(subset.size(), Ints(states.size(), -1));
  for (unsigned int i = 0; i < states.size(); ++i) {
    for (unsigned int j = 0; j < states[i].size(); ++j) {
      rotated[j][i] = states[i][j];
    }
  }
  for (unsigned int i = 0; i < rotated.size(); ++i) {
    std::sort(rotated[i].begin(), rotated[i].end());
    rotated[i].erase(std::unique(rotated[i].begin(), rotated[i].end()),
                     rotated[i].end());
  }
  Vector<Ints> clustering(states.size());
  for (unsigned int i = 0; i < subset.size(); ++i) {
    IMP::PointerMember<ParticleStates> ps =
        pst->get_particle_states(subset[i]);
    Ints c = get_state_clusters(subset[i], ps, rotated[i], resolution);
    clustering[i] = c;
  }

  return filter_states(subset, states, clustering);
}
Paths CorrespondenceGenerator::generate()
{
	Paths result;

	auto boxA = a->bbox(), boxB = b->bbox();

	QStringList nodesA, nodesB;
	for (auto n : a->nodes) nodesA << n->id;
	for (auto n : b->nodes) nodesB << n->id;
	for (auto g : a->groups) for (auto nid : g) nodesA.removeAll(nid);
	for (auto g : b->groups) for (auto nid : g) nodesB.removeAll(nid);
	Structure::NodeGroups tmpA, tmpB;
	for (auto nid : nodesA) tmpA.push_back( QVector<QString>() << nid );
	for (auto nid : nodesB) tmpB.push_back( QVector<QString>() << nid );
	for (auto g : a->groups) tmpA.push_back(g);
	for (auto g : b->groups) tmpB.push_back(g);
	a->groups = tmpA;
	b->groups = tmpB;

	/// Build similarity matrix of groups:
	Eigen::MatrixXd similiarity = Eigen::MatrixXd::Ones(a->groups.size(), b->groups.size() + 1);

	for (size_t i = 0; i < similiarity.rows(); i++){
		double minVal = DBL_MAX;
		for (size_t j = 0; j < similiarity.cols(); j++){
			double val = 0;

			if (j < b->groups.size())
			{
				Eigen::AlignedBox3d groupBoxA, groupBoxB;
				for (auto sid : a->groups[i]) groupBoxA.extend(a->getNode(sid)->bbox(1.01));
				for (auto sid : b->groups[j]) groupBoxB.extend(b->getNode(sid)->bbox(1.01));

				Vector3 relativeCenterA = (groupBoxA.center() - boxA.min()).array() / boxA.sizes().array();
				Vector3 relativeCenterB = (groupBoxB.center() - boxB.min()).array() / boxB.sizes().array();

				val = (relativeCenterA - relativeCenterB).norm();

				minVal = std::min(minVal, val);
			}

			similiarity(i, j) = val;
		}
		double maxVal = similiarity.row(i).maxCoeff();
		if (maxVal == 0) maxVal = 1.0;

		for (size_t j = 0; j < b->groups.size(); j++)
			similiarity(i, j) = (similiarity(i, j) - minVal) / maxVal;
	}

	std::vector< std::vector<float> > data;
	for (int i = 0; i < similiarity.rows(); i++){
		std::vector<float> dataRow;
		for (int j = 0; j < similiarity.cols(); j++)
			dataRow.push_back(similiarity(i, j));
		data.push_back(dataRow);
	}
	//if (false) showTableColorMap(data, true); // DEBUG

	// Parameters:
	double similarity_threshold = 0.4;

	if (similiarity.rows() < 4) similarity_threshold = 1.0;

	// Collect good candidates
	Assignments candidates;
	for (size_t i = 0; i < similiarity.rows(); i++){
		QVector<size_t> candidate;
		for (size_t j = 0; j < similiarity.cols(); j++){
			if (similiarity(i, j) < similarity_threshold)
				candidate << j;
		}
		candidates << candidate;
	}

	int count_threshold = 1;

	Assignments assignments;
	if (candidates.size() > 7)
	{
		debugBox(QString("%1 candidates. Too complex (lower similairty?)").arg(candidates.size()));

		similarity_threshold = 0.1;

		Assignments candidates;
		for (size_t i = 0; i < similiarity.rows(); i++){
			QVector<size_t> candidate;
			for (size_t j = 0; j < similiarity.cols(); j++){
				if (similiarity(i, j) < similarity_threshold)
					candidate << j;
			}
			candidates << candidate;
		}

		cart_product(assignments, candidates, 10000);
		count_threshold = 12;
	}
	else
	{
		cart_product(assignments, candidates);
	}

	// Filter assignments
	Assignments filtered;
	for (auto & a : assignments)
	{
		QMap<size_t, size_t> counts;
		bool accept = true;
		auto NOTHING_SEGMENT = similiarity.cols() - 1;

		for (auto i : a) counts[i]++;
		for (auto k : counts.keys())
		{
			if (k != NOTHING_SEGMENT && counts[k] > count_threshold){
				accept = false;
				break;
			}
		}

		if (accept) filtered << a;
	}

	for (auto & assignment : filtered)
	{
		QVector < QStringList > landmarksA, landmarksB;

		for (size_t i = 0; i < assignment.size(); i++)
		{
			if (assignment[i] == b->groups.size()) continue;

			auto grpA = a->groups[i];
			auto grpB = b->groups[assignment[i]];

			// Resolve many-to-many
			if (grpA.size() > 1 && grpB.size() > 1)
			{
				QVector<QString> tmpA, tmpB;

				Eigen::AlignedBox3d groupBoxA, groupBoxB;
				for (auto sid : grpA) groupBoxA.extend(a->getNode(sid)->bbox(1.01));
				for (auto sid : grpB) groupBoxB.extend(b->getNode(sid)->bbox(1.01));

				for (auto nodeid_i : grpA){
					auto nodeA = a->getNode(nodeid_i);

					QMap < QString, double > dists;
					for (auto nodeid_j : grpB){
						auto nodeB = b->getNode(nodeid_j);

						Vector3 posA = (nodeA->position(Eigen::Vector4d(0.5, 0.5, 0, 0)) - boxA.min()).array() / boxA.sizes().array();
						Vector3 posB = (nodeB->position(Eigen::Vector4d(0.5, 0.5, 0, 0)) - boxB.min()).array() / boxB.sizes().array();

						dists[nodeid_j] = (posA - posB).norm();
					}
					auto nodeid_j = sortQMapByValue(dists).first().second;

					landmarksA << (QStringList() << nodeid_i);
					landmarksB << (QStringList() << nodeid_j);
				}
			}
			else
			{
				landmarksA << QStringList::fromVector(grpA);
				landmarksB << QStringList::fromVector(grpB);
			}
		}

		result.push_back( qMakePair(landmarksA, landmarksB) );
	}

    return result;
}