diff options
Diffstat (limited to 'Master/texmf-dist/tex/lualatex/pgfmolbio')
6 files changed, 24 insertions, 1396 deletions
diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.lua b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.lua deleted file mode 100644 index 7c1eae02177..00000000000 --- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.lua +++ /dev/null @@ -1,562 +0,0 @@ --- --- This is file `pgfmolbio.chromatogram.lua', --- generated with the docstrip utility. --- --- The original source files were: --- --- pgfmolbio.dtx (with options: `pmb-chr-lua') --- --- Copyright (C) 2013 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.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 stringToDim = pgfmolbio.stringToDim -local dimToString = pgfmolbio.dimToString -local packageError = pgfmolbio.packageError -local packageWarning = pgfmolbio.packageWarning -local getRange = pgfmolbio.getRange - -local function stdProbStyle(prob) - local color = "" - if prob >= 0 and prob < 10 then - color = "black" - elseif prob >= 10 and prob < 20 then - color = "pmbTraceRed" - elseif prob >= 20 and prob < 30 then - color = "pmbTraceYellow" - else - color = "pmbTraceGreen" - end - return "ultra thick, " .. color -end - -local function findBasesInStr(target) - if not target then return end - local result = {} - for _, v in ipairs(ALL_BASES) do - if target:upper():find(v) then - table.insert(result, v) - end - end - return result -end - -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(self.selectedPeaks) do - for __, currProb in pairs(currPeak.prob) do - if currProb > maxProb then maxProb = currProb end - if currProb < minProb then minProb = currProb end - end - end - return minProb, maxProb -end - -function Chromatogram:getSampleAndPeakIndex(baseIndex, isLowerLimit) - local sampleId, peakId - - 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 sampleId, peakId -end - -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, 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 - end - 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, self.header.basesNumber do - self.peaks[i].prob.A = readInt(scfFile, 1) - end - - for i = 1, self.header.basesNumber do - self.peaks[i].prob.C = readInt(scfFile, 1) - end - - for i = 1, self.header.basesNumber do - self.peaks[i].prob.G = readInt(scfFile, 1) - end - - for i = 1, self.header.basesNumber do - self.peaks[i].prob.T = readInt(scfFile, 1) - end - - for i = 1, self.header.basesNumber do - self.peaks[i].base = string.char(readInt(scfFile, 1)) - end - - scfFile:close() - end -end - -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 Chromatogram:printTikzChromatogram() - if pgfmolbio.errorCatched then return end - self.selectedPeaks = {} - local tIndex = 1 - 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 = self.sampleMax + 1 - self.sampleMin - } - if tIndex > 1 then - 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 self.baseNumberMin == -1 then - self.baseNumberMin = self.selectedPeaks[1].baseIndex - end - if self.baseNumberMax == -1 then - self.baseNumberMax = self.selectedPeaks[tIndex-1].baseIndex - end - end - - local samplesLeft = self.sampleMax - self.sampleMin + 1 - local currLine = 0 - while samplesLeft > 0 do - local yLower = -currLine * self.baselineSkip - local yUpper = -currLine * self.baselineSkip + self.canvasHeight - local xRight = - (math.min(self.samplesPerLine, samplesLeft) - 1) * self.xUnit - tex.sprint( - "\n\t\\draw [" .. PGFKEYS_PATH .. "canvas style] (" .. - dimToString(0) .. - ", " .. - dimToString(yLower) .. - ") rectangle (" .. - dimToString(xRight) .. - ", " .. - dimToString(yUpper) .. - ");" - ) - samplesLeft = samplesLeft - self.samplesPerLine - currLine = currLine + 1 - end - - 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 <= 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 - firstPointInLine = false - end - tex.sprint( - "(" .. - dimToString(x) .. - ", " .. - dimToString(y) .. - ")" - ) - end - if sampleX ~= self.sampleMax + 1 - self.sampleMin then - if sampleX >= (currLine + 1) * self.samplesPerLine then - currLine = currLine + 1 - tex.sprint(";\n\t\\draw [" .. self.traceStyle[baseName] .. "] ") - firstPointInLine = true - end - else - tex.sprint(";") - end - sampleX = sampleX + 1 - currSampleIndex = currSampleIndex + 1 - end - end - - local currLine = 0 - local lastProbX = 1 - local probRemainder = false - - for _, currPeak in ipairs(self.selectedPeaks) do - while currPeak.offset > (currLine + 1) * self.samplesPerLine do - currLine = currLine + 1 - end - - local x = ((currPeak.offset - 1) % self.samplesPerLine) * self.xUnit - local yUpper = -currLine * self.baselineSkip - local yLower = -currLine * self.baselineSkip - self.tickLength - local tickOperation = "" - if self.ticksDrawn:upper():find(currPeak.base) then - tickOperation = "--" - end - - tex.sprint( - "\n\t\\draw [" .. - self.tickStyle[currPeak.base] .. - "] (" .. - dimToString(x) .. - ", " .. - dimToString(yUpper) .. - ") " .. - tickOperation .. - " (" .. - dimToString(x) .. - ", " .. - dimToString(yLower) .. - ")" - ) - if self.baseLabelsDrawn:upper():find(currPeak.base) then - tex.sprint( - " node [" .. - self.baseLabelStyle[currPeak.base] .. - "] {" .. - self.baseLabelText[currPeak.base] .. - "}" - ) - end - - 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] {\\strut " .. - currPeak.baseIndex .. - "}" - ) - end - tex.sprint(";") - - if probRemainder then - tex.sprint(probRemainder) - probRemainder = false - end - local drawCurrProb = - self.probabilitiesDrawn:upper():find(currPeak.base) - local xLeft = lastProbX - 1 - currLine * self.samplesPerLine - if xLeft < 0 then - 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( - "\n\t\\draw [" .. - self.probStyle(currPeak.prob[currPeak.base]) .. - "] (" .. - dimToString(xLeftPrev) .. - ", " .. - dimToString(yPrev) .. - ") -- (" .. - dimToString(xRightPrev) .. - ", " .. - dimToString(yPrev) .. - ");" - ) - end - xLeft = 0 - else - xLeft = xLeft * self.xUnit - end - - local xRight = currPeak.probXRight - 1 - currLine * self.samplesPerLine - if xRight >= self.samplesPerLine then - if drawCurrProb then - local xRightNext = (xRight - self.samplesPerLine) * self.xUnit - local yNext = -(currLine+1) * self.baselineSkip - self.probDistance - probRemainder = - "\n\t\\draw [" .. - self.probStyle(currPeak.prob[currPeak.base]) .. - "] (" .. - dimToString(0) .. - ", " .. - dimToString(yNext) .. - ") -- (" .. - dimToString(xRightNext) .. - ", " .. - dimToString(yNext) .. - ");" - end - xRight = (self.samplesPerLine - 1) * self.xUnit - else - xRight = xRight * self.xUnit - end - - local y = -currLine * self.baselineSkip - self.probDistance - if drawCurrProb then - tex.sprint( - "\n\t\\draw [" .. - self.probStyle(currPeak.prob[currPeak.base]) .. - "] (" .. - dimToString(xLeft) .. - ", " .. - dimToString(y) .. - ") -- (" .. - dimToString(xRight) .. - ", " .. - dimToString(y) .. - ");" - ) - end - lastProbX = currPeak.probXRight - end -end --- --- End of file `pgfmolbio.chromatogram.lua'. diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex index 32cd1c4e867..95a75d31ff9 100644 --- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex +++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.chromatogram.tex @@ -6,17 +6,17 @@ %% %% pgfmolbio.dtx (with options: `pmb-chr-tex') %% -%% Copyright (C) 2013 by Wolfgang Skala +%% Copyright (C) 2024 by Wolfgang Esser-Skala %% %% This work may be distributed and/or modified under the -%% conditions of the LaTeX Project Public License, either version 1.3 +%% conditions of the LaTeX Project Public License, either version 1.3c %% 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. +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX +%% version 2008/05/04 or later. %% -\ProvidesFile{pgfmolbio.chromatogram.tex}[2013/08/01 v0.21 SCF chromatograms] +\ProvidesFile{pgfmolbio.chromatogram.tex}[2024/06/17 v0.21a SCF chromatograms] \ifluatex diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex index 49a77fe6986..6e789f7e07e 100644 --- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex +++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.convert.tex @@ -6,17 +6,17 @@ %% %% pgfmolbio.dtx (with options: `pmb-con-tex') %% -%% Copyright (C) 2013 by Wolfgang Skala +%% Copyright (C) 2024 by Wolfgang Esser-Skala %% %% This work may be distributed and/or modified under the -%% conditions of the LaTeX Project Public License, either version 1.3 +%% conditions of the LaTeX Project Public License, either version 1.3c %% 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. +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX +%% version 2008/05/04 or later. %% -\ProvidesFile{pgfmolbio.convert.tex}[2013/08/01 v0.21 pgfmolbio graph conversion] +\ProvidesFile{pgfmolbio.convert.tex}[2024/06/17 v0.21a pgfmolbio graph conversion] \pdfdraftmode1 diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.lua b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.lua deleted file mode 100644 index 88d8907aa83..00000000000 --- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.lua +++ /dev/null @@ -1,810 +0,0 @@ --- --- 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) 2013 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 index 4fe6bcae04e..05f08bba45e 100644 --- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.tex +++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.domains.tex @@ -6,17 +6,17 @@ %% %% pgfmolbio.dtx (with options: `pmb-dom-tex') %% -%% Copyright (C) 2013 by Wolfgang Skala +%% Copyright (C) 2024 by Wolfgang Esser-Skala %% %% This work may be distributed and/or modified under the -%% conditions of the LaTeX Project Public License, either version 1.3 +%% conditions of the LaTeX Project Public License, either version 1.3c %% 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. +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX +%% version 2008/05/04 or later. %% -\ProvidesFile{pgfmolbio.domains.tex}[2013/08/01 v0.21 Protein domains] +\ProvidesFile{pgfmolbio.domains.tex}[2024/06/17 v0.21a Protein domains] \ProvidesFile{pgfmolbio.domains.tex}[2012/10/01 v0.2 Protein Domains] diff --git a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty index cb3479cb2ea..0d294dab5b9 100644 --- a/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty +++ b/Master/texmf-dist/tex/lualatex/pgfmolbio/pgfmolbio.sty @@ -6,17 +6,17 @@ %% %% pgfmolbio.dtx (with options: `pgfmolbio-tex') %% -%% Copyright (C) 2013 by Wolfgang Skala +%% Copyright (C) 2024 by Wolfgang Esser-Skala %% %% This work may be distributed and/or modified under the -%% conditions of the LaTeX Project Public License, either version 1.3 +%% conditions of the LaTeX Project Public License, either version 1.3c %% 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. +%% https://www.latex-project.org/lppl.txt +%% and version 1.3c or later is part of all distributions of LaTeX +%% version 2008/05/04 or later. %% -\ProvidesPackage{pgfmolbio}[2013/08/01 v0.21 Molecular biology graphs with TikZ] +\ProvidesPackage{pgfmolbio}[2024/06/17 v0.21a Molecular biology graphs with TikZ] \NeedsTeXFormat{LaTeX2e}[1999/12/01] |