ab923da8deeb3fc3bd5d04fa84e36090c6bcb129 tdreszer Tue Apr 22 16:47:33 2014 -0700 Added a trap for when map items are written outside the track they are supposed to be for. The trap is only on for genome-test and sandboxes. I found one bug with it: gold in dense had wild map item ending coordinates. Fixed. Redmine #13087 diff --git src/hg/hgTracks/imageV2.c src/hg/hgTracks/imageV2.c index 9a81869..fd8c4a3 100644 --- src/hg/hgTracks/imageV2.c +++ src/hg/hgTracks/imageV2.c @@ -999,52 +999,113 @@ slice = imgTrackSliceAdd(imgTrack,type,img,title,width,height,offsetX,offsetY); return slice; } struct imgSlice *imgTrackSliceUpdateOrAdd(struct imgTrack *imgTrack,enum sliceType type, struct image *img,char *title,int width,int height, int offsetX,int offsetY) // Updates the slice or adds it { struct imgSlice *slice = imgTrackSliceGetByType(imgTrack,type); if (slice == NULL) return imgTrackSliceAdd(imgTrack,type,img,title,width,height,offsetX,offsetY); return sliceUpdate(slice,type,img,title,width,height,offsetX,offsetY); } +int imgTrackCoordinates(struct imgTrack *imgTrack, int *leftX,int *topY,int *rightX,int *bottomY) +// Fills in topLeft x,y and bottomRight x,y coordinates, returning topY. +{ +int xLeft = 0,yTop = 0,xRight = 0,yBottom = 0; +struct imgSlice *slice; +for (slice = imgTrack->slices;slice != NULL;slice=slice->next) + { + if (revCmplDisp) + { + if (xLeft == 0 || xLeft > slice->offsetX - slice->width) + xLeft = slice->offsetX - slice->width; + if (xRight < slice->offsetX) + xRight = slice->offsetX; + } + else + { + if (xLeft == 0 || xLeft > slice->offsetX) + xLeft = slice->offsetX; + if (xRight < slice->offsetX + slice->width) + xRight = slice->offsetX + slice->width; + } + if (yTop == 0 || yTop > slice->offsetY) + yTop = slice->offsetY; + if (yBottom < slice->offsetY + slice->height) + yBottom = slice->offsetY + slice->height; + } +if ( leftX != NULL) + *leftX = xLeft; +if ( topY != NULL) + *topY = yTop; +if ( rightX != NULL) + *rightX = xRight; +if ( bottomY != NULL) + *bottomY = yBottom; +return yTop; +} +#define imgTrackTopY(imgTrack) imgTrackCoordinates(imgTrack,NULL,NULL,NULL,NULL) + +int imgTrackBottomY(struct imgTrack *imgTrack) +// Returns the Y coordinate of the bottom of the track. +{ +int bottomY = 0; +imgTrackCoordinates(imgTrack,NULL,NULL,NULL,&bottomY); +return bottomY; +} + struct mapSet *imgTrackGetMapByType(struct imgTrack *imgTrack,enum sliceType type) // Gets the map assocated with a specific slice belonging to the imgTrack { struct imgSlice *slice = imgTrackSliceGetByType(imgTrack,type); if (slice == NULL) return NULL; return sliceGetMap(slice,FALSE); // Map could belong to image or could be slice specific } int imgTrackAddMapItem(struct imgTrack *imgTrack,char *link,char *title, int topLeftX,int topLeftY,int bottomRightX,int bottomRightY, char *id) // Will add a map item to an imgTrack's appropriate slice's map. Since a map item may span // slices, the imgTrack is in the best position to determine where to put the map item // returns count of map items added, which could be 0, 1 or more than one if item spans slices // NOTE: Precedence is given to first map item when adding items with same coordinates! { struct imgSlice *slice; char *imgFile = NULL; // name of file that hold the image char *neededId = NULL; // id is only added it it is NOT the trackId. if (imgTrack->tdb == NULL || differentStringNullOk(id, imgTrack->tdb->track)) neededId = id; +// Trap surprising location s for map items, but only on test machines. +if (hIsPrivateHost()) + { + int leftX, topY, rightX, bottomY; + imgTrackCoordinates(imgTrack, &leftX, &topY, &rightX, &bottomY); + if (topLeftY < topY || bottomRightY > bottomY || topLeftX < leftX || bottomRightX > rightX) + { + char * name = (imgTrack->name != NULL ? imgTrack->name + : imgTrack->tdb != NULL ? imgTrack->tdb->track + : imgFile); + warnWithBackTrace("imgTrackAddMapItem(%s,%s) mapItem(%d:%d,%d:%d) spills over track bounds(%d:%d,%d:%d)", + name,title,topLeftX,topLeftY,bottomRightX,bottomRightY,leftX,topY,rightX,bottomY); + } + } + int count = 0; for (slice = imgTrack->slices;slice != NULL;slice=slice->next) { if (slice->type == stButton) // Buttons don't have maps. Overlap will be ignored! continue; if (slice->parentImg != NULL) { if (imgFile == NULL) imgFile = slice->parentImg->file; } if (topLeftX < (slice->offsetX + slice->width-1) && bottomRightX > (slice->offsetX + 1) && topLeftY < (slice->offsetY + slice->height-1) && bottomRightY > (slice->offsetY + 1)) // Overlap of a pixel or 2 is tolerated {