THIRD UPDATE​The function regexMultiplexerSpecs scans the lengths of all primers under consideration and produces HashTable multiplexerSpecsHash. The hashtable is keyed by
ϵ
accept
. The hashtable values are a list of data pairs needed downstream. The first element of each pair is specification for construction of a regex from primers with length associated with
ϵ
accept
. This specification has the form {first,offset,last}. The “first” value specifies what character position in the primer string will be used for the leading character of the regex. These are positive values. The “last” specifies what character position in the primer string will be the final character of the regex. These are negative values; i.e. -1 is the last primer character, -2 is the second from last primer character, etc. The “offset” is added to the primer length to specify the number of intervening characters between first and last regex characters. The second pair element is the list {
ϵ
accept
, wA} which is needed downstream with the first pair element to specify a filename.​For example, the primer TTTCCATATTAACAGG has 16 bp and thus
ϵ
accept
= 4. regexMultiplexerSpecs produces a list of 41 pairs for this size, one of which is {{3,1,-1},{4,1}}. The second element informs that this is one of possibly multiple specifications for wA = 1. The first element specifies a regex construction, which in this example yields “T.{17,17}G”.​Here is example code:
(*producesregexspecificationsfor
ϵ
accept
valuesdeterminedfromprimerlengths*)​​(*placesspecificationsinaHashTablewith
ϵ
accept
askey*)​​(*primerlengthsmustbe≥6bp*)​​​​testPrimers={​​"TTTCCATATTAACAGG",​​"GTAATCCCCCGAGAAAG",​​"TGTAAAACGACGGCCAGT",​​"GCTTCCGATGCTGCTCTTA",​​"AAGACATTGAGACATACCAG",​​"CTTATGAAAACTCGGTAGAAG",​​"GTATTGGATCTTGATTATGTTT",​​"ATGTTATAGTTGAGTGAGGATAA",​​"CAGATGAGGTTGACGATGTTATTG",​​"AGTCTTAACCAGTAGGGGATCCGTC",​​"CCTGACATAAGTACGCCGAGACGCCT",​​"CAGCCTGTGTTCTTGAACAGGTCTTCA",​​"CAGAACTAGCGTGGGGGTGTTGCGTCCT",​​"CGCCGTCACTAGAAGCCATCTTTCGCTCC",​​"CATTAGAAAAATCTCTTTCCCCATAAGATG",​​"AATCCCGGTCCCTATTTGTGCCGGCGATGTA",​​"ACAGGAATTCTGATGCCGAGTGTGGAACCTGC"​​};​​ϵAcceptValues=Union[Max[4,Round[StringLength[#]/5]]&/@testPrimers];​​multiplexerSpecsHash=CreateDataStructure["HashTable"];​​multiplexerTreeHash=CreateDataStructure["HashTable"];(*forvisualization*)​​​​Do[​​level1=Table[{ϵAccept,wA},{wA,-ϵAccept,ϵAccept}];​​level1Count=Length[level1];​​​​(*elementsare{1stletterindex,internallengthoffset,lastletterindex}*)​​level2=Table[​​Which[​​spec[[2]]<0,Join[​​Table[{{1-spec[[2]]-i,spec[[2]]+i-2,-1},spec},{i,0,-1-spec[[2]]}],​​{{{1,spec[[2]]-2,-1},spec}},​​Table[{{1,spec[[2]]+i-2,spec[[2]]-1+i},spec},{i,0,-1-spec[[2]]}]​​],​​spec[[2]]0,{{{1,-2,-1},spec}},​​spec[[2]]>0,If[spec[[1]]spec[[2]],​​{{{1,spec[[2]]-2,-1},spec}},​​(*else
ϵ
accept
>wA*)​​Join[​​{{{1,spec[[2]]-2,-1},spec}},​​Table[{{i+1,i+spec[[2]]-2,-1},spec},{i,1,spec[[1]]-spec[[2]]}],​​Table[{{1,i+spec[[2]]-2,-1-i},spec},{i,1,spec[[1]]-spec[[2]]}]​​]​​]​​],​​{spec,level1}​​];​​multiplexerSpecsHash["Insert",ϵAcceptFlatten[level2,1]];​​multiplexerTreeHash["Insert",ϵAccept{level1Count,level1,level2}];​​{},​​{ϵAccept,ϵAcceptValues}​​];
Some statistics from the example:
ϵ
accept
# of specs
example spec: {regex params,​{​
ϵ
accept
​, wA}​}
4
41
{{3,1,-1},{4,1}}
5
61
{{5,3,-1},{5,1}}
6
85
{{3,-4,-1},{6,-2}}
A visualization of the specs for
ϵ
accept
= 4 :
regexMultiplexerSpecs is called early in the main application program, whose present version is here:
kernelCount=9;(*dependsonnumberofCPUcores,installedRAM,andWolframlicense*)​​multiplexerSpecsHash=regexMultiplexerSpecs[primers];​​(*producesspecsfor
ϵ
accept
=4,5,...*)​​(*typically41to85,rarelyafew1000*)​​Do[​​ chrSequence=Import[chrFileSpec];​​ Do[​​ regexSpecifications=multiplexer[primer,multiplexerSpecsHash];​​ InitKernels[kernelCount];​​ ParallelDo[​​ regexString=regexSpec[[1]];​​ positions=StringPosition[chrSequence,RegularExpression[regexString]];​​ (*1000'swillbereturned*)​​ vettedCandidates=OrderedPartsCalc[positions,regexSpec,chrSequence];​​ exportFile=ExportFileCalc[regexSpec];​​ Export[exportFile,vettedCandidates],​​ {regexSpec,regexSpecifications},Method"CoarsestGrained"​​ ];​​ CloseKernels[];​​ regexSpecifications=Null;​​ Pause[1],​​ {primer,primers}(*afewtoafew1000*)​​ ];​​ chrSequence=Null,​​ {chrFileSpec,chromosomeFiles}(*typicallyaboutadozen*)​​];​​
Two levels downstream, the function multiplexer uses the output of regexMultiplexerSpecs to produce regexSpecifications. Here is example code:
In[]:=
(*multiplexer*)​​primer=testPrimers[[1]];​​primerBp=StringLength[primer];​​ϵAccept=Max[4,Round[StringLength[primer]/5]];​​multiplexerSpecs=multiplexerSpecsHash["Lookup",ϵAccept];​​regexSpecifications=Table[​​{(StringTake[primer,{mSpec[[1,1]],mSpec[[1,1]]}]<>".{"<>#<>","<>#<>"}"<>StringTake[primer,{mSpec[[1,3]],mSpec[[1,3]]}])&[ToString[primerBp+mSpec[[1,2]]]],mSpec[[2]],mSpec[[1]],primer},​​{mSpec,multiplexerSpecs}​​];​​​​Print[regexSpecifications//Column];