378 lines
12 KiB
Nix
378 lines
12 KiB
Nix
{ core, document, ... } @ libs:
|
||
let
|
||
inherit(core) debug indentation lambda list number path set string type;
|
||
inherit(document) ClearPage Heading' LaTeX PhantomHeading;
|
||
|
||
getDetails
|
||
= minimum:
|
||
peak:
|
||
string.concatWith ", "
|
||
(
|
||
list.filter (x: x != null)
|
||
[
|
||
(
|
||
let
|
||
strength = ( 100.0 - peak.y ) / ( 100.0 - minimum ) * 1.2;
|
||
in
|
||
if strength >= 0.7 then "s"
|
||
else if strength <= 0.3 then "w"
|
||
else "m"
|
||
)
|
||
(
|
||
let
|
||
assignment = "\\ch{${peak.assignment}}";
|
||
type
|
||
= {
|
||
stretching = "\\nu";
|
||
bending = "\\delta";
|
||
scissoring = "\\delta";
|
||
rocking = "\\gamma";
|
||
twisting = "\\tau";
|
||
wagging = "\\kappa";
|
||
}.${peak.type} or "???";
|
||
symmetric
|
||
= if peak.sym == null then ""
|
||
else if peak.sym then "\\textsubscript{s}"
|
||
else "\\textsubscript{as}";
|
||
in
|
||
if peak.assignment == null then null
|
||
else if peak.type == null then "${assignment}"
|
||
else "${symmetric}${type}(${assignment})"
|
||
)
|
||
]
|
||
);
|
||
|
||
getXpos
|
||
= peak:
|
||
if set.isInstanceOf peak.x then "${string (number.round peak.x.from)}–${string (number.round peak.x.till)}"
|
||
else (string (number.round peak.x));
|
||
|
||
reportSpectrum
|
||
= { acronyms, ... }:
|
||
spectrum:
|
||
let
|
||
signals
|
||
= list.filter
|
||
(
|
||
{ y, ... }:
|
||
let
|
||
strength = ( 100.0 - y ) / ( 100.0 - spectrum.min ) * 1.2;
|
||
in
|
||
strength >= 0.3
|
||
)
|
||
spectrum.signals;
|
||
signals'
|
||
= list.sort
|
||
(
|
||
first:
|
||
second:
|
||
let
|
||
first'
|
||
= if list.isInstanceOf first.x
|
||
then
|
||
list.head first.x
|
||
else if set.isInstanceOf first.x
|
||
then
|
||
first.x.from
|
||
else
|
||
first.x;
|
||
second'
|
||
= if list.isInstanceOf second.x
|
||
then
|
||
list.head second.x
|
||
else if set.isInstanceOf second.x
|
||
then
|
||
second.x.from
|
||
else
|
||
second.x;
|
||
in
|
||
debug.info "compare ir-signals" { data = { first = first.x; second = second.x; }; }
|
||
first' > second'
|
||
)
|
||
signals;
|
||
spectrum'
|
||
= list.map
|
||
( peak: "${getXpos peak} (${getDetails spectrum.min peak})" )
|
||
signals';
|
||
note
|
||
= if spectrum.note or null != null
|
||
then
|
||
"${spectrum.note}, "
|
||
else
|
||
"";
|
||
in
|
||
if spectrum' != [ ]
|
||
then
|
||
LaTeX
|
||
(
|
||
[
|
||
"\\mbox{}\\textbf{${acronyms.infrared.short}} (${note}${acronyms.waveNumber.short}/${acronyms.cm-1.short}):"
|
||
indentation.more
|
||
]
|
||
++ ( list.generate (x: "${list.get spectrum' x},") (( list.length spectrum' ) - 1) )
|
||
++ [
|
||
"${list.foot spectrum'}."
|
||
indentation.less
|
||
]
|
||
)
|
||
else
|
||
null;
|
||
|
||
genPeaks
|
||
= list.map
|
||
(
|
||
peak:
|
||
let
|
||
x'
|
||
= if set.isInstanceOf peak.x
|
||
then
|
||
( peak.x.from + peak.x.till ) / 2
|
||
else
|
||
peak.x;
|
||
x = string (number.round x');
|
||
y = string peak.y;
|
||
z = string (number.round ( x' + peak.z or 0 ));
|
||
colour = "0x00aaaaaa";
|
||
in
|
||
''
|
||
set arrow from first ${x}, graph 0.2 to first ${x}, first ${y} nohead lc rgb "${colour}"
|
||
set arrow from first ${x}, graph 0.2 to first ${z}, graph 0.13 nohead lc rgb "${colour}"
|
||
set label "\\tiny ${x}" right rotate by 90 at first ${z}, graph 0.12
|
||
''
|
||
);
|
||
genAppendix
|
||
= { acronyms, ... }:
|
||
{ journal ? "", substance, ... } @ product:
|
||
{ label ? null, plot, min, max, note ? null, range, signals ? [], ... } @ spectrum:
|
||
if plot != null
|
||
then
|
||
let
|
||
fileName
|
||
= let
|
||
plot' = path.getBaseName plot;
|
||
matching = string.match "(.+)[.]plot$" plot';
|
||
in
|
||
if matching != null
|
||
then
|
||
list.head matching
|
||
else
|
||
plot';
|
||
|
||
body
|
||
= ''
|
||
${string.concat ( genPeaks signals )}
|
||
set xlabel "{\\small ''${\${acronyms.waveNumber.short} / \${acronyms.cm-1.short}}$}"
|
||
set ylabel "{\\small ''${\\text{Transmission} / \${acronyms.percent.short}}$}"
|
||
set xrange [${string range.max}:${string range.min}]
|
||
set yrange [${string min}:${string max}]
|
||
plot "${plot}" notitle with lines lt rgb "0x00777777"
|
||
set output
|
||
'';
|
||
|
||
hash = string.hash "sha1" body;
|
||
dst = "generated/appendix/ir/${hash}-plot";
|
||
epsFile = "${dst}.eps";
|
||
texFile = "${dst}.tex";
|
||
gnuplotSourceFile
|
||
= path.toFile "${hash}.gnuplot"
|
||
''
|
||
set terminal epslatex
|
||
set output "${epsFile}"
|
||
${body}
|
||
'';
|
||
gnuplotDestinationFile = "${dst}.gnuplot";
|
||
|
||
src
|
||
= output:
|
||
string.concatWith " && "
|
||
[
|
||
"(mkdir -p \"generated/appendix/ir/${substance.name}/\""
|
||
"gnuplot \"${gnuplotSourceFile}\""
|
||
"mv \"${texFile}\" \"${output}.tex\""
|
||
"epstopdf \"${epsFile}\" \"${output}.pdf\")"
|
||
];
|
||
note'
|
||
= if note != null
|
||
then
|
||
" (${note})"
|
||
else
|
||
"";
|
||
in
|
||
Heading' "${acronyms.infrared.short}-Spektrum~${substance.NameID}${note'}"
|
||
[
|
||
(
|
||
LaTeX
|
||
(
|
||
(
|
||
if label != null
|
||
then
|
||
[ "\\labelAppendix{ir:${label}}%" ]
|
||
else
|
||
[ ]
|
||
)
|
||
++ (
|
||
if true
|
||
then
|
||
[
|
||
"\\vspace{-1\\normalbaselineskip}"
|
||
"\\begin{figure}[H]%" indentation.more
|
||
"\\centering%"
|
||
"\\begin{adjustbox}%" indentation.more
|
||
"{max width=\\textwidth,max height=.4\\textheight,keepaspectratio}%"
|
||
"{\\input{\\source/${texFile}}}%"
|
||
indentation.less "\\end{adjustbox}%"
|
||
indentation.less "\\end{figure}%" null
|
||
]
|
||
else
|
||
[
|
||
"\\begin{figure}[H]%" indentation.more
|
||
"\\centering%"
|
||
"\\begin{adjustbox}%" indentation.more
|
||
"{angle=90,min width=\\textwidth,min totalheight=\\textheightleft,max width=\\textwidth,max totalheight=\\textheightleft-2em}%"
|
||
"{\\input{\\source/${texFile}}}%"
|
||
indentation.less "\\end{adjustbox}%"
|
||
indentation.less "\\end{figure}%" null
|
||
]
|
||
)
|
||
)
|
||
)
|
||
]
|
||
{
|
||
clearPage = false;
|
||
# rotate = false;
|
||
before = "\\refstepcounter{ctrAppendix}%";
|
||
dependencies
|
||
= [
|
||
{ src = gnuplotSourceFile; dst = gnuplotDestinationFile; }
|
||
{ inherit dst src; }
|
||
];
|
||
}
|
||
else
|
||
[ ];
|
||
genAppendix'
|
||
= resources:
|
||
{ failure ? false, ... } @ product:
|
||
let
|
||
ir
|
||
= product.ir
|
||
or product.substance.ir
|
||
or null;
|
||
genAppendix' = genAppendix resources product;
|
||
in
|
||
if ir != null
|
||
&& !failure
|
||
then
|
||
if list.isInstanceOf ir
|
||
then
|
||
list.map genAppendix' ir
|
||
else
|
||
[ ( genAppendix' ir ) ]
|
||
else
|
||
[ ];
|
||
generateAppendix
|
||
= syntheses:
|
||
{ configuration, resources, ... } @ document:
|
||
let
|
||
syntheses'
|
||
= if path.isInstanceOf syntheses
|
||
then
|
||
import
|
||
syntheses
|
||
(libs // { chemistry = libs.chemistry // { ir = null; }; })
|
||
document
|
||
else
|
||
syntheses;
|
||
in
|
||
LaTeX
|
||
[
|
||
( ClearPage )
|
||
(
|
||
PhantomHeading
|
||
(
|
||
PhantomHeading
|
||
(
|
||
list.concatMap
|
||
(
|
||
synthesis:
|
||
if synthesis ? product
|
||
then
|
||
let
|
||
product
|
||
= if lambda.isInstanceOf synthesis.product then synthesis.product { }
|
||
else synthesis.product;
|
||
in
|
||
if list.isInstanceOf product then list.map (genAppendix' resources) product
|
||
else [ ( genAppendix' resources product ) ]
|
||
else
|
||
[ ]
|
||
)
|
||
(
|
||
if list.isInstanceOf syntheses'
|
||
then
|
||
syntheses'
|
||
else
|
||
syntheses'.list
|
||
)
|
||
)
|
||
)
|
||
)
|
||
];
|
||
|
||
report
|
||
= { ... } @ resources:
|
||
spectra:
|
||
let
|
||
reportSpectrum' = reportSpectrum resources;
|
||
in
|
||
if list.isInstanceOf spectra
|
||
then
|
||
list.filter
|
||
(x: x != null)
|
||
(list.map reportSpectrum' spectra)
|
||
else
|
||
[ ( reportSpectrum' spectra ) ];
|
||
|
||
Spectrum
|
||
= plot:
|
||
config:
|
||
signals:
|
||
{
|
||
inherit plot signals;
|
||
min = config.min or (-10);
|
||
max = config.max or 101;
|
||
range
|
||
= {
|
||
min = ( config.range or {} ).min or 500;
|
||
max = ( config.range or {} ).max or 4000;
|
||
};
|
||
note = config.note or null;
|
||
};
|
||
Signal
|
||
= x: y: z:
|
||
type:
|
||
sym:
|
||
assignment:
|
||
{
|
||
x
|
||
= type.matchPrimitiveOrDefault x
|
||
{
|
||
set
|
||
= {
|
||
from = x.from;
|
||
till = x.till;
|
||
};
|
||
list
|
||
= {
|
||
from = list.get x 0;
|
||
till = list.get x 1;
|
||
};
|
||
}
|
||
x;
|
||
inherit y z type sym assignment;
|
||
};
|
||
in
|
||
{
|
||
inherit generateAppendix report;
|
||
inherit Spectrum Signal;
|
||
Signal' = x: y: z: Signal x y z null null null;
|
||
} |