From 501d1837aeddc838bf1ea0898f94d6b9435aa205 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 18 Oct 2012 22:52:50 +0000 Subject: pgfmolbio 0.2 (7oct12) git-svn-id: svn://tug.org/texlive/trunk@28023 c570f23f-e606-0410-a88d-b1316a301751 --- .../lualatex/pgfmolbio/pgfmolbio.chromatogram.lua | 624 +++++++++------- .../lualatex/pgfmolbio/pgfmolbio.chromatogram.tex | 233 +++--- .../tex/lualatex/pgfmolbio/pgfmolbio.convert.tex | 40 + .../tex/lualatex/pgfmolbio/pgfmolbio.domains.lua | 810 +++++++++++++++++++++ .../tex/lualatex/pgfmolbio/pgfmolbio.domains.tex | 799 ++++++++++++++++++++ .../tex/lualatex/pgfmolbio/pgfmolbio.sty | 52 +- 6 files changed, 2170 insertions(+), 388 deletions(-) create mode 100644 Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex create mode 100644 Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.lua create mode 100644 Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.tex (limited to 'Master/texmf-dist/tex/lualatex/pgfmolbio') 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'. -- cgit v1.2.3