static void test_stSet_getUnion(CuTest* testCase) { testSetup(); // Check union of empty sets is empty stSet *set2 = stSet_construct(); stSet *set3 = stSet_construct(); stSet *set4 = stSet_getUnion(set2, set3); CuAssertTrue(testCase, stSet_size(set4) == 0); stSet_destruct(set2); stSet_destruct(set3); stSet_destruct(set4); // Check union of non empty set and empty set is non-empty set2 = stSet_construct(); set3 = stSet_getUnion(set0, set2); CuAssertTrue(testCase, stSet_size(set3) == 6); stSet_destruct(set2); stSet_destruct(set3); // Check union of two non-empty overlapping sets is correct set2 = stSet_construct(); set3 = stSet_construct(); stIntTuple **uniqs = (stIntTuple **) st_malloc(sizeof(*uniqs) * 4); uniqs[0] = stIntTuple_construct2(9, 0); uniqs[1] = stIntTuple_construct2(9, 1); uniqs[2] = stIntTuple_construct2(9, 2); uniqs[3] = stIntTuple_construct2(9, 3); stIntTuple **common = (stIntTuple **) st_malloc(sizeof(*uniqs) * 5); common[0] = stIntTuple_construct2(5, 0); common[1] = stIntTuple_construct2(5, 1); common[2] = stIntTuple_construct2(5, 2); common[3] = stIntTuple_construct2(5, 3); common[4] = stIntTuple_construct2(5, 4); for (int i = 0; i < 5; ++i) { stSet_insert(set2, common[i]); stSet_insert(set3, common[i]); } stSet_insert(set2, uniqs[0]); stSet_insert(set2, uniqs[1]); stSet_insert(set3, uniqs[2]); stSet_insert(set3, uniqs[3]); set4 = stSet_getUnion(set2, set3); CuAssertTrue(testCase, stSet_size(set4) == 9); for (int i = 0; i < 4; ++i) { CuAssertTrue(testCase, stSet_search(set4, uniqs[i]) != NULL); } for (int i = 0; i < 5; ++i) { CuAssertTrue(testCase, stSet_search(set4, common[i]) != NULL); } stSet_destruct(set2); stSet_destruct(set3); stSet_destruct(set4); // Check we get an exception with sets with different functions. stTry { stSet_getUnion(set0, set1); } stCatch(except) { CuAssertTrue(testCase, stExcept_getId(except) == SET_EXCEPTION_ID); } stTryEnd testTeardown(); }
static void setup() { teardown(); assert(nodeNumber == -1); while(nodeNumber % 2 != 0) { nodeNumber = st_randomInt(0, 100); } assert(nodeNumber >= 0); assert(nodeNumber % 2 == 0); stubs = stList_construct3(0, (void (*)(void *))stIntTuple_destruct); chains = stList_construct3(0, (void (*)(void *))stIntTuple_destruct); for(int64_t i=0; i<nodeNumber/2; i++) { assert(nodeNumber/2 > 0); stIntTuple *edge = stIntTuple_construct2(i, nodeNumber/2 + i); if(stList_length(stubs) == 0 || st_random() > 0.9) { stList_append(stubs, edge); } else { stList_append(chains, edge); } } zMatrix = st_calloc(nodeNumber*nodeNumber, sizeof(float)); for(int64_t i=0; i<nodeNumber; i++) { for(int64_t j=i+1; j<nodeNumber; j++) { double score = st_random(); zMatrix[i * nodeNumber + j] = score; zMatrix[j * nodeNumber + i] = score; } } st_logDebug("To test the adjacency problem we've created a problem with %" PRIi64 " nodes %" PRIi64 " stubs and %" PRIi64 " chains\n", nodeNumber, stList_length(stubs), stList_length(chains)); }
static void test_stSet_search(CuTest* testCase) { testSetup(); stIntTuple *i = stIntTuple_construct1( 0); stIntTuple *j = stIntTuple_construct2(10, 0); stIntTuple *k = stIntTuple_construct1( 5); //Check search by memory address CuAssertTrue(testCase, stSet_search(set0, one) == one); CuAssertTrue(testCase, stSet_search(set0, two) == two); CuAssertTrue(testCase, stSet_search(set0, three) == three); CuAssertTrue(testCase, stSet_search(set0, four) == four); CuAssertTrue(testCase, stSet_search(set0, five) == five); CuAssertTrue(testCase, stSet_search(set0, six) == six); //Check not present CuAssertTrue(testCase, stSet_search(set0, i) == NULL); CuAssertTrue(testCase, stSet_search(set0, j) == NULL); CuAssertTrue(testCase, stSet_search(set0, k) == NULL); //Check search by memory address CuAssertTrue(testCase, stSet_search(set1, one) == one); CuAssertTrue(testCase, stSet_search(set1, two) == two); CuAssertTrue(testCase, stSet_search(set1, three) == three); CuAssertTrue(testCase, stSet_search(set1, four) == four); CuAssertTrue(testCase, stSet_search(set1, five) == five); CuAssertTrue(testCase, stSet_search(set1, six) == six); //Check not present CuAssertTrue(testCase, stSet_search(set1, j) == NULL); //Check is searching by memory CuAssertTrue(testCase, stSet_search(set1, i) == one); CuAssertTrue(testCase, stSet_search(set1, k) == six); stIntTuple_destruct(i); stIntTuple_destruct(j); stIntTuple_destruct(k); testTeardown(); }
/* * Uses the functions above to build an adjacency list, then by DFS attempts to create * a valid topological sort, returning non-zero if the graph contains a cycle. */ static int64_t containsACycle(stList *pairs, int64_t sequenceNumber) { //Build an adjacency list structure.. stHash *adjacencyList = buildAdjacencyList(pairs, sequenceNumber); //Do a topological sort of the adjacency list stSortedSet *started = stSortedSet_construct3((int (*)(const void *, const void *))stIntTuple_cmpFn, NULL); stSortedSet *done = stSortedSet_construct3((int (*)(const void *, const void *))stIntTuple_cmpFn, NULL); int64_t cyclic = 0; for(int64_t seq=0; seq<sequenceNumber; seq++) { stIntTuple *seqPos = stIntTuple_construct2( seq, 0); //The following hacks avoid memory cleanup.. stSortedSet *column = stHash_search(adjacencyList, seqPos); assert(column != NULL); stIntTuple *seqPos2 = stSortedSet_search(column, seqPos); assert(seqPos2 != NULL); cyclic = cyclic || dfs(adjacencyList, seqPos2, started, done); stIntTuple_destruct(seqPos); } //cleanup stHashIterator *it = stHash_getIterator(adjacencyList); stIntTuple *seqPos; stSortedSet *columns = stSortedSet_construct2((void (*)(void *))stSortedSet_destruct); while((seqPos = stHash_getNext(it)) != NULL) { stSortedSet *column = stHash_search(adjacencyList, seqPos); assert(column != NULL); stSortedSet_insert(columns, column); } stHash_destructIterator(it); stHash_destruct(adjacencyList); stSortedSet_destruct(columns); stSortedSet_destruct(started); stSortedSet_destruct(done); return cyclic; }
/* * Function does the actual depth first search to detect if the thing has an acyclic ordering. */ static int64_t dfs(stHash *adjacencyList, stIntTuple *seqPos, stSortedSet *started, stSortedSet *done) { if(stSortedSet_search(started, seqPos) != NULL) { if(stSortedSet_search(done, seqPos) == NULL) { //We have detected a cycle //st_logInfo("I have cycle %" PRIi64 " %" PRIi64 "\n", stIntTuple_getPosition(seqPos, 0), stIntTuple_getPosition(seqPos, 1)); return 1; } //We have already explored this area, but no cycle. return 0; } stSortedSet_insert(started, seqPos); int64_t cycle =0; stIntTuple *nextSeqPos = stIntTuple_construct2( stIntTuple_get(seqPos, 0), stIntTuple_get(seqPos, 1) + 1); stSortedSet *column = stHash_search(adjacencyList, nextSeqPos); if(column != NULL) { //It is in the adjacency list, so we can do the recursion assert(stSortedSet_search(column, nextSeqPos) != NULL); stSortedSetIterator *it = stSortedSet_getIterator(column); stIntTuple *seqPos2; while((seqPos2 = stSortedSet_getNext(it)) != NULL) { cycle = cycle || dfs(adjacencyList, seqPos2, started, done); } stSortedSet_destructIterator(it); } stIntTuple_destruct(nextSeqPos); stSortedSet_insert(done, seqPos); return cycle; }
/* * Gets the position in sequence2 that the position in sequence1 must be greater than or equal to in the alignment */ static stIntTuple *getConstraint_greaterThan(stPosetAlignment *posetAlignment, int64_t sequence1, int64_t position1, int64_t sequence2) { stIntTuple *pos = stIntTuple_construct2(INT64_MAX, position1); //Get less than or equal stIntTuple *constraint = stSortedSet_searchLessThanOrEqual(getConstraintList(posetAlignment, sequence2, sequence1), pos); stIntTuple_destruct(pos); assert(constraint == NULL || position1 >= stIntTuple_get(constraint, 1)); return constraint; }
/* * This builds an adjacency list structure for the the sequences. Every sequence-position * has a column in the hash with which it can be aligned with. */ static stHash *buildAdjacencyList(stList *pairs, int64_t sequenceNumber) { stHash *hash = stHash_construct3((uint64_t (*)(const void *))stIntTuple_hashKey, (int (*)(const void *, const void *))stIntTuple_equalsFn, (void (*)(void *))stIntTuple_destruct, NULL); for(int64_t seq=0; seq<sequenceNumber; seq++) { for(int64_t position=0; position<MAX_SEQUENCE_SIZE; position++) { stIntTuple *seqPos = stIntTuple_construct2( seq, position); stSortedSet *column = stSortedSet_construct3((int (*)(const void *, const void *))stIntTuple_cmpFn, NULL); stSortedSet_insert(column, seqPos); stHash_insert(hash, seqPos, column); } } stListIterator *it = stList_getIterator(pairs); stIntTuple *pair; while((pair = stList_getNext(it)) != NULL) { stIntTuple *seqPos1 = stIntTuple_construct2( stIntTuple_get(pair, 0), stIntTuple_get(pair, 1)); stIntTuple *seqPos2 = stIntTuple_construct2( stIntTuple_get(pair, 2), stIntTuple_get(pair, 3)); stSortedSet *column1 = stHash_search(hash, seqPos1); assert(column1 != NULL); stSortedSet *column2 = stHash_search(hash, seqPos2); assert(column2 != NULL); if(column1 != column2) { //Merge the columns stSortedSetIterator *it2 = stSortedSet_getIterator(column2); stIntTuple *seqPos3; while((seqPos3 = stSortedSet_getNext(it2)) != NULL) { assert(stSortedSet_search(column1, seqPos3) == NULL); stSortedSet_insert(column1, seqPos3); assert(stHash_search(hash, seqPos3) == column2); stHash_insert(hash, seqPos3, column1); assert(stHash_search(hash, seqPos3) == column1); } stSortedSet_destructIterator(it2); stSortedSet_destruct(column2); } //Cleanup loop. stIntTuple_destruct(seqPos1); stIntTuple_destruct(seqPos2); } stList_destructIterator(it); return hash; }
static void test_stSet_insert(CuTest* testCase) { /* * Tests inserting already present keys. */ testSetup(); CuAssertTrue(testCase, stSet_search(set0, one) == one); stSet_insert(set0, one); CuAssertTrue(testCase, stSet_search(set0, one) == one); stSet_insert(set0, three); CuAssertTrue(testCase, stSet_search(set0, three) == three); stIntTuple *seven = stIntTuple_construct2(7, 7); CuAssertTrue(testCase, stSet_search(set0, seven) == NULL); stSet_insert(set0, seven); CuAssertTrue(testCase, stSet_search(set0, seven) == seven); stIntTuple_destruct(seven); testTeardown(); }
// copied from cPecanRealign struct PairwiseAlignment *convertAlignedPairsToPairwiseAlignment(char *seqName1, char *seqName2, double score, int64_t length1, int64_t length2, stList *alignedPairs) { //Make pairwise alignment int64_t pX = -1, pY = -1, mL = 0; //Create an end matched pair, which is used to ensure the alignment has the correct end indels. struct List *opList = constructEmptyList(0, (void (*)(void *)) destructAlignmentOperation); stList_append(alignedPairs, stIntTuple_construct2(length1, length2)); for (int64_t i = 0; i < stList_length(alignedPairs); i++) { stIntTuple *alignedPair = stList_get(alignedPairs, i); int64_t x = stIntTuple_get(alignedPair, 0); int64_t y = stIntTuple_get(alignedPair, 1); assert(x - pX > 0); assert(y - pY > 0); if (x - pX > 0 && y - pY > 0) { //This is a hack for filtering if (x - pX > 1) { //There is an indel. if (mL > 0) { listAppend(opList, constructAlignmentOperation(PAIRWISE_MATCH, mL, 0)); mL = 0; } listAppend(opList, constructAlignmentOperation(PAIRWISE_INDEL_X, x - pX - 1, 0)); } if (y - pY > 1) { if (mL > 0) { listAppend(opList, constructAlignmentOperation(PAIRWISE_MATCH, mL, 0)); mL = 0; } listAppend(opList, constructAlignmentOperation(PAIRWISE_INDEL_Y, y - pY - 1, 0)); } mL++; pX = x; pY = y; } } //Deal with a trailing match, but exclude the final match if (mL > 1) { listAppend(opList, constructAlignmentOperation(PAIRWISE_MATCH, mL - 1, 0)); } stIntTuple_destruct(stList_pop(alignedPairs)); //Construct the alignment struct PairwiseAlignment *pA = constructPairwiseAlignment(seqName1, 0, length1, 1, seqName2, 0, length2, 1, score, opList); return pA; }
// copied from cPecanRealign, which is sloppy. void *convertToAnchorPair(void *aPair, void *extraArg) { stIntTuple *i = stIntTuple_construct2(stIntTuple_get(aPair, 1), stIntTuple_get(aPair, 2)); stIntTuple_destruct(aPair); return i; }