1 /*
2 This file is part of Primer Pooler (c) Silas S. Brown.  For Wen.
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8     http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16 /* thirty-two to sixty-four dot h is automatically generated
17    from sixty-four to one-hundred-and-twenty-eight dot h,
18    with these two numbers halved throughout.
19 
20    These files should be included ONLY by bit-common.h.
21    The general interface is in all-primers.h.
22 */
23 
24 enum { PrimerLimit = 128 }; /* max length of a primer */
25 typedef struct {
26   union { /* array of primers read "forward" (5'-3') */
27     MaybeDegeneratePrimer64* p64;
28     MaybeDegeneratePrimer128* p128;
29   } forward;
30   union { /* same primers read "backward" (3'-5')
31              (not to be confused with "reverse primer") */
32     MaybeDegeneratePrimer64* p64;
33     MaybeDegeneratePrimer128* p128;
34   } backward;
35   union { /* array of tags (read 5'-3') */
36     MaybeDegeneratePrimer64* p64;
37     MaybeDegeneratePrimer128* p128;
38   } tags;
39   int *whichTag; /* which tag no. applies to primer N (-1 for none) */
40   char* *names; /* pointers to primer names */
41   void *rawData; /* for above pointers to point into */
42   int np;     /* total number of primers */
43   int maxLen; /* length of longest primer */
44 } AllPrimers;
freeAllPrimers(AllPrimers ap)45 void freeAllPrimers(AllPrimers ap) {
46   if(ap.np >= 0) {
47     free(ap.names); free(ap.forward.p64);
48     free(ap.backward.p64); free(ap.tags.p64);
49     free(ap.whichTag); free(ap.rawData);
50   }
51 }
sizeofMDPrimer(int maxLen)52 static inline int sizeofMDPrimer(int maxLen) {
53   return (maxLen <= 64) ? sizeof(MaybeDegeneratePrimer64):sizeof(MaybeDegeneratePrimer128);
54 }
loadFASTA(FILE * f)55 AllPrimers loadFASTA(FILE *f) {
56   AllPrimers r; /* sets r.np=-1 on failure */
57   char *loadAndClose(FILE *f);
58   int numPrimers(const char*,int*,int*); /*load-common.c*/
59   r.rawData = loadAndClose(f);
60   if(!r.rawData) {
61     fputs("Could not load file\n",stderr); r.np = -1;
62     return r;
63   }
64   int numTags=0;
65   r.np = numPrimers(r.rawData, &r.maxLen, &numTags);
66   if(r.np<0) return r; /* err already printed */
67   r.forward.p64 = malloc(r.np * sizeofMDPrimer(r.maxLen));
68   r.backward.p64 = malloc(r.np*sizeofMDPrimer(r.maxLen));
69   r.whichTag = malloc(r.np*sizeof(int));
70   r.tags.p64 = calloc(numTags,sizeofMDPrimer(r.maxLen));
71   r.names = malloc(r.np*sizeof(char*));
72   if(memFail(r.forward.p64,r.backward.p64,r.tags.p64,r.names,r.rawData,_memFail)) { r.np=-1; return r; }
73   if(r.maxLen <= 64) {
74     parseFASTA64(r.rawData,r.forward.p64,r.tags.p64,r.whichTag,r.names);
75     int i; for(i=0; i<r.np; i++) r.backward.p64[i] = MaybeDegeneratePrimerReverse64(r.forward.p64[i]);
76   }
77   else {
78     parseFASTA128(r.rawData,r.forward.p128,r.tags.p128,r.whichTag,r.names);
79     int i; for(i=0; i<r.np; i++) r.backward.p128[i] = MaybeDegeneratePrimerReverse128(r.forward.p128[i]);
80   }
81   return r;
82 }
addTags(AllPrimers ap)83 void addTags(AllPrimers ap) {
84   int i;
85   if(ap.maxLen <= 64) {
86     for(i=0; i<ap.np; i++) if(ap.whichTag[i]>=0) {
87       MaybeDegeneratePrimer64 tag=ap.tags.p64[ap.whichTag[i]];
88       MaybeDegeneratePrimerTag64(ap.forward.p64+i,tag);
89       MaybeDegeneratePrimerTag64B(ap.backward.p64+i,tag);
90     }
91   } else
92     for(i=0; i<ap.np; i++) if(ap.whichTag[i]>=0) {
93       MaybeDegeneratePrimer128 tag=ap.tags.p128[ap.whichTag[i]];
94       MaybeDegeneratePrimerTag128(ap.forward.p128+i,tag);
95       MaybeDegeneratePrimerTag128B(ap.backward.p128+i,tag);
96     }
97 }
removeTags(AllPrimers ap)98 void removeTags(AllPrimers ap) {
99   int i;
100   if(ap.maxLen <= 64) {
101     for(i=0; i<ap.np; i++) if(ap.whichTag[i]>=0) {
102       MaybeDegeneratePrimer64 tag=ap.tags.p64[ap.whichTag[i]];
103       MaybeDegeneratePrimerRmTag64(ap.forward.p64+i,tag);
104       MaybeDegeneratePrimerRmTag64B(ap.backward.p64+i,tag);
105     }
106   } else
107     for(i=0; i<ap.np; i++) if(ap.whichTag[i]>=0) {
108       MaybeDegeneratePrimer128 tag=ap.tags.p128[ap.whichTag[i]];
109       MaybeDegeneratePrimerRmTag128(ap.forward.p128+i,tag);
110       MaybeDegeneratePrimerRmTag128B(ap.backward.p128+i,tag);
111     }
112 }
printCounts(AllPrimers ap,FILE * f)113 void printCounts(AllPrimers ap,FILE *f) {
114   if(ap.maxLen <= 64)
115     counts64(ap.forward.p64,ap.backward.p64,ap.np,f);
116   else counts128(ap.forward.p128,ap.backward.p128,ap.np,f);
117 }
printPooledCounts(AllPrimers ap,const int * pools,const int * precalcScores)118 int printPooledCounts(AllPrimers ap,const int *pools,const int *precalcScores) { /* precalcScores==NULL ok */
119   if(ap.maxLen <= 64)
120     return pCounts64(ap.forward.p64,ap.backward.p64,ap.np,pools,precalcScores);
121   else return pCounts128(ap.forward.p128,ap.backward.p128,ap.np,pools,precalcScores);
122 }
printBonds(AllPrimers ap,FILE * f,int threshold,const int * pools)123 void printBonds(AllPrimers ap,FILE *f,int threshold,const int *pools) {
124   if(ap.maxLen <= 64)
125     printBonds64(ap.forward.p64,ap.backward.p64,ap.np,f,threshold,ap.names,pools);
126   else printBonds128(ap.forward.p128,ap.backward.p128,ap.np,f,threshold,ap.names,pools);
127   if (f!=stdout) fclose(f);
128 }
triangle(AllPrimers ap)129 int* triangle(AllPrimers ap) {
130   if(ap.maxLen <= 64)
131     return triangle64(ap.forward.p64,ap.backward.p64,ap.np);
132   else return triangle128(ap.forward.p128,ap.backward.p128,ap.np);
133 }
134 
135 void printFASTA(AllPrimers ap,FILE *f,const int *pools,const int poolNo);
printBasesMaybeD(AllPrimers ap,int n,FILE * f)136 void printBasesMaybeD(AllPrimers ap,int n,FILE *f) {
137   if(ap.maxLen <= 64)
138     printBases64MaybeD(ap.forward.p64[n],f);
139   else printBases128MaybeD(ap.forward.p128[n],f);
140 }
141 
NumPossibilities_32bases(AllPrimers ap,int n)142 int NumPossibilities_32bases(AllPrimers ap,int n) {
143   /* forward or backward should yield same result */
144   if(ap.maxLen <= 64) return NumPossibilities64MaybeD_32bases(ap.forward.p64[n]);
145   else return NumPossibilities128MaybeD_32bases(ap.forward.p128[n]);
146 }
Make2bit(AllPrimers ap,int n,int useBackward,int doComplement,ULL * out,ULL * outValid,int possNo,int nPoss)147 int Make2bit(AllPrimers ap,int n,int useBackward,int doComplement,ULL *out,ULL *outValid,int possNo,int nPoss) {
148   if(ap.maxLen <= 64) {
149     MaybeDegeneratePrimer64 p = useBackward ? ap.backward.p64[n] : ap.forward.p64[n];
150     if(doComplement) PrimerComplement64MaybeD(&p);
151     return Make2bitFrom64D(upgradeToDegenerate64(p),out,outValid,possNo,nPoss);
152   } else {
153     MaybeDegeneratePrimer128 p = useBackward ? ap.backward.p128[n] : ap.forward.p128[n];
154     if(doComplement) PrimerComplement128MaybeD(&p);
155     return Make2bitFrom128D(upgradeToDegenerate128(p),out,outValid,possNo,nPoss);
156   }
157 }
158 
dGprintBonds(AllPrimers ap,FILE * f,float threshold,const int * pools,const float * table)159 void dGprintBonds(AllPrimers ap,FILE *f,float threshold,const int *pools,const float *table) {
160   if(ap.maxLen <= 64)
161     dGprintBonds64(ap.forward.p64,ap.backward.p64,ap.np,f,threshold,ap.names,pools,table);
162   else dGprintBonds128(ap.forward.p128,ap.backward.p128,ap.np,f,threshold,ap.names,pools,table);
163   if (f!=stdout) fclose(f);
164 }
dGtriangle(AllPrimers ap,const float * table)165 int* dGtriangle(AllPrimers ap,const float *table) {
166   if(ap.maxLen <= 64)
167     return dGtriangle64(ap.forward.p64,ap.backward.p64,ap.np,table);
168   else return dGtriangle128(ap.forward.p128,ap.backward.p128,ap.np,table);
169 }
dGprintPooledCounts(AllPrimers ap,const int * pools,const int * precalcScores,FILE * f)170 int dGprintPooledCounts(AllPrimers ap,const int *pools,const int *precalcScores,FILE *f) {
171   if(ap.maxLen <= 64)
172     return dGpCounts64(ap.np,pools,precalcScores,f);
173   else return dGpCounts128(ap.np,pools,precalcScores,f);
174 }
dGandScoreCounts(AllPrimers ap,const float * table,FILE * f)175 void dGandScoreCounts(AllPrimers ap,const float *table,FILE *f) {
176   if(ap.maxLen <= 64)
177     return dGsCounts64(ap.forward.p64,ap.backward.p64,ap.np,table,f);
178   else return dGsCounts128(ap.forward.p128,ap.backward.p128,ap.np,table,f);
179 }
180 
printStats(AllPrimers ap,const int * pools,const int * precalcScores,FILE * f)181 void printStats(AllPrimers ap,const int *pools,const int *precalcScores,FILE *f) { /* precalcScores==NULL ok */
182   if(ap.maxLen <= 64)
183     pStats64(ap.forward.p64,ap.backward.p64,ap.np,pools,precalcScores,f);
184   else pStats128(ap.forward.p128,ap.backward.p128,ap.np,pools,precalcScores,f);
185 }
dGprintStats(AllPrimers ap,const int * pools,const int * precalcScores,FILE * f)186 void dGprintStats(AllPrimers ap,const int *pools,const int *precalcScores,FILE *f) { /* precalcScores==NULL NOT ok in current implementation */
187   if(ap.maxLen <= 64)
188     pStats64dG(ap.np,pools,precalcScores,f);
189   else pStats128dG(ap.np,pools,precalcScores,f);
190 }
191