13b584581e6d7b1860e0cab97adc3594b1899308 braney Mon Aug 7 12:05:10 2023 -0700 add instaPort to bigBed support diff --git src/hg/lib/liftOver.c src/hg/lib/liftOver.c index 0e69235..429199c 100644 --- src/hg/lib/liftOver.c +++ src/hg/lib/liftOver.c @@ -29,55 +29,57 @@ static char otherStrand(char c) /* Swap +/- */ { if (c == '-') return '+'; else if (c == '+') return '-'; else return c; } // The maximum number of words per line that can be lifted: #define LIFTOVER_MAX_WORDS 2048 +void liftOverAddChainHash(struct hash *chainHash, struct chain *chain) +/* Add this chain to the hash of chains used by remapBlockedBed */ +{ +struct chromMap *map; + +if ((map = hashFindVal(chainHash, chain->tName)) == NULL) + { + AllocVar(map); + map->bk = binKeeperNew(0, chain->tSize); + hashAddSaveName(chainHash, chain->tName, map, &map->name); + } +binKeeperAdd(map->bk, chain->tStart, chain->tEnd, chain); +} + void readLiftOverMap(char *fileName, struct hash *chainHash) /* Read map file into hashes. */ { - struct lineFile *lf; if (udcIsLocal(fileName)) lf = lineFileOpen(fileName, TRUE); else lf = netLineFileOpen(fileName); struct chain *chain; -struct chromMap *map; -int chainCount = 0; while ((chain = chainRead(lf)) != NULL) - { - if ((map = hashFindVal(chainHash, chain->tName)) == NULL) - { - AllocVar(map); - map->bk = binKeeperNew(0, chain->tSize); - hashAddSaveName(chainHash, chain->tName, map, &map->name); - } - binKeeperAdd(map->bk, chain->tStart, chain->tEnd, chain); - ++chainCount; - } + liftOverAddChainHash(chainHash, chain); } static struct binElement *findRange(struct hash *chainHash, char *chrom, int start, int end) /* Find elements that intersect range. */ { struct chromMap *map = hashFindVal(chainHash, chrom); if (map == NULL) return NULL; return binKeeperFind(map->bk, start, (end == start) ? end + 1 : end); } static int chainAliSize(struct chain *chain) /* Return size of all blocks in chain. */ { @@ -699,38 +701,49 @@ struct liftRange /* A start/stop pair. */ { struct liftRange *next; int start; /* Start 0 based */ int end; /* End, non-inclusive. */ int val; /* Some value (optional). */ }; static struct liftRange *bedToRangeList(struct bed *bed) /* Convert blocks in bed to a range list. */ { struct liftRange *range, *rangeList = NULL; int bedStart = bed->chromStart; int i, count = bed->blockCount, start; +if (count == 0) + { + AllocVar(range); + start = bed->chromStart; + range->start = start; + range->end = bed->chromEnd; + slAddHead(&rangeList, range); + } +else + { for (i=0; i<count; ++i) { AllocVar(range); start = bedStart + bed->chromStarts[i]; range->start = start; range->end = start + bed->blockSizes[i]; slAddHead(&rangeList, range); } + } slReverse(&rangeList); return rangeList; } static struct liftRange *tPslToRangeList(struct psl *psl) /* Convert target blocks in psl to a range list. */ { struct liftRange *range, *rangeList = NULL; int i, count = psl->blockCount, start; for (i=0; i<count; ++i) { AllocVar(range); start = psl->tStarts[i]; range->start = start; range->end = start + psl->blockSizes[i]; @@ -983,32 +996,37 @@ { struct liftRange *range; for (range = rangeList; range != NULL; range = range->next) fprintf(f, "%d,", range->end - range->start); fprintf(f, "\n"); for (range = rangeList; range != NULL; range = range->next) fprintf(f, "%d,", range->start); fprintf(f, "\n"); } #endif /* DEBUG */ static int sumBedBlocks(struct bed *bed) /* Calculate sum of all block sizes in bed. */ { int i, total = 0; +if (bed->blockCount == 0) + total = bed->chromEnd - bed->chromStart; +else + { for (i=0; i<bed->blockCount; ++i) total += bed->blockSizes[i]; + } return total; } static int sumPslBlocks(struct psl *psl) /* Calculate sum of all block sizes in psl. */ { int i, total = 0; for (i=0; i<psl->blockCount; ++i) total += psl->blockSizes[i]; return total; } static struct liftRange *reverseRangeList(struct liftRange *rangeList, int chromSize) /* Return reverse-complemented rangeList. */ { @@ -1028,45 +1046,49 @@ *retError = NULL; /* See if best one is good enough. */ if (chain->score < minMatch * bedSize) *retError = "Partially deleted in new"; struct liftRange *rangeList = *pRangeList, *badRanges = NULL, *range; int thickStart = bed->thickStart; int thickEnd = bed->thickEnd; if (*retError == NULL) remapRangeList(chain, &rangeList, &thickStart, &thickEnd, minBlocks, fudgeThick, &rangeList, &badRanges, retError); /* Convert rangeList back to bed blocks. Also calculate start and end. */ if (*retError == NULL) { - int i, start, end = 0; + int i, start, end = rangeList->end; if (chain->qStrand == '-') { rangeList = reverseRangeList(rangeList, chain->qSize); reverseIntRange(&thickStart, &thickEnd, chain->qSize); bed->strand[0] = otherStrand(bed->strand[0]); } bed->chromStart = start = rangeList->start; + //if (slCount(rangeList) > 1) + if (bed->blockSizes != NULL) + { bed->blockCount = slCount(rangeList); for (i=0, range = rangeList; range != NULL; range = range->next, ++i) { end = range->end; bed->blockSizes[i] = end - range->start; bed->chromStarts[i] = range->start - start; } + } if (!sameString(chain->qName, chain->tName)) { freeMem(bed->chrom); bed->chrom = cloneString(chain->qName); } bed->chromEnd = end; bed->thickStart = thickStart; bed->thickEnd = thickEnd; } slFreeList(&rangeList); slFreeList(&badRanges); *pRangeList = NULL; } char *remapBlockedBed(struct hash *chainHash, struct bed *bed,