39e533cc9ffcb46d9c484dc09a387a031a739391
Merge parents 1c86690 f642bab
kate
  Mon Sep 24 16:35:53 2018 -0700
Updating from master

diff --cc src/hg/hgTracks/interactTrack.c
index 1365ee9,ce8ee7a..da67bef
--- src/hg/hgTracks/interactTrack.c
+++ src/hg/hgTracks/interactTrack.c
@@@ -100,147 -99,30 +100,153 @@@
              {
              if (!(sOnScreen || tOnScreen))
                  continue;
              }
          }
      slAddHead(&filteredItems, inter);
      }
  
  slReverse(&filteredItems);
  // consider sorting by score/value so highest scored items draw last (on top)
  if (slCount(filteredItems) != count)
      labelTrackAsFiltered(tg);
  tg->items = filteredItems;
  }
  
 +void interactDrawLeftLabels(struct track *tg, int seqStart, int seqEnd,
 +    struct hvGfx *hvg, int xOff, int yOff, int width, int height,
 +    boolean withCenterLabels, MgFont *font,
 +    Color color, enum trackVisibility vis)
 +/* Override default */
 +{
 +}
 +
 +void interactFreeItems(struct track *tg)
 +/* Free up interact items track */
 +{
 +interactFreeList((struct interact **)(&tg->items));
 +}
 +
 +static boolean isBedMode(struct track *tg)
 +/* Pack and squish modes display using BED linked features code */
 +{
 +return tg->visibility == tvPack || tg->visibility == tvSquish;
 +}
 +
 +static struct linkedFeatures *interactToLf(struct interact *inter, boolean doColor)
 +/* Convert interact BED to linkedFeatures */
 +{
 +struct bed *bed = interactToBed(inter);
 +struct linkedFeatures *lf = lfFromBed(bed);
 +if (doColor)
 +    {
 +    lf->extra = (void *)USE_ITEM_RGB;   /* signal for coloring */
 +    lf->filterColor = bed->itemRgb;
 +    }
 +bedFree(&bed);
 +// TODO: use lfFromBedExtra with scoreMin, scoreMax ?
 +return lf;
 +}
 +
++static boolean isMergeMode(struct track *tg)
++/* Packed mode with merging on targets */
++{
++return cartBoolean(cart, "interactTargetMerge");
++}
++
 +void interactLoadItems(struct track *tg)
 +/* Load interact items in interact format */
 +{
 +loadAndFilterItems(tg);
 +if (isBedMode(tg))
 +    {
 +    // convert to BEDs for linked feature display
 +    struct interact *inters = tg->items, *inter;
 +    struct linkedFeatures *lfs = NULL, *lf;
 +    struct hash *intersMerge = hashNew(0);
-     boolean doMerge = cartVarExists(cart, "interactTargetMerge");
++    boolean doMerge = isMergeMode(tg);
 +    boolean doColor = !tg->colorShades;
 +    for (inter = inters; inter; inter = inter->next)
 +        {
 +        if (doMerge)
 +            {
 +            lf = (struct linkedFeatures *) hashFindVal(intersMerge, inter->targetName);
 +            if (lf)
 +                {
 +                // add a simple feature for this source to the linked feature
 +                struct simpleFeature *sf = NULL;
 +                AllocVar(sf);
 +                sf->start = inter->sourceStart;
 +                sf->end = inter->sourceEnd;
 +                struct simpleFeature *sfs = lf->components;
 +                slAddHead(&sfs, sf);
 +                lf->components = sfs;
 +                // TODO: consider averaging score
 +
 +/*
 +                // FIXME: just for demo
 +                struct bed *tempBed = interactToBed(inter);
 +                if (orientFromChar(tempBed->strand[0]) != lf->orientation)
 +                    lf->orientation = 0;
 +                bedFree(&tempBed);
 +*/
 +                }
 +            else
 +                {
 +                // create a linked feature for this target
 +                lf = interactToLf(inter, doColor);
 +                lf->name = inter->targetName;
 +                lf->tallStart = inter->targetStart;
 +                lf->tallEnd = inter->targetEnd;
 +                lf->orientation = 0;
 +                hashAdd(intersMerge, lf->name, lf);
 +                }
 +            }
 +        else 
 +            {
 +            lf = interactToLf(inter, doColor);
 +            slAddHead(&lfs, lf);
 +            }
 +        }
 +    if (doMerge)
 +        {
 +        // sort simplefeatures and adjust bounds of merged features
 +        struct hashEl *el, *els = hashElListHash(intersMerge);
 +        for (el = els; el; el = el->next)
 +            {
 +            lf = (struct linkedFeatures *)el->val;
 +            linkedFeaturesSortAndBound(lf);
 +            slAddHead(&lfs, lf);
 +            }
 +        slSort(&lfs, linkedFeaturesCmp);
 +        }
 +    else
 +        {
 +        slReverse(&lfs);
 +        }
 +    tg->items = lfs;
 +    // TODO: consider freeing interact items
 +    }
 +else
 +    {
 +    tg->mapsSelf = TRUE;
 +    tg->totalHeight = interactTotalHeight;
 +    tg->drawLeftLabels = interactDrawLeftLabels;
 +    tg->freeItems = interactFreeItems;
 +    }
 +}
 +
  char *interactMouseover(struct interact *inter, char *otherChrom)
  /* Make mouseover text for an interaction */
  {
  struct dyString *ds = dyStringNew(0);
  if (isEmptyTextField(inter->name))
      {
      if (!isEmptyTextField(inter->exp))
          dyStringPrintf(ds, "%s ", inter->exp);
      if (otherChrom)
          dyStringPrintf(ds, "%s", otherChrom);
      else
          {
          char buf[4096];
          sprintLongWithCommas(buf, inter->chromEnd - inter->chromStart);
          dyStringPrintf(ds, "%s bp", buf);
@@@ -680,56 -571,39 +686,59 @@@
              ellipseOrient = ELLIPSE_TOP;
              yLeft = yOff + tg->height - peakHeight;
              yTop = yOff + tg->height + peakHeight;
              }
          hvGfxEllipseDraw(hvg, lowerX, yLeft, upperX, yTop, color, ellipseOrient,
                                  isReversed && doDashes);
          // draw grab box and map box on peak
          int maxY = peakHeight + yOff;
          int peakX = ((upperX - lowerX + 1) / 2) + lowerX;
          drawPeakMapbox(tg, hvg, inter->chromStart, inter->chromEnd, inter->name, statusBuf,
                              peakX, maxY, peakColor, highlightColor, drawUp);
          }
      }
  }
  
 -void interactDrawLeftLabels(struct track *tg, int seqStart, int seqEnd,
 -    struct hvGfx *hvg, int xOff, int yOff, int width, int height,
 -    boolean withCenterLabels, MgFont *font,
 -    Color color, enum trackVisibility vis)
 -/* Override default */
 +void interactLinkedFeaturesDrawAt(struct track *tg, void *item,
 +                          struct hvGfx *hvg, int xOff, int y, double scale,
 +                          MgFont *font, Color color, enum trackVisibility vis)
 +/* Draw a item with target in contrasting color */
 +{
 +linkedFeaturesDrawAt(tg, item, hvg, xOff, y, scale, font, color, vis);
 +
++if (isMergeMode(tg))
+     {
 +    struct linkedFeatures *lf = item;
 +    // TODO: use magenta if track isn't colored ?
 +    drawScaledBox(hvg, lf->tallStart, lf->tallEnd, scale, xOff, y, tg->heightPer, MG_BLACK);
 +    }
++}
 +
 +void interactDrawItems(struct track *tg, int seqStart, int seqEnd,
 +        struct hvGfx *hvg, int xOff, int yOff, int width, 
 +        MgFont *font, Color color, enum trackVisibility vis)
 +/* Draw a list of interact structures. */
 +{
 +if (isBedMode(tg))
 +    {
 +    tg->drawItemAt = interactLinkedFeaturesDrawAt;
 +    linkedFeaturesDraw(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis);
 +    }
 +else
 +    drawInteractItems(tg, seqStart, seqEnd, hvg, xOff, yOff, width, font, color, vis);
  }
  
  void interactMethods(struct track *tg)
  /* Interact track type methods */
  {
 +tg->bedSize = 12;
 +linkedFeaturesMethods(tg);         // for pack and squish modes 
  tg->loadItems = interactLoadItems;
  tg->drawItems = interactDrawItems;
 -tg->drawLeftLabels = interactDrawLeftLabels;
 -tg->totalHeight = interactTotalHeight;
 -tg->mapsSelf = TRUE;
  }
  
  void interactCtMethods(struct track *tg)
  /* Interact track methods for custom track */
  {
  interactMethods(tg);
  }