Skip to content

Commit

Permalink
Fix long-standing layering violation. Now we make average node width …
Browse files Browse the repository at this point in the history
…(for drawing purposes)

an internal thing of graphics nodes. Graph nodes do not care about this (and they should not).

As a nice side effect, this reduces the size of graph node down to 96 bytes
  • Loading branch information
asl committed Aug 1, 2022
1 parent 86777d1 commit 182c605
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 171 deletions.
114 changes: 28 additions & 86 deletions graph/assemblygraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -970,32 +970,21 @@ QString AssemblyGraph::getUniqueNodeName(QString baseName) const {
return baseName;
}

void AssemblyGraph::recalculateAllDepthsRelativeToDrawnMean()
{
double meanDrawnDepth = getMeanDepth(true);
for (auto *node : m_deBruijnGraphNodes) {
double depthRelativeToMeanDrawnDepth;
if (meanDrawnDepth == 0)
depthRelativeToMeanDrawnDepth = 1.0;
else
depthRelativeToMeanDrawnDepth = node->getDepth() / meanDrawnDepth;

node->setDepthRelativeToMeanDrawnDepth(depthRelativeToMeanDrawnDepth);
}
}


void AssemblyGraph::recalculateAllNodeWidths(double averageNodeWidth,
double depthPower, double depthEffectOnWidth) {
for (auto &entry : m_deBruijnGraphNodes) {
if (GraphicsItemNode * graphicsItemNode = entry->getGraphicsItemNode())
graphicsItemNode->setWidth(averageNodeWidth, depthPower, depthEffectOnWidth);
double meanDrawnDepth = getMeanDepth(true);

for (auto *node : m_deBruijnGraphNodes) {
if (GraphicsItemNode * graphicsItemNode = node->getGraphicsItemNode())
graphicsItemNode->setWidth(meanDrawnDepth== 0 ? 1.0 : node->getDepth() / meanDrawnDepth,
averageNodeWidth,
depthPower, depthEffectOnWidth);
}
}


int AssemblyGraph::getDrawnNodeCount() const
{
int AssemblyGraph::getDrawnNodeCount() const {
int nodeCount = 0;
for (auto *node : m_deBruijnGraphNodes)
nodeCount += node->isDrawn();
Expand Down Expand Up @@ -1104,18 +1093,6 @@ void AssemblyGraph::duplicateNodePair(DeBruijnNode * node, BandageGraphicsScene
originalPosNode->setDepth(newDepth);
originalNegNode->setDepth(newDepth);

double meanDrawnDepth = getMeanDepth(true);
double depthRelativeToMeanDrawnDepth;
if (meanDrawnDepth == 0)
depthRelativeToMeanDrawnDepth = 1.0;
else
depthRelativeToMeanDrawnDepth = originalPosNode->getDepth() / meanDrawnDepth;

originalPosNode->setDepthRelativeToMeanDrawnDepth(depthRelativeToMeanDrawnDepth);
originalNegNode->setDepthRelativeToMeanDrawnDepth(depthRelativeToMeanDrawnDepth);
newPosNode->setDepthRelativeToMeanDrawnDepth(depthRelativeToMeanDrawnDepth);
newPosNode->setDepthRelativeToMeanDrawnDepth(depthRelativeToMeanDrawnDepth);

scene->duplicateGraphicsNode(originalPosNode, newPosNode);
scene->duplicateGraphicsNode(originalNegNode, newNegNode);
}
Expand Down Expand Up @@ -1166,9 +1143,7 @@ static void mergeGraphicsNodes(const std::vector<DeBruijnNode *> &originalNodes,
//This function will merge the given nodes, if possible. Nodes can only be
//merged if they are in a simple, unbranching path with no extra edges. If the
//merge is successful, it returns true, otherwise false.
bool AssemblyGraph::mergeNodes(QList<DeBruijnNode *> nodes, BandageGraphicsScene * scene,
bool recalulateDepth)
{
bool AssemblyGraph::mergeNodes(QList<DeBruijnNode *> nodes, BandageGraphicsScene * scene) {
if (nodes.empty())
return true;

Expand All @@ -1178,25 +1153,21 @@ bool AssemblyGraph::mergeNodes(QList<DeBruijnNode *> nodes, BandageGraphicsScene
nodes.pop_front();

bool addedNode;
do
{
do {
addedNode = false;
for (int i = 0; i < nodes.size(); ++i)
{
for (int i = 0; i < nodes.size(); ++i) {
DeBruijnNode * potentialNextNode = nodes[i];

//Check if the node can be added to the end of the list.
if (canAddNodeToEndOfMergeList(mergeList.back(), potentialNextNode))
{
if (canAddNodeToEndOfMergeList(mergeList.back(), potentialNextNode)) {
mergeList.push_back(potentialNextNode);
nodes.removeAt(i);
addedNode = true;
break;
}

//Check if the node can be added to the front of the list.
if (canAddNodeToStartOfMergeList(mergeList.front(), potentialNextNode))
{
if (canAddNodeToStartOfMergeList(mergeList.front(), potentialNextNode)) {
mergeList.push_front(potentialNextNode);
nodes.removeAt(i);
addedNode = true;
Expand All @@ -1206,15 +1177,13 @@ bool AssemblyGraph::mergeNodes(QList<DeBruijnNode *> nodes, BandageGraphicsScene
//If neither of those worked, then we should try the node's reverse
//complement.
DeBruijnNode * potentialNextNodeRevComp = potentialNextNode->getReverseComplement();
if (canAddNodeToEndOfMergeList(mergeList.back(), potentialNextNodeRevComp))
{
if (canAddNodeToEndOfMergeList(mergeList.back(), potentialNextNodeRevComp)) {
mergeList.push_back(potentialNextNodeRevComp);
nodes.removeAt(i);
addedNode = true;
break;
}
if (canAddNodeToStartOfMergeList(mergeList.front(), potentialNextNodeRevComp))
{
if (canAddNodeToStartOfMergeList(mergeList.front(), potentialNextNodeRevComp)) {
mergeList.push_front(potentialNextNodeRevComp);
nodes.removeAt(i);
addedNode = true;
Expand All @@ -1224,7 +1193,6 @@ bool AssemblyGraph::mergeNodes(QList<DeBruijnNode *> nodes, BandageGraphicsScene

if (nodes.empty())
break;

} while (addedNode);

//If there are still nodes left in the first list, then they don't form a
Expand Down Expand Up @@ -1264,67 +1232,42 @@ bool AssemblyGraph::mergeNodes(QList<DeBruijnNode *> nodes, BandageGraphicsScene
m_deBruijnGraphNodes.emplace(newPosNodeName.toStdString(), newPosNode);
m_deBruijnGraphNodes.emplace(newNegNodeName.toStdString(), newNegNode);

std::vector<DeBruijnEdge *> leavingEdges = orderedList.back()->getLeavingEdges();
for (auto leavingEdge : leavingEdges)
{
for (auto *leavingEdge : orderedList.back()->getLeavingEdges())
createDeBruijnEdge(newPosNodeName, leavingEdge->getEndingNode()->getName(), leavingEdge->getOverlap(),
leavingEdge->getOverlapType());
}

std::vector<DeBruijnEdge *> enteringEdges = orderedList.front()->getEnteringEdges();
for (auto enteringEdge : enteringEdges)
{
for (auto *enteringEdge : orderedList.front()->getEnteringEdges())
createDeBruijnEdge(enteringEdge->getStartingNode()->getName(), newPosNodeName, enteringEdge->getOverlap(),
enteringEdge->getOverlapType());
}

if (recalulateDepth)
{
double meanDrawnDepth = getMeanDepth(true);
double depthRelativeToMeanDrawnDepth;
if (meanDrawnDepth == 0)
depthRelativeToMeanDrawnDepth = 1.0;
else
depthRelativeToMeanDrawnDepth = newPosNode->getDepth() / meanDrawnDepth;

newPosNode->setDepthRelativeToMeanDrawnDepth(depthRelativeToMeanDrawnDepth);
newNegNode->setDepthRelativeToMeanDrawnDepth(depthRelativeToMeanDrawnDepth);
}
else
{
newPosNode->setDepthRelativeToMeanDrawnDepth(1.0);
newNegNode->setDepthRelativeToMeanDrawnDepth(1.0);
}

mergeGraphicsNodes(orderedList, revCompOrderedList, newPosNode, scene);

deleteNodes(orderedList);

recalculateAllNodeWidths(g_settings->averageNodeWidth,
g_settings->depthPower, g_settings->depthEffectOnWidth);

return true;
}


static bool mergeGraphicsNodes2(const std::vector<DeBruijnNode *> &originalNodes,
DeBruijnNode * newNode,
BandageGraphicsScene * scene)
{
BandageGraphicsScene * scene) {
bool success = true;
std::vector<QPointF> linePoints;

for (auto *node : originalNodes)
{
for (auto *node : originalNodes) {
//If we are in single mode, then we should check for a GraphicsItemNode only
//in the positive nodes.
bool opposite = false;
if (!g_settings->doubleMode && node->isNegativeNode())
{
if (!g_settings->doubleMode && node->isNegativeNode()) {
node = node->getReverseComplement();
opposite = true;
}

GraphicsItemNode * originalGraphicsItemNode = node->getGraphicsItemNode();
if (originalGraphicsItemNode == nullptr)
{
if (originalGraphicsItemNode == nullptr) {
success = false;
break;
}
Expand All @@ -1343,7 +1286,8 @@ static bool mergeGraphicsNodes2(const std::vector<DeBruijnNode *> &originalNodes
}

if (success) {
auto * newGraphicsItemNode = new GraphicsItemNode(newNode, linePoints);
// We pass dummy width here, as node widths will be recalculated later
auto * newGraphicsItemNode = new GraphicsItemNode(newNode, 0, linePoints);

newNode->setGraphicsItemNode(newGraphicsItemNode);
newGraphicsItemNode->setFlag(QGraphicsItem::ItemIsSelectable);
Expand All @@ -1366,8 +1310,7 @@ static bool mergeGraphicsNodes2(const std::vector<DeBruijnNode *> &originalNodes
static void mergeGraphicsNodes(const std::vector<DeBruijnNode *> &originalNodes,
const std::vector<DeBruijnNode *> &revCompOriginalNodes,
DeBruijnNode * newNode,
BandageGraphicsScene * scene)
{
BandageGraphicsScene * scene) {
bool success = mergeGraphicsNodes2(originalNodes, newNode, scene);
if (success)
newNode->setAsDrawn();
Expand Down Expand Up @@ -1472,12 +1415,11 @@ int AssemblyGraph::mergeAllPossible(BandageGraphicsScene * scene,
if (progressDialog != nullptr && progressDialog->wasCancelled())
break;

mergeNodes(allMerges[i], scene, false);
mergeNodes(allMerges[i], scene);
emit setMergeCompletedCount(i+1);
QApplication::processEvents();
}

recalculateAllDepthsRelativeToDrawnMean();
recalculateAllNodeWidths(g_settings->averageNodeWidth,
g_settings->depthPower, g_settings->depthEffectOnWidth);

Expand Down
5 changes: 2 additions & 3 deletions graph/assemblygraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class AssemblyGraph : public QObject
void resetNodeContiguityStatus();
void determineGraphInfo();
void clearGraphInfo();
void recalculateAllDepthsRelativeToDrawnMean();

void recalculateAllNodeWidths(double averageNodeWidth,
double depthPower, double depthEffectOnWidth);

Expand Down Expand Up @@ -153,8 +153,7 @@ class AssemblyGraph : public QObject
void deleteNodes(const std::vector<DeBruijnNode *> &nodes);
void deleteEdges(const std::vector<DeBruijnEdge *> &edges);
void duplicateNodePair(DeBruijnNode * node, BandageGraphicsScene * scene);
bool mergeNodes(QList<DeBruijnNode *> nodes, BandageGraphicsScene * scene,
bool recalulateDepth);
bool mergeNodes(QList<DeBruijnNode *> nodes, BandageGraphicsScene * scene);

int mergeAllPossible(BandageGraphicsScene * scene = 0,
MyProgressDialog * progressDialog = 0);
Expand Down
3 changes: 1 addition & 2 deletions graph/debruijnnode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@

//The length parameter is optional. If it is set, then the node will use that
//for its length. If not set, it will just use the sequence length.
DeBruijnNode::DeBruijnNode(QString name, double depth, const Sequence& sequence, int length) :
DeBruijnNode::DeBruijnNode(QString name, float depth, const Sequence& sequence, int length) :
m_name(std::move(name)),
m_depth(depth),
m_depthRelativeToMeanDrawnDepth(1.0),
m_sequence(sequence),
m_length(sequence.size()),
m_contiguityStatus(NOT_CONTIGUOUS),
Expand Down
6 changes: 1 addition & 5 deletions graph/debruijnnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class DeBruijnNode
{
public:
//CREATORS
DeBruijnNode(QString name, double depth, const Sequence &sequence, int length = 0);
DeBruijnNode(QString name, float depth, const Sequence &sequence, int length = 0);
~DeBruijnNode() = default;

//ACCESSORS
Expand All @@ -47,7 +47,6 @@ class DeBruijnNode
QString getSign() const {if (m_name.length() > 0) return m_name.right(1); else return "+";}

double getDepth() const {return m_depth;}
double getDepthRelativeToMeanDrawnDepth() const {return m_depthRelativeToMeanDrawnDepth;}

float getGC() const;

Expand Down Expand Up @@ -93,8 +92,6 @@ class DeBruijnNode
DeBruijnEdge *getSelfLoopingEdge() const;
int getDeadEndCount() const;

//MODIFERS
void setDepthRelativeToMeanDrawnDepth(double newVal) {m_depthRelativeToMeanDrawnDepth = newVal;}
void setSequence(const QByteArray &newSeq) {m_sequence = Sequence(newSeq); m_length = m_sequence.size();}
void setSequence(const Sequence &newSeq) {m_sequence = newSeq; m_length = m_sequence.size();}
void upgradeContiguityStatus(ContiguityStatus newStatus);
Expand Down Expand Up @@ -122,7 +119,6 @@ class DeBruijnNode
GraphicsItemNode * m_graphicsItemNode;

float m_depth;
float m_depthRelativeToMeanDrawnDepth;

int m_length : 27;
ContiguityStatus m_contiguityStatus : 3;
Expand Down
Loading

0 comments on commit 182c605

Please sign in to comment.