8c908f948b09826c6cb4452ee5b282aca41be85e
galt
  Tue Dec 8 21:52:59 2015 -0800
Multi-region (exonMostly). This work allows people to look at virtual chromosomes from a list of regions and then navigate and perform all of the usual functions on it.

diff --git src/hg/hgTracks/hgTracks.h src/hg/hgTracks/hgTracks.h
index f8239fe..41fe675 100644
--- src/hg/hgTracks/hgTracks.h
+++ src/hg/hgTracks/hgTracks.h
@@ -103,31 +103,31 @@
 
     int (*itemHeight)(struct track *tg, void *item);
     /* Return height of one item. */
 
     int (*itemRightPixels)(struct track *tg, void *item);
     /* Return number of pixels needed to right of item for additional labeling. (Optional) */
 
     void (*drawItems)(struct track *tg, int seqStart, int seqEnd,
 	struct hvGfx *hvg, int xOff, int yOff, int width,
 	MgFont *font, Color color, enum trackVisibility vis);
     /* Draw item list, one per track. */
 
     void (*drawItemAt)(struct track *tg, void *item, struct hvGfx *hvg,
         int xOff, int yOff, double scale,
 	MgFont *font, Color color, enum trackVisibility vis);
-    /* Draw a single option.  This is optional, but if it's here
+    /* Draw a single item.  This is optional, but if it's here
      * then you can plug in genericDrawItems into the drawItems,
      * which takes care of all sorts of things including packing. */
 
     int (*itemStart)(struct track *tg, void *item);
     /* Return start of item in base pairs. */
 
     int (*itemEnd)(struct track *tg, void *item);
     /* Return end of item in base pairs. */
 
     void (*freeItems)(struct track *tg);
     /* Free item list. */
 
     Color (*itemColor)(struct track *tg, void *item, struct hvGfx *hvg);
     /* Get color of item (optional). */
 
@@ -205,65 +205,102 @@
     /* fill in left label drawing area */
     Color labelColor;   /* Fixed color for the track label (optional) */
     void (*drawLeftLabels)(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);
 
     struct track *subtracks;   /* list of subsidiary tracks that are
                                 loaded and drawn by this track.  This
                                 is used for "composite" tracks, such
                                 as "mafWiggle */
     struct track *parent;	/* Parent track if any */
     struct track *prevTrack;    // if not NULL, points to track immediately above in the image.
                                 //    Needed by ConditionalCenterLabel logic
 
-    void (*nextPrevExon)(struct track *tg, struct hvGfx *hvg, void *item, int x, int y, int w, int h, boolean next);
+    boolean (*nextPrevExon)(struct track *tg, struct hvGfx *hvg, void *item, int x, int y, int w, int h, boolean next);
     /* Function will draw the button on a track item and assign a map */
     /* box to it as well, so that a click will move the browser window */
     /* to the next (or previous if next==FALSE) item. This is meant to */
     /* jump to parts of an item already partially in the window but is */
     /* hanging off the edge... e.g. the next exon in a gene. */
 
     void (*nextPrevItem)(struct track *tg, boolean next);
     /* If this function is given, it can dictate where the browser loads */
     /* up based on whether a next-item button on the longLabel line of */
     /* the track was pressed (as opposed to the next-item buttons on the */
     /* track items themselves... see nextPrevExon() ). This is meant for */
     /* going to the next/previous item currently unseen in the browser, */
-    /* e.g. the next gene. SO FAR THIS IS UNIMPLEMENTED. */
+    /* e.g. the next gene. */
 
     char *(*itemDataName)(struct track *tg, char *itemName);
     /* If not NULL, function to translated an itemName into a data name.
      * This is can be used for looking up sequence, CDS, etc. It is used
      * to support item names that have uniqueness identifiers added to deal
      * with multiple alignments.  The resulting value should *not* be freed,
      * and it should be assumed that it might only remain valid for a short
      * period of time.*/
 
     int loadTime;	/* Time it takes to load (for performance tuning) */
     int drawTime;	/* Time it takes to draw (for performance tuning) */
 
     enum enumBool remoteDataSource; /* The data for this track is from a remote source */
                    /* Slow retrieval means image can be rendered via an AJAX callback. */
     boolean customTrack; /* Need to explicitly declare this is a custom track */
     boolean syncChildVisToSelf;	/* If TRUE sync visibility to of children to self. */
     char *networkErrMsg;        /* Network layer error message */
     boolean parallelLoading;    /* If loading in parallel, usually network resources. */
     struct bbiSummaryElement *summary;  /* for bigBed */
-    struct bbiSummaryElement *sumAll;   /* for bigBid */
+    struct bbiSummaryElement *sumAll;   /* for bigBed */
     boolean drawLabelInBox;     /* draw labels into the features instead of next to them */
+    
+    struct track *nextWindow;   /* Same track in next window's track list. */
+    struct track *prevWindow;   /* Same track in prev window's track list. */
+
+    // Fixed-width non-proportional tracks
+    void (*nonPropDrawItemAt)(struct track *tg, void *item, struct hvGfx *hvg,
+        int xOff, int yOff, double scale,
+	MgFont *font, Color color, enum trackVisibility vis);
+    /* Draw a single Non-proportional fixed-width item.  Such as gtexGene.
+     * This is method is optional, but if it's here
+     * then you can plug in genericDrawItems into the drawItems,
+     * which takes care of all sorts of things including packing. */
+
+    int (*nonPropPixelWidth)(struct track *tg, void *item);
+    /* Return the width in pixels of the non-proportional part of track, e.g. gtexGene graphic */
+
+    };
+
+struct window  // window in multiwindow image
+    {
+    struct window *next;   // Next on list.
+
+    // These two were experimental and will be removed soon:
+    char *organism;        /* Name of organism */
+    char *database;        /* Name of database */
+
+    char *chromName;
+    int winStart;           // in bases
+    int winEnd;
+    int insideX;            // in pixels
+    int insideWidth;
+    long virtStart;         // in bases on virt chrom
+    long virtEnd;
+
+    boolean regionOdd;      // window comes from odd region? or even? for window separator coloring
+
+    struct track *trackList;   // track list for window
     };
 
 
 typedef void (*TrackHandler)(struct track *tg);
 
 int trackPriCmp(const void *va, const void *vb);
 /* Compare for sort based on priority */
 
 boolean trackIsCompositeWithSubtracks(struct track *track);
 /* Temporary function until all composite tracks point to their own children */
 
 struct trackRef
 /* A reference to a track. */
     {
     struct trackRef *next;	/* Next in list. */
@@ -343,49 +380,121 @@
     char *name;                      /* name for series of linked features */
     int start, end;                     /* Start/end in browser coordinates. */
     int orientation;                    /* Orientation. */
     int grayIx;				/* Gray index (average of features) */
     boolean noLine;                     /* if true don't draw line connecting features */
     struct linkedFeatures *features;    /* linked features for a series */
 };
 
 struct knownGenesExtra
 /* need more than 1 string in linkedFeatures extra field */
     {
     char *hgg_prot;             /* protein ID */
     char *name;                 /* name to be used on label */
     };
 
-/* global GSID subject list */
 struct gsidSubj
+/* global GSID subject list */
     {
     struct gsidSubj  *next;
     char *subjId;
     };
 
-/* global GSID sequence list */
 struct gsidSeq
+/* global GSID sequence list */
     {
     struct gsidSeq  *next;
     char *seqId;
     char *subjId;
     };
 
+
+struct virtRegion
+/* virtual chromosome structure */
+    {
+    struct virtRegion *next;
+    char *chrom;
+    int start;
+    int end;
+    char strand[2];	/* + or - for strand */
+    };
+
+struct virtChromRegionPos
+/* virtual chromosome region position*/
+    {
+    long virtPos;
+    struct virtRegion *virtRegion;
+    };
+
+struct positionMatch
+/* virtual chroom position that matches or overlaps search query chrom,start,end */
+ {
+ struct positionMatch *next;
+ long virtStart;
+ long virtEnd;
+ };
+
+
+extern struct virtRegion *virtRegionList;
+extern struct virtChromRegionPos *virtChrom; // Array
+extern int virtRegionCount;
+extern long virtWinStart;  // start of virtual window in bases
+extern long virtWinEnd;    //   end of virtual window in bases
+extern long defaultVirtWinStart;  // default start of virtual window in bases
+extern long defaultVirtWinEnd;    // default end   of virtual window in bases
+extern long virtWinBaseCount;  /* Number of bases in windows, also virtWinEnd - virtWinStart. */
+extern long virtSeqBaseCount; // all bases in virt chrom
+//extern char *virtPosition;          /* Name of virtual position. TODO Remove? */
+extern char *virtChromName;         /* Name of virtual chrom */
+extern boolean virtMode;            /* Are we in virtual chrom mode? */
+extern boolean virtChromChanged;     /* Has the virtChrom changed? */
+extern boolean emAltHighlight;      /* Highlight alternativing regions in virt view? */
+extern int emPadding;               /* # bases padding for exon-mostly regions */
+extern char *emGeneTable;           /* Gene table to use for exon mostly */
+extern struct track *emGeneTrack;   /* Track for gene table for exon mostly */
+extern struct rgbColor vertWindowSeparatorColor; /* color for vertical windows separator */
+extern char *multiRegionsBedUrl;       /* URL to bed regions list */
+
+// demo2
+extern int demo2NumWindows;
+extern int demo2WindowSize;
+extern int demo2StepSize;
+
+// singleTrans (single transcript)
+extern char *singleTransId; 
+
+// singleAltHaplos (one alternate haplotype)
+extern char *singleAltHaploId; 
+
+extern char *virtModeType;         /* virtual chrom mode type */
+extern char *lastVirtModeType;
+extern char *virtModeShortDescr;   /* short description of virt mode */
+extern char *virtModeExtraState;   /* Other settings that affect the virtMode state such as padding or some parameter */
+extern char *lastVirtModeExtraState;
+extern struct cart *lastDbPosCart;     /* store settings for use in lastDbPos and hgTracks.js setupHistory */
+
 extern char *excludeVars[];
 extern struct trackLayout tl;
 extern struct jsonElement *jsonForClient;
 
+/* multiple windows */
+extern struct window *windows;        // list of windows in image
+extern struct window *currentWindow;  // current window
+extern bool trackLoadingInProgress;  // flag to delay ss layout until all windows are ready.
+extern int fullInsideX;      // full-image insideX 
+extern int fullInsideWidth;  // full-image insideWidth 
+
 extern struct cart *cart; /* The cart where we keep persistent variables. */
 extern struct hash *oldVars;       /* List of vars from previous cart. */
 extern struct track *trackList;    /* List of all tracks. */
 extern struct hash *trackHash; /* Hash of the tracks by their name. */
 extern char *chromName;	  /* Name of chromosome sequence . */
 extern char *database;	  /* Name of database we're using. */
 extern char *organism;	  /* Name of organism we're working on. */
 extern char *browserName;              /* Test or public browser */
 extern char *organization;             /* UCSC or MGC */
 extern int winStart;	  /* Start of window in sequence. */
 extern int winEnd;	  /* End of window in sequence. */
 extern int maxItemsInFullTrack;  /* Maximum number of items displayed in full */
 extern char *position; 		/* Name of position. */
 extern int leftLabelWidthDefaultChars;   /* default number of characters allowed for left label */
 extern int leftLabelWidthChars;   /* number of characters allowed for left label */
@@ -485,44 +594,44 @@
 /* Return 1 or -1 in place of + or - */
 
 enum trackVisibility limitVisibility(struct track *tg);
 /* Return default visibility limited by number of items. */
 
 char *hgcNameAndSettings();
 /* Return path to hgc with variables to store UI settings. */
 
 void mapBoxHc(struct hvGfx *hvg, int start, int end, int x, int y, int width, int height,
 	char *group, char *item, char *statusLine);
 /* Print out image map rectangle that would invoke the htc (human track click)
  * program. */
 
 void mapBoxReinvoke(struct hvGfx *hvg, int x, int y, int width, int height,
 		    struct track *track, boolean toggle, char *chrom,
-		    int start, int end, char *message, char *extra);
+		    long start, long end, char *message, char *extra);
 /* Print out image map rectangle that would invoke this program again.
  * If track is non-NULL then put that track's id in the map item.
  * if toggle is true, then toggle track between full and dense.
  * If chrom is non-null then jump to chrom:start-end.
  * Add extra string to the URL if it's not NULL */
 
 void mapBoxToggleVis(struct hvGfx *hvg, int x, int y, int width, int height,
 	struct track *curGroup);
 /* Print out image map rectangle that would invoke this program again.
  * program with the current track expanded. */
 
 void mapBoxJumpTo(struct hvGfx *hvg, int x, int y, int width, int height, struct track *toggleGroup,
-		  char *newChrom, int newStart, int newEnd, char *message);
+		  char *newChrom, long newStart, long newEnd, char *message);
 /* Print out image map rectangle that would invoke this program again
  * at a different window. */
 
 void mapBoxHgcOrHgGene(struct hvGfx *hvg, int start, int end, int x, int y, int width, int height,
                        char *track, char *item, char *statusLine, char *directUrl, boolean withHguid,
                        char *extra);
 /* Print out image map rectangle that would invoke the hgc (human genome click)
  * program. */
 
 void genericMapItem(struct track *tg, struct hvGfx *hvg, void *item,
 		    char *itemName, char *mapItemName, int start, int end,
 		    int x, int y, int width, int height);
 /* This is meant to be used by genericDrawItems to set to tg->mapItem in */
 /* case tg->mapItem isn't set to anything already. */
 
@@ -534,37 +643,34 @@
 #endif
 ;
 
 double scaleForWindow(double width, int seqStart, int seqEnd);
 /* Return the scale for the window. */
 
 double scaleForPixels(double pixelWidth);
 /* Return what you need to multiply bases by to
  * get to scale of pixel coordinates. */
 
 void drawScaledBox(struct hvGfx *hvg, int chromStart, int chromEnd,
 	double scale, int xOff, int y, int height, Color color);
 /* Draw a box scaled from chromosome to window coordinates.
  * Get scale first with scaleForPixels. */
 
-void drawScaledBoxBlend(struct hvGfx *hvg, int chromStart, int chromEnd,
-	double scale, int xOff, int y, int height, Color color);
-/* Draw a box scaled from chromosome to window coordinates.
- * Get scale first with scaleForPixels.
- * use colorBin to collect multiple colors for the same pixel, choose
- * majority color, break ties by blending the colors.
- * Yellow and red are blended as brown, other colors not implemented.*/
+void drawScaledBoxLabel(struct hvGfx *hvg,
+     int chromStart, int chromEnd, double scale,
+     int xOff, int y, int height, Color color, MgFont *font,  char *label);
+/* Draw a box scaled from chromosome to window coordinates and draw a label onto it. */
 
 Color whiteIndex();
 /* Return index of white. */
 
 Color blackIndex();
 /* Return index of black. */
 
 Color grayIndex();
 /* Return index of gray. */
 
 Color lightGrayIndex();
 /* Return index of light gray. */
 
 Color veryLightGrayIndex();
 /* Return index of very light gray. */
@@ -651,31 +757,31 @@
 
 void bedDrawSimple(struct track *tg, int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width,
         MgFont *font, Color color, enum trackVisibility vis);
 /* Draw simple Bed items. */
 
 typedef struct slList *(*ItemLoader)(char **row);
 
 void bedLoadItemByQuery(struct track *tg, char *table, char *query, ItemLoader loader);
 /* Generic tg->item loader. If query is NULL use generic
  hRangeQuery(). */
 
 void bedLoadItem(struct track *tg, char *table, ItemLoader loader);
 /* Generic tg->item loader. */
 
-void simpleBedNextPrevEdge(struct track *tg, struct hvGfx *hvg, void *item, int x, int y, int w,
+boolean simpleBedNextPrevEdge(struct track *tg, struct hvGfx *hvg, void *item, int x, int y, int w,
 			   int h, boolean next);
 /* Like linkedFeaturesNextPrevItem, but for simple bed which has no block structure so
  * this simply zaps us to the right/left edge of the feature.  Arrows have already been
  * drawn; here we figure out coords and draw a mapBox. */
 
 void loadLinkedFeaturesWithLoaders(struct track *tg, struct slList *(*itemLoader)(char **row),
 				   struct linkedFeatures *(*lfFromWhatever)(struct slList *item),
 				   char *scoreColumn, char *moreWhere,
                                    boolean (*itemFilter)(struct slList *item));
 /* Make a linkedFeatures loader by providing three functions: (1) a regular */
 /* item loader found in all autoSql modules, (2) a custom myStruct->linkedFeatures */
 /* translating function, and (3) a function to free the thing loaded in (1). */
 
 struct linkedFeatures *linkedFeaturesFromGenePred(struct track *tg, struct genePred *gp, boolean extra);
 /* construct a linkedFeatures object from a genePred */
@@ -1094,41 +1200,30 @@
 /* Draw linked features series items. */
 
 struct linkedFeaturesSeries *lfsFromColoredExonBed(struct bed *bed);
 /* Convert a single BED 14 thing into a special linkedFeaturesSeries */
 /* where each linkedFeatures is a colored block. */
 
 void makeRedGreenShades(struct hvGfx *hvg);
 /* Makes some colors for the typical red/green microarray spectrum. */
 
 void linkedFeaturesSeriesMethods(struct track *tg);
 
 void lfsMapItemName(struct track *tg, struct hvGfx *hvg, void *item, char *itemName,
                     char *mapItemName, int start, int end,
 		    int x, int y, int width, int height);
 
-void drawScaledBoxSample(struct hvGfx *hvg,
-        int chromStart, int chromEnd, double scale,
-        int xOff, int y, int height, Color color,
-        int score);
-/* Draw a box scaled from chromosome to window coordinates. */
-
-void drawScaledBoxSampleLabel(struct hvGfx *hvg,
-     int chromStart, int chromEnd, double scale,
-     int xOff, int y, int height, Color color, MgFont *font,  char *label);
-/* Draw a box scaled from chromosome to window coordinates and draw a label onto it. */
-
 struct track *trackFromTrackDb(struct trackDb *tdb);
 /* Create a track based on the tdb */
 
 int spreadStringCharWidth(int width, int count);
 
 Color getOrangeColor();
 /* Return color used for insert indicators in multiple alignments */
 
 Color getBlueColor();
 Color getChromBreakBlueColor();
 Color getChromBreakGreenColor();
 
 void linkedFeaturesDrawAt(struct track *tg, void *item,
                           struct hvGfx *hvg, int xOff, int y, double scale,
                           MgFont *font, Color color, enum trackVisibility vis);
@@ -1167,30 +1262,33 @@
 
 struct hash *makeGlobalTrackHash(struct track *trackList);
 /* Create a global track hash and returns a pointer to it. */
 
 void makeActiveImage(struct track *trackList, char *psOutput);
 /* Make image and image map. */
 
 void configPage();
 /* Put up configuration page. */
 
 void configPageSetTrackVis(int vis);
 /* Do config page after setting track visibility. If vis is -2, then visibility
  * is unchanged.  If -1 then set visibility to default, otherwise it should
  * be tvHide, tvDense, etc. */
 
+void configMultiRegionPage();
+/* Put up multi-region configuration page. */
+
 struct track *trackNew();
 /* Allocate track . */
 
 void bedMethods(struct track *tg);
 /* Fill in methods for (simple) bed tracks. */
 
 void bed9Methods(struct track *tg);
 /* Fill in methods for bed9 tracks. */
 
 void complexBedMethods(struct track *track, struct trackDb *tdb, boolean isBigBed,
                                 int wordCount, char *words[]);
 /* Fill in methods for more complex bed tracks. */
 
 void makeCompositeTrack(struct track *track, struct trackDb *tdb);
 /* Construct track subtrack list from trackDb entry.
@@ -1408,28 +1506,77 @@
 
 #endif//ndef REMOTE_TRACK_AJAX_CALLBACK
 
 int gCmpPriority(const void *va, const void *vb);
 /* Compare groups based on priority. */
 
 int tgCmpPriority(const void *va, const void *vb);
 /* Compare to sort based on priority; use shortLabel as secondary sort key. */
 
 void printMenuBar();
 /* Put up the menu bar. */
 
 void checkIfWiggling(struct cart *cart, struct track *tg);
 /* Check to see if a linkedFeatures track should be drawing as a wiggle. */
 
+boolean isTypeBedLike(struct track *track);
+/* Check if track type is BED-like packable thing (but not rmsk or joinedRmsk) */
+
+boolean isTypeUseItemNameAsKey(struct track *track);
+/* Check if track type is like expRatio and key is just item name. */
+
+void setEMGeneTrack();
+/* Find the track for the gene table to use for exonMostly and geneMostly. */
+
+void findBestEMGeneTable(struct track *trackList);
+/* Find the best gene table to use for exonMostly */
+
+struct window *makeWindowListFromVirtChrom(long virtWinStart, long virtWinEnd);
+/* make list of windows from virtual position on virtualChrom */
+
+struct convertRange
+    {
+    struct convertRange *next;
+    char *chrom;
+    int start;
+    int end;
+    long vStart;
+    long vEnd;
+    boolean found;
+    boolean skipIt;
+    };
+
+
+void linkedFeaturesNextPrevExonFind(struct track *tg, boolean next, struct convertRange *crList);
+/* Find next-exon function for linkedFeatures.  Finds corresponding position on virtual chrom for new winStart/winEnd of exon non-virt position,
+ * and returns it. This function was cloned from linkedFeaturesLabelNextPrevItem and modified. */
+
+boolean virtualSingleChrom();
+/* Return TRUE if using virtual single chromosome mode */
+
+void parseVPosition(char *position, char **pChrom, long *pStart, long *pEnd);
+/* parse Virt position */
+
+char *undisguisePosition(char *position); // UN-DISGUISE VMODE
+/* Find the virt position
+ * position should be real chrom span. 
+ * Limitation: can only convert things in the current windows set. */
+
+
+char *disguisePositionVirtSingleChrom(char *position); // DISGUISE VMODE
+/* Hide the virt position, convert to real single chrom span.
+ * position should be virt chrom span. 
+ * Can handle anything in the virt single chrom. */
+
 #define measureTime uglyTime
 
 #define SUPPORT_CONTENT_TYPE 1
 
 struct bbiFile *fetchBbiForTrack(struct track *track);
 /* Fetch bbiFile from track, opening it if it is not already open. */
 
 void genericDrawNextItem(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y,
                             double scale, Color color, enum trackVisibility vis);
 /* Draw next item buttons and map boxes */
 
 #endif /* HGTRACKS_H */