/* hapmapSnpsCombined.c was originally generated by the autoSql program, which also 
 * generated hapmapSnpsCombined.h and hapmapSnpsCombined.sql.  This module links the database and
 * the RAM representation of objects. */

/* Copyright (C) 2014 The Regents of the University of California 
 * See README in this or parent directory for licensing information. */

#include "common.h"
#include "linefile.h"
#include "dystring.h"
#include "jksql.h"
#include "hapmapSnpsCombined.h"


void hapmapSnpsCombinedStaticLoad(char **row, struct hapmapSnpsCombined *ret)
/* Load a row from hapmapSnpsCombined table into ret.  The contents of ret will
 * be replaced at the next call to this function. */
{

ret->chrom = row[0];
ret->chromStart = sqlUnsigned(row[1]);
ret->chromEnd = sqlUnsigned(row[2]);
ret->name = row[3];
ret->score = sqlUnsigned(row[4]);
safecpy(ret->strand, sizeof(ret->strand), row[5]);
ret->observed = row[6];
safecpy(ret->allele1, sizeof(ret->allele1), row[7]);
ret->homoCount1CEU = sqlUnsigned(row[8]);
ret->homoCount1CHB = sqlUnsigned(row[9]);
ret->homoCount1JPT = sqlUnsigned(row[10]);
ret->homoCount1YRI = sqlUnsigned(row[11]);
ret->allele2 = row[12];
ret->homoCount2CEU = sqlUnsigned(row[13]);
ret->homoCount2CHB = sqlUnsigned(row[14]);
ret->homoCount2JPT = sqlUnsigned(row[15]);
ret->homoCount2YRI = sqlUnsigned(row[16]);
ret->heteroCountCEU = sqlUnsigned(row[17]);
ret->heteroCountCHB = sqlUnsigned(row[18]);
ret->heteroCountJPT = sqlUnsigned(row[19]);
ret->heteroCountYRI = sqlUnsigned(row[20]);
}

struct hapmapSnpsCombined *hapmapSnpsCombinedLoad(char **row)
/* Load a hapmapSnpsCombined from row fetched with select * from hapmapSnpsCombined
 * from database.  Dispose of this with hapmapSnpsCombinedFree(). */
{
struct hapmapSnpsCombined *ret;

AllocVar(ret);
ret->chrom = cloneString(row[0]);
ret->chromStart = sqlUnsigned(row[1]);
ret->chromEnd = sqlUnsigned(row[2]);
ret->name = cloneString(row[3]);
ret->score = sqlUnsigned(row[4]);
safecpy(ret->strand, sizeof(ret->strand), row[5]);
ret->observed = cloneString(row[6]);
safecpy(ret->allele1, sizeof(ret->allele1), row[7]);
ret->homoCount1CEU = sqlUnsigned(row[8]);
ret->homoCount1CHB = sqlUnsigned(row[9]);
ret->homoCount1JPT = sqlUnsigned(row[10]);
ret->homoCount1YRI = sqlUnsigned(row[11]);
ret->allele2 = cloneString(row[12]);
ret->homoCount2CEU = sqlUnsigned(row[13]);
ret->homoCount2CHB = sqlUnsigned(row[14]);
ret->homoCount2JPT = sqlUnsigned(row[15]);
ret->homoCount2YRI = sqlUnsigned(row[16]);
ret->heteroCountCEU = sqlUnsigned(row[17]);
ret->heteroCountCHB = sqlUnsigned(row[18]);
ret->heteroCountJPT = sqlUnsigned(row[19]);
ret->heteroCountYRI = sqlUnsigned(row[20]);
return ret;
}

struct hapmapSnpsCombined *hapmapSnpsCombinedLoadAll(char *fileName) 
/* Load all hapmapSnpsCombined from a whitespace-separated file.
 * Dispose of this with hapmapSnpsCombinedFreeList(). */
{
struct hapmapSnpsCombined *list = NULL, *el;
struct lineFile *lf = lineFileOpen(fileName, TRUE);
char *row[21];

while (lineFileRow(lf, row))
    {
    el = hapmapSnpsCombinedLoad(row);
    slAddHead(&list, el);
    }
lineFileClose(&lf);
slReverse(&list);
return list;
}

struct hapmapSnpsCombined *hapmapSnpsCombinedLoadAllByChar(char *fileName, char chopper) 
/* Load all hapmapSnpsCombined from a chopper separated file.
 * Dispose of this with hapmapSnpsCombinedFreeList(). */
{
struct hapmapSnpsCombined *list = NULL, *el;
struct lineFile *lf = lineFileOpen(fileName, TRUE);
char *row[21];

while (lineFileNextCharRow(lf, chopper, row, ArraySize(row)))
    {
    el = hapmapSnpsCombinedLoad(row);
    slAddHead(&list, el);
    }
lineFileClose(&lf);
slReverse(&list);
return list;
}

struct hapmapSnpsCombined *hapmapSnpsCombinedCommaIn(char **pS, struct hapmapSnpsCombined *ret)
/* Create a hapmapSnpsCombined out of a comma separated string. 
 * This will fill in ret if non-null, otherwise will
 * return a new hapmapSnpsCombined */
{
char *s = *pS;

if (ret == NULL)
    AllocVar(ret);
ret->chrom = sqlStringComma(&s);
ret->chromStart = sqlUnsignedComma(&s);
ret->chromEnd = sqlUnsignedComma(&s);
ret->name = sqlStringComma(&s);
ret->score = sqlUnsignedComma(&s);
sqlFixedStringComma(&s, ret->strand, sizeof(ret->strand));
ret->observed = sqlStringComma(&s);
sqlFixedStringComma(&s, ret->allele1, sizeof(ret->allele1));
ret->homoCount1CEU = sqlUnsignedComma(&s);
ret->homoCount1CHB = sqlUnsignedComma(&s);
ret->homoCount1JPT = sqlUnsignedComma(&s);
ret->homoCount1YRI = sqlUnsignedComma(&s);
ret->allele2 = sqlStringComma(&s);
ret->homoCount2CEU = sqlUnsignedComma(&s);
ret->homoCount2CHB = sqlUnsignedComma(&s);
ret->homoCount2JPT = sqlUnsignedComma(&s);
ret->homoCount2YRI = sqlUnsignedComma(&s);
ret->heteroCountCEU = sqlUnsignedComma(&s);
ret->heteroCountCHB = sqlUnsignedComma(&s);
ret->heteroCountJPT = sqlUnsignedComma(&s);
ret->heteroCountYRI = sqlUnsignedComma(&s);
*pS = s;
return ret;
}

void hapmapSnpsCombinedFree(struct hapmapSnpsCombined **pEl)
/* Free a single dynamically allocated hapmapSnpsCombined such as created
 * with hapmapSnpsCombinedLoad(). */
{
struct hapmapSnpsCombined *el;

if ((el = *pEl) == NULL) return;
freeMem(el->chrom);
freeMem(el->name);
freeMem(el->observed);
freeMem(el->allele2);
freez(pEl);
}

void hapmapSnpsCombinedFreeList(struct hapmapSnpsCombined **pList)
/* Free a list of dynamically allocated hapmapSnpsCombined's */
{
struct hapmapSnpsCombined *el, *next;

for (el = *pList; el != NULL; el = next)
    {
    next = el->next;
    hapmapSnpsCombinedFree(&el);
    }
*pList = NULL;
}

void hapmapSnpsCombinedOutput(struct hapmapSnpsCombined *el, FILE *f, char sep, char lastSep) 
/* Print out hapmapSnpsCombined.  Separate fields with sep. Follow last field with lastSep. */
{
if (sep == ',') fputc('"',f);
fprintf(f, "%s", el->chrom);
if (sep == ',') fputc('"',f);
fputc(sep,f);
fprintf(f, "%u", el->chromStart);
fputc(sep,f);
fprintf(f, "%u", el->chromEnd);
fputc(sep,f);
if (sep == ',') fputc('"',f);
fprintf(f, "%s", el->name);
if (sep == ',') fputc('"',f);
fputc(sep,f);
fprintf(f, "%u", el->score);
fputc(sep,f);
if (sep == ',') fputc('"',f);
fprintf(f, "%s", el->strand);
if (sep == ',') fputc('"',f);
fputc(sep,f);
if (sep == ',') fputc('"',f);
fprintf(f, "%s", el->observed);
if (sep == ',') fputc('"',f);
fputc(sep,f);
if (sep == ',') fputc('"',f);
fprintf(f, "%s", el->allele1);
if (sep == ',') fputc('"',f);
fputc(sep,f);
fprintf(f, "%u", el->homoCount1CEU);
fputc(sep,f);
fprintf(f, "%u", el->homoCount1CHB);
fputc(sep,f);
fprintf(f, "%u", el->homoCount1JPT);
fputc(sep,f);
fprintf(f, "%u", el->homoCount1YRI);
fputc(sep,f);
if (sep == ',') fputc('"',f);
fprintf(f, "%s", el->allele2);
if (sep == ',') fputc('"',f);
fputc(sep,f);
fprintf(f, "%u", el->homoCount2CEU);
fputc(sep,f);
fprintf(f, "%u", el->homoCount2CHB);
fputc(sep,f);
fprintf(f, "%u", el->homoCount2JPT);
fputc(sep,f);
fprintf(f, "%u", el->homoCount2YRI);
fputc(sep,f);
fprintf(f, "%u", el->heteroCountCEU);
fputc(sep,f);
fprintf(f, "%u", el->heteroCountCHB);
fputc(sep,f);
fprintf(f, "%u", el->heteroCountJPT);
fputc(sep,f);
fprintf(f, "%u", el->heteroCountYRI);
fputc(lastSep,f);
}

/* -------------------------------- End autoSql Generated Code -------------------------------- */


int getPopCount(struct hapmapSnpsCombined *thisItem)
{
int ret = 0;
if (thisItem->homoCount1CEU > 0 || thisItem->homoCount2CEU > 0 || thisItem->heteroCountCEU > 0) ret++;
if (thisItem->homoCount1CHB > 0 || thisItem->homoCount2CHB > 0 || thisItem->heteroCountJPT > 0) ret++;
if (thisItem->homoCount1JPT > 0 || thisItem->homoCount2JPT > 0 || thisItem->heteroCountCHB > 0) ret++;
if (thisItem->homoCount1YRI > 0 || thisItem->homoCount2YRI > 0 || thisItem->heteroCountYRI > 0) ret++;
return ret;
}


boolean isMixed(struct hapmapSnpsCombined *thisItem)
/* return TRUE if different populations have a different major allele */
/* don't need to consider heteroCount */
{
int allele1Count = 0;
int allele2Count = 0;

if (thisItem->homoCount1CEU >= thisItem->homoCount2CEU && thisItem->homoCount1CEU > 0) 
    allele1Count++;
else if (thisItem->homoCount2CEU > 0)
    allele2Count++;

if (thisItem->homoCount1CHB >= thisItem->homoCount2CHB && thisItem->homoCount1CHB > 0) 
    allele1Count++;
else if (thisItem->homoCount2CHB > 0)
    allele2Count++;

if (thisItem->homoCount1JPT >= thisItem->homoCount2JPT && thisItem->homoCount1JPT > 0) 
    allele1Count++;
else if (thisItem->homoCount2JPT > 0)
    allele2Count++;

if (thisItem->homoCount1YRI >= thisItem->homoCount2YRI && thisItem->homoCount1YRI > 0) 
    allele1Count++;
else if (thisItem->homoCount2YRI > 0)
    allele2Count++;

if (allele1Count > 0 && allele2Count > 0) return TRUE;

return FALSE;
}

void printOne(struct hapmapSnpsCombined *thisItem)
{
verbose(1, "chrom = %s\n", thisItem->chrom);
verbose(1, "chromStart = %d\n", thisItem->chromStart);
verbose(1, "chromEnd = %d\n", thisItem->chromEnd);
verbose(1, "name = %s\n", thisItem->name);
verbose(1, "score = %d\n", thisItem->score);
verbose(1, "strand = %s\n", thisItem->strand);
verbose(1, "observed = %s\n", thisItem->observed);
verbose(1, "allele1 = %s\n", thisItem->allele1);
verbose(1, "homoCount1CEU = %d\n", thisItem->homoCount1CEU);
verbose(1, "homoCount1CHB = %d\n", thisItem->homoCount1CHB);
verbose(1, "homoCount1JPT = %d\n", thisItem->homoCount1JPT);
verbose(1, "homoCount1YRI = %d\n", thisItem->homoCount1YRI);
verbose(1, "allele2 = %s\n", thisItem->allele2);
verbose(1, "homoCount2CEU = %d\n", thisItem->homoCount2CEU);
verbose(1, "homoCount2CHB = %d\n", thisItem->homoCount2CHB);
verbose(1, "homoCount2JPT = %d\n", thisItem->homoCount2JPT);
verbose(1, "homoCount2YRI = %d\n", thisItem->homoCount2YRI);
verbose(1, "heteroCountCEU = %d\n", thisItem->heteroCountCEU);
verbose(1, "heteroCountCHB = %d\n", thisItem->heteroCountCHB);
verbose(1, "heteroCountJPT = %d\n", thisItem->heteroCountJPT);
verbose(1, "heteroCountYRI = %d\n", thisItem->heteroCountYRI);
}


int calcHet(struct hapmapSnpsCombined *thisItem)
/* calculate heterozygosity (2pq) */
/* convert from individuals to alleles */
{
int allele1Count = 0;
int allele2Count = 0;
int total = 0;
float p = 0.0; // freq1
float q = 0.0; // freq2

allele1Count = allele1Count + (2 * thisItem->homoCount1CEU) + thisItem->heteroCountCEU;
allele1Count = allele1Count + (2 * thisItem->homoCount1CHB) + thisItem->heteroCountCHB;
allele1Count = allele1Count + (2 * thisItem->homoCount1JPT) + thisItem->heteroCountJPT;
allele1Count = allele1Count + (2 * thisItem->homoCount1YRI) + thisItem->heteroCountYRI;

allele2Count = allele2Count + (2 * thisItem->homoCount2CEU) + thisItem->heteroCountCEU;
allele2Count = allele2Count + (2 * thisItem->homoCount2CHB) + thisItem->heteroCountCHB;
allele2Count = allele2Count + (2 * thisItem->homoCount2JPT) + thisItem->heteroCountJPT;
allele2Count = allele2Count + (2 * thisItem->homoCount2YRI) + thisItem->heteroCountYRI;

total = allele1Count + allele2Count;

if (total == 0) return 0;

p = (float)allele1Count / (float)total;
q = (float)allele2Count / (float)total;

/* 1000 is to normalize to store as integer */
return (int)1000*2*p*q;
}


