Sebastian Walz 860d31cee1
Tohu vaBohu
2023-04-21 00:22:52 +02:00

378 lines
12 KiB
Nix
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{ 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;
}