ebb119f63d024ea706a6922adf67bb9956d5f049 kate Tue Sep 3 16:33:52 2019 -0700 More fixes for multi-region (cross-chrom and non-cluster mode). refs #22422 diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index 45c4a7f..2d9d289 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -465,50 +465,54 @@ struct window *w; struct track *tgSave = tg; // find out which items are the same, // and belong on the same line with (probably one) label: struct hash *sameItem = newHash(10); // TODO estimate this as log base 2 # items in all windows //struct hash *itemDone = newHash(10); // TODO I do not need this yet in this version if no dupes. for(w=windows,tg=tgSave; w; w=w->next,tg=tg->nextWindow) { // Have to init these here // save old spaceSaver until callback on another window later struct spaceSaver *ssOld = tg->ss; tg->ss = spaceSaverNew(0, fullInsideWidth, maxCount); // actual params do not matter, just using ss->nodeList. tg->ss->next = ssOld; + boolean useItemNameAsKey = isTypeUseItemNameAsKey(tg); + boolean useMapItemNameAsKey = isTypeUseMapItemNameAsKey(tg); char *chrom = w->chromName; for (item = tg->items; item != NULL; item = item->next) { int baseStart = tg->itemStart(tg, item); int baseEnd = tg->itemEnd(tg, item); if (baseStart < w->winEnd && baseEnd > w->winStart) { // it intersects the window char *mapItemName = tg->mapItemName(tg, item); char key[1024]; // TODO I am making the key based on chrom, so no items will be aligned on the same line // that are in different chromosomes. If the itemName is unique per chromosome or in other ways // then itemName alone could be the key. // TODO we know that for some tracks there is great duplication, names are not unique, // even this key of position+name will not be unique enough. // But fixing that may require creating a new function that converts the item into a string // and then use that to prove uniqueness, or as near as can be had. // // For now, this should be good enough to illustrate the basic behavior we want to see. - if (isTypeUseItemNameAsKey(tg)) + if (useItemNameAsKey) safef(key, sizeof key, "%s", tg->itemName(tg, item)); + else if (useMapItemNameAsKey) + safef(key, sizeof key, "%s", mapItemName); else safef(key, sizeof key, "%s:%d-%d %s", chrom, baseStart, baseEnd, mapItemName); struct hashEl *hel = hashLookup(sameItem, key); struct sameItemNode *sin; if (hel) { sin = (struct sameItemNode *)hel->val; if (sin->window == w) { // dupe found for key, all windows should have the same number of dupes //char *itemName = tg->itemName(tg, item); //char *itemDataName = getItemDataName(tg, itemName); //char *mapItemName = tg->mapItemName(tg, item); //warn("duplicate keys in same window.\n key=[%s] itemDataName=%s mapItemName=%s w=%lu sin->window=%lu", // TODO //key, itemDataName, mapItemName, (unsigned long) w, (unsigned long) sin->window); @@ -528,45 +532,48 @@ } } // do spaceSaver layout struct spaceSaver *ss; ss = spaceSaverNew(0, fullInsideWidth, maxCount); ss->vis = vis; for(w=windows,tg=tgSave; w; w=w->next,tg=tg->nextWindow) { // save these values so we can detect vis and window changes tg->ss->vis = vis; tg->ss->window = w; char *chrom = w->chromName; // int winOffset = w->insideX - fullInsideX; // no longer needed double scale = (double)w->insideWidth/(w->winEnd - w->winStart); - boolean useTypeItemNameAsKey = isTypeUseItemNameAsKey(tg); + boolean useItemNameAsKey = isTypeUseItemNameAsKey(tg); + boolean useMapItemNameAsKey = isTypeUseMapItemNameAsKey(tg); for (item = tg->items; item != NULL; item = item->next) { // TODO match items from different windows by using item start end and name in hash? int baseStart = tg->itemStart(tg, item); int baseEnd = tg->itemEnd(tg, item); if (baseStart < w->winEnd && baseEnd > w->winStart) { // it intersects the window char *mapItemName = tg->mapItemName(tg, item); char key[1024]; // TODO see key caveats above // For now, this should be good enough to illustrate the basic behavior we want to see. - if (useTypeItemNameAsKey) + if (useItemNameAsKey) safef(key, sizeof key, "%s", tg->itemName(tg, item)); + else if (useMapItemNameAsKey) + safef(key, sizeof key, "%s", mapItemName); else safef(key, sizeof key, "%s:%d-%d %s", chrom, baseStart, baseEnd, mapItemName); struct hashEl *hel = hashLookup(sameItem, key); if (!hel) { if (tg->networkErrMsg) // probably timed-out before thread finished adding more items. break; errAbort("unexpected error: lookup of key [%s] in sameItem hash failed.", key); } struct sameItemNode *sin = (struct sameItemNode *)hel->val; if (!sin) errAbort("sin empty (hel->val)!"); if (!sin->done) { // still needs to be done slReverse(&hel->val);