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("<FORM ACTION='%s' NAME='customTrackForm' ID='customTrackForm'>", hgCustomName());
 cartSaveSession(cart);
 printf("</FORM>\n");
 
 /* Hidden form for jumping to track hub manager CGI. */
 printf("<FORM ACTION='%s' NAME='trackHubForm'>", hgHubConnectName());
 //#*** well, almost verbatim... lib version should use cgiScriptName.
 cartSaveSession(cart);
 printf("</FORM>\n");
 
 printf("<FORM ACTION=\"%s\" NAME=\"mainForm\" ID=\"mainForm\" METHOD=%s>\n",
-	cgiScriptName(), cartUsualString(cart, "formMethod", "GET"));
+	cgiScriptName(), cartUsualString(cart, "formMethod", "POST"));
 cartSaveSession(cart);
 
 //#*** ------------------ end verbatim ---------------
 
 printf("<div class='sectionLiteHeader noReorderRemove'>"
        "Select Genome Assembly and Region</div>\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("</SELECT><BR>\n");
 
 printf("<div id='"hgvaHgvsPasteContainer"'%s>\n",
        differentString(selected, hgvaUseHgvs) ? " style='display: none;'" : "");
 printf("Enter HGVS terms: one term per line; blank lines and comment lines beginning with '#' "
-       "are ignored.<BR>\n");
+       "are ignored.<BR>\n"
+       HGVS_MUST_USE_ACC"<br>\n");
 char *oldPasted = cartUsualString(cart, hgvaHgvs, "");
 cgiMakeTextArea(hgvaHgvs, oldPasted, 10, 70);
 puts("</div>");
 
 if (hasSnps)
     {
     printf("<div id='"hgvaVariantPasteContainer"'%s>\n",
 	   differentString(selected, hgvaUseVariantIds) ? " style='display: none;'" : "");
     printf("Enter dbSNP rs# identifiers separated by whitespace or commas:<BR>\n");
     char *oldPasted = cartUsualString(cart, hgvaVariantIds, "");
     cgiMakeTextArea(hgvaVariantIds, oldPasted, 10, 70);
     puts("</div>");
     }
 
 printf("<B>maximum number of variants to be processed:</B>\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.