5e8e0ed53c05f2ef9b51ce897440bae308367f47 chmalee Wed Feb 9 14:45:54 2022 -0800 Add csv output option to table browser to support opening files in Excel, refs #27623. Also change the output filename message to hint that Excel can auto-recognize .csv extensions and behave appropriately. Lastly, fix output dropdown selection to properly warn on update when using GTF output option or a snp table. diff --git src/hg/hgTables/bam.c src/hg/hgTables/bam.c index ecd4a35..02a262a 100644 --- src/hg/hgTables/bam.c +++ src/hg/hgTables/bam.c @@ -90,31 +90,31 @@ row[0] = sam->qName; row[1] = numPt; numPt += sprintf(numPt, "%u", sam->flag); numPt += 1; row[2] = sam->rName; row[3] = numPt; numPt += sprintf(numPt, "%u", sam->pos); numPt += 1; row[4] = numPt; numPt += sprintf(numPt, "%u", sam->mapQ); numPt += 1; row[5] = sam->cigar; row[6] = sam->rNext; row[7] = numPt; numPt += sprintf(numPt, "%d", sam->pNext); numPt += 1; row[8] = numPt; numPt += sprintf(numPt, "%d", sam->tLen); numPt += 1; row[9] = sam->seq; row[10] = sam->qual; row[11] = sam->tagTypeVals; assert(numPt < numBufEnd); } -void bamTabOut(char *db, char *table, struct sqlConnection *conn, char *fields, FILE *f) +void bamTabOut(char *db, char *table, struct sqlConnection *conn, char *fields, FILE *f, char outSep) /* Print out selected fields from BAM. If fields is NULL, then print out all fields. */ { struct hTableInfo *hti = NULL; hti = getHti(db, table, conn); struct hash *idHash = NULL; char *idField = getIdField(db, curTrack, table, hti); int idFieldNum = 0; /* if we know what field to use for the identifiers, get the hash of names */ if (idField != NULL) idHash = identifierHash(db, table); if (f == NULL) f = stdout; @@ -134,33 +134,41 @@ /* if we know the field for identifiers, save it away */ if ((idField != NULL) && sameString(idField, bb->name)) idFieldNum = i; hashAddInt(fieldHash, bb->name, i); } /* Create an array of column indexes corresponding to the selected field list. */ int *columnArray; AllocArray(columnArray, fieldCount); for (i=0; i<fieldCount; ++i) { columnArray[i] = hashIntVal(fieldHash, fieldArray[i]); } /* Output row of labels */ -fprintf(f, "#%s", fieldArray[0]); +fprintf(f, "#"); +if (outSep == ',') fputc('"', f); +fprintf(f, "%s", fieldArray[0]); +if (outSep == ',') fputc('"', f); for (i=1; i<fieldCount; ++i) - fprintf(f, "\t%s", fieldArray[i]); + { + fputc(outSep, f); + if (outSep == ',') fputc('"', f); + fprintf(f, "%s", fieldArray[i]); + if (outSep == ',') fputc('"', f); + } fprintf(f, "\n"); struct asObject *as = bamAsObj(); struct asFilter *filter = NULL; if (anyFilter()) { filter = asFilterFromCart(cart, db, table, as); if (filter) { fprintf(f, "# Filtering on %d columns\n", slCount(filter->columnList)); } } /* Loop through outputting each region */ @@ -178,33 +186,40 @@ struct samAlignment *sam, *samList = bamAndIndexFetchSamAlignmentPlus(fileName, baiUrl, region->chrom, region->start, region->end, lm, refUrl, cacheDir); char *row[SAMALIGNMENT_NUM_COLS]; char numBuf[BAM_NUM_BUF_SIZE]; for (sam = samList; sam != NULL && (maxOut > 0); sam = sam->next) { samAlignmentToRow(sam, numBuf, row); if (asFilterOnRow(filter, row)) { /* if we're looking for identifiers, check if this matches */ if ((idHash != NULL)&&(hashLookup(idHash, row[idFieldNum]) == NULL)) continue; int i; + if (outSep == ',') fputc('"', f); fprintf(f, "%s", row[columnArray[0]]); + if (outSep == ',') fputc('"', f); for (i=1; i<fieldCount; ++i) - fprintf(f, "\t%s", row[columnArray[i]]); + { + fputc(outSep, f); + if (outSep == ',') fputc('"', f); + fprintf(f, "%s", row[columnArray[i]]); + if (outSep == ',') fputc('"', f); + } fprintf(f, "\n"); maxOut --; } } freeMem(fileName); lmCleanup(&lm); } if (maxOut == 0) errAbort("Reached output limit of %d data values, please make region smaller,\n\tor set a higher output line limit with the filter settings.", bigFileMaxOutput()); /* Clean up and exit. */ hashFree(&fieldHash); freeMem(fieldArray); freeMem(columnArray); }