summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/lualatex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-10-18 22:52:50 +0000
committerKarl Berry <karl@freefriends.org>2012-10-18 22:52:50 +0000
commit501d1837aeddc838bf1ea0898f94d6b9435aa205 (patch)
tree4eaea5c3364c6e11708179ed88ed224158f88e86 /Master/texmf-dist/tex/lualatex
parent3ab72bbc8f60fc642a7dd422ed357c1b5dc0ec23 (diff)
pgfmolbio 0.2 (7oct12)
git-svn-id: svn://tug.org/texlive/trunk@28023 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/lualatex')
-rw-r--r--Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.lua624
-rw-r--r--Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex233
-rw-r--r--Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex40
-rw-r--r--Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.lua810
-rw-r--r--Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.tex799
-rw-r--r--Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty52
6 files changed, 2170 insertions, 388 deletions
diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.lua b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.lua
index 59d500cc0c0..4919aeab702 100644
--- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.lua
+++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.lua
@@ -6,7 +6,7 @@
--
-- pgfmolbio.dtx (with options: `pmb-chr-lua')
--
--- Copyright (C) 2011 by Wolfgang Skala
+-- Copyright (C) 2012 by Wolfgang Skala
--
-- This work may be distributed and/or modified under the
-- conditions of the LaTeX Project Public License, either version 1.3
@@ -18,27 +18,29 @@
--
module("pgfmolbio.chromatogram", package.seeall)
+
+if luatexbase then
+ luatexbase.provides_module{
+ name = "pgfmolbio.chromatogram",
+ version = 0.2,
+ date = "2012/10/01",
+ description = "DNA sequencing chromatograms",
+ author = "Wolfgang Skala",
+ copyright = "Wolfgang Skala",
+ license = "LPPL",
+ }
+end
+
local ALL_BASES = {"A", "C", "G", "T"}
local PGFKEYS_PATH = "/pgfmolbio/chromatogram/"
-local header, samples,
- peaks, parms,
- selectedPeaks,
- lastScfFile
-
-local function baseToSampleIndex (baseIndex)
- local result = tonumber(baseIndex)
- if result then
- return result
- else
- result = string.match(baseIndex, "base%s*(%d+)")
- if tonumber(result) then
- return peaks[tonumber(result)].offset
- end
- end
-end
+local stringToDim = pgfmolbio.stringToDim
+local dimToString = pgfmolbio.dimToString
+local packageError = pgfmolbio.packageError
+local packageWarning = pgfmolbio.packageWarning
+local getRange = pgfmolbio.getRange
-local function stdProbStyle (prob)
+local function stdProbStyle(prob)
local color = ""
if prob >= 0 and prob < 10 then
color = "black"
@@ -52,21 +54,85 @@ local function stdProbStyle (prob)
return "ultra thick, " .. color
end
-local function findBasesInStr (target)
+local function findBasesInStr(target)
if not target then return end
local result = {}
for _, v in ipairs(ALL_BASES) do
- if string.find(string.upper(target), v) then
+ if target:upper():find(v) then
table.insert(result, v)
end
end
return result
end
-function getMinMaxProbability ()
+local function readInt(file, n, offset)
+ if offset then file:seek("set", offset) end
+ local result = 0
+ for i = 1, n do
+ result = result * 0x100 + file:read(1):byte()
+ end
+ return result
+end
+
+Chromatogram = {}
+
+function Chromatogram:new()
+ newChromatogram = {
+ sampleMin = 1,
+ sampleMax = 500,
+ sampleStep = 1,
+ peakMin = -1,
+ peakMax = -1,
+ xUnit = stringToDim("0.2mm"),
+ yUnit = stringToDim("0.01mm"),
+ samplesPerLine = 500,
+ baselineSkip = stringToDim("3cm"),
+ canvasHeight = stringToDim("2cm"),
+ traceStyle = {
+ A = PGFKEYS_PATH .. "trace A style",
+ C = PGFKEYS_PATH .. "trace C style",
+ G = PGFKEYS_PATH .. "trace G style",
+ T = PGFKEYS_PATH .. "trace T style"
+ },
+ tickStyle = {
+ A = PGFKEYS_PATH .. "tick A style",
+ C = PGFKEYS_PATH .. "tick C style",
+ G = PGFKEYS_PATH .. "tick G style",
+ T = PGFKEYS_PATH .. "tick T style"
+ },
+ tickLength = stringToDim("1mm"),
+ baseLabelText = {
+ A = "\\pgfkeysvalueof{" .. PGFKEYS_PATH .. "base label A text}",
+ C = "\\pgfkeysvalueof{" .. PGFKEYS_PATH .. "base label C text}",
+ G = "\\pgfkeysvalueof{" .. PGFKEYS_PATH .. "base label G text}",
+ T = "\\pgfkeysvalueof{" .. PGFKEYS_PATH .. "base label T text}"
+ },
+ baseLabelStyle = {
+ A = PGFKEYS_PATH .. "base label A style",
+ C = PGFKEYS_PATH .. "base label C style",
+ G = PGFKEYS_PATH .. "base label G style",
+ T = PGFKEYS_PATH .. "base label T style"
+ },
+ showBaseNumbers = true,
+ baseNumberMin = -1,
+ baseNumberMax = -1,
+ baseNumberStep = 10,
+ probDistance = stringToDim("0.8cm"),
+ probStyle = stdProbStyle,
+ tracesDrawn = ALL_BASES,
+ ticksDrawn = "ACGT",
+ baseLabelsDrawn = "ACGT",
+ probabilitiesDrawn = "ACGT",
+ }
+ setmetatable(newChromatogram, self)
+ self.__index = self
+ return newChromatogram
+end
+
+function Chromatogram:getMinMaxProbability()
local minProb = 0
local maxProb = 0
- for _, currPeak in ipairs(selectedPeaks) do
+ for _, currPeak in ipairs(self.selectedPeaks) do
for __, currProb in pairs(currPeak.prob) do
if currProb > maxProb then maxProb = currProb end
if currProb < minProb then minProb = currProb end
@@ -75,232 +141,266 @@ function getMinMaxProbability ()
return minProb, maxProb
end
-local function getRange (rangeInput, regExp)
- local lower, upper = string.match(rangeInput, regExp)
- local step = string.match(rangeInput, "step%s*(%d*)")
- return lower, upper, step
-end
+function Chromatogram:getSampleAndPeakIndex(baseIndex, isLowerLimit)
+ local sampleId, peakId
-local function readInt (file, n, offset)
- if offset then file:seek("set", offset) end
- local result = 0
- for i = 1, n do
- result = result * 0x100 + string.byte(file:read(1))
+ sampleId = tonumber(baseIndex)
+ if sampleId then
+ for i, v in ipairs(self.peaks) do
+ if isLowerLimit then
+ if v.offset >= sampleId then
+ peakId = i
+ break
+ end
+ else
+ if v.offset == sampleId then
+ peakId = i
+ break
+ elseif v.offset > sampleId then
+ peakId = i - 1
+ break
+ end
+ end
+ end
+ else
+ peakId = tonumber(baseIndex:match("base%s*(%d+)"))
+ if peakId then
+ sampleId = self.peaks[peakId].offset
+ end
end
- return result
+ return sampleId, peakId
end
-local function evaluateScfFile (file)
- samples = {A = {}, C = {}, G = {}, T = {}}
- peaks = {}
- header = {
- magicNumber = readInt(file, 4, 0),
- samplesNumber = readInt(file, 4),
- samplesOffset = readInt(file, 4),
- basesNumber = readInt(file, 4),
- leftClip = readInt(file, 4),
- rightClip = readInt(file, 4),
- basesOffset = readInt(file, 4),
- comments = readInt(file, 4),
- commentsOffset = readInt(file, 4),
- version = readInt(file, 4),
- sampleSize = readInt(file, 4),
- codeSet = readInt(file, 4),
- privateSize = readInt(file, 4),
- privateOffset = readInt(file, 4)
- }
- if header.magicNumber ~= 0x2E736366 then
- tex.error("Magic number in scf file '" .. lastScfFile .. "' corrupt!")
- end
- if header.version ~= 0x332E3030 then
- tex.error("Scf file '" .. lastScfFile .. "' is not version 3.00!")
- end
-
- file:seek("set", header.samplesOffset)
- for baseIndex, baseName in ipairs(ALL_BASES) do
- for i = 1, header.samplesNumber do
- samples[baseName][i] = readInt(file, header.sampleSize)
+function Chromatogram:readScfFile(filename)
+ if filename ~= self.lastScfFile then
+ self.lastScfFile = filename
+ local scfFile, errorMsg = io.open(filename, "rb")
+ if not scfFile then packageError(errorMsg) end
+
+ self.samples = {A = {}, C = {}, G = {}, T = {}}
+ self.peaks = {}
+ self.header = {
+ magicNumber = readInt(scfFile, 4, 0),
+ samplesNumber = readInt(scfFile, 4),
+ samplesOffset = readInt(scfFile, 4),
+ basesNumber = readInt(scfFile, 4),
+ leftClip = readInt(scfFile, 4),
+ rightClip = readInt(scfFile, 4),
+ basesOffset = readInt(scfFile, 4),
+ comments = readInt(scfFile, 4),
+ commentsOffset = readInt(scfFile, 4),
+ version = readInt(scfFile, 4),
+ sampleSize = readInt(scfFile, 4),
+ codeSet = readInt(scfFile, 4),
+ privateSize = readInt(scfFile, 4),
+ privateOffset = readInt(scfFile, 4)
+ }
+ if self.header.magicNumber ~= 0x2E736366 then
+ packageError(
+ "Magic number in scf scfFile '" ..
+ self.lastScfFile ..
+ "' corrupt!"
+ )
end
+ if self.header.version ~= 0x332E3030 then
+ packageError(
+ "Scf scfFile '" ..
+ self.lastScfFile ..
+ "' is not version 3.00!"
+ )
+ end
+ scfFile:seek("set", self.header.samplesOffset)
+ for baseIndex, baseName in ipairs(ALL_BASES) do
+ for i = 1, self.header.samplesNumber do
+ self.samples[baseName][i] =
+ readInt(scfFile, self.header.sampleSize)
+ end
- for _ = 1, 2 do
- local preValue = 0
- for i = 1, header.samplesNumber do
- samples[baseName][i] = samples[baseName][i] + preValue
- if samples[baseName][i] > 0xFFFF then
- samples[baseName][i] = samples[baseName][i] - 0x10000
+ for _ = 1, 2 do
+ local preValue = 0
+ for i = 1, self.header.samplesNumber do
+ self.samples[baseName][i] = self.samples[baseName][i] + preValue
+ if self.samples[baseName][i] > 0xFFFF then
+ self.samples[baseName][i] = self.samples[baseName][i] - 0x10000
+ end
+ preValue = self.samples[baseName][i]
end
- preValue = samples[baseName][i]
end
end
- end
-
- for i = 1, header.basesNumber do
- peaks[i] = {
- offset = readInt(file, 4),
- prob = {A, C, G, T},
- base
- }
- end
+ for i = 1, self.header.basesNumber do
+ self.peaks[i] = {
+ offset = readInt(scfFile, 4),
+ prob = {A, C, G, T},
+ base
+ }
+ end
- for i = 1, header.basesNumber do
- peaks[i].prob.A = readInt(file, 1)
- end
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].prob.A = readInt(scfFile, 1)
+ end
- for i = 1, header.basesNumber do
- peaks[i].prob.C = readInt(file, 1)
- end
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].prob.C = readInt(scfFile, 1)
+ end
- for i = 1, header.basesNumber do
- peaks[i].prob.G = readInt(file, 1)
- end
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].prob.G = readInt(scfFile, 1)
+ end
- for i = 1, header.basesNumber do
- peaks[i].prob.T = readInt(file, 1)
- end
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].prob.T = readInt(scfFile, 1)
+ end
- for i = 1, header.basesNumber do
- peaks[i].base = string.char(readInt(file, 1))
- end
-end
+ for i = 1, self.header.basesNumber do
+ self.peaks[i].base = string.char(readInt(scfFile, 1))
+ end
-function readScfFile (filename)
- if filename ~= lastScfFile then
- lastScfFile = filename
- local scfFile, errorMsg = io.open(filename, "rb")
- if not scfFile then tex.error(errorMsg) end
- evaluateScfFile(scfFile)
scfFile:close()
end
end
-function setParameters (newParms)
- local sampleRangeMin, sampleRangeMax, sampleRangeStep =
- getRange(
- newParms.sampleRange or "1 to 500 step 1",
- "([base]*%s*%d+)%s*to%s*([base]*%s*%d+)"
- )
- local baseNumberRangeMin, baseNumberRangeMax, baseNumberRangeStep =
- getRange(
- newParms.baseNumberRange or "auto to auto step 10",
- "([auto%d]*)%s+to%s+([auto%d]*)"
- )
-
- parms = {
- sampleMin = baseToSampleIndex(sampleRangeMin) or 1,
- sampleMax = baseToSampleIndex(sampleRangeMax) or 500,
- sampleStep = sampleRangeStep or 1,
- xUnit = newParms.xUnit or dimen("0.2mm")[1],
- yUnit = newParms.yUnit or dimen("0.01mm")[1],
- samplesPerLine = newParms.samplesPerLine or 500,
- baselineSkip = newParms.baselineSkip or dimen("3cm")[1],
- canvasHeight= newParms.canvasHeight or dimen("2cm")[1],
- traceStyle = {
- A = PGFKEYS_PATH .. "trace A style@style",
- C = PGFKEYS_PATH .. "trace C style@style",
- G = PGFKEYS_PATH .. "trace G style@style",
- T = PGFKEYS_PATH .. "trace T style@style"
- },
- tickStyle = {
- A = PGFKEYS_PATH .. "tick A style@style",
- C = PGFKEYS_PATH .. "tick C style@style",
- G = PGFKEYS_PATH .. "tick G style@style",
- T = PGFKEYS_PATH .. "tick T style@style"
- },
- tickLength = newParms.tickLength or dimen("1mm")[1],
- baseLabelText = {
- A = "\\csname pmb@chr@base label A text\\endcsname",
- C = "\\csname pmb@chr@base label C text\\endcsname",
- G = "\\csname pmb@chr@base label G text\\endcsname",
- T = "\\csname pmb@chr@base label T text\\endcsname"
- },
- baseLabelStyle = {
- A = PGFKEYS_PATH .. "base label A style@style",
- C = PGFKEYS_PATH .. "base label C style@style",
- G = PGFKEYS_PATH .. "base label G style@style",
- T = PGFKEYS_PATH .. "base label T style@style"
- },
- showBaseNumbers = newParms.showBaseNumbers,
- baseNumberMin = tonumber(baseNumberRangeMin) or -1,
- baseNumberMax = tonumber(baseNumberRangeMax) or -1,
- baseNumberStep = tonumber(baseNumberRangeStep) or 10,
- probDistance = newParms.probDistance or dimen("0.8cm")[1],
- probStyle = newParms.probStyle or stdProbStyle,
- tracesDrawn = findBasesInStr(newParms.tracesDrawn) or ALL_BASES,
- ticksDrawn = newParms.ticksDrawn or "ACGT",
- baseLabelsDrawn = newParms.baseLabelsDrawn or "ACGT",
- probabilitiesDrawn = newParms.probabilitiesDrawn or "ACGT",
- coordUnit = "mm",
- coordFmtStr = "%s%s"
+function Chromatogram:setParameters(newParms)
+ local keyHash = {
+ sampleRange = function(v)
+ local sampleRangeMin, sampleRangeMax, sampleRangeStep =
+ getRange(
+ v:trim(),
+ "^([base]*%s*%d+)%s*%-",
+ "%-%s*([base]*%s*%d+)",
+ "step%s*(%d+)$"
+ )
+ self.sampleMin, self.peakMin =
+ self:getSampleAndPeakIndex(sampleRangeMin, true)
+ self.sampleMax, self.peakMax =
+ self:getSampleAndPeakIndex(sampleRangeMax, false)
+ if self.sampleMin >= self.sampleMax then
+ packageError("Sample range is smaller than 1.")
+ end
+ self.sampleStep = sampleRangeStep or self.sampleStep
+ end,
+ xUnit = stringToDim,
+ yUnit = stringToDim,
+ samplesPerLine = tonumber,
+ baselineSkip = stringToDim,
+ canvasHeight = stringToDim,
+ tickLength = stringToDim,
+ showBaseNumbers = function(v)
+ if v == "true" then return true else return false end
+ end,
+ baseNumberRange = function(v)
+ local baseNumberRangeMin, baseNumberRangeMax, baseNumberRangeStep =
+ getRange(
+ v:trim(),
+ "^([auto%d]*)%s+%-",
+ "%-%s+([auto%d]*$)"
+ )
+ if tonumber(baseNumberRangeMin) then
+ self.baseNumberMin = tonumber(baseNumberRangeMin)
+ else
+ self.baseNumberMin = self.peakMin
+ end
+ if tonumber(baseNumberRangeMax) then
+ self.baseNumberMax = tonumber(baseNumberRangeMax)
+ else
+ self.baseNumberMax = self.peakMax
+ end
+ if self.baseNumberMin >= self.baseNumberMax then
+ packageError("Base number range is smaller than 1.")
+ end
+ if self.baseNumberMin < self.peakMin then
+ self.baseNumberMin = self.peakMin
+ packageWarning("Lower base number range is smaller than lower sample range. It was adjusted to " .. self.baseNumberMin .. ".")
+ end
+ if self.baseNumberMax > self.peakMax then
+ self.baseNumberMax = self.peakMax
+ packageWarning("Upper base number range exceeds upper sample range. It was adjusted to " .. self.baseNumberMax .. ".")
+ end
+ self.baseNumberStep = tonumber(baseNumberRangeStep)
+ or self.baseNumberStep
+ end,
+ probDistance = stringToDim,
+ probStyle = function(v) return v end,
+ tracesDrawn = findBasesInStr,
+ ticksDrawn = function(v) return v end,
+ baseLabelsDrawn = function(v) return v end,
+ probabilitiesDrawn = function(v) return v end,
+ probStyle = function(v) return v end
}
+ for key, value in pairs(newParms) do
+ if keyHash[key] then
+ self[key] = keyHash[key](value)
+ end
+ end
end
-function printTikzChromatogram ()
- selectedPeaks = {}
+function Chromatogram:printTikzChromatogram()
+ if pgfmolbio.errorCatched then return end
+ self.selectedPeaks = {}
local tIndex = 1
- for rPeakIndex, currPeak in ipairs(peaks) do
- if currPeak.offset >= parms.sampleMin
- and currPeak.offset <= parms.sampleMax then
- selectedPeaks[tIndex] = {
- offset = currPeak.offset + 1 - parms.sampleMin,
+ for rPeakIndex, currPeak in ipairs(self.peaks) do
+ if currPeak.offset >= self.sampleMin
+ and currPeak.offset <= self.sampleMax then
+ self.selectedPeaks[tIndex] = {
+ offset = currPeak.offset + 1 - self.sampleMin,
base = currPeak.base,
prob = currPeak.prob,
baseIndex = rPeakIndex,
- probXRight = parms.sampleMax + 1 - parms.sampleMin
+ probXRight = self.sampleMax + 1 - self.sampleMin
}
if tIndex > 1 then
- selectedPeaks[tIndex-1].probXRight =
- (selectedPeaks[tIndex-1].offset
- + selectedPeaks[tIndex].offset) / 2
+ self.selectedPeaks[tIndex-1].probXRight =
+ (self.selectedPeaks[tIndex-1].offset
+ + self.selectedPeaks[tIndex].offset) / 2
end
tIndex = tIndex + 1
end
end
if tIndex > 1 then
- if parms.baseNumberMin == -1 then
- parms.baseNumberMin = selectedPeaks[1].baseIndex
+ if self.baseNumberMin == -1 then
+ self.baseNumberMin = self.selectedPeaks[1].baseIndex
end
- if parms.baseNumberMax == -1 then
- parms.baseNumberMax = selectedPeaks[tIndex-1].baseIndex
+ if self.baseNumberMax == -1 then
+ self.baseNumberMax = self.selectedPeaks[tIndex-1].baseIndex
end
end
- local samplesLeft = parms.sampleMax - parms.sampleMin + 1
+ local samplesLeft = self.sampleMax - self.sampleMin + 1
local currLine = 0
while samplesLeft > 0 do
- local yLower = -currLine * parms.baselineSkip
- local yUpper = -currLine * parms.baselineSkip + parms.canvasHeight
+ local yLower = -currLine * self.baselineSkip
+ local yUpper = -currLine * self.baselineSkip + self.canvasHeight
local xRight =
- (math.min(parms.samplesPerLine, samplesLeft) - 1) * parms.xUnit
+ (math.min(self.samplesPerLine, samplesLeft) - 1) * self.xUnit
tex.sprint(
- "\\draw[" .. PGFKEYS_PATH .. "canvas style@style] (" ..
- number.todimen(0, parms.coordUnit, parms.coordFmtStr) ..
+ "\n\t\\draw [" .. PGFKEYS_PATH .. "canvas style] (" ..
+ dimToString(0) ..
", " ..
- number.todimen(yLower, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(yLower) ..
") rectangle (" ..
- number.todimen(xRight, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(xRight) ..
", " ..
- number.todimen(yUpper, parms.coordUnit, parms.coordFmtStr) ..
- ");\n"
+ dimToString(yUpper) ..
+ ");"
)
- samplesLeft = samplesLeft - parms.samplesPerLine
+ samplesLeft = samplesLeft - self.samplesPerLine
currLine = currLine + 1
end
- for _, baseName in ipairs(parms.tracesDrawn) do
- tex.sprint("\\draw[" .. parms.traceStyle[baseName] .. "] ")
- local currSampleIndex = parms.sampleMin
+ for _, baseName in ipairs(self.tracesDrawn) do
+ tex.sprint("\n\t\\draw [" .. self.traceStyle[baseName] .. "] ")
+ local currSampleIndex = self.sampleMin
local sampleX = 1
local x = 0
local y = 0
local currLine = 0
local firstPointInLine = true
- while currSampleIndex <= parms.sampleMax do
- x = ((sampleX - 1) % parms.samplesPerLine) * parms.xUnit
- y = samples[baseName][currSampleIndex] * parms.yUnit
- - currLine * parms.baselineSkip
- if sampleX % parms.sampleStep == 0 then
+ while currSampleIndex <= self.sampleMax do
+ x = ((sampleX - 1) % self.samplesPerLine) * self.xUnit
+ y = self.samples[baseName][currSampleIndex] * self.yUnit
+ - currLine * self.baselineSkip
+ if sampleX % self.sampleStep == 0 then
if not firstPointInLine then
tex.sprint(" -- ")
else
@@ -308,20 +408,20 @@ function printTikzChromatogram ()
end
tex.sprint(
"(" ..
- number.todimen(x, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(x) ..
", " ..
- number.todimen(y, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(y) ..
")"
)
end
- if sampleX ~= parms.sampleMax + 1 - parms.sampleMin then
- if sampleX >= (currLine + 1) * parms.samplesPerLine then
+ if sampleX ~= self.sampleMax + 1 - self.sampleMin then
+ if sampleX >= (currLine + 1) * self.samplesPerLine then
currLine = currLine + 1
- tex.sprint(";\n\\draw[" .. parms.traceStyle[baseName] .. "] ")
+ tex.sprint(";\n\t\\draw [" .. self.traceStyle[baseName] .. "] ")
firstPointInLine = true
end
else
- tex.sprint(";\n")
+ tex.sprint(";")
end
sampleX = sampleX + 1
currSampleIndex = currSampleIndex + 1
@@ -332,127 +432,127 @@ function printTikzChromatogram ()
local lastProbX = 1
local probRemainder = false
- for _, currPeak in ipairs(selectedPeaks) do
- while currPeak.offset > (currLine + 1) * parms.samplesPerLine do
+ for _, currPeak in ipairs(self.selectedPeaks) do
+ while currPeak.offset > (currLine + 1) * self.samplesPerLine do
currLine = currLine + 1
end
- local x = ((currPeak.offset - 1) % parms.samplesPerLine) * parms.xUnit
- local yUpper = -currLine * parms.baselineSkip
- local yLower = -currLine * parms.baselineSkip - parms.tickLength
+ local x = ((currPeak.offset - 1) % self.samplesPerLine) * self.xUnit
+ local yUpper = -currLine * self.baselineSkip
+ local yLower = -currLine * self.baselineSkip - self.tickLength
local tickOperation = ""
- if string.find(string.upper(parms.ticksDrawn), currPeak.base) then
+ if self.ticksDrawn:upper():find(currPeak.base) then
tickOperation = "--"
end
tex.sprint(
- "\\draw[" ..
- parms.tickStyle[currPeak.base] ..
+ "\n\t\\draw [" ..
+ self.tickStyle[currPeak.base] ..
"] (" ..
- number.todimen(x, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(x) ..
", " ..
- number.todimen(yUpper, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(yUpper) ..
") " ..
tickOperation ..
" (" ..
- number.todimen(x, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(x) ..
", " ..
- number.todimen(yLower, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(yLower) ..
")"
)
- if string.find(string.upper(parms.baseLabelsDrawn), currPeak.base) then
+ if self.baseLabelsDrawn:upper():find(currPeak.base) then
tex.sprint(
- " node[" ..
- parms.baseLabelStyle[currPeak.base] ..
+ " node [" ..
+ self.baseLabelStyle[currPeak.base] ..
"] {" ..
- parms.baseLabelText[currPeak.base] ..
+ self.baseLabelText[currPeak.base] ..
"}"
)
end
- if parms.showBaseNumbers
- and currPeak.baseIndex >= parms.baseNumberMin
- and currPeak.baseIndex <= parms.baseNumberMax
- and (currPeak.baseIndex - parms.baseNumberMin)
- % parms.baseNumberStep == 0 then
+ if self.showBaseNumbers
+ and currPeak.baseIndex >= self.baseNumberMin
+ and currPeak.baseIndex <= self.baseNumberMax
+ and (currPeak.baseIndex - self.baseNumberMin)
+ % self.baseNumberStep == 0 then
tex.sprint(
- " node[" .. PGFKEYS_PATH .. "base number style@style] {\\strut " ..
+ " node [" ..
+ PGFKEYS_PATH ..
+ "base number style] {\\strut " ..
currPeak.baseIndex ..
"}"
)
end
- tex.sprint(";\n")
+ tex.sprint(";")
if probRemainder then
tex.sprint(probRemainder)
probRemainder = false
end
- local drawCurrProb = string.find(
- string.upper(parms.probabilitiesDrawn),
- currPeak.base
- )
- local xLeft = lastProbX - 1 - currLine * parms.samplesPerLine
+ local drawCurrProb =
+ self.probabilitiesDrawn:upper():find(currPeak.base)
+ local xLeft = lastProbX - 1 - currLine * self.samplesPerLine
if xLeft < 0 then
- local xLeftPrev = (parms.samplesPerLine + xLeft) * parms.xUnit
- local xRightPrev = (parms.samplesPerLine - 1) * parms.xUnit
- local yPrev = -(currLine-1) * parms.baselineSkip - parms.probDistance
+ local xLeftPrev = (self.samplesPerLine + xLeft) * self.xUnit
+ local xRightPrev = (self.samplesPerLine - 1) * self.xUnit
+ local yPrev = -(currLine-1) * self.baselineSkip - self.probDistance
if drawCurrProb then
tex.sprint(
- "\\draw[" ..
- parms.probStyle(currPeak.prob[currPeak.base]) ..
- " ] (" ..
- number.todimen(xLeftPrev, parms.coordUnit, parms.coordFmtStr) ..
+ "\n\t\\draw [" ..
+ self.probStyle(currPeak.prob[currPeak.base]) ..
+ "] (" ..
+ dimToString(xLeftPrev) ..
", " ..
- number.todimen(yPrev, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(yPrev) ..
") -- (" ..
- number.todimen(xRightPrev, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(xRightPrev) ..
", " ..
- number.todimen(yPrev, parms.coordUnit, parms.coordFmtStr) ..
- ");\n"
+ dimToString(yPrev) ..
+ ");"
)
end
xLeft = 0
else
- xLeft = xLeft * parms.xUnit
+ xLeft = xLeft * self.xUnit
end
- local xRight = currPeak.probXRight - 1 - currLine * parms.samplesPerLine
- if xRight >= parms.samplesPerLine then
+ local xRight = currPeak.probXRight - 1 - currLine * self.samplesPerLine
+ if xRight >= self.samplesPerLine then
if drawCurrProb then
- local xRightNext = (xRight - parms.samplesPerLine) * parms.xUnit
- local yNext = -(currLine+1) * parms.baselineSkip - parms.probDistance
+ local xRightNext = (xRight - self.samplesPerLine) * self.xUnit
+ local yNext = -(currLine+1) * self.baselineSkip - self.probDistance
probRemainder =
- "\\draw[" ..
- parms.probStyle(currPeak.prob[currPeak.base]) ..
- " ] (" ..
- number.todimen(0, parms.coordUnit, parms.coordFmtStr) ..
+ "\n\t\\draw [" ..
+ self.probStyle(currPeak.prob[currPeak.base]) ..
+ "] (" ..
+ dimToString(0) ..
", " ..
- number.todimen(yNext, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(yNext) ..
") -- (" ..
- number.todimen(xRightNext, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(xRightNext) ..
", " ..
- number.todimen(yNext, parms.coordUnit, parms.coordFmtStr) ..
- ");\n"
+ dimToString(yNext) ..
+ ");"
end
- xRight = (parms.samplesPerLine - 1) * parms.xUnit
+ xRight = (self.samplesPerLine - 1) * self.xUnit
else
- xRight = xRight * parms.xUnit
+ xRight = xRight * self.xUnit
end
- local y = -currLine * parms.baselineSkip - parms.probDistance
+ local y = -currLine * self.baselineSkip - self.probDistance
if drawCurrProb then
tex.sprint(
- "\\draw[" ..
- parms.probStyle(currPeak.prob[currPeak.base]) ..
- " ] (" ..
- number.todimen(xLeft, parms.coordUnit, parms.coordFmtStr) ..
+ "\n\t\\draw [" ..
+ self.probStyle(currPeak.prob[currPeak.base]) ..
+ "] (" ..
+ dimToString(xLeft) ..
", " ..
- number.todimen(y, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(y) ..
") -- (" ..
- number.todimen(xRight, parms.coordUnit, parms.coordFmtStr) ..
+ dimToString(xRight) ..
", " ..
- number.todimen(y, parms.coordUnit, parms.coordFmtStr) ..
- ");\n"
+ dimToString(y) ..
+ ");"
)
end
lastProbX = currPeak.probXRight
diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex
index 4aff5ef075c..a895f89603a 100644
--- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex
+++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex
@@ -4,9 +4,9 @@
%%
%% The original source files were:
%%
-%% pgfmolbio.dtx (with options: `pmb-chr')
+%% pgfmolbio.dtx (with options: `pmb-chr-tex')
%%
-%% Copyright (C) 2011 by Wolfgang Skala
+%% Copyright (C) 2012 by Wolfgang Skala
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
@@ -16,9 +16,12 @@
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
-\ProvidesFile{pgfmolbio.chromatogram.tex}[2011/09/20 v0.1 SCF Chromatograms]
+\ProvidesFile{pgfmolbio.chromatogram.tex}[2012/10/01 v0.2 SCF chromatograms]
-\RequireLuaModule{pgfmolbio.chromatogram}
+
+\ifluatex
+ \RequireLuaModule{pgfmolbio.chromatogram}
+\fi
\definecolor{pmbTraceGreen}{RGB}{34,114,46}
\definecolor{pmbTraceBlue}{RGB}{48,37,199}
@@ -26,130 +29,101 @@
\definecolor{pmbTraceRed}{RGB}{191,27,27}
\definecolor{pmbTraceYellow}{RGB}{233,230,0}
-\def\@pmb@chr@keydef#1{%
- \pgfkeysdef{/pgfmolbio/chromatogram/#1}{%
- \expandafter\def\csname pmb@chr@#1\endcsname{##1}%
- }%
+\def\@pmb@chr@keydef#1#2{%
+ \pgfkeyssetvalue{/pgfmolbio/chromatogram/#1}{#2}%
}
-\def\@pmb@chr@stylekeydef#1{%
- \pgfkeysdef{/pgfmolbio/chromatogram/#1}{%
- \pgfkeys{/pgfmolbio/chromatogram/#1@style/.style={##1}}%
- }%
+\def\@pmb@chr@stylekeydef#1#2{%
+ \pgfkeys{/pgfmolbio/chromatogram/#1/.style={#2}}%
+}
+\def\@pmb@chr@getkey#1{%
+ \pgfkeysvalueof{/pgfmolbio/chromatogram/#1}%
}
-\def\@pmb@chr@getkey#1{\csname pmb@chr@#1\endcsname}
-\@pmb@chr@keydef{sample range}
+\@pmb@chr@keydef{sample range}{1-500 step 1}
-\@pmb@chr@keydef{x unit}
-\@pmb@chr@keydef{y unit}
-\@pmb@chr@keydef{samples per line}
-\@pmb@chr@keydef{baseline skip}
-\@pmb@chr@stylekeydef{canvas style}
-\@pmb@chr@keydef{canvas height}
+\@pmb@chr@keydef{x unit}{0.2mm}
+\@pmb@chr@keydef{y unit}{0.01mm}
+\@pmb@chr@keydef{samples per line}{500}
+\@pmb@chr@keydef{baseline skip}{3cm}
+\@pmb@chr@stylekeydef{canvas style}{draw=none, fill=none}
+\@pmb@chr@keydef{canvas height}{2cm}
-\@pmb@chr@stylekeydef{trace A style}
-\@pmb@chr@stylekeydef{trace C style}
-\@pmb@chr@stylekeydef{trace G style}
-\@pmb@chr@stylekeydef{trace T style}
-\pgfkeysdef{/pgfmolbio/chromatogram/trace style}{%
- \pgfmolbioset[chromatogram]{
- trace A style={#1},
- trace C style={#1},
- trace G style={#1},
- trace T style={#1}
+\@pmb@chr@stylekeydef{trace A style}{pmbTraceGreen}
+\@pmb@chr@stylekeydef{trace C style}{pmbTraceBlue}
+\@pmb@chr@stylekeydef{trace G style}{pmbTraceBlack}
+\@pmb@chr@stylekeydef{trace T style}{pmbTraceRed}
+\pgfmolbioset[chromatogram]{%
+ trace style/.code=\pgfkeysalso{
+ trace A style/.style={#1},
+ trace C style/.style={#1},
+ trace G style/.style={#1},
+ trace T style/.style={#1}
}%
}
-\@pmb@chr@keydef{traces drawn}
+\@pmb@chr@keydef{traces drawn}{}
-\@pmb@chr@stylekeydef{tick A style}
-\@pmb@chr@stylekeydef{tick C style}
-\@pmb@chr@stylekeydef{tick G style}
-\@pmb@chr@stylekeydef{tick T style}
-\pgfkeysdef{/pgfmolbio/chromatogram/tick style}{%
- \pgfmolbioset[chromatogram]{
- tick A style={#1},
- tick C style={#1},
- tick G style={#1},
- tick T style={#1}
+\@pmb@chr@stylekeydef{tick A style}{thin, pmbTraceGreen}
+\@pmb@chr@stylekeydef{tick C style}{thin, pmbTraceBlue}
+\@pmb@chr@stylekeydef{tick G style}{thin, pmbTraceBlack}
+\@pmb@chr@stylekeydef{tick T style}{thin, pmbTraceRed}
+\pgfmolbioset[chromatogram]{%
+ tick style/.code=\pgfkeysalso{
+ tick A style/.style={#1},
+ tick C style/.style={#1},
+ tick G style/.style={#1},
+ tick T style/.style={#1}
}%
}
-\@pmb@chr@keydef{tick length}
-\@pmb@chr@keydef{ticks drawn}
+\@pmb@chr@keydef{tick length}{1mm}
+\@pmb@chr@keydef{ticks drawn}{}
-\@pmb@chr@keydef{base label A text}
-\@pmb@chr@keydef{base label C text}
-\@pmb@chr@keydef{base label G text}
-\@pmb@chr@keydef{base label T text}
-\@pmb@chr@stylekeydef{base label A style}
-\@pmb@chr@stylekeydef{base label C style}
-\@pmb@chr@stylekeydef{base label G style}
-\@pmb@chr@stylekeydef{base label T style}
-\pgfkeysdef{/pgfmolbio/chromatogram/base label style}{%
- \pgfmolbioset[chromatogram]{
- base label A style={#1},
- base label C style={#1},
- base label G style={#1},
- base label T style={#1}
+\@pmb@chr@keydef{base label A text}{\strut A}
+\@pmb@chr@keydef{base label C text}{\strut C}
+\@pmb@chr@keydef{base label G text}{\strut G}
+\@pmb@chr@keydef{base label T text}{\strut T}
+\@pmb@chr@stylekeydef{base label A style}%
+ {below=4pt, font=\ttfamily\footnotesize, pmbTraceGreen}
+\@pmb@chr@stylekeydef{base label C style}%
+ {below=4pt, font=\ttfamily\footnotesize, pmbTraceBlue}
+\@pmb@chr@stylekeydef{base label G style}%
+ {below=4pt, font=\ttfamily\footnotesize, pmbTraceBlack}
+\@pmb@chr@stylekeydef{base label T style}%
+ {below=4pt, font=\ttfamily\footnotesize, pmbTraceRed}
+\pgfmolbioset[chromatogram]{%
+ base label style/.code=\pgfkeysalso{
+ base label A style/.style={#1},
+ base label C style/.style={#1},
+ base label G style/.style={#1},
+ base label T style/.style={#1}
}%
}
-\@pmb@chr@keydef{base labels drawn}
+\@pmb@chr@keydef{base labels drawn}{}
\newif\ifpmb@chr@showbasenumbers
-\pgfkeys{/pgfmolbio/chromatogram/show base numbers/%
- .is if=pmb@chr@showbasenumbers}
-\@pmb@chr@stylekeydef{base number style}
-\@pmb@chr@keydef{base number range}
+\pgfmolbioset[chromatogram]{%
+ show base numbers/.is if=pmb@chr@showbasenumbers,
+ show base numbers
+}
+\@pmb@chr@stylekeydef{base number style}%
+ {pmbTraceBlack, below=-3pt, font=\sffamily\tiny}
+\@pmb@chr@keydef{base number range}{auto-auto step 10}
-\@pmb@chr@keydef{probability distance}
-\@pmb@chr@keydef{probabilities drawn}
-\@pmb@chr@keydef{probability style function}
+\@pmb@chr@keydef{probability distance}{0.8cm}
+\@pmb@chr@keydef{probabilities drawn}{}
+\@pmb@chr@keydef{probability style function}{nil}
-\pgfkeysdef{/pgfmolbio/chromatogram/bases drawn}{%
- \pgfmolbioset[chromatogram]{
+\pgfmolbioset[chromatogram]{
+ bases drawn/.code=\pgfkeysalso{
traces drawn=#1,
ticks drawn=#1,
base labels drawn=#1,
probabilities drawn=#1
- }%
-}
-
-\pgfmolbioset[chromatogram]{%
- sample range=1 to 500 step 1,
- x unit=0.2mm,
- y unit=0.01mm,
- samples per line=500,
- baseline skip=3cm,
- canvas style={draw=none, fill=none},
- canvas height=2cm,
- trace A style={pmbTraceGreen},
- trace C style={pmbTraceBlue},
- trace G style={pmbTraceBlack},
- trace T style={pmbTraceRed},
- tick A style={thin, pmbTraceGreen},
- tick C style={thin, pmbTraceBlue},
- tick G style={thin, pmbTraceBlack},
- tick T style={thin, pmbTraceRed},
- tick length=1mm,
- base label A text=\strut A,
- base label C text=\strut C,
- base label G text=\strut G,
- base label T text=\strut T,
- base label A style=%
- {below=4pt, font=\ttfamily\footnotesize, pmbTraceGreen},
- base label C style=%
- {below=4pt, font=\ttfamily\footnotesize, pmbTraceBlue},
- base label G style=%
- {below=4pt, font=\ttfamily\footnotesize, pmbTraceBlack},
- base label T style=%
- {below=4pt, font=\ttfamily\footnotesize, pmbTraceRed},
- show base numbers,
- base number style={pmbTraceBlack, below=-3pt, font=\sffamily\tiny},
- base number range=auto to auto step 10,
- probability distance=0.8cm,
- probability style function=nil,
+ },
bases drawn=ACGT
}
+\ifluatex\else\expandafter\endinput\fi
+
\newif\ifpmb@chr@tikzpicture
\newcommand\pmbchromatogram[2][]{%
@@ -158,25 +132,52 @@
{\pmb@chr@tikzpicturetrue\begingroup}%
\pgfmolbioset[chromatogram]{#1}%
\directlua{
- pgfmolbio.chromatogram.readScfFile("#2")
- pgfmolbio.chromatogram.setParameters{
+ pmbChromatogram = pgfmolbio.chromatogram.Chromatogram:new()
+ pmbChromatogram:readScfFile("#2")
+ pmbChromatogram:setParameters{
sampleRange = "\@pmb@chr@getkey{sample range}",
- xUnit = dimen("\@pmb@chr@getkey{x unit}")[1],
- yUnit = dimen("\@pmb@chr@getkey{y unit}")[1],
- samplesPerLine = \@pmb@chr@getkey{samples per line},
- baselineSkip = dimen("\@pmb@chr@getkey{baseline skip}")[1],
- canvasHeight = dimen("\@pmb@chr@getkey{canvas height}")[1],
+ xUnit = "\@pmb@chr@getkey{x unit}",
+ yUnit = "\@pmb@chr@getkey{y unit}",
+ samplesPerLine = "\@pmb@chr@getkey{samples per line}",
+ baselineSkip = "\@pmb@chr@getkey{baseline skip}",
+ canvasHeight = "\@pmb@chr@getkey{canvas height}",
tracesDrawn = "\@pmb@chr@getkey{traces drawn}",
- tickLength = dimen("\@pmb@chr@getkey{tick length}")[1],
+ tickLength = "\@pmb@chr@getkey{tick length}",
ticksDrawn = "\@pmb@chr@getkey{ticks drawn}",
baseLabelsDrawn = "\@pmb@chr@getkey{base labels drawn}",
- showBaseNumbers = \ifpmb@chr@showbasenumbers true\else false\fi,
- baseNumberRange = "\@pmb@chr@getkey{base number range}",
- probDistance = dimen("\@pmb@chr@getkey{probability distance}")[1],
+ showBaseNumbers = "\ifpmb@chr@showbasenumbers true\else false\fi",
+ probDistance = "\@pmb@chr@getkey{probability distance}",
probabilitiesDrawn = "\@pmb@chr@getkey{probabilities drawn}",
probStyle = \@pmb@chr@getkey{probability style function}
}
- pgfmolbio.chromatogram.printTikzChromatogram()
+ pmbChromatogram:setParameters{
+ baseNumberRange = "\@pmb@chr@getkey{base number range}",
+ }
+ pgfmolbio.setCoordinateFormat(
+ "\pgfkeysvalueof{/pgfmolbio/coordinate unit}",
+ "\pgfkeysvalueof{/pgfmolbio/coordinate format string}"
+ )
+ \ifpmb@loadmodule@convert
+ local filename =
+ "\pgfkeysvalueof{/pgfmolbio/convert/output file name}"
+ if filename == "(auto)" then
+ filename = "pmbconverted" .. pgfmolbio.outputFileId
+ end
+ filename = filename ..
+ ".\pgfkeysvalueof{/pgfmolbio/convert/output file extension}"
+ outputFile, ioError = io.open(filename, "w")
+ if ioError then
+ tex.error(ioError)
+ end
+ tex.sprint = function (a) outputFile:write(a) end
+ tex.sprint("\string\\begin{tikzpicture}")
+ pmbChromatogram:printTikzChromatogram()
+ tex.sprint("\string\n\string\\end{tikzpicture}")
+ outputFile:close()
+ pgfmolbio.outputFileId = pgfmolbio.outputFileId + 1
+ \else
+ pmbChromatogram:printTikzChromatogram()
+ \fi
}%
\ifpmb@chr@tikzpicture\endgroup\else\end{tikzpicture}\fi%
}
diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex
new file mode 100644
index 00000000000..557dc333d65
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex
@@ -0,0 +1,40 @@
+%%
+%% This is file `pgfmolbio.convert.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% pgfmolbio.dtx (with options: `pmb-con-tex')
+%%
+%% Copyright (C) 2012 by Wolfgang Skala
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+\ProvidesFile{pgfmolbio.convert.tex}[2012/10/01 v0.2 pgfmolbio graph conversion]
+
+
+\pdfdraftmode1
+
+\pgfkeyssetvalue{/pgfmolbio/convert/output file name}{(auto)}
+\pgfkeyssetvalue{/pgfmolbio/convert/output file extension}{tex}
+
+\pgfmolbioset[convert]{%
+ output code/.is choice,
+ output code/tikz/.code=\pmb@con@outputtikzcodetrue,
+ output code/pgfmolbio/.code=\pmb@con@outputtikzcodefalse,
+ output code=tikz
+}
+
+\pgfmolbioset[convert]{%
+ include description/.is if=pmb@con@includedescription,
+ include description
+}
+\endinput
+%%
+%% End of file `pgfmolbio.convert.tex'.
diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.lua b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.lua
new file mode 100644
index 00000000000..905c6d688e0
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.lua
@@ -0,0 +1,810 @@
+--
+-- This is file `pgfmolbio.domains.lua',
+-- generated with the docstrip utility.
+--
+-- The original source files were:
+--
+-- pgfmolbio.dtx (with options: `pmb-dom-lua')
+--
+-- Copyright (C) 2012 by Wolfgang Skala
+--
+-- This work may be distributed and/or modified under the
+-- conditions of the LaTeX Project Public License, either version 1.3
+-- of this license or (at your option) any later version.
+-- The latest version of this license is in
+-- http://www.latex-project.org/lppl.txt
+-- and version 1.3 or later is part of all distributions of LaTeX
+-- version 2005/12/01 or later.
+--
+module("pgfmolbio.domains", package.seeall)
+
+
+if luatexbase then
+ luatexbase.provides_module({
+ name = "pgfmolbio.domains",
+ version = 0.2,
+ date = "2012/10/01",
+ description = "Domain graphs",
+ author = "Wolfgang Skala",
+ copyright = "Wolfgang Skala",
+ license = "LPPL",
+ })
+end
+
+local stringToDim = pgfmolbio.stringToDim
+local dimToString = pgfmolbio.dimToString
+local packageError = pgfmolbio.packageError
+local packageWarning = pgfmolbio.packageWarning
+local getRange = pgfmolbio.getRange
+
+function printSequenceFeature(feature, xLeft, xRight, yMid, xUnit, yUnit)
+ xLeft = xLeft + 0.5
+ for currResidue in feature.sequence:gmatch(".") do
+ tex.sprint("\n\t\t\\def\\xMid{" .. dimToString(xLeft * xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\yMid{" .. dimToString(yMid * yUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\currentResidue{" .. currResidue .. "}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{other/sequence}")
+ xLeft = xLeft + 1
+ end
+end
+
+function printHelixFeature(feature, xLeft, xRight, yMid, xUnit, yUnit)
+ local residuesLeft, currX
+ tex.sprint("\n\t\t\\pgfmolbioset[domains]{current style}")
+
+ residuesLeft = feature.stop - feature.start + 1
+ currX = xLeft
+ tex.sprint("\n\t\t\\def\\xLeft{" .. dimToString(currX * xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\yMid{" .. dimToString(yMid * yUnit) .. "}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/half upper back}")
+ residuesLeft = residuesLeft - 2
+ currX = currX + 2.5
+
+ while residuesLeft > 0 do
+ if residuesLeft == 1 then
+ tex.sprint(
+ "\n\t\t\\def\\xRight{" ..
+ dimToString((currX + 0.5) * xUnit) ..
+ "}"
+ )
+ tex.sprint("\n\t\t\\def\\yMid{" .. dimToString(yMid * yUnit) .. "}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/half lower back}")
+ else
+ tex.sprint("\n\t\t\\def\\xMid{" .. dimToString(currX * xUnit) .. "}")
+ tex.sprint(
+ "\n\t\t\\def\\yLower{" ..
+ dimToString(yMid * yUnit - 1.5 * xUnit) ..
+ "}"
+ )
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/full back}")
+ end
+ residuesLeft = residuesLeft - 2
+ currX = currX + 2
+ end
+
+ residuesLeft = feature.stop - feature.start
+ currX = xLeft + 1.5
+ while residuesLeft > 0 do
+ if residuesLeft == 1 then
+ tex.sprint(
+ "\n\t\t\\def\\xRight{" ..
+ dimToString((currX + 0.5) * xUnit) ..
+ "}"
+ )
+ tex.sprint("\n\t\t\\def\\yMid{" .. dimToString(yMid * yUnit) .. "}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/half upper front}")
+ else
+ tex.sprint("\n\t\t\\def\\xMid{" .. dimToString(currX * xUnit) .. "}")
+ tex.sprint(
+ "\n\t\t\\def\\yLower{" ..
+ dimToString(yMid * yUnit - 1.5 * xUnit) ..
+ "}"
+ )
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{helix/full front}")
+ end
+ residuesLeft = residuesLeft - 2
+ currX = currX + 2
+ end
+end
+
+SpecialKeys = {}
+
+function SpecialKeys:new(parms)
+ parms = parms or {}
+ local newSpecialKeys = {
+ disulfideKeys = {},
+ featureStyles = {},
+ printFunctions = {}
+ }
+
+ for keyList, listContents in pairs(parms) do
+ for key, value in pairs(listContents) do
+ newSpecialKeys[keyList][key] = value
+ end
+ end
+
+ setmetatable(newSpecialKeys, self)
+ self.__index = self
+ return newSpecialKeys
+end
+
+function SpecialKeys:setKeys(keylist, keys, value)
+ for key in keys:gmatch("([^,]+)") do
+ key = key:trim()
+ self[keylist][key] = value
+ end
+end
+
+function SpecialKeys:setFeatureStyle(key, style)
+ local newStyleList, styleCycles, styleContents
+
+ newStyleList = {}
+ while style ~= "" do
+ styleCycles = 1
+ if style:sub(1,1) == "{" then
+ styleContents = style:match("%b{}")
+ style = style:match("%b{}(.*)")
+ elseif style:sub(1,1) == "*" then
+ styleCycles, styleContents = style:match("%*(%d*)(%b{})")
+ if styleCycles == "" then styleCycles = 1 end
+ style = style:match("%*%d*%b{}(.*)")
+ elseif style:sub(1,1) == "," or style:sub(1,1) == " " then
+ style = style:match("[,%s]+(.*)")
+ styleCycles, styleContents = nil, nil
+ else
+ styleContents = style:match("([^,]+),")
+ if not styleContents then
+ styleContents = style
+ style = ""
+ else
+ style = style:match("[^,]+,(.*)")
+ end
+ end
+ if styleCycles then
+ table.insert(
+ newStyleList,
+ {cycles = styleCycles, style = styleContents}
+ )
+ end
+ end
+ self.featureStyles[key] = newStyleList
+end
+
+function SpecialKeys:aliasFeatureStyle(newKey, oldKey)
+ self.featureStyles[newKey] = {alias = oldKey}
+end
+
+function SpecialKeys:getBaseKey(key)
+ if self.featureStyles[key] then
+ if self.featureStyles[key].alias then
+ return self.featureStyles[key].alias
+ end
+ end
+ return key
+end
+
+function SpecialKeys:clearKeys(keylist)
+ self[keylist] = {}
+end
+
+function SpecialKeys:selectStyleFromList(key, styleID)
+ local styleList
+
+ if not self.featureStyles[key] then
+ packageWarning(
+ "Feature style `" ..
+ key ..
+ "' unknown, using `default'."
+ )
+ styleList = self.featureStyles.default
+ elseif self.featureStyles[key].alias then
+ styleList = self.featureStyles[self.featureStyles[key].alias]
+ else
+ styleList = self.featureStyles[key]
+ end
+
+ while true do
+ for _, v in ipairs(styleList) do
+ styleID = styleID - v.cycles
+ if styleID < 1 then
+ return v.style
+ end
+ end
+ end
+end
+
+Protein = {}
+
+function Protein:new()
+ local newProtein = {
+ name = "",
+ sequenceLength = -1,
+ ft = {},
+ sequence = "",
+ xUnit = stringToDim("0.5mm"),
+ yUnit = stringToDim("6mm"),
+ residuesPerLine = 250,
+ residueRangeMin = 1,
+ residueRangeMax = 100,
+ residueNumbering = {},
+ revResidueNumbering = {},
+ baselineSkip = 3,
+ rulerRange = {},
+ defaultRulerStepSize = 50,
+ showRuler = true,
+ currentStyle = {},
+ specialKeys = SpecialKeys:new()
+ }
+ setmetatable(newProtein, self)
+ self.__index = self
+ return newProtein
+end
+
+function Protein:toAbsoluteResidueNumber(value)
+ local result = value:match("%b()")
+ if result then
+ result = tonumber(result:sub(2, -2))
+ else
+ result = self.revResidueNumbering[(value:gsub("[<>%?]", ""))]
+ end
+ if not result then
+ packageError("Bad or missing start/end point value: " .. value)
+ end
+ return result
+end
+
+function Protein:readUniprotFile(filename)
+ local uniprotFile, errorMsg = io.open(filename, "r")
+ if not uniprotFile then packageError(errorMsg) end
+
+ local sequence = {}
+ local inSequence = false
+ local featureTable = {}
+
+ for currLine in uniprotFile:lines() do
+ local lineCode = currLine:sub(1, 2)
+ local lineContents = currLine:sub(3)
+ if lineCode == "ID" then
+ local name, sequenceLength =
+ lineContents:match("%s*(%S+)%s*%a+;%s*(%d+)%s*AA%.")
+ self.name = name
+ self.sequenceLength = tonumber(sequenceLength)
+ self.residueRangeMax = self.sequenceLength
+ elseif lineCode == "FT" then
+ local key = currLine:sub(6, 13):trim()
+ local start, stop, description =
+ currLine:sub(15, 20), currLine:sub(22, 27), currLine:sub(35, 75)
+ if key ~= "" then
+ table.insert(featureTable, {
+ key = key,
+ start = "(" .. start .. ")",
+ stop = "(" .. stop .. ")",
+ description = description,
+ style = "",
+ kvList = ""
+ })
+ else
+ featureTable[#featureTable].description =
+ featureTable[#featureTable].description .. description
+ end
+ elseif lineCode == "SQ" then
+ inSequence = true
+ elseif lineCode == " " and inSequence then
+ table.insert(sequence, (lineContents:gsub("%s+", "")))
+ elseif lineCode == "\\\\" then
+ break
+ end
+ end
+ uniprotFile:close()
+ if next(sequence) then self.sequence = table.concat(sequence) end
+ for _, v in ipairs(featureTable) do self:addFeature(v) end
+end
+
+function Protein:readGffFile(filename)
+ local gffFile, errorMsg = io.open(filename, "r")
+ local lineContents, fields, lineNumber
+
+ if not gffFile then packageError(errorMsg) end
+ lineNumber = 1
+ for currLine in gffFile:lines() do
+ lineContents = currLine:gsub("#.*$", "")
+ fields = {}
+ if lineContents ~= "" then
+ for currField in lineContents:gmatch("([^\t]+)") do
+ table.insert(fields, currField)
+ end
+ if not fields[5] then
+ packageError("Bad line (" .. lineNumber .. ") in gff file '" ..
+ filename .. "':\n" .. currLine)
+ break
+ end
+ self:addFeature{
+ key = fields[3],
+ start = "(" .. fields[4] .. ")",
+ stop = "(" .. fields[5] .. ")",
+ description = fields[9] or "",
+ style = "",
+ kvList = ""
+ }
+ end
+ lineNumber = lineNumber + 1
+ end
+ gffFile:close()
+end
+
+function Protein:getParameters()
+ tex.sprint(
+ "\\pgfmolbioset[domains]{name={" ..
+ self.name ..
+ "},sequence={" ..
+ self.sequence ..
+ "},sequence length=" ..
+ self.sequenceLength ..
+ "}"
+ )
+end
+
+function Protein:setParameters(newParms)
+ local keyHash = {
+ sequenceLength = function(v)
+ v = tonumber(v)
+ if not v then return self.sequenceLength end
+ if v < 1 then
+ packageError("Sequence length must be larger than zero.")
+ end
+ return v
+ end,
+ residueNumbering = function(v)
+ local ranges = {}
+ local start, startNumber, startLetter, stop
+ self.revResidueNumbering = {}
+ if v:trim() == "auto" then
+ for i = 1, self.sequenceLength do
+ table.insert(ranges, tostring(i))
+ end
+ else --example list: `1-4,5,6A-D'
+ for _, value in ipairs(v:explode(",+")) do
+ value = value:trim()
+ start, stop = value:match("(%w*)%s*%-%s*(%w*)$")
+ if not start then
+ start = value:match("(%w*)")
+ end
+ if not start or start == "" then --invalid range
+ packageError("Unknown residue numbering range: " .. value)
+ end
+ if stop then
+ if tonumber(start) and tonumber(stop) then
+ --process range `1-4'
+ for currNumber = tonumber(start), tonumber(stop) do
+ table.insert(ranges, tostring(currNumber))
+ end
+ else --process range `6A-D'
+ startNumber, startLetter = start:match("(%d*)(%a)")
+ stop = stop:match("(%a)")
+ for currLetter = startLetter:byte(), stop:byte() do
+ table.insert(ranges,
+ startNumber .. string.char(currLetter))
+ end
+ end
+ else --process range `5'
+ table.insert(ranges, start)
+ end
+ end
+ end
+ for i, value in ipairs(ranges) do
+ if self.revResidueNumbering[value] then
+ packageError("The range value " .. value ..
+ " appears more than once.")
+ else
+ self.revResidueNumbering[value] = i
+ end
+ end
+ return ranges
+ end,
+ residueRange = function(v)
+ local num
+ local residueRangeMin, residueRangeMax =
+ getRange(v:trim(), "^([%w%(%)]+)%s*%-", "%-%s*([%w%(%)]+)$")
+ if residueRangeMin == "auto" then
+ self.residueRangeMin = 1
+ else
+ num = residueRangeMin:match("%b()")
+ if num then
+ self.residueRangeMin = tonumber(num:sub(2, -2))
+ elseif self.revResidueNumbering[residueRangeMin] then
+ self.residueRangeMin = self.revResidueNumbering[residueRangeMin]
+ else
+ packageError("Invalid residue range: " .. residueRangeMin)
+ end
+ end
+
+ if residueRangeMax == "auto" then
+ self.residueRangeMax = self.sequenceLength
+ else
+ num = residueRangeMax:match("%b()")
+ if num then
+ self.residueRangeMax = tonumber(num:sub(2, -2))
+ elseif self.revResidueNumbering[residueRangeMax] then
+ self.residueRangeMax = self.revResidueNumbering[residueRangeMax]
+ else
+ packageError("Invalid residue range: " .. residueRangeMax)
+ end
+ end
+
+ if self.residueRangeMin >= self.residueRangeMax then
+ packageError("Residue range is smaller than 1.")
+ end
+ end,
+ defaultRulerStepSize = tonumber,
+ name = tostring,
+ sequence = tostring,
+ xUnit = stringToDim,
+ yUnit = stringToDim,
+ residuesPerLine = tonumber,
+ baselineSkip = tonumber,
+ rulerRange = function(v)
+ local num
+ local ranges = {}
+ local rulerRangeMin, rulerRangeMax, rulerRangeStep
+ for _, value in ipairs(v:explode(",+")) do
+ rulerRangeMin, rulerRangeMax, rulerRangeStep =
+ getRange(value:trim(), "^([%w%(%)]+)",
+ "%-%s*([%w%(%)]+)", "step%s*(%d+)$")
+
+ if rulerRangeMin == "auto" then
+ rulerRangeMin = self.residueRangeMin
+ else
+ num = rulerRangeMin:match("%b()")
+ if num then
+ rulerRangeMin = tonumber(num:sub(2, -2))
+ elseif self.revResidueNumbering[rulerRangeMin] then
+ rulerRangeMin = self.revResidueNumbering[rulerRangeMin]
+ else
+ packageError("Invalid lower ruler range: " .. rulerRangeMin)
+ end
+ end
+
+ if rulerRangeMax then
+ if rulerRangeMax == "auto" then
+ rulerRangeMax = self.residueRangeMax
+ else
+ num = rulerRangeMax:match("%b()")
+ if num then
+ rulerRangeMax = tonumber(num:sub(2, -2))
+ elseif self.revResidueNumbering[rulerRangeMax] then
+ rulerRangeMax = self.revResidueNumbering[rulerRangeMax]
+ else
+ packageError("Invalid upper ruler range: " .. rulerRangeMax)
+ end
+ end
+
+ if rulerRangeMin >= rulerRangeMax then
+ packageError("Ruler range is smaller than 1.")
+ end
+ if rulerRangeMin < self.residueRangeMin then
+ rulerRangeMin = self.residueRangeMin
+ packageWarning(
+ "Lower ruler range is smaller than" ..
+ "lower residue range. It was adjusted to " ..
+ rulerRangeMin .. "."
+ )
+ end
+ if rulerRangeMax > self.residueRangeMax then
+ rulerRangeMax = self.residueRangeMax
+ packageWarning(
+ "Upper ruler range exceeds" ..
+ "upper residue range. It was adjusted to " ..
+ rulerRangeMax .. "."
+ )
+ end
+ else
+ rulerRangeMax = rulerRangeMin
+ end
+ rulerRangeStep = tonumber(rulerRangeStep)
+ or self.defaultRulerStepSize
+
+ for i = rulerRangeMin, rulerRangeMax, rulerRangeStep do
+ table.insert(
+ ranges,
+ {pos = i, number = self.residueNumbering[i]}
+ )
+ end
+ end
+ return ranges
+ end,
+ showRuler = function(v)
+ if v == "true" then return true else return false end
+ end
+ }
+ for key, value in pairs(newParms) do
+ if keyHash[key] then
+ self[key] = keyHash[key](value)
+ if pgfmolbio.errorCatched then return end
+ end
+ end
+end
+
+function Protein:addFeature(newFeature)
+ local baseKey, ftEntry
+
+ baseKey = self.specialKeys:getBaseKey(newFeature.key)
+ if self.currentStyle[baseKey] then
+ self.currentStyle[baseKey] = self.currentStyle[baseKey] + 1
+ else
+ self.currentStyle[baseKey] = 1
+ end
+
+ ftEntry = {
+ key = newFeature.key,
+ start = self:toAbsoluteResidueNumber(newFeature.start),
+ stop = self:toAbsoluteResidueNumber(newFeature.stop),
+ kvList = "style={" ..
+ self.specialKeys:selectStyleFromList(baseKey,
+ self.currentStyle[baseKey]) .. "}",
+ level = newFeature.level or nil
+ }
+ if newFeature.kvList ~= "" then
+ ftEntry.kvList = ftEntry.kvList .. "," .. newFeature.kvList
+ end
+ if newFeature.description then
+ ftEntry.kvList = ftEntry.kvList ..
+ ",description={" .. newFeature.description .. "}"
+ ftEntry.description = newFeature.description
+ end
+ table.insert(self.ft, newFeature.layer or #self.ft + 1, ftEntry)
+end
+
+function Protein:calculateDisulfideLevels()
+ if pgfmolbio.errorCatched then return end
+ local disulfideGrid, currLevel, levelFree
+ disulfideGrid = {}
+
+ for i, v in ipairs(self.ft) do
+ if self.specialKeys.disulfideKeys[v.key] then
+ if v.level then
+ if not disulfideGrid[v.level] then
+ disulfideGrid[v.level] = {}
+ end
+ for currPos = v.start, v.stop do
+ disulfideGrid[v.level][currPos] = true
+ end
+ else
+ currLevel = 1
+ repeat
+ levelFree = true
+ if disulfideGrid[currLevel] then
+ for currPos = v.start, v.stop do
+ levelFree = levelFree
+ and not disulfideGrid[currLevel][currPos]
+ end
+ if levelFree then
+ self.ft[i].level = currLevel
+ for currPos = v.start, v.stop do
+ disulfideGrid[currLevel][currPos] = true
+ end
+ end
+ else
+ self.ft[i].level = currLevel
+ disulfideGrid[currLevel] = {}
+ for currPos = v.start, v.stop do
+ disulfideGrid[currLevel][currPos] = true
+ end
+ levelFree = true
+ end
+ currLevel = currLevel + 1
+ until levelFree == true
+ end
+ end
+ end
+end
+
+function Protein:printTikzDomains()
+ if pgfmolbio.errorCatched then return end
+ local xLeft, xMid, xRight, yMid, xLeftClip, xRightClip,
+ currLine, residuesLeft, currStyle
+
+ for _, currFeature in ipairs(self.ft) do
+ currLine = 0
+ xLeft = currFeature.start - self.residueRangeMin -
+ currLine * self.residuesPerLine + 1
+ while xLeft > self.residuesPerLine do
+ xLeft = xLeft - self.residuesPerLine
+ currLine = currLine + 1
+ end
+ xLeft = xLeft - 1
+ xRight = currFeature.stop - self.residueRangeMin -
+ currLine * self.residuesPerLine + 1
+ residuesLeft = self.residueRangeMax - self.residueRangeMin -
+ currLine * self.residuesPerLine + 1
+ xLeftClip = stringToDim("-5cm")
+ xRightClip = self.residuesPerLine * self.xUnit
+
+ if currFeature.start <= self.residueRangeMax
+ and currFeature.stop >= self.residueRangeMin then
+ repeat
+ if residuesLeft <= self.residuesPerLine then
+ if residuesLeft < xRight then
+ xRightClip = residuesLeft * self.xUnit
+ else
+ xRightClip = xRight * self.xUnit + stringToDim("5cm")
+ end
+ else
+ if xRight <= self.residuesPerLine then
+ xRightClip = xRight * self.xUnit + stringToDim("5cm")
+ end
+ end
+ if xLeft < 0 then xLeftClip = stringToDim("0cm") end
+
+ xMid = (xLeft + xRight) / 2
+ yMid = -currLine * self.baselineSkip
+ if currFeature.level then
+ currFeature.kvList = currFeature.kvList ..
+ ",level=" .. currFeature.level
+ end
+ currFeature.sequence =
+ self.sequence:sub(currFeature.start, currFeature.stop)
+
+ tex.sprint("\n\t\\begin{scope}\\begin{pgfinterruptboundingbox}")
+ tex.sprint("\n\t\t\\def\\xLeft{" ..
+ dimToString(xLeft * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\xMid{" ..
+ dimToString(xMid * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\xRight{" ..
+ dimToString(xRight * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\yMid{" ..
+ dimToString(yMid * self.yUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\featureSequence{" ..
+ currFeature.sequence .. "}")
+ tex.sprint(
+ "\n\t\t\\clip (" ..
+ dimToString(xLeftClip) ..
+ ", \\yMid + " ..
+ dimToString(stringToDim("10cm")) ..
+ ") rectangle (" ..
+ dimToString(xRightClip) ..
+ ", \\yMid - " ..
+ dimToString(stringToDim("10cm")) ..
+ ");"
+ )
+ tex.sprint(
+ "\n\t\t\\pgfmolbioset[domains]{" ..
+ currFeature.kvList ..
+ "}"
+ )
+ if self.specialKeys.printFunctions[currFeature.key] then
+ self.specialKeys.printFunctions[currFeature.key](
+ currFeature, xLeft, xRight, yMid, self.xUnit, self.yUnit)
+ else
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{" ..
+ currFeature.key .. "}")
+ end
+ tex.sprint("\n\t\\end{pgfinterruptboundingbox}\\end{scope}")
+
+ currLine = currLine + 1
+ xLeft = xLeft - self.residuesPerLine
+ xRight = xRight - self.residuesPerLine
+ residuesLeft = residuesLeft - self.residuesPerLine
+ until xRight < 1 or residuesLeft < 1
+ end
+ end
+
+ if self.showRuler then
+ currStyle = 1
+ tex.sprint("\n\t\\begin{scope}")
+ for _, currRuler in ipairs(self.rulerRange) do
+ currLine = 0
+ xMid = currRuler.pos - self.residueRangeMin -
+ currLine * self.residuesPerLine + 1
+ while xMid > self.residuesPerLine do
+ xMid = xMid - self.residuesPerLine
+ currLine = currLine + 1
+ end
+ xMid = xMid - 0.5
+ yMid = -currLine * self.baselineSkip
+ tex.sprint(
+ "\n\t\t\\pgfmolbioset[domains]{current style/.style={" ..
+ self.specialKeys:selectStyleFromList("other/ruler", currStyle) ..
+ "}}"
+ )
+ tex.sprint("\n\t\t\t\\def\\xMid{" ..
+ dimToString(xMid * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\t\\let\\xLeft\\xMid\\let\\xRight\\xMid")
+ tex.sprint("\n\t\t\t\\def\\yMid{" ..
+ dimToString(yMid * self.yUnit) .. "}")
+ tex.sprint("\n\t\t\t\\def\\residueNumber{" ..
+ currRuler.number .. "}")
+ tex.sprint("\n\t\t\t\\pmbdomdrawfeature{other/ruler}")
+ currStyle = currStyle + 1
+ end
+ tex.sprint("\n\t\\end{scope}")
+ end
+
+ xMid =
+ math.min(
+ self.residuesPerLine,
+ self.residueRangeMax - self.residueRangeMin + 1
+ ) / 2
+ tex.sprint("\n\t\\begin{scope}")
+ tex.sprint(
+ "\n\t\t\\pgfmolbioset[domains]{current style/.style={" ..
+ self.specialKeys:selectStyleFromList("other/name", 1) ..
+ "}}"
+ )
+ tex.sprint("\n\t\t\\def\\xLeft{0mm}")
+ tex.sprint("\n\t\t\\def\\xMid{" .. dimToString(xMid * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\xRight{" ..
+ dimToString(self.residuesPerLine * self.xUnit) .. "}")
+ tex.sprint("\n\t\t\\def\\yMid{0mm}")
+ tex.sprint("\n\t\t\\pmbdomdrawfeature{other/name}")
+ tex.sprint("\n\t\\end{scope}")
+
+ tex.sprint(
+ "\n\t\\pmbprotocolsizes{" ..
+ "\\pmbdomvalueof{enlarge left}}{\\pmbdomvalueof{enlarge top}}"
+ )
+ currLine =
+ math.ceil(
+ (self.residueRangeMax - self.residueRangeMin + 1) /
+ self.residuesPerLine
+ ) - 1
+ xRight =
+ math.min(
+ self.residuesPerLine,
+ self.residueRangeMax - self.residueRangeMin + 1
+ )
+ tex.sprint(
+ "\n\t\\pmbprotocolsizes{" ..
+ dimToString(xRight * self.xUnit) ..
+ " + \\pmbdomvalueof{enlarge right}}{" ..
+ dimToString(-currLine * self.baselineSkip * self.yUnit) ..
+ " + \\pmbdomvalueof{enlarge bottom}}"
+ )
+end
+
+function Protein:__tostring()
+ local result = {}
+ local currLine
+
+ currLine = "\\begin{pmbdomains}\n\t\t[name={" ..
+ self.name ..
+ "}"
+ if self.sequence ~= "" then
+ currLine = currLine ..
+ ",\n\t\tsequence=" ..
+ self.sequence
+ end
+ currLine = currLine ..
+ "]{" ..
+ self.sequenceLength ..
+ "}"
+ table.insert(result, currLine)
+
+ for i, v in ipairs(self.ft) do
+ if v.key ~= "other/main chain" then
+ currLine = "\t\\addfeature"
+ if self.includeDescription and v.description then
+ currLine =
+ currLine ..
+ "[description={" ..
+ v.description ..
+ "}]"
+ end
+ currLine =
+ currLine ..
+ "{" ..
+ v.key ..
+ "}{" ..
+ v.start ..
+ "}{" ..
+ v.stop ..
+ "}"
+ table.insert(result, currLine)
+ end
+ end
+ table.insert(result,
+ "\\end{pmbdomains}"
+ )
+ return table.concat(result, "\n")
+end
+--
+-- End of file `pgfmolbio.domains.lua'.
diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.tex b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.tex
new file mode 100644
index 00000000000..104d92763dc
--- /dev/null
+++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.tex
@@ -0,0 +1,799 @@
+%%
+%% This is file `pgfmolbio.domains.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% pgfmolbio.dtx (with options: `pmb-dom-tex')
+%%
+%% Copyright (C) 2012 by Wolfgang Skala
+%%
+%% This work may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.3 or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+\ProvidesFile{pgfmolbio.domains.tex}[2012/10/01 v0.2 Protein domains]
+
+
+\ProvidesFile{pgfmolbio.domains.tex}[2012/10/01 v0.2 Protein Domains]
+
+\ifluatex
+ \RequireLuaModule{pgfmolbio.domains}
+ \directlua{pmbSpecialKeys = pgfmolbio.domains.SpecialKeys:new()}
+\fi
+
+\def\@pmb@dom@keydef#1#2{%
+ \pgfkeyssetvalue{/pgfmolbio/domains/#1}{#2}%
+}
+
+\def\pmbdomvalueof#1{%
+ \pgfkeysvalueof{/pgfmolbio/domains/#1}%
+}
+
+\@pmb@dom@keydef{name}{Protein}
+\newif\ifpmb@dom@showname
+\pgfmolbioset[domains]{%
+ show name/.is if=pmb@dom@showname,
+ show name
+}
+\@pmb@dom@keydef{description}{}
+
+\@pmb@dom@keydef{x unit}{.5mm}
+\@pmb@dom@keydef{y unit}{6mm}
+\@pmb@dom@keydef{residues per line}{200}
+\@pmb@dom@keydef{baseline skip}{3}
+\@pmb@dom@keydef{residue numbering}{auto}
+\@pmb@dom@keydef{residue range}{auto-auto}
+\@pmb@dom@keydef{enlarge left}{0cm}
+\@pmb@dom@keydef{enlarge right}{0cm}
+\@pmb@dom@keydef{enlarge top}{1cm}
+\@pmb@dom@keydef{enlarge bottom}{0cm}
+
+\pgfmolbioset[domains]{%
+ style/.code=\pgfmolbioset[domains]{current style/.style={#1}}
+}
+
+\@pmb@dom@keydef{domain font}{\footnotesize}
+
+\@pmb@dom@keydef{level}{}
+\@pmb@dom@keydef{disulfide base distance}{1}
+\@pmb@dom@keydef{disulfide level distance}{.2}
+\@pmb@dom@keydef{range font}{\sffamily\scriptsize}
+
+\newif\ifpmb@dom@showruler
+\pgfmolbioset[domains]{%
+ show ruler/.is if=pmb@dom@showruler,
+ show ruler
+}
+\@pmb@dom@keydef{ruler range}{auto-auto}
+\@pmb@dom@keydef{default ruler step size}{50}
+\@pmb@dom@keydef{ruler distance}{-.5}
+
+\@pmb@dom@keydef{sequence}{}
+\@pmb@dom@keydef{magnified sequence font}{\ttfamily\footnotesize}
+
+\newif\ifpmb@dom@showsecstructure
+\pgfmolbioset[domains]{%
+ show secondary structure/.is if=pmb@dom@showsecstructure,
+ show secondary structure=false
+}
+\@pmb@dom@keydef{secondary structure distance}{1}
+\pgfmolbioset[domains]{%
+ helix back border color/.code=\colorlet{helix back border color}{#1},
+ helix back main color/.code=\colorlet{helix back main color}{#1},
+ helix back middle color/.code=\colorlet{helix back middle color}{#1},
+ helix front border color/.code=\colorlet{helix front border color}{#1},
+ helix front main color/.code=\colorlet{helix front main color}{#1},
+ helix front middle color/.code=\colorlet{helix front middle color}{#1},
+ helix back border color=white!50!black,
+ helix back main color=white!90!black,
+ helix back middle color=white,
+ helix front border color=red!50!black,
+ helix front main color=red!90!black,
+ helix front middle color=red!10!white
+}
+
+\@pmb@dom@keydef{sequence length}{}
+
+\@pmb@dom@keydef{@layer}{}
+
+\newcommand\setfeatureshape[2]{%
+ \expandafter\def\csname @pmb@dom@feature@#1@shape\endcsname{#2}%
+}
+
+\newcommand\setfeatureshapealias[2]{%
+ \expandafter\def\csname @pmb@dom@feature@#1@shape\endcsname{%
+ \@nameuse{@pmb@dom@feature@#2@shape}%
+ }%
+}
+
+\ifluatex
+ \newcommand\setfeaturestylealias[2]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:aliasFeatureStyle("#1", "#2")
+ else
+ pmbSpecialKeys:aliasFeatureStyle("#1", "#2")
+ end
+ }%
+ }
+ \newcommand\setfeaturealias[2]{%
+ \setfeatureshapealias{#1}{#2}%
+ \setfeaturestylealias{#1}{#2}%
+ }
+\else
+ \let\setfeaturealias\setfeatureshapealias%
+\fi
+
+\newcommand\pmbdomdrawfeature[1]{%
+ \@ifundefined{@pmb@dom@feature@#1@shape}{%
+ \PackageWarning{pgfmolbio}%
+ {Feature shape `#1' unknown, using `default'.}%
+ \@pmb@dom@feature@default@shape%
+ }{%
+ \@nameuse{@pmb@dom@feature@#1@shape}%
+ }%
+}
+
+\setfeatureshape{default}{%
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+ (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+}
+
+\setfeatureshape{domain}{
+ \draw [/pgfmolbio/domains/current style, rounded corners=2pt]
+ (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+ (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+ \node at (\xMid, \yMid)
+ {\pmbdomvalueof{domain font}{\pmbdomvalueof{description}}};
+}
+\setfeaturealias{DOMAIN}{domain}
+
+\setfeatureshape{signal peptide}{%
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + \pmbdomvalueof{y unit} / 5) rectangle
+ (\xRight, \yMid - \pmbdomvalueof{y unit} / 5);
+}
+\setfeaturealias{SIGNAL}{signal peptide}
+
+\setfeatureshape{propeptide}{%
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + .5 * \pmbdomvalueof{y unit}) rectangle
+ (\xRight, \yMid - .5 * \pmbdomvalueof{y unit});
+}
+\setfeaturealias{PROPEP}{propeptide}
+
+\setfeatureshape{carbohydrate}{%
+ \draw [/pgfmolbio/domains/current style]
+ (\xMid, \yMid) --
+ (\xMid, \yMid + .7 * \pmbdomvalueof{y unit})
+ node [above] {\tiny\strut\pmbdomvalueof{description}};
+ \fill [/pgfmolbio/domains/current style]
+ (\xMid, \yMid + .7 * \pmbdomvalueof{y unit}) circle [radius=1pt];
+}
+\setfeaturealias{CARBOHYD}{carbohydrate}
+
+\setfeatureshape{other/main chain}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yUpper{%
+ \yMid + \pmbdomvalueof{secondary structure distance}
+ * \pmbdomvalueof{y unit}%
+ }
+ \draw [thin]
+ (\xLeft, \yUpper pt) --
+ (\xRight, \yUpper pt);%
+ \fi%
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid) --
+ (\xRight, \yMid);%
+}
+
+\setfeatureshape{other/name}{%
+ \ifpmb@dom@showname%
+ \node [/pgfmolbio/domains/current style]
+ at (\xMid, \pmbdomvalueof{baseline skip} * \pmbdomvalueof{y unit})
+ {\pmbdomvalueof{name} (\pmbdomvalueof{sequence length} residues)};
+ \fi%
+}
+
+\setfeatureshape{disulfide}{%
+ \pgfmathsetmacro\yUpper{%
+ \yMid + (
+ \pmbdomvalueof{disulfide base distance} +
+ (\pmbdomvalueof{level} - 1) *
+ \pmbdomvalueof{disulfide level distance}
+ ) * \pmbdomvalueof{y unit}
+ }
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid) --
+ (\xLeft, \yUpper pt) --
+ (\xRight, \yUpper pt) --
+ (\xRight, \yMid);
+}
+\setfeaturealias{DISULFID}{disulfide}
+
+\setfeatureshape{range}{%
+ \pgfmathsetmacro\yUpper{%
+ \yMid + (
+ \pmbdomvalueof{disulfide base distance} +
+ (\pmbdomvalueof{level} - 1) *
+ \pmbdomvalueof{disulfide level distance}
+ ) * \pmbdomvalueof{y unit}
+ }
+ \path [/pgfmolbio/domains/current style]
+ (\xLeft, \yUpper pt) --
+ (\xRight, \yUpper pt)
+ node [pos=.5, above]
+ {\pmbdomvalueof{range font}{\pmbdomvalueof{description}}};
+}
+
+\setfeatureshape{other/ruler}{%
+ \draw [/pgfmolbio/domains/current style]
+ (\xMid,
+ \yMid + \pmbdomvalueof{ruler distance} *
+ \pmbdomvalueof{y unit}) --
+ (\xMid,
+ \yMid + \pmbdomvalueof{ruler distance} *
+ \pmbdomvalueof{y unit} - 1mm)
+ node [below=-1mm] {\tiny\sffamily\strut\residueNumber};
+}
+
+\setfeatureshape{other/sequence}{%
+ \node [/pgfmolbio/domains/current style]
+ at (\xMid, \yMid) {\strut\currentResidue};
+}
+
+\newlength\pmb@magnifiedsequence@width
+
+\setfeatureshape{other/magnified sequence above}{%
+ \settowidth\pmb@magnifiedsequence@width{%
+ \begin{pgfinterruptpicture}%
+ \pmbdomvalueof{magnified sequence font}%
+ \featureSequence%
+ \end{pgfinterruptpicture}%
+ }%
+ \pgfmathsetmacro\xUpperLeft{\xMid - \pmb@magnifiedsequence@width / 2}
+ \pgfmathsetmacro\xUpperRight{\xMid + \pmb@magnifiedsequence@width / 2}
+
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid) --
+ (\xLeft, \yMid + \pmbdomvalueof{y unit} / 6) --
+ (\xUpperLeft pt, \yMid + \pmbdomvalueof{y unit} * 4/6) --
+ (\xUpperLeft pt, \yMid + \pmbdomvalueof{y unit} * 5/6)
+ (\xUpperRight pt, \yMid + \pmbdomvalueof{y unit} * 5/6) --
+ (\xUpperRight pt, \yMid + \pmbdomvalueof{y unit} * 4/6) --
+ (\xRight, \yMid + \pmbdomvalueof{y unit} / 6) --
+ (\xRight, \yMid);
+ \node [anchor=mid]
+ at (\xMid, \yMid + \pmbdomvalueof{y unit})
+ {\pmbdomvalueof{magnified sequence font}\featureSequence};
+}
+
+\setfeatureshape{other/magnified sequence below}{%
+ \settowidth\pmb@magnifiedsequence@width{%
+ \begin{pgfinterruptpicture}%
+ \pmbdomvalueof{magnified sequence font}%
+ \featureSequence%
+ \end{pgfinterruptpicture}%
+ }%
+ \pgfmathsetmacro\xLowerLeft{\xMid - \pmb@magnifiedsequence@width / 2}
+ \pgfmathsetmacro\xLowerRight{\xMid + \pmb@magnifiedsequence@width / 2}
+
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid) --
+ (\xLeft, \yMid - \pmbdomvalueof{y unit} / 6) --
+ (\xLowerLeft pt, \yMid - \pmbdomvalueof{y unit}) --
+ (\xLowerLeft pt, \yMid - \pmbdomvalueof{y unit} * 7/6)
+ (\xLowerRight pt, \yMid - \pmbdomvalueof{y unit} * 7/6) --
+ (\xLowerRight pt, \yMid - \pmbdomvalueof{y unit}) --
+ (\xRight, \yMid - \pmbdomvalueof{y unit} / 6) --
+ (\xRight, \yMid);
+ \node [anchor=mid]
+ at (\xMid, \yMid - \pmbdomvalueof{y unit} * 8/6)
+ {\pmbdomvalueof{magnified sequence font}\featureSequence};
+}
+
+\newcommand\@pmb@dom@helixsegment[1]{%
+ svg [scale=#1] "%
+ c 0.30427 0
+ 0.62523 0.59174
+ 0.79543 0.96646
+ c 0.97673 2.15039
+ 1.34005 4.49858
+ 1.84538 6.6178
+ c 0.56155 2.35498
+ 0.99602 4.514
+ 1.82948 6.72355
+ c 0.11069 0.29346
+ 0.23841 0.69219
+ 0.56172 0.69219
+ l -5 0
+ c -0.27235 0.0237
+ -0.55793 -0.51373
+ -0.65225 -0.76773
+ c -0.98048 -2.64055
+ -1.40233 -5.46534
+ -2.06809 -8.00784
+ c -0.50047 -1.91127
+ -0.94696 -3.73368
+ -1.68631 -5.43929
+ c -0.14066 -0.3245
+ -0.34516 -0.78514
+ -0.69997 -0.78514
+ z"
+}
+
+\newcommand\@pmb@dom@helixhalfsegment[1]{%
+ svg [scale=#1] "%
+ c 0.50663 2.18926
+ 0.96294 4.51494
+ 1.78125 6.71875
+ c 0.09432 0.254
+ 0.35265 0.80495
+ 0.625 0.78125
+ l 5 0
+ c -0.32331 0
+ -0.45181 -0.42529
+ -0.5625 -0.71875
+ c -0.83346 -2.20955
+ -1.2822 -4.36377
+ -1.84375 -6.78125
+ l -5 0
+ z"
+}
+
+\pgfdeclareverticalshading[%
+ helix back border color,%
+ helix back main color,%
+ helix back middle color%
+ ]{helix half upper back}{100bp}{
+ color(0bp)=(helix back middle color);
+ color(5bp)=(helix back middle color);
+ color(45bp)=(helix back main color);
+ color(75bp)=(helix back border color);
+ color(100bp)=(helix back border color)
+}
+
+\pgfdeclareverticalshading[%
+ helix back border color,%
+ helix back main color,%
+ helix back middle color%
+ ]{helix half lower back}{100bp}{
+ color(0bp)=(helix back border color);
+ color(25bp)=(helix back border color);
+ color(35bp)=(helix back main color);
+ color(55bp)=(helix back middle color);
+ color(95bp)=(helix back main color);
+ color(100bp)=(helix back main color)
+}
+
+\pgfdeclareverticalshading[%
+ helix back border color,%
+ helix back main color,%
+ helix back middle color%
+ ]{helix full back}{100bp}{
+ color(0bp)=(helix back border color);
+ color(25bp)=(helix back border color);
+ color(30bp)=(helix back main color);
+ color(40bp)=(helix back middle color);
+ color(60bp)=(helix back main color);
+ color(75bp)=(helix back border color);
+ color(100bp)=(helix back border color)
+}
+
+\pgfdeclareverticalshading[%
+ helix front border color,%
+ helix front main color,%
+ helix front middle color%
+ ]{helix half upper front}{100bp}{
+ color(0bp)=(helix front main color);
+ color(5bp)=(helix front main color);
+ color(45bp)=(helix front middle color);
+ color(65bp)=(helix front main color);
+ color(75bp)=(helix front border color);
+ color(100bp)=(helix front border color)
+}
+
+\pgfdeclareverticalshading[%
+ helix front border color,%
+ helix front main color,%
+ helix front middle color%
+ ]{helix full front}{100bp}{
+ color(0bp)=(helix front border color);
+ color(25bp)=(helix front border color);
+ color(40bp)=(helix front main color);
+ color(60bp)=(helix front middle color);
+ color(70bp)=(helix front main color);
+ color(75bp)=(helix front border color);
+ color(100bp)=(helix front border color)
+}
+
+\setfeatureshape{helix/half upper back}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix half upper back]
+ (\xLeft, \yMid + \yShift pt)
+ \@pmb@dom@helixhalfsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\setfeatureshape{helix/half lower back}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix half lower back]
+ (\xRight, \yMid + \yShift pt) [rotate=180]
+ \@pmb@dom@helixhalfsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\setfeatureshape{helix/full back}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix full back]
+ (\xMid, \yLower + \yShift pt)
+ \@pmb@dom@helixsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\setfeatureshape{helix/half upper front}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix half upper front]
+ (\xRight, \yMid + \yShift pt) [xscale=-1]
+ \@pmb@dom@helixhalfsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\setfeatureshape{helix/full front}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [shading=helix full front]
+ (\xMid, \yLower + \yShift pt) [xscale=-1]
+ \@pmb@dom@helixsegment{\pmbdomvalueof{x unit} / 5};
+ \fi%
+}
+
+\definecolor{strand left color}{RGB}{42,127,255}
+\definecolor{strand right color}{RGB}{128,179,255}
+
+\setfeatureshape{beta strand}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid + \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid + 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight, \yMid + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid - 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid - \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xLeft, \yMid - \pmbdomvalueof{x unit} + \yShift pt) --
+ cycle;%
+ \fi%
+}
+\setfeaturealias{STRAND}{beta strand}
+
+\setfeatureshape{beta turn}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \pgfmathsetmacro\turnXradius{(\xRight - \xLeft) / 2}%
+ \pgfmathsetmacro\turnYradius{\pmbdomvalueof{x unit} * 1.5}%
+ \fill [white]
+ (\xLeft, \yMid + 1mm + \yShift pt) rectangle
+ (\xRight, \yMid - 1mm + \yShift pt);%
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft - .5pt, \yMid + \yShift pt) --
+ (\xLeft, \yMid + \yShift pt) arc
+ [start angle=180, end angle=0,
+ x radius=\turnXradius pt, y radius=\turnYradius pt] --
+ (\xRight + .5pt, \yMid + \yShift pt);%
+ \fi%
+}
+\setfeaturealias{TURN}{beta turn}
+
+\setfeatureshape{beta bridge}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft, \yMid + .25 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid + .25 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid + 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight, \yMid + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid - 1.5 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xRight - 1.5 * \pmbdomvalueof{x unit},
+ \yMid - .25 * \pmbdomvalueof{x unit} + \yShift pt) --
+ (\xLeft, \yMid - .25 * \pmbdomvalueof{x unit} + \yShift pt) --
+ cycle;%
+ \fi%
+}
+
+\setfeatureshape{bend}{%
+ \ifpmb@dom@showsecstructure%
+ \pgfmathsetmacro\yShift{%
+ \pmbdomvalueof{secondary structure distance} *
+ \pmbdomvalueof{y unit}%
+ }
+ \fill [white]
+ (\xLeft, \yMid + 1mm + \yShift pt) rectangle
+ (\xRight, \yMid - 1mm + \yShift pt);%
+ \draw [/pgfmolbio/domains/current style]
+ (\xLeft - .5pt, \yMid + \yShift pt) --
+ (\xLeft, \yMid + \yShift pt) --
+ (\xMid, \yMid + .5 * \pmbdomvalueof{y unit} + \yShift pt) --
+ (\xRight, \yMid + \yShift pt) --
+ (\xRight + .5pt, \yMid + \yShift pt);%
+ \fi%
+}
+
+\ifluatex\else\expandafter\endinput\fi
+
+\newcommand\pmb@dom@inputuniprot[1]{%
+ \directlua{
+ pmbProtein:readUniprotFile("#1")
+ pmbProtein:getParameters()
+ pmbProtein:setParameters{
+ residueNumbering = "\pmbdomvalueof{residue numbering}"
+ }
+ }%
+}
+
+\newcommand\pmb@dom@inputgff[1]{%
+ \directlua{
+ pmbProtein:readGffFile("#1")
+ pmbProtein:setParameters{
+ residueNumbering = "\pmbdomvalueof{residue numbering}"
+ }
+ }%
+}
+
+\newcommand\pmb@dom@addfeature[4][]{%
+ \begingroup%
+ \pgfmolbioset[domains]{#1}%
+ \@pmb@toksa{#1}%
+ \directlua{
+ pmbProtein:addFeature{
+ key = "#2",
+ start = "#3",
+ stop = "#4",
+ kvList = "\luaescapestring{\the\@pmb@toksa}",
+ level = tonumber("\pmbdomvalueof{level}"),
+ layer = tonumber("\pmbdomvalueof{@layer}")
+ }
+ }%
+ \endgroup%
+}
+
+\newif\ifpmb@dom@tikzpicture
+
+\newenvironment{pmbdomains}[2][]{%
+ \@ifundefined{useasboundingbox}%
+ {\pmb@dom@tikzpicturefalse\begin{tikzpicture}}%
+ {\pmb@dom@tikzpicturetrue}%
+ \pgfmolbioset[domains]{sequence length=#2, #1}%
+ \let\inputuniprot\pmb@dom@inputuniprot%
+ \let\inputgff\pmb@dom@inputgff%
+ \let\addfeature\pmb@dom@addfeature%
+ \directlua{
+ pmbProtein = pgfmolbio.domains.Protein:new()
+ pmbProtein.specialKeys =
+ pgfmolbio.domains.SpecialKeys:new(pmbSpecialKeys)
+ pmbProtein:setParameters{
+ sequenceLength = "\pmbdomvalueof{sequence length}"
+ }
+ pmbProtein:setParameters{
+ residueNumbering = "\pmbdomvalueof{residue numbering}"
+ }
+ }%
+}{%
+ \pmb@dom@addfeature[@layer=1]{other/main chain}%
+ {(1)}{(\pmbdomvalueof{sequence length})}%
+ \@pmb@toksa=%
+ \expandafter\expandafter\expandafter\expandafter%
+ \expandafter\expandafter\expandafter{%
+ \pgfkeysvalueof{/pgfmolbio/domains/name}%
+ }%
+ \directlua{
+ pmbProtein:setParameters{
+ residueRange = "\pmbdomvalueof{residue range}",
+ defaultRulerStepSize = "\pmbdomvalueof{default ruler step size}"
+ }
+ pmbProtein:setParameters{
+ name = "\luaescapestring{\the\@pmb@toksa}",
+ xUnit = "\pmbdomvalueof{x unit}",
+ yUnit = "\pmbdomvalueof{y unit}",
+ residuesPerLine = "\pmbdomvalueof{residues per line}",
+ baselineSkip = "\pmbdomvalueof{baseline skip}",
+ showRuler = "\ifpmb@dom@showruler true\else false\fi",
+ rulerRange = "\pmbdomvalueof{ruler range}",
+ sequence = "\pmbdomvalueof{sequence}"
+ }
+ pmbProtein:calculateDisulfideLevels()
+ pgfmolbio.setCoordinateFormat(
+ "\pgfkeysvalueof{/pgfmolbio/coordinate unit}",
+ "\pgfkeysvalueof{/pgfmolbio/coordinate format string}"
+ )
+ \ifpmb@loadmodule@convert
+ local filename =
+ "\pgfkeysvalueof{/pgfmolbio/convert/output file name}"
+ if filename == "(auto)" then
+ filename = "pmbconverted" .. pgfmolbio.outputFileId
+ end
+ filename = filename ..
+ ".\pgfkeysvalueof{/pgfmolbio/convert/output file extension}"
+ outputFile, ioError = io.open(filename, "w")
+ if ioError then
+ tex.error(ioError)
+ end
+ \ifpmb@con@outputtikzcode
+ tex.sprint = function(a) outputFile:write(a) end
+ pmbProtein:getParameters()
+ tex.sprint("\string\n\string\\begin{tikzpicture}")
+ pmbProtein:printTikzDomains()
+ tex.sprint("\string\n\string\\end{tikzpicture}")
+ \else
+ \ifpmb@con@includedescription
+ pmbProtein.includeDescription = true
+ \fi
+ outputFile:write(tostring(pmbProtein))
+ \fi
+ outputFile:close()
+ pgfmolbio.outputFileId = pgfmolbio.outputFileId + 1
+ \else
+ pmbProtein:printTikzDomains()
+ \fi
+ pmbProtein = nil
+ }%
+ \ifpmb@dom@tikzpicture\else\end{tikzpicture}\fi%
+}
+
+\newcommand\setdisulfidefeatures[1]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:clearKeys("disulfideKeys")
+ pmbProtein.specialKeys:setKeys("disulfideKeys", "#1", true)
+ else
+ pmbSpecialKeys:clearKeys("disulfideKeys")
+ pmbSpecialKeys:setKeys("disulfideKeys", "#1", true)
+ end
+ }%
+}
+
+\newcommand\adddisulfidefeatures[1]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setKeys("disulfideKeys", "#1", true)
+ else
+ pmbSpecialKeys:setKeys("disulfideKeys", "#1", true)
+ end
+ }%
+}
+
+\newcommand\removedisulfidefeatures[1]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setKeys("disulfideKeys", "#1", nil)
+ else
+ pmbSpecialKeys:setKeys("disulfideKeys", "#1", nil)
+ end
+ }%
+}
+
+\setdisulfidefeatures{DISULFID, disulfide, range}
+
+\newcommand\setfeatureprintfunction[2]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setKeys("printFunctions", "#1", #2)
+ else
+ pmbSpecialKeys:setKeys("printFunctions", "#1", #2)
+ end
+ }%
+}
+
+\newcommand\removefeatureprintfunction[1]{%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setKeys("printFunctions", "#1", nil)
+ else
+ pmbSpecialKeys:setKeys("printFunctions", "#1", nil)
+ end
+ }%
+}
+
+\setfeatureprintfunction{other/sequence}%
+ {pgfmolbio.domains.printSequenceFeature}
+\setfeatureprintfunction{alpha helix, pi helix, 310 helix, HELIX}%
+ {pgfmolbio.domains.printHelixFeature}
+
+\newcommand\setfeaturestyle[2]{%
+ \@pmb@toksa{#2}%
+ \directlua{
+ if pmbProtein then
+ pmbProtein.specialKeys:setFeatureStyle(
+ "#1", "\luaescapestring{\the\@pmb@toksa}"
+ )
+ else
+ pmbSpecialKeys:setFeatureStyle(
+ "#1", "\luaescapestring{\the\@pmb@toksa}"
+ )
+ end
+ }%
+}
+
+\setfeaturestyle{default}{draw}
+\setfeaturestyle{domain}%
+ {fill=Chartreuse,fill=LightSkyBlue,fill=LightPink,fill=Gold!50}
+\setfeaturestyle{signal peptide}{fill=black}
+\setfeaturestyle{propeptide}%
+ {*1{fill=Gold, opacity=.5, rounded corners=4pt}}
+\setfeaturestyle{carbohydrate}{red}
+\setfeaturestyle{other/main chain}{*1{draw, line width=2pt, black!25}}
+\setfeaturestyle{other/name}{font=\sffamily}
+\setfeaturestyle{disulfide}{draw=olive}
+\setfeaturestyle{range}{*1{draw,decorate,decoration=brace}}
+\setfeaturestyle{other/ruler}{black, black!50}
+\setfeaturestyle{other/sequence}{*1{font=\ttfamily\tiny}}%
+\setfeaturestyle{other/magnified sequence above}%
+ {*1{draw=black!50, densely dashed}}
+\setfeaturestylealias{other/magnified sequence below}%
+ {other/magnified sequence above}
+\setfeaturestyle{alpha helix}{%
+ *1{helix front border color=red!50!black,%
+ helix front main color=red!90!black,%
+ helix front middle color=red!10!white}%
+}
+\setfeaturestylealias{HELIX}{alpha helix}
+\setfeaturestyle{pi helix}{%
+ *1{helix front border color=yellow!50!black,%
+ helix front main color=yellow!70!red,%
+ helix front middle color=yellow!10!white}%
+}
+\setfeaturestyle{310 helix}{%
+ *1{helix front border color=magenta!50!black,%
+ helix front main color=magenta!90!black,%
+ helix front middle color=magenta!10!white}%
+}
+\setfeaturestyle{beta strand}{%
+ *1{left color=strand left color, right color=strand right color}%
+}
+\setfeaturestyle{beta turn}{*1{draw=violet, thick}}
+\setfeaturestyle{beta bridge}{*1{fill=MediumBlue}}
+\setfeaturestyle{bend}{*1{draw=magenta, thick}}
+\endinput
+%%
+%% End of file `pgfmolbio.domains.tex'.
diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty
index 46aa6e10a9d..a841ec2d6ea 100644
--- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty
+++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty
@@ -4,9 +4,9 @@
%%
%% The original source files were:
%%
-%% pgfmolbio.dtx (with options: `pgfmolbio')
+%% pgfmolbio.dtx (with options: `pgfmolbio-tex')
%%
-%% Copyright (C) 2011 by Wolfgang Skala
+%% Copyright (C) 2012 by Wolfgang Skala
%%
%% This work may be distributed and/or modified under the
%% conditions of the LaTeX Project Public License, either version 1.3
@@ -16,22 +16,35 @@
%% and version 1.3 or later is part of all distributions of LaTeX
%% version 2005/12/01 or later.
%%
-\ProvidesPackage{pgfmolbio}[2011/09/20 v0.1 Molecular biology graphs with TikZ]
+\ProvidesPackage{pgfmolbio}[2012/10/01 v0.2 Molecular biology graphs with TikZ]
\NeedsTeXFormat{LaTeX2e}[1999/12/01]
+
\newif\ifpmb@loadmodule@chromatogram
+\newif\ifpmb@loadmodule@domains
+\newif\ifpmb@loadmodule@convert
-\DeclareOption{chromatogram}{
- \pmb@loadmodule@chromatogramtrue
+\DeclareOption{chromatogram}{%
+ \pmb@loadmodule@chromatogramtrue%
+}
+\DeclareOption{domains}{%
+ \pmb@loadmodule@domainstrue%
+}
+\DeclareOption{convert}{%
+ \pmb@loadmodule@converttrue%
}
+
\ProcessOptions
-\RequirePackage{luatexbase-modutils}
- \RequireLuaModule{lualibs}
+\RequirePackage{ifluatex}
+\ifluatex
+ \RequirePackage{luatexbase-modutils}
+ \RequireLuaModule{lualibs}
+ \RequireLuaModule{pgfmolbio}
+\fi
+\RequirePackage[svgnames,dvipsnames]{xcolor}
\RequirePackage{tikz}
- \usetikzlibrary{positioning}
-
-\RequirePackage{xcolor}
+ \usetikzlibrary{positioning,svg.path}
\newcommand\pgfmolbioset[2][]{%
\def\@tempa{#1}%
@@ -42,9 +55,28 @@
\fi%
}
+\pgfkeyssetvalue{/pgfmolbio/coordinate unit}{mm}
+\pgfkeyssetvalue{/pgfmolbio/coordinate format string}{\%s\%s}
+
+\newtoks\@pmb@toksa
+\newtoks\@pmb@toksb
+\newif\ifpmb@con@includedescription
+\newif\ifpmb@con@outputtikzcode
+
+\def\pmbprotocolsizes#1#2{%
+ \pgfpoint{#1}{#2}%
+ \pgf@protocolsizes{\pgf@x}{\pgf@y}%
+}
+
\ifpmb@loadmodule@chromatogram
\input{pgfmolbio.chromatogram.tex}
\fi
+\ifpmb@loadmodule@domains
+ \input{pgfmolbio.domains.tex}
+\fi
+\ifpmb@loadmodule@convert
+ \input{pgfmolbio.convert.tex}
+\fi
\endinput
%%
%% End of file `pgfmolbio.sty'.