533112afe2a2005e80cdb1f82904ea65032d4302 braney Sat Oct 2 11:37:34 2021 -0700 split hg/lib into two separate libaries, one only used by the cgis diff --git src/hg/cgilib/pcrResult.c src/hg/cgilib/pcrResult.c new file mode 100644 index 0000000..9d4f1e8 --- /dev/null +++ src/hg/cgilib/pcrResult.c @@ -0,0 +1,214 @@ +/* pcrResult -- support for internal track of hgPcr results. */ + +/* Copyright (C) 2014 The Regents of the University of California + * See README in this or parent directory for licensing information. */ + +#include "common.h" +#include "hdb.h" +#include "hui.h" +#include "obscure.h" +#include "targetDb.h" +#include "pcrResult.h" + + +char *pcrResultCartVar(char *db) +/* Returns the cart variable name for PCR result track info for db. + * Don't free the result! */ +{ +static char buf[1024]; +safef(buf, sizeof(buf), "%s_%s", PCR_RESULT_TRACK_NAME, db); +return buf; +} + +#define setPtIfNotNull(pt, val) if (pt != NULL) *pt = val + +boolean pcrResultParseCart(char *db, struct cart *cart, char **retPslFile, + char **retPrimerFile, + struct targetDb **retTarget) +/* Parse out hgPcrResult cart variable into components and make sure + * they are valid. If so, set *ret's and return TRUE. Otherwise, null out + * *ret's and return FALSE (and clear the cart variable if it exists). + * ret's are ignored if NULL. */ +{ +char *cartVar = pcrResultCartVar(cartString(cart, "db")); +char *hgPcrResult = cartOptionalString(cart, cartVar); +if (isEmpty(hgPcrResult)) + { + setPtIfNotNull(retPslFile, NULL); + setPtIfNotNull(retPrimerFile, NULL); + setPtIfNotNull(retTarget, NULL); + return FALSE; + } +static char buf[2048]; +char *words[3]; +int wordCount; +safecpy(buf, sizeof(buf), hgPcrResult); +wordCount = chopLine(buf, words); +if (wordCount < 2) + errAbort("Badly formatted hgPcrResult variable: %s", hgPcrResult); +char *pslFile = words[0]; +char *primerFile = words[1]; +char *targetName = (wordCount > 2) ? words[2] : NULL; +struct targetDb *target = NULL; +if (isNotEmpty(targetName)) + target = targetDbLookup(db, targetName); + +if (!fileExists(pslFile) || !fileExists(primerFile) || + (wordCount > 2 && target == NULL)) + { + cartRemove(cart, cartVar); + setPtIfNotNull(retPslFile, NULL); + setPtIfNotNull(retPrimerFile, NULL); + setPtIfNotNull(retTarget, NULL); + return FALSE; + } +setPtIfNotNull(retPslFile, cloneString(pslFile)); +setPtIfNotNull(retPrimerFile, cloneString(primerFile)); +setPtIfNotNull(retTarget, target); +if (retTarget == NULL) + targetDbFreeList(&target); +return TRUE; +} + +void pcrResultGetPrimers(char *fileName, char **retFPrimer, char **retRPrimer) +/* Given a file whose first line is 2 words (forward primer, reverse primer) + * set the ret's to upper-cased primer sequences. + * Do not free the statically allocated ret's. */ +{ +static char fPrimer[1024], rPrimer[1024];; +struct lineFile *lf = lineFileOpen(fileName, TRUE); +char *words[2]; +if (! lineFileRow(lf, words)) + lineFileAbort(lf, "Couldn't read primers"); +if (retFPrimer != NULL) + { + safecpy(fPrimer, sizeof(fPrimer), words[0]); + touppers(fPrimer); + *retFPrimer = fPrimer; + } +if (retRPrimer != NULL) + { + safecpy(rPrimer, sizeof(rPrimer), words[1]); + touppers(rPrimer); + *retRPrimer = rPrimer; + } +lineFileClose(&lf); +} + +void pcrResultGetPsl(char *fileName, struct targetDb *target, char *item, + char *chrom, int itemStart, int itemEnd, + struct psl **retItemPsl, struct psl **retOtherPsls) +/* Read in psl from file. If a psl matches the given item position, set + * retItemPsl to that; otherwise add it to retOtherPsls. Die if no psl + * matches the given item position. */ +{ +struct lineFile *lf = lineFileOpen(fileName, TRUE); +struct psl *itemPsl = NULL, *otherPsls = NULL; +char *pslFields[21]; +while (lineFileRow(lf, pslFields)) + { + struct psl *psl = pslLoad(pslFields); + boolean gotIt = FALSE; + if (target != NULL) + { + if (sameString(psl->tName, item) && psl->tStart == itemStart && psl->tEnd == itemEnd) + gotIt = TRUE; + } + else if (sameString(psl->tName, chrom) && psl->tStart == itemStart && + psl->tEnd == itemEnd) + gotIt = TRUE; + if (gotIt) + itemPsl = psl; + else + slAddHead(&otherPsls, psl); + } +lineFileClose(&lf); +if (itemPsl == NULL) + { + if (target != NULL) + errAbort("Did not find record for amplicon in %s sequence %s", + target->description, item); + else + errAbort("Did not find record for amplicon at %s:%d-%d", + chrom, itemStart, itemEnd); + } +if (retItemPsl != NULL) + *retItemPsl = itemPsl; +else + pslFree(&itemPsl); +if (retOtherPsls != NULL) + { + slSort(&otherPsls, pslCmpTarget); + *retOtherPsls = otherPsls; + } +else + pslFreeList(&otherPsls); +} + +struct trackDb *pcrResultFakeTdb() +/* Construct a trackDb record for PCR Results track. */ +{ +struct trackDb *tdb; +AllocVar(tdb); +tdb->track = cloneString(PCR_RESULT_TRACK_NAME); +tdb->table = cloneString(PCR_RESULT_TRACK_NAME); +tdb->shortLabel = cloneString(PCR_RESULT_TRACK_LABEL); +tdb->longLabel = cloneString(PCR_RESULT_TRACK_LONGLABEL); +tdb->grp = cloneString("map"); +tdb->type = cloneString("psl ."); +tdb->priority = 100.01; +tdb->canPack = TRUE; +tdb->visibility = tvPack; +tdb->html = hFileContentsOrWarning(hHelpFile(PCR_RESULT_TRACK_NAME)); +trackDbPolish(tdb); +if (tdb->settingsHash == NULL) + tdb->settingsHash = hashNew(0); +hashAdd(tdb->settingsHash, BASE_COLOR_DEFAULT, cloneString("diffBases")); +hashAdd(tdb->settingsHash, BASE_COLOR_USE_SEQUENCE, + cloneString(PCR_RESULT_TRACK_NAME)); +hashAdd(tdb->settingsHash, SHOW_DIFF_BASES_ALL_SCALES, cloneString(".")); +hashAdd(tdb->settingsHash, INDEL_DOUBLE_INSERT, cloneString("on")); +hashAdd(tdb->settingsHash, INDEL_QUERY_INSERT, cloneString("on")); +hashAdd(tdb->settingsHash, INDEL_POLY_A, cloneString("on")); +hashAdd(tdb->settingsHash, "nextItemButton", cloneString("off")); +return tdb; +} + +char *pcrResultItemAccName(char *acc, char *name) +/* If a display name is given in addition to the acc, concatenate them + * into a single name that must match a non-genomic target item's name + * in the targetDb .2bit. Do not free the result. */ +{ +static char accName[256]; +if (isEmpty(name)) + safecpy(accName, sizeof(accName), acc); +else + safef(accName, sizeof(accName), "%s__%s", acc, name); +return accName; +} + +char *pcrResultItemAccession(char *nameIn) +/* If nameIn contains a concatenated accession and display name, returns + * just the accession. Do not free the result.*/ +{ +char *ptr = strstr(nameIn, "__"); +if (ptr != NULL) + { + static char nameOut[128]; + safecpy(nameOut, sizeof(nameOut), nameIn); + nameOut[ptr-nameIn] = '\0'; + return nameOut; + } +return nameIn; +} + +char *pcrResultItemName(char *nameIn) +/* If nameIn contains a concatenated accession and display name, returns + * just the name. If accession only, returns NULL. Do not free the result.*/ +{ +char *ptr = strstr(nameIn, "__"); +if (ptr != NULL) + return ptr+2; +return NULL; +} +