5b4fcca505f362e2fd288f57d8d8dd2de1148d6c angie Wed Apr 11 11:47:25 2018 -0700 Make POST the formMethod default instead of GET, to support long lists of rsIds / HGVS terms. Let the user know that unlike the position/search input that accepts HGVS-ish terms with gene symbols, hgVai needs specific transcript IDs. Thanks Jairo! refs #21142 diff --git src/hg/hgVai/hgVai.c src/hg/hgVai/hgVai.c index 9452f01..16c53cc 100644 --- src/hg/hgVai/hgVai.c +++ src/hg/hgVai/hgVai.c @@ -35,30 +35,33 @@ #include "hAnno.h" #include "annoGratorQuery.h" #include "annoGratorGpVar.h" #include "annoFormatVep.h" #include "annoStreamBigBed.h" #include "annoStreamDb.h" #include "windowsToAscii.h" #include "libifyMe.h" #define GENCODE_TAG_DOC_URL "\"http://www.gencodegenes.org/gencode_tags.html\"" #define GENCODE_BASIC_DOC_URL "\"http://www.gencodegenes.org/faq.html\"" #define REFSEQ_STATUS_DOC_URL "\"https://www.ncbi.nlm.nih.gov/books/NBK21091/table/ch18.T.refseq_status_codes\"" #define APPRIS_DOC_URL "\"http://appris.bioinfo.cnio.es/#/help/database\"" +#define HGVS_MUST_USE_ACC "Note: HGVS terms must use versioned transcript or genomic accessions " \ + "(e.g. NM_000023.3, NC_000012.11, ENST00000000233.9), not gene symbols." + /* Global Variables */ struct cart *cart; /* CGI and other variables */ struct hash *oldVars = NULL; /* The cart before new cgi stuff added. */ char *genome = NULL; /* Name of genome - mouse, human, etc. */ char *database = NULL; /* Current genome database - hg17, mm5, etc. */ char *regionType = NULL; /* genome, ENCODE pilot regions, or specific position range. */ struct grp *fullGroupList = NULL; /* List of all groups. */ struct trackDb *fullTrackList = NULL; /* List of all tracks in database. */ static struct pipeline *compressPipeline = (struct pipeline *)NULL; // Null terminated list of CGI Variables we don't want to save permanently: char *excludeVars[] = {"Submit", "submit", "hgva_startQuery", NULL,}; #define hgvaRange "position" @@ -259,31 +262,31 @@ jsCreateHiddenForm(cart, cgiScriptName(), saveVars, ArraySize(saveVars)); } /* Hidden form for jumping to custom tracks CGI. */ printf("
", hgCustomName()); cartSaveSession(cart); printf("
\n"); /* Hidden form for jumping to track hub manager CGI. */ printf("
", hgHubConnectName()); //#*** well, almost verbatim... lib version should use cgiScriptName. cartSaveSession(cart); printf("
\n"); printf("
\n", - cgiScriptName(), cartUsualString(cart, "formMethod", "GET")); + cgiScriptName(), cartUsualString(cart, "formMethod", "POST")); cartSaveSession(cart); //#*** ------------------ end verbatim --------------- printf("
" "Select Genome Assembly and Region
\n"); /* Print clade, genome and assembly line. */ hgGatewayCladeGenomeDb(); //#*** No longer ending form here... } void factorSourceListInputProperties(struct trackDb *tdb, struct slName **retFactorList, struct slName **retCellTypeList, struct slName **retTreatmentList) @@ -493,31 +496,32 @@ struct trackDb *tdb = ref->val; printOption(tdb->track, selected, tdb->longLabel); } printOption(hgvaSampleVariants, selected, hgvaSampleVariantsLabel); printOption(hgvaUseHgvs, selected, hgvaHgvsLabel); struct trackDb *snpTdb = hFindLatestSnpTrack(database, NULL, &fullTrackList); // We can convert rsIds from snpNNN tables (but not ancient "snp" - no refUCSC column) into VCF boolean hasSnps = (snpTdb != NULL && differentString(snpTdb->table, "snp")); if (hasSnps) printOption(hgvaUseVariantIds, selected, hgvaVariantIdsLabel); printf("
\n"); printf("
\n", differentString(selected, hgvaUseHgvs) ? " style='display: none;'" : ""); printf("Enter HGVS terms: one term per line; blank lines and comment lines beginning with '#' " - "are ignored.
\n"); + "are ignored.
\n" + HGVS_MUST_USE_ACC"
\n"); char *oldPasted = cartUsualString(cart, hgvaHgvs, ""); cgiMakeTextArea(hgvaHgvs, oldPasted, 10, 70); puts("
"); if (hasSnps) { printf("
\n", differentString(selected, hgvaUseVariantIds) ? " style='display: none;'" : ""); printf("Enter dbSNP rs# identifiers separated by whitespace or commas:
\n"); char *oldPasted = cartUsualString(cart, hgvaVariantIds, ""); cgiMakeTextArea(hgvaVariantIds, oldPasted, 10, 70); puts("
"); } printf("maximum number of variants to be processed:\n"); @@ -2480,60 +2484,67 @@ writeMinimalVcfRow(f, var); carefulClose(&f); } return annoStreamVcfNew(varFile, NULL, FALSE, assembly, maxOutRows); } static struct vcfRecord *parseHgvs(struct vcfFile *vcff, struct annoAssembly *assembly, char *hgvsTerms, struct slName **pCommentList) /* Return a sorted list of vcfRecords . */ { struct vcfRecord *recList = NULL; struct slName *failedTerms = NULL; struct dyString *dyError = dyStringNew(0); struct lineFile *lf = lineFileOnString("user-provided HGVS terms", TRUE, cloneString(hgvsTerms)); char *term = NULL; +boolean notVersionedAcc = FALSE; while (lineFileNextReal(lf, &term)) { eraseTrailingSpaces(term); dyStringClear(dyError); struct vcfRow *vcfRow = hgvsToVcfRow(assembly->name, term, FALSE, dyError); if (vcfRow) { char *row[8]; row[0] = vcfRow->chrom; char posStr[64]; safef(posStr, sizeof(posStr), "%d", vcfRow->pos); row[1] = posStr; row[2] = vcfRow->id; row[3] = vcfRow->ref; row[4] = vcfRow->alt; row[5] = "."; row[6] = vcfRow->filter; row[7] = vcfRow->info; slAddHead(&recList, vcfRecordFromRow(vcff, row)); } else + { + if (!regexMatch(term, "^[A-Z_]+\\.[0-9]+[: ]")) + notVersionedAcc = TRUE; slNameAddHead(&failedTerms, dyStringContents(dyError)); } + } if (failedTerms != NULL) { slReverse(&failedTerms); char *firstUnknownIds = firstNCommaSep(failedTerms, 5); struct dyString *dy = dyStringCreate("%d HGVS terms could not be parsed and/or mapped to %s, " "e.g. %s", slCount(failedTerms), assembly->name, firstUnknownIds); + if (notVersionedAcc) + dyStringAppend(dy, ". " HGVS_MUST_USE_ACC); slAddTail(pCommentList, slNameNew(dy->string)); freeMem(firstUnknownIds); dyStringFree(&dy); } slSort(&recList, vcfRecordCmp); slNameFreeList(&failedTerms); dyStringFree(&dyError); lineFileClose(&lf); return recList; } static struct annoStreamer *makeHgvsStreamer(struct annoAssembly *assembly, int maxOutRows, char **pChrom, uint *pStart, uint *pEnd, struct slName **pCommentList) /* Translate user's pasted/uploaded variant IDs into minimal VCF if possible.