/*!
Resolve the overloaded method to call.  The algorithm works conceptually like this:
    1.  Resolve the set of overloads it is *possible* to call.
        Impossible overloads include those that have too many parameters or have parameters 
        of unknown type.  
    2.  Filter the set of overloads to only contain those with the closest number of 
        parameters.
        For example, if we are called with 3 parameters and there are 2 overloads that
        take 2 parameters and one that takes 3, eliminate the 2 parameter overloads.
    3.  Find the best remaining overload based on its match score.  
        If two or more overloads have the same match score, call the last one.  The match
        score is constructed by adding the matchScore() result for each of the parameters.
*/
QDeclarativeObjectMethodScriptClass::Value
QDeclarativeObjectMethodScriptClass::callOverloaded(MethodData *method, QScriptContext *ctxt)
{
    int argumentCount = ctxt->argumentCount();

    QDeclarativePropertyCache::Data *best = 0;
    int bestParameterScore = INT_MAX;
    int bestMatchScore = INT_MAX;

    QDeclarativePropertyCache::Data dummy;
    QDeclarativePropertyCache::Data *attempt = &method->data;

    do {
        QList<QByteArray> methodArgTypeNames;

        if (attempt->flags & QDeclarativePropertyCache::Data::HasArguments)
            methodArgTypeNames = method->object->metaObject()->method(attempt->coreIndex).parameterTypes();

        int methodArgumentCount = methodArgTypeNames.count();

        if (methodArgumentCount > argumentCount)
            continue; // We don't have sufficient arguments to call this method

        int methodParameterScore = argumentCount - methodArgumentCount;
        if (methodParameterScore > bestParameterScore)
            continue; // We already have a better option

        int methodMatchScore = 0;
        QVarLengthArray<int, 9> methodArgTypes(methodArgumentCount);

        bool unknownArgument = false;
        for (int ii = 0; ii < methodArgumentCount; ++ii) {
            methodArgTypes[ii] = QMetaType::type(methodArgTypeNames.at(ii));
            if (methodArgTypes[ii] == QVariant::Invalid) 
                methodArgTypes[ii] = enumType(method->object->metaObject(), 
                                              QString::fromLatin1(methodArgTypeNames.at(ii)));
            if (methodArgTypes[ii] == QVariant::Invalid) {
                unknownArgument = true;
                break;
            }
            methodMatchScore += matchScore(ctxt->argument(ii), methodArgTypes[ii], methodArgTypeNames.at(ii));
        }
        if (unknownArgument)
            continue; // We don't understand all the parameters

        if (bestParameterScore > methodParameterScore || bestMatchScore > methodMatchScore) {
            best = attempt;
            bestParameterScore = methodParameterScore;
            bestMatchScore = methodMatchScore;
        }

        if (bestParameterScore == 0 && bestMatchScore == 0)
            break; // We can't get better than that

    } while((attempt = relatedMethod(method->object, attempt, dummy)) != 0);

    if (best) {
        return callPrecise(method->object, *best, ctxt);
    } else {
        QString error = QLatin1String("Unable to determine callable overload.  Candidates are:");
        QDeclarativePropertyCache::Data *candidate = &method->data;
        while (candidate) {
            error += QLatin1String("\n    ") + QString::fromUtf8(method->object->metaObject()->method(candidate->coreIndex).signature());
            candidate = relatedMethod(method->object, candidate, dummy);
        }
        return Value(ctxt, ctxt->throwError(error));
    }
}
Beispiel #2
0
    pair<vector<unsigned long>,vector<unsigned long>> SeqGraphAlignment::alignStringToGraphFast() {
        //if (typeid(sequence).name() != "string") {
        //    cerr << "Invalid Type" << endl;
        //    return;
        //}

        unsigned long l1 = graph->numberOfNodes;
        unsigned long l2 = sequence.length();

        unordered_map<unsigned long, unsigned long> nodeIDtoIndex;
        unordered_map<unsigned long, unsigned long> nodeIndexToID;
        nodeIndexToID[-1] = (unsigned long) -1;

        auto nodes = graph->nodes;
        unsigned long index = 0;
        for (auto nodeID : graph->nodeOrder) {
            nodeIDtoIndex[nodeID] = index;
            nodeIndexToID[index] = nodeID;
            index++;
        }
//        for (map<int, Node *>::iterator it = nodes.begin(); it != nodes.end(); it++) {
//            nodeIDtoIndex[it->second->ID] = it->first;
//            nodeIndexToID[it->first] = it->second->ID;
//        }

        vector<vector<long>> scores(l1 + 1, vector<long>(l2 + 1));

        if (globalAlign) {
            for (int i = 1; i < l2 + 1; i++) {
                scores[0][i] = openGapValue + (i - 1) * extendGapValue;
            }

            nodes = graph->nodes;

            index = 0;
            for (auto nodeID : graph->nodeOrder) {
                auto mIter = graph->nodes[nodeID];
                auto prevIndexs = prevIndices(mIter, nodeIDtoIndex);

                scores[0][0] = openGapValue - extendGapValue;
                long best = scores[prevIndexs.front() + 1][0];

                for (auto lIter = prevIndexs.begin(); lIter != prevIndexs.end(); lIter++) {
                    best = max(best, scores[*lIter + 1][0]);
                }

                scores[index + 1][0] = best + extendGapValue;
                scores[0][0] = 0;
                index++;
            }
        }

        vector<vector<unsigned long>> backStrIdx(l1 + 1, vector<unsigned long>(l2 + 1));
        vector<vector<unsigned long>> backGrphIdx(l1 + 1, vector<unsigned long>(l2 + 1));

        vector<char> seqvec;
        copy(sequence.begin(), sequence.end(), back_inserter(seqvec));

        vector<vector<long>> insertCost(l1 + 1, vector<long>(l2 + 1, this->openGapValue));
//        memset(*insertCost, this->openGapValue, sizeof (int) * (l1+1) * (l2+1));
        vector<vector<long>> deleteCost(l1 + 1, vector<long>(l2 + 1, this->openGapValue));
//        memset(deleteCost, this->openGapValue, sizeof (int) * (l1+1) * (l2+1));
//        fill(&insertCost[0][0], &insertCost[l1][l2], this->openGapValue);
//        fill(&deleteCost[0][0], &deleteCost[l1][l2], this->openGapValue);
        vector<bool> inserted(l2 + 1, false);
        vector<long> insertScore(l2 + 2, 0);

        char gbase;
        vector<unsigned long> predecessors;
        vector<long> matchPoints, deleteScore(l2), matchScore(l2);
        vector<unsigned long> bestDelete(l2), bestMatch(l2);
        vector<bool> deleted;

        index = 0;
        for (auto nodeID : graph->nodeOrder) {
            auto it = nodes[nodeID];
            gbase = it->base;
            predecessors = prevIndices(it, nodeIDtoIndex);
            matchPoints = matchScoreVec(gbase, seqvec);

            deleteScore.clear();
            for (int j = 1; j < l2 + 1; j++) {
                deleteScore.push_back(scores[predecessors.front() + 1][j] + deleteCost[predecessors.front() + 1][j]);
                matchScore[j - 1] = scores[predecessors.front() + 1][j - 1] + matchPoints[j - 1];
            }
            auto fill_value = predecessors.front() + 1;
            fill(bestDelete.begin(), bestDelete.end(), fill_value);
            fill(bestMatch.begin(), bestMatch.end(), fill_value);

            for (auto it2 = next(predecessors.begin()); it2 != predecessors.end(); it2++) {

                vector<long> newDeleteScore;
                vector<long> newMatchScore;
                for (int j = 1; j < l2 + 1; j++) {
                    newDeleteScore.push_back(scores[*it2 + 1][j] + deleteCost[*it2 + 1][j]);
                    newMatchScore.push_back(scores[*it2 + 1][j - 1] + matchPoints[j - 1]);
                }
                for (int i = 0; i < l2; i++) {
                    bestDelete[i] = newDeleteScore[i] > deleteScore[i] ? *it2 + 1 : bestDelete[i];
                    bestMatch[i] = newMatchScore[i] > matchScore[i] ? *it2 + 1 : bestMatch[i];
                }

                for (int i = 0; i < l2; i++) {
                    deleteScore[i] = max(newDeleteScore[i], deleteScore[i]);
                    matchScore[i] = max(newMatchScore[i], matchScore[i]);
                }
            }

            deleted.clear();
            for (unsigned long i = 0; i < l2; i++) {
                deleted.push_back(deleteScore[i] > matchScore[i]);
            }

            for (unsigned long j = 1; j < l2 + 1; j++) {
                scores[index + 1][j] =
                        deleteScore[j - 1] >= matchScore[j - 1] ? deleteScore[j - 1] : matchScore[j - 1];
                backGrphIdx[index + 1][j] = deleted[j - 1] ? bestDelete[j - 1] : bestMatch[j - 1];
                backStrIdx[index + 1][j] = deleted[j - 1] ? j : j - 1;
                deleteCost[index + 1][j] = deleted[j - 1] ? extendGapValue : deleteCost[index + 1][j];
            }

            //insertions
            fill(inserted.begin(), inserted.end(), false);
            for (int j = 0; j < l2 + 1; j++) {
                insertScore[j] = scores[index + 1][j] + insertCost[index + 1][j];
            }

            for (unsigned long j = 0; j < l2; j++) {
                if (insertScore[j] > scores[index + 1][j + 1]) {
                    scores[index + 1][j + 1] = insertScore[j];
                    insertCost[index + 1][j + 1] = extendGapValue;
                    backStrIdx[index + 1][j + 1] = j;
                    inserted[j + 1] = true;
                    insertScore[j + 1] = scores[index + 1][j + 1] + insertCost[index + 1][j + 1];
                }
            }

            for (int j = 1; j < l2 + 1; j++) {
                if (inserted[j]) {
                    insertCost[index + 1][j] = extendGapValue;
                    deleteCost[index + 1][j] = openGapValue;
                    backGrphIdx[index + 1][j] = index + 1;
                }
            }

            if (!globalAlign) {
                for (int j = 0; j < l2; j++) {
                    backGrphIdx[nodeID + 1][j] = scores[nodeID + 1][j] > 0 ? backGrphIdx[nodeID + 1][j] : (unsigned long) -1;
                    backStrIdx[nodeID + 1][j] = scores[nodeID + 1][j] > 0 ? backStrIdx[nodeID + 1][j] : (unsigned long) -1;
                    scores[nodeID + 1][j] = max(scores[nodeID + 1][j], 0L);
                }
            }
            index++;
        }
        return backTrack(l1, l2, scores, backStrIdx, backGrphIdx, nodeIndexToID);
    }
Beispiel #3
0
    pair<vector<unsigned long>,vector<unsigned long>> SeqGraphAlignment::alignStringToGraphSimple() {
        unsigned long l1 = graph->numberOfNodes;
        unsigned long l2 = sequence.length();

        unordered_map<unsigned long, unsigned long> nodeIDtoIndex;
        unordered_map<unsigned long, unsigned long> nodeIndexToID;
        nodeIndexToID[-1] = (unsigned long) -1;

        auto nodes = graph->nodes;
        unsigned long index = 0;
        for (auto nodeID : graph->nodeOrder) {
            nodeIDtoIndex[nodeID] = index;
            nodeIndexToID[index] = nodeID;
            index++;
        }

        vector<vector<long>> scores(l1 + 1, vector<long>(l2 + 1));

        if (globalAlign) {
            for (unsigned long i = 1; i < l2 + 1; i++) {
                scores[0][i] = openGapValue + (i - 1) * extendGapValue;
            }

            nodes = graph->nodes;

            index = 0;
            for (auto nodeID : graph->nodeOrder) {
                auto mIter = graph->nodes[nodeID];
                auto prevIndexs = prevIndices(mIter, nodeIDtoIndex);

                scores[0][0] = openGapValue - extendGapValue;
                long best = scores[prevIndexs.front() + 1][0];

                for (auto lIter = prevIndexs.begin(); lIter != prevIndexs.end(); lIter++) {
                    best = max(best, scores[*lIter + 1][0]);
                }

                scores[index + 1][0] = best + extendGapValue;
                scores[0][0] = 0;
                index++;
            }
        }

        vector<vector<unsigned long>> backStrIdx(l1 + 1, vector<unsigned long>(l2 + 1));
        vector<vector<unsigned long>> backGrphIdx(l1 + 1, vector<unsigned long>(l2 + 1));

//        map<tuple<int,int>,int> insertCost, deleteCost;
        int insertCost[l1 + 1][l2 + 1];
//        memset(*insertCost, this->openGapValue, sizeof (int) * (l1+1) * (l2+1));
        int deleteCost[l1 + 1][l2 + 1];
//        memset(deleteCost, this->openGapValue, sizeof (int) * (l1+1) * (l2+1));
        fill_n(*insertCost, (l1+1) * (l2+1), this->openGapValue);
        fill_n(*deleteCost, (l1+1) * (l2+1), this->openGapValue);

        char gbase;
        vector<char> seqvec;
        copy(sequence.begin(), sequence.end(), back_inserter(seqvec));

        index = 0;
        for (auto nodeID : graph->nodeOrder) {
            auto it = nodes[nodeID];
            gbase = it->base;

            unsigned long index2=0;
            for (vector<char>::iterator it3 = seqvec.begin(); it3 != seqvec.end(); it3++) {

                long best1=scores[index+1][index2] + insertCost[index+1][index2];
                unsigned long best2=index+1;
                unsigned long best3=index2;
                string best4="INS";

                auto predIndex = prevIndices(it, nodeIDtoIndex);
                for (auto it2 = predIndex.begin(); it2 != predIndex.end(); it2++) {
                    if(
                        best1 < (scores[*it2+1][index2] + matchScore(*it3,gbase)) ||
                        best2 < (*it2+1) ||
                        best3 < index2
                    ) {
                        best1 = (scores[*it2+1][index2] + matchScore(*it3,gbase));
                        best2 = (*it2+1);
                        best3 = index2;
                        best4 = "MATCH";
                    }

                    if(
                        best1 < (scores[*it2+1][index2+1] + deleteCost[*it2+1][index2]) ||
                        best2 < (*it2+1) ||
                        best3 < index2
                    ) {
                        best1 = (scores[*it2+1][index2+1] + deleteCost[*it2+1][index2]);
                        best2 = (*it2+1);
                        best3 = index2+1;
                        best4 = "DEL";
                    }
                }

                scores[index+1][index2+1] = best1;
                backGrphIdx[index+1][index2+1] = best2;
                backStrIdx[index+1][index2+1] = best3;

                if(best4 == "INS") {
                    insertCost[index+1][index2+1] = extendGapValue;
                }
                else if(best4 == "DEL") {
                    deleteCost[index+1][index2+1] = extendGapValue;
                }

            }
        }

        return backTrack(l1, l2, scores, backStrIdx, backGrphIdx, nodeIndexToID);

    }
void
NDalgorithm::forward(char    *A,   int32 Alen,
                     char    *T,   int32 Tlen,
                     int32   &A_End,
                     int32   &T_End,
                     bool    &Match_To_End) {

  assert (Alen <= Tlen);

  int32  Best_d      = 0;
  int32  Best_e      = 0;
  int32  Best_row    = 0;
  int32  Best_score  = 0;


  int32  Row = 0;
  int32  Dst = 0;
  int32  Err = 0;
  int32  Sco = 0;

  int32  fromd = 0;

  //  Skip ahead over matches.  The original used to also skip if either sequence was N.
  while ((Row < Alen) && (isMatch(A[Row], T[Row]))) {
    Sco += matchScore(A[Row], T[Row]);
    Row++;
  }

  if (Edit_Array_Lazy[0] == NULL)
    allocateMoreEditSpace();

  Edit_Array_Lazy[0][0].row    = Row;
  Edit_Array_Lazy[0][0].dist   = Dst;
  Edit_Array_Lazy[0][0].errs   = 0;
  Edit_Array_Lazy[0][0].score  = Sco;
  Edit_Array_Lazy[0][0].fromd  = INT32_MAX;

  // Exact match?

  if (Row == Alen) {
    A_End        = Alen;
    T_End        = Alen;
    Match_To_End = true;

    Right_Score       = Sco;
    Right_Delta_Len   = 0;

    return;
  }

  int32  Left  = 0;
  int32  Right = 0;

  int32  Max_Score         = PEDMINSCORE;
  int32  Max_Score_Len     = 0;
  int32  Max_Score_Best_d  = 0;
  int32  Max_Score_Best_e  = 0;

  for (int32 ei=1; ei <= Edit_Space_Max; ei++) {
    if (Edit_Array_Lazy[ei] == NULL)
      if (allocateMoreEditSpace() == false) {
        //  FAIL
        return;
      }

    Left  = MAX (Left  - 1, -ei);
    Right = MIN (Right + 1,  ei);

    //fprintf(stderr, "FORWARD ei=%d Left=%d Right=%d\n", ei, Left, Right);

    Edit_Array_Lazy[ei-1][Left  - 1].init();
    Edit_Array_Lazy[ei-1][Left     ].init();
    //  Of note, [0][0] on the first iteration is not reset here.
    Edit_Array_Lazy[ei-1][Right    ].init();
    Edit_Array_Lazy[ei-1][Right + 1].init();

    for (int32 d = Left;  d <= Right;  d++) {

      //  A mismatch.
      {
        int32  aPos         =  (1 + Edit_Array_Lazy[ei-1][d].row)     - 1;  //  -1 because we need to compare the base we are at,
        int32  tPos         =  (1 + Edit_Array_Lazy[ei-1][d].row) + d - 1;  //  not the base we will be at after the mismatch

        Row   = 1 + Edit_Array_Lazy[ei-1][d].row;
        Dst   =     Edit_Array_Lazy[ei-1][d].dist  + 1;
        Err   =     Edit_Array_Lazy[ei-1][d].errs  + 1;
        fromd =     d;

        //  If positive, we have a pointer into valid sequence.  If not, this mismatch
        //  doesn't make sense, and the row/score are set to bogus values.

        if ((aPos >= 0) && (tPos >= 0)) {
          assert (aPos <= Alen);
          assert( tPos <= Tlen);

          assert(A[aPos] != T[tPos]);

          Sco = Edit_Array_Lazy[ei-1][d].score + mismatchScore(A[aPos], T[tPos]);

        } else {
          Sco = PEDMINSCORE;
        }
      }

      //  Insert a gap in A.  Check the other sequence to see if this is a zero-cost gap.  Note
      //  agreement with future value of Row and what is used in isMatch() below.

      {
        int32  tPos    = 0 + Edit_Array_Lazy[ei-1][d-1].row + d;

        //assert(tPos >= 0);
        //assert(tPos < Tlen);

        if ((tPos >= 0) && (tPos <= Tlen)) {
          int32  gapCost = isFreeGap( T[tPos] ) ? PEDFREEGAP : PEDGAP;

          //if (gapCost == 0)
          //  fprintf(stderr, "NDalgorithm::forward()--  free A gap for aPos=%d tPos=%d t=%c/%d\n", tPos - d, tPos, T[tPos], T[tPos]);

          if (Edit_Array_Lazy[ei-1][d-1].score + gapCost > Sco) {
            Row   =     Edit_Array_Lazy[ei-1][d-1].row;
            Dst   =     Edit_Array_Lazy[ei-1][d-1].dist  + (gapCost == PEDFREEGAP) ? 0 : 0;
            Err   =     Edit_Array_Lazy[ei-1][d-1].errs  + (gapCost == PEDFREEGAP) ? 0 : 0;
            Sco   =     Edit_Array_Lazy[ei-1][d-1].score +  gapCost;
            fromd =     d-1;
          }
        }
      }

      //  Insert a gap in T.
      //  Testcase test-st-ts shows this works.

      {
        int32  aPos    = 1 + Edit_Array_Lazy[ei-1][d+1].row;

        //assert(aPos >= 0);
        //assert(aPos < Tlen);

        if ((aPos >= 0) && (aPos <= Alen)) {
          int32  gapCost = isFreeGap( A[aPos] ) ? 0 : PEDGAP;

          //if (gapCost == 0)
          //  fprintf(stderr, "NDalgorithm::forward()--  free T gap for aPos=%d tPos=%d a=%c/%d\n", aPos, aPos + d, A[aPos], A[aPos]);

          if (Edit_Array_Lazy[ei-1][d+1].score + gapCost > Sco) {
            Row   = 1 + Edit_Array_Lazy[ei-1][d+1].row;
            Dst   =     Edit_Array_Lazy[ei-1][d+1].dist  + (gapCost == PEDFREEGAP) ? 0 : 1;
            Err   =     Edit_Array_Lazy[ei-1][d+1].errs  + (gapCost == PEDFREEGAP) ? 0 : 1;
            Sco   =     Edit_Array_Lazy[ei-1][d+1].score +  gapCost;
            fromd =     d+1;
          }
        }
      }

      //  If A or B is N, that isn't a mismatch.
      //  If A is lowercase and T is uppercase, it's a match.
      //  If A is lowercase and T doesn't match, ignore the cost of the gap in B

      while ((Row < Alen) && (Row + d < Tlen) && (isMatch(A[Row], T[Row + d]))) {
        Sco += matchScore(A[Row], T[Row + d]);
        Row += 1;
        Dst += 1;
        Err += 0;
      }

      Edit_Array_Lazy[ei][d].row   = Row;
      Edit_Array_Lazy[ei][d].dist  = Dst;
      Edit_Array_Lazy[ei][d].errs  = Err;
      Edit_Array_Lazy[ei][d].score = Sco;
      Edit_Array_Lazy[ei][d].fromd = fromd;

      //fprintf(stderr, "SET ei=%d d=%d -- row=%d dist=%d errs=%d score=%d fromd=%d\n", ei, d, Row, Dst, Err, Sco, fromd);

      if (Row == Alen || Row + d == Tlen) {
        A_End = Row;           // One past last align position
        T_End = Row + d;

        Set_Right_Delta(ei, d);

        Match_To_End = true;

        return;  //return(ei);
      }
    }  //  Over all diagonals.

    //  Reset the band
    //
    //  The .dist used to be .row.

    while  ((Left <= Right) && (Left < 0) && (Edit_Array_Lazy[ei][Left].dist < Edit_Match_Limit[ Edit_Array_Lazy[ei][Left].errs ]))
      Left++;

    if (Left >= 0)
      while  ((Left <= Right) && (Edit_Array_Lazy[ei][Left].dist + Left < Edit_Match_Limit[ Edit_Array_Lazy[ei][Left].errs ]))
        Left++;

    if (Left > Right)
      break;

    while  ((Right > 0) && (Edit_Array_Lazy[ei][Right].dist + Right < Edit_Match_Limit[ Edit_Array_Lazy[ei][Right].errs ]))
      Right--;

    if (Right <= 0)
      while  (Edit_Array_Lazy[ei][Right].dist < Edit_Match_Limit[ Edit_Array_Lazy[ei][Right].errs ])
        Right--;

    assert (Left <= Right);

    for (int32 d = Left;  d <= Right;  d++)
      if (Edit_Array_Lazy[ei][d].score > Best_score) {
        Best_d      = d;
        Best_e      = ei;
        Best_row    = Edit_Array_Lazy[ei][d].row;
        Best_score  = Edit_Array_Lazy[ei][d].score;
      }

    if (Best_score > Max_Score) {
      Max_Score_Best_d = Best_d;
      Max_Score_Best_e = Best_e;
      Max_Score        = Best_score;
      Max_Score_Len    = Best_row;
    }
  }  //  Over all possible number of errors

  //fprintf(stderr, "NDalgorithm::forward()- iterated over all errors, return best found\n");

  A_End = Max_Score_Len;
  T_End = Max_Score_Len + Max_Score_Best_d;

  Set_Right_Delta(Max_Score_Best_e, Max_Score_Best_d);

  Match_To_End = false;

  return;  //return(Max_Score_Best_e);
}