Commit c950aa82 authored by Turnhout, M.C. van's avatar Turnhout, M.C. van
Browse files

start working it out on paper

parent 2ff6f85b
function [amounts, imrgb] = clrdecon(dyes, imRGB)
function [amounts, atoRGB, imrgb] = clrdecon(dyes, imRGB)
% dye OD matrix: amount*nOD
p = -log(dyes + 1); % add one to avoid taking log(0) (which would be bad)
p = log(dyes + 1); % add one to avoid taking log(0) (which would be bad)
% normalise: matrix M contains `p-hat'
% normalise: matrix M contains `p-hat' or `nOD'
M = p;
for r = 1:size(p, 2) % loop over rows (input colours)
M(r, :) = M(r, :)/norm(p(r, :)); % divide row by its length
end
M = M
% image OD
imOD = -log(imRGB + 1);
imOD = log(imRGB + 1);
% dye contributions: 3 by 1 column
% amounts = inv(M)*imOD
amounts = M\imOD; % is faster and more accurate in Matlab
amounts = inv(M')*imOD'
amounts = M'\imOD'; % is faster and more accurate in Matlab
% convert back to intensities
atoRGB = zeros(3);
for c = 1:3
% [amounts(1)*M(c, 1) amounts(3)*M(c, 3) amounts(3)*M(c, 3)]
atoRGB(c, :) = exp(-amounts'.*M(c, :)) - 1;
atoRGB(c, :) = exp(amounts'.*M(c, :)) - 1; % subtract one to scale back to 0-255
end
imrgb = sum(atoRGB, 1);
......
% !TeX root = colourdecon.tex
%\begin{savequote}
%The ``computable'' numbers may be described briefly as the real numbers whose expressions as a decimal are calculable by finite means.\qauthor{Alan Turing \cite{Turing1937}}
%\end{savequote}
\chapter{Linear algebra behind colour deconvolution}\label{algebra}
\section{Introduction}
Ruifrok and Johnston propose a method to do colour deconvolution for subtractive colour mixing in \cite{Ruifrok2001}.
They use the law of Bouguer-Lambert-Beer \cite{Beer1852,Perrin1948} for a linear relationship between `the amount dye' and `the amount of absorbed light', and neglect such effects as reflection and scattering.
\section{Transmittance and absorbance}
The amount (fraction) of light that is transmitted through a certain amount of a certain dye $T$ is usually written as
\begin{equation}
T(\lambda) = \frac{I(\lambda)}{I_0(\lambda)} = 10^{-\varepsilon(\lambda)cd}
\end{equation}
with $\lambda$\,[nm] the wavelength of the light, $I_0$\,[-] the intensity of the incoming light, $I$\,[-] the intensity of the light after the sample, $\varepsilon$\,[mol\ap{-1}] the molar extinction coefficient, $c$\,[mol/m] the dye concentration, and $d$\,[m] the path length through the sample.
The corresponding `absorbance' is then:
\begin{equation}
A(\lambda) = \log\left(\frac{I(\lambda)}{I_0(\lambda)}\right) = -\log T(\lambda) = \varepsilon(\lambda)cd
\end{equation}
~\\
\noindent We now choose to write this as:
\begin{equation}
T(\lambda) = \mathrm{e}^{-k(\lambda)a} \label{Tlambda}
\end{equation}
With $k(\lambda)$\,[g\ap{-1}] the mass extinction coefficient, and $a$\,[g] the amount of dye in the sample (in grams), and with
\begin{align}
a & = cdM\\
k(\lambda) & =\frac{ \ln(10) \varepsilon(\lambda)}{M}
\end{align}
with $M$\,[g/mol] the molar mass of the dye, and $\ln(10)$ from the conversion of the base of the exponent.
Absorbance is now linear in the extinction coefficient $k$ and the amount of dye $a$:
\begin{equation}
A(\lambda) = -\ln T(\lambda) = k(\lambda)a \label{Alambda}
\end{equation}
In this formulation `optical density' is an alternative term for $A(\lambda)$, and `absorption coefficient' and `attenuation coefficient' are alternative names for $k(\lambda)$.
The concept that is exploited by Ruifrok and Johnson \cite{Ruifrok2001} is that: since optical density $A(\lambda)$ is linear in absorption $k(\lambda)$ and dye amount $a$ we can simple add contributions of $n$ different dyes to find their combined (`total') absorbance or optical density. For $N$ dyes:
\begin{equation}
A(\lambda) = \sum_{n=1}^N a_n k_n(\lambda)
\end{equation}
\section{Linear algebra with discrete wavelengths}
For a discrete number of $N$ wavelengths, we can now write for the absorbance of a single dye in column format as:
\begin{align}
\col{A} & = \begin{bmatrix} A(\lambda_1)\\ A(\lambda_2)\\ \vdots \\ A(\lambda_N)\end{bmatrix} = \begin{bmatrix} A_\mathrm{1}\\ A_\mathrm{2}\\ \vdots \\ A_\mathrm{N}\end{bmatrix} \\
\col{k} & = \begin{bmatrix} k(\lambda_1)\\ k(\lambda_2)\\ \vdots \\ k(\lambda_N)\end{bmatrix} = \begin{bmatrix} k_\mathrm{1}\\ k_\mathrm{2}\\ \vdots \\ k_\mathrm{N}\end{bmatrix} \\
\col{A} = & a\col{k}\\
\end{align}
However, this column for $\col{k}$ has a (definite) length in this discrete formulation, and this length affects the (strength of) absorption of a certain `colour' as much as the factor $a$. For our purposes, we would like to separate `dye amount' and 'dye colour effect' completely, i.e.\ only $a$ should affect the strength of absorption.
So we divide $\col{k}$ by its length $l_k$ (`normalize') to get $\col{\hat{k}}$ and add the original effect of this length to $a$ to get $\hat{a}$:
\begin{align}
l_k & = \sqrt{k_1^2 + k_2^2 + \dots +k_N^3} = \sqrt{\sum_{n=1}^N k_n^2}\\
\col{\hat{k}} & = \frac{\col{k}}{l_k} = \begin{bmatrix}\frac{k_1}{l_k}\\[.5em] \frac{k_2}{l_k}\\[.5em] \vdots\\[.5em] \frac{k_N}{l_k}\end{bmatrix} \\
\hat{a} & = al_k\\
\col{A} & = \hat{a}\hat{\col{k}}
\end{align}
Thus, the column $\hat{\col{k}}$ contains the \textsl{relative} absorption coefficients for our (three) discrete wavelengths such that the combined effect of the (three) absorption coefficients adds up to 1.
The total absorption $\col{A}$ for our $N$ discrete wavelengths for $D$ different dyes can now be written as
\begin{equation}
\col{A} = \sum_{d=1}^D\hat{a}_d \col{\hat{k}}_d \label{sumdyedis}
\end{equation}
Which simply says that the total amount of light absorbed at a certain wavelength is the sum of the amount absorbed of the first dye at that wavelength plus the amount absorbed of the second dye at that wavelength plus the amount absorbed of the third dye at that wavelength plus \dots\\
Equation \ref{sumdyedis} can be written in matrix form as:
\begin{align}
\mat{K} & = \begin{bmatrix} \col{\hat{k}}_1 & \col{\hat{k}}_ 2 & \dots & \col{\hat{k}}_D\end{bmatrix},\; \col{a} = \begin{bmatrix} \hat{a}_1 \\ \hat{a}_ 2\\ \vdots \\ \hat{a}_D\end{bmatrix}\\
\mat{K}\col{\hat{a}} & = \col{A} \label{sumdyesmat}
\end{align}
Matrix $\mat{K}$ is composed of the $D$ columns with (normalized) absorption coefficients $\col{\hat{k}}$ put together side-by-side. Since each column $\col{\hat{k}}$ contains $N$ coefficients for $N$ wavelengths, the size of $\mat{K}$ is $N\times D$. The column $\hat{a}$ contains the $D$ dye amounts $\hat{a}_1$ through $\hat{a}_D$, and column $\col{A}$ contains the total (summed) absorption of the $D$ dyes for each of the $N$ wavelengths.
\noindent We can always calculate total absorbance $\col{A}$ for known $\mat{K}$ and $\hat{a}$ with equation \ref{sumdyesmat}, but to find the amounts $\hat{a}$ for given $\col{A}$ and $\mat{K}$, we have to solve:
\begin{align}
\mat{K}\col{\hat{a}} & = \col{A} \tag{\ref{sumdyesmat}}\\
\mat{K}^{-1}\mat{K}\col{\hat{a}} & = \mat{K}^{-1}\col{A} \\
\col{\hat{a}} & = \mat{K}^{-1}\col{A} \label{sumdyesinv}
\end{align}
and the inverse $\mat{K}^{-1}$ only exists for square matrices $\mat{K}$. Not to worry, we can get a square $\mat{K}$ by simply evaluating as much dyes $D$ as wavelengths $N$: $D = N$.
\section{Colour deconvolution in RGB}
\subsection{Deconvolution in `absorption-space'}
When we use three wavelengths and label them, say, $R$, $G$, and $B$ and (thus) use three dyes labelled 1, 2 and 3, equation \ref{sumdyesmat} comes out as:
\begin{equation}
\begin{bmatrix} \hat{k}_{R_1} & \hat{k}_{R_2} & k_{R_3} \\ \hat{k}_{G_1} & \hat{k}_{G_2} & \hat{k}_{G_3} \\ \hat{k}_{B_1} & \hat{k}_{B_2} & \hat{k}_{B_3}\end{bmatrix}\cdot\begin{bmatrix}\hat{a}_1\\\hat{a}_2\\\hat{a}_3 \end{bmatrix} = \begin{bmatrix}\hat{a}_1 \hat{k}_{R_1} + \hat{a}_2\hat{k}_{R_2} +\hat{a}_3 \hat{k}_{R_3} \\\hat{a}_1 \hat{k}_{G_1} + \hat{a}_2\hat{k}_{G_2} +\hat{a}_3 \hat{k}_{G_3} \\ \hat{a}_1 \hat{k}_{B_1} + \hat{a}_2\hat{k}_{B_2} +\hat{a}_3 \hat{k}_{B_3} \end{bmatrix}= \begin{bmatrix}A_R\\A_G\\A_B \end{bmatrix}
\end{equation}
and equation \ref{sumdyesinv} comes out as:
\begin{equation}
\begin{bmatrix}\hat{a}_1\\\hat{a}_2\\\hat{a}_3 \end{bmatrix} = \begin{bmatrix} \hat{k}_{R_1} & \hat{k}_{R_2} & k_{R_3} \\ \hat{k}_{G_1} & \hat{k}_{G_2} & \hat{k}_{G_3} \\ \hat{k}_{B_1} & \hat{k}_{B_2} & \hat{k}_{B_3}\end{bmatrix}^{-1}\cdot \begin{bmatrix}A_R\\A_G\\A_B \end{bmatrix}
\end{equation}
So when we know matrix $\mat{K}$ (and can calculate its inverse), and know the total amount of absorption for the three wavelengths $\col{A}$, we can calculate the contributions (amounts) of the three dyes $\hat{a}$.
Q.E.D.!
\subsection{Except that our images are in `transmission-space'}
Except that your RGB images are in `transmission space': the RGB scheme uses additive mixing. Worse, it is fundamentally impossible to measure absorption: you always measure intensity, brightness, `transmission', not `the amount of darkness'.\\
\noindent We can use equations \ref{Tlambda} and \ref{Alambda} to go from `transmission-space' to `absorption-space' and back.
When the maximum possible pixel intensity is $I_\mathrm{max}$ ($2^n-1$ for a $n$-bits camera) and the actual/recorded pixel intensity (RGB) column is $\col{I}_p$, then:
\begin{equation}
\col{T} = \frac{\col{I}_p}{I_\mathrm{max}} = \mathrm{e}^{-\col{\hat{k}}\hat{a}}
\end{equation}
which would make pixel intensity from absorption
\begin{equation}
\col{I}_p = I_\mathrm{max} \col{T} = I_\mathrm{max} \mathrm{e}^{-\col{\hat{k}}\hat{a}}
\end{equation}
and absorption from pixel intensity:
\begin{equation}
\col{A}= -\ln \left(\frac{\col{I}_p}{I_\mathrm{max}} \right) = \ln I_\mathrm{max} -\ln \col{I}_p =\col{\hat{k}}\hat{a}
\end{equation}
~\\
Except that pixel values can be zero, and the (any) log of zero is $-\infty$ which makes numerical computations hard.
So we add 1 to the pixel intensities to avoid that we have to store $\pm\infty$ in the computer:
\begin{equation}
\col{A}= -\ln \left(\frac{\col{I}_p + 1}{I_\mathrm{max}} \right) = \ln I_\mathrm{max} - \ln \left(\col{I}_p+ 1\right) \approx \col{\hat{k}}\hat{a}
\end{equation}
But
\ No newline at end of file
% Encoding: UTF-8
@Article{Beer1852,
author = {Beer, August},
title = {{B}estimmung der {A}bsorption des rothen {L}ichts in farbigen {F}l{\"u}ssigkeiten},
journal = {Annalen der Physik},
year = {1852},
volume = {162},
number = {5},
pages = {78--88},
doi = {10.1002/andp.18521620505},
owner = {mark},
timestamp = {2010.06.07},
}
@Article{Ruifrok2001,
author = {Ruifrok, Arnout C. and Johnston, Dennis A.},
title = {Quantification of histochemical staining by color deconvolution},
journal = {Analytical and quantitative cytology and histology},
year = {2001},
volume = {23},
number = {4},
pages = {291--299},
abstract = {Objective: To develop a flexible method of separation and quantification of
immunohistochemical staining by means of color image analysis.
Study Design: An algorithm was developed to deconvolve the color information
acquired with RGB cameras, to calculate the contribution of each of the applied stains,
based on the stain-specific RGB absorption. The algorithm was tested using different
combinations of DAB, hematoxylin and eosin at different staining levels.
Results: Quantification of the different stains was not significantly influenced by
the combination of multiple stains in a single sample. The color deconvolution algorithm
resulted in comparable quantification independent of the stain combinations, as long as
the histochemical procedures did not influence the amount of stain in the sample due to
bleaching because of stain solubility, and saturation of staining was prevented.
Conclusion: The presented image analysis algorithm provides a robust and
flexible method for objective immunohistochemical analysis of samples stained with up
to three different stains, using a laboratory microscope and standard RGB camera setup,
and the public domain program NIH image.},
keywords = {image processing, computer-assisted; color separation, color deconvolution, immunohistochemistry},
owner = {tue},
pmid = {11531144},
publisher = {St. Louis, MO: Science Printers and Publishers, 1985-},
timestamp = {2020.09.18},
}
@Article{Perrin1948,
author = {Perrin, Fred H.},
title = {{W}hose {A}bsorption {L}aw?},
journal = {Journal of the Optical Society of America},
year = {1948},
volume = {38},
number = {1},
pages = {72--74},
doi = {10.1364/JOSA.38.000072},
owner = {mark},
timestamp = {2010.06.07},
}
@Misc{Oransky2017,
author = {Oransky, Ivan and {Marcus (\href{https://retractionwatch.com}{Retraction Watch})}, Adam},
title = {Welcome to the {J}ournal of {A}lternative {F}acts. {T}hey're the greatest! {A}nd winning!},
howpublished = {\newline \href{https://retractionwatch.com/2017/01/31/welcome-journal-alternative-facts-theyre-greatest-winning/}{https://retractionwatch.com/2017/01/31/welcome-journal-alternative-facts-theyre-greatest-winning/}},
month = {January},
year = {2017},
owner = {tue},
timestamp = {2020-08-16},
}
@Comment{jabref-meta: databaseType:bibtex;}
%\pdfminorversion=4
%\RequirePackage[l2tabu,orthodox]{nag} % This package helps prevent you from doing things wrong.
%\RequirePackage{snapshot} % keep track of packages and package versions
\documentclass[12pt,a4paper,twoside,openright,headinclude,fleqn,chapterprefix=true]{scrbook}
%\RequirePackage{pdf14} % default is pdf version 1.5, however, this gave me trouble in a presentation once
% load packages
\usepackage{microtype}% Magically improves typesetting for pdflatex
% fonts and input
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{ae,aecompl}
\usepackage[greekuppercase = italicized,charter]{mathdesign} % use \Deltaup and \piupup from mathdesign instead of \upDelta and \uppiup from upgreek!
% use \micro (from the text font!) for \micro m instead of \muup m
% math
\usepackage[OMLmathrm,OMLmathbf,OMLmathsfit]{isomath}
\usepackage[nac]{misomath}
% listings and code
\usepackage{listings}
\input{listingset.tex}
% references and hyperlinks
\usepackage[square,sort&compress,comma,numbers]{natbib}
\usepackage[pdftex,breaklinks]{hyperref}
\usepackage{hypernat}
% graphics and color
\usepackage[pdftex]{graphicx}
\graphicspath{{pics/}}
\usepackage{svgimport}
\usepackage{xcolor}
\definecolor{ispurple}{RGB}{128,0,128}
\usepackage{transparent}
\usepackage[labelfont = {bf},format = default,indention = -4\parindent]{caption,subfig}
\captionsetup[subfloat]{labelfont = {bf},singlelinecheck = false,format = hang}
% language
\usepackage[dutch,german,UKenglish]{babel}
\selectlanguage{UKenglish}
% layout
\usepackage[grey,kpfonts]{quotchap} % chapter layout; kpfonts is chapter number font (was: charter)
%\usepackage{titlesec}
% \definecolor{Gray}{gray}{0.65}
\usepackage{appendix}
\usepackage{scrlayer-scrpage} % enable automark
\automark[chapter]{chapter} % create running heads
\setkomafont{pagehead}{\normalfont\footnotesize\sffamily}
\typearea[1.5cm]{18} % proper typeblock
% chapter number font to something undefined in quotchap.sty
% \makeatletter
% \renewcommand{\@defaultcnfont}{LinuxBiolinumO-LF}
% \makeatother
% document specific conventions
\providecommand*\warning{\marginpar{\center\includegraphics[width=1cm]{Exclamation.png}\\}}
\usepackage{makeidx}
\providecommand*\kwo[1]{%
\index{#1@\texttt{#1}}%
\textcolor{orange}{\texttt{#1}}%
}
\providecommand*\kwc[1]{%
\index{#1@\texttt{#1}}%
\textcolor{cyan}{\texttt{#1}}%
}
\makeindex
\usepackage{enumitem}
\usepackage{tabularx}
\begin{document}
\frontmatter
\pagestyle{empty}
\begin{center}
\Huge \textbf{On colour deconvolution}\\~\\
\href{https://gitlab.tue.nl/stem/colourdecon}{https://gitlab.tue.nl/stem/colourdecon}\\
\end{center}
\clearpage
\pagestyle{scrheadings}
\tableofcontents
\mainmatter
\include{algebra}
\begin{savequote}\vspace*{-2cm}
Here at the Journal of Alternative Facts, we do not believe in retraction. In the field of alternative facts, there are no mistakes or falsehoods, only facts that are appropriately alternative. In fact, we encourage submission of retracted papers from other venues to the Journal of Alternative Facts. \qauthor{Casey Fiesler, cited by Ivan Oransky \cite{Oransky2017}}\end{savequote}
\def\bibname{References}
\bibliographystyle{myplainhp}
\bibliography{colourdecon}
%
%\clearpage
%\begin{savequote}\vspace*{-2cm}
%Elsevier prides itself on only indexing high quality publications in Scopus, and if doesn't index all of the journals it publishes, isn't that admitting that not all of the journals Elsevier publishes are not high quality? \dots\ So, it is a good question to ask. And ask it I did. \qauthor{Ryan Regier \cite{Regier2016}}
%\end{savequote}
%\addcontentsline{toc}{chapter}{\protect\numberline{\color{white}}Index}
%\printindex
%\clearpage
\appendix
%\include{addendum}
%\include{demosall}
%\include{engines}
%\include{elmlib}
%\include{chapter7}
\end{document}
\hypersetup{colorlinks=true, backref=false, pdfauthor={Mark C. van Turnhout}, pdftitle={On colour deconvolution}, pdfsubject={On colour deconvolution}, pdfstartview=FitW, pdfkeywords={RGB, dyes, additive coulor mixing, subtractive colour mixing, optical density, colour deconvolution}}
%\def\@linkcolor{red}
%\def\@anchorcolor{black}
%\def\@citecolor{red}
%\def\@filecolor{cyan}
%\def\@urlcolor{blue}
%\def\@menucolor{red}
%\def\@pagecolor{red}
%\def\@linkcolor{TUEblue}
%\def\@anchorcolor{black}
%\def\@citecolor{TUEgreen}
%\def\@filecolor{cyan}
%\def\@urlcolor{TUEgreen}
%\def\@menucolor{TUEblue}
%\def\@pagecolor{TUEblue}
\def\@linkcolor{blue}
\def\@anchorcolor{black}
\def\@citecolor{blue}
\def\@filecolor{black}
\def\@urlcolor{blue}
\def\@menucolor{black}
\def\@pagecolor{black}
\lstset{ %
language = Octave, % choose the language of the code
basicstyle = \footnotesize\ttfamily, % the size of the fonts that are used for the code
numbers = left, % where to put the line-numbers
numberstyle = \footnotesize, % the size of the fonts that are used for the line-numbers
stepnumber = 1, % the step between two line-numbers. If it's 1 each line will be numbered
numbersep = 15pt, % how far the line-numbers are from the code
backgroundcolor = \color[rgb]{0.95,0.95,0.95}, % choose the background color. You must add \usepackage{color}
showspaces = false, % show spaces adding particular underscores
showstringspaces = false, % underline spaces within strings
showtabs = false, % show tabs within strings adding particular underscores
frameround = fttt, % rounded frame corners
frame = trBL, % adds a frame around the code
tabsize = 2, % sets default tabsize to 2 spaces
captionpos = b, % sets the caption-position to bottom
breaklines = true, % sets automatic line breaking
breakatwhitespace = false, % sets if automatic breaks should only happen at whitespace
title = \lstname, % show the filename of files included with \lstinputlisting;
% also try caption instead of title
captionpos = t, % sets the caption-position to top
escapeinside = {\%*}{*)}, % if you want to add a comment within your code
%morekeywords = {*,...}, % if you want to add more keywords to the set
commentstyle = \color{green},
stringstyle = \color{red},
keywordstyle = \color{blue},
abovecaptionskip=0pt,
belowcaptionskip=0pt,
caption={}}
\lst@definelanguage{mlfem}
{alsolanguage = Octave,
classoffset=0,
morekeywords = {clearvars,function,end,unique,numel},
%keywordsprefix = {mat.},
classoffset=1,
morekeywords={coord, top, pos, dest, nodfrc, bndcnd,inode,ielem,maxnodelm,iimat,iitype, mat,types,idof,ibnd,bndcon,nodfrc,sol,points,curves,subarea,usercurves,userpoints,
usersurfaces,itime,norder,istat,ntime,dt,theta,ietype, nincr, newtoptions,solinc,itype,
qe, qem, qme, qke, rhse, qde, qed,soln},
keywordstyle=\color{orange},
classoffset=2,
morekeywords={startup_nac,
elembld, % elemfnct
elemdrv,
eleminfo,
elemshp,
defdi, % elmlib
elcd_a,
elcd_i,
elcd,
elcd_s,
elcdu_i,
elcdu,
elcdu_s,
elchypo_i,
elchypo,
elchypo_s,
elcneofib_D,
elcneofib_i,
elcneofib,
elcneofib_s,
elcneo_i,
elcneo,
elcneo_s,
elcneotot_i,
elcneotot,
elcneotot_s,
ele_d,
elefib_d,
elefib_i,
elefib,
elefib_s,
ele_i,
ele,
eler_d,
eler_i,
eler,
eler_s,
ele_s,
elineo_i,
elineo,
elineo_s,
elm1dcd_d,
elm1dcd_i,
elm1dcd,
elm1dcd_s,
elm1d_c,
elm1d_d,
elm1d_i,
elm1d,
elm1d_s,
elme_d,
elme_i,
elme,
elme_s,
elneo_i,
elneo,
elneo_s,
elsf_d,
elsf_i,
elsf,
elsf_s,
elucm_i,
elucm,
elucm_s,
elup_d,
elup_i,
elup,
elup_s,
elu_s,
int2elm_e,
int2elm,
int2elmq,
addmesh, % guilib
colegend,
crsshair,
defbndc,
defline,
getcurpt,
getline,
gtbox,
gtinpoly,
gtline,
gtnodcrv,
gtnodelm,
gtnods,
gtpnts,
gtrect,
inside,
isinpoly,
line2pnt,
polyhit,
pzoom,
rmlines,
rmlnpoly,
zoomsurf,
fem1dcd, % main
fem1d,
femlin_cd,
femlin_e,
femlin,
femnl,
femnlt,
areabndcon, % mesh
avnod,
bndconsp,
crmesh_arcfea,
crmesh_arcfe,
crmesh_arc,
crmesharc,
crmesh_area,
crmesh,
getarcs,
innmdxdy,
mcrmesh,
mk3dmesh,
mspbndcon,
plmesh3d,
pointonarc,
repos,
spbndcon,
spcoord,
spmesharc,
spmesh,
trimesh,
trimeshq,
blmesh2d, % meshlib
cleancrd,
meshgen,
meshmk,
addbndc, % meshpde
contraction2,
contraction_b,
contraction_coarse,
contraction,
crackg,
defbndcon,
defgeomd_coarse,
defgeomd_ext,
defgeomd,
defgeom,
defgeom_xyz,
defmesh,
elembld,
elemdrv,
eleminfo,
elemshp,
examples,
genmesh,
refinepoly,
segline,
segmentline,
transmesh_crv,
transmesh,
transmesh_nodpot,
transmesh_start,
user_def_crack,
user_def_curve,
user_def_polygon,
xonarc,
count, % misclib
findcomm,
in,
iscolumnold,
isintegerold,
lump,
reverse,
rowsum,
unblank,
arcl, % plib
arrow,
cnt,
cntr,
coelmdat,
coleg,
conoddat,
covalues,
gplot3,
gplotm,
mcc_conoddat,
mvnoddat,
mvvec,
plarrow3,
plarrow,
plbndc,
plbound,
pldisp,
pldofnum,
pldot,
plelem,
plelgrp,
plelmdat,
plelnum,
plmesh,
plnoddat,
plnodes,
plnodnum,
plnodvec,
plqarrow,
plqarrw3,
plstress,
plusrcrv,
plusrpts,
plvec,
top2grph,